1 /* -----------------------------------------------------------------------------
2 * See the LICENSE file for information on copyright, usage and redistribution
3 * of SWIG, and the README file for authors - http://www.swig.org/release.html.
7 * Director support functions.
8 * Not all of these may be necessary, and some may duplicate existing functionality
10 * ----------------------------------------------------------------------------- */
12 char cvsroot_directors_cxx[] = "$Id";
16 /* Swig_csuperclass_call()
18 * Generates a fully qualified method call, including the full parameter list.
19 * e.g. "base::method(i, j)"
23 String *Swig_csuperclass_call(String *base, String *method, ParmList *l) {
24 String *call = NewString("");
28 Printf(call, "%s::", base);
30 Printf(call, "%s(", method);
31 for (p = l; p; p = nextSibling(p)) {
32 String *pname = Getattr(p, "name");
33 if (!pname && Cmp(Getattr(p, "type"), "void")) {
34 pname = NewString("");
35 Printf(pname, "arg%d", arg_idx++);
39 Printv(call, pname, NIL);
45 /* Swig_class_declaration()
47 * Generate the start of a class/struct declaration.
48 * e.g. "class myclass"
52 String *Swig_class_declaration(Node *n, String *name) {
54 name = Getattr(n, "sym:name");
56 String *result = NewString("");
57 String *kind = Getattr(n, "kind");
58 Printf(result, "%s %s", kind, name);
62 String *Swig_class_name(Node *n) {
64 name = Copy(Getattr(n, "sym:name"));
68 /* Swig_director_declaration()
70 * Generate the full director class declaration, complete with base classes.
71 * e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {"
75 String *Swig_director_declaration(Node *n) {
76 String *classname = Swig_class_name(n);
77 String *directorname = NewStringf("SwigDirector_%s", classname);
78 String *base = Getattr(n, "classtype");
79 String *declaration = Swig_class_declaration(n, directorname);
80 Printf(declaration, " : public %s, public Swig::Director {\n", base);
87 String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms) {
96 nname = SwigType_namestr(name);
97 Printf(func, "%s(", nname);
100 pt = Getattr(p, "type");
101 if ((SwigType_type(pt) != T_VOID)) {
104 pname = Getattr(p, "name");
105 Printf(func, "%s", pname);
117 * Misnamed and misappropriated! Taken from SWIG's type string manipulation utilities
118 * and modified to generate full (or partial) type qualifiers for method declarations,
119 * local variable declarations, and return value casting. More importantly, it merges
120 * parameter type information with actual parameter names to produce a complete method
121 * declaration that fully mirrors the original method declaration.
123 * There is almost certainly a saner way to do this.
125 * This function needs to be cleaned up and possibly split into several smaller
126 * functions. For instance, attaching default names to parameters should be done in a
131 String *Swig_method_decl(SwigType *returntype, SwigType *decl, const_String_or_char_ptr id, List *args, int strip, int values) {
134 String *element = 0, *nextelement;
141 result = NewString(Char(id));
143 result = NewString("");
146 elements = SwigType_split(decl);
147 nelements = Len(elements);
149 element = Getitem(elements, 0);
151 for (i = 0; i < nelements; i++) {
152 if (i < (nelements - 1)) {
153 nextelement = Getitem(elements, i + 1);
157 if (SwigType_isqualifier(element)) {
161 q = SwigType_parm(element);
162 if (!Cmp(q, "const")) {
164 is_func = SwigType_isfunction(nextelement);
170 Insert(result, 0, " ");
171 Insert(result, 0, q);
175 } else if (SwigType_isfunction(element)) {
181 String *type = Getattr(parm, "type");
182 String *name = Getattr(parm, "name");
183 if (!name && Cmp(type, "void")) {
184 name = NewString("");
185 Printf(name, "arg%d", arg_idx++);
186 Setattr(parm, "name", name);
189 name = NewString("");
191 p = SwigType_str(type, name);
193 String *value = Getattr(parm, "value");
194 if (values && (value != 0)) {
195 Printf(result, " = %s", value);
197 parm = nextSibling(parm);
199 Append(result, ", ");
202 } else if (returntype) { // This check is intended for conversion operators to a pointer/reference which needs the pointer/reference ignoring in the declaration
203 if (SwigType_ispointer(element)) {
204 Insert(result, 0, "*");
205 if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
206 Insert(result, 0, "(");
209 } else if (SwigType_ismemberpointer(element)) {
211 q = SwigType_parm(element);
212 Insert(result, 0, "::*");
213 Insert(result, 0, q);
214 if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
215 Insert(result, 0, "(");
219 } else if (SwigType_isreference(element)) {
220 Insert(result, 0, "&");
221 } else if (SwigType_isarray(element)) {
224 size = SwigType_parm(element);
225 Append(result, size);
229 if (Strcmp(element, "v(...)") == 0) {
230 Insert(result, 0, "...");
232 String *bs = SwigType_namestr(element);
233 Insert(result, 0, " ");
234 Insert(result, 0, bs);
239 element = nextelement;
247 Append(result, "const");
249 Insert(result, 0, "const ");
256 Insert(result, 0, " ");
257 String *rtype = SwigType_str(returntype, 0);
258 Insert(result, 0, rtype);
265 /* -----------------------------------------------------------------------------
266 * Swig_director_emit_dynamic_cast()
268 * In order to call protected virtual director methods from the target language, we need
269 * to add an extra dynamic_cast to call the public C++ wrapper in the director class.
270 * Also for non-static protected members when the allprotected option is on.
271 * ----------------------------------------------------------------------------- */
272 void Swig_director_emit_dynamic_cast(Node *n, Wrapper *f) {
273 // TODO: why is the storage element removed in staticmemberfunctionHandler ??
274 if ((!is_public(n) && (is_member_director(n) || GetFlag(n, "explicitcall"))) ||
275 (is_non_virtual_protected_access(n) && !(checkAttribute(n, "staticmemberfunctionHandler:storage", "static") ||
276 checkAttribute(n, "storage", "static"))
277 && !Equal(nodeType(n), "constructor"))) {
278 Node *parent = Getattr(n, "parentNode");
279 String *symname = Getattr(parent, "sym:name");
280 String *dirname = NewStringf("SwigDirector_%s", symname);
281 String *dirdecl = NewStringf("%s *darg = 0", dirname);
282 Wrapper_add_local(f, "darg", dirdecl);
283 Printf(f->code, "darg = dynamic_cast<%s *>(arg1);\n", dirname);