diff options
author | thegeorg <thegeorg@yandex-team.com> | 2023-10-03 11:19:48 +0300 |
---|---|---|
committer | thegeorg <thegeorg@yandex-team.com> | 2023-10-03 11:43:28 +0300 |
commit | cda0c13f23f6b169fb0a49dc504b40a0aaecea09 (patch) | |
tree | 26476e92e5af2c856e017afb1df8f8dff42495bf /contrib/tools/swig/Source/Modules/directors.cxx | |
parent | 4854116da9c5e3c95bb8440f2ea997c54b6e1a61 (diff) | |
download | ydb-cda0c13f23f6b169fb0a49dc504b40a0aaecea09.tar.gz |
Move contrib/tools/jdk to build/platform/java/jdk/testing
Diffstat (limited to 'contrib/tools/swig/Source/Modules/directors.cxx')
-rw-r--r-- | contrib/tools/swig/Source/Modules/directors.cxx | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/contrib/tools/swig/Source/Modules/directors.cxx b/contrib/tools/swig/Source/Modules/directors.cxx new file mode 100644 index 0000000000..14e2e84661 --- /dev/null +++ b/contrib/tools/swig/Source/Modules/directors.cxx @@ -0,0 +1,270 @@ +/* ----------------------------------------------------------------------------- + * 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 https://www.swig.org/legal.html. + * + * directors.cxx + * + * Director support functions. + * Not all of these may be necessary, and some may duplicate existing functionality + * in SWIG. --MR + * ----------------------------------------------------------------------------- */ + +#include "swigmod.h" + +/* ----------------------------------------------------------------------------- + * Swig_csuperclass_call() + * + * Generates a fully qualified method call, including the full parameter list. + * e.g. "base::method(i, j)" + * ----------------------------------------------------------------------------- */ + +String *Swig_csuperclass_call(String *base, String *method, ParmList *l) { + String *call = NewString(""); + int arg_idx = 0; + Parm *p; + if (base) { + Printf(call, "%s::", base); + } + Printf(call, "%s(", method); + for (p = l; p; p = nextSibling(p)) { + String *pname = Getattr(p, "name"); + if (!pname && Cmp(Getattr(p, "type"), "void")) { + pname = NewString(""); + Printf(pname, "arg%d", arg_idx++); + } + if (p != l) + Printf(call, ", "); + Printv(call, pname, NIL); + } + Printf(call, ")"); + return call; +} + +/* ----------------------------------------------------------------------------- + * Swig_class_declaration() + * + * Generate the start of a class/struct declaration. + * e.g. "class myclass" + * ----------------------------------------------------------------------------- */ + +String *Swig_class_declaration(Node *n, String *name) { + if (!name) { + name = Getattr(n, "sym:name"); + } + String *result = NewString(""); + String *kind = Getattr(n, "kind"); + Printf(result, "%s %s", kind, name); + return result; +} + +/* ----------------------------------------------------------------------------- + * Swig_class_name() + * ----------------------------------------------------------------------------- */ + +String *Swig_class_name(Node *n) { + String *name; + name = Copy(Getattr(n, "sym:name")); + return name; +} + +/* ----------------------------------------------------------------------------- + * Swig_director_declaration() + * + * Generate the full director class declaration, complete with base classes. + * e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {" + * ----------------------------------------------------------------------------- */ + +String *Swig_director_declaration(Node *n) { + String *classname = Swig_class_name(n); + String *directorname = Language::instance()->directorClassName(n); + String *base = Getattr(n, "classtype"); + String *declaration = Swig_class_declaration(n, directorname); + + Printf(declaration, " : public %s, public Swig::Director {\n", base); + Delete(classname); + Delete(directorname); + return declaration; +} + + +/* ----------------------------------------------------------------------------- + * Swig_method_call() + * ----------------------------------------------------------------------------- */ + +String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms) { + String *func; + int comma = 0; + Parm *p = parms; + SwigType *pt; + String *nname; + + func = NewString(""); + nname = SwigType_namestr(name); + Printf(func, "%s(", nname); + while (p) { + String *pname; + pt = Getattr(p, "type"); + if ((SwigType_type(pt) != T_VOID)) { + if (comma) + Printf(func, ","); + pname = Getattr(p, "name"); + Printf(func, "%s", pname); + comma = 1; + } + p = nextSibling(p); + } + Printf(func, ")"); + return func; +} + +/* ----------------------------------------------------------------------------- + * Swig_method_decl() + * + * Return a stringified version of a C/C++ declaration. + * ----------------------------------------------------------------------------- */ + +String *Swig_method_decl(SwigType *return_base_type, SwigType *decl, const_String_or_char_ptr id, List *args, int default_args) { + String *result = NewString(""); + bool conversion_operator = Strstr(id, "operator ") != 0 && !return_base_type; + + Parm *parm = args; + int arg_idx = 0; + while (parm) { + String *type = Getattr(parm, "type"); + String *name = Getattr(parm, "name"); + if (!name && Cmp(type, "void")) { + name = NewString(""); + Printf(name, "arg%d", arg_idx++); + Setattr(parm, "name", name); + } + parm = nextSibling(parm); + } + + String *rettype = Copy(decl); + String *quals = SwigType_pop_function_qualifiers(rettype); + String *qualifiers = 0; + if (quals) + qualifiers = SwigType_str(quals, 0); + + String *popped_decl = SwigType_pop_function(rettype); + if (return_base_type) + Append(rettype, return_base_type); + + if (!conversion_operator) { + SwigType *rettype_stripped = SwigType_strip_qualifiers(rettype); + String *rtype = SwigType_str(rettype, 0); + Append(result, rtype); + if ((SwigType_issimple(rettype_stripped) && return_base_type) || SwigType_isqualifier(rettype)) + Append(result, " "); + Delete(rtype); + Delete(rettype_stripped); + } + + if (id) + Append(result, id); + + String *args_string = default_args ? ParmList_str_defaultargs(args) : ParmList_str(args); + Printv(result, "(", args_string, ")", NIL); + + if (qualifiers) + Printv(result, " ", qualifiers, NIL); + + Delete(args_string); + Delete(popped_decl); + Delete(qualifiers); + Delete(quals); + Delete(rettype); + return result; +} + +/* ----------------------------------------------------------------------------- + * Swig_director_emit_dynamic_cast() + * + * In order to call protected virtual director methods from the target language, we need + * to add an extra dynamic_cast to call the public C++ wrapper in the director class. + * Also for non-static protected members when the allprotected option is on. + * ----------------------------------------------------------------------------- */ + +void Swig_director_emit_dynamic_cast(Node *n, Wrapper *f) { + // TODO: why is the storage element removed in staticmemberfunctionHandler ?? + if ((!is_public(n) && (is_member_director(n) || GetFlag(n, "explicitcall"))) || + (is_non_virtual_protected_access(n) && !(Swig_storage_isstatic_custom(n, "staticmemberfunctionHandler:storage") || + Swig_storage_isstatic(n)) + && !Equal(nodeType(n), "constructor"))) { + Node *parent = Getattr(n, "parentNode"); + String *dirname; + String *dirdecl; + dirname = Language::instance()->directorClassName(parent); + dirdecl = NewStringf("%s *darg = 0", dirname); + Wrapper_add_local(f, "darg", dirdecl); + Printf(f->code, "darg = dynamic_cast<%s *>(arg1);\n", dirname); + Delete(dirname); + Delete(dirdecl); + } +} + +/* ----------------------------------------------------------------------------- + * Swig_director_parms_fixup() + * + * For each parameter in the C++ member function, copy the parameter name + * to its "lname"; this ensures that Swig_typemap_attach_parms() will do + * the right thing when it sees strings like "$1" in "directorin" typemaps. + * ----------------------------------------------------------------------------- */ + +void Swig_director_parms_fixup(ParmList *parms) { + Parm *p; + int i; + for (i = 0, p = parms; p; p = nextSibling(p), ++i) { + String *arg = Getattr(p, "name"); + String *lname = 0; + + if (!arg && !Equal(Getattr(p, "type"), "void")) { + lname = NewStringf("arg%d", i); + Setattr(p, "name", lname); + } else + lname = Copy(arg); + + Setattr(p, "lname", lname); + Delete(lname); + } +} + +/* ----------------------------------------------------------------------------- + * Swig_director_can_unwrap() + * + * Determine whether a function's return type can be returned as an existing + * target language object instead of creating a new target language object. + * Must be a director class and only for return by pointer or reference only + * (not by value or by pointer to pointer etc). + * ----------------------------------------------------------------------------- */ + +bool Swig_director_can_unwrap(Node *n) { + + // FIXME: this will not try to unwrap directors returned as non-director + // base class pointers! + + bool unwrap = false; + + String *type = Getattr(n, "type"); + SwigType *t = SwigType_typedef_resolve_all(type); + SwigType *t1 = SwigType_strip_qualifiers(t); + SwigType *prefix = SwigType_prefix(t1); + + if (Strcmp(prefix, "p.") == 0 || Strcmp(prefix, "r.") == 0) { + Node *parent = Swig_methodclass(n); + Node *module = Getattr(parent, "module"); + Node *target = Swig_directormap(module, t1); + if (target) + unwrap = true; + } + + Delete(prefix); + Delete(t1); + Delete(t); + + return unwrap; +} |