/trunk/Source/Modules/d.cxx
C++ | 1938 lines | 1269 code | 297 blank | 372 comment | 238 complexity | 10b1678babbe738037ae5bbff7e705ee MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
Large files files are truncated, but you can click here to view the full file
- /* -----------------------------------------------------------------------------
- * 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 <ctype.h>
- // 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 *im_dmodule_name;
- // The fully qualified name of the wrap D module (package name included).
- String *im_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 intermediary D module header set via
- // %pragma(d) imdmoduleimports.
- String *im_dmodule_imports;
- // 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
- // %pragma(d) globalproxyimports.
- String *global_proxy_imports;
- // The D code for the main proxy modules. nspace_proxy_dmodules is a hash from
- // the namespace name as key to an {"imports", "code"}. If the nspace feature
- // is not active, only proxy_dmodule_imports and proxy_dmodule_code are used,
- // which contain the code for the root proxy module.
- //
- // These variables should not be accessed directly but rather via the
- // proxy{Imports, Code}Buffer)() helper functions which return the right
- // buffer for a given namespace. If not in split proxy mode, they contain the
- // whole proxy code.
- String *proxy_dmodule_imports;
- String *proxy_dmodule_code;
- Hash *nspace_proxy_dmodules;
- // The D code generated for the currently processed enum.
- String *proxy_enum_code;
- /*
- * D data for the current proxy class.
- *
- * These strings are mainly used to temporarily accumulate code from the
- * various member handling functions while a single class is processed and are
- * no longer relevant once that class has been finished, i.e. after
- * classHandler() has returned.
- */
- // The unqualified name of the current proxy class.
- String *proxy_class_name;
- // The name of the current proxy class, qualified with the name of the
- // namespace it is in, if any.
- String *proxy_class_qname;
- // 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 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 the functions declared in the
- // intermediary D module 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),
- 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),
- im_dmodule_imports(NULL),
- im_dmodule_code(NULL),
- global_proxy_imports(NULL),
- proxy_dmodule_imports(NULL),
- proxy_dmodule_code(NULL),
- nspace_proxy_dmodules(NULL),
- proxy_enum_code(NULL),
- proxy_class_name(NULL),
- proxy_class_qname(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, "imdmodulename")) {
- im_dmodule_name = Copy(Getattr(optionsnode, "imdmodulename"));
- }
- 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 (!im_dmodule_name) {
- im_dmodule_name = NewStringf("%s_im", Getattr(n, "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);
- im_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("");
- nspace_proxy_dmodules = NewHash();
- im_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
- // [lib]<module>_wrap[.so/.dll].
- if (!wrap_library_name)
- wrap_library_name = NewStringf("%s_wrap", Getattr(n, "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, im_dmodule_name);
- File *im_d_file = NewFile(filen, "w", SWIG_output_files());
- if (!im_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(im_d_file);
- Printf(im_d_file, "module %s;\n", im_dmodule_fq_name);
- 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(im_d_file, "%s\n", wrapper_loader_code);
- // Add the wrapper function declarations.
- replaceModuleVariables(im_dmodule_code);
- Printv(im_d_file, im_dmodule_code, NIL);
- Close(im_d_file);
- }
- // Generate the main D proxy 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", 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);
- // 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);
- }
- // Generate the additional proxy modules for nspace support.
- for (Iterator it = First(nspace_proxy_dmodules); it.key; it = Next(it)) {
- String *module_name = createLastNamespaceName(it.key);
- String *filename = NewStringf("%s%s.d", outputDirectory(it.key), module_name);
- File *file = NewFile(filename, "w", SWIG_output_files());
- if (!file) {
- FileErrorDisplay(filename);
- SWIG_exit(EXIT_FAILURE);
- }
- Delete(filename);
- emitBanner(file);
- Printf(file, "module %s%s.%s;\n", package, it.key, module_name);
- Printf(file, "\nstatic import %s;\n", im_dmodule_fq_name);
- Printv(file, global_proxy_imports, NIL);
- Printv(file, Getattr(it.item, "imports"), NIL);
- Printv(file, "\n", NIL);
- String *code = Getattr(it.item, "code");
- replaceModuleVariables(code);
- Printv(file, code, NIL);
- Close(file);
- Delete(module_name);
- }
- 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(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);
- 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(nspace_proxy_dmodules);
- nspace_proxy_dmodules = NULL;
- Delete(im_dmodule_imports);
- im_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:
- * 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 im D module).
- * wrapperloaderbindcommand - D code for binding a symbol from the wrapper
- * library to the declaration in the im 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, "imdmodulecode") == 0) {
- Printf(im_dmodule_code, "%s\n", strvalue);
- } else if (Strcmp(code, "imdmoduleimports") == 0) {
- replaceImportTypeMacros(strvalue);
- Chop(strvalue);
- Printf(im_dmodule_imports, "%s\n", strvalue);
- } else if (Strcmp(code, "proxydmodulecode") == 0) {
- Printf(proxyCodeBuffer(0), "%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 *nspace = Getattr(n, "sym:nspace");
- String *output_directory = outputDirectory(nspace);
- String *filename = NewStringf("%s%s.d", output_directory, symname);
- Delete(output_directory);
- 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);
- if (nspace) {
- Printf(class_file, "module %s%s.%s;\n", package, nspace, symname);
- } else {
- 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 {
- String *nspace = Getattr(n, "sym:nspace");
- Printv(proxyImportsBuffer(nspace), imports, NIL);
- Printv(proxyCodeBuffer(nspace), 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);
- // Deal with enum values that are not int
- int swigtype = SwigType_type(Getattr(n, "type"));
- if (swigtype == T_BOOL) {
- const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0";
- Setattr(n, "enumvalue", val);
- } else if (swigtype == T_CHAR) {
- String *val = NewStringf("'%s'", Getattr(n, "enumvalue"));
- Setattr(n, "enumvalue", val);
- Delete(val);
- }
- // Emit the enum item.
- {
- if (!GetFlag(n, "firstenumitem"))
- Printf(proxy_enum_code, ",\n");
- Printf(proxy_enum_code, " %s", Getattr(n, "sym: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,
- // %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);
- }
- // 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(getNSpace(), 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.
- // TODO: This might occur with nspace as well, augment the check.
- 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(getNSpace(), 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:manifestconst") != 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 overloadedprocess in D.
- if (Getattr(n, "overload:ignore")) {
- return SWIG_OK;
- }
- 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.
- 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(getNSpace(), 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, "imtype", true);
- 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 = 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, 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("dtype", l, NULL);
- Swig_typemap_attach_parms("din", l, NULL);
- emit_mark_varargs(l);
- int gencomma = 0;
- /* Output each parameter */
- Parm *p = l;
- for (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, "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_DTYPE_UNDEF, input_file, line_number,
- "No dtype 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
- // intermediary 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, "$imcall", helper_name);
- Delete(helper_name);
- } else {
- Replaceall(proxy_constructor_code, "$imcall", 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, im_dmodule_fq_name, ".", Swig_name_destroy(getNSpace(),symname), "(cast(void*)swigCPtr)", NIL);
- return SWIG_OK;
- }
- /* ---------------------------------------------------------------------------
- * D::classHandler()
- * --------------------------------------------------------------------------- */
- virtual int classHandler(Node *n) {
- String *nspace = getNSpace();
- File *class_file = NULL;
- proxy_class_name = Copy(Getattr(n, "sym:name"));
- if (nspace) {
- proxy_class_qname = NewStringf("%s.%s", nspace, proxy_class_name);
- } else {
- proxy_class_qname = Copy(proxy_class_name);
- }
- if (!addSymbol(proxy_class_name, n, nspace)) {
- return SWIG_ERROR;
- }
- assertClassNameValidity(proxy_class_name);
- if (split_proxy_dmodule) {
- String *output_directory = outputDirectory(nspace);
- String *filename = NewStringf("%s%s.d", output_directory, proxy_class_name);
- class_file = NewFile(filename, "w", SWIG_output_files());
- Delete(output_directory);
- if (!class_file) {
- FileErrorDisplay(filename);
- SWIG_exit(EXIT_FAILURE);
- }
- Append(filenames_list, Copy(filename));
- Delete(filename);
- emitBanner(class_file);
- if (nspace) {
- Printf(class_file, "module %s%s.%s;\n", package, nspace, proxy_class_name);
- } else {
- Printf(class_file, "module %s%s;\n", package, proxy_class_name);
- }
- Printf(class_file, "\nstatic import %s;\n", im_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);
- // Traverse the tree for this class, using the *Handler()s to generate code
- // to the proxy_class_* variables.
- Language::classHandler(n);
- writeProxyClassAndUpcasts(n);
- writeDirectorConnectWrapper(n);
- Replaceall(proxy_class_code, "$dclassname", proxy_class_name);
- String *dclazzname = Swig_name_member(getNSpace(), proxy_class_name, "");
- Replaceall(proxy_class_code, "$dclazzname", dclazzname);
- Delete(dclazzname);
- 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(proxyImportsBuffer(getNSpace()), proxy_class_imports, NIL);
- Printv(proxyCodeBuffer(getNSpace()), proxy_class_code, NIL);
- }
- Delete(proxy_class_qname);
- proxy_class_qname = NULL;
- 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 %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.
- * --------------------------------------------------------------------------- */
- virtual int constantWrapper(Node *n) {
- String *symname = Getattr(n, "sym:name");
- if (!addSymbol(symname, n))
- return SWIG_ERROR;
- // 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.
- // Note that this is only called for global constants, static member
- // constants are already handeled in staticmemberfunctionHandler().
- Swig_save("constantWrapper", n, "value", NIL);
- Swig_save("constantWrapper", n, "tmap:ctype:out", "tmap:imtype:out", "tmap:dtype:out", "tmap:out:null", "tmap:imtype:outattributes", "tmap:dtype:outattributes", 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);
- }
- SetFlag(n, "feature:immutable");
- 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("dtype", l, NULL);
- // Get D return type.
- String *return_type = NewString("");
- String *tm;
- 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 dtype typemap.
- tm = dtypeout;
- replaceClassname(tm, t);
- }
- Printf(return_type, "%s", tm);
- } else {
- 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;
- 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.
- …
Large files files are truncated, but you can click here to view the full file