From 89a7ab06856f3f0d7e879d6c3df9c6db85792d6b Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 22 Jul 2010 17:02:55 +0000 Subject: Include the values of configurable options in `swig -version`. Show the value of important compilation options in swig -version output. Currently there is just one such option, for PCRE use, but more may be added in the future. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12176 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/main.cxx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'Source/Modules') diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx index f0e941f22..3f2008d7d 100644 --- a/Source/Modules/main.cxx +++ b/Source/Modules/main.cxx @@ -622,7 +622,14 @@ void SWIG_getoptions(int argc, char *argv[]) { } else if (strcmp(argv[i], "-version") == 0) { fprintf(stdout, "\nSWIG Version %s\n", Swig_package_version()); fprintf(stdout, "\nCompiled with %s [%s]\n", SWIG_CXX, SWIG_PLATFORM); - fprintf(stdout, "Please see %s for reporting bugs and further information\n", PACKAGE_BUGREPORT); + fprintf(stdout, "\nConfigured options: %cpcre\n", +#ifdef HAVE_PCRE + '+' +#else + '-' +#endif + ); + fprintf(stdout, "\nPlease see %s for reporting bugs and further information\n", PACKAGE_BUGREPORT); SWIG_exit(EXIT_SUCCESS); } else if (strcmp(argv[i], "-copyright") == 0) { fprintf(stdout, "\nSWIG Version %s\n", Swig_package_version()); -- cgit v1.2.1 From a25ccbf58b5d45a5916cf81821659c1730f0e793 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Wed, 8 Sep 2010 02:40:56 +0000 Subject: [PHP] Fix handling of OUTPUT typemaps (Patch from Ryan in SF#3058394). git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12208 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/php.cxx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Source/Modules') diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index 365fcd370..89204d7bf 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -915,8 +915,10 @@ public: } /* Insert argument output code */ + bool hasargout = false; for (i = 0, p = l; p; i++) { if ((tm = Getattr(p, "tmap:argout"))) { + hasargout = true; Replaceall(tm, "$source", Getattr(p, "lname")); // Replaceall(tm,"$input",Getattr(p,"lname")); Replaceall(tm, "$target", "return_value"); @@ -1663,7 +1665,7 @@ public: } } Printf(output, "%s", prepare); - } else if (Cmp(d, "void") == 0) { + } else if (Cmp(d, "void") == 0 && !hasargout) { if (Cmp(invoke, "$r") != 0) Printf(output, "\t\t%s;\n", invoke); } else if (is_class(d)) { -- cgit v1.2.1 From c0fe7400d2a4fa334558c73be3a6f1f2dd0f0bf7 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 14 Sep 2010 06:34:57 +0000 Subject: Fix undefined behaviour with Ruby and autodoc generation git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12218 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/ruby.cxx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'Source/Modules') diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx index bcdfd69d3..3887d8a98 100644 --- a/Source/Modules/ruby.cxx +++ b/Source/Modules/ruby.cxx @@ -121,6 +121,7 @@ public: /* flags for the make_autodoc function */ enum autodoc_t { + AUTODOC_NOTSET, AUTODOC_CLASS, AUTODOC_CTOR, AUTODOC_DTOR, @@ -580,6 +581,9 @@ private: case AUTODOC_SETTER: Printf(doc, " Document-method: %s.%s=\n\n", full_name, symname); break; + case AUTODOC_NOTSET: + assert(0); + break; } } @@ -608,6 +612,9 @@ private: if (type) Printf(doc, " -> %s", type); break; } + case AUTODOC_NOTSET: + assert(0); + break; default: break; } @@ -665,6 +672,9 @@ private: if (type) Printf(doc, " -> %s", type); break; } + case AUTODOC_NOTSET: + assert(0); + break; } } @@ -698,6 +708,9 @@ private: case AUTODOC_SETTER: Printf(doc, "Set new value for attribute.\n"); break; + case AUTODOC_NOTSET: + assert(0); + break; } } @@ -762,6 +775,7 @@ public: modvar = 0; feature = 0; prefix = 0; + last_mode = AUTODOC_NOTSET, last_autodoc = NewString(""); current = NO_CPP; classes = 0; -- cgit v1.2.1 From a202bf98183f8ef66d83d3c75e22078bcfdc4922 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 14 Sep 2010 18:52:18 +0000 Subject: Fix undefined behaviour git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12220 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/ruby.cxx | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx index 3887d8a98..bcdfd69d3 100644 --- a/Source/Modules/ruby.cxx +++ b/Source/Modules/ruby.cxx @@ -121,7 +121,6 @@ public: /* flags for the make_autodoc function */ enum autodoc_t { - AUTODOC_NOTSET, AUTODOC_CLASS, AUTODOC_CTOR, AUTODOC_DTOR, @@ -581,9 +580,6 @@ private: case AUTODOC_SETTER: Printf(doc, " Document-method: %s.%s=\n\n", full_name, symname); break; - case AUTODOC_NOTSET: - assert(0); - break; } } @@ -612,9 +608,6 @@ private: if (type) Printf(doc, " -> %s", type); break; } - case AUTODOC_NOTSET: - assert(0); - break; default: break; } @@ -672,9 +665,6 @@ private: if (type) Printf(doc, " -> %s", type); break; } - case AUTODOC_NOTSET: - assert(0); - break; } } @@ -708,9 +698,6 @@ private: case AUTODOC_SETTER: Printf(doc, "Set new value for attribute.\n"); break; - case AUTODOC_NOTSET: - assert(0); - break; } } @@ -775,7 +762,6 @@ public: modvar = 0; feature = 0; prefix = 0; - last_mode = AUTODOC_NOTSET, last_autodoc = NewString(""); current = NO_CPP; classes = 0; -- cgit v1.2.1 From d1e66431613ad092aa91770f52a2a2e5dede5a23 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 15 Sep 2010 20:17:11 +0000 Subject: Expand the family of debug print functions for displaying DOH types. Provide gdb support for calling these. Document improved debugging experience. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12221 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/lang.cxx | 2 +- Source/Modules/swigmod.h | 9 +++- Source/Modules/utils.cxx | 113 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 3 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index e28fcbb89..6ec0463fa 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -52,7 +52,7 @@ extern "C" { return all_protected_mode; } void Language_replace_special_variables(String *method, String *tm, Parm *parm) { - Language::instance()->replaceSpecialVariables(method, tm, parm); + Language::instance()->replaceSpecialVariables(method, tm, parm); } } diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h index b0b488d6f..d3074105f 100644 --- a/Source/Modules/swigmod.h +++ b/Source/Modules/swigmod.h @@ -380,9 +380,15 @@ void Wrapper_fast_dispatch_mode_set(int); void Wrapper_cast_dispatch_mode_set(int); void Wrapper_naturalvar_mode_set(int); - void clean_overloaded(Node *n); +extern "C" { + const char *Swig_to_string(DOH *object, int count = -1); + const char *Swig_to_string_with_location(DOH *object, int count = -1); + void Swig_print(DOH *object, int count = -1); + void Swig_print_with_location(DOH *object, int count = -1); +} + /* Contracts */ void Swig_contracts(Node *n); @@ -395,5 +401,4 @@ void Swig_browser(Node *n, int); void Swig_default_allocators(Node *n); void Swig_process_types(Node *n); - #endif diff --git a/Source/Modules/utils.cxx b/Source/Modules/utils.cxx index 3fe7a2709..13a504bcf 100644 --- a/Source/Modules/utils.cxx +++ b/Source/Modules/utils.cxx @@ -100,3 +100,116 @@ void clean_overloaded(Node *n) { Delattr(n, "sym:overloaded"); } } + +/* ----------------------------------------------------------------------------- + * Swig_set_max_hash_expand() + * + * Controls how many Hash objects are displayed when displaying nested Hash objects. + * Makes DohSetMaxHashExpand an externally callable function (for debugger). + * ----------------------------------------------------------------------------- */ + +void Swig_set_max_hash_expand(int count) { + SetMaxHashExpand(count); +} + +extern "C" { + +/* ----------------------------------------------------------------------------- + * Swig_get_max_hash_expand() + * + * Returns how many Hash objects are displayed when displaying nested Hash objects. + * Makes DohGetMaxHashExpand an externally callable function (for debugger). + * ----------------------------------------------------------------------------- */ + +int Swig_get_max_hash_expand() { + return GetMaxHashExpand(); +} + +/* ----------------------------------------------------------------------------- + * Swig_to_doh_string() + * + * DOH version of Swig_to_string() + * ----------------------------------------------------------------------------- */ + +static String *Swig_to_doh_string(DOH *object, int count) { + int old_count = Swig_get_max_hash_expand(); + if (count >= 0) + Swig_set_max_hash_expand(count); + + String *debug_string = object ? NewStringf("%s", object) : NewString("NULL"); + + Swig_set_max_hash_expand(old_count); + return debug_string; +} + +/* ----------------------------------------------------------------------------- + * Swig_to_doh_string_with_location() + * + * DOH version of Swig_to_string_with_location() + * ----------------------------------------------------------------------------- */ + +static String *Swig_to_doh_string_with_location(DOH *object, int count) { + int old_count = Swig_get_max_hash_expand(); + if (count >= 0) + Swig_set_max_hash_expand(count); + + String *debug_string = Swig_stringify_with_location(object); + + Swig_set_max_hash_expand(old_count); + return debug_string; +} + +/* ----------------------------------------------------------------------------- + * Swig_to_string() + * + * Swig debug - return C string representation of any DOH type. + * Nested Hash types expand count is value of Swig_get_max_hash_expand when count<0 + * Note: leaks memory. + * ----------------------------------------------------------------------------- */ + +const char *Swig_to_string(DOH *object, int count) { + return Char(Swig_to_doh_string(object, count)); +} + +/* ----------------------------------------------------------------------------- + * Swig_to_string_with_location() + * + * Swig debug - return C string representation of any DOH type, within [] brackets + * for Hash and List types, prefixed by line and file information. + * Nested Hash types expand count is value of Swig_get_max_hash_expand when count<0 + * Note: leaks memory. + * ----------------------------------------------------------------------------- */ + +const char *Swig_to_string_with_location(DOH *object, int count) { + return Char(Swig_to_doh_string_with_location(object, count)); +} + +/* ----------------------------------------------------------------------------- + * Swig_print() + * + * Swig debug - display string representation of any DOH type. + * Nested Hash types expand count is value of Swig_get_max_hash_expand when count<0 + * ----------------------------------------------------------------------------- */ + +void Swig_print(DOH *object, int count) { + String *output = Swig_to_doh_string(object, count); + Printf(stdout, "%s\n", output); + Delete(output); +} + +/* ----------------------------------------------------------------------------- + * Swig_to_string_with_location() + * + * Swig debug - display string representation of any DOH type, within [] brackets + * for Hash and List types, prefixed by line and file information. + * Nested Hash types expand count is value of Swig_get_max_hash_expand when count<0 + * ----------------------------------------------------------------------------- */ + +void Swig_print_with_location(DOH *object, int count) { + String *output = Swig_to_doh_string_with_location(object, count); + Printf(stdout, "%s\n", output); + Delete(output); +} + +} // extern "C" + -- cgit v1.2.1 From b01277a19be53421d66f800c942e5b8663100a46 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 18 Sep 2010 01:14:21 +0000 Subject: Various inherited class warning/error line number fixes git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12223 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/typepass.cxx | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx index e0e06d54e..438b66617 100644 --- a/Source/Modules/typepass.cxx +++ b/Source/Modules/typepass.cxx @@ -175,10 +175,10 @@ class TypePass:private Dispatcher { } } if (Strcmp(nodeType(bcls), "classforward") != 0) { - Swig_error(Getfile(cls), Getline(cls), "'%s' does not have a valid base class.\n", Getattr(cls, "name")); - Swig_error(Getfile(bcls), Getline(bcls), "'%s' is not a valid base class.\n", SwigType_namestr(bname)); + Swig_error(Getfile(bname), Getline(bname), "'%s' is not a valid base class.\n", SwigType_namestr(bname)); + Swig_error(Getfile(bcls), Getline(bcls), "See definition of '%s'.\n", SwigType_namestr(bname)); } else { - Swig_warning(WARN_TYPE_INCOMPLETE, Getfile(cls), Getline(cls), "Base class '%s' is incomplete.\n", SwigType_namestr(bname)); + Swig_warning(WARN_TYPE_INCOMPLETE, Getfile(bname), Getline(bname), "Base class '%s' is incomplete.\n", SwigType_namestr(bname)); Swig_warning(WARN_TYPE_INCOMPLETE, Getfile(bcls), Getline(bcls), "Only forward declaration '%s' was found.\n", SwigType_namestr(bname)); clsforward = 1; } @@ -189,7 +189,7 @@ class TypePass:private Dispatcher { ilist = alist = NewList(); Append(ilist, bcls); } else { - Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(cls), Getline(cls), "Base class '%s' undefined.\n", SwigType_namestr(bname)); + Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Base class '%s' undefined.\n", SwigType_namestr(bname)); Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bcls), Getline(bcls), "'%s' must be defined before it is used as a base class.\n", SwigType_namestr(bname)); } } @@ -202,10 +202,9 @@ class TypePass:private Dispatcher { if (!bcls) { if (!clsforward) { 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(bname), Getline(bname), "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)); + Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Maybe you forgot to instantiate '%s' using %%template.\n", SwigType_namestr(bname)); } Setmeta(bname, "already_warned", "1"); } @@ -259,7 +258,7 @@ class TypePass:private Dispatcher { Delete(bsmart); Delete(smart); } else { - Swig_error(Getfile(first), Getline(first), "Invalid type (%s) in 'smartptr' feature for class %s.\n", smartptr, clsname); + Swig_error(Getfile(first), Getline(first), "Invalid type (%s) in 'smartptr' feature for class %s.\n", SwigType_namestr(smartptr), SwigType_namestr(clsname)); } } if (!importmode) { @@ -275,7 +274,7 @@ class TypePass:private Dispatcher { Symtab *st = Getattr(cls, "symtab"); Symtab *bst = Getattr(bclass, "symtab"); if (st == bst) { - Swig_warning(WARN_PARSE_REC_INHERITANCE, Getfile(cls), Getline(cls), "Recursive scope inheritance of '%s'.\n", Getattr(cls, "name")); + Swig_warning(WARN_PARSE_REC_INHERITANCE, Getfile(cls), Getline(cls), "Recursive scope inheritance of '%s'.\n", SwigType_namestr(Getattr(cls, "name"))); continue; } Symtab *s = Swig_symbol_current(); -- cgit v1.2.1 From 6c094629cbd6df08a20c68656a487965b7072d30 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 20 Sep 2010 19:11:55 +0000 Subject: File and line number corrections for warnings WARN_JAVA_MULTIPLE_INHERITANCE WARN_MODULA3_MULTIPLE_INHERITANCE WARN_CSHARP_MULTIPLE_INHERITANCE and errors 'The javabase typemap for proxy' 'No methodname attribute...' 'No methodmodifiers attribute...' 'The csbase typemap for proxy...' git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12224 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/csharp.cxx | 16 ++++++++-------- Source/Modules/java.cxx | 18 ++++++++---------- Source/Modules/modula3.cxx | 11 ++++------- 3 files changed, 20 insertions(+), 25 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index 8ffd9768a..e0c4a4332 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -1640,10 +1640,10 @@ public: base = Next(base); continue; } - String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0); - String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0); - Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, input_file, line_number, - "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in C#.\n", proxyclassname, baseclassname); + String *proxyclassname = Getattr(n, "classtypeobj"); + String *baseclassname = Getattr(base.item, "name"); + Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), + "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Java.\n", SwigType_namestr(proxyclassname), SwigType_namestr(baseclassname)); base = Next(base); } } @@ -1661,9 +1661,9 @@ public: Delete(baseclass); baseclass = NULL; if (purebase_notderived) - Swig_error(input_file, line_number, "The csbase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n", typemap_lookup_type); + Swig_error(Getfile(n), Getline(n), "The csbase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n", typemap_lookup_type); } else if (Len(pure_baseclass) > 0 && Len(baseclass) > 0) { - Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, input_file, line_number, + Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in C#. " "Perhaps you need one of the 'replace' or 'notderived' attributes in the csbase typemap?\n", typemap_lookup_type, pure_baseclass); } @@ -1704,10 +1704,10 @@ public: } if (tm && *Char(tm)) { if (!destruct_methodname) { - Swig_error(input_file, line_number, "No methodname attribute defined in csdestruct%s typemap for %s\n", (derived ? "_derived" : ""), proxy_class_name); + Swig_error(Getfile(n), Getline(n), "No methodname attribute defined in csdestruct%s typemap for %s\n", (derived ? "_derived" : ""), proxy_class_name); } if (!destruct_methodmodifiers) { - Swig_error(input_file, line_number, + Swig_error(Getfile(n), Getline(n), "No methodmodifiers attribute defined in csdestruct%s typemap for %s.\n", (derived ? "_derived" : ""), proxy_class_name); } } diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx index 4a6abd569..c8769a876 100644 --- a/Source/Modules/java.cxx +++ b/Source/Modules/java.cxx @@ -1714,10 +1714,10 @@ public: base = Next(base); continue; } - String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0); - String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0); - Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, input_file, line_number, - "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Java.\n", proxyclassname, baseclassname); + String *proxyclassname = Getattr(n, "classtypeobj"); + String *baseclassname = Getattr(base.item, "name"); + Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), + "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Java.\n", SwigType_namestr(proxyclassname), SwigType_namestr(baseclassname)); base = Next(base); } } @@ -1735,9 +1735,9 @@ public: Delete(baseclass); baseclass = NULL; if (purebase_notderived) - Swig_error(input_file, line_number, "The javabase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n", typemap_lookup_type); + Swig_error(Getfile(n), Getline(n), "The javabase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n", typemap_lookup_type); } else if (Len(pure_baseclass) > 0 && Len(baseclass) > 0) { - Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, input_file, line_number, + Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Java. " "Perhaps you need one of the 'replace' or 'notderived' attributes in the csbase typemap?\n", typemap_lookup_type, pure_baseclass); } @@ -1772,12 +1772,10 @@ public: } if (tm && *Char(tm)) { if (!destruct_methodname) { - Swig_error(input_file, line_number, - "No methodname attribute defined in javadestruct%s typemap for %s\n", (derived ? "_derived" : ""), proxy_class_name); + Swig_error(Getfile(n), Getline(n), "No methodname attribute defined in javadestruct%s typemap for %s\n", (derived ? "_derived" : ""), proxy_class_name); } if (!destruct_methodmodifiers) { - Swig_error(input_file, line_number, - "No methodmodifiers attribute defined in javadestruct%s typemap for %s.\n", (derived ? "_derived" : ""), proxy_class_name); + Swig_error(Getfile(n), Getline(n), "No methodmodifiers attribute defined in javadestruct%s typemap for %s.\n", (derived ? "_derived" : ""), proxy_class_name); } } // Emit the finalize and delete methods diff --git a/Source/Modules/modula3.cxx b/Source/Modules/modula3.cxx index edd6690ce..ede63f802 100644 --- a/Source/Modules/modula3.cxx +++ b/Source/Modules/modula3.cxx @@ -2222,8 +2222,7 @@ MODULA3(): } base = Next(base); if (base.item != NIL) { - Swig_warning(WARN_MODULA3_MULTIPLE_INHERITANCE, input_file, - line_number, + Swig_warning(WARN_MODULA3_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Modula 3.\n", classDeclarationName, Getattr(base.item, "name")); } @@ -2236,8 +2235,7 @@ MODULA3(): // Inheritance from pure Modula 3 classes const String *pure_baseclass = typemapLookup(n, "m3base", classDeclarationName, WARN_NONE); if (hasContent(pure_baseclass) && hasContent(baseclass)) { - Swig_warning(WARN_MODULA3_MULTIPLE_INHERITANCE, input_file, - line_number, + Swig_warning(WARN_MODULA3_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Modula 3.\n", classDeclarationName, pure_baseclass); } // Pure Modula 3 interfaces @@ -2273,7 +2271,7 @@ MODULA3(): destruct_methodname = Getattr(attributes, "tmap:m3destruct:methodname"); } if (!destruct_methodname) { - Swig_error(input_file, line_number, "No methodname attribute defined in m3destruct%s typemap for %s\n", (derived ? "_derived" : ""), proxy_class_name); + Swig_error(Getfile(n), Getline(n), "No methodname attribute defined in m3destruct%s typemap for %s\n", (derived ? "_derived" : ""), proxy_class_name); } // Emit the Finalize and Dispose methods if (tm) { @@ -2466,8 +2464,7 @@ MODULA3(): Append(baseclassname, Getattr(base.item, "sym:name")); base = Next(base); if (base.item != NIL) { - Swig_warning(WARN_MODULA3_MULTIPLE_INHERITANCE, input_file, - line_number, + Swig_warning(WARN_MODULA3_MULTIPLE_INHERITANCE, input_file, line_number, "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Modula 3.\n", proxy_class_name, Getattr(base.item, "name")); } -- cgit v1.2.1 From 1e051820ec601ca34bbd8abc4926193319708e3e Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 21 Sep 2010 06:07:06 +0000 Subject: Line/file reporting corrections for warnings: WARN_RUBY_MULTIPLE_INHERITANCE, WARN_TYPE_UNDEFINED_CLASS, WARN_MODULA3_MULTIPLE_INHERITANCE git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12225 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/modula3.cxx | 2 +- Source/Modules/python.cxx | 2 +- Source/Modules/ruby.cxx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/modula3.cxx b/Source/Modules/modula3.cxx index ede63f802..45ceba1a4 100644 --- a/Source/Modules/modula3.cxx +++ b/Source/Modules/modula3.cxx @@ -2464,7 +2464,7 @@ MODULA3(): Append(baseclassname, Getattr(base.item, "sym:name")); base = Next(base); if (base.item != NIL) { - Swig_warning(WARN_MODULA3_MULTIPLE_INHERITANCE, input_file, line_number, + Swig_warning(WARN_MODULA3_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Modula 3.\n", proxy_class_name, Getattr(base.item, "name")); } diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index fed5205e1..b807cc627 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -2866,7 +2866,7 @@ public: bool ignore = GetFlag(b.item, "feature:ignore") ? true : false; if (!bname || ignore) { if (!bname && !ignore) { - Swig_warning(WARN_TYPE_UNDEFINED_CLASS, input_file, line_number, + Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(n), Getline(n), "Base class '%s' ignored - unknown module name for base. Either import the appropriate module interface file or specify the name of the module in the %%import directive.\n", SwigType_namestr(Getattr(b.item, "name"))); } b = Next(b); diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx index bcdfd69d3..ab1210a79 100644 --- a/Source/Modules/ruby.cxx +++ b/Source/Modules/ruby.cxx @@ -2395,7 +2395,7 @@ public: } String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0); String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0); - Swig_warning(WARN_RUBY_MULTIPLE_INHERITANCE, input_file, line_number, + Swig_warning(WARN_RUBY_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Ruby.\n", proxyclassname, baseclassname); base = Next(base); } -- cgit v1.2.1 From e1ddf0ea3a778bf5bac48009004f2a4a7ac9d9ea Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 25 Sep 2010 17:08:13 +0000 Subject: Apply SF patch #3075150 - Java directors using static variables in named namespace git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12228 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/java.cxx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx index c8769a876..1d4e522c6 100644 --- a/Source/Modules/java.cxx +++ b/Source/Modules/java.cxx @@ -3324,8 +3324,10 @@ public: } Printf(f_runtime, "namespace Swig {\n"); - Printf(f_runtime, " static jclass jclass_%s = NULL;\n", imclass_name); - Printf(f_runtime, " static jmethodID director_methids[%d];\n", n_methods); + Printf(f_runtime, " namespace {\n"); + Printf(f_runtime, " jclass jclass_%s = NULL;\n", imclass_name); + Printf(f_runtime, " jmethodID director_methids[%d];\n", n_methods); + Printf(f_runtime, " }\n"); Printf(f_runtime, "}\n"); Printf(w->def, "SWIGEXPORT void JNICALL Java_%s%s_%s(JNIEnv *jenv, jclass jcls) {", jnipackage, jni_imclass_name, swig_module_init_jni); -- cgit v1.2.1 From 5437d71d73569400cc2f544a7934f2c768efa8f5 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Mon, 27 Sep 2010 01:16:29 +0000 Subject: [Python] Improve error message given when a parameter of the wrong type is passed to an overloaded method (SF#3027355). git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12229 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/python.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Modules') diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index b807cc627..80f2e68df 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -1799,7 +1799,7 @@ public: } while ((sibl = Getattr(sibl, "sym:nextSibling"))); Append(f->code, "fail:\n"); Printf(f->code, "SWIG_SetErrorMsg(PyExc_NotImplementedError," - "\"Wrong number of arguments for overloaded function '%s'.\\n\"" "\n\" Possible C/C++ prototypes are:\\n\"%s);\n", symname, protoTypes); + "\"Wrong number or type of arguments for overloaded function '%s'.\\n\"" "\n\" Possible C/C++ prototypes are:\\n\"%s);\n", symname, protoTypes); Append(f->code, "return NULL;\n"); Delete(protoTypes); } -- cgit v1.2.1 From eaada32f264f828ec326f4c91f5c1a73399a8897 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Fri, 1 Oct 2010 04:42:29 +0000 Subject: [Ruby] Avoid segfault when a method node has no parentNode (SF#3034054). git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12237 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/ruby.cxx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx index ab1210a79..8461b8bef 100644 --- a/Source/Modules/ruby.cxx +++ b/Source/Modules/ruby.cxx @@ -2054,8 +2054,15 @@ public: // Construct real method name String* methodName = NewString(""); - if ( isMethod ) - Printv( methodName, Getattr(parentNode(sibl),"sym:name"), ".", NIL ); + if ( isMethod ) { + // Sometimes a method node has no parent (SF#3034054). + // This value is used in an exception message, so just skip the class + // name in this case so at least we don't segfault. This is probably + // just working around a problem elsewhere though. + Node *parent_node = parentNode(sibl); + if (parent_node) + Printv( methodName, Getattr(parent_node,"sym:name"), ".", NIL ); + } Append( methodName, Getattr(sibl,"sym:name" ) ); if ( isCtor ) Append( methodName, ".new" ); -- cgit v1.2.1 From 766ed8db375f47ef0ed4751bcd28eba31e40f3d7 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 1 Oct 2010 23:52:46 +0000 Subject: Add -pcreversion option to display PCRE version information git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12239 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/main.cxx | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'Source/Modules') diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx index 3f2008d7d..95327018d 100644 --- a/Source/Modules/main.cxx +++ b/Source/Modules/main.cxx @@ -129,6 +129,7 @@ static const char *usage3 = (const char *) "\ -oh - Set name of the output header file to \n\ -outcurrentdir - Set default output dir to current dir instead of input file's path\n\ -outdir - Set language specific files output directory to \n\ + -pcreversion - Display PCRE version information\n\ -small - Compile in virtual elimination & compact mode\n\ -swiglib - Report location of SWIG library and exit\n\ -templatereduce - Reduce all the typedefs in templates\n\ @@ -515,6 +516,12 @@ void SWIG_getoptions(int argc, char *argv[]) { } else if (strcmp(argv[i], "-nodirprot") == 0) { Wrapper_director_protected_mode_set(0); Swig_mark_arg(i); + } else if (strcmp(argv[i], "-pcreversion") == 0) { + String *version = Swig_pcre_version(); + Printf(stdout, "%s\n", version); + Delete(version); + Swig_mark_arg(i); + SWIG_exit(EXIT_SUCCESS); } else if (strcmp(argv[i], "-small") == 0) { Wrapper_compact_print_mode_set(1); Wrapper_virtual_elimination_mode_set(1); -- cgit v1.2.1 From 3219746776bb1bcb9f46f895c68040303f0d4b33 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sun, 3 Oct 2010 13:12:00 +0000 Subject: Apply patch #3066958 from Mikael Johansson to fix default smart pointer handling when the smart pointer contains both a const and non-const operator->. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12240 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/allocate.cxx | 6 ++++-- Source/Modules/lang.cxx | 7 +++++-- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/allocate.cxx b/Source/Modules/allocate.cxx index 2e05fd190..31f7c20ae 100644 --- a/Source/Modules/allocate.cxx +++ b/Source/Modules/allocate.cxx @@ -824,9 +824,12 @@ Allocate(): int isconst = 0; Delete(SwigType_pop(type)); if (SwigType_isconst(type)) { - isconst = 1; + isconst = !Getattr(inclass, "allocate:smartpointermutable"); Setattr(inclass, "allocate:smartpointerconst", "1"); } + else { + Setattr(inclass, "allocate:smartpointermutable", "1"); + } List *methods = smart_pointer_methods(sc, 0, isconst); Setattr(inclass, "allocate:smartpointer", methods); Setattr(inclass, "allocate:smartpointerbase", base); @@ -834,7 +837,6 @@ Allocate(): /* Hmmm. The return value is not a pointer. If the type is a value or reference. We're going to chase it to see if another operator->() can be found */ - if ((SwigType_check_decl(type, "")) || (SwigType_check_decl(type, "r."))) { Node *nn = Swig_symbol_clookup((char *) "operator ->", Getattr(sc, "symtab")); if (nn) { diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index 6ec0463fa..0110b6ea1 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -1344,7 +1344,7 @@ int Language::variableHandler(Node *n) { Swig_save("variableHandler", n, "feature:immutable", NIL); if (SmartPointer) { /* If a smart-pointer and it's a constant access, we have to set immutable */ - if (Getattr(CurrentClass, "allocate:smartpointerconst")) { + if (!Getattr(CurrentClass, "allocate:smartpointermutable")) { SetFlag(n, "feature:immutable"); } } @@ -1391,7 +1391,7 @@ int Language::membervariableHandler(Node *n) { int assignable = is_assignable(n); if (SmartPointer) { - if (Getattr(CurrentClass, "allocate:smartpointerconst")) { + if (!Getattr(CurrentClass, "allocate:smartpointermutable")) { assignable = 0; } } @@ -2443,6 +2443,9 @@ int Language::classHandler(Node *n) { List *methods = Getattr(n, "allocate:smartpointer"); cplus_mode = PUBLIC; SmartPointer = CWRAP_SMART_POINTER; + if (Getattr(n, "allocate:smartpointerconst") && Getattr(n, "allocate:smartpointermutable")) { + SmartPointer |= CWRAP_SMART_POINTER_OVERLOAD; + } Iterator c; for (c = First(methods); c.item; c = Next(c)) { emit_one(c.item); -- cgit v1.2.1 From 77a45b263102a22bb6d854760e8ecef32f956d1e Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sun, 3 Oct 2010 16:42:22 +0000 Subject: visual c++ warning fixes git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12243 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/go.cxx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx index f62586b92..4b1d05b92 100644 --- a/Source/Modules/go.cxx +++ b/Source/Modules/go.cxx @@ -1945,7 +1945,7 @@ private: String *ty = NewString(Getattr(ni, "type")); SwigType_push(ty, Getattr(ni, "decl")); String *fullty = SwigType_typedef_resolve_all(ty); - bool is_function = SwigType_isfunction(fullty); + bool is_function = SwigType_isfunction(fullty) ? true : false; Delete(ty); Delete(fullty); @@ -2426,7 +2426,7 @@ private: * ------------------------------------------------------------ */ int classDirectorConstructor(Node *n) { - bool is_ignored = GetFlag(n, "feature:ignore"); + bool is_ignored = GetFlag(n, "feature:ignore") ? true : false; String *name = Getattr(n, "sym:name"); if (!name) { @@ -2667,7 +2667,7 @@ private: return SWIG_OK; } - bool is_ignored = GetFlag(n, "feature:ignore"); + bool is_ignored = GetFlag(n, "feature:ignore") ? true : false; if (!is_ignored) { String *fnname = NewString("DeleteDirector"); @@ -2781,7 +2781,7 @@ private: int classDirectorMethod(Node *n, Node *parent, String *super) { (void) super; - bool is_ignored = GetFlag(n, "feature:ignore"); + bool is_ignored = GetFlag(n, "feature:ignore") ? true : false; bool is_pure_virtual = (Cmp(Getattr(n, "storage"), "virtual") == 0 && Cmp(Getattr(n, "value"), "0") == 0); // We don't need explicit calls. @@ -2869,7 +2869,7 @@ private: * ------------------------------------------------------------ */ int oneClassDirectorMethod(Node *n, Node *parent) { - bool is_ignored = GetFlag(n, "feature:ignore"); + bool is_ignored = GetFlag(n, "feature:ignore") ? true : false; bool is_pure_virtual = (Cmp(Getattr(n, "storage"), "virtual") == 0 && Cmp(Getattr(n, "value"), "0") == 0); String *name = Getattr(n, "sym:name"); @@ -3782,7 +3782,7 @@ private: int num_required = emit_num_required(pi); int num_arguments = emit_num_arguments(pi); - bool varargs = emit_isvarargs(pi); + bool varargs = emit_isvarargs(pi) ? true : false; if (varargs) { Printf(f_go_wrappers, "\tif argc >= %d {\n", num_required); @@ -4138,7 +4138,7 @@ private: n1, name, n2); return false; } - bool r = addSymbol(name, n, scope); + bool r = addSymbol(name, n, scope) ? true : false; assert(r); return true; } -- cgit v1.2.1 From 9eaf5ba1be143ea16eb7bfc096122be3c7bead19 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Thu, 14 Oct 2010 05:13:09 +0000 Subject: [PHP] Allow compilation on non-conforming Microsoft C++ compilers which don't accept: return function_returning_void(); Reported by Frank Vanden Berghen on the SWIG mailing list. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12265 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/php.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Modules') diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index 89204d7bf..05f2082c2 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -666,7 +666,7 @@ public: /* We have an extra 'this' parameter. */ SetFlag(n, "wrap:this"); } - String *dispatch = Swig_overload_dispatch(n, "return %s(INTERNAL_FUNCTION_PARAM_PASSTHRU);", &maxargs); + String *dispatch = Swig_overload_dispatch(n, "%s(INTERNAL_FUNCTION_PARAM_PASSTHRU); return;", &maxargs); /* Generate a dispatch wrapper for all overloaded functions */ -- cgit v1.2.1 From 98441fc6ad6d6097c98baf28b54c7059045806b6 Mon Sep 17 00:00:00 2001 From: Joseph Wang Date: Sun, 17 Oct 2010 07:33:58 +0000 Subject: [R] Fix failure in overloaded functions which was breaking QuantLib-SWIG git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12282 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/r.cxx | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'Source/Modules') diff --git a/Source/Modules/r.cxx b/Source/Modules/r.cxx index 749797c78..61cbcdd79 100644 --- a/Source/Modules/r.cxx +++ b/Source/Modules/r.cxx @@ -1603,6 +1603,16 @@ void R::dispatchFunction(Node *n) { j == 0 ? "" : " && ", j+1); } + else if (DohStrcmp(tm,"integer")==0) { + Printf(f->code, "%s(is.integer(argv[[%d]]) || is.numeric(argv[[%d]]))", + j == 0 ? "" : " && ", + j+1, j+1); + } + else if (DohStrcmp(tm,"character")==0) { + Printf(f->code, "%sis.character(argv[[%d]])", + j == 0 ? "" : " && ", + j+1); + } else { Printf(f->code, "%sextends(argtypes[%d], '%s')", j == 0 ? "" : " && ", @@ -1617,7 +1627,9 @@ void R::dispatchFunction(Node *n) { } } if (cur_args != -1) { - Printv(f->code, "}", NIL); + Printf(f->code, "} else {\n" + "stop(\"cannot find overloaded function for %s\");\n" + "}", sfname); } Printv(f->code, ";\nf(...)", NIL); Printv(f->code, ";\n}", NIL); -- cgit v1.2.1 From f77ccd81d5c0b09ba0d99833e60945edf381f2f5 Mon Sep 17 00:00:00 2001 From: Joseph Wang Date: Sun, 17 Oct 2010 09:35:34 +0000 Subject: [R] Improve error message for missing argtypes git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12283 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/r.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Source/Modules') diff --git a/Source/Modules/r.cxx b/Source/Modules/r.cxx index 61cbcdd79..8eb784c68 100644 --- a/Source/Modules/r.cxx +++ b/Source/Modules/r.cxx @@ -1628,7 +1628,8 @@ void R::dispatchFunction(Node *n) { } if (cur_args != -1) { Printf(f->code, "} else {\n" - "stop(\"cannot find overloaded function for %s\");\n" + "stop(\"cannot find overloaded function for %s with argtypes (\"," + "toString(argtypes),\")\");\n" "}", sfname); } Printv(f->code, ";\nf(...)", NIL); -- cgit v1.2.1 From 77b87aa9196c226b8625218b8608b5696b335d06 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 11 Nov 2010 19:30:44 +0000 Subject: typo fix in help message git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12288 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/python.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Modules') diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 80f2e68df..6d5f500a4 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -130,7 +130,7 @@ static const char *usage2 = (char *) "\ -nofastproxy - Use traditional proxy mechanism for member methods (default) \n\ -nofastquery - Use traditional query mechanism for types (default) \n\ -noh - Don't generate the output header file\n\ - -nomodern - Don't use modern python features which are not back compatible \n\ + -nomodern - Don't use modern python features which are not backwards compatible \n\ -nomodernargs - Use classic ParseTuple/CallFunction methods to pack/unpack the function arguments (default) \n"; static const char *usage3 = (char *) "\ -noolddefs - Don't emit the old method definitions even when using fastproxy (default) \n\ -- cgit v1.2.1 From 580f2549582602399553fded9e12bca6f9746143 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 12 Nov 2010 16:43:03 +0000 Subject: Update for recent runtime name changes (a better mechanism is clearly needed here). git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12290 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/go.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx index 4b1d05b92..d3de53f8f 100644 --- a/Source/Modules/go.cxx +++ b/Source/Modules/go.cxx @@ -1068,7 +1068,7 @@ private: Delete(parm_size); Printv(f->code, "{\n", NULL); - Printv(f->code, "\tcgocall(", wname, ", &p);\n", NULL); + Printv(f->code, "\truntime\xc2\xb7" "cgocall(", wname, ", &p);\n", NULL); Printv(f->code, "}\n", NULL); Printv(f->code, "\n", NULL); @@ -2749,7 +2749,7 @@ private: Printv(f_gc_wrappers, "void\n", NULL); Printv(f_gc_wrappers, wname, "(void *a, int32 n)\n", NULL); Printv(f_gc_wrappers, "{\n", NULL); - Printv(f_gc_wrappers, "\tcgocallback(\xc2\xb7", go_name, ", a, n);\n", NULL); + Printv(f_gc_wrappers, "\truntime\xc2\xb7" "cgocallback(\xc2\xb7", go_name, ", a, n);\n", NULL); Printv(f_gc_wrappers, "}\n\n", NULL); } else { Printv(f_c_directors, " ", wname, "(go_val);\n", NULL); @@ -3475,7 +3475,7 @@ private: Printv(f_gc_wrappers, "void\n", NULL); Printv(f_gc_wrappers, callback_wname, "(void *a, int32 n)\n", NULL); Printv(f_gc_wrappers, "{\n", NULL); - Printv(f_gc_wrappers, "\tcgocallback(\xc2\xb7", callback_name, ", a, n);\n", NULL); + Printv(f_gc_wrappers, "\truntime\xc2\xb7" "cgocallback(\xc2\xb7", callback_name, ", a, n);\n", NULL); Printv(f_gc_wrappers, "}\n\n", NULL); } else { if (SwigType_type(result) != T_VOID) { -- cgit v1.2.1 From 03aefbc6e95d094a6de231e1f5264c0946e209a3 Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Thu, 18 Nov 2010 00:24:02 +0000 Subject: Added support for the D programming languge. It is still a bit rough around some edges, particularly with regard to multi-threading and operator overloading, and there are some documentation bits missing, but it should be fine for basic use. The test-suite should build and run fine with the current versions of DMD, LDC and Tango (at least) on Linux x86_64 and Mac OS X 10.6. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12299 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/d.cxx | 4359 +++++++++++++++++++++++++++++++++++++++++++ Source/Modules/swigmain.cxx | 2 + 2 files changed, 4361 insertions(+) create mode 100644 Source/Modules/d.cxx (limited to 'Source/Modules') diff --git a/Source/Modules/d.cxx b/Source/Modules/d.cxx new file mode 100644 index 000000000..e3e1d9759 --- /dev/null +++ b/Source/Modules/d.cxx @@ -0,0 +1,4359 @@ +/* ----------------------------------------------------------------------------- + * This file is part of SWIG, which is licensed as a whole under version 3 + * (or any later version) of the GNU General Public License. Some additional + * terms also apply to certain portions of SWIG. The full details of the SWIG + * license and copyrights can be found in the LICENSE and COPYRIGHT files + * included with the SWIG source code as distributed by the SWIG developers + * and at http://www.swig.org/legal.html. + * + * d.cxx + * + * D language module for SWIG. + * ----------------------------------------------------------------------------- */ + +char cvsroot_d_cxx[] = "$Id$"; + +#include "swigmod.h" +#include "cparse.h" +#include + +// Hash type used for storing information about director callbacks for a class. +typedef DOH UpcallData; + +class D : public Language { + static const char *usage; + const String *empty_string; + const String *public_string; + const String *protected_string; + const String *static_string; + + /* + * Files and file sections containing C/C++ code. + */ + File *f_begin; + File *f_runtime; + File *f_runtime_h; + File *f_header; + File *f_wrappers; + File *f_init; + File *f_directors; + File *f_directors_h; + List *filenames_list; + + /* + * Command line-set modes of operation. + */ + // Whether a single proxy D module is generated or classes and enums are + // written to their own files. + bool split_proxy_dmodule; + + // The major D version targeted (currently 1 or 2). + unsigned short d_version; + + /* + * State variables which indicate what is being wrapped at the moment. + * This is probably not the most elegant way of handling state, but it has + * proven to work in the C# and Java modules. + */ + // Indicates if wrapping a native function. + bool native_function_flag; + + // Indicates if wrapping a static functions or member variables + bool static_flag; + + // Indicates if wrapping a nonstatic member variable + bool variable_wrapper_flag; + + // Indicates if wrapping a member variable/enum/const. + bool wrapping_member_flag; + + // Indicates if wrapping a global variable. + bool global_variable_flag; + + // Name of a variable being wrapped. + String *variable_name; + + /* + * Variables temporarily holding the generated C++ code. + */ + // C++ code for the generated wrapper functions for casts up the C++ + // for inheritance hierarchies. + String *upcasts_code; + + // Function pointer typedefs for handling director callbacks on the C++ side. + String *director_callback_typedefs; + + // Variables for storing the function pointers to the director callbacks on + // the C++ side. + String *director_callback_pointers; + + /* + * Names of generated D entities. + */ + // The name of the D module containing the interface to the C wrapper. + String *wrap_dmodule_name; + + // The fully qualified name of the wrap D module (package name included). + String *wrap_dmodule_fq_name; + + // The name of the proxy module which exposes the (SWIG) module contents as a + // D module. + String *proxy_dmodule_name; + + // The fully qualified name of the proxy D module. + String *proxy_dmodule_fq_name; + + // Optional: Package the D modules are placed in (set via the -package + // command line option). + String *package; + + // The directory the generated D module files are written to. Is constructed + // from the package path if a target package is set, points to the general + // output directory otherwise. + String *dmodule_directory; + + // The name of the library which contains the C wrapper (used when generating + // the dynamic library loader). Can be overridden via the -wrapperlibrary + // command line flag. + String *wrap_library_name; + + /* + * Variables temporarily holding the generated D code. + */ + // Import statements written to the wrap D module header set via + // %pragma(d) wrapdmoduleimports. + String *wrap_dmodule_imports; + + // The code for the wrap D module body. + String *wrap_dmodule_code; + + // Import statements for all proxy modules (the main proxy module and, if in + // split proxy module mode, the proxy class modules) from + // %pragma(d) globalproxyimports. + String *global_proxy_imports; + + // Imports written to the proxy D module header from global_proxy_imports + // and, if in split proxy module mode, from D::requireDType(). + String *proxy_dmodule_imports; + + // The D code for proxy functions/classes which is written to the proxy D + // module. If not in split proxy mode, this contains the whole proxy code. + String *proxy_dmodule_code; + + // The D code generated for the currently wrapped enum. + String *proxy_enum_code; + + /* + * D data for the current proxy class. + */ + // The name of the current proxy class. + String *proxy_class_name; + + // The import directives for the current proxy class. They are written to the + // same D module the proxy class is written to. + String *proxy_class_imports; + + // Code for enumerations nested in the current proxy class. Is emitted earlier + // than the rest of the body to work around forward referencing-issues. + String *proxy_class_enums_code; + + // The generated D code making up the body of the current proxy class. + String *proxy_class_body_code; + + // D code which is emitted right after the proxy class. + String *proxy_class_epilogue_code; + + // The full code for the current proxy class, including the epilogue. + String* proxy_class_code; + + // Contains a D call to the function wrapping C++ the destructor of the + // current class (if there is a public C++ destructor). + String *destructor_call; + + // D code for the director callbacks generated for the current class. + String *director_dcallbacks_code; + + /* + * Code for dynamically loading the wrapper library on the D side. + */ + // D code which is inserted into the wrapper module if dynamic linking is used. + String *wrapper_loader_code; + + // The D code to bind a function pointer to a library symbol. + String *wrapper_loader_bind_command; + + // The cumulated binding commands binding all wrapper functions to the C/C++ + // library symbols. + String *wrapper_loader_bind_code; + + /* + * Director data. + */ + List *dmethods_seq; + Hash *dmethods_table; + int n_dmethods; + int first_class_dmethod; + int curr_class_dmethod; + + /* + * SWIG types data. + */ + // Collects information about encountered types SWIG does not know about (e.g. + // incomplete types). This is used later to generate type wrapper proxy + // classes for the unknown types. + Hash *unknown_types; + + +public: + /* --------------------------------------------------------------------------- + * D::D() + * --------------------------------------------------------------------------- */ + D():empty_string(NewString("")), + public_string(NewString("public")), + protected_string(NewString("protected")), + f_begin(NULL), + f_runtime(NULL), + f_runtime_h(NULL), + f_header(NULL), + f_wrappers(NULL), + f_init(NULL), + f_directors(NULL), + f_directors_h(NULL), + filenames_list(NULL), + split_proxy_dmodule(false), + d_version(1), + native_function_flag(false), + static_flag(false), + variable_wrapper_flag(false), + wrapping_member_flag(false), + global_variable_flag(false), + variable_name(NULL), + upcasts_code(NULL), + director_callback_typedefs(NULL), + director_callback_pointers(NULL), + wrap_dmodule_name(NULL), + wrap_dmodule_fq_name(NULL), + proxy_dmodule_name(NULL), + proxy_dmodule_fq_name(NULL), + package(NULL), + dmodule_directory(NULL), + wrap_library_name(NULL), + wrap_dmodule_imports(NULL), + wrap_dmodule_code(NULL), + global_proxy_imports(NULL), + proxy_dmodule_imports(NULL), + proxy_dmodule_code(NULL), + proxy_enum_code(NULL), + proxy_class_name(NULL), + proxy_class_imports(NULL), + proxy_class_enums_code(NULL), + proxy_class_body_code(NULL), + proxy_class_epilogue_code(NULL), + proxy_class_code(NULL), + destructor_call(NULL), + director_dcallbacks_code(NULL), + wrapper_loader_code(NULL), + wrapper_loader_bind_command(NULL), + wrapper_loader_bind_code(NULL), + dmethods_seq(NULL), + dmethods_table(NULL), + n_dmethods(0), + unknown_types(NULL) { + + // For now, multiple inheritance with directors is not possible. It should be + // easy to implement though. + director_multiple_inheritance = 0; + director_language = 1; + + // Not used: + Delete(none_comparison); + none_comparison = NewString(""); + } + + /* --------------------------------------------------------------------------- + * D::main() + * --------------------------------------------------------------------------- */ + virtual void main(int argc, char *argv[]) { + SWIG_library_directory("d"); + + // Look for certain command line options + for (int i = 1; i < argc; i++) { + if (argv[i]) { + if ((strcmp(argv[i], "-d2") == 0)) { + Swig_mark_arg(i); + d_version = 2; + } else if (strcmp(argv[i], "-wrapperlibrary") == 0) { + if (argv[i + 1]) { + wrap_library_name = NewString(""); + Printf(wrap_library_name, argv[i + 1]); + Swig_mark_arg(i); + Swig_mark_arg(i + 1); + i++; + } else { + Swig_arg_error(); + } + } else if (strcmp(argv[i], "-package") == 0) { + if (argv[i + 1]) { + package = NewString(""); + Printf(package, argv[i + 1]); + Swig_mark_arg(i); + Swig_mark_arg(i + 1); + i++; + } else { + Swig_arg_error(); + } + } else if ((strcmp(argv[i], "-splitproxy") == 0)) { + Swig_mark_arg(i); + split_proxy_dmodule = true; + } else if (strcmp(argv[i], "-help") == 0) { + Printf(stdout, "%s\n", usage); + } + } + } + + // Add a symbol to the parser for conditional compilation + Preprocessor_define("SWIGD 1", 0); + + // Also make the target D version available as preprocessor symbol for + // use in our library files. + String *version_define = NewStringf("SWIG_D_VERSION %u", d_version); + Preprocessor_define(version_define, 0); + Delete(version_define); + + // Add typemap definitions + SWIG_typemap_lang("d"); + SWIG_config_file("d.swg"); + + allow_overloading(); + } + + /* --------------------------------------------------------------------------- + * D::top() + * --------------------------------------------------------------------------- */ + virtual int top(Node *n) { + // Get any options set in the module directive + Node *optionsnode = Getattr(Getattr(n, "module"), "options"); + + if (optionsnode) { + if (Getattr(optionsnode, "wrapdmodulename")) { + wrap_dmodule_name = Copy(Getattr(optionsnode, "wrapdmodulename")); + } + + if (Getattr(optionsnode, "directors")) { + // Check if directors are enabled for this module. Note: This is a + // "master switch", if it is not set, not director code will be emitted + // at all. %feature("director") statements are also required to enable + // directors for individual classes or methods. + // + // Use the »directors« attributte of the %module directive to enable + // director generation (e.g. »%module(directors="1") modulename«). + allow_directors(); + } + + if (Getattr(optionsnode, "dirprot")) { + allow_dirprot(); + } + + allow_allprotected(GetFlag(optionsnode, "allprotected")); + } + + /* Initialize all of the output files */ + String *outfile = Getattr(n, "outfile"); + String *outfile_h = Getattr(n, "outfile_h"); + + if (!outfile) { + Printf(stderr, "Unable to determine outfile\n"); + SWIG_exit(EXIT_FAILURE); + } + + f_begin = NewFile(outfile, "w", SWIG_output_files()); + if (!f_begin) { + FileErrorDisplay(outfile); + SWIG_exit(EXIT_FAILURE); + } + + if (directorsEnabled()) { + if (!outfile_h) { + Printf(stderr, "Unable to determine outfile_h\n"); + SWIG_exit(EXIT_FAILURE); + } + f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files()); + if (!f_runtime_h) { + FileErrorDisplay(outfile_h); + SWIG_exit(EXIT_FAILURE); + } + } + + f_runtime = NewString(""); + f_init = NewString(""); + f_header = NewString(""); + f_wrappers = NewString(""); + f_directors_h = NewString(""); + f_directors = NewString(""); + + /* Register file targets with the SWIG file handler */ + Swig_register_filebyname("header", f_header); + Swig_register_filebyname("wrapper", f_wrappers); + Swig_register_filebyname("begin", f_begin); + Swig_register_filebyname("runtime", f_runtime); + Swig_register_filebyname("init", f_init); + Swig_register_filebyname("director", f_directors); + Swig_register_filebyname("director_h", f_directors_h); + + unknown_types = NewHash(); + filenames_list = NewList(); + + // Make the package name and the resulting module output path. + if (package) { + // Append a dot so we can prepend the package variable directly to the + // module names in the rest of the code. + Printv(package, ".", NIL); + } else { + // Write the generated D modules to the »root« package by default. + package = NewString(""); + } + + dmodule_directory = Copy(SWIG_output_directory()); + if (Len(package) > 0) { + String *package_directory = Copy(package); + Replaceall(package_directory, ".", SWIG_FILE_DELIMITER); + Printv(dmodule_directory, package_directory, NIL); + Delete(package_directory); + } + + // Make the wrap and proxy D module names. + // The wrap module name can be set in the module directive. + if (!wrap_dmodule_name) { + wrap_dmodule_name = NewStringf("%s_wrap", Getattr(n, "name")); + } + wrap_dmodule_fq_name = NewStringf("%s%s", package, wrap_dmodule_name); + proxy_dmodule_name = Copy(Getattr(n, "name")); + proxy_dmodule_fq_name = NewStringf("%s%s", package, proxy_dmodule_name); + + wrap_dmodule_code = NewString(""); + proxy_class_imports = NewString(""); + proxy_class_enums_code = NewString(""); + proxy_class_body_code = NewString(""); + proxy_class_epilogue_code = NewString(""); + proxy_class_code = NewString(""); + destructor_call = NewString(""); + proxy_dmodule_code = NewString(""); + proxy_dmodule_imports = NewString(""); + wrap_dmodule_imports = NewString(""); + upcasts_code = NewString(""); + global_proxy_imports = NewString(""); + wrapper_loader_code = NewString(""); + wrapper_loader_bind_command = NewString(""); + wrapper_loader_bind_code = NewString(""); + dmethods_seq = NewList(); + dmethods_table = NewHash(); + n_dmethods = 0; + + // By default, expect the dynamically loaded wrapper library to be named + // like the wrapper D module (i.e. [lib]_wrap[.so/.dll] unless the + // user overrides it). + if (!wrap_library_name) + wrap_library_name = Copy(wrap_dmodule_name); + + Swig_banner(f_begin); + + Printf(f_runtime, "\n"); + Printf(f_runtime, "#define SWIGD\n"); + + if (directorsEnabled()) { + Printf(f_runtime, "#define SWIG_DIRECTORS\n"); + + /* Emit initial director header and director code: */ + Swig_banner(f_directors_h); + Printf(f_directors_h, "\n"); + Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", proxy_dmodule_name); + Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", proxy_dmodule_name); + + Printf(f_directors, "\n\n"); + Printf(f_directors, "/* ---------------------------------------------------\n"); + Printf(f_directors, " * C++ director class methods\n"); + Printf(f_directors, " * --------------------------------------------------- */\n\n"); + if (outfile_h) + Printf(f_directors, "#include \"%s\"\n\n", Swig_file_filename(outfile_h)); + } + + Printf(f_runtime, "\n"); + + Swig_name_register("wrapper", "D_%f"); + + Printf(f_wrappers, "\n#ifdef __cplusplus\n"); + Printf(f_wrappers, "extern \"C\" {\n"); + Printf(f_wrappers, "#endif\n\n"); + + // Emit all the wrapper code. + Language::top(n); + + if (directorsEnabled()) { + // Insert director runtime into the f_runtime file (before %header section). + Swig_insert_file("director.swg", f_runtime); + } + + // Generate the wrap D module. + // TODO: Add support for »static« linking. + { + String *filen = NewStringf("%s%s.d", dmodule_directory, wrap_dmodule_name); + File *wrap_d_file = NewFile(filen, "w", SWIG_output_files()); + if (!wrap_d_file) { + FileErrorDisplay(filen); + SWIG_exit(EXIT_FAILURE); + } + Append(filenames_list, Copy(filen)); + Delete(filen); + filen = NULL; + + // Start writing out the intermediary class file. + emitBanner(wrap_d_file); + + Printf(wrap_d_file, "module %s;\n", wrap_dmodule_fq_name); + + Printv(wrap_d_file, wrap_dmodule_imports, "\n", NIL); + + Replaceall(wrapper_loader_code, "$wraplibrary", wrap_library_name); + Replaceall(wrapper_loader_code, "$wrapperloaderbindcode", wrapper_loader_bind_code); + Replaceall(wrapper_loader_code, "$module", proxy_dmodule_name); + Printf(wrap_d_file, "%s\n", wrapper_loader_code); + + // Add the wrapper function declarations. + replaceModuleVariables(wrap_dmodule_code); + Printv(wrap_d_file, wrap_dmodule_code, NIL); + + Close(wrap_d_file); + } + + // Generate the D proxy module for the wrapped module. + { + String *filen = NewStringf("%s%s.d", dmodule_directory, proxy_dmodule_name); + File *proxy_d_file = NewFile(filen, "w", SWIG_output_files()); + if (!proxy_d_file) { + FileErrorDisplay(filen); + SWIG_exit(EXIT_FAILURE); + } + Append(filenames_list, Copy(filen)); + Delete(filen); + filen = NULL; + + emitBanner(proxy_d_file); + + Printf(proxy_d_file, "module %s;\n", proxy_dmodule_fq_name); + Printf(proxy_d_file, "\nstatic import %s;\n", wrap_dmodule_fq_name); + Printv(proxy_d_file, global_proxy_imports, NIL); + Printv(proxy_d_file, proxy_dmodule_imports, NIL); + Printv(proxy_d_file, "\n", NIL); + + // Write a D type wrapper class for each SWIG type to the proxy module code. + for (Iterator swig_type = First(unknown_types); swig_type.key; swig_type = Next(swig_type)) { + writeTypeWrapperClass(swig_type.key, swig_type.item); + } + + // Add the proxy functions (and classes, if they are not written to a + // seperate file). + replaceModuleVariables(proxy_dmodule_code); + Printv(proxy_d_file, proxy_dmodule_code, NIL); + + Close(proxy_d_file); + } + + if (upcasts_code) + Printv(f_wrappers, upcasts_code, NIL); + + Printf(f_wrappers, "#ifdef __cplusplus\n"); + Printf(f_wrappers, "}\n"); + Printf(f_wrappers, "#endif\n"); + + // Check for overwriting file problems on filesystems that are case insensitive + Iterator it1; + Iterator it2; + for (it1 = First(filenames_list); it1.item; it1 = Next(it1)) { + String *item1_lower = Swig_string_lower(it1.item); + for (it2 = Next(it1); it2.item; it2 = Next(it2)) { + String *item2_lower = Swig_string_lower(it2.item); + if (it1.item && it2.item) { + if (Strcmp(item1_lower, item2_lower) == 0) { + Swig_warning(WARN_LANG_PORTABILITY_FILENAME, input_file, line_number, + "Portability warning: File %s will be overwritten by %s on case insensitive filesystems such as " + "Windows' FAT32 and NTFS unless the class/module name is renamed\n", it1.item, it2.item); + } + } + Delete(item2_lower); + } + Delete(item1_lower); + } + + Delete(unknown_types); + unknown_types = NULL; + Delete(filenames_list); + filenames_list = NULL; + Delete(wrap_dmodule_name); + wrap_dmodule_name = NULL; + Delete(wrap_dmodule_fq_name); + wrap_dmodule_fq_name = NULL; + Delete(wrap_dmodule_code); + wrap_dmodule_code = NULL; + Delete(proxy_class_imports); + proxy_class_imports = NULL; + Delete(proxy_class_enums_code); + proxy_class_enums_code = NULL; + Delete(proxy_class_body_code); + proxy_class_body_code = NULL; + Delete(proxy_class_epilogue_code); + proxy_class_epilogue_code = NULL; + Delete(proxy_class_code); + proxy_class_code = NULL; + Delete(destructor_call); + destructor_call = NULL; + Delete(proxy_dmodule_name); + proxy_dmodule_name = NULL; + Delete(proxy_dmodule_fq_name); + proxy_dmodule_fq_name = NULL; + Delete(proxy_dmodule_code); + proxy_dmodule_code = NULL; + Delete(proxy_dmodule_imports); + proxy_dmodule_imports = NULL; + Delete(wrap_dmodule_imports); + wrap_dmodule_imports = NULL; + Delete(upcasts_code); + upcasts_code = NULL; + Delete(global_proxy_imports); + global_proxy_imports = NULL; + Delete(wrapper_loader_code); + wrapper_loader_code = NULL; + Delete(wrapper_loader_bind_code); + wrapper_loader_bind_code = NULL; + Delete(wrapper_loader_bind_command); + wrapper_loader_bind_command = NULL; + Delete(dmethods_seq); + dmethods_seq = NULL; + Delete(dmethods_table); + dmethods_table = NULL; + Delete(package); + package = NULL; + Delete(dmodule_directory); + dmodule_directory = NULL; + n_dmethods = 0; + + // Merge all the generated C/C++ code and close the output files. + Dump(f_runtime, f_begin); + Dump(f_header, f_begin); + + if (directorsEnabled()) { + Dump(f_directors, f_begin); + Dump(f_directors_h, f_runtime_h); + + Printf(f_runtime_h, "\n"); + Printf(f_runtime_h, "#endif\n"); + + Close(f_runtime_h); + Delete(f_runtime_h); + f_runtime_h = NULL; + Delete(f_directors); + f_directors = NULL; + Delete(f_directors_h); + f_directors_h = NULL; + } + + Dump(f_wrappers, f_begin); + Wrapper_pretty_print(f_init, f_begin); + Delete(f_header); + Delete(f_wrappers); + Delete(f_init); + Close(f_begin); + Delete(f_runtime); + Delete(f_begin); + + return SWIG_OK; + } + + /* --------------------------------------------------------------------------- + * D::insertDirective() + * --------------------------------------------------------------------------- */ + virtual int insertDirective(Node *n) { + String *code = Getattr(n, "code"); + replaceModuleVariables(code); + return Language::insertDirective(n); + } + + /* --------------------------------------------------------------------------- + * D::pragmaDirective() + * + * Valid Pragmas: + * wrapdmodulecode - text (D code) is copied verbatim to the wrap module + * wrapdmoduleimports - import statements for the wrap module + * + * proxydmodulecode - text (D code) is copied verbatim to the proxy module + * (the main proxy module if in split proxy mode). + * globalproxyimports - import statements inserted into _all_ proxy modules. + * + * wrapperloadercode - D code for loading the wrapper library (is copied to + * the wrap D module). + * wrapperloaderbindcommand - D code for binding a symbol from the wrapper + * library to the declaration in the wrap D module. + * --------------------------------------------------------------------------- */ + virtual int pragmaDirective(Node *n) { + if (!ImportMode) { + String *lang = Getattr(n, "lang"); + String *code = Getattr(n, "name"); + String *value = Getattr(n, "value"); + + if (Strcmp(lang, "d") == 0) { + String *strvalue = NewString(value); + Replaceall(strvalue, "\\\"", "\""); + + if (Strcmp(code, "wrapdmodulecode") == 0) { + Printf(wrap_dmodule_code, "%s\n", strvalue); + } else if (Strcmp(code, "wrapdmoduleimports") == 0) { + replaceImportTypeMacros(strvalue); + Chop(strvalue); + Printf(wrap_dmodule_imports, "%s\n", strvalue); + } else if (Strcmp(code, "proxydmodulecode") == 0) { + Printf(proxy_dmodule_code, "%s\n", strvalue); + } else if (Strcmp(code, "globalproxyimports") == 0) { + replaceImportTypeMacros(strvalue); + Chop(strvalue); + Printf(global_proxy_imports, "%s\n", strvalue); + } else if (Strcmp(code, "wrapperloadercode") == 0) { + Delete(wrapper_loader_code); + wrapper_loader_code = Copy(strvalue); + } else if (Strcmp(code, "wrapperloaderbindcommand") == 0) { + Delete(wrapper_loader_bind_command); + wrapper_loader_bind_command = Copy(strvalue); + } else { + Swig_error(input_file, line_number, "Unrecognized pragma.\n"); + } + Delete(strvalue); + } + } + return Language::pragmaDirective(n); + } + + /* --------------------------------------------------------------------------- + * D::enumDeclaration() + * + * Wraps C/C++ enums as D enums. + * --------------------------------------------------------------------------- */ + virtual int enumDeclaration(Node *n) { + if (ImportMode) + return SWIG_OK; + + if (getCurrentClass() && (cplus_mode != PUBLIC)) + return SWIG_NOWRAP; + + proxy_enum_code = NewString(""); + String *symname = Getattr(n, "sym:name"); + String *typemap_lookup_type = Getattr(n, "name"); + + // Emit the enum declaration. + if (typemap_lookup_type) { + const String *enummodifiers = lookupCodeTypemap(n, "dclassmodifiers", typemap_lookup_type, WARN_D_TYPEMAP_CLASSMOD_UNDEF); + Printv(proxy_enum_code, "\n", enummodifiers, " ", symname, " {\n", NIL); + } else { + // Handle anonymous enums. + Printv(proxy_enum_code, "\nenum {\n", NIL); + } + + // Emit each enum item. + Language::enumDeclaration(n); + + if (!GetFlag(n, "nonempty")) { + // Do not wrap empty enums; the resulting D code would be illegal. + Delete(proxy_enum_code); + return SWIG_NOWRAP; + } + + // Finish the enum. + if (typemap_lookup_type) { + Printv(proxy_enum_code, + lookupCodeTypemap(n, "dcode", typemap_lookup_type, WARN_NONE), // Extra D code + "\n}\n", NIL); + } else { + // Handle anonymous enums. + Printv(proxy_enum_code, "\n}\n", NIL); + } + + Replaceall(proxy_enum_code, "$dclassname", symname); + + const String* imports = + lookupCodeTypemap(n, "dimports", typemap_lookup_type, WARN_NONE); + String* imports_trimmed; + if (Len(imports) > 0) { + imports_trimmed = Copy(imports); + Chop(imports_trimmed); + replaceImportTypeMacros(imports_trimmed); + Printv(imports_trimmed, "\n", NIL); + } else { + imports_trimmed = NewString(""); + } + + if (is_wrapping_class()) { + // Enums defined within the C++ class are written into the proxy + // class. + Printv(proxy_class_imports, imports_trimmed, NIL); + Printv(proxy_class_enums_code, proxy_enum_code, NIL); + } else { + // Write non-anonymous enums to their own file if in split proxy module + // mode. + if (split_proxy_dmodule && typemap_lookup_type) { + assertClassNameValidity(proxy_class_name); + + String *filename = NewStringf("%s%s.d", dmodule_directory, symname); + File *class_file = NewFile(filename, "w", SWIG_output_files()); + if (!class_file) { + FileErrorDisplay(filename); + SWIG_exit(EXIT_FAILURE); + } + Append(filenames_list, Copy(filename)); + Delete(filename); + + emitBanner(class_file); + Printf(class_file, "module %s%s;\n", package, symname); + Printv(class_file, imports_trimmed, NIL); + + Printv(class_file, proxy_enum_code, NIL); + + Close(class_file); + Delete(class_file); + } else { + Printv(proxy_dmodule_imports, imports, NIL); + Printv(proxy_dmodule_code, proxy_enum_code, NIL); + } + } + + Delete(imports_trimmed); + + Delete(proxy_enum_code); + proxy_enum_code = NULL; + return SWIG_OK; + } + + /* --------------------------------------------------------------------------- + * D::enumvalueDeclaration() + * --------------------------------------------------------------------------- */ + virtual int enumvalueDeclaration(Node *n) { + if (getCurrentClass() && (cplus_mode != PUBLIC)) + return SWIG_NOWRAP; + + Swig_require("enumvalueDeclaration", n, "*name", "?value", NIL); + String *value = Getattr(n, "value"); + String *name = Getattr(n, "name"); + Node *parent = parentNode(n); + String *tmpValue; + + // Strange hack from parent method. + // RESEARCH: What is this doing? + if (value) + tmpValue = NewString(value); + else + tmpValue = NewString(name); + // Note that this is used in enumValue() amongst other places + Setattr(n, "value", tmpValue); + + String *proxy_name = Getattr(n, "sym:name"); + + // Emit the enum item. + { + if (!GetFlag(n, "firstenumitem")) + Printf(proxy_enum_code, ",\n"); + + Printf(proxy_enum_code, " %s", proxy_name); + + // Check for the %dconstvalue feature + String *value = Getattr(n, "feature:d:constvalue"); + + // Note that in D, enum values must be compile-time constants. Thus, + // %dnativeconst(0) (getting the enum values at runtime) is not supported. + value = value ? value : Getattr(n, "enumvalue"); + if (value) { + Printf(proxy_enum_code, " = %s", value); + } + + // Keep track that the currently processed enum has at least one value. + SetFlag(parent, "nonempty"); + } + + Delete(tmpValue); + Swig_restore(n); + return SWIG_OK; + } + + /* --------------------------------------------------------------------------- + * D::memberfunctionHandler() + * --------------------------------------------------------------------------- */ + virtual int memberfunctionHandler(Node *n) { + Language::memberfunctionHandler(n); + + String *overloaded_name = getOverloadedName(n); + String *intermediary_function_name = + Swig_name_member(NSPACE_TODO,proxy_class_name, overloaded_name); + Setattr(n, "imfuncname", intermediary_function_name); + + String *proxy_func_name = Getattr(n, "sym:name"); + Setattr(n, "proxyfuncname", proxy_func_name); + if (split_proxy_dmodule && + Len(Getattr(n, "parms")) == 0 && + Strncmp(proxy_func_name, package, Len(proxy_func_name)) == 0) { + // If we are in split proxy mode and the function is named like the + // target package, the D compiler is unable to resolve the ambiguity + // between the package name and an argument-less function call. + Swig_warning(WARN_D_NAME_COLLISION, input_file, line_number, + "%s::%s might collide with the package name, consider using %%rename to resolve the ambiguity.\n", + proxy_class_name, proxy_func_name); + } + + writeProxyClassFunction(n); + + Delete(overloaded_name); + + // For each function, look if we have to alias in the parent class function + // for the overload resolution process to work as expected from C++ + // (http://www.digitalmars.com/d/2.0/function.html#function-inheritance). + // For multiple overloads, only emit the alias directive once (for the + // last method, »sym:nextSibling« is null then). + // Smart pointer classes do not mirror the inheritance hierarchy of the + // underlying types, so aliasing the base class methods in is not required + // for them. + // DMD BUG: We have to emit the alias after the last function becasue + // taking a delegate in the overload checking code fails otherwise + // (http://d.puremagic.com/issues/show_bug.cgi?id=4860). + if (!Getattr(n, "sym:nextSibling") && !is_smart_pointer() && + !areAllOverloadsOverridden(n)) { + String *name = Getattr(n, "sym:name"); + Printf(proxy_class_body_code, "\nalias $dbaseclass.%s %s;\n", name, name); + } + return SWIG_OK; + } + + /* --------------------------------------------------------------------------- + * D::staticmemberfunctionHandler() + * --------------------------------------------------------------------------- */ + virtual int staticmemberfunctionHandler(Node *n) { + static_flag = true; + + Language::staticmemberfunctionHandler(n); + + String *overloaded_name = getOverloadedName(n); + String *intermediary_function_name = + Swig_name_member(NSPACE_TODO,proxy_class_name, overloaded_name); + Setattr(n, "proxyfuncname", Getattr(n, "sym:name")); + Setattr(n, "imfuncname", intermediary_function_name); + writeProxyClassFunction(n); + Delete(overloaded_name); + + static_flag = false; + return SWIG_OK; + } + + /* --------------------------------------------------------------------------- + * D::globalvariableHandler() + * --------------------------------------------------------------------------- */ + virtual int globalvariableHandler(Node *n) { + variable_name = Getattr(n, "sym:name"); + global_variable_flag = true; + int ret = Language::globalvariableHandler(n); + global_variable_flag = false; + + return ret; + } + + /* --------------------------------------------------------------------------- + * D::membervariableHandler() + * --------------------------------------------------------------------------- */ + virtual int membervariableHandler(Node *n) { + variable_name = Getattr(n, "sym:name"); + wrapping_member_flag = true; + variable_wrapper_flag = true; + Language::membervariableHandler(n); + wrapping_member_flag = false; + variable_wrapper_flag = false; + + return SWIG_OK; + } + + /* --------------------------------------------------------------------------- + * D::staticmembervariableHandler() + * --------------------------------------------------------------------------- */ + virtual int staticmembervariableHandler(Node *n) { + if (GetFlag(n, "feature:d:nativeconst") != 1) { + Delattr(n, "value"); + } + + variable_name = Getattr(n, "sym:name"); + wrapping_member_flag = true; + static_flag = true; + Language::staticmembervariableHandler(n); + wrapping_member_flag = false; + static_flag = false; + + return SWIG_OK; + } + + /* --------------------------------------------------------------------------- + * D::memberconstantHandler() + * --------------------------------------------------------------------------- */ + virtual int memberconstantHandler(Node *n) { + variable_name = Getattr(n, "sym:name"); + wrapping_member_flag = true; + Language::memberconstantHandler(n); + wrapping_member_flag = false; + return SWIG_OK; + } + + /* --------------------------------------------------------------------------- + * D::constructorHandler() + * --------------------------------------------------------------------------- */ + virtual int constructorHandler(Node *n) { + Language::constructorHandler(n); + + // Wrappers not wanted for some methods where the parameters cannot be overloaded in D. + if (Getattr(n, "overload:ignore")) { + return SWIG_OK; + } + + ParmList *l = Getattr(n, "parms"); + String *tm; + String *proxy_constructor_code = NewString(""); + + // Holds code for the constructor helper method generated only when the din + // typemap has code in the pre or post attributes. + String *helper_code = NewString(""); + String *helper_args = NewString(""); + String *pre_code = NewString(""); + String *post_code = NewString(""); + String *terminator_code = NewString(""); + NewString(""); + + String *overloaded_name = getOverloadedName(n); + String *mangled_overname = Swig_name_construct(NSPACE_TODO,overloaded_name); + String *imcall = NewString(""); + + const String *methodmods = Getattr(n, "feature:d:methodmodifiers"); + methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string); + + // Typemaps were attached earlier to the node, get the return type of the + // call to the C++ constructor wrapper. + const String *wrapper_return_type = lookupDTypemap(n, "dwtype", true); + + String *dwtypeout = Getattr(n, "tmap:dwtype:out"); + if (dwtypeout) { + // The type in the dwtype typemap's out attribute overrides the type in + // the typemap itself. + wrapper_return_type = dwtypeout; + } + + Printf(proxy_constructor_code, "\n%s this(", methodmods); + Printf(helper_code, "static private %s SwigConstruct%s(", + wrapper_return_type, proxy_class_name); + + Printv(imcall, wrap_dmodule_fq_name, ".", mangled_overname, "(", NIL); + + /* Attach the non-standard typemaps to the parameter list */ + Swig_typemap_attach_parms("in", l, NULL); + Swig_typemap_attach_parms("dptype", l, NULL); + Swig_typemap_attach_parms("din", l, NULL); + + emit_mark_varargs(l); + + int gencomma = 0; + + /* Output each parameter */ + Parm *p = l; + for (unsigned int i = 0; p; i++) { + if (checkAttribute(p, "varargs:ignore", "1")) { + // Skip ignored varargs. + p = nextSibling(p); + continue; + } + + if (checkAttribute(p, "tmap:in:numinputs", "0")) { + // Skip ignored parameters. + p = Getattr(p, "tmap:in:next"); + continue; + } + + SwigType *pt = Getattr(p, "type"); + String *param_type = NewString(""); + + // Get the D parameter type. + if ((tm = lookupDTypemap(p, "dptype", true))) { + const String *inattributes = Getattr(p, "tmap:dptype:inattributes"); + Printf(param_type, "%s%s", inattributes ? inattributes : empty_string, tm); + } else { + Swig_warning(WARN_D_TYPEMAP_DPTYPE_UNDEF, input_file, line_number, + "No dptype typemap defined for %s\n", SwigType_str(pt, 0)); + } + + if (gencomma) + Printf(imcall, ", "); + + String *arg = makeParameterName(n, p, i, false); + String *parmtype = 0; + + // Get the D code to convert the parameter value to the type used in the + // wrapper D module. + if ((tm = lookupDTypemap(p, "din"))) { + Replaceall(tm, "$dinput", arg); + String *pre = Getattr(p, "tmap:din:pre"); + if (pre) { + replaceClassname(pre, pt); + Replaceall(pre, "$dinput", arg); + if (Len(pre_code) > 0) + Printf(pre_code, "\n"); + Printv(pre_code, pre, NIL); + } + String *post = Getattr(p, "tmap:din:post"); + if (post) { + replaceClassname(post, pt); + Replaceall(post, "$dinput", arg); + if (Len(post_code) > 0) + Printf(post_code, "\n"); + Printv(post_code, post, NIL); + } + String *terminator = Getattr(p, "tmap:din:terminator"); + if (terminator) { + replaceClassname(terminator, pt); + Replaceall(terminator, "$dinput", arg); + if (Len(terminator_code) > 0) + Insert(terminator_code, 0, "\n"); + Insert(terminator_code, 0, terminator); + } + parmtype = Getattr(p, "tmap:din:parmtype"); + if (parmtype) + Replaceall(parmtype, "$dinput", arg); + Printv(imcall, tm, NIL); + } else { + Swig_warning(WARN_D_TYPEMAP_DIN_UNDEF, input_file, line_number, + "No din typemap defined for %s\n", SwigType_str(pt, 0)); + } + + /* Add parameter to proxy function */ + if (gencomma) { + Printf(proxy_constructor_code, ", "); + Printf(helper_code, ", "); + Printf(helper_args, ", "); + } + Printf(proxy_constructor_code, "%s %s", param_type, arg); + Printf(helper_code, "%s %s", param_type, arg); + Printf(helper_args, "%s", parmtype ? parmtype : arg); + ++gencomma; + + Delete(parmtype); + Delete(arg); + Delete(param_type); + p = Getattr(p, "tmap:in:next"); + } + + Printf(imcall, ")"); + + Printf(proxy_constructor_code, ")"); + Printf(helper_code, ")"); + + // Insert the dconstructor typemap (replacing $directorconnect as needed). + Hash *attributes = NewHash(); + String *construct_tm = Copy(lookupCodeTypemap(n, "dconstructor", + Getattr(n, "name"), WARN_D_TYPEMAP_DCONSTRUCTOR_UNDEF, attributes)); + if (construct_tm) { + const bool use_director = (parentNode(n) && Swig_directorclass(n)); + if (!use_director) { + Replaceall(construct_tm, "$directorconnect", ""); + } else { + String *connect_attr = Getattr(attributes, "tmap:dconstructor:directorconnect"); + + if (connect_attr) { + Replaceall(construct_tm, "$directorconnect", connect_attr); + } else { + Swig_warning(WARN_D_NO_DIRECTORCONNECT_ATTR, input_file, line_number, + "\"directorconnect\" attribute missing in %s \"dconstructor\" typemap.\n", + Getattr(n, "name")); + Replaceall(construct_tm, "$directorconnect", ""); + } + } + + Printv(proxy_constructor_code, " ", construct_tm, NIL); + } + + replaceExcode(n, proxy_constructor_code, "dconstructor", attributes); + + bool is_pre_code = Len(pre_code) > 0; + bool is_post_code = Len(post_code) > 0; + bool is_terminator_code = Len(terminator_code) > 0; + if (is_pre_code || is_post_code || is_terminator_code) { + Printf(helper_code, " {\n"); + if (is_pre_code) { + Printv(helper_code, pre_code, "\n", NIL); + } + if (is_post_code) { + Printf(helper_code, " try {\n"); + Printv(helper_code, " return ", imcall, ";\n", NIL); + Printv(helper_code, " } finally {\n", post_code, "\n }", NIL); + } else { + Printv(helper_code, " return ", imcall, ";", NIL); + } + if (is_terminator_code) { + Printv(helper_code, "\n", terminator_code, NIL); + } + Printf(helper_code, "\n}\n"); + String *helper_name = NewStringf("%s.SwigConstruct%s(%s)", + proxy_class_name, proxy_class_name, helper_args); + Replaceall(proxy_constructor_code, "$wcall", helper_name); + Delete(helper_name); + } else { + Replaceall(proxy_constructor_code, "$wcall", imcall); + } + + Printv(proxy_class_body_code, proxy_constructor_code, "\n", NIL); + + Delete(helper_args); + Delete(pre_code); + Delete(post_code); + Delete(terminator_code); + Delete(construct_tm); + Delete(attributes); + Delete(overloaded_name); + Delete(imcall); + + return SWIG_OK; + } + + /* --------------------------------------------------------------------------- + * D::destructorHandler() + * --------------------------------------------------------------------------- */ + virtual int destructorHandler(Node *n) { + Language::destructorHandler(n); + String *symname = Getattr(n, "sym:name"); + Printv(destructor_call, wrap_dmodule_fq_name, ".", Swig_name_destroy(NSPACE_TODO,symname), "(cast(void*)swigCPtr)", NIL); + return SWIG_OK; + } + + /* --------------------------------------------------------------------------- + * D::classHandler() + * --------------------------------------------------------------------------- */ + virtual int classHandler(Node *n) { + File *class_file = NULL; + + proxy_class_name = Copy(Getattr(n, "sym:name")); + + if (!addSymbol(proxy_class_name, n)) { + return SWIG_ERROR; + } + + assertClassNameValidity(proxy_class_name); + + if (split_proxy_dmodule) { + String *filename = NewStringf("%s%s.d", dmodule_directory, proxy_class_name); + class_file = NewFile(filename, "w", SWIG_output_files()); + if (!class_file) { + FileErrorDisplay(filename); + SWIG_exit(EXIT_FAILURE); + } + Append(filenames_list, Copy(filename)); + Delete(filename); + + emitBanner(class_file); + Printf(class_file, "module %s%s;\n", package, proxy_class_name); + Printf(class_file, "\nstatic import %s;\n", wrap_dmodule_fq_name); + } + + Clear(proxy_class_imports); + Clear(proxy_class_enums_code); + Clear(proxy_class_body_code); + Clear(proxy_class_epilogue_code); + Clear(proxy_class_code); + Clear(destructor_call); + + + Language::classHandler(n); + + + writeProxyClassAndUpcasts(n); + writeDirectorConnectWrapper(n); + + Replaceall(proxy_class_code, "$dclassname", proxy_class_name); + + if (split_proxy_dmodule) { + Printv(class_file, global_proxy_imports, NIL); + Printv(class_file, proxy_class_imports, NIL); + + replaceModuleVariables(proxy_class_code); + Printv(class_file, proxy_class_code, NIL); + + Close(class_file); + Delete(class_file); + } else { + Printv(proxy_dmodule_imports, proxy_class_imports, NIL); + Printv(proxy_dmodule_code, proxy_class_code, NIL); + } + + Delete(proxy_class_name); + proxy_class_name = NULL; + + return SWIG_OK; + } + + /* --------------------------------------------------------------------------- + * D::constantWrapper() + * + * Used for wrapping constants declared by #define or %constant and also for + * (primitive) static member constants initialised inline. + * + * If the %dnativeconst feature is used, the C/C++ constant value is used to + * initialize a D »const«. If not, a »getter« method is generated which + * retrieves the value via a call to the C wrapper. However, if there is a + * %dconstvalue specified, it overrides all other settings. + * --------------------------------------------------------------------------- */ + virtual int constantWrapper(Node *n) { + String *symname = Getattr(n, "sym:name"); + if (!addSymbol(symname, n)) + return SWIG_ERROR; + + // The %dnativeconst feature determines if a D const or a getter function is + // created. + if (GetFlag(n, "feature:d:nativeconst") != 1) { + // Default constant handling will work with any type of C constant. It + // generates a getter function (which is the same as a read only property + // in D) which retrieves the value via by calling the C wrapper. + // Note that this is only called for global constants, static member + // constants are already handeled in staticmemberfunctionHandler(). + + Swig_save("constantWrapper", n, "value", NIL); + + // Add the stripped quotes back in. + String *old_value = Getattr(n, "value"); + SwigType *t = Getattr(n, "type"); + if (SwigType_type(t) == T_STRING) { + Setattr(n, "value", NewStringf("\"%s\"", old_value)); + Delete(old_value); + } else if (SwigType_type(t) == T_CHAR) { + Setattr(n, "value", NewStringf("\'%s\'", old_value)); + Delete(old_value); + } + + int result = globalvariableHandler(n); + + Swig_restore(n); + return result; + } + + String *constants_code = NewString(""); + SwigType *t = Getattr(n, "type"); + ParmList *l = Getattr(n, "parms"); + + // Attach the non-standard typemaps to the parameter list. + Swig_typemap_attach_parms("dptype", l, NULL); + + // Get D return type. + String *return_type = NewString(""); + String *tm; + if ((tm = lookupDTypemap(n, "dptype"))) { + String *dptypeout = Getattr(n, "tmap:dptype:out"); + if (dptypeout) { + // The type in the out attribute of the typemap overrides the type + // in the dptype typemap. + tm = dptypeout; + replaceClassname(tm, t); + } + Printf(return_type, "%s", tm); + } else { + Swig_warning(WARN_D_TYPEMAP_DPTYPE_UNDEF, input_file, line_number, + "No dptype typemap defined for %s\n", SwigType_str(t, 0)); + } + + const String *itemname = wrapping_member_flag ? variable_name : symname; + + String *attributes = Getattr(n, "feature:d:methodmodifiers"); + if (attributes) { + attributes = Copy(attributes); + } else { + attributes = Copy(is_public(n) ? public_string : protected_string); + } + + if (d_version == 1) { + if (static_flag) { + Printv(attributes, " static", NIL); + } + Printf(constants_code, "\n%s const %s %s = ", attributes, return_type, itemname); + } else { + Printf(constants_code, "\n%s enum %s %s = ", attributes, return_type, itemname); + } + Delete(attributes); + + // Retrive the override value set via %dconstvalue, if any. + String *override_value = Getattr(n, "feature:d:constvalue"); + if (override_value) { + Printf(constants_code, "%s;\n", override_value); + } else { + // Just take the value from the C definition and hope it compiles in D. + String* value = Getattr(n, "wrappedasconstant") ? + Getattr(n, "staticmembervariableHandler:value") : Getattr(n, "value"); + + // Add the stripped quotes back in. + if (SwigType_type(t) == T_STRING) { + Printf(constants_code, "\"%s\";\n", value); + } else if (SwigType_type(t) == T_CHAR) { + Printf(constants_code, "\'%s\';\n", value); + } else { + Printf(constants_code, "%s;\n", value); + } + } + + // Emit the generated code to appropriate place. + if (wrapping_member_flag) { + Printv(proxy_class_body_code, constants_code, NIL); + } else { + Printv(proxy_dmodule_code, constants_code, NIL); + } + + // Cleanup. + Delete(return_type); + Delete(constants_code); + + return SWIG_OK; + } + + /* --------------------------------------------------------------------------- + * D::functionWrapper() + * + * Generates the C wrapper code for a function and the corresponding + * declaration in the wrap D module. + * --------------------------------------------------------------------------- */ + virtual int functionWrapper(Node *n) { + String *symname = Getattr(n, "sym:name"); + SwigType *t = Getattr(n, "type"); + ParmList *l = Getattr(n, "parms"); + String *tm; + Parm *p; + int i; + String *c_return_type = NewString(""); + String *im_return_type = NewString(""); + String *cleanup = NewString(""); + String *outarg = NewString(""); + String *body = NewString(""); + int num_arguments = 0; + int num_required = 0; + bool is_void_return; + String *overloaded_name = getOverloadedName(n); + + if (!Getattr(n, "sym:overloaded")) { + if (!addSymbol(Getattr(n, "sym:name"), n)) + return SWIG_ERROR; + } + + // A new wrapper function object + Wrapper *f = NewWrapper(); + + // Make a wrapper name for this function + String *wname = Swig_name_wrapper(overloaded_name); + + /* Attach the non-standard typemaps to the parameter list. */ + Swig_typemap_attach_parms("cwtype", l, f); + Swig_typemap_attach_parms("dwtype", l, f); + + /* Get return types */ + if ((tm = lookupDTypemap(n, "cwtype"))) { + String *cwtypeout = Getattr(n, "tmap:cwtype:out"); + if (cwtypeout) { + // The type in the cwtype typemap's out attribute overrides the type in + // the typemap itself. + tm = cwtypeout; + } + Printf(c_return_type, "%s", tm); + } else { + Swig_warning(WARN_D_TYPEMAP_CWTYPE_UNDEF, input_file, line_number, + "No cwtype typemap defined for %s\n", SwigType_str(t, 0)); + } + + if ((tm = lookupDTypemap(n, "dwtype"))) { + String *dwtypeout = Getattr(n, "tmap:dwtype:out"); + if (dwtypeout) { + // The type in the dwtype typemap's out attribute overrides the type in + // the typemap itself. + tm = dwtypeout; + } + Printf(im_return_type, "%s", tm); + } else { + Swig_warning(WARN_D_TYPEMAP_DWTYPE_UNDEF, input_file, line_number, "No dwtype typemap defined for %s\n", SwigType_str(t, 0)); + } + + is_void_return = (Cmp(c_return_type, "void") == 0); + if (!is_void_return) + Wrapper_add_localv(f, "jresult", c_return_type, "jresult", NIL); + + Printv(f->def, " SWIGEXPORT ", c_return_type, " SWIGSTDCALL ", wname, "(", NIL); + + // Emit all of the local variables for holding arguments. + emit_parameter_variables(l, f); + + /* Attach the standard typemaps */ + emit_attach_parmmaps(l, f); + + // Parameter overloading + Setattr(n, "wrap:parms", l); + Setattr(n, "wrap:name", wname); + + // Wrappers not wanted for some methods where the parameters cannot be overloaded in D + if (Getattr(n, "sym:overloaded")) { + // Emit warnings for the few cases that can't be overloaded in D and give up on generating wrapper + Swig_overload_check(n); + if (Getattr(n, "overload:ignore")) + return SWIG_OK; + } + + // Collect the parameter list for the wrap D module declaration of the + // generated wrapper function. + String *wrap_dmodule_parameters = NewString("("); + + /* Get number of required and total arguments */ + num_arguments = emit_num_arguments(l); + num_required = emit_num_required(l); + int gencomma = 0; + + // Now walk the function parameter list and generate code to get arguments + for (i = 0, p = l; i < num_arguments; i++) { + + while (checkAttribute(p, "tmap:in:numinputs", "0")) { + p = Getattr(p, "tmap:in:next"); + } + + SwigType *pt = Getattr(p, "type"); + String *ln = Getattr(p, "lname"); + String *im_param_type = NewString(""); + String *c_param_type = NewString(""); + String *arg = NewString(""); + + Printf(arg, "j%s", ln); + + /* Get the cwtype types of the parameter */ + if ((tm = lookupDTypemap(p, "cwtype", true))) { + Printv(c_param_type, tm, NIL); + } else { + Swig_warning(WARN_D_TYPEMAP_CWTYPE_UNDEF, input_file, line_number, "No cwtype typemap defined for %s\n", SwigType_str(pt, 0)); + } + + /* Get the intermediary class parameter types of the parameter */ + if ((tm = lookupDTypemap(p, "dwtype", true))) { + const String *inattributes = Getattr(p, "tmap:dwtype:inattributes"); + Printf(im_param_type, "%s%s", inattributes ? inattributes : empty_string, tm); + } else { + Swig_warning(WARN_D_TYPEMAP_DWTYPE_UNDEF, input_file, line_number, "No dwtype typemap defined for %s\n", SwigType_str(pt, 0)); + } + + /* Add parameter to intermediary class method */ + if (gencomma) + Printf(wrap_dmodule_parameters, ", "); + Printf(wrap_dmodule_parameters, "%s %s", im_param_type, arg); + + // Add parameter to C function + Printv(f->def, gencomma ? ", " : "", c_param_type, " ", arg, NIL); + + gencomma = 1; + + // Get typemap for this argument + if ((tm = Getattr(p, "tmap:in"))) { + canThrow(n, "in", p); + Replaceall(tm, "$input", arg); + Setattr(p, "emit:input", arg); + Printf(f->code, "%s\n", tm); + p = Getattr(p, "tmap:in:next"); + } else { + Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0)); + p = nextSibling(p); + } + Delete(im_param_type); + Delete(c_param_type); + Delete(arg); + } + + /* Insert constraint checking code */ + for (p = l; p;) { + if ((tm = Getattr(p, "tmap:check"))) { + canThrow(n, "check", p); + Replaceall(tm, "$input", Getattr(p, "emit:input")); + Printv(f->code, tm, "\n", NIL); + p = Getattr(p, "tmap:check:next"); + } else { + p = nextSibling(p); + } + } + + /* Insert cleanup code */ + for (p = l; p;) { + if ((tm = Getattr(p, "tmap:freearg"))) { + canThrow(n, "freearg", p); + Replaceall(tm, "$input", Getattr(p, "emit:input")); + Printv(cleanup, tm, "\n", NIL); + p = Getattr(p, "tmap:freearg:next"); + } else { + p = nextSibling(p); + } + } + + /* Insert argument output code */ + for (p = l; p;) { + if ((tm = Getattr(p, "tmap:argout"))) { + canThrow(n, "argout", p); + Replaceall(tm, "$result", "jresult"); + Replaceall(tm, "$input", Getattr(p, "emit:input")); + Printv(outarg, tm, "\n", NIL); + p = Getattr(p, "tmap:argout:next"); + } else { + p = nextSibling(p); + } + } + + // Look for usage of throws typemap and the canthrow flag + ParmList *throw_parm_list = NULL; + if ((throw_parm_list = Getattr(n, "catchlist"))) { + Swig_typemap_attach_parms("throws", throw_parm_list, f); + for (p = throw_parm_list; p; p = nextSibling(p)) { + if ((tm = Getattr(p, "tmap:throws"))) { + canThrow(n, "throws", p); + } + } + } + + String *null_attribute = 0; + // Now write code to make the function call + if (!native_function_flag) { + if (Cmp(nodeType(n), "constant") == 0) { + // Wrapping a constant hack + Swig_save("functionWrapper", n, "wrap:action", NIL); + + // below based on Swig_VargetToFunction() + SwigType *ty = Swig_wrapped_var_type(Getattr(n, "type"), use_naturalvar_mode(n)); + Setattr(n, "wrap:action", NewStringf("result = (%s) %s;", SwigType_lstr(ty, 0), Getattr(n, "value"))); + } + + Swig_director_emit_dynamic_cast(n, f); + String *actioncode = emit_action(n); + + if (Cmp(nodeType(n), "constant") == 0) + Swig_restore(n); + + /* Return value if necessary */ + if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) { + canThrow(n, "out", n); + Replaceall(tm, "$result", "jresult"); + + if (GetFlag(n, "feature:new")) + Replaceall(tm, "$owner", "1"); + else + Replaceall(tm, "$owner", "0"); + + Printf(f->code, "%s", tm); + null_attribute = Getattr(n, "tmap:out:null"); + if (Len(tm)) + Printf(f->code, "\n"); + } else { + Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(t, 0), Getattr(n, "name")); + } + emit_return_variable(n, t, f); + } + + /* Output argument output code */ + Printv(f->code, outarg, NIL); + + /* Output cleanup code */ + Printv(f->code, cleanup, NIL); + + /* Look to see if there is any newfree cleanup code */ + if (GetFlag(n, "feature:new")) { + if ((tm = Swig_typemap_lookup("newfree", n, "result", 0))) { + canThrow(n, "newfree", n); + Printf(f->code, "%s\n", tm); + } + } + + /* See if there is any return cleanup code */ + if (!native_function_flag) { + if ((tm = Swig_typemap_lookup("ret", n, "result", 0))) { + canThrow(n, "ret", n); + Printf(f->code, "%s\n", tm); + } + } + + // Complete D wrapper parameter list and emit the declaration/binding code. + Printv(wrap_dmodule_parameters, ")", NIL); + writeWrapDModuleFunction(overloaded_name, im_return_type, + wrap_dmodule_parameters, wname); + Delete(wrap_dmodule_parameters); + + // Finish C function header. + Printf(f->def, ") {"); + + if (!is_void_return) + Printv(f->code, " return jresult;\n", NIL); + Printf(f->code, "}\n"); + + /* Substitute the cleanup code */ + Replaceall(f->code, "$cleanup", cleanup); + + /* Substitute the function name */ + Replaceall(f->code, "$symname", symname); + + /* Contract macro modification */ + if (Replaceall(f->code, "SWIG_contract_assert(", "SWIG_contract_assert($null, ") > 0) { + Setattr(n, "d:canthrow", "1"); + } + + if (!null_attribute) + Replaceall(f->code, "$null", "0"); + else + Replaceall(f->code, "$null", null_attribute); + + /* Dump the function out */ + if (!native_function_flag) { + Wrapper_print(f, f_wrappers); + + // Handle %exception which sets the canthrow attribute. + if (Getattr(n, "feature:except:canthrow")) { + Setattr(n, "d:canthrow", "1"); + } + + // A very simple check (it is not foolproof) to assist typemap writers + // with setting the correct features when the want to throw D exceptions + // from C++ code. It checks for the common methods which set + // a pending D exception and issues a warning if one of them has been found + // in the typemap, but the »canthrow« attribute/feature is not set. + if (!Getattr(n, "d:canthrow")) { + if (Strstr(f->code, "SWIG_exception")) { + Swig_warning(WARN_D_CANTHROW_MISSING, input_file, line_number, + "C code contains a call to SWIG_exception and D code does not handle pending exceptions via the canthrow attribute.\n"); + } else if (Strstr(f->code, "SWIG_DSetPendingException")) { + Swig_warning(WARN_D_CANTHROW_MISSING, input_file, line_number, + "C code contains a call to a SWIG_DSetPendingException method and D code does not handle pending exceptions via the canthrow attribute.\n"); + } + } + } + + // If we are not processing an enum or constant, and we were not generating + // a wrapper function which will be accessed via a proxy class, write a + // function to the proxy D module. + if (!is_wrapping_class()) { + writeProxyDModuleFunction(n); + } + + // If we are processing a public member variable, write the property-style + // member function to the proxy class. + if (wrapping_member_flag) { + Setattr(n, "proxyfuncname", variable_name); + Setattr(n, "imfuncname", symname); + + writeProxyClassFunction(n); + } + + Delete(c_return_type); + Delete(im_return_type); + Delete(cleanup); + Delete(outarg); + Delete(body); + Delete(overloaded_name); + DelWrapper(f); + return SWIG_OK; + } + + /* --------------------------------------------------------------------------- + * D::nativeWrapper() + * --------------------------------------------------------------------------- */ + virtual int nativeWrapper(Node *n) { + String *wrapname = Getattr(n, "wrap:name"); + + if (!addSymbol(wrapname, n)) + return SWIG_ERROR; + + if (Getattr(n, "type")) { + Swig_save("nativeWrapper", n, "name", NIL); + Setattr(n, "name", wrapname); + native_function_flag = true; + functionWrapper(n); + Swig_restore(n); + native_function_flag = false; + } else { + Swig_error(input_file, line_number, "No return type for %%native method %s.\n", Getattr(n, "wrap:name")); + } + + return SWIG_OK; + } + + /* --------------------------------------------------------------------------- + * D::classDirector() + * --------------------------------------------------------------------------- */ + virtual int classDirector(Node *n) { + proxy_class_name = NewString(Getattr(n, "sym:name")); + + int success = Language::classDirector(n); + + Delete(proxy_class_name); + proxy_class_name = NULL; + + return success; + } + + + /* --------------------------------------------------------------------------- + * D::classDirectorInit() + * --------------------------------------------------------------------------- */ + virtual int classDirectorInit(Node *n) { + Delete(director_ctor_code); + director_ctor_code = NewString("$director_new"); + + // Write C++ director class declaration, for example: + // class SwigDirector_myclass : public myclass, public Swig::Director { + String *classname = Swig_class_name(n); + String *directorname = NewStringf("SwigDirector_%s", classname); + String *declaration = Swig_class_declaration(n, directorname); + const String *base = Getattr(n, "classtype"); + + Printf(f_directors_h, + "%s : public %s, public Swig::Director {\n", declaration, base); + Printf(f_directors_h, "\npublic:\n"); + + Delete(declaration); + Delete(directorname); + Delete(classname); + + // Stash for later. + Setattr(n, "director:ctor", NewString("Swig::Director()")); + + // Keep track of the director methods for this class. + first_class_dmethod = curr_class_dmethod = n_dmethods; + + director_callback_typedefs = NewString(""); + director_callback_pointers = NewString(""); + director_dcallbacks_code = NewString(""); + + return Language::classDirectorInit(n); + } + + /* --------------------------------------------------------------------------- + * D::classDirectorMethod() + * + * Emit a virtual director method to pass a method call on to the + * underlying D object. + * --------------------------------------------------------------------------- */ + virtual int classDirectorMethod(Node *n, Node *parent, String *super) { + String *empty_str = NewString(""); + String *classname = Getattr(parent, "sym:name"); + String *c_classname = Getattr(parent, "name"); + String *name = Getattr(n, "name"); + String *symname = Getattr(n, "sym:name"); + SwigType *type = Getattr(n, "type"); + SwigType *returntype = Getattr(n, "returntype"); + String *overloaded_name = getOverloadedName(n); + String *storage = Getattr(n, "storage"); + String *value = Getattr(n, "value"); + String *decl = Getattr(n, "decl"); + String *declaration = NewString(""); + String *tm; + Parm *p; + int i; + Wrapper *w = NewWrapper(); + ParmList *l = Getattr(n, "parms"); + bool is_void = !(Cmp(returntype, "void")); + String *qualified_return = NewString(""); + bool pure_virtual = (!(Cmp(storage, "virtual")) && !(Cmp(value, "0"))); + int status = SWIG_OK; + bool output_director = true; + String *dirclassname = getDirectorClassName(parent); + String *qualified_name = NewStringf("%s::%s", dirclassname, name); + SwigType *c_ret_type = NULL; + String *dcallback_call_args = NewString(""); + String *imclass_dmethod; + String *callback_typedef_parms = NewString(""); + String *delegate_parms = NewString(""); + String *proxy_method_param_list = NewString(""); + String *proxy_callback_return_type = NewString(""); + String *callback_def = NewString(""); + String *callback_code = NewString(""); + String *imcall_args = NewString(""); + int gencomma = 0; + bool ignored_method = GetFlag(n, "feature:ignore") ? true : false; + + // Kludge Alert: functionWrapper sets sym:overload properly, but it + // isn't at this point, so we have to manufacture it ourselves. At least + // we're consistent with the sym:overload name in functionWrapper. (?? when + // does the overloaded method name get set?) + + imclass_dmethod = NewStringf("SwigDirector_%s", Swig_name_member(NSPACE_TODO,classname, overloaded_name)); + + if (returntype) { + qualified_return = SwigType_rcaststr(returntype, "c_result"); + + if (!is_void && !ignored_method) { + if (!SwigType_isclass(returntype)) { + if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) { + String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0)); + Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL); + Delete(construct_result); + } else { + String *base_typename = SwigType_base(returntype); + String *resolved_typename = SwigType_typedef_resolve_all(base_typename); + Symtab *symtab = Getattr(n, "sym:symtab"); + Node *typenode = Swig_symbol_clookup(resolved_typename, symtab); + + if (SwigType_ispointer(returntype) || (typenode && Getattr(typenode, "abstract"))) { + /* initialize pointers to something sane. Same for abstract + classes when a reference is returned. */ + Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL); + } else { + /* If returning a reference, initialize the pointer to a sane + default - if a D exception occurs, then the pointer returns + something other than a NULL-initialized reference. */ + String *non_ref_type = Copy(returntype); + + /* Remove reference and const qualifiers */ + Replaceall(non_ref_type, "r.", ""); + Replaceall(non_ref_type, "q(const).", ""); + Wrapper_add_localv(w, "result_default", "static", SwigType_str(non_ref_type, "result_default"), "=", SwigType_str(non_ref_type, "()"), NIL); + Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= &result_default", NIL); + + Delete(non_ref_type); + } + + Delete(base_typename); + Delete(resolved_typename); + } + } else { + SwigType *vt; + + vt = cplus_value_type(returntype); + if (!vt) { + Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), NIL); + } else { + Wrapper_add_localv(w, "c_result", SwigType_lstr(vt, "c_result"), NIL); + Delete(vt); + } + } + } + + /* Create the intermediate class wrapper */ + Parm *tp = NewParm(returntype, empty_str, n); + + tm = lookupDTypemap(tp, "dwtype"); + if (tm) { + String *dwtypeout = Getattr(tp, "tmap:dwtype:out"); + if (dwtypeout) { + // The type in the dwtype typemap's out attribute overrides the type + // in the typemap. + tm = dwtypeout; + } + Printf(callback_def, "\nprivate extern(C) %s swigDirectorCallback_%s_%s(void* dObject", tm, classname, overloaded_name); + Printv(proxy_callback_return_type, tm, NIL); + } else { + Swig_warning(WARN_D_TYPEMAP_DWTYPE_UNDEF, input_file, line_number, + "No dwtype typemap defined for %s\n", SwigType_str(returntype, 0)); + } + + Parm *retpm = NewParm(returntype, empty_str, n); + + if ((c_ret_type = Swig_typemap_lookup("cwtype", retpm, "", 0))) { + if (!is_void && !ignored_method) { + String *jretval_decl = NewStringf("%s jresult", c_ret_type); + Wrapper_add_localv(w, "jresult", jretval_decl, "= 0", NIL); + Delete(jretval_decl); + } + } else { + Swig_warning(WARN_D_TYPEMAP_CWTYPE_UNDEF, input_file, line_number, + "No cwtype typemap defined for %s for use in %s::%s (skipping director method)\n", + SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); + output_director = false; + } + + Delete(retpm); + } + + /* Go through argument list, attach lnames for arguments */ + for (i = 0, p = l; p; p = nextSibling(p), ++i) { + String *arg = Getattr(p, "name"); + String *lname = NewString(""); + + if (!arg && Cmp(Getattr(p, "type"), "void")) { + lname = NewStringf("arg%d", i); + Setattr(p, "name", lname); + } else + lname = arg; + + Setattr(p, "lname", lname); + } + + // Attach the standard typemaps. + Swig_typemap_attach_parms("out", l, 0); + Swig_typemap_attach_parms("cwtype", l, 0); + Swig_typemap_attach_parms("dwtype", l, 0); + Swig_typemap_attach_parms("dptype", l, 0); + Swig_typemap_attach_parms("directorin", l, 0); + Swig_typemap_attach_parms("ddirectorin", l, 0); + + // Preamble code. + if (!ignored_method) + Printf(w->code, "if (!swig_callback_%s) {\n", overloaded_name); + + if (!pure_virtual) { + String *super_call = Swig_method_call(super, l); + if (is_void) { + Printf(w->code, "%s;\n", super_call); + if (!ignored_method) + Printf(w->code, "return;\n"); + } else { + Printf(w->code, "return %s;\n", super_call); + } + Delete(super_call); + } else { + Printf(w->code, " throw Swig::DirectorPureVirtualException(\"%s::%s\");\n", SwigType_namestr(c_classname), SwigType_namestr(name)); + } + + if (!ignored_method) + Printf(w->code, "} else {\n"); + + // Go through argument list. + for (p = l; p; /* empty */) { + /* Is this superfluous? */ + while (checkAttribute(p, "tmap:directorin:numinputs", "0")) { + p = Getattr(p, "tmap:directorin:next"); + } + + SwigType *pt = Getattr(p, "type"); + String *ln = Copy(Getattr(p, "name")); + String *c_param_type = NULL; + String *c_decl = NewString(""); + String *arg = NewString(""); + + Printf(arg, "j%s", ln); + + // Add each parameter to the D callback invocation arguments. + Printf(dcallback_call_args, ", %s", arg); + + /* Get parameter's intermediary C type */ + if ((c_param_type = lookupDTypemap(p, "cwtype", true))) { + String *cwtypeout = Getattr(p, "tmap:cwtype:out"); + if (cwtypeout) { + // The type in the cwtype typemap's out attribute overrides the type + // in the typemap itself. + c_param_type = cwtypeout; + } + + Parm *tp = NewParm(c_param_type, empty_str, n); + String *desc_tm = NULL; + + /* Add to local variables */ + Printf(c_decl, "%s %s", c_param_type, arg); + if (!ignored_method) + Wrapper_add_localv(w, arg, c_decl, (!(SwigType_ispointer(pt) || SwigType_isreference(pt)) ? "" : "= 0"), NIL); + + /* Add input marshalling code */ + if ((desc_tm = Swig_typemap_lookup("directorin", tp, "", 0)) + && (tm = Getattr(p, "tmap:directorin"))) { + + Replaceall(tm, "$input", arg); + Replaceall(tm, "$owner", "0"); + + if (Len(tm)) + if (!ignored_method) + Printf(w->code, "%s\n", tm); + + Delete(tm); + + // Add parameter type to the C typedef for the D callback function. + Printf(callback_typedef_parms, ", %s", c_param_type); + + /* Add parameter to the intermediate class code if generating the + * intermediate's upcall code */ + if ((tm = lookupDTypemap(p, "dwtype", true))) { + String *dwtypeout = Getattr(p, "tmap:dwtype:out"); + if (dwtypeout) { + // The type in the dwtype typemap's out attribute overrides the + // type in the typemap itself. + tm = dwtypeout; + } + const String *im_directorinattributes = Getattr(p, "tmap:dwtype:directorinattributes"); + + // TODO: Is this copy really needed? + String *din = Copy(lookupDTypemap(p, "ddirectorin", true)); + + if (din) { + Replaceall(din, "$winput", ln); + + Printf(delegate_parms, ", "); + if (gencomma > 0) { + Printf(proxy_method_param_list, ", "); + Printf(imcall_args, ", "); + } + Printf(delegate_parms, "%s%s %s", im_directorinattributes ? im_directorinattributes : empty_string, tm, ln); + + if (Cmp(din, ln)) { + Printv(imcall_args, din, NIL); + } else { + Printv(imcall_args, ln, NIL); + } + + Delete(din); + + // Get the parameter type in the proxy D class (used later when + // generating the overload checking code for the directorConnect + // function). + if ((tm = lookupDTypemap(p, "dptype", true))) { + Printf(proxy_method_param_list, "%s", tm); + } else { + Swig_warning(WARN_D_TYPEMAP_DPTYPE_UNDEF, input_file, line_number, + "No dptype typemap defined for %s\n", SwigType_str(pt, 0)); + } + } else { + Swig_warning(WARN_D_TYPEMAP_DDIRECTORIN_UNDEF, input_file, line_number, + "No ddirectorin typemap defined for %s for use in %s::%s (skipping director method)\n", + SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); + output_director = false; + } + } else { + Swig_warning(WARN_D_TYPEMAP_DWTYPE_UNDEF, input_file, line_number, + "No dwtype typemap defined for %s for use in %s::%s (skipping director method)\n", + SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); + output_director = false; + } + + p = Getattr(p, "tmap:directorin:next"); + + Delete(desc_tm); + } else { + if (!desc_tm) { + Swig_warning(WARN_D_TYPEMAP_DDIRECTORIN_UNDEF, input_file, line_number, + "No or improper directorin typemap defined for %s for use in %s::%s (skipping director method)\n", + SwigType_str(c_param_type, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); + p = nextSibling(p); + } else if (!tm) { + Swig_warning(WARN_D_TYPEMAP_DDIRECTORIN_UNDEF, input_file, line_number, + "No or improper directorin typemap defined for argument %s for use in %s::%s (skipping director method)\n", + SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); + p = nextSibling(p); + } + + output_director = false; + } + + Delete(tp); + } else { + Swig_warning(WARN_D_TYPEMAP_CWTYPE_UNDEF, input_file, line_number, + "No cwtype typemap defined for %s for use in %s::%s (skipping director method)\n", + SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); + output_director = false; + p = nextSibling(p); + } + + gencomma++; + Delete(arg); + Delete(c_decl); + Delete(c_param_type); + } + + /* header declaration, start wrapper definition */ + String *target; + SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : type; + target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0); + Printf(w->def, "%s", target); + Delete(qualified_name); + Delete(target); + target = Swig_method_decl(rtype, decl, name, l, 0, 1); + Printf(declaration, " virtual %s", target); + Delete(target); + + // Add any exception specifications to the methods in the director class + ParmList *throw_parm_list = NULL; + if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) { + int gencomma = 0; + + Append(w->def, " throw("); + Append(declaration, " throw("); + + if (throw_parm_list) + Swig_typemap_attach_parms("throws", throw_parm_list, 0); + for (p = throw_parm_list; p; p = nextSibling(p)) { + if ((tm = Getattr(p, "tmap:throws"))) { + if (gencomma++) { + Append(w->def, ", "); + Append(declaration, ", "); + } + Printf(w->def, "%s", SwigType_str(Getattr(p, "type"), 0)); + Printf(declaration, "%s", SwigType_str(Getattr(p, "type"), 0)); + } + } + + Append(w->def, ")"); + Append(declaration, ")"); + } + + Append(w->def, " {"); + Append(declaration, ";\n"); + + // Finish the callback function declaraction. + Printf(callback_def, "%s)", delegate_parms); + Printf(callback_def, " {\n"); + + /* Emit the intermediate class's upcall to the actual class */ + + String *upcall = NewStringf("(cast(%s)dObject).%s(%s)", classname, symname, imcall_args); + + if (!is_void) { + Parm *tp = NewParm(returntype, empty_str, n); + + // RESEARCH: What happens if there is no ddirectorout typemap? + if ((tm = lookupDTypemap(tp, "ddirectorout"))) { + Replaceall(tm, "$dpcall", upcall); + + Printf(callback_code, " return %s;\n", tm); + } + + Delete(tm); + Delete(tp); + } else { + Printf(callback_code, " %s;\n", upcall); + } + + Printf(callback_code, "}\n"); + Delete(upcall); + + if (!ignored_method) { + if (!is_void) + Printf(w->code, "jresult = (%s) ", c_ret_type); + + Printf(w->code, "swig_callback_%s(d_object%s);\n", overloaded_name, dcallback_call_args); + + if (!is_void) { + String *jresult_str = NewString("jresult"); + String *result_str = NewString("c_result"); + Parm *tp = NewParm(returntype, result_str, n); + + /* Copy jresult into c_result... */ + // FIXME: lookupDTypemap? + if ((tm = Swig_typemap_lookup("directorout", tp, result_str, w))) { + Replaceall(tm, "$input", jresult_str); + Replaceall(tm, "$result", result_str); + Printf(w->code, "%s\n", tm); + } else { + Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number, + "Unable to use return type %s used in %s::%s (skipping director method)\n", + SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); + output_director = false; + } + + Delete(tp); + Delete(jresult_str); + Delete(result_str); + } + + /* Terminate wrapper code */ + Printf(w->code, "}\n"); + if (!is_void) + Printf(w->code, "return %s;", qualified_return); + } + + Printf(w->code, "}"); + + // We expose virtual protected methods via an extra public inline method which makes a straight call to the wrapped class' method + String *inline_extra_method = NewString(""); + if (dirprot_mode() && !is_public(n) && !pure_virtual) { + Printv(inline_extra_method, declaration, NIL); + String *extra_method_name = NewStringf("%sSwigPublic", name); + Replaceall(inline_extra_method, name, extra_method_name); + Replaceall(inline_extra_method, ";\n", " {\n "); + if (!is_void) + Printf(inline_extra_method, "return "); + String *methodcall = Swig_method_call(super, l); + Printv(inline_extra_method, methodcall, ";\n }\n", NIL); + Delete(methodcall); + Delete(extra_method_name); + } + + /* emit code */ + if (status == SWIG_OK && output_director) { + if (!is_void) { + Replaceall(w->code, "$null", qualified_return); + } else { + Replaceall(w->code, "$null", ""); + } + if (!ignored_method) + Printv(director_dcallbacks_code, callback_def, callback_code, NIL); + if (!Getattr(n, "defaultargs")) { + Wrapper_print(w, f_directors); + Printv(f_directors_h, declaration, NIL); + Printv(f_directors_h, inline_extra_method, NIL); + } + } + + if (!ignored_method) { + // Register the upcall method so that the callback registering code can + // be written later. + + // We cannot directly use n here because its »type« attribute does not + // the full return type any longer after Language::functionHandler has + // returned. + Parm *tp = NewParm(returntype, empty_str, n); + String *dp_return_type = lookupDTypemap(tp, "dptype"); + if (dp_return_type) { + String *dptypeout = Getattr(n, "tmap:dptype:out"); + if (dptypeout) { + // The type in the dptype typemap's out attribute overrides the type + // in the typemap itself. + dp_return_type = dptypeout; + replaceClassname(dp_return_type, returntype); + } + } else { + Swig_warning(WARN_D_TYPEMAP_DPTYPE_UNDEF, input_file, line_number, + "No dptype typemap defined for %s\n", SwigType_str(type, 0)); + dp_return_type = NewString(""); + } + + UpcallData *udata = addUpcallMethod(imclass_dmethod, symname, decl, overloaded_name, dp_return_type, proxy_method_param_list); + Delete(dp_return_type); + + // Write the global callback function pointer on the C code. + String *methid = Getattr(udata, "class_methodidx"); + + Printf(director_callback_typedefs, " typedef %s (SWIGSTDCALL* SWIG_Callback%s_t)", c_ret_type, methid); + Printf(director_callback_typedefs, "(void *dobj%s);\n", callback_typedef_parms); + Printf(director_callback_pointers, " SWIG_Callback%s_t swig_callback_%s;\n", methid, overloaded_name); + + // Write the type alias for the callback to the wrap D module. + String* proxy_callback_type = NewString(""); + Printf(proxy_callback_type, "SwigDirector_%s_Callback%s", classname, methid); + Printf(wrap_dmodule_code, "alias extern(C) %s function(void*%s) %s;\n", proxy_callback_return_type, delegate_parms, proxy_callback_type); + Delete(proxy_callback_type); + } + + Delete(qualified_return); + Delete(c_ret_type); + Delete(declaration); + Delete(callback_typedef_parms); + Delete(delegate_parms); + Delete(proxy_method_param_list); + Delete(callback_def); + Delete(callback_code); + DelWrapper(w); + + return status; + } + + /* --------------------------------------------------------------------------- + * D::classDirectorConstructor() + * --------------------------------------------------------------------------- */ + virtual int classDirectorConstructor(Node *n) { + Node *parent = parentNode(n); + String *decl = Getattr(n, "decl");; + String *supername = Swig_class_name(parent); + String *classname = getDirectorClassName(parent); + String *sub = NewString(""); + Parm *p; + ParmList *superparms = Getattr(n, "parms"); + ParmList *parms; + int argidx = 0; + + /* Assign arguments to superclass's parameters, if not already done */ + for (p = superparms; p; p = nextSibling(p)) { + String *pname = Getattr(p, "name"); + + if (!pname) { + pname = NewStringf("arg%d", argidx++); + Setattr(p, "name", pname); + } + } + + // TODO: Is this copy needed? + parms = CopyParmList(superparms); + + if (!Getattr(n, "defaultargs")) { + /* constructor */ + { + String *basetype = Getattr(parent, "classtype"); + String *target = Swig_method_decl(0, decl, classname, parms, 0, 0); + String *call = Swig_csuperclass_call(0, basetype, superparms); + String *classtype = SwigType_namestr(Getattr(n, "name")); + + Printf(f_directors, "%s::%s : %s, %s {\n", classname, target, call, Getattr(parent, "director:ctor")); + Printf(f_directors, " swig_init_callbacks();\n"); + Printf(f_directors, "}\n\n"); + + Delete(classtype); + Delete(target); + Delete(call); + } + + /* constructor header */ + { + String *target = Swig_method_decl(0, decl, classname, parms, 0, 1); + Printf(f_directors_h, " %s;\n", target); + Delete(target); + } + } + + Delete(sub); + Delete(supername); + Delete(parms); + return Language::classDirectorConstructor(n); + } + + /* --------------------------------------------------------------------------- + * D::classDirectorDefaultConstructor() + * --------------------------------------------------------------------------- */ + virtual int classDirectorDefaultConstructor(Node *n) { + String *classname = Swig_class_name(n); + String *classtype = SwigType_namestr(Getattr(n, "name")); + Wrapper *w = NewWrapper(); + + Printf(w->def, "SwigDirector_%s::SwigDirector_%s() : %s {", classname, classname, Getattr(n, "director:ctor")); + Printf(w->code, "}\n"); + Wrapper_print(w, f_directors); + + Printf(f_directors_h, " SwigDirector_%s();\n", classname); + DelWrapper(w); + Delete(classtype); + Delete(classname); + return Language::classDirectorDefaultConstructor(n); + } + + /* --------------------------------------------------------------------------- + * D::classDirectorDestructor() + * --------------------------------------------------------------------------- */ + virtual int classDirectorDestructor(Node *n) { + Node *current_class = getCurrentClass(); + String *classname = Swig_class_name(current_class); + Wrapper *w = NewWrapper(); + + if (Getattr(n, "throw")) { + Printf(f_directors_h, " virtual ~SwigDirector_%s() throw ();\n", classname); + Printf(w->def, "SwigDirector_%s::~SwigDirector_%s() throw () {\n", classname, classname); + } else { + Printf(f_directors_h, " virtual ~SwigDirector_%s();\n", classname); + Printf(w->def, "SwigDirector_%s::~SwigDirector_%s() {\n", classname, classname); + } + + Printv(w->code, "}\n", NIL); + + Wrapper_print(w, f_directors); + + DelWrapper(w); + Delete(classname); + return SWIG_OK; + } + + /* --------------------------------------------------------------------------- + * D::classDirectorEnd() + * --------------------------------------------------------------------------- */ + virtual int classDirectorEnd(Node *n) { + int i; + String *director_classname = getDirectorClassName(n); + + Wrapper *w = NewWrapper(); + + if (Len(director_callback_typedefs) > 0) { + Printf(f_directors_h, "\n%s", director_callback_typedefs); + } + + Printf(f_directors_h, " void swig_connect_director(void* dobj"); + + Printf(w->def, "void %s::swig_connect_director(void* dobj", director_classname); + Printf(w->code, "d_object = dobj;"); + + for (i = first_class_dmethod; i < curr_class_dmethod; ++i) { + UpcallData *udata = Getitem(dmethods_seq, i); + String *methid = Getattr(udata, "class_methodidx"); + String *overname = Getattr(udata, "overname"); + + Printf(f_directors_h, ", SWIG_Callback%s_t callback%s", methid, overname); + Printf(w->def, ", SWIG_Callback%s_t callback_%s", methid, overname); + Printf(w->code, "swig_callback_%s = callback_%s;\n", overname, overname); + } + + Printf(f_directors_h, ");\n"); + Printf(w->def, ") {"); + + Printf(f_directors_h, "\nprivate:\n"); + Printf(f_directors_h, " void swig_init_callbacks();\n"); + Printf(f_directors_h, " void *d_object;\n"); + if (Len(director_callback_typedefs) > 0) { + Printf(f_directors_h, "%s", director_callback_pointers); + } + Printf(f_directors_h, "};\n\n"); + Printf(w->code, "}\n\n"); + + Printf(w->code, "void %s::swig_init_callbacks() {\n", director_classname); + for (i = first_class_dmethod; i < curr_class_dmethod; ++i) { + UpcallData *udata = Getitem(dmethods_seq, i); + String *overname = Getattr(udata, "overname"); + Printf(w->code, "swig_callback_%s = 0;\n", overname); + } + Printf(w->code, "}"); + + Wrapper_print(w, f_directors); + + DelWrapper(w); + + return Language::classDirectorEnd(n); + } + + /* --------------------------------------------------------------------------- + * D::classDirectorDisown() + * --------------------------------------------------------------------------- */ + virtual int classDirectorDisown(Node *n) { + (void) n; + return SWIG_OK; + } + + /* --------------------------------------------------------------------------- + * D::replaceSpecialVariables() + * --------------------------------------------------------------------------- */ + virtual void replaceSpecialVariables(String *method, String *tm, Parm *parm) { + (void)method; + SwigType *type = Getattr(parm, "type"); + + // Just assume that this goes to the proxy class, we cannot know. + replaceClassname(tm, type); + } + +protected: + /* --------------------------------------------------------------------------- + * D::extraDirectorProtectedCPPMethodsRequired() + * --------------------------------------------------------------------------- */ + virtual bool extraDirectorProtectedCPPMethodsRequired() const { + return false; + } + +private: + /* --------------------------------------------------------------------------- + * D::writeWrapDModuleFunction() + * + * Writes a function declaration for the given (C) wrapper function to the + * wrap D module. + * + * d_name - The name the function in the D wrap module will get. + * wrapper_function_name - The name of the exported function in the C wrapper + * (usually d_name prefixed by »D_«). + * --------------------------------------------------------------------------- */ + void writeWrapDModuleFunction(const_String_or_char_ptr d_name, + const_String_or_char_ptr return_type, const_String_or_char_ptr parameters, + const_String_or_char_ptr wrapper_function_name) { + + // TODO: Add support for static linking here. + Printf(wrap_dmodule_code, "extern(C) %s function%s %s;\n", return_type, + parameters, d_name); + Printv(wrapper_loader_bind_code, wrapper_loader_bind_command, NIL); + Replaceall(wrapper_loader_bind_code, "$function", d_name); + Replaceall(wrapper_loader_bind_code, "$symbol", wrapper_function_name); + } + + /* --------------------------------------------------------------------------- + * D::writeProxyClassFunction() + * + * Creates a D proxy function for a C++ function in the wrapped class. Used + * for both static and non-static C++ class functions. + * + * The Node must contain two extra attributes. + * - "proxyfuncname": The name of the D proxy function. + * - "imfuncname": The corresponding function in the wrap D module. + * --------------------------------------------------------------------------- */ + void writeProxyClassFunction(Node *n) { + SwigType *t = Getattr(n, "type"); + ParmList *l = Getattr(n, "parms"); + String *intermediary_function_name = Getattr(n, "imfuncname"); + String *proxy_function_name = Getattr(n, "proxyfuncname"); + String *tm; + Parm *p; + int i; + String *imcall = NewString(""); + String *return_type = NewString(""); + String *function_code = NewString(""); + bool setter_flag = false; + String *pre_code = NewString(""); + String *post_code = NewString(""); + String *terminator_code = NewString(""); + + // Wrappers not wanted for some methods where the parameters cannot be + // overloaded in D. + if (Getattr(n, "overload:ignore")) + return; + + // Don't generate proxy method for additional explicitcall method used in + // directors. + if (GetFlag(n, "explicitcall")) + return; + + // RESEARCH: What is this good for? + if (l) { + if (SwigType_type(Getattr(l, "type")) == T_VOID) { + l = nextSibling(l); + } + } + + /* Attach the non-standard typemaps to the parameter list */ + Swig_typemap_attach_parms("in", l, NULL); + Swig_typemap_attach_parms("dptype", l, NULL); + Swig_typemap_attach_parms("din", l, NULL); + + // Get return types. + if ((tm = lookupDTypemap(n, "dptype"))) { + String *dptypeout = Getattr(n, "tmap:dptype:out"); + if (dptypeout) { + // The type in the dptype typemap's out attribute overrides the type in + // the typemap. + tm = dptypeout; + replaceClassname(tm, t); + } + Printf(return_type, "%s", tm); + } else { + Swig_warning(WARN_D_TYPEMAP_DPTYPE_UNDEF, input_file, line_number, + "No dptype typemap defined for %s\n", SwigType_str(t, 0)); + } + + if (wrapping_member_flag) { + // Check if this is a setter method for a public member. + setter_flag = (Cmp(Getattr(n, "sym:name"), + Swig_name_set(NSPACE_TODO,Swig_name_member(NSPACE_TODO,proxy_class_name, variable_name))) == 0); + } + + // Write function modifiers. + { + String *modifiers; + + const String *mods_override = Getattr(n, "feature:d:methodmodifiers"); + if (mods_override) { + modifiers = Copy(mods_override); + } else { + modifiers = Copy(is_public(n) ? public_string : protected_string); + + if (Getattr(n, "override")) { + Printf(modifiers, " override"); + } + } + + if (is_smart_pointer()) { + // Smart pointer classes do not mirror the inheritance hierarchy of the + // underlying pointer type, so no override required. + Replaceall(modifiers, "override", ""); + } + + Chop(modifiers); + + if (static_flag) { + Printf(modifiers, " static"); + } + + Printf(function_code, "%s ", modifiers); + Delete(modifiers); + } + + // Complete the function declaration up to the parameter list. + Printf(function_code, "%s %s(", return_type, proxy_function_name); + + // Write the wrapper function call up to the parameter list. + Printv(imcall, wrap_dmodule_fq_name, ".$imfuncname(", NIL); + if (!static_flag) { + Printf(imcall, "cast(void*)swigCPtr"); + } + + // Write the parameter list for the proxy function declaration and the + // wrapper function call. + emit_mark_varargs(l); + int gencomma = !static_flag; + for (i = 0, p = l; p; i++) { + // Ignored varargs. + if (checkAttribute(p, "varargs:ignore", "1")) { + p = nextSibling(p); + continue; + } + + // Ignored parameters. + if (checkAttribute(p, "tmap:in:numinputs", "0")) { + p = Getattr(p, "tmap:in:next"); + continue; + } + + // Ignore the 'this' argument for variable wrappers. + if (!(variable_wrapper_flag && i == 0)) { + String *param_name = makeParameterName(n, p, i, setter_flag); + SwigType *pt = Getattr(p, "type"); + + // Write the wrapper function call argument. + { + if (gencomma) { + Printf(imcall, ", "); + } + + if ((tm = lookupDTypemap(p, "din", true))) { + Replaceall(tm, "$dinput", param_name); + String *pre = Getattr(p, "tmap:din:pre"); + if (pre) { + replaceClassname(pre, pt); + Replaceall(pre, "$dinput", param_name); + if (Len(pre_code) > 0) + Printf(pre_code, "\n"); + Printv(pre_code, pre, NIL); + } + String *post = Getattr(p, "tmap:din:post"); + if (post) { + replaceClassname(post, pt); + Replaceall(post, "$dinput", param_name); + if (Len(post_code) > 0) + Printf(post_code, "\n"); + Printv(post_code, post, NIL); + } + String *terminator = Getattr(p, "tmap:din:terminator"); + if (terminator) { + replaceClassname(terminator, pt); + Replaceall(terminator, "$dinput", param_name); + if (Len(terminator_code) > 0) + Insert(terminator_code, 0, "\n"); + Insert(terminator_code, 0, terminator); + } + Printv(imcall, tm, NIL); + } else { + Swig_warning(WARN_D_TYPEMAP_DIN_UNDEF, input_file, line_number, + "No din typemap defined for %s\n", SwigType_str(pt, 0)); + } + } + + // Write the D proxy function parameter. + { + String *proxy_type = NewString(""); + + if ((tm = lookupDTypemap(p, "dptype"))) { + const String *inattributes = Getattr(p, "tmap:dptype:inattributes"); + Printf(proxy_type, "%s%s", inattributes ? inattributes : empty_string, tm); + } else { + Swig_warning(WARN_D_TYPEMAP_DPTYPE_UNDEF, input_file, line_number, + "No dptype typemap defined for %s\n", SwigType_str(pt, 0)); + } + + if (gencomma >= 2) + Printf(function_code, ", "); + gencomma = 2; + Printf(function_code, "%s %s", proxy_type, param_name); + + Delete(proxy_type); + } + + Delete(param_name); + } + p = Getattr(p, "tmap:in:next"); + } + + Printf(imcall, ")"); + Printf(function_code, ") "); + + if (d_version > 1 && wrapping_member_flag) { + Printf(function_code, "@property "); + } + + if (wrapMemberFunctionAsDConst(n)) { + Printf(function_code, "const "); + } + + // Lookup the code used to convert the wrapper return value to the proxy + // function return type. + if ((tm = lookupDTypemap(n, "dout"))) { + replaceExcode(n, tm, "dout", n); + bool is_pre_code = Len(pre_code) > 0; + bool is_post_code = Len(post_code) > 0; + bool is_terminator_code = Len(terminator_code) > 0; + if (is_pre_code || is_post_code || is_terminator_code) { + if (is_post_code) { + Insert(tm, 0, "\n try "); + Printv(tm, " finally {\n", post_code, "\n }", NIL); + } else { + Insert(tm, 0, "\n "); + } + if (is_pre_code) { + Insert(tm, 0, pre_code); + Insert(tm, 0, "\n"); + } + if (is_terminator_code) { + Printv(tm, "\n", terminator_code, NIL); + } + Insert(tm, 0, "{"); + Printv(tm, "}", NIL); + } + if (GetFlag(n, "feature:new")) + Replaceall(tm, "$owner", "true"); + else + Replaceall(tm, "$owner", "false"); + replaceClassname(tm, t); + + // For director methods: generate code to selectively make a normal + // polymorphic call or an explicit method call. Needed to prevent infinite + // recursion when calling director methods. + Node *explicit_n = Getattr(n, "explicitcallnode"); + if (explicit_n) { + String *ex_overloaded_name = getOverloadedName(explicit_n); + String *ex_intermediary_function_name = Swig_name_member(NSPACE_TODO,proxy_class_name, ex_overloaded_name); + + String *ex_imcall = Copy(imcall); + Replaceall(ex_imcall, "$imfuncname", ex_intermediary_function_name); + Replaceall(imcall, "$imfuncname", intermediary_function_name); + + String *excode = NewString(""); + if (!Cmp(return_type, "void")) + Printf(excode, "if (this.classinfo == %s.classinfo) %s; else %s", proxy_class_name, imcall, ex_imcall); + else + Printf(excode, "((this.classinfo == %s.classinfo) ? %s : %s)", proxy_class_name, imcall, ex_imcall); + + Clear(imcall); + Printv(imcall, excode, NIL); + Delete(ex_overloaded_name); + Delete(excode); + } else { + Replaceall(imcall, "$imfuncname", intermediary_function_name); + } + Replaceall(tm, "$wcall", imcall); + } else { + Swig_warning(WARN_D_TYPEMAP_DOUT_UNDEF, input_file, line_number, + "No dout typemap defined for %s\n", SwigType_str(t, 0)); + } + + // The whole function body is now in stored tm (if there was a matching type + // map, of course), so simply append it to the code buffer. The braces are + // included in the typemap. + Printv(function_code, tm, NIL); + + // Write function code buffer to the class code. + Printv(proxy_class_body_code, "\n", function_code, "\n", NIL); + + Delete(pre_code); + Delete(post_code); + Delete(terminator_code); + Delete(function_code); + Delete(return_type); + Delete(imcall); + } + + /* --------------------------------------------------------------------------- + * D::writeProxyDModuleFunction() + * --------------------------------------------------------------------------- */ + void writeProxyDModuleFunction(Node *n) { + SwigType *t = Getattr(n, "type"); + ParmList *l = Getattr(n, "parms"); + String *tm; + Parm *p; + int i; + String *imcall = NewString(""); + String *return_type = NewString(""); + String *function_code = NewString(""); + int num_arguments = 0; + int num_required = 0; + String *overloaded_name = getOverloadedName(n); + String *func_name = NULL; + String *pre_code = NewString(""); + String *post_code = NewString(""); + String *terminator_code = NewString(""); + + // RESEARCH: What is this good for? + if (l) { + if (SwigType_type(Getattr(l, "type")) == T_VOID) { + l = nextSibling(l); + } + } + + /* Attach the non-standard typemaps to the parameter list */ + Swig_typemap_attach_parms("dptype", l, NULL); + Swig_typemap_attach_parms("din", l, NULL); + + /* Get return types */ + if ((tm = lookupDTypemap(n, "dptype"))) { + String *dptypeout = Getattr(n, "tmap:dptype:out"); + if (dptypeout) { + // The type in the dptype typemap's out attribute overrides the type in + // the typemap. + tm = dptypeout; + replaceClassname(tm, t); + } + Printf(return_type, "%s", tm); + } else { + Swig_warning(WARN_D_TYPEMAP_DPTYPE_UNDEF, input_file, line_number, + "No dptype typemap defined for %s\n", SwigType_str(t, 0)); + } + + /* Change function name for global variables */ + if (global_variable_flag) { + // RESEARCH: Is the Copy() needed here? + func_name = Copy(variable_name); + } else { + func_name = Copy(Getattr(n, "sym:name")); + } + + /* Start generating the function */ + const String *outattributes = Getattr(n, "tmap:dptype:outattributes"); + if (outattributes) + Printf(function_code, " %s\n", outattributes); + + const String *methodmods = Getattr(n, "feature:d:methodmodifiers"); + // TODO: Check if is_public(n) could possibly make any sense here + // (private global functions would be useless anyway?). + methodmods = methodmods ? methodmods : empty_string; + + Printf(function_code, "\n%s%s %s(", methodmods, return_type, func_name); + Printv(imcall, wrap_dmodule_fq_name, ".", overloaded_name, "(", NIL); + + /* Get number of required and total arguments */ + num_arguments = emit_num_arguments(l); + num_required = emit_num_required(l); + + int gencomma = 0; + + /* Output each parameter */ + for (i = 0, p = l; i < num_arguments; i++) { + + /* Ignored parameters */ + while (checkAttribute(p, "tmap:in:numinputs", "0")) { + p = Getattr(p, "tmap:in:next"); + } + + SwigType *pt = Getattr(p, "type"); + String *param_type = NewString(""); + + // Get the D parameter type. + if ((tm = lookupDTypemap(p, "dptype", true))) { + const String *inattributes = Getattr(p, "tmap:dptype:inattributes"); + Printf(param_type, "%s%s", inattributes ? inattributes : empty_string, tm); + } else { + Swig_warning(WARN_D_TYPEMAP_DPTYPE_UNDEF, input_file, line_number, + "No dptype typemap defined for %s\n", SwigType_str(pt, 0)); + } + + if (gencomma) + Printf(imcall, ", "); + + const bool generating_setter = global_variable_flag || wrapping_member_flag; + String *arg = makeParameterName(n, p, i, generating_setter); + + // Get the D code to convert the parameter value to the type used in the + // wrapper D module. + if ((tm = lookupDTypemap(p, "din", true))) { + Replaceall(tm, "$dinput", arg); + String *pre = Getattr(p, "tmap:din:pre"); + if (pre) { + replaceClassname(pre, pt); + Replaceall(pre, "$dinput", arg); + if (Len(pre_code) > 0) + Printf(pre_code, "\n"); + Printv(pre_code, pre, NIL); + } + String *post = Getattr(p, "tmap:din:post"); + if (post) { + replaceClassname(post, pt); + Replaceall(post, "$dinput", arg); + if (Len(post_code) > 0) + Printf(post_code, "\n"); + Printv(post_code, post, NIL); + } + String *terminator = Getattr(p, "tmap:din:terminator"); + if (terminator) { + replaceClassname(terminator, pt); + Replaceall(terminator, "$dinput", arg); + if (Len(terminator_code) > 0) + Insert(terminator_code, 0, "\n"); + Insert(terminator_code, 0, terminator); + } + Printv(imcall, tm, NIL); + } else { + Swig_warning(WARN_D_TYPEMAP_DIN_UNDEF, input_file, line_number, + "No din typemap defined for %s\n", SwigType_str(pt, 0)); + } + + /* Add parameter to module class function */ + if (gencomma >= 2) + Printf(function_code, ", "); + gencomma = 2; + Printf(function_code, "%s %s", param_type, arg); + + p = Getattr(p, "tmap:in:next"); + Delete(arg); + Delete(param_type); + } + + Printf(imcall, ")"); + Printf(function_code, ") "); + + if (global_variable_flag && (d_version > 1)) { + Printf(function_code, "@property "); + } + + // Lookup the code used to convert the wrapper return value to the proxy + // function return type. + if ((tm = lookupDTypemap(n, "dout"))) { + replaceExcode(n, tm, "dout", n); + bool is_pre_code = Len(pre_code) > 0; + bool is_post_code = Len(post_code) > 0; + bool is_terminator_code = Len(terminator_code) > 0; + if (is_pre_code || is_post_code || is_terminator_code) { + if (is_post_code) { + Insert(tm, 0, "\n try "); + Printv(tm, " finally {\n", post_code, "\n }", NIL); + } else { + Insert(tm, 0, "\n "); + } + if (is_pre_code) { + Insert(tm, 0, pre_code); + Insert(tm, 0, "\n"); + } + if (is_terminator_code) { + Printv(tm, "\n", terminator_code, NIL); + } + Insert(tm, 0, " {"); + Printf(tm, "\n}"); + } + if (GetFlag(n, "feature:new")) + Replaceall(tm, "$owner", "true"); + else + Replaceall(tm, "$owner", "false"); + replaceClassname(tm, t); + Replaceall(tm, "$wcall", imcall); + } else { + Swig_warning(WARN_D_TYPEMAP_DOUT_UNDEF, input_file, line_number, + "No dout typemap defined for %s\n", SwigType_str(t, 0)); + } + + // The whole function code is now stored in tm (if there was a matching + // type map, of course), so simply append it to the code buffer. + Printf(function_code, "%s\n", tm ? (const String *) tm : empty_string); + Printv(proxy_dmodule_code, function_code, NIL); + + Delete(pre_code); + Delete(post_code); + Delete(terminator_code); + Delete(function_code); + Delete(return_type); + Delete(imcall); + Delete(func_name); + } + + /* --------------------------------------------------------------------------- + * D::writeProxyClassAndUpcasts() + * --------------------------------------------------------------------------- */ + void writeProxyClassAndUpcasts(Node *n) { + SwigType *typemap_lookup_type = Getattr(n, "classtypeobj"); + + /* + * Handle inheriting from D and C++ classes. + */ + + String *c_classname = SwigType_namestr(Getattr(n, "name")); + String *c_baseclass = NULL; + String *baseclass = NULL; + String *c_baseclassname = NULL; + + // Inheritance from pure D classes. + Node *attributes = NewHash(); + const String *pure_baseclass = + lookupCodeTypemap(n, "dbase", typemap_lookup_type, WARN_NONE, attributes); + bool purebase_replace = GetFlag(attributes, "tmap:dbase:replace") ? true : false; + bool purebase_notderived = GetFlag(attributes, "tmap:dbase:notderived") ? true : false; + Delete(attributes); + + // C++ inheritance. + if (!purebase_replace) { + List *baselist = Getattr(n, "bases"); + if (baselist) { + Iterator base = First(baselist); + while (base.item && GetFlag(base.item, "feature:ignore")) { + base = Next(base); + } + if (base.item) { + c_baseclassname = Getattr(base.item, "name"); + baseclass = Copy(getProxyName(c_baseclassname)); + if (baseclass) + c_baseclass = SwigType_namestr(Getattr(base.item, "name")); + base = Next(base); + /* Warn about multiple inheritance for additional base class(es) */ + while (base.item) { + if (GetFlag(base.item, "feature:ignore")) { + base = Next(base); + continue; + } + String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0); + String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0); + Swig_warning(WARN_D_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), + "Base %s of class %s ignored: multiple inheritance is not supported in D.\n", baseclassname, proxyclassname); + base = Next(base); + } + } + } + } + + bool derived = baseclass && getProxyName(c_baseclassname); + + if (derived && purebase_notderived) { + pure_baseclass = empty_string; + } + const String *wanted_base = baseclass ? baseclass : pure_baseclass; + + if (purebase_replace) { + wanted_base = pure_baseclass; + derived = false; + Delete(baseclass); + baseclass = NULL; + if (purebase_notderived) { + Swig_error(Getfile(n), Getline(n), + "The dbase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n", + typemap_lookup_type); + } + } else if (baseclass && Len(pure_baseclass) > 0) { + Swig_warning(WARN_D_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), + "Warning for %s proxy: Base class %s ignored. Multiple inheritance is not supported in D. " + "Perhaps you need one of the 'replace' or 'notderived' attributes in the dbase typemap?\n", typemap_lookup_type, pure_baseclass); + } + + // Add code to do C++ casting to base class (only for classes in an inheritance hierarchy) + if (derived) { + writeClassUpcast(n, proxy_class_name, c_classname, c_baseclass); + } + + /* + * Write needed imports. + */ + // If this class is derived from a C++ class, we need to have the D class + // generated for it in scope. + if (derived) { + requireDType(baseclass); + + if (split_proxy_dmodule) { + // Fully qualify the baseclass name. + String *module = NewStringf("%s%s.", package, baseclass); + Insert(baseclass, 0, module); + Delete(module); + } + } + + // Write any custom import statements to the proxy module header. + const String *imports = lookupCodeTypemap(n, "dimports", typemap_lookup_type, WARN_NONE); + if (Len(imports) > 0) { + String* imports_trimmed = Copy(imports); + Chop(imports_trimmed); + replaceImportTypeMacros(imports_trimmed); + Printv(proxy_class_imports, imports_trimmed, "\n", NIL); + Delete(imports_trimmed); + } + + /* + * Write the proxy class header. + */ + // Class modifiers. + const String *modifiers = + lookupCodeTypemap(n, "dclassmodifiers", typemap_lookup_type, WARN_D_TYPEMAP_CLASSMOD_UNDEF); + + // User-defined interfaces. + const String *interfaces = + lookupCodeTypemap(n, derived ? "dinterfaces_derived" : "dinterfaces", typemap_lookup_type, WARN_NONE); + + Printv(proxy_class_code, + "\n", + modifiers, + " $dclassname", + (*Char(wanted_base) || *Char(interfaces)) ? " : " : "", wanted_base, + (*Char(wanted_base) && *Char(interfaces)) ? ", " : "", interfaces, " {", + NIL); + + /* + * Write the proxy class body. + */ + String* body = NewString(""); + + // Default class body. + const String *dbody; + if (derived) { + dbody = lookupCodeTypemap(n, "dbody_derived", typemap_lookup_type, WARN_D_TYPEMAP_DBODY_UNDEF); + } else { + dbody = lookupCodeTypemap(n, "dbody", typemap_lookup_type, WARN_D_TYPEMAP_DBODY_UNDEF); + } + + Printv(body, dbody, NIL); + + // Destructor and dispose(). + // If the C++ destructor is accessible (public), it is wrapped by the + // dispose() method which is also called by the emitted D constructor. If it + // is not accessible, no D destructor is written and the generated dispose() + // method throws an exception. + // This enables C++ classes with protected or private destructors to be used + // in D as it would be used in C++ (GC finalization is a no-op then because + // of the empty D destructor) while preventing usage in »scope« variables. + // The method name for the dispose() method is specified in a typemap + // attribute called »methodname«. + const String *tm = NULL; + + String *dispose_methodname; + String *dispose_methodmodifiers; + attributes = NewHash(); + if (derived) { + tm = lookupCodeTypemap(n, "ddispose_derived", typemap_lookup_type, WARN_NONE, attributes); + dispose_methodname = Getattr(attributes, "tmap:ddispose_derived:methodname"); + dispose_methodmodifiers = Getattr(attributes, "tmap:ddispose_derived:methodmodifiers"); + } else { + tm = lookupCodeTypemap(n, "ddispose", typemap_lookup_type, WARN_NONE, attributes); + dispose_methodname = Getattr(attributes, "tmap:ddispose:methodname"); + dispose_methodmodifiers = Getattr(attributes, "tmap:ddispose:methodmodifiers"); + } + + if (tm && *Char(tm)) { + if (!dispose_methodname) { + Swig_error(Getfile(n), Getline(n), + "No methodname attribute defined in the ddispose%s typemap for %s\n", + (derived ? "_derived" : ""), proxy_class_name); + } + if (!dispose_methodmodifiers) { + Swig_error(Getfile(n), Getline(n), + "No methodmodifiers attribute defined in ddispose%s typemap for %s.\n", + (derived ? "_derived" : ""), proxy_class_name); + } + } + + if (tm) { + // Write the destructor if the C++ one is accessible. + if (*Char(destructor_call)) { + Printv(body, + lookupCodeTypemap(n, "ddestructor", typemap_lookup_type, WARN_NONE), NIL); + } + + // Write the dispose() method. + String *dispose_code = NewString(""); + Printv(dispose_code, tm, NIL); + + if (*Char(destructor_call)) { + Replaceall(dispose_code, "$wcall", destructor_call); + } else { + Replaceall(dispose_code, "$wcall", "throw new Exception(\"C++ destructor does not have public access\")"); + } + + if (*Char(dispose_code)) { + Printv(body, "\n", dispose_methodmodifiers, + (derived ? " override" : ""), " void ", dispose_methodname, "() ", + dispose_code, "\n", NIL); + } + } + + if (Swig_directorclass(n)) { + // If directors are enabled for the current class, generate the + // director connect helper function which is called from the constructor + // and write it to the class body. + writeDirectorConnectProxy(); + } + + // Write all constants and enumerations first to prevent forward reference + // errors. + Printv(body, proxy_class_enums_code, NIL); + + // Write the code generated in other methods to the class body. + Printv(body, proxy_class_body_code, NIL); + + // Append extra user D code to the class body. + Printv(body, + lookupCodeTypemap(n, "dcode", typemap_lookup_type, WARN_NONE), "\n", NIL); + + // Write the class body and the curly bracket closing the class definition + // to the proxy module. + indentCode(body); + Replaceall(body, "$dbaseclass", baseclass); + Delete(baseclass); + + Printv(proxy_class_code, body, "\n}\n", NIL); + Delete(body); + + // Write the epilogue code if there is any. + Printv(proxy_class_code, proxy_class_epilogue_code, NIL); + } + + + /* --------------------------------------------------------------------------- + * D::writeClassUpcast() + * --------------------------------------------------------------------------- */ + void writeClassUpcast(Node *n, const String* d_class_name, + String* c_class_name, String* c_base_name) { + + String *smartptr = Getattr(n, "feature:smartptr"); + String *upcast_name = NewString(""); + Printv(upcast_name, d_class_name, + (smartptr != 0 ? "SmartPtrUpcast" : "Upcast"), NIL); + + String *upcast_wrapper_name = Swig_name_wrapper(upcast_name); + + writeWrapDModuleFunction(upcast_name, "void*", "(void* objectRef)", + upcast_wrapper_name); + + if (smartptr) { + SwigType *spt = Swig_cparse_type(smartptr); + if (spt) { + SwigType *smart = SwigType_typedef_resolve_all(spt); + Delete(spt); + SwigType *bsmart = Copy(smart); + SwigType *rclassname = SwigType_typedef_resolve_all(c_class_name); + SwigType *rbaseclass = SwigType_typedef_resolve_all(c_base_name); + Replaceall(bsmart, rclassname, rbaseclass); + Delete(rclassname); + Delete(rbaseclass); + String *smartnamestr = SwigType_namestr(smart); + String *bsmartnamestr = SwigType_namestr(bsmart); + Printv(upcasts_code, + "SWIGEXPORT ", bsmartnamestr, " * SWIGSTDCALL ", upcast_wrapper_name, + "(", smartnamestr, " *objectRef) {\n", + " return objectRef ? new ", bsmartnamestr, "(*objectRef) : 0;\n" + "}\n", + "\n", NIL); + Delete(bsmartnamestr); + Delete(smartnamestr); + Delete(bsmart); + } else { + Swig_error(Getfile(n), Getline(n), + "Invalid type (%s) in 'smartptr' feature for class %s.\n", + smartptr, c_class_name); + } + } else { + Printv(upcasts_code, + "SWIGEXPORT ", c_base_name, " * SWIGSTDCALL ", upcast_wrapper_name, + "(", c_base_name, " *objectRef) {\n", + " return (", c_base_name, " *)objectRef;\n" + "}\n", + "\n", NIL); + } + + Replaceall(upcasts_code, "$cclass", c_class_name); + Replaceall(upcasts_code, "$cbaseclass", c_base_name); + + Delete(upcast_name); + Delete(upcast_wrapper_name); + } + + /* --------------------------------------------------------------------------- + * D::writeTypeWrapperClass() + * --------------------------------------------------------------------------- */ + void writeTypeWrapperClass(String *classname, SwigType *type) { + Node *n = NewHash(); + Setfile(n, input_file); + Setline(n, line_number); + + assertClassNameValidity(classname); + + String* imports_target; + String* code_target; + File *class_file = NULL; + if (split_proxy_dmodule) { + String *filename = NewStringf("%s%s.d", dmodule_directory, classname); + class_file = NewFile(filename, "w", SWIG_output_files()); + if (!class_file) { + FileErrorDisplay(filename); + SWIG_exit(EXIT_FAILURE); + } + Append(filenames_list, Copy(filename)); + Delete(filename); + + emitBanner(class_file); + Printf(class_file, "module %s%s;\n", package, classname); + Printf(class_file, "\nstatic import %s;\n", wrap_dmodule_fq_name); + + imports_target = NewString(""); + code_target = NewString(""); + } else { + imports_target = proxy_dmodule_imports; + code_target = proxy_dmodule_code; + } + + // Import statements. + const String *imports = lookupCodeTypemap(n, "dimports", type, WARN_NONE); + if (Len(imports) > 0) { + String *imports_trimmed = Copy(imports); + Chop(imports_trimmed); + replaceImportTypeMacros(imports_trimmed); + Printv(imports_target, imports_trimmed, "\n", NIL); + Delete(imports_trimmed); + } + + // Pure D baseclass and interfaces (no C++ inheritance possible. + const String *pure_baseclass = lookupCodeTypemap(n, "dbase", type, WARN_NONE); + const String *pure_interfaces = lookupCodeTypemap(n, "dinterfaces", type, WARN_NONE); + + // Emit the class. + Printv(code_target, + "\n", + lookupCodeTypemap(n, "dclassmodifiers", type, WARN_D_TYPEMAP_CLASSMOD_UNDEF), + " $dclassname", + (*Char(pure_baseclass) || *Char(pure_interfaces)) ? " : " : "", pure_baseclass, + ((*Char(pure_baseclass)) && *Char(pure_interfaces)) ? ", " : "", pure_interfaces, + " {", NIL); + + String* body = NewString(""); + Printv(body, lookupCodeTypemap(n, "dbody", type, WARN_D_TYPEMAP_DBODY_UNDEF), + lookupCodeTypemap(n, "dcode", type, WARN_NONE), NIL); + indentCode(body); + Printv(code_target, body, "\n}\n", NIL); + Delete(body); + + Replaceall(code_target, "$dclassname", classname); + + if (split_proxy_dmodule) { + Printv(class_file, imports_target, NIL); + Delete(imports_target); + + replaceModuleVariables(code_target); + Printv(class_file, code_target, NIL); + Delete(code_target); + + Close(class_file); + Delete(class_file); + } + + Delete(n); + } + + /* --------------------------------------------------------------------------- + * D::writeDirectorConnectProxy() + * + * Writes the helper method which registers the director callbacks by calling + * the director connect function from the D side to the proxy class. + * --------------------------------------------------------------------------- */ + void writeDirectorConnectProxy() { + Printf(proxy_class_body_code, "\nprivate void swigDirectorConnect() {\n"); + + int i; + for (i = first_class_dmethod; i < curr_class_dmethod; ++i) { + UpcallData *udata = Getitem(dmethods_seq, i); + String *method = Getattr(udata, "method"); + String *overloaded_name = Getattr(udata, "overname"); + String *return_type = Getattr(udata, "return_type"); + String *param_list = Getattr(udata, "param_list"); + String *methid = Getattr(udata, "class_methodidx"); + Printf(proxy_class_body_code, " %s.SwigDirector_%s_Callback%s callback%s;\n", wrap_dmodule_fq_name, proxy_class_name, methid, methid); + Printf(proxy_class_body_code, " if (swigIsMethodOverridden!(%s delegate(%s), %s function(%s), %s)()) {\n", return_type, param_list, return_type, param_list, method); + Printf(proxy_class_body_code, " callback%s = &swigDirectorCallback_%s_%s;\n", methid, proxy_class_name, overloaded_name); + Printf(proxy_class_body_code, " }\n\n"); + } + Printf(proxy_class_body_code, " %s.%s_director_connect(cast(void*)swigCPtr, cast(void*)this", wrap_dmodule_fq_name, proxy_class_name); + for (i = first_class_dmethod; i < curr_class_dmethod; ++i) { + UpcallData *udata = Getitem(dmethods_seq, i); + String *methid = Getattr(udata, "class_methodidx"); + Printf(proxy_class_body_code, ", callback%s", methid); + } + Printf(proxy_class_body_code, ");\n"); + Printf(proxy_class_body_code, "}\n"); + + // Helper function to determine if a method has been overridden in a + // subclass of the wrapped class. If not, we just pass null to the + // director_connect_function since the method from the C++ class should + // be called as usual (see above). + // Only emit it if the proxy class has at least one method. + if (first_class_dmethod < curr_class_dmethod) { + Printf(proxy_class_body_code, "\n"); + Printf(proxy_class_body_code, "private bool swigIsMethodOverridden(DelegateType, FunctionType, alias fn)() {\n"); + Printf(proxy_class_body_code, " DelegateType dg = &fn;\n"); + Printf(proxy_class_body_code, " return dg.funcptr != SwigNonVirtualAddressOf!(FunctionType, fn);\n"); + Printf(proxy_class_body_code, "}\n"); + Printf(proxy_class_body_code, "\n"); + Printf(proxy_class_body_code, "private static Function SwigNonVirtualAddressOf(Function, alias fn)() {\n"); + Printf(proxy_class_body_code, " return cast(Function) &fn;\n"); + Printf(proxy_class_body_code, "}\n"); + } + + if (Len(director_dcallbacks_code) > 0) { + Printv(proxy_class_epilogue_code, director_dcallbacks_code, NIL); + } + + Delete(director_callback_typedefs); + director_callback_typedefs = NULL; + Delete(director_callback_pointers); + director_callback_pointers = NULL; + Delete(director_dcallbacks_code); + director_dcallbacks_code = NULL; + } + + /* --------------------------------------------------------------------------- + * D::writeDirectorConnectWrapper() + * + * Writes the director connect function and the corresponding declaration to + * the C++ wrapper respectively the D wrapper. + * --------------------------------------------------------------------------- */ + void writeDirectorConnectWrapper(Node *n) { + if (!Swig_directorclass(n)) + return; + + // Output the director connect method. + String *norm_name = SwigType_namestr(Getattr(n, "name")); + String *connect_name = NewStringf("%s_director_connect", proxy_class_name); + String *sym_name = Getattr(n, "sym:name"); + Wrapper *code_wrap; + + Printv(wrapper_loader_bind_code, wrapper_loader_bind_command, NIL); + Replaceall(wrapper_loader_bind_code, "$function", connect_name); + Replaceall(wrapper_loader_bind_code, "$symbol", Swig_name_wrapper(connect_name)); + + Printf(wrap_dmodule_code, "extern(C) void function(void* cObject, void* dObject"); + + code_wrap = NewWrapper(); + Printf(code_wrap->def, "SWIGEXPORT void SWIGSTDCALL D_%s(void *objarg, void *dobj", connect_name); + + Printf(code_wrap->code, " %s *obj = (%s *)objarg;\n", norm_name, norm_name); + Printf(code_wrap->code, " SwigDirector_%s *director = dynamic_cast(obj);\n", sym_name, sym_name); + + Printf(code_wrap->code, " if (director) {\n"); + Printf(code_wrap->code, " director->swig_connect_director(dobj"); + + for (int i = first_class_dmethod; i < curr_class_dmethod; ++i) { + UpcallData *udata = Getitem(dmethods_seq, i); + String *methid = Getattr(udata, "class_methodidx"); + + Printf(code_wrap->def, ", SwigDirector_%s::SWIG_Callback%s_t callback%s", sym_name, methid, methid); + Printf(code_wrap->code, ", callback%s", methid); + Printf(wrap_dmodule_code, ", SwigDirector_%s_Callback%s callback%s", sym_name, methid, methid); + } + + Printf(code_wrap->def, ") {\n"); + Printf(code_wrap->code, ");\n"); + Printf(wrap_dmodule_code, ") %s;\n", connect_name); + Printf(code_wrap->code, " }\n"); + Printf(code_wrap->code, "}\n"); + + Wrapper_print(code_wrap, f_wrappers); + DelWrapper(code_wrap); + + Delete(connect_name); + } + + /* --------------------------------------------------------------------------- + * D::requireDType() + * + * Adds an import statement for the given module to the header of current + * module. This is only used for dependencies created in generated code, user- + * (read: typemap-) specified import statements are handeled seperately. + * --------------------------------------------------------------------------- */ + void requireDType(const String *dmodule_name) { + String *import = createImportStatement(dmodule_name); + Append(import, "\n"); + if (is_wrapping_class()) { + addImportStatement(proxy_class_imports, import); + } else { + addImportStatement(proxy_dmodule_imports, import); + } + Delete(import); + } + + /* --------------------------------------------------------------------------- + * D::addImportStatement() + * + * Adds the given import statement to the given list of import statements if + * there is no statement importing that module present yet. + * --------------------------------------------------------------------------- */ + void addImportStatement(String *target, const String *import) const { + char *position = Strstr(target, import); + if (position) { + // If the import statement has been found in the target string, we have to + // check if the previous import was static, which would lead to problems + // if this import is not. + // Thus, we check if the seven characters in front of the occurence are + // »static «. If the import string passed is also static, the checks fail + // even if the found statement is also static because the last seven + // characters would be part of the previous import statement then. + + if (position - Char(target) < 7) { + return; + } + if (strncmp(position - 7, "static ", 7)) { + return; + } + } + + Printv(target, import, NIL); + } + + /* --------------------------------------------------------------------------- + * D::createImportStatement() + * + * Creates a string containing an import statement for the given module if it + * is needed in the currently generated proxy D module (i.e. if it is not the + * current module itself). + * --------------------------------------------------------------------------- */ + String *createImportStatement(const String *dmodule_name, + bool static_import = true) const { + + if (inProxyModule(dmodule_name)) { + return NewStringf(""); + } else { + if (static_import) { + return NewStringf("static import %s%s;", package, dmodule_name); + } else { + return NewStringf("import %s%s;", package, dmodule_name); + } + } + } + + /* --------------------------------------------------------------------------- + * D::inProxyModule() + * + * Determines if the specified proxy class is decleared in the currently + * processed proxy D module. + * + * This function is used to determine if fully qualified type names have to be + * used (package, module and type name). This is never the case if the split + * proxy mode is not used, all proxy types are written to the same module then. + * --------------------------------------------------------------------------- */ + bool inProxyModule(const String *type_name) const { + if (!split_proxy_dmodule) { + // If we are not in split proxy module mode, proxy code is always written + // to the same module. + return true; + } + + if (!Len(proxy_class_name)) { + return false; + } + + return (Strcmp(proxy_class_name, type_name) == 0); + } + + /* --------------------------------------------------------------------------- + * D::addUpcallMethod() + * + * Adds new director upcall signature. + * --------------------------------------------------------------------------- */ + UpcallData *addUpcallMethod(String *imclass_method, String *class_method, + String *decl, String *overloaded_name, String *return_type, String *param_list) { + + UpcallData *udata; + String *imclass_methodidx; + String *class_methodidx; + Hash *new_udata; + String *key = NewStringf("%s|%s", imclass_method, decl); + + ++curr_class_dmethod; + + /* Do we know about this director class already? */ + if ((udata = Getattr(dmethods_table, key))) { + Delete(key); + return Getattr(udata, "methodoff"); + } + + imclass_methodidx = NewStringf("%d", n_dmethods); + class_methodidx = NewStringf("%d", n_dmethods - first_class_dmethod); + n_dmethods++; + + new_udata = NewHash(); + Append(dmethods_seq, new_udata); + Setattr(dmethods_table, key, new_udata); + + Setattr(new_udata, "method", Copy(class_method)); + Setattr(new_udata, "class_methodidx", class_methodidx); + Setattr(new_udata, "decl", Copy(decl)); + Setattr(new_udata, "overname", Copy(overloaded_name)); + Setattr(new_udata, "return_type", Copy(return_type)); + Setattr(new_udata, "param_list", Copy(param_list)); + + Delete(key); + return new_udata; + } + + /* --------------------------------------------------------------------------- + * D::assertClassNameValidity() + * --------------------------------------------------------------------------- */ + void assertClassNameValidity(const String* class_name) const { + if (split_proxy_dmodule) { + if (Cmp(class_name, wrap_dmodule_name) == 0) { + Swig_error(input_file, line_number, "Class name cannot be equal to wrap D module name: %s\n", + class_name); + SWIG_exit(EXIT_FAILURE); + } + + if (Cmp(class_name, proxy_dmodule_name) == 0) { + Swig_error(input_file, line_number, "Class name cannot be equal to proxy D module name: %s\n", + class_name); + SWIG_exit(EXIT_FAILURE); + } + } + } + + /* --------------------------------------------------------------------------- + * D::getPrimitiveDptype() + * + * Returns the D proxy type for the passed type if it is a primitive type in + * both C and D. + * --------------------------------------------------------------------------- */ + String *getPrimitiveDptype(Node *node, SwigType *type) { + SwigType *stripped_type = SwigType_typedef_resolve_all(type); + + // A reference can only be the »outermost element« of a typ. + bool mutable_ref = false; + if (SwigType_isreference(stripped_type)) { + SwigType_del_reference(stripped_type); + + if (SwigType_isconst(stripped_type)) { + SwigType_del_qualifier(stripped_type); + } else { + mutable_ref = true; + } + } + + // Strip all the pointers from the type. + int indirection_count = 0; + while (SwigType_ispointer(stripped_type)) { + ++indirection_count; + SwigType_del_pointer(stripped_type); + } + + // Now that we got rid of the pointers, see if we are dealing with a + // primitive type. + String *dptype = 0; + if (SwigType_isfunction(stripped_type) && indirection_count > 0) { + // type was a function pointer, split it up. + SwigType_add_pointer(stripped_type); + --indirection_count; + + SwigType *return_type = Copy(stripped_type); + SwigType *params_type = SwigType_functionpointer_decompose(return_type); + String *return_dtype = getPrimitiveDptype(node, return_type); + Delete(return_type); + if (!return_dtype) { + return 0; + } + + List *parms = SwigType_parmlist(params_type); + List *param_dtypes = NewList(); + for (Iterator it = First(parms); it.item; it = Next(it)) { + String *current_dtype = getPrimitiveDptype(node, it.item); + if (Cmp(current_dtype, "void") == 0) { + // void somefunc(void) is legal syntax in C, but not in D, so simply + // skip the void parameter. + Delete(current_dtype); + continue; + } + if (!current_dtype) { + Delete(return_dtype); + Delete(param_dtypes); + return 0; + } + Append(param_dtypes, current_dtype); + } + + String *param_list = NewString(""); + { + bool gen_comma = false; + for (Iterator it = First(param_dtypes); it.item; it = Next(it)) { + if (gen_comma) { + Append(param_list, ", "); + } + Append(param_list, it.item); + Delete(it.item); + gen_comma = true; + } + } + + dptype = NewStringf("%s function(%s)", return_dtype, param_list); + Delete(param_list); + Delete(param_dtypes); + Delete(return_dtype); + } else { + Hash *attributes = NewHash(); + const String *tm = + lookupCodeTypemap(node, "dptype", stripped_type, WARN_NONE, attributes); + if(!GetFlag(attributes, "tmap:dptype:cprimitive")) { + dptype = 0; + } else { + dptype = Copy(tm); + + // We need to call replaceClassname here with the stripped type to avoid + // $dclassname in the enum typemaps being replaced later with the full + // type. + replaceClassname(dptype, stripped_type); + } + Delete(attributes); + } + Delete(stripped_type); + + if (!dptype) { + // The type passed is no primitive type. + return 0; + } + + // The type is ultimately a primitive type, now append the right number of + // indirection levels (pointers). + for (int i = 0; i < indirection_count; ++i) { + Append(dptype, "*"); + } + + // Add a level of indirection for a mutable reference since it is wrapped + // as a pointer. + if (mutable_ref) { + Append(dptype, "*"); + } + + return dptype; + } + + /* --------------------------------------------------------------------------- + * D::lookupCodeTypemap() + * + * Looks up a D code fragment for generating the wrapper class for the given + * type. + * + * n - for input only and must contain info for Getfile(n) and Getline(n) to work + * tmap_method - typemap method name + * type - typemap type to lookup + * warning - warning number to issue if no typemaps found + * typemap_attributes - the typemap attributes are attached to this node and will + * also be used for temporary storage if non null + * return is never NULL, unlike Swig_typemap_lookup() + * --------------------------------------------------------------------------- */ + const String *lookupCodeTypemap(Node *n, const_String_or_char_ptr tmap_method, + SwigType *type, int warning, Node *typemap_attributes = 0) const { + + Node *node = !typemap_attributes ? NewHash() : typemap_attributes; + Setattr(node, "type", type); + Setfile(node, Getfile(n)); + Setline(node, Getline(n)); + const String *tm = Swig_typemap_lookup(tmap_method, node, "", 0); + if (!tm) { + tm = empty_string; + if (warning != WARN_NONE) { + Swig_warning(warning, Getfile(n), Getline(n), + "No %s typemap defined for %s\n", tmap_method, SwigType_str(type, 0)); + } + } + if (!typemap_attributes) { + Delete(node); + } + + return tm; + } + + /* --------------------------------------------------------------------------- + * D::lookupDTypemap() + * + * Looks up a D typemap for the given node, replacing D-specific special + * variables as needed. + * + * The method parameter specifies the typemap method to use. If attached is + * true, the value is just fetched from the tmap: node attribute, + * Swig_typemap_lookup is used otherwise. + * --------------------------------------------------------------------------- */ + String *lookupDTypemap(Node *n, const_String_or_char_ptr method, bool attached = false) { + String *result = 0; + + if (attached) { + String *attr_name = NewStringf("tmap:%s", method); + result = Getattr(n, attr_name); + Delete(attr_name); + } else { + // FIXME: As a workaround for a bug so far only surfacing in the + // smart_pointer_const_overload test case, remove the nativepointer + // typemap attribute since it seems to be already there from a dout + // typemap of a different type in that test. + String *np_key = NewStringf("tmap:%s:nativepointer", method); + Delattr(n, np_key); + Delete(np_key); + + result = Swig_typemap_lookup(method, n, "", 0); + } + + if (!result) { + return 0; + } + + // Check if the passed node actually has type information attached. This + // is not the case e.g. in constructorWrapper. + SwigType *type = Getattr(n, "type"); + if (type) { + String *np_key = NewStringf("tmap:%s:nativepointer", method); + String *np_value = Getattr(n, np_key); + Delete(np_key); + String *dptype; + if (np_value && (dptype = getPrimitiveDptype(n, type))) { + // If the typemap in question has a »nativepointer« attribute and we + // are dealing with a primitive type, use it instead. + result = Copy(np_value); + Replaceall(result, "$dptype", dptype); + } + + replaceClassname(result, type); + } + + return result; + } + + /* --------------------------------------------------------------------------- + * D::replaceClassname() + * + * Replaces the special variable $dclassname with the proxy class name for + * classes/structs/unions SWIG knows about. Also substitutes the enumeration + * name for non-anonymous enums. Otherwise, $classname is replaced with a + * $descriptor(type)-like name. + * + * $*dclassname and $&classname work like with descriptors (see manual section + * 10.4.3), they remove a prointer from respectively add a pointer to the type. + * + * Inputs: + * tm - String to perform the substitution at (will usually come from a + * typemap. + * pt - The type to substitute for the variables. + * Outputs: + * tm - String with the variables substituted. + * Return: + * substitution_performed - flag indicating if a substitution was performed + * --------------------------------------------------------------------------- */ + bool replaceClassname(String *tm, SwigType *pt) { + bool substitution_performed = false; + SwigType *type = Copy(SwigType_typedef_resolve_all(pt)); + SwigType *strippedtype = SwigType_strip_qualifiers(type); + + if (Strstr(tm, "$dclassname")) { + SwigType *classnametype = Copy(strippedtype); + replaceClassnameVariable(tm, "$dclassname", classnametype); + substitution_performed = true; + Delete(classnametype); + } + if (Strstr(tm, "$*dclassname")) { + SwigType *classnametype = Copy(strippedtype); + Delete(SwigType_pop(classnametype)); + replaceClassnameVariable(tm, "$*dclassname", classnametype); + substitution_performed = true; + Delete(classnametype); + } + if (Strstr(tm, "$&dclassname")) { + SwigType *classnametype = Copy(strippedtype); + SwigType_add_pointer(classnametype); + replaceClassnameVariable(tm, "$&dclassname", classnametype); + substitution_performed = true; + Delete(classnametype); + } + + Delete(strippedtype); + Delete(type); + + return substitution_performed; + } + + /* --------------------------------------------------------------------------- + * D::replaceClassnameVariable() + * + * See D::replaceClassname(). + * --------------------------------------------------------------------------- */ + void replaceClassnameVariable(String *target, const char *variable, SwigType *type) { + // TODO: Fix const-correctness of methods called in here and make type const. + + // We make use of the fact that this function is called at least once for + // every type encountered which is written to a seperate file, which allows + // us to handle imports here. + // When working in split proxy module mode, each generated proxy class/enum + // is written to a seperate module. This requires us to add a corresponding + // import when a type is used in another generated module. If we are not + // working in split proxy module mode, this is not relevant and the + // generated module name is discarded. + String *import_name; + + String *qualified_type_name; + if (SwigType_isenum(type)) { + // RESEARCH: Make sure that we really cannot get here for anonymous enums. + Node *n = enumLookup(type); + const String *symname = Getattr(n, "sym:name"); + + // Add in class scope when referencing enum if not a global enum. + const String *parent_name = NULL; + String *scopename_prefix = Swig_scopename_prefix(Getattr(n, "name")); + if (scopename_prefix) { + parent_name = getProxyName(scopename_prefix); + Delete(scopename_prefix); + } + + if (parent_name) { + qualified_type_name = createQualifiedName(parent_name); + Printv(qualified_type_name, ".", symname, NIL); + + // An enum nested in a class is not written to a seperate module (this + // would not even be possible in D), so just import the parent. + import_name = Copy(parent_name); + } else { + qualified_type_name = createQualifiedName(symname); + + // A non-nested enum is written to a seperate module, import it. + import_name = Copy(symname); + } + } else { + const String *class_name = getProxyName(type); + if (class_name) { + // This is something wrapped as a proxy class (getProxyName() works for + // pointers to classes too). + qualified_type_name = createQualifiedName(class_name); + import_name = Copy(class_name); + } else { + // SWIG does not know anything about the type (after resolving typedefs). + // Just mangle the type name string like $descriptor(type) would do. + String *descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(type)); + qualified_type_name = createQualifiedName(descriptor); + import_name = Copy(descriptor); + + // Add to hash table so that a type wrapper class can be created later. + Setattr(unknown_types, descriptor, type); + + Delete(descriptor); + } + } + + Replaceall(target, variable, qualified_type_name); + Delete(qualified_type_name); + + requireDType(import_name); + Delete(import_name); + } + + /* --------------------------------------------------------------------------- + * D::createQualifiedName() + * --------------------------------------------------------------------------- */ + String *createQualifiedName(const String *class_name) const { + if (inProxyModule(class_name)) { + return Copy(class_name); + } else { + return NewStringf("%s%s.%s", package, class_name, class_name); + } +} + + /* --------------------------------------------------------------------------- + * D::replaceModuleVariables() + * + * Replaces the $wrapdmodule and $module variables with their values in the + * target string. + * --------------------------------------------------------------------------- */ + void replaceModuleVariables(String *target) const { + Replaceall(target, "$wrapdmodule", wrap_dmodule_fq_name); + Replaceall(target, "$module", proxy_dmodule_name); + } + + /* --------------------------------------------------------------------------- + * D::replaceExcode() + * + * If a C++ method can throw a exception, additional code is added to the + * proxy method to check if an exception is pending so that it can be + * rethrown on the D side. + * + * This method replaces the $excode variable with the exception handling code + * in the excode typemap attribute if it »canthrow« an exception. + * --------------------------------------------------------------------------- */ + void replaceExcode(Node *n, String *code, const String *typemap, Node *parameter) const { + String *excode_attribute = NewStringf("tmap:%s:excode", typemap); + String *excode = Getattr(parameter, excode_attribute); + if (Getattr(n, "d:canthrow")) { + int count = Replaceall(code, "$excode", excode); + if (count < 1 || !excode) { + Swig_warning(WARN_D_EXCODE_MISSING, input_file, line_number, + "D exception may not be thrown – no $excode or excode attribute in '%s' typemap.\n", + typemap); + } + } else { + Replaceall(code, "$excode", ""); + } + Delete(excode_attribute); + } + + /* --------------------------------------------------------------------------- + * D::replaceImportTypeMacros() + * + * Replaces the $importtype(SomeDClass) macro with an import statement if it + * is required to get SomeDClass in scope for the currently generated proxy + * D module. + * --------------------------------------------------------------------------- */ + void replaceImportTypeMacros(String *target) const { + // Code from replace_embedded_typemap. + char *start = 0; + while ((start = Strstr(target, "$importtype("))) { + char *end = 0; + char *param_start = 0; + char *param_end = 0; + int level = 0; + char *c = start; + while (*c) { + if (*c == '(') { + if (level == 0) { + param_start = c + 1; + } + level++; + } + if (*c == ')') { + level--; + if (level == 0) { + param_end = c; + end = c + 1; + break; + } + } + c++; + } + + if (end) { + String *current_macro = NewStringWithSize(start, (end - start)); + String *current_param = NewStringWithSize(param_start, (param_end - param_start)); + + String *import = createImportStatement(current_param, false); + Replace(target, current_macro, import, DOH_REPLACE_ANY); + Delete(import); + + Delete(current_param); + Delete(current_macro); + } else { + String *current_macro = NewStringWithSize(start, (c - start)); + Swig_error(Getfile(target), Getline(target), "Syntax error in: %s\n", current_macro); + Replace(target, current_macro, "", DOH_REPLACE_ANY); + Delete(current_macro); + } + } + } + + /* --------------------------------------------------------------------------- + * D::getOverloadedName() + * --------------------------------------------------------------------------- */ + String *getOverloadedName(Node *n) const { + // A void* parameter is used for all wrapped classes in the wrapper code. + // Thus, the wrapper function names for overloaded functions are postfixed + // with a counter string to make them unique. + String *overloaded_name = Copy(Getattr(n, "sym:name")); + + if (Getattr(n, "sym:overloaded")) { + Append(overloaded_name, Getattr(n, "sym:overname")); + } + + return overloaded_name; + } + + /* --------------------------------------------------------------------------- + * D::getProxyName() + * + * Returns the D class name if a type corresponds to something wrapped with a + * proxy class, NULL otherwise. + * --------------------------------------------------------------------------- */ + const String *getProxyName(SwigType *t) { + Node *n = classLookup(t); + if (n) { + return Getattr(n, "sym:name"); + } else { + return NULL; + } + } + + /* --------------------------------------------------------------------------- + * D::directorClassName() + * --------------------------------------------------------------------------- */ + String *getDirectorClassName(Node *n) const { + String *dirclassname; + const char *attrib = "director:classname"; + + if (!(dirclassname = Getattr(n, attrib))) { + String *classname = Getattr(n, "sym:name"); + + dirclassname = NewStringf("SwigDirector_%s", classname); + Setattr(n, attrib, dirclassname); + } + + return dirclassname; + } + + /* --------------------------------------------------------------------------- + * D::makeParameterName() + * + * Inputs: + * n - Node + * p - parameter node + * arg_num - parameter argument number + * setter - set this flag when wrapping variables + * Return: + * arg - a unique parameter name + * --------------------------------------------------------------------------- */ + String *makeParameterName(Node *n, Parm *p, int arg_num, bool setter) const { + String *arg = 0; + String *pn = Getattr(p, "name"); + + // Use C parameter name unless it is a duplicate or an empty parameter name + int count = 0; + ParmList *plist = Getattr(n, "parms"); + while (plist) { + if ((Cmp(pn, Getattr(plist, "name")) == 0)) + count++; + plist = nextSibling(plist); + } + String *wrn = pn ? Swig_name_warning(p, 0, pn, 0) : 0; + arg = (!pn || (count > 1) || wrn) ? NewStringf("arg%d", arg_num) : Copy(pn); + + if (setter && Cmp(arg, "self") != 0) { + // In theory, we could use the normal parameter name for setter functions. + // Unfortunately, it is set to "Class::VariableName" for static public + // members by the parser, which is not legal D syntax. Thus, we just force + // it to "value". + Delete(arg); + arg = NewString("value"); + } + + if (split_proxy_dmodule && Strncmp(arg, package, Len(arg)) == 0) { + // If we are in split proxy mode and the argument is named like the target + // package, we append an underscore to its name to avoid clashes. + Append(arg, "_"); + } + + return arg; + } + + /* --------------------------------------------------------------------------- + * D::canThrow() + * + * Determines whether the code in the typemap can throw a D exception. + * If so, note it for later when excodeSubstitute() is called. + * --------------------------------------------------------------------------- */ + void canThrow(Node *n, const String *typemap, Node *parameter) const { + String *canthrow_attribute = NewStringf("tmap:%s:canthrow", typemap); + String *canthrow = Getattr(parameter, canthrow_attribute); + if (canthrow) + Setattr(n, "d:canthrow", "1"); + Delete(canthrow_attribute); + } + + /* --------------------------------------------------------------------------- + * D::wrapMemberFunctionAsDConst() + * + * Determines whether the member function represented by the passed node is + * wrapped as D »const« or not. + * --------------------------------------------------------------------------- */ + bool wrapMemberFunctionAsDConst(Node *n) const { + if (d_version == 1) return false; + if (static_flag) return false; // Never emit »const« for static member functions. + return GetFlag(n, "memberget") || SwigType_isconst(Getattr(n, "decl")); + } + + /* --------------------------------------------------------------------------- + * D::areAllOverloadsOverridden() + * + * Determines whether the class the passed function node belongs to overrides + * all the overlaods for the passed function node defined somewhere up the + * inheritance hierachy. + * --------------------------------------------------------------------------- */ + bool areAllOverloadsOverridden(Node *n) const { + List *base_list = Getattr(parentNode(n), "bases"); + if (!base_list) { + // If the class which contains n is not derived from any other class, + // there cannot be any not-overridden overloads. + return true; + } + + // In case of multiple base classes, skip to the one which has not been + // ignored. + // RESEARCH: Also emit a warning in case of multiple inheritance here? + Iterator it = First(base_list); + while (it.item && GetFlag(it.item, "feature:ignore")) { + it = Next(it); + } + Node *base_class = it.item; + + if (!base_class) { + // If all base classes have been ignored, there cannot be one either. + return true; + } + + // We try to find at least a single overload which exists in the base class + // so we can progress up the inheritance hierachy even if there have been + // new overloads introduced after the topmost class. + Node *base_function = NULL; + for (Node *tmp = firstChild(base_class); tmp; tmp = nextSibling(tmp)) { + if (Strcmp(Getattr(tmp, "sym:name"), Getattr(n, "sym:name")) == 0) { + base_function = tmp; + break; + } + } + + if (!base_function) { + // If there is no overload which also exists in the super class, there + // cannot be any base class overloads not overridden. + return true; + } + + size_t base_overload_count = 0; + for (Node *tmp = firstSibling(base_function); tmp; tmp = Getattr(tmp, "sym:nextSibling")) { + if (is_protected(base_function) && + !(Swig_director_mode() && Swig_director_protected_mode() && Swig_all_protected_mode())) { + // If the base class function is »protected« and were are not in + // director mode, it is not emitted to the base class and thus we do + // not count it. Otherwise, we would run into issues if the visiblity + // of some functions was changed from protected to public in a child + // class with the using directive. + continue; + } + ++base_overload_count; + } + + return ((base_overload_count <= overridingOverloadCount(n)) && + areAllOverloadsOverridden(base_function)); + } + + /* --------------------------------------------------------------------------- + * D::overridingOverloadCount() + * + * Given a member function node, this function counts how many of the + * overloads of the function (including itself) override a function in the + * base class. + * --------------------------------------------------------------------------- */ + size_t overridingOverloadCount(Node *n) const { + size_t result = 0; + + Node *tmp = firstSibling(n); + do { + // KLUDGE: We also have to count the function if the access attribute is + // not present, since this means that it has been promoted into another + // protection level in the base class with the C++ »using« directive, and + // is thus taken into account when counting the base class overloads, even + // if it is not marked as »override« by the SWIG parser. + if (Getattr(n, "override") || !Getattr(n, "access")) { + ++result; + } + } while((tmp = Getattr(tmp, "sym:nextSibling"))); + + return result; + } + + /* --------------------------------------------------------------------------- + * D::firstSibling() + * + * Returns the first sibling of the passed node. + * --------------------------------------------------------------------------- */ + Node *firstSibling(Node *n) const { + Node *result = n; + while (Node *tmp = Getattr(result, "sym:previousSibling")) { + result = tmp; + } + return result; + } + + /* --------------------------------------------------------------------------- + * D::indentCode() + * + * Helper function to indent a code (string) by one level. + * --------------------------------------------------------------------------- */ + void indentCode(String* code) const { + Replaceall(code, "\n", "\n "); + Replaceall(code, " \n", "\n"); + Chop(code); + } + + /* --------------------------------------------------------------------------- + * D::emitBanner() + * --------------------------------------------------------------------------- */ + void emitBanner(File *f) const { + Printf(f, "/* ----------------------------------------------------------------------------\n"); + Swig_banner_target_lang(f, " *"); + Printf(f, " * ----------------------------------------------------------------------------- */\n\n"); + } +}; + +static Language *new_swig_d() { + return new D(); +} + +/* ----------------------------------------------------------------------------- + * swig_d() - Instantiate module + * ----------------------------------------------------------------------------- */ +extern "C" Language *swig_d(void) { + return new_swig_d(); +} + +/* ----------------------------------------------------------------------------- + * Usage information displayed at the command line. + * ----------------------------------------------------------------------------- */ +const char *D::usage = (char *) "\ +D Options (available with -d)\n\ + -splitproxy - Write each D type to a dedicated file instead of\n\ + generating a single proxy D module.\n\ + -noproxy - Generate the low-level functional interface instead\n\ + of proxy classes\n\ + -package - Write generated D modules into package \n\ + -wrapperlibrary - Sets the name of the wrapper library to \n\ +\n"; diff --git a/Source/Modules/swigmain.cxx b/Source/Modules/swigmain.cxx index 86cccdf88..01ab1b79f 100644 --- a/Source/Modules/swigmain.cxx +++ b/Source/Modules/swigmain.cxx @@ -52,6 +52,7 @@ extern "C" { Language *swig_uffi(void); Language *swig_r(void); Language *swig_go(void); + Language *swig_d(void); } struct swig_module { @@ -70,6 +71,7 @@ static swig_module modules[] = { {"-clisp", swig_clisp, "CLISP"}, {"-cffi", swig_cffi, "CFFI"}, {"-csharp", swig_csharp, "C#"}, + {"-d", swig_d, "D"}, {"-go", swig_go, "Go"}, {"-guile", swig_guile, "Guile"}, {"-java", swig_java, "Java"}, -- cgit v1.2.1 From d69d8ff641b28fdd7a6ddaeb724980060225fd3d Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Thu, 18 Nov 2010 10:16:05 +0000 Subject: [D] Renamed the "dnativeconst" feature to "dmanifestconst". This should make it clearer that it controls manifest constant generation, not handling of C++ const member functions. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12300 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/d.cxx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/d.cxx b/Source/Modules/d.cxx index e3e1d9759..4f48275fc 100644 --- a/Source/Modules/d.cxx +++ b/Source/Modules/d.cxx @@ -864,7 +864,7 @@ public: String *value = Getattr(n, "feature:d:constvalue"); // Note that in D, enum values must be compile-time constants. Thus, - // %dnativeconst(0) (getting the enum values at runtime) is not supported. + // %dmanifestconst(0) (getting the enum values at runtime) is not supported. value = value ? value : Getattr(n, "enumvalue"); if (value) { Printf(proxy_enum_code, " = %s", value); @@ -976,7 +976,7 @@ public: * D::staticmembervariableHandler() * --------------------------------------------------------------------------- */ virtual int staticmembervariableHandler(Node *n) { - if (GetFlag(n, "feature:d:nativeconst") != 1) { + if (GetFlag(n, "feature:d:manifestconst") != 1) { Delattr(n, "value"); } @@ -1298,7 +1298,7 @@ public: * Used for wrapping constants declared by #define or %constant and also for * (primitive) static member constants initialised inline. * - * If the %dnativeconst feature is used, the C/C++ constant value is used to + * If the %dmanifestconst feature is used, the C/C++ constant value is used to * initialize a D »const«. If not, a »getter« method is generated which * retrieves the value via a call to the C wrapper. However, if there is a * %dconstvalue specified, it overrides all other settings. @@ -1308,9 +1308,9 @@ public: if (!addSymbol(symname, n)) return SWIG_ERROR; - // The %dnativeconst feature determines if a D const or a getter function is - // created. - if (GetFlag(n, "feature:d:nativeconst") != 1) { + // The %dmanifestconst feature determines if a D manifest constant + // (const/enum) or a getter function is created. + if (GetFlag(n, "feature:d:manifestconst") != 1) { // Default constant handling will work with any type of C constant. It // generates a getter function (which is the same as a read only property // in D) which retrieves the value via by calling the C wrapper. -- cgit v1.2.1 From e362f85431c5cfa321870ea14431c803e1a2da7b Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Mon, 22 Nov 2010 00:33:26 +0000 Subject: [D] Use __cdecl instead of __stdcall on Windows as well to avoid special casing. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12303 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/d.cxx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/d.cxx b/Source/Modules/d.cxx index 4f48275fc..c4274bf63 100644 --- a/Source/Modules/d.cxx +++ b/Source/Modules/d.cxx @@ -1480,7 +1480,7 @@ public: if (!is_void_return) Wrapper_add_localv(f, "jresult", c_return_type, "jresult", NIL); - Printv(f->def, " SWIGEXPORT ", c_return_type, " SWIGSTDCALL ", wname, "(", NIL); + Printv(f->def, " SWIGEXPORT ", c_return_type, " ", wname, "(", NIL); // Emit all of the local variables for holding arguments. emit_parameter_variables(l, f); @@ -2308,7 +2308,7 @@ public: // Write the global callback function pointer on the C code. String *methid = Getattr(udata, "class_methodidx"); - Printf(director_callback_typedefs, " typedef %s (SWIGSTDCALL* SWIG_Callback%s_t)", c_ret_type, methid); + Printf(director_callback_typedefs, " typedef %s (* SWIG_Callback%s_t)", c_ret_type, methid); Printf(director_callback_typedefs, "(void *dobj%s);\n", callback_typedef_parms); Printf(director_callback_pointers, " SWIG_Callback%s_t swig_callback_%s;\n", methid, overloaded_name); @@ -3287,7 +3287,7 @@ private: String *smartnamestr = SwigType_namestr(smart); String *bsmartnamestr = SwigType_namestr(bsmart); Printv(upcasts_code, - "SWIGEXPORT ", bsmartnamestr, " * SWIGSTDCALL ", upcast_wrapper_name, + "SWIGEXPORT ", bsmartnamestr, " * ", upcast_wrapper_name, "(", smartnamestr, " *objectRef) {\n", " return objectRef ? new ", bsmartnamestr, "(*objectRef) : 0;\n" "}\n", @@ -3302,7 +3302,7 @@ private: } } else { Printv(upcasts_code, - "SWIGEXPORT ", c_base_name, " * SWIGSTDCALL ", upcast_wrapper_name, + "SWIGEXPORT ", c_base_name, " * ", upcast_wrapper_name, "(", c_base_name, " *objectRef) {\n", " return (", c_base_name, " *)objectRef;\n" "}\n", @@ -3480,7 +3480,7 @@ private: Printf(wrap_dmodule_code, "extern(C) void function(void* cObject, void* dObject"); code_wrap = NewWrapper(); - Printf(code_wrap->def, "SWIGEXPORT void SWIGSTDCALL D_%s(void *objarg, void *dobj", connect_name); + Printf(code_wrap->def, "SWIGEXPORT void D_%s(void *objarg, void *dobj", connect_name); Printf(code_wrap->code, " %s *obj = (%s *)objarg;\n", norm_name, norm_name); Printf(code_wrap->code, " SwigDirector_%s *director = dynamic_cast(obj);\n", sym_name, sym_name); -- cgit v1.2.1 From e0c82f6f2b5d550d45449979980a024fc822a34d Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 25 Nov 2010 20:35:10 +0000 Subject: portability fix git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12308 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/d.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Source/Modules') diff --git a/Source/Modules/d.cxx b/Source/Modules/d.cxx index c4274bf63..ce33b5252 100644 --- a/Source/Modules/d.cxx +++ b/Source/Modules/d.cxx @@ -1015,6 +1015,7 @@ public: ParmList *l = Getattr(n, "parms"); String *tm; String *proxy_constructor_code = NewString(""); + int i; // Holds code for the constructor helper method generated only when the din // typemap has code in the pre or post attributes. @@ -1060,7 +1061,7 @@ public: /* Output each parameter */ Parm *p = l; - for (unsigned int i = 0; p; i++) { + for (i = 0; p; i++) { if (checkAttribute(p, "varargs:ignore", "1")) { // Skip ignored varargs. p = nextSibling(p); -- cgit v1.2.1 From 004643ff30118e7a61484f329bfeebebfb202053 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 25 Nov 2010 20:39:11 +0000 Subject: Fix mangling of PHP constructor wrapper when types use global scope or typedefs git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12309 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/php.cxx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index 05f2082c2..b95eaa7cd 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -1601,10 +1601,9 @@ public: Delete(args); args = NewString("$res=null"); } - SwigType *t = Getattr(current_class, "classtype"); - String *mangled_type = SwigType_manglestr(SwigType_ltype(t)); + String *mangled_type = SwigType_manglestr(Getattr(n, "type")); Printf(output, "\t%sfunction %s(%s) {\n", acc, methodname, args); - Printf(output, "\t\tif (is_resource($%s) && get_resource_type($%s) === '_p%s') {\n", arg0, arg0, mangled_type); + Printf(output, "\t\tif (is_resource($%s) && get_resource_type($%s) === '%s') {\n", arg0, arg0, mangled_type); Printf(output, "\t\t\t$this->%s=$%s;\n", SWIG_PTR, arg0); Printf(output, "\t\t\treturn;\n"); Printf(output, "\t\t}\n"); -- cgit v1.2.1 From 75ad4f57b94728e6ecfb0ad29e985ea483672555 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 26 Nov 2010 20:28:39 +0000 Subject: Incorrect mangling leading to some cast errors in the Go director destructors git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12315 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/go.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Modules') diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx index d3de53f8f..6e8d2c09a 100644 --- a/Source/Modules/go.cxx +++ b/Source/Modules/go.cxx @@ -2679,7 +2679,7 @@ private: Setattr(n, "wrap:name", fnname); - Swig_DestructorToFunction(n, getNSpace(), Getattr(parentNode(n), "classtype"), CPlusPlus, Extend); + Swig_DestructorToFunction(n, getNSpace(), getClassType(), CPlusPlus, Extend); ParmList *parms = Getattr(n, "parms"); Setattr(n, "wrap:parms", parms); -- cgit v1.2.1 From a22df2eca9d1726fa7af02cebc459eb373ed7fc7 Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Sat, 27 Nov 2010 00:13:44 +0000 Subject: [D] Refer to the built-in Exception class using its fully-qualified name. A C++ class called "Exception" could shadow the built-in one before, leading to compilation errors in the exception handling code. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12318 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/d.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Modules') diff --git a/Source/Modules/d.cxx b/Source/Modules/d.cxx index ce33b5252..c726ac022 100644 --- a/Source/Modules/d.cxx +++ b/Source/Modules/d.cxx @@ -3216,7 +3216,7 @@ private: if (*Char(destructor_call)) { Replaceall(dispose_code, "$wcall", destructor_call); } else { - Replaceall(dispose_code, "$wcall", "throw new Exception(\"C++ destructor does not have public access\")"); + Replaceall(dispose_code, "$wcall", "throw new object.Exception(\"C++ destructor does not have public access\")"); } if (*Char(dispose_code)) { -- cgit v1.2.1 From 3477a9dff13227605d51433df50935b87f5f73af Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Sun, 28 Nov 2010 23:12:03 +0000 Subject: [D] Replaced the term "wrap D module" with "intermediary D module" (including names derived from it). This was suggested by wsfulton on the mailing list in order to bring the D module in line with the C# one, the naming scheme of which is intended to be language-independent. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12319 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/d.cxx | 419 +++++++++++++++++++++++++-------------------------- 1 file changed, 209 insertions(+), 210 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/d.cxx b/Source/Modules/d.cxx index c726ac022..63da28a81 100644 --- a/Source/Modules/d.cxx +++ b/Source/Modules/d.cxx @@ -91,10 +91,10 @@ class D : public Language { * Names of generated D entities. */ // The name of the D module containing the interface to the C wrapper. - String *wrap_dmodule_name; + String *im_dmodule_name; // The fully qualified name of the wrap D module (package name included). - String *wrap_dmodule_fq_name; + String *im_dmodule_fq_name; // The name of the proxy module which exposes the (SWIG) module contents as a // D module. @@ -120,12 +120,12 @@ class D : public Language { /* * Variables temporarily holding the generated D code. */ - // Import statements written to the wrap D module header set via - // %pragma(d) wrapdmoduleimports. - String *wrap_dmodule_imports; + // Import statements written to the intermediary D module header set via + // %pragma(d) imdmoduleimports. + String *im_dmodule_imports; - // The code for the wrap D module body. - String *wrap_dmodule_code; + // The code for the intermediary D module body. + String *im_dmodule_code; // Import statements for all proxy modules (the main proxy module and, if in // split proxy module mode, the proxy class modules) from @@ -140,7 +140,7 @@ class D : public Language { // module. If not in split proxy mode, this contains the whole proxy code. String *proxy_dmodule_code; - // The D code generated for the currently wrapped enum. + // The D code generated for the currently processed enum. String *proxy_enum_code; /* @@ -176,14 +176,14 @@ class D : public Language { /* * Code for dynamically loading the wrapper library on the D side. */ - // D code which is inserted into the wrapper module if dynamic linking is used. + // D code which is inserted into the im D module if dynamic linking is used. String *wrapper_loader_code; // The D code to bind a function pointer to a library symbol. String *wrapper_loader_bind_command; - // The cumulated binding commands binding all wrapper functions to the C/C++ - // library symbols. + // The cumulated binding commands binding all the functions declared in the + // intermediary D module to the C/C++ library symbols. String *wrapper_loader_bind_code; /* @@ -231,15 +231,15 @@ public: upcasts_code(NULL), director_callback_typedefs(NULL), director_callback_pointers(NULL), - wrap_dmodule_name(NULL), - wrap_dmodule_fq_name(NULL), + im_dmodule_name(NULL), + im_dmodule_fq_name(NULL), proxy_dmodule_name(NULL), proxy_dmodule_fq_name(NULL), package(NULL), dmodule_directory(NULL), wrap_library_name(NULL), - wrap_dmodule_imports(NULL), - wrap_dmodule_code(NULL), + im_dmodule_imports(NULL), + im_dmodule_code(NULL), global_proxy_imports(NULL), proxy_dmodule_imports(NULL), proxy_dmodule_code(NULL), @@ -335,8 +335,8 @@ public: Node *optionsnode = Getattr(Getattr(n, "module"), "options"); if (optionsnode) { - if (Getattr(optionsnode, "wrapdmodulename")) { - wrap_dmodule_name = Copy(Getattr(optionsnode, "wrapdmodulename")); + if (Getattr(optionsnode, "imdmodulename")) { + im_dmodule_name = Copy(Getattr(optionsnode, "imdmodulename")); } if (Getattr(optionsnode, "directors")) { @@ -423,14 +423,14 @@ public: // Make the wrap and proxy D module names. // The wrap module name can be set in the module directive. - if (!wrap_dmodule_name) { - wrap_dmodule_name = NewStringf("%s_wrap", Getattr(n, "name")); + if (!im_dmodule_name) { + im_dmodule_name = NewStringf("%s_im", Getattr(n, "name")); } - wrap_dmodule_fq_name = NewStringf("%s%s", package, wrap_dmodule_name); + im_dmodule_fq_name = NewStringf("%s%s", package, im_dmodule_name); proxy_dmodule_name = Copy(Getattr(n, "name")); proxy_dmodule_fq_name = NewStringf("%s%s", package, proxy_dmodule_name); - wrap_dmodule_code = NewString(""); + im_dmodule_code = NewString(""); proxy_class_imports = NewString(""); proxy_class_enums_code = NewString(""); proxy_class_body_code = NewString(""); @@ -439,7 +439,7 @@ public: destructor_call = NewString(""); proxy_dmodule_code = NewString(""); proxy_dmodule_imports = NewString(""); - wrap_dmodule_imports = NewString(""); + im_dmodule_imports = NewString(""); upcasts_code = NewString(""); global_proxy_imports = NewString(""); wrapper_loader_code = NewString(""); @@ -450,10 +450,9 @@ public: n_dmethods = 0; // By default, expect the dynamically loaded wrapper library to be named - // like the wrapper D module (i.e. [lib]_wrap[.so/.dll] unless the - // user overrides it). + // [lib]_wrap[.so/.dll]. if (!wrap_library_name) - wrap_library_name = Copy(wrap_dmodule_name); + wrap_library_name = NewStringf("%s_wrap", Getattr(n, "name")); Swig_banner(f_begin); @@ -496,9 +495,9 @@ public: // Generate the wrap D module. // TODO: Add support for »static« linking. { - String *filen = NewStringf("%s%s.d", dmodule_directory, wrap_dmodule_name); - File *wrap_d_file = NewFile(filen, "w", SWIG_output_files()); - if (!wrap_d_file) { + String *filen = NewStringf("%s%s.d", dmodule_directory, im_dmodule_name); + File *im_d_file = NewFile(filen, "w", SWIG_output_files()); + if (!im_d_file) { FileErrorDisplay(filen); SWIG_exit(EXIT_FAILURE); } @@ -507,22 +506,22 @@ public: filen = NULL; // Start writing out the intermediary class file. - emitBanner(wrap_d_file); + emitBanner(im_d_file); - Printf(wrap_d_file, "module %s;\n", wrap_dmodule_fq_name); + Printf(im_d_file, "module %s;\n", im_dmodule_fq_name); - Printv(wrap_d_file, wrap_dmodule_imports, "\n", NIL); + Printv(im_d_file, im_dmodule_imports, "\n", NIL); Replaceall(wrapper_loader_code, "$wraplibrary", wrap_library_name); Replaceall(wrapper_loader_code, "$wrapperloaderbindcode", wrapper_loader_bind_code); Replaceall(wrapper_loader_code, "$module", proxy_dmodule_name); - Printf(wrap_d_file, "%s\n", wrapper_loader_code); + Printf(im_d_file, "%s\n", wrapper_loader_code); // Add the wrapper function declarations. - replaceModuleVariables(wrap_dmodule_code); - Printv(wrap_d_file, wrap_dmodule_code, NIL); + replaceModuleVariables(im_dmodule_code); + Printv(im_d_file, im_dmodule_code, NIL); - Close(wrap_d_file); + Close(im_d_file); } // Generate the D proxy module for the wrapped module. @@ -540,7 +539,7 @@ public: emitBanner(proxy_d_file); Printf(proxy_d_file, "module %s;\n", proxy_dmodule_fq_name); - Printf(proxy_d_file, "\nstatic import %s;\n", wrap_dmodule_fq_name); + Printf(proxy_d_file, "\nstatic import %s;\n", im_dmodule_fq_name); Printv(proxy_d_file, global_proxy_imports, NIL); Printv(proxy_d_file, proxy_dmodule_imports, NIL); Printv(proxy_d_file, "\n", NIL); @@ -588,12 +587,12 @@ public: unknown_types = NULL; Delete(filenames_list); filenames_list = NULL; - Delete(wrap_dmodule_name); - wrap_dmodule_name = NULL; - Delete(wrap_dmodule_fq_name); - wrap_dmodule_fq_name = NULL; - Delete(wrap_dmodule_code); - wrap_dmodule_code = NULL; + Delete(im_dmodule_name); + im_dmodule_name = NULL; + Delete(im_dmodule_fq_name); + im_dmodule_fq_name = NULL; + Delete(im_dmodule_code); + im_dmodule_code = NULL; Delete(proxy_class_imports); proxy_class_imports = NULL; Delete(proxy_class_enums_code); @@ -614,8 +613,8 @@ public: proxy_dmodule_code = NULL; Delete(proxy_dmodule_imports); proxy_dmodule_imports = NULL; - Delete(wrap_dmodule_imports); - wrap_dmodule_imports = NULL; + Delete(im_dmodule_imports); + im_dmodule_imports = NULL; Delete(upcasts_code); upcasts_code = NULL; Delete(global_proxy_imports); @@ -681,17 +680,17 @@ public: * D::pragmaDirective() * * Valid Pragmas: - * wrapdmodulecode - text (D code) is copied verbatim to the wrap module - * wrapdmoduleimports - import statements for the wrap module + * imdmodulecode - text (D code) is copied verbatim to the wrap module + * imdmoduleimports - import statements for the im D module * * proxydmodulecode - text (D code) is copied verbatim to the proxy module * (the main proxy module if in split proxy mode). * globalproxyimports - import statements inserted into _all_ proxy modules. * * wrapperloadercode - D code for loading the wrapper library (is copied to - * the wrap D module). + * the im D module). * wrapperloaderbindcommand - D code for binding a symbol from the wrapper - * library to the declaration in the wrap D module. + * library to the declaration in the im D module. * --------------------------------------------------------------------------- */ virtual int pragmaDirective(Node *n) { if (!ImportMode) { @@ -703,12 +702,12 @@ public: String *strvalue = NewString(value); Replaceall(strvalue, "\\\"", "\""); - if (Strcmp(code, "wrapdmodulecode") == 0) { - Printf(wrap_dmodule_code, "%s\n", strvalue); - } else if (Strcmp(code, "wrapdmoduleimports") == 0) { + if (Strcmp(code, "imdmodulecode") == 0) { + Printf(im_dmodule_code, "%s\n", strvalue); + } else if (Strcmp(code, "imdmoduleimports") == 0) { replaceImportTypeMacros(strvalue); Chop(strvalue); - Printf(wrap_dmodule_imports, "%s\n", strvalue); + Printf(im_dmodule_imports, "%s\n", strvalue); } else if (Strcmp(code, "proxydmodulecode") == 0) { Printf(proxy_dmodule_code, "%s\n", strvalue); } else if (Strcmp(code, "globalproxyimports") == 0) { @@ -1035,24 +1034,24 @@ public: // Typemaps were attached earlier to the node, get the return type of the // call to the C++ constructor wrapper. - const String *wrapper_return_type = lookupDTypemap(n, "dwtype", true); + const String *wrapper_return_type = lookupDTypemap(n, "imtype", true); - String *dwtypeout = Getattr(n, "tmap:dwtype:out"); - if (dwtypeout) { - // The type in the dwtype typemap's out attribute overrides the type in + String *imtypeout = Getattr(n, "tmap:imtype:out"); + if (imtypeout) { + // The type in the imtype typemap's out attribute overrides the type in // the typemap itself. - wrapper_return_type = dwtypeout; + wrapper_return_type = imtypeout; } Printf(proxy_constructor_code, "\n%s this(", methodmods); Printf(helper_code, "static private %s SwigConstruct%s(", wrapper_return_type, proxy_class_name); - Printv(imcall, wrap_dmodule_fq_name, ".", mangled_overname, "(", NIL); + Printv(imcall, im_dmodule_fq_name, ".", mangled_overname, "(", NIL); /* Attach the non-standard typemaps to the parameter list */ Swig_typemap_attach_parms("in", l, NULL); - Swig_typemap_attach_parms("dptype", l, NULL); + Swig_typemap_attach_parms("dtype", l, NULL); Swig_typemap_attach_parms("din", l, NULL); emit_mark_varargs(l); @@ -1078,12 +1077,12 @@ public: String *param_type = NewString(""); // Get the D parameter type. - if ((tm = lookupDTypemap(p, "dptype", true))) { - const String *inattributes = Getattr(p, "tmap:dptype:inattributes"); + if ((tm = lookupDTypemap(p, "dtype", true))) { + const String *inattributes = Getattr(p, "tmap:dtype:inattributes"); Printf(param_type, "%s%s", inattributes ? inattributes : empty_string, tm); } else { - Swig_warning(WARN_D_TYPEMAP_DPTYPE_UNDEF, input_file, line_number, - "No dptype typemap defined for %s\n", SwigType_str(pt, 0)); + Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number, + "No dtype typemap defined for %s\n", SwigType_str(pt, 0)); } if (gencomma) @@ -1093,7 +1092,7 @@ public: String *parmtype = 0; // Get the D code to convert the parameter value to the type used in the - // wrapper D module. + // intermediary D module. if ((tm = lookupDTypemap(p, "din"))) { Replaceall(tm, "$dinput", arg); String *pre = Getattr(p, "tmap:din:pre"); @@ -1198,10 +1197,10 @@ public: Printf(helper_code, "\n}\n"); String *helper_name = NewStringf("%s.SwigConstruct%s(%s)", proxy_class_name, proxy_class_name, helper_args); - Replaceall(proxy_constructor_code, "$wcall", helper_name); + Replaceall(proxy_constructor_code, "$imcall", helper_name); Delete(helper_name); } else { - Replaceall(proxy_constructor_code, "$wcall", imcall); + Replaceall(proxy_constructor_code, "$imcall", imcall); } Printv(proxy_class_body_code, proxy_constructor_code, "\n", NIL); @@ -1224,7 +1223,7 @@ public: virtual int destructorHandler(Node *n) { Language::destructorHandler(n); String *symname = Getattr(n, "sym:name"); - Printv(destructor_call, wrap_dmodule_fq_name, ".", Swig_name_destroy(NSPACE_TODO,symname), "(cast(void*)swigCPtr)", NIL); + Printv(destructor_call, im_dmodule_fq_name, ".", Swig_name_destroy(NSPACE_TODO,symname), "(cast(void*)swigCPtr)", NIL); return SWIG_OK; } @@ -1254,7 +1253,7 @@ public: emitBanner(class_file); Printf(class_file, "module %s%s;\n", package, proxy_class_name); - Printf(class_file, "\nstatic import %s;\n", wrap_dmodule_fq_name); + Printf(class_file, "\nstatic import %s;\n", im_dmodule_fq_name); } Clear(proxy_class_imports); @@ -1342,23 +1341,23 @@ public: ParmList *l = Getattr(n, "parms"); // Attach the non-standard typemaps to the parameter list. - Swig_typemap_attach_parms("dptype", l, NULL); + Swig_typemap_attach_parms("dtype", l, NULL); // Get D return type. String *return_type = NewString(""); String *tm; - if ((tm = lookupDTypemap(n, "dptype"))) { - String *dptypeout = Getattr(n, "tmap:dptype:out"); - if (dptypeout) { + if ((tm = lookupDTypemap(n, "dtype"))) { + String *dtypeout = Getattr(n, "tmap:dtype:out"); + if (dtypeout) { // The type in the out attribute of the typemap overrides the type - // in the dptype typemap. - tm = dptypeout; + // in the dtype typemap. + tm = dtypeout; replaceClassname(tm, t); } Printf(return_type, "%s", tm); } else { - Swig_warning(WARN_D_TYPEMAP_DPTYPE_UNDEF, input_file, line_number, - "No dptype typemap defined for %s\n", SwigType_str(t, 0)); + Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number, + "No dtype typemap defined for %s\n", SwigType_str(t, 0)); } const String *itemname = wrapping_member_flag ? variable_name : symname; @@ -1448,33 +1447,33 @@ public: String *wname = Swig_name_wrapper(overloaded_name); /* Attach the non-standard typemaps to the parameter list. */ - Swig_typemap_attach_parms("cwtype", l, f); - Swig_typemap_attach_parms("dwtype", l, f); + Swig_typemap_attach_parms("ctype", l, f); + Swig_typemap_attach_parms("imtype", l, f); /* Get return types */ - if ((tm = lookupDTypemap(n, "cwtype"))) { - String *cwtypeout = Getattr(n, "tmap:cwtype:out"); - if (cwtypeout) { - // The type in the cwtype typemap's out attribute overrides the type in + if ((tm = lookupDTypemap(n, "ctype"))) { + String *ctypeout = Getattr(n, "tmap:ctype:out"); + if (ctypeout) { + // The type in the ctype typemap's out attribute overrides the type in // the typemap itself. - tm = cwtypeout; + tm = ctypeout; } Printf(c_return_type, "%s", tm); } else { - Swig_warning(WARN_D_TYPEMAP_CWTYPE_UNDEF, input_file, line_number, - "No cwtype typemap defined for %s\n", SwigType_str(t, 0)); + Swig_warning(WARN_D_TYPEMAP_CTYPE_UNDEF, input_file, line_number, + "No ctype typemap defined for %s\n", SwigType_str(t, 0)); } - if ((tm = lookupDTypemap(n, "dwtype"))) { - String *dwtypeout = Getattr(n, "tmap:dwtype:out"); - if (dwtypeout) { - // The type in the dwtype typemap's out attribute overrides the type in + if ((tm = lookupDTypemap(n, "imtype"))) { + String *imtypeout = Getattr(n, "tmap:imtype:out"); + if (imtypeout) { + // The type in the imtype typemap's out attribute overrides the type in // the typemap itself. - tm = dwtypeout; + tm = imtypeout; } Printf(im_return_type, "%s", tm); } else { - Swig_warning(WARN_D_TYPEMAP_DWTYPE_UNDEF, input_file, line_number, "No dwtype typemap defined for %s\n", SwigType_str(t, 0)); + Swig_warning(WARN_D_TYPEMAP_IMTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(t, 0)); } is_void_return = (Cmp(c_return_type, "void") == 0); @@ -1501,9 +1500,9 @@ public: return SWIG_OK; } - // Collect the parameter list for the wrap D module declaration of the - // generated wrapper function. - String *wrap_dmodule_parameters = NewString("("); + // Collect the parameter list for the intermediary D module declaration of + // the generated wrapper function. + String *im_dmodule_parameters = NewString("("); /* Get number of required and total arguments */ num_arguments = emit_num_arguments(l); @@ -1525,25 +1524,25 @@ public: Printf(arg, "j%s", ln); - /* Get the cwtype types of the parameter */ - if ((tm = lookupDTypemap(p, "cwtype", true))) { + /* Get the ctype types of the parameter */ + if ((tm = lookupDTypemap(p, "ctype", true))) { Printv(c_param_type, tm, NIL); } else { - Swig_warning(WARN_D_TYPEMAP_CWTYPE_UNDEF, input_file, line_number, "No cwtype typemap defined for %s\n", SwigType_str(pt, 0)); + Swig_warning(WARN_D_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s\n", SwigType_str(pt, 0)); } /* Get the intermediary class parameter types of the parameter */ - if ((tm = lookupDTypemap(p, "dwtype", true))) { - const String *inattributes = Getattr(p, "tmap:dwtype:inattributes"); + if ((tm = lookupDTypemap(p, "imtype", true))) { + const String *inattributes = Getattr(p, "tmap:imtype:inattributes"); Printf(im_param_type, "%s%s", inattributes ? inattributes : empty_string, tm); } else { - Swig_warning(WARN_D_TYPEMAP_DWTYPE_UNDEF, input_file, line_number, "No dwtype typemap defined for %s\n", SwigType_str(pt, 0)); + Swig_warning(WARN_D_TYPEMAP_IMTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(pt, 0)); } /* Add parameter to intermediary class method */ if (gencomma) - Printf(wrap_dmodule_parameters, ", "); - Printf(wrap_dmodule_parameters, "%s %s", im_param_type, arg); + Printf(im_dmodule_parameters, ", "); + Printf(im_dmodule_parameters, "%s %s", im_param_type, arg); // Add parameter to C function Printv(f->def, gencomma ? ", " : "", c_param_type, " ", arg, NIL); @@ -1674,11 +1673,11 @@ public: } } - // Complete D wrapper parameter list and emit the declaration/binding code. - Printv(wrap_dmodule_parameters, ")", NIL); - writeWrapDModuleFunction(overloaded_name, im_return_type, - wrap_dmodule_parameters, wname); - Delete(wrap_dmodule_parameters); + // Complete D im parameter list and emit the declaration/binding code. + Printv(im_dmodule_parameters, ")", NIL); + writeImDModuleFunction(overloaded_name, im_return_type, + im_dmodule_parameters, wname); + Delete(im_dmodule_parameters); // Finish C function header. Printf(f->def, ") {"); @@ -1931,32 +1930,32 @@ public: /* Create the intermediate class wrapper */ Parm *tp = NewParm(returntype, empty_str, n); - tm = lookupDTypemap(tp, "dwtype"); + tm = lookupDTypemap(tp, "imtype"); if (tm) { - String *dwtypeout = Getattr(tp, "tmap:dwtype:out"); - if (dwtypeout) { - // The type in the dwtype typemap's out attribute overrides the type + String *imtypeout = Getattr(tp, "tmap:imtype:out"); + if (imtypeout) { + // The type in the imtype typemap's out attribute overrides the type // in the typemap. - tm = dwtypeout; + tm = imtypeout; } Printf(callback_def, "\nprivate extern(C) %s swigDirectorCallback_%s_%s(void* dObject", tm, classname, overloaded_name); Printv(proxy_callback_return_type, tm, NIL); } else { - Swig_warning(WARN_D_TYPEMAP_DWTYPE_UNDEF, input_file, line_number, - "No dwtype typemap defined for %s\n", SwigType_str(returntype, 0)); + Swig_warning(WARN_D_TYPEMAP_IMTYPE_UNDEF, input_file, line_number, + "No imtype typemap defined for %s\n", SwigType_str(returntype, 0)); } Parm *retpm = NewParm(returntype, empty_str, n); - if ((c_ret_type = Swig_typemap_lookup("cwtype", retpm, "", 0))) { + if ((c_ret_type = Swig_typemap_lookup("ctype", retpm, "", 0))) { if (!is_void && !ignored_method) { String *jretval_decl = NewStringf("%s jresult", c_ret_type); Wrapper_add_localv(w, "jresult", jretval_decl, "= 0", NIL); Delete(jretval_decl); } } else { - Swig_warning(WARN_D_TYPEMAP_CWTYPE_UNDEF, input_file, line_number, - "No cwtype typemap defined for %s for use in %s::%s (skipping director method)\n", + Swig_warning(WARN_D_TYPEMAP_CTYPE_UNDEF, input_file, line_number, + "No ctype typemap defined for %s for use in %s::%s (skipping director method)\n", SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); output_director = false; } @@ -1980,9 +1979,9 @@ public: // Attach the standard typemaps. Swig_typemap_attach_parms("out", l, 0); - Swig_typemap_attach_parms("cwtype", l, 0); - Swig_typemap_attach_parms("dwtype", l, 0); - Swig_typemap_attach_parms("dptype", l, 0); + Swig_typemap_attach_parms("ctype", l, 0); + Swig_typemap_attach_parms("imtype", l, 0); + Swig_typemap_attach_parms("dtype", l, 0); Swig_typemap_attach_parms("directorin", l, 0); Swig_typemap_attach_parms("ddirectorin", l, 0); @@ -2026,12 +2025,12 @@ public: Printf(dcallback_call_args, ", %s", arg); /* Get parameter's intermediary C type */ - if ((c_param_type = lookupDTypemap(p, "cwtype", true))) { - String *cwtypeout = Getattr(p, "tmap:cwtype:out"); - if (cwtypeout) { - // The type in the cwtype typemap's out attribute overrides the type + if ((c_param_type = lookupDTypemap(p, "ctype", true))) { + String *ctypeout = Getattr(p, "tmap:ctype:out"); + if (ctypeout) { + // The type in the ctype typemap's out attribute overrides the type // in the typemap itself. - c_param_type = cwtypeout; + c_param_type = ctypeout; } Parm *tp = NewParm(c_param_type, empty_str, n); @@ -2060,14 +2059,14 @@ public: /* Add parameter to the intermediate class code if generating the * intermediate's upcall code */ - if ((tm = lookupDTypemap(p, "dwtype", true))) { - String *dwtypeout = Getattr(p, "tmap:dwtype:out"); - if (dwtypeout) { - // The type in the dwtype typemap's out attribute overrides the + if ((tm = lookupDTypemap(p, "imtype", true))) { + String *imtypeout = Getattr(p, "tmap:imtype:out"); + if (imtypeout) { + // The type in the imtype typemap's out attribute overrides the // type in the typemap itself. - tm = dwtypeout; + tm = imtypeout; } - const String *im_directorinattributes = Getattr(p, "tmap:dwtype:directorinattributes"); + const String *im_directorinattributes = Getattr(p, "tmap:imtype:directorinattributes"); // TODO: Is this copy really needed? String *din = Copy(lookupDTypemap(p, "ddirectorin", true)); @@ -2093,11 +2092,11 @@ public: // Get the parameter type in the proxy D class (used later when // generating the overload checking code for the directorConnect // function). - if ((tm = lookupDTypemap(p, "dptype", true))) { + if ((tm = lookupDTypemap(p, "dtype", true))) { Printf(proxy_method_param_list, "%s", tm); } else { - Swig_warning(WARN_D_TYPEMAP_DPTYPE_UNDEF, input_file, line_number, - "No dptype typemap defined for %s\n", SwigType_str(pt, 0)); + Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number, + "No dtype typemap defined for %s\n", SwigType_str(pt, 0)); } } else { Swig_warning(WARN_D_TYPEMAP_DDIRECTORIN_UNDEF, input_file, line_number, @@ -2106,8 +2105,8 @@ public: output_director = false; } } else { - Swig_warning(WARN_D_TYPEMAP_DWTYPE_UNDEF, input_file, line_number, - "No dwtype typemap defined for %s for use in %s::%s (skipping director method)\n", + Swig_warning(WARN_D_TYPEMAP_IMTYPE_UNDEF, input_file, line_number, + "No imtype typemap defined for %s for use in %s::%s (skipping director method)\n", SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); output_director = false; } @@ -2133,8 +2132,8 @@ public: Delete(tp); } else { - Swig_warning(WARN_D_TYPEMAP_CWTYPE_UNDEF, input_file, line_number, - "No cwtype typemap defined for %s for use in %s::%s (skipping director method)\n", + Swig_warning(WARN_D_TYPEMAP_CTYPE_UNDEF, input_file, line_number, + "No ctype typemap defined for %s for use in %s::%s (skipping director method)\n", SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); output_director = false; p = nextSibling(p); @@ -2198,7 +2197,7 @@ public: // RESEARCH: What happens if there is no ddirectorout typemap? if ((tm = lookupDTypemap(tp, "ddirectorout"))) { - Replaceall(tm, "$dpcall", upcall); + Replaceall(tm, "$dcall", upcall); Printf(callback_code, " return %s;\n", tm); } @@ -2288,18 +2287,18 @@ public: // the full return type any longer after Language::functionHandler has // returned. Parm *tp = NewParm(returntype, empty_str, n); - String *dp_return_type = lookupDTypemap(tp, "dptype"); + String *dp_return_type = lookupDTypemap(tp, "dtype"); if (dp_return_type) { - String *dptypeout = Getattr(n, "tmap:dptype:out"); - if (dptypeout) { - // The type in the dptype typemap's out attribute overrides the type + String *dtypeout = Getattr(n, "tmap:dtype:out"); + if (dtypeout) { + // The type in the dtype typemap's out attribute overrides the type // in the typemap itself. - dp_return_type = dptypeout; + dp_return_type = dtypeout; replaceClassname(dp_return_type, returntype); } } else { - Swig_warning(WARN_D_TYPEMAP_DPTYPE_UNDEF, input_file, line_number, - "No dptype typemap defined for %s\n", SwigType_str(type, 0)); + Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number, + "No dtype typemap defined for %s\n", SwigType_str(type, 0)); dp_return_type = NewString(""); } @@ -2313,10 +2312,10 @@ public: Printf(director_callback_typedefs, "(void *dobj%s);\n", callback_typedef_parms); Printf(director_callback_pointers, " SWIG_Callback%s_t swig_callback_%s;\n", methid, overloaded_name); - // Write the type alias for the callback to the wrap D module. + // Write the type alias for the callback to the intermediary D module. String* proxy_callback_type = NewString(""); Printf(proxy_callback_type, "SwigDirector_%s_Callback%s", classname, methid); - Printf(wrap_dmodule_code, "alias extern(C) %s function(void*%s) %s;\n", proxy_callback_return_type, delegate_parms, proxy_callback_type); + Printf(im_dmodule_code, "alias extern(C) %s function(void*%s) %s;\n", proxy_callback_return_type, delegate_parms, proxy_callback_type); Delete(proxy_callback_type); } @@ -2519,21 +2518,21 @@ protected: private: /* --------------------------------------------------------------------------- - * D::writeWrapDModuleFunction() + * D::writeImDModuleFunction() * * Writes a function declaration for the given (C) wrapper function to the - * wrap D module. + * intermediary D module. * - * d_name - The name the function in the D wrap module will get. + * d_name - The name the function in the intermediary D module will get. * wrapper_function_name - The name of the exported function in the C wrapper * (usually d_name prefixed by »D_«). * --------------------------------------------------------------------------- */ - void writeWrapDModuleFunction(const_String_or_char_ptr d_name, + void writeImDModuleFunction(const_String_or_char_ptr d_name, const_String_or_char_ptr return_type, const_String_or_char_ptr parameters, const_String_or_char_ptr wrapper_function_name) { // TODO: Add support for static linking here. - Printf(wrap_dmodule_code, "extern(C) %s function%s %s;\n", return_type, + Printf(im_dmodule_code, "extern(C) %s function%s %s;\n", return_type, parameters, d_name); Printv(wrapper_loader_bind_code, wrapper_loader_bind_command, NIL); Replaceall(wrapper_loader_bind_code, "$function", d_name); @@ -2548,7 +2547,7 @@ private: * * The Node must contain two extra attributes. * - "proxyfuncname": The name of the D proxy function. - * - "imfuncname": The corresponding function in the wrap D module. + * - "imfuncname": The corresponding function in the intermediary D module. * --------------------------------------------------------------------------- */ void writeProxyClassFunction(Node *n) { SwigType *t = Getattr(n, "type"); @@ -2585,22 +2584,22 @@ private: /* Attach the non-standard typemaps to the parameter list */ Swig_typemap_attach_parms("in", l, NULL); - Swig_typemap_attach_parms("dptype", l, NULL); + Swig_typemap_attach_parms("dtype", l, NULL); Swig_typemap_attach_parms("din", l, NULL); // Get return types. - if ((tm = lookupDTypemap(n, "dptype"))) { - String *dptypeout = Getattr(n, "tmap:dptype:out"); - if (dptypeout) { - // The type in the dptype typemap's out attribute overrides the type in + if ((tm = lookupDTypemap(n, "dtype"))) { + String *dtypeout = Getattr(n, "tmap:dtype:out"); + if (dtypeout) { + // The type in the dtype typemap's out attribute overrides the type in // the typemap. - tm = dptypeout; + tm = dtypeout; replaceClassname(tm, t); } Printf(return_type, "%s", tm); } else { - Swig_warning(WARN_D_TYPEMAP_DPTYPE_UNDEF, input_file, line_number, - "No dptype typemap defined for %s\n", SwigType_str(t, 0)); + Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number, + "No dtype typemap defined for %s\n", SwigType_str(t, 0)); } if (wrapping_member_flag) { @@ -2644,7 +2643,7 @@ private: Printf(function_code, "%s %s(", return_type, proxy_function_name); // Write the wrapper function call up to the parameter list. - Printv(imcall, wrap_dmodule_fq_name, ".$imfuncname(", NIL); + Printv(imcall, im_dmodule_fq_name, ".$imfuncname(", NIL); if (!static_flag) { Printf(imcall, "cast(void*)swigCPtr"); } @@ -2714,12 +2713,12 @@ private: { String *proxy_type = NewString(""); - if ((tm = lookupDTypemap(p, "dptype"))) { - const String *inattributes = Getattr(p, "tmap:dptype:inattributes"); + if ((tm = lookupDTypemap(p, "dtype"))) { + const String *inattributes = Getattr(p, "tmap:dtype:inattributes"); Printf(proxy_type, "%s%s", inattributes ? inattributes : empty_string, tm); } else { - Swig_warning(WARN_D_TYPEMAP_DPTYPE_UNDEF, input_file, line_number, - "No dptype typemap defined for %s\n", SwigType_str(pt, 0)); + Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number, + "No dtype typemap defined for %s\n", SwigType_str(pt, 0)); } if (gencomma >= 2) @@ -2801,7 +2800,7 @@ private: } else { Replaceall(imcall, "$imfuncname", intermediary_function_name); } - Replaceall(tm, "$wcall", imcall); + Replaceall(tm, "$imcall", imcall); } else { Swig_warning(WARN_D_TYPEMAP_DOUT_UNDEF, input_file, line_number, "No dout typemap defined for %s\n", SwigType_str(t, 0)); @@ -2851,22 +2850,22 @@ private: } /* Attach the non-standard typemaps to the parameter list */ - Swig_typemap_attach_parms("dptype", l, NULL); + Swig_typemap_attach_parms("dtype", l, NULL); Swig_typemap_attach_parms("din", l, NULL); /* Get return types */ - if ((tm = lookupDTypemap(n, "dptype"))) { - String *dptypeout = Getattr(n, "tmap:dptype:out"); - if (dptypeout) { - // The type in the dptype typemap's out attribute overrides the type in + if ((tm = lookupDTypemap(n, "dtype"))) { + String *dtypeout = Getattr(n, "tmap:dtype:out"); + if (dtypeout) { + // The type in the dtype typemap's out attribute overrides the type in // the typemap. - tm = dptypeout; + tm = dtypeout; replaceClassname(tm, t); } Printf(return_type, "%s", tm); } else { - Swig_warning(WARN_D_TYPEMAP_DPTYPE_UNDEF, input_file, line_number, - "No dptype typemap defined for %s\n", SwigType_str(t, 0)); + Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number, + "No dtype typemap defined for %s\n", SwigType_str(t, 0)); } /* Change function name for global variables */ @@ -2878,7 +2877,7 @@ private: } /* Start generating the function */ - const String *outattributes = Getattr(n, "tmap:dptype:outattributes"); + const String *outattributes = Getattr(n, "tmap:dtype:outattributes"); if (outattributes) Printf(function_code, " %s\n", outattributes); @@ -2888,7 +2887,7 @@ private: methodmods = methodmods ? methodmods : empty_string; Printf(function_code, "\n%s%s %s(", methodmods, return_type, func_name); - Printv(imcall, wrap_dmodule_fq_name, ".", overloaded_name, "(", NIL); + Printv(imcall, im_dmodule_fq_name, ".", overloaded_name, "(", NIL); /* Get number of required and total arguments */ num_arguments = emit_num_arguments(l); @@ -2908,12 +2907,12 @@ private: String *param_type = NewString(""); // Get the D parameter type. - if ((tm = lookupDTypemap(p, "dptype", true))) { - const String *inattributes = Getattr(p, "tmap:dptype:inattributes"); + if ((tm = lookupDTypemap(p, "dtype", true))) { + const String *inattributes = Getattr(p, "tmap:dtype:inattributes"); Printf(param_type, "%s%s", inattributes ? inattributes : empty_string, tm); } else { - Swig_warning(WARN_D_TYPEMAP_DPTYPE_UNDEF, input_file, line_number, - "No dptype typemap defined for %s\n", SwigType_str(pt, 0)); + Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number, + "No dtype typemap defined for %s\n", SwigType_str(pt, 0)); } if (gencomma) @@ -3003,7 +3002,7 @@ private: else Replaceall(tm, "$owner", "false"); replaceClassname(tm, t); - Replaceall(tm, "$wcall", imcall); + Replaceall(tm, "$imcall", imcall); } else { Swig_warning(WARN_D_TYPEMAP_DOUT_UNDEF, input_file, line_number, "No dout typemap defined for %s\n", SwigType_str(t, 0)); @@ -3214,9 +3213,9 @@ private: Printv(dispose_code, tm, NIL); if (*Char(destructor_call)) { - Replaceall(dispose_code, "$wcall", destructor_call); + Replaceall(dispose_code, "$imcall", destructor_call); } else { - Replaceall(dispose_code, "$wcall", "throw new object.Exception(\"C++ destructor does not have public access\")"); + Replaceall(dispose_code, "$imcall", "throw new object.Exception(\"C++ destructor does not have public access\")"); } if (*Char(dispose_code)) { @@ -3271,7 +3270,7 @@ private: String *upcast_wrapper_name = Swig_name_wrapper(upcast_name); - writeWrapDModuleFunction(upcast_name, "void*", "(void* objectRef)", + writeImDModuleFunction(upcast_name, "void*", "(void* objectRef)", upcast_wrapper_name); if (smartptr) { @@ -3342,7 +3341,7 @@ private: emitBanner(class_file); Printf(class_file, "module %s%s;\n", package, classname); - Printf(class_file, "\nstatic import %s;\n", wrap_dmodule_fq_name); + Printf(class_file, "\nstatic import %s;\n", im_dmodule_fq_name); imports_target = NewString(""); code_target = NewString(""); @@ -3415,12 +3414,12 @@ private: String *return_type = Getattr(udata, "return_type"); String *param_list = Getattr(udata, "param_list"); String *methid = Getattr(udata, "class_methodidx"); - Printf(proxy_class_body_code, " %s.SwigDirector_%s_Callback%s callback%s;\n", wrap_dmodule_fq_name, proxy_class_name, methid, methid); + Printf(proxy_class_body_code, " %s.SwigDirector_%s_Callback%s callback%s;\n", im_dmodule_fq_name, proxy_class_name, methid, methid); Printf(proxy_class_body_code, " if (swigIsMethodOverridden!(%s delegate(%s), %s function(%s), %s)()) {\n", return_type, param_list, return_type, param_list, method); Printf(proxy_class_body_code, " callback%s = &swigDirectorCallback_%s_%s;\n", methid, proxy_class_name, overloaded_name); Printf(proxy_class_body_code, " }\n\n"); } - Printf(proxy_class_body_code, " %s.%s_director_connect(cast(void*)swigCPtr, cast(void*)this", wrap_dmodule_fq_name, proxy_class_name); + Printf(proxy_class_body_code, " %s.%s_director_connect(cast(void*)swigCPtr, cast(void*)this", im_dmodule_fq_name, proxy_class_name); for (i = first_class_dmethod; i < curr_class_dmethod; ++i) { UpcallData *udata = Getitem(dmethods_seq, i); String *methid = Getattr(udata, "class_methodidx"); @@ -3478,7 +3477,7 @@ private: Replaceall(wrapper_loader_bind_code, "$function", connect_name); Replaceall(wrapper_loader_bind_code, "$symbol", Swig_name_wrapper(connect_name)); - Printf(wrap_dmodule_code, "extern(C) void function(void* cObject, void* dObject"); + Printf(im_dmodule_code, "extern(C) void function(void* cObject, void* dObject"); code_wrap = NewWrapper(); Printf(code_wrap->def, "SWIGEXPORT void D_%s(void *objarg, void *dobj", connect_name); @@ -3495,12 +3494,12 @@ private: Printf(code_wrap->def, ", SwigDirector_%s::SWIG_Callback%s_t callback%s", sym_name, methid, methid); Printf(code_wrap->code, ", callback%s", methid); - Printf(wrap_dmodule_code, ", SwigDirector_%s_Callback%s callback%s", sym_name, methid, methid); + Printf(im_dmodule_code, ", SwigDirector_%s_Callback%s callback%s", sym_name, methid, methid); } Printf(code_wrap->def, ") {\n"); Printf(code_wrap->code, ");\n"); - Printf(wrap_dmodule_code, ") %s;\n", connect_name); + Printf(im_dmodule_code, ") %s;\n", connect_name); Printf(code_wrap->code, " }\n"); Printf(code_wrap->code, "}\n"); @@ -3647,8 +3646,8 @@ private: * --------------------------------------------------------------------------- */ void assertClassNameValidity(const String* class_name) const { if (split_proxy_dmodule) { - if (Cmp(class_name, wrap_dmodule_name) == 0) { - Swig_error(input_file, line_number, "Class name cannot be equal to wrap D module name: %s\n", + if (Cmp(class_name, im_dmodule_name) == 0) { + Swig_error(input_file, line_number, "Class name cannot be equal to intermediary D module name: %s\n", class_name); SWIG_exit(EXIT_FAILURE); } @@ -3691,7 +3690,7 @@ private: // Now that we got rid of the pointers, see if we are dealing with a // primitive type. - String *dptype = 0; + String *dtype = 0; if (SwigType_isfunction(stripped_type) && indirection_count > 0) { // type was a function pointer, split it up. SwigType_add_pointer(stripped_type); @@ -3736,29 +3735,29 @@ private: } } - dptype = NewStringf("%s function(%s)", return_dtype, param_list); + dtype = NewStringf("%s function(%s)", return_dtype, param_list); Delete(param_list); Delete(param_dtypes); Delete(return_dtype); } else { Hash *attributes = NewHash(); const String *tm = - lookupCodeTypemap(node, "dptype", stripped_type, WARN_NONE, attributes); - if(!GetFlag(attributes, "tmap:dptype:cprimitive")) { - dptype = 0; + lookupCodeTypemap(node, "dtype", stripped_type, WARN_NONE, attributes); + if(!GetFlag(attributes, "tmap:dtype:cprimitive")) { + dtype = 0; } else { - dptype = Copy(tm); + dtype = Copy(tm); // We need to call replaceClassname here with the stripped type to avoid // $dclassname in the enum typemaps being replaced later with the full // type. - replaceClassname(dptype, stripped_type); + replaceClassname(dtype, stripped_type); } Delete(attributes); } Delete(stripped_type); - if (!dptype) { + if (!dtype) { // The type passed is no primitive type. return 0; } @@ -3766,16 +3765,16 @@ private: // The type is ultimately a primitive type, now append the right number of // indirection levels (pointers). for (int i = 0; i < indirection_count; ++i) { - Append(dptype, "*"); + Append(dtype, "*"); } // Add a level of indirection for a mutable reference since it is wrapped // as a pointer. if (mutable_ref) { - Append(dptype, "*"); + Append(dtype, "*"); } - return dptype; + return dtype; } /* --------------------------------------------------------------------------- @@ -3854,12 +3853,12 @@ private: String *np_key = NewStringf("tmap:%s:nativepointer", method); String *np_value = Getattr(n, np_key); Delete(np_key); - String *dptype; - if (np_value && (dptype = getPrimitiveDptype(n, type))) { + String *dtype; + if (np_value && (dtype = getPrimitiveDptype(n, type))) { // If the typemap in question has a »nativepointer« attribute and we // are dealing with a primitive type, use it instead. result = Copy(np_value); - Replaceall(result, "$dptype", dptype); + Replaceall(result, "$dtype", dtype); } replaceClassname(result, type); @@ -4007,11 +4006,11 @@ private: /* --------------------------------------------------------------------------- * D::replaceModuleVariables() * - * Replaces the $wrapdmodule and $module variables with their values in the + * Replaces the $imdmodule and $module variables with their values in the * target string. * --------------------------------------------------------------------------- */ void replaceModuleVariables(String *target) const { - Replaceall(target, "$wrapdmodule", wrap_dmodule_fq_name); + Replaceall(target, "$imdmodule", im_dmodule_fq_name); Replaceall(target, "$module", proxy_dmodule_name); } -- cgit v1.2.1 From d87c312fd0db86072633e4d219452c26d0d76f43 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 29 Nov 2010 07:49:42 +0000 Subject: Corrections to calls to SwigType_manglestr to use a genuine SwigType git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12320 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/go.cxx | 4 ++-- Source/Modules/lua.cxx | 2 +- Source/Modules/mzscheme.cxx | 2 +- Source/Modules/tcl8.cxx | 5 +---- 4 files changed, 5 insertions(+), 8 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx index 6e8d2c09a..ac8ba333d 100644 --- a/Source/Modules/go.cxx +++ b/Source/Modules/go.cxx @@ -1128,7 +1128,7 @@ private: Parm *base_parm = NULL; if (base && !isStatic(n)) { - SwigType *base_type = Copy(Getattr(class_node, "classtype")); + SwigType *base_type = Copy(getClassType()); SwigType_add_pointer(base_type); base_parm = NewParm(base_type, NewString("arg1"), n); set_nextSibling(base_parm, parms); @@ -1244,7 +1244,7 @@ private: Parm *base_parm = NULL; if (base && !isStatic(n)) { - SwigType *base_type = Copy(Getattr(class_node, "classtype")); + SwigType *base_type = Copy(getClassType()); SwigType_add_pointer(base_type); base_parm = NewParm(base_type, NewString("arg1"), n); set_nextSibling(base_parm, parms); diff --git a/Source/Modules/lua.cxx b/Source/Modules/lua.cxx index d240d3d6f..d0cbc9195 100644 --- a/Source/Modules/lua.cxx +++ b/Source/Modules/lua.cxx @@ -919,7 +919,7 @@ public: String *wrap_class = NewStringf("&_wrap_class_%s", mangled_classname); SwigType_remember_clientdata(t, wrap_class); - String *rt = Copy(Getattr(n, "classtype")); + String *rt = Copy(getClassType()); SwigType_add_pointer(rt); // Register the class structure with the type checker diff --git a/Source/Modules/mzscheme.cxx b/Source/Modules/mzscheme.cxx index 0bc3c8a68..d071dc870 100644 --- a/Source/Modules/mzscheme.cxx +++ b/Source/Modules/mzscheme.cxx @@ -682,7 +682,7 @@ public: String *mangled_classname = 0; String *real_classname = 0; String *scm_structname = NewString(""); - SwigType *ctype_ptr = NewStringf("p.%s", Getattr(n, "classtype")); + SwigType *ctype_ptr = NewStringf("p.%s", getClassType()); SwigType *t = NewStringf("p.%s", Getattr(n, "name")); swigtype_ptr = SwigType_manglestr(t); diff --git a/Source/Modules/tcl8.cxx b/Source/Modules/tcl8.cxx index b6b4c6965..dfdd71b64 100644 --- a/Source/Modules/tcl8.cxx +++ b/Source/Modules/tcl8.cxx @@ -783,10 +783,7 @@ public: String *wrap_class = NewStringf("&_wrap_class_%s", mangled_classname); SwigType_remember_clientdata(t, wrap_class); - // t = Copy(Getattr(n,"classtype")); - // SwigType_add_pointer(t); - - String *rt = Copy(Getattr(n, "classtype")); + String *rt = Copy(getClassType()); SwigType_add_pointer(rt); // Register the class structure with the type checker -- cgit v1.2.1 From 61fefd8cc4c5cb71cdc15dd758a44407bd0d46fe Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 7 Dec 2010 20:12:17 +0000 Subject: Remove bad usage of a String rather than SwigType for csharp directors git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12325 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/csharp.cxx | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index e0c4a4332..6ecd18aed 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -3641,17 +3641,13 @@ public: if (ctypeout) c_param_type = ctypeout; - Parm *tp = NewParm(c_param_type, empty_str, n); - String *desc_tm = NULL; - /* Add to local variables */ Printf(c_decl, "%s %s", c_param_type, arg); if (!ignored_method) Wrapper_add_localv(w, arg, c_decl, (!(SwigType_ispointer(pt) || SwigType_isreference(pt)) ? "" : "= 0"), NIL); /* Add input marshalling code */ - if ((desc_tm = Swig_typemap_lookup("directorin", tp, "", 0)) - && (tm = Getattr(p, "tmap:directorin"))) { + if ((tm = Getattr(p, "tmap:directorin"))) { Replaceall(tm, "$input", arg); Replaceall(tm, "$owner", "0"); @@ -3716,24 +3712,13 @@ public: p = Getattr(p, "tmap:directorin:next"); - Delete(desc_tm); } else { - if (!desc_tm) { - Swig_warning(WARN_CSHARP_TYPEMAP_CSDIRECTORIN_UNDEF, input_file, line_number, - "No or improper directorin typemap defined for %s for use in %s::%s (skipping director method)\n", - SwigType_str(c_param_type, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - p = nextSibling(p); - } else if (!tm) { - Swig_warning(WARN_CSHARP_TYPEMAP_CSDIRECTORIN_UNDEF, input_file, line_number, - "No or improper directorin typemap defined for argument %s for use in %s::%s (skipping director method)\n", - SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - p = nextSibling(p); - } - + Swig_warning(WARN_CSHARP_TYPEMAP_CSDIRECTORIN_UNDEF, input_file, line_number, + "No or improper directorin typemap defined for argument %s for use in %s::%s (skipping director method)\n", + SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); + p = nextSibling(p); output_director = false; } - - Delete(tp); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s for use in %s::%s (skipping director method)\n", SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); -- cgit v1.2.1 From 5558d0092acaf666804421795a7e631fe8dcec88 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 7 Dec 2010 21:15:05 +0000 Subject: Remove bad usage of a String rather than SwigType for D directors git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12330 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/d.cxx | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/d.cxx b/Source/Modules/d.cxx index 63da28a81..986079d65 100644 --- a/Source/Modules/d.cxx +++ b/Source/Modules/d.cxx @@ -2033,17 +2033,13 @@ public: c_param_type = ctypeout; } - Parm *tp = NewParm(c_param_type, empty_str, n); - String *desc_tm = NULL; - /* Add to local variables */ Printf(c_decl, "%s %s", c_param_type, arg); if (!ignored_method) Wrapper_add_localv(w, arg, c_decl, (!(SwigType_ispointer(pt) || SwigType_isreference(pt)) ? "" : "= 0"), NIL); /* Add input marshalling code */ - if ((desc_tm = Swig_typemap_lookup("directorin", tp, "", 0)) - && (tm = Getattr(p, "tmap:directorin"))) { + if ((tm = Getattr(p, "tmap:directorin"))) { Replaceall(tm, "$input", arg); Replaceall(tm, "$owner", "0"); @@ -2068,7 +2064,7 @@ public: } const String *im_directorinattributes = Getattr(p, "tmap:imtype:directorinattributes"); - // TODO: Is this copy really needed? + // TODO: Is this copy really needed? String *din = Copy(lookupDTypemap(p, "ddirectorin", true)); if (din) { @@ -2087,7 +2083,7 @@ public: Printv(imcall_args, ln, NIL); } - Delete(din); + Delete(din); // Get the parameter type in the proxy D class (used later when // generating the overload checking code for the directorConnect @@ -2112,25 +2108,13 @@ public: } p = Getattr(p, "tmap:directorin:next"); - - Delete(desc_tm); } else { - if (!desc_tm) { - Swig_warning(WARN_D_TYPEMAP_DDIRECTORIN_UNDEF, input_file, line_number, - "No or improper directorin typemap defined for %s for use in %s::%s (skipping director method)\n", - SwigType_str(c_param_type, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - p = nextSibling(p); - } else if (!tm) { - Swig_warning(WARN_D_TYPEMAP_DDIRECTORIN_UNDEF, input_file, line_number, - "No or improper directorin typemap defined for argument %s for use in %s::%s (skipping director method)\n", - SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - p = nextSibling(p); - } - + Swig_warning(WARN_D_TYPEMAP_DDIRECTORIN_UNDEF, input_file, line_number, + "No or improper directorin typemap defined for argument %s for use in %s::%s (skipping director method)\n", + SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); + p = nextSibling(p); output_director = false; } - - Delete(tp); } else { Swig_warning(WARN_D_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s for use in %s::%s (skipping director method)\n", -- cgit v1.2.1 From bb2d75892074cf87f12b5706958f63d1eb6f0980 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 15 Dec 2010 20:37:40 +0000 Subject: Use a SwigType instead of String where expected including call to SwigType_manglestr git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12348 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/ocaml.cxx | 45 ++++++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 27 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/ocaml.cxx b/Source/Modules/ocaml.cxx index 82e3f846a..6021cf276 100644 --- a/Source/Modules/ocaml.cxx +++ b/Source/Modules/ocaml.cxx @@ -35,7 +35,7 @@ static String *classname = 0; static String *module = 0; static String *init_func_def = 0; static String *f_classtemplate = 0; -static String *name_qualifier = 0; +static SwigType *name_qualifier_type = 0; static Hash *seen_enums = 0; static Hash *seen_enumvalues = 0; @@ -898,12 +898,12 @@ public: String *name = Getattr(n, "feature:symname"); SwigType *type = Getattr(n, "type"); String *value = Getattr(n, "value"); - String *qvalue = Getattr(n, "qualified:value"); + SwigType *qname = Getattr(n, "qualified:name"); String *rvalue = NewString(""); String *temp = 0; - if (qvalue) - value = qvalue; + if (qname) + value = qname; if (!name) { name = mangleNameForCaml(Getattr(n, "name")); @@ -1228,20 +1228,18 @@ public: return out; } - String *fully_qualify_enum_name(Node *n, String *name) { + SwigType *fully_qualified_enum_type(Node *n) { Node *parent = 0; - String *qualification = NewString(""); String *fully_qualified_name = NewString(""); String *parent_type = 0; - String *normalized_name; parent = parentNode(n); while (parent) { parent_type = nodeType(parent); if (Getattr(parent, "name")) { String *parent_copy = NewStringf("%s::", Getattr(parent, "name")); - if (!Cmp(parent_type, "class") || !Cmp(parent_type, "namespace")) - Insert(qualification, 0, parent_copy); + if (Cmp(parent_type, "class") == 0 || Cmp(parent_type, "namespace") == 0) + Insert(fully_qualified_name, 0, parent_copy); Delete(parent_copy); } if (!Cmp(parent_type, "class")) @@ -1249,25 +1247,18 @@ public: parent = parentNode(parent); } - Printf(fully_qualified_name, "%s%s", qualification, name); - - normalized_name = normalizeTemplatedClassName(fully_qualified_name); - if (!strncmp(Char(normalized_name), "enum ", 5)) { - Insert(normalized_name, 5, qualification); - } - - return normalized_name; + return fully_qualified_name; } /* Benedikt Grundmann inspired --> Enum wrap styles */ int enumvalueDeclaration(Node *n) { String *name = Getattr(n, "name"); - String *qvalue = 0; + SwigType *qtype = 0; - if (name_qualifier) { - qvalue = Copy(name_qualifier); - Printv(qvalue, name, NIL); + if (name_qualifier_type) { + qtype = Copy(name_qualifier_type); + Printv(qtype, name, NIL); } if (const_enum && name && !Getattr(seen_enumvalues, name)) { @@ -1275,10 +1266,10 @@ public: SetFlag(n, "feature:immutable"); Setattr(n, "feature:enumvalue", "1"); // this does not appear to be used - if (qvalue) - Setattr(n, "qualified:value", qvalue); + if (qtype) + Setattr(n, "qualified:name", SwigType_namestr(qtype)); - String *evname = SwigType_manglestr(qvalue); + String *evname = SwigType_manglestr(qtype); Insert(evname, 0, "SWIG_ENUM_"); Setattr(n, "feature:enumvname", name); @@ -1309,10 +1300,10 @@ public: /* name is now fully qualified */ String *fully_qualified_name = NewString(name); bool seen_enum = false; - if (name_qualifier) - Delete(name_qualifier); + if (name_qualifier_type) + Delete(name_qualifier_type); char *strip_position; - name_qualifier = fully_qualify_enum_name(n, NewString("")); + name_qualifier_type = fully_qualified_enum_type(n); strip_position = strstr(Char(oname), "::"); -- cgit v1.2.1 From 1adc50e73032eb80e2f77cac15205112e422cdf5 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 15 Dec 2010 21:55:08 +0000 Subject: constify SwigType * in many places git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12349 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/lang.cxx | 2 +- Source/Modules/php.cxx | 4 ++-- Source/Modules/swigmod.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index 0110b6ea1..7f96007e3 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -3011,7 +3011,7 @@ Node *Language::symbolLookup(String *s, const_String_or_char_ptr scope) { * Tries to locate a class from a type definition * ----------------------------------------------------------------------------- */ -Node *Language::classLookup(SwigType *s) { +Node *Language::classLookup(const SwigType *s) { Node *n = 0; /* Look in hash of cached values */ diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index b95eaa7cd..43eee9ae6 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -126,7 +126,7 @@ static enum { } wrapperType = standard; extern "C" { - static void (*r_prevtracefunc) (SwigType *t, String *mangled, String *clientdata) = 0; + static void (*r_prevtracefunc) (const SwigType *t, String *mangled, String *clientdata) = 0; } static void SwigPHP_emit_resource_registrations() { @@ -2710,7 +2710,7 @@ static PHP *maininstance = 0; // We use this function to be able to write out zend_register_list_destructor_ex // lines for most things in the type table // NOTE: it's a function NOT A PHP::METHOD -extern "C" void typetrace(SwigType *ty, String *mangled, String *clientdata) { +extern "C" void typetrace(const SwigType *ty, String *mangled, String *clientdata) { Node *class_node; if (!zend_types) { zend_types = NewHash(); diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h index d3074105f..208a7b026 100644 --- a/Source/Modules/swigmod.h +++ b/Source/Modules/swigmod.h @@ -213,7 +213,7 @@ public: virtual int addSymbol(const String *s, const Node *n, const_String_or_char_ptr scope = ""); /* Add symbol */ virtual void dumpSymbols(); virtual Node *symbolLookup(String *s, const_String_or_char_ptr scope = ""); /* Symbol lookup */ - virtual Node *classLookup(SwigType *s); /* Class lookup */ + virtual Node *classLookup(const SwigType *s); /* Class lookup */ virtual Node *enumLookup(SwigType *s); /* Enum lookup */ virtual int abstractClassTest(Node *n); /* Is class really abstract? */ virtual int is_assignable(Node *n); /* Is variable assignable? */ -- cgit v1.2.1 From 7f4283f6843991f189b1b6ba4ad6f1d58c1ba4af Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 23 Dec 2010 20:27:34 +0000 Subject: Fix special variable not being expanded for csvarin typemaps when used for global variables git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12354 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/csharp.cxx | 1 + 1 file changed, 1 insertion(+) (limited to 'Source/Modules') diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index 6ecd18aed..d93891795 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -2343,6 +2343,7 @@ public: SwigType *pt = Getattr(p, "type"); if ((tm = Getattr(p, "tmap:csvarin"))) { substituteClassname(pt, tm); + Replaceall(tm, "$csinput", "value"); Replaceall(tm, "$imcall", imcall); excodeSubstitute(n, tm, "csvarin", p); Printf(proxy_class_code, "%s", tm); -- cgit v1.2.1 From 91523f7510a248bd4d2fcc2e892b29f35cd33a04 Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Thu, 30 Dec 2010 15:40:17 +0000 Subject: [C#, D, Java] Check for collision of parameter names with target language keywords when generating the director glue code. The situation in which the generated could would previously be invalid is illustrated in the new 'director_keywords' test case. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12358 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/csharp.cxx | 13 ++++++------- Source/Modules/d.cxx | 9 ++++----- Source/Modules/java.cxx | 8 ++++---- 3 files changed, 14 insertions(+), 16 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index d93891795..6d0896b16 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -3473,7 +3473,6 @@ public: String *callback_def = NewString(""); String *callback_code = NewString(""); String *imcall_args = NewString(""); - int gencomma = 0; bool ignored_method = GetFlag(n, "feature:ignore") ? true : false; // Kludge Alert: functionWrapper sets sym:overload properly, but it @@ -3617,14 +3616,14 @@ public: Printf(w->code, "} else {\n"); /* Go through argument list, convert from native to Java */ - for (p = l; p; /* empty */ ) { + for (i = 0, p = l; p; ++i) { /* Is this superfluous? */ while (checkAttribute(p, "tmap:directorin:numinputs", "0")) { p = Getattr(p, "tmap:directorin:next"); } SwigType *pt = Getattr(p, "type"); - String *ln = Copy(Getattr(p, "name")); + String *ln = makeParameterName(n, p, i, false); String *c_param_type = NULL; String *c_decl = NewString(""); String *arg = NewString(""); @@ -3632,7 +3631,7 @@ public: Printf(arg, "j%s", ln); /* And add to the upcall args */ - if (gencomma > 0) + if (i > 0) Printf(jupcall_args, ", "); Printf(jupcall_args, "%s", arg); @@ -3660,7 +3659,7 @@ public: Delete(tm); /* Add C type to callback typedef */ - if (gencomma > 0) + if (i > 0) Printf(callback_typedef_parms, ", "); Printf(callback_typedef_parms, "%s", c_param_type); @@ -3681,7 +3680,7 @@ public: substituteClassname(pt, din); Replaceall(din, "$iminput", ln); - if (gencomma > 0) { + if (i > 0) { Printf(delegate_parms, ", "); Printf(proxy_method_types, ", "); Printf(imcall_args, ", "); @@ -3727,7 +3726,7 @@ public: p = nextSibling(p); } - gencomma++; + Delete(ln); Delete(arg); Delete(c_decl); Delete(c_param_type); diff --git a/Source/Modules/d.cxx b/Source/Modules/d.cxx index 986079d65..4fdc25fac 100644 --- a/Source/Modules/d.cxx +++ b/Source/Modules/d.cxx @@ -1867,7 +1867,6 @@ public: String *callback_def = NewString(""); String *callback_code = NewString(""); String *imcall_args = NewString(""); - int gencomma = 0; bool ignored_method = GetFlag(n, "feature:ignore") ? true : false; // Kludge Alert: functionWrapper sets sym:overload properly, but it @@ -2007,14 +2006,14 @@ public: Printf(w->code, "} else {\n"); // Go through argument list. - for (p = l; p; /* empty */) { + for (i = 0, p = l; p; ++i) { /* Is this superfluous? */ while (checkAttribute(p, "tmap:directorin:numinputs", "0")) { p = Getattr(p, "tmap:directorin:next"); } SwigType *pt = Getattr(p, "type"); - String *ln = Copy(Getattr(p, "name")); + String *ln = makeParameterName(n, p, i, false); String *c_param_type = NULL; String *c_decl = NewString(""); String *arg = NewString(""); @@ -2071,7 +2070,7 @@ public: Replaceall(din, "$winput", ln); Printf(delegate_parms, ", "); - if (gencomma > 0) { + if (i > 0) { Printf(proxy_method_param_list, ", "); Printf(imcall_args, ", "); } @@ -2123,10 +2122,10 @@ public: p = nextSibling(p); } - gencomma++; Delete(arg); Delete(c_decl); Delete(c_param_type); + Delete(ln); } /* header declaration, start wrapper definition */ diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx index 1d4e522c6..234a1e85b 100644 --- a/Source/Modules/java.cxx +++ b/Source/Modules/java.cxx @@ -3548,7 +3548,6 @@ public: String *callback_def = NewString(""); String *callback_code = NewString(""); String *imcall_args = NewString(""); - int gencomma = 0; int classmeth_off = curr_class_dmethod - first_class_dmethod; bool ignored_method = GetFlag(n, "feature:ignore") ? true : false; @@ -3767,14 +3766,14 @@ public: Delete(tp); /* Go through argument list, convert from native to Java */ - for (p = l; p; /* empty */ ) { + for (i = 0, p = l; p; ++i) { /* Is this superfluous? */ while (checkAttribute(p, "tmap:directorin:numinputs", "0")) { p = Getattr(p, "tmap:directorin:next"); } SwigType *pt = Getattr(p, "type"); - String *ln = Copy(Getattr(p, "name")); + String *ln = makeParameterName(n, p, i, false); String *c_param_type = NULL; String *c_decl = NewString(""); String *arg = NewString(""); @@ -3833,7 +3832,7 @@ public: substituteClassname(pt, din); Replaceall(din, "$jniinput", ln); - if (++gencomma > 1) + if (i > 0) Printf(imcall_args, ", "); Printf(callback_def, ", %s %s", tm, ln); @@ -3896,6 +3895,7 @@ public: Delete(arg); Delete(c_decl); Delete(c_param_type); + Delete(ln); } /* header declaration, start wrapper definition */ -- cgit v1.2.1 From 892caec201744b4af004ecaa5db18a60c3dbc2dc Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Sat, 8 Jan 2011 21:05:49 +0000 Subject: [D] Fixed a bug in the loop breaking code for directors leading to a superclass implementation erroneously being called. The situation in which this would previously happen is illustrated in the new "director_alternating" test case. Currently broken for C# and Java. Thanks to Jimmy Cao for reporting this. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12380 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/d.cxx | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/d.cxx b/Source/Modules/d.cxx index 4fdc25fac..9937452a9 100644 --- a/Source/Modules/d.cxx +++ b/Source/Modules/d.cxx @@ -2630,6 +2630,8 @@ private: if (!static_flag) { Printf(imcall, "cast(void*)swigCPtr"); } + + String *proxy_param_types = NewString(""); // Write the parameter list for the proxy function declaration and the // wrapper function call. @@ -2704,10 +2706,13 @@ private: "No dtype typemap defined for %s\n", SwigType_str(pt, 0)); } - if (gencomma >= 2) + if (gencomma >= 2) { Printf(function_code, ", "); + Printf(proxy_param_types, ", "); + } gencomma = 2; Printf(function_code, "%s %s", proxy_type, param_name); + Append(proxy_param_types, proxy_type); Delete(proxy_type); } @@ -2772,9 +2777,11 @@ private: String *excode = NewString(""); if (!Cmp(return_type, "void")) - Printf(excode, "if (this.classinfo == %s.classinfo) %s; else %s", proxy_class_name, imcall, ex_imcall); + Printf(excode, "if (swigIsMethodOverridden!(%s delegate(%s), %s function(%s), %s)()) %s; else %s", + return_type, proxy_param_types, return_type, proxy_param_types, proxy_function_name, ex_imcall, imcall); else - Printf(excode, "((this.classinfo == %s.classinfo) ? %s : %s)", proxy_class_name, imcall, ex_imcall); + Printf(excode, "((swigIsMethodOverridden!(%s delegate(%s), %s function(%s), %s)()) ? %s : %s)", + return_type, proxy_param_types, return_type, proxy_param_types, proxy_function_name, ex_imcall, imcall); Clear(imcall); Printv(imcall, excode, NIL); @@ -2788,6 +2795,8 @@ private: Swig_warning(WARN_D_TYPEMAP_DOUT_UNDEF, input_file, line_number, "No dout typemap defined for %s\n", SwigType_str(t, 0)); } + + Delete(proxy_param_types); // The whole function body is now in stored tm (if there was a matching type // map, of course), so simply append it to the code buffer. The braces are @@ -3418,7 +3427,7 @@ private: // Only emit it if the proxy class has at least one method. if (first_class_dmethod < curr_class_dmethod) { Printf(proxy_class_body_code, "\n"); - Printf(proxy_class_body_code, "private bool swigIsMethodOverridden(DelegateType, FunctionType, alias fn)() {\n"); + Printf(proxy_class_body_code, "private bool swigIsMethodOverridden(DelegateType, FunctionType, alias fn)() %s{\n", (d_version > 1) ? "const " : ""); Printf(proxy_class_body_code, " DelegateType dg = &fn;\n"); Printf(proxy_class_body_code, " return dg.funcptr != SwigNonVirtualAddressOf!(FunctionType, fn);\n"); Printf(proxy_class_body_code, "}\n"); -- cgit v1.2.1 From 18a4f389f92b4ea64e0d3c2f7172938384e06de2 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 11 Jan 2011 18:46:50 +0000 Subject: Update to support current Go releases. The Go foreign function interface changed. This changes SWIG accordingly, and also fixes a couple of bugs. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12389 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/go.cxx | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx index ac8ba333d..094b1dd5a 100644 --- a/Source/Modules/go.cxx +++ b/Source/Modules/go.cxx @@ -43,11 +43,9 @@ class GO:public Language { File *f_go_runtime; File *f_go_header; File *f_go_wrappers; - File *f_go_once; File *f_gc_runtime; File *f_gc_header; File *f_gc_wrappers; - File *f_gc_once; // True if we imported a module. bool saw_import; @@ -100,11 +98,9 @@ public: f_go_runtime(NULL), f_go_header(NULL), f_go_wrappers(NULL), - f_go_once(NULL), f_gc_runtime(NULL), f_gc_header(NULL), f_gc_wrappers(NULL), - f_gc_once(NULL), saw_import(false), imported_package(NULL), interfaces(NULL), @@ -303,12 +299,10 @@ private: f_go_runtime = NewString(""); f_go_header = NewString(""); f_go_wrappers = NewString(""); - f_go_once = NewString(""); if (!gccgo_flag) { f_gc_runtime = NewString(""); f_gc_header = NewString(""); f_gc_wrappers = NewString(""); - f_gc_once = NewString(""); } Swig_register_filebyname("begin", f_c_begin); @@ -322,13 +316,11 @@ private: Swig_register_filebyname("go_runtime", f_go_runtime); Swig_register_filebyname("go_header", f_go_header); Swig_register_filebyname("go_wrapper", f_go_wrappers); - Swig_register_filebyname("go_once", f_go_once); if (!gccgo_flag) { Swig_register_filebyname("gc_begin", f_gc_begin); Swig_register_filebyname("gc_runtime", f_gc_runtime); Swig_register_filebyname("gc_header", f_gc_header); Swig_register_filebyname("gc_wrapper", f_gc_wrappers); - Swig_register_filebyname("gc_once", f_gc_once); } Swig_banner(f_c_begin); @@ -349,6 +341,7 @@ private: if (!gccgo_flag) { Swig_banner(f_gc_begin); Printf(f_gc_begin, "\n/* This file should be compiled with 6c/8c. */\n"); + Printf(f_gc_begin, "#pragma dynimport _ _ \"%s\"\n", soname); } // Output module initialization code. @@ -414,16 +407,10 @@ private: Dump(f_c_wrappers, f_c_begin); Dump(f_c_init, f_c_begin); Dump(f_go_header, f_go_begin); - if (!saw_import) { - Dump(f_go_once, f_go_begin); - } Dump(f_go_runtime, f_go_begin); Dump(f_go_wrappers, f_go_begin); if (!gccgo_flag) { Dump(f_gc_header, f_gc_begin); - if (!saw_import) { - Dump(f_gc_once, f_gc_begin); - } Dump(f_gc_runtime, f_gc_begin); Dump(f_gc_wrappers, f_gc_begin); } @@ -1011,8 +998,9 @@ private: int gcFunctionWrapper(Node *n, String *name, String *go_name, String *overname, String *wname, ParmList *parms, SwigType *result, bool is_static, bool needs_wrapper) { Wrapper *f = NewWrapper(); - Printv(f->def, "#pragma dynimport ", wname, " ", wname, " \"", soname, "\"\n", NULL); - Printv(f->def, "void (*", wname, ")(void*);\n", NULL); + Printv(f->def, "#pragma dynimport ", wname, " ", wname, " \"\"\n", NULL); + Printv(f->def, "extern void (*", wname, ")(void*);\n", NULL); + Printv(f->def, "static void (*x", wname, ")(void*) = ", wname, ";\n", NULL); Printv(f->def, "\n", NULL); Printv(f->def, "void\n", NULL); @@ -1068,7 +1056,7 @@ private: Delete(parm_size); Printv(f->code, "{\n", NULL); - Printv(f->code, "\truntime\xc2\xb7" "cgocall(", wname, ", &p);\n", NULL); + Printv(f->code, "\truntime\xc2\xb7" "cgocall(x", wname, ", &p);\n", NULL); Printv(f->code, "}\n", NULL); Printv(f->code, "\n", NULL); @@ -1166,7 +1154,7 @@ private: p = nextParm(p); } if (SwigType_type(result) != T_VOID) { - Printv(f->code, "\t\tint : 0;\n", NULL); + Printv(f->code, "\t\tlong : 0;\n", NULL); String *ln = NewString("result"); String *ct = gcCTypeForGoValue(n, result, ln); Delete(ln); @@ -1270,7 +1258,11 @@ private: Parm *p = parms; for (int i = 0; i < parm_count; ++i) { p = getParm(p); - SwigType *pt = Getattr(p, "type"); + SwigType *pt = Copy(Getattr(p, "type")); + if (SwigType_isarray(pt)) { + SwigType_del_array(pt); + SwigType_add_pointer(pt); + } String *pn = NewString("g"); Append(pn, Getattr(p, "lname")); String *ct = gccgoCTypeForGoValue(p, pt, pn); @@ -1280,6 +1272,7 @@ private: Printv(fnname, ct, NULL); Delete(ct); Delete(pn); + Delete(pt); p = nextParm(p); } @@ -3415,7 +3408,7 @@ private: p = Getattr(p, "tmap:directorin:next"); } if (SwigType_type(result) != T_VOID) { - Printv(f->code, " int : 0;\n", NULL); + Printv(f->code, " long : 0;\n", NULL); String *rname = NewString("result"); String *cg = gcCTypeForGoValue(n, result, rname); Printv(f->code, " ", cg, ";\n", NULL); @@ -3545,7 +3538,7 @@ private: } } else { assert(is_pure_virtual); - Printv(f->code, " _swig_gopanic(\"call to pure virtual function ", Getattr(parent, "sym:name"), name, "\");\n"); + Printv(f->code, " _swig_gopanic(\"call to pure virtual function ", Getattr(parent, "sym:name"), name, "\");\n", NULL); if (SwigType_type(result) != T_VOID) { String *retstr = SwigType_rcaststr(Getattr(n, "returntype"), "c_result"); Printv(f->code, " return ", retstr, ";\n", NULL); -- cgit v1.2.1 From 3d7799fe0d519c05817392678974555c09b629c6 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 17 Jan 2011 21:12:35 +0000 Subject: New warning when the smartptr feature is missing in some classes in an inheritance chain. Errors test-suite now uses Python instead of Tcl as testing language git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12395 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/typepass.cxx | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'Source/Modules') diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx index 438b66617..8751b1e67 100644 --- a/Source/Modules/typepass.cxx +++ b/Source/Modules/typepass.cxx @@ -254,12 +254,17 @@ class TypePass:private Dispatcher { Delete(smartnamestr); /* setup inheritance relationship between smart pointer templates */ SwigType_inherit(smart, bsmart, 0, convcode); + if (!GetFlag(bclass, "feature:smartptr")) + Swig_warning(WARN_LANG_SMARTPTR_MISSING, Getfile(first), Getline(first), "Base class '%s' of '%s' is not similarly marked as a smart pointer.\n", SwigType_namestr(Getattr(bclass, "name")), SwigType_namestr(Getattr(first, "name"))); Delete(convcode); Delete(bsmart); Delete(smart); } else { Swig_error(Getfile(first), Getline(first), "Invalid type (%s) in 'smartptr' feature for class %s.\n", SwigType_namestr(smartptr), SwigType_namestr(clsname)); } + } else { + if (GetFlag(bclass, "feature:smartptr")) + Swig_warning(WARN_LANG_SMARTPTR_MISSING, Getfile(first), Getline(first), "Derived class '%s' of '%s' is not similarly marked as a smart pointer.\n", SwigType_namestr(Getattr(first, "name")), SwigType_namestr(Getattr(bclass, "name"))); } if (!importmode) { String *btype = Copy(bname); -- cgit v1.2.1 From 85ed05c24142a61974c16c8ebaf83170c8b7b141 Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Sat, 29 Jan 2011 21:31:40 +0000 Subject: [D] Tiny typo fix. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12405 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/d.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Modules') diff --git a/Source/Modules/d.cxx b/Source/Modules/d.cxx index 9937452a9..cc1bd2365 100644 --- a/Source/Modules/d.cxx +++ b/Source/Modules/d.cxx @@ -3661,7 +3661,7 @@ private: String *getPrimitiveDptype(Node *node, SwigType *type) { SwigType *stripped_type = SwigType_typedef_resolve_all(type); - // A reference can only be the »outermost element« of a typ. + // A reference can only be the »outermost element« of a type. bool mutable_ref = false; if (SwigType_isreference(stripped_type)) { SwigType_del_reference(stripped_type); -- cgit v1.2.1 From 4a73d986ddc26fd8eab62219090a4bc4bb55a453 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 1 Feb 2011 07:02:50 +0000 Subject: Any 'using' statements in the protected section of a class were previously ignored with dirprot mode, certainly with Java and C#. Also directors - a call to a method being defined in the base class, not overridden in a subcalss, but again overridden in a class derived from the first subclass was not being dispatched correcly to the most derived class - affecting non-scripting languages. Fix for C# is based on recent fix for D. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12419 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/csharp.cxx | 27 +++++++++++++++++++-------- Source/Modules/lang.cxx | 25 +++++++++++++++++-------- Source/Modules/typepass.cxx | 1 + 3 files changed, 37 insertions(+), 16 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index 6d0896b16..1444dbd87 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -2292,17 +2292,24 @@ public: String *ex_imcall = Copy(imcall); Replaceall(ex_imcall, "$imfuncname", ex_intermediary_function_name); Replaceall(imcall, "$imfuncname", intermediary_function_name); - String *excode = NewString(""); - if (!Cmp(return_type, "void")) - Printf(excode, "if (this.GetType() == typeof(%s)) %s; else %s", proxy_class_name, imcall, ex_imcall); - else - Printf(excode, "((this.GetType() == typeof(%s)) ? %s : %s)", proxy_class_name, imcall, ex_imcall); + Node *directorNode = Getattr(n, "directorNode"); + if (directorNode) { + UpcallData *udata = Getattr(directorNode, "upcalldata"); + String *methid = Getattr(udata, "class_methodidx"); - Clear(imcall); - Printv(imcall, excode, NIL); - Delete(ex_overloaded_name); + if (!Cmp(return_type, "void")) + Printf(excode, "if (SwigDerivedClassHasMethod(\"%s\", swigMethodTypes%s)) %s; else %s", proxy_function_name, methid, ex_imcall, imcall); + else + Printf(excode, "(SwigDerivedClassHasMethod(\"%s\", swigMethodTypes%s) ? %s : %s)", proxy_function_name, methid, ex_imcall, imcall); + + Clear(imcall); + Printv(imcall, excode, NIL); + } else { + // probably an ignored method or nodirector + } Delete(excode); + Delete(ex_overloaded_name); } else { Replaceall(imcall, "$imfuncname", intermediary_function_name); } @@ -3869,6 +3876,10 @@ public: /* Emit the actual upcall through */ UpcallData *udata = addUpcallMethod(imclass_dmethod, symname, decl, overloaded_name); String *methid = Getattr(udata, "class_methodidx"); + Setattr(n, "upcalldata", udata); + /* + Printf(stdout, "setting upcalldata, nodeType: %s %s::%s %p\n", nodeType(n), classname, Getattr(n, "name"), n); + */ Printf(director_callback_typedefs, " typedef %s (SWIGSTDCALL* SWIG_Callback%s_t)(", c_ret_type, methid); Printf(director_callback_typedefs, "%s);\n", callback_typedef_parms); diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index 7f96007e3..82af250f7 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -1806,17 +1806,25 @@ int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int default_ classname = Getattr(n, "name"); for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) { /* we only need to check the virtual members */ - if (!checkAttribute(ni, "storage", "virtual")) - continue; nodeType = Getattr(ni, "nodeType"); + int is_using = (Cmp(nodeType, "using") == 0); + Node *nn = is_using ? firstChild(ni) : ni; /* assume there is only one child node for "using" nodes */ + if (is_using) { + if (nn) + nodeType = Getattr(nn, "nodeType"); + else + continue; // A private "using" node + } + if (!checkAttribute(nn, "storage", "virtual")) + continue; /* we need to add methods(cdecl) and destructor (to check for throw decl) */ int is_destructor = (Cmp(nodeType, "destructor") == 0); if ((Cmp(nodeType, "cdecl") == 0) || is_destructor) { - decl = Getattr(ni, "decl"); + decl = Getattr(nn, "decl"); /* extra check for function type and proper access */ - if (SwigType_isfunction(decl) && (((!protectedbase || dirprot_mode()) && is_public(ni)) || need_nonpublic_member(ni))) { - String *name = Getattr(ni, "name"); - Node *method_id = is_destructor ? NewStringf("~destructor") : vtable_method_id(ni); + if (SwigType_isfunction(decl) && (((!protectedbase || dirprot_mode()) && is_public(nn)) || need_nonpublic_member(nn))) { + String *name = Getattr(nn, "name"); + Node *method_id = is_destructor ? NewStringf("~destructor") : vtable_method_id(nn); /* Make sure that the new method overwrites the existing: */ int len = Len(vm); const int DO_NOT_REPLACE = -1; @@ -1834,7 +1842,7 @@ int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int default_ String *fqdname = NewStringf("%s::%s", classname, name); Hash *item = NewHash(); Setattr(item, "fqdname", fqdname); - Node *m = Copy(ni); + Node *m = Copy(nn); /* Store the complete return type - needed for non-simple return types (pointers, references etc.) */ SwigType *ty = NewString(Getattr(m, "type")); @@ -1854,6 +1862,7 @@ int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int default_ Append(vm, item); else Setitem(vm, replace, item); + Setattr(nn, "directorNode", m); Delete(mname); } @@ -2806,7 +2815,7 @@ int Language::validIdentifier(String *s) { * ----------------------------------------------------------------------------- */ int Language::usingDeclaration(Node *n) { - if ((cplus_mode == PUBLIC)) { + if ((cplus_mode == PUBLIC) || (!is_public(n) && dirprot_mode())) { Node *np = Copy(n); Node *c; for (c = firstChild(np); c; c = nextSibling(c)) { diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx index 8751b1e67..3e2c9ca1e 100644 --- a/Source/Modules/typepass.cxx +++ b/Source/Modules/typepass.cxx @@ -999,6 +999,7 @@ class TypePass:private Dispatcher { } Node *nn = copyNode(c); Delattr(nn, "access"); // access might be different from the method in the base class + Setattr(nn, "access", Getattr(n, "access")); if (!Getattr(nn, "sym:name")) Setattr(nn, "sym:name", symname); -- cgit v1.2.1 From 867e6a9986ce3a6ebfdb90148a0fb5e0c78a6192 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 4 Feb 2011 19:43:24 +0000 Subject: [clisp] SF #3148200 Fix segfault parsing nested unions. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12428 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/clisp.cxx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/clisp.cxx b/Source/Modules/clisp.cxx index b1a6f5610..d26df36c2 100644 --- a/Source/Modules/clisp.cxx +++ b/Source/Modules/clisp.cxx @@ -293,16 +293,18 @@ int CLISP::classDeclaration(Node *n) { } String *temp = Copy(Getattr(c, "decl")); - Append(temp, Getattr(c, "type")); //appending type to the end, otherwise wrong type - String *lisp_type = get_ffi_type(n, temp); - Delete(temp); + if (temp) { + Append(temp, Getattr(c, "type")); //appending type to the end, otherwise wrong type + String *lisp_type = get_ffi_type(n, temp); + Delete(temp); - String *slot_name = Getattr(c, "sym:name"); - Printf(f_cl, "\n\t(%s %s)", slot_name, lisp_type); + String *slot_name = Getattr(c, "sym:name"); + Printf(f_cl, "\n\t(%s %s)", slot_name, lisp_type); - Append(entries, NewStringf("%s-%s", name, slot_name)); + Append(entries, NewStringf("%s-%s", name, slot_name)); - Delete(lisp_type); + Delete(lisp_type); + } } Printf(f_cl, ")\n"); -- cgit v1.2.1 From 74883f1dd7b22fdca609787300460f5550aec095 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 4 Feb 2011 20:25:59 +0000 Subject: [PHP] SF #3166423 Recent PHP versions no longer define zend_error_noreturn - calls to this have been replaced with zend_error. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12430 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/php.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Source/Modules') diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index 43eee9ae6..554e40bb8 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -976,7 +976,7 @@ public: /* Error handling code */ Printf(f->code, "fail:\n"); Printv(f->code, cleanup, NIL); - Printv(f->code, "zend_error_noreturn(SWIG_ErrorCode(),\"%s\",SWIG_ErrorMsg());", NIL); + Printv(f->code, "zend_error(SWIG_ErrorCode(),\"%s\",SWIG_ErrorMsg());", NIL); Printf(f->code, "}\n"); @@ -2290,7 +2290,7 @@ done: Append(f->code, "return;\n"); Append(f->code, "fail:\n"); - Append(f->code, "zend_error_noreturn(SWIG_ErrorCode(),\"%s\",SWIG_ErrorMsg());\n"); + Append(f->code, "zend_error(SWIG_ErrorCode(),\"%s\",SWIG_ErrorMsg());\n"); Printf(f->code, "}\n"); Wrapper_print(f, s_wrappers); @@ -2665,7 +2665,7 @@ done: } Append(w->code, "fail:\n"); - Append(w->code, "zend_error_noreturn(SWIG_ErrorCode(),\"%s\",SWIG_ErrorMsg());\n"); + Append(w->code, "zend_error(SWIG_ErrorCode(),\"%s\",SWIG_ErrorMsg());\n"); Append(w->code, "}\n"); // We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method -- cgit v1.2.1 From f4c74bc500195797d41fad5d1203a0c109ab00e7 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 4 Feb 2011 23:42:06 +0000 Subject: R - SF #3168676 Fix %rename not working for member variables and methods. Add new simple rename testcase with runtime tests for C# and R git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12432 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/r.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Modules') diff --git a/Source/Modules/r.cxx b/Source/Modules/r.cxx index 8eb784c68..64583175b 100644 --- a/Source/Modules/r.cxx +++ b/Source/Modules/r.cxx @@ -300,7 +300,7 @@ public: Printf(stderr, " %s %s\n", Getattr(n, "name"), Getattr(n, "type")); - member_name = Getattr(n, "name"); + member_name = Getattr(n, "sym:name"); processing_class_member_function = 1; int status = Language::memberfunctionHandler(n); processing_class_member_function = 0; -- cgit v1.2.1 From fb6f48dda42379ccd46ea1933ede0ebd99ab309a Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sun, 13 Feb 2011 16:33:12 +0000 Subject: Apply patch #3171793 from szager - protected director methods failing when -fvirtual is used. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12458 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/allocate.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Modules') diff --git a/Source/Modules/allocate.cxx b/Source/Modules/allocate.cxx index 31f7c20ae..110a92939 100644 --- a/Source/Modules/allocate.cxx +++ b/Source/Modules/allocate.cxx @@ -216,7 +216,7 @@ class Allocate:public Dispatcher { if (!most_base_covariant_type) { // Eliminate the derived virtual method. - if (virtual_elimination_mode) + if (virtual_elimination_mode && !is_member_director(n)) if (both_have_public_access) if (!is_non_public_base(inclass, b)) if (!Swig_symbol_isoverloaded(n)) { -- cgit v1.2.1