1 /* -----------------------------------------------------------------------------
2 * This file is part of SWIG, which is licensed as a whole under version 3
3 * (or any later version) of the GNU General Public License. Some additional
4 * terms also apply to certain portions of SWIG. The full details of the SWIG
5 * license and copyrights can be found in the LICENSE and COPYRIGHT files
6 * included with the SWIG source code as distributed by the SWIG developers
7 * and at http://www.swig.org/legal.html.
8 *
9 * lang.cxx
10 *
11 * Language base class functions. Default C++ handling is also implemented here.
12 * ----------------------------------------------------------------------------- */
13
14 #include "swigmod.h"
15 #include "cparse.h"
16 #include <ctype.h>
17
18 /* default mode settings */
19 static int director_mode = 0;
20 static int director_protected_mode = 1;
21 static int all_protected_mode = 0;
22 static int naturalvar_mode = 0;
23 Language *Language::this_ = 0;
24
25 /* Set director_protected_mode */
Wrapper_director_mode_set(int flag)26 void Wrapper_director_mode_set(int flag) {
27 director_mode = flag;
28 }
29
Wrapper_director_protected_mode_set(int flag)30 void Wrapper_director_protected_mode_set(int flag) {
31 director_protected_mode = flag;
32 }
33
Wrapper_all_protected_mode_set(int flag)34 void Wrapper_all_protected_mode_set(int flag) {
35 all_protected_mode = flag;
36 }
37
Wrapper_naturalvar_mode_set(int flag)38 void Wrapper_naturalvar_mode_set(int flag) {
39 naturalvar_mode = flag;
40 }
41
42 extern "C" {
Swig_director_mode()43 int Swig_director_mode() {
44 return director_mode;
45 }
Swig_director_protected_mode()46 int Swig_director_protected_mode() {
47 return director_protected_mode;
48 }
Swig_all_protected_mode()49 int Swig_all_protected_mode() {
50 return all_protected_mode;
51 }
Language_replace_special_variables(String * method,String * tm,Parm * parm)52 void Language_replace_special_variables(String *method, String *tm, Parm *parm) {
53 Language::instance()->replaceSpecialVariables(method, tm, parm);
54 }
55 }
56
57 /* Some status variables used during parsing */
58 static int InClass = 0; /* Parsing C++ or not */
59 static String *ClassName = 0; /* This is the real name of the current class */
60 static String *EnumClassName = 0; /* Enum class name */
61 static String *ClassPrefix = 0; /* Class prefix */
62 static String *EnumClassPrefix = 0; /* Prefix for strongly typed enums (including ClassPrefix) */
63 static String *NSpace = 0; /* Namespace for the nspace feature */
64 static String *ClassType = 0; /* Fully qualified type name to use */
65 static String *DirectorClassName = 0; /* Director name of the current class */
66 int Abstract = 0;
67 int ImportMode = 0;
68 int IsVirtual = 0;
69 static String *AttributeFunctionGet = 0;
70 static String *AttributeFunctionSet = 0;
71 static Node *CurrentClass = 0;
72 int line_number = 0;
73 String *input_file = 0;
74 int SmartPointer = 0;
75 static Hash *classhash;
76
77 extern int GenerateDefault;
78 extern int ForceExtern;
79 extern int AddExtern;
80
81 /* import modes */
82
83 #define IMPORT_MODE 1
84
85 /* ----------------------------------------------------------------------
86 * Dispatcher::emit_one()
87 *
88 * Dispatch a single node
89 * ---------------------------------------------------------------------- */
90
emit_one(Node * n)91 int Dispatcher::emit_one(Node *n) {
92 int ret = SWIG_OK;
93
94 char *tag = Char(nodeType(n));
95 if (!tag) {
96 /* Printf(stderr,"SWIG: Fatal internal error. Malformed parse tree
97 node!\n"); */
98 return SWIG_OK;
99 }
100
101 /* Do not proceed if marked with an error */
102
103 if (Getattr(n, "error"))
104 return SWIG_OK;
105
106 /* Look for warnings */
107 String *wrn = Getattr(n, "feature:warnfilter");
108 if (wrn)
109 Swig_warnfilter(wrn, 1);
110
111 /* ============================================================
112 * C/C++ parsing
113 * ============================================================ */
114
115 if (strcmp(tag, "extern") == 0) {
116 ret = externDeclaration(n);
117 } else if (strcmp(tag, "cdecl") == 0) {
118 ret = cDeclaration(n);
119 } else if (strcmp(tag, "enum") == 0) {
120 ret = enumDeclaration(n);
121 } else if (strcmp(tag, "enumitem") == 0) {
122 ret = enumvalueDeclaration(n);
123 } else if (strcmp(tag, "enumforward") == 0) {
124 ret = enumforwardDeclaration(n);
125 } else if (strcmp(tag, "class") == 0) {
126 ret = classDeclaration(n);
127 } else if (strcmp(tag, "classforward") == 0) {
128 ret = classforwardDeclaration(n);
129 } else if (strcmp(tag, "constructor") == 0) {
130 ret = constructorDeclaration(n);
131 } else if (strcmp(tag, "destructor") == 0) {
132 ret = destructorDeclaration(n);
133 } else if (strcmp(tag, "access") == 0) {
134 ret = accessDeclaration(n);
135 } else if (strcmp(tag, "using") == 0) {
136 ret = usingDeclaration(n);
137 } else if (strcmp(tag, "namespace") == 0) {
138 ret = namespaceDeclaration(n);
139 } else if (strcmp(tag, "template") == 0) {
140 ret = templateDeclaration(n);
141 } else if (strcmp(tag, "lambda") == 0) {
142 ret = lambdaDeclaration(n);
143 }
144
145 /* ===============================================================
146 * SWIG directives
147 * =============================================================== */
148
149 else if (strcmp(tag, "top") == 0) {
150 ret = top(n);
151 } else if (strcmp(tag, "extend") == 0) {
152 ret = extendDirective(n);
153 } else if (strcmp(tag, "apply") == 0) {
154 ret = applyDirective(n);
155 } else if (strcmp(tag, "clear") == 0) {
156 ret = clearDirective(n);
157 } else if (strcmp(tag, "constant") == 0) {
158 ret = constantDirective(n);
159 } else if (strcmp(tag, "fragment") == 0) {
160 ret = fragmentDirective(n);
161 } else if (strcmp(tag, "import") == 0) {
162 ret = importDirective(n);
163 } else if (strcmp(tag, "include") == 0) {
164 ret = includeDirective(n);
165 } else if (strcmp(tag, "insert") == 0) {
166 ret = insertDirective(n);
167 } else if (strcmp(tag, "module") == 0) {
168 ret = moduleDirective(n);
169 } else if (strcmp(tag, "native") == 0) {
170 ret = nativeDirective(n);
171 } else if (strcmp(tag, "pragma") == 0) {
172 ret = pragmaDirective(n);
173 } else if (strcmp(tag, "typemap") == 0) {
174 ret = typemapDirective(n);
175 } else if (strcmp(tag, "typemapcopy") == 0) {
176 ret = typemapcopyDirective(n);
177 } else if (strcmp(tag, "typemapitem") == 0) {
178 ret = typemapitemDirective(n);
179 } else if (strcmp(tag, "types") == 0) {
180 ret = typesDirective(n);
181 } else {
182 Swig_error(input_file, line_number, "Unrecognized parse tree node type '%s'\n", tag);
183 ret = SWIG_ERROR;
184 }
185 if (wrn)
186 Swig_warnfilter(wrn, 0);
187 return ret;
188 }
189
190 /* ----------------------------------------------------------------------
191 * Dispatcher::emit_children()
192 *
193 * Emit all children that match the given type. type = 0 means all types.
194 * ---------------------------------------------------------------------- */
195
emit_children(Node * n)196 int Dispatcher::emit_children(Node *n) {
197 Node *c;
198 char *eo = Char(Getattr(n, "feature:emitonlychildren"));
199 for (c = firstChild(n); c; c = nextSibling(c)) {
200 if (eo) {
201 const char *tag = Char(nodeType(c));
202 if (strcmp(tag, "cdecl") == 0) {
203 if (checkAttribute(c, "storage", "typedef"))
204 tag = "typedef";
205 }
206 if (strstr(eo, tag) == 0) {
207 continue;
208 }
209 }
210 emit_one(c);
211 }
212 return SWIG_OK;
213 }
214
215
216 /* Stubs for dispatcher class. We don't do anything by default---up to derived class
217 to fill in traversal code */
218
defaultHandler(Node *)219 int Dispatcher::defaultHandler(Node *) {
220 return SWIG_OK;
221 }
extendDirective(Node * n)222 int Dispatcher::extendDirective(Node *n) {
223 return defaultHandler(n);
224 }
applyDirective(Node * n)225 int Dispatcher::applyDirective(Node *n) {
226 return defaultHandler(n);
227 }
clearDirective(Node * n)228 int Dispatcher::clearDirective(Node *n) {
229 return defaultHandler(n);
230 }
constantDirective(Node * n)231 int Dispatcher::constantDirective(Node *n) {
232 return defaultHandler(n);
233 }
fragmentDirective(Node * n)234 int Dispatcher::fragmentDirective(Node *n) {
235 return defaultHandler(n);
236 }
importDirective(Node * n)237 int Dispatcher::importDirective(Node *n) {
238 return defaultHandler(n);
239 }
includeDirective(Node * n)240 int Dispatcher::includeDirective(Node *n) {
241 return defaultHandler(n);
242 }
insertDirective(Node * n)243 int Dispatcher::insertDirective(Node *n) {
244 return defaultHandler(n);
245 }
moduleDirective(Node * n)246 int Dispatcher::moduleDirective(Node *n) {
247 return defaultHandler(n);
248 }
nativeDirective(Node * n)249 int Dispatcher::nativeDirective(Node *n) {
250 return defaultHandler(n);
251 }
pragmaDirective(Node * n)252 int Dispatcher::pragmaDirective(Node *n) {
253 return defaultHandler(n);
254 }
typemapDirective(Node * n)255 int Dispatcher::typemapDirective(Node *n) {
256 return defaultHandler(n);
257 }
typemapitemDirective(Node * n)258 int Dispatcher::typemapitemDirective(Node *n) {
259 return defaultHandler(n);
260 }
typemapcopyDirective(Node * n)261 int Dispatcher::typemapcopyDirective(Node *n) {
262 return defaultHandler(n);
263 }
typesDirective(Node * n)264 int Dispatcher::typesDirective(Node *n) {
265 return defaultHandler(n);
266 }
cDeclaration(Node * n)267 int Dispatcher::cDeclaration(Node *n) {
268 return defaultHandler(n);
269 }
externDeclaration(Node * n)270 int Dispatcher::externDeclaration(Node *n) {
271 return defaultHandler(n);
272 }
enumDeclaration(Node * n)273 int Dispatcher::enumDeclaration(Node *n) {
274 return defaultHandler(n);
275 }
enumvalueDeclaration(Node * n)276 int Dispatcher::enumvalueDeclaration(Node *n) {
277 return defaultHandler(n);
278 }
enumforwardDeclaration(Node * n)279 int Dispatcher::enumforwardDeclaration(Node *n) {
280 return defaultHandler(n);
281 }
classDeclaration(Node * n)282 int Dispatcher::classDeclaration(Node *n) {
283 return defaultHandler(n);
284 }
templateDeclaration(Node * n)285 int Dispatcher::templateDeclaration(Node *n) {
286 return defaultHandler(n);
287 }
lambdaDeclaration(Node * n)288 int Dispatcher::lambdaDeclaration(Node *n) {
289 return defaultHandler(n);
290 }
classforwardDeclaration(Node * n)291 int Dispatcher::classforwardDeclaration(Node *n) {
292 return defaultHandler(n);
293 }
constructorDeclaration(Node * n)294 int Dispatcher::constructorDeclaration(Node *n) {
295 return defaultHandler(n);
296 }
destructorDeclaration(Node * n)297 int Dispatcher::destructorDeclaration(Node *n) {
298 return defaultHandler(n);
299 }
accessDeclaration(Node * n)300 int Dispatcher::accessDeclaration(Node *n) {
301 return defaultHandler(n);
302 }
usingDeclaration(Node * n)303 int Dispatcher::usingDeclaration(Node *n) {
304 return defaultHandler(n);
305 }
namespaceDeclaration(Node * n)306 int Dispatcher::namespaceDeclaration(Node *n) {
307 return defaultHandler(n);
308 }
309
310 /* Allocators */
Language()311 Language::Language():
312 none_comparison(NewString("$arg != 0")),
313 director_ctor_code(NewString("")),
314 director_prot_ctor_code(0),
315 symtabs(NewHash()),
316 overloading(0),
317 multiinput(0),
318 cplus_runtime(0),
319 directors(0) {
320 symbolAddScope(""); // create top level/global symbol table scope
321 argc_template_string = NewString("argc");
322 argv_template_string = NewString("argv[%d]");
323
324 /* Default director constructor code, passed to Swig_ConstructorToFunction */
325 Printv(director_ctor_code, "if ( $comparison ) { /* subclassed */\n", " $director_new \n", "} else {\n", " $nondirector_new \n", "}\n", NIL);
326
327 /*
328 Default director 'protected' constructor code, disabled by
329 default. Each language that needs it, has to define it.
330 */
331 director_prot_ctor_code = 0;
332 director_multiple_inheritance = 1;
333 director_language = 0;
334 assert(!this_);
335 this_ = this;
336
337 doxygenTranslator = NULL;
338 }
339
~Language()340 Language::~Language() {
341 Delete(symtabs);
342 Delete(director_ctor_code);
343 Delete(none_comparison);
344 this_ = 0;
345 }
346
347 /* -----------------------------------------------------------------------------
348 * directorClassName()
349 * ----------------------------------------------------------------------------- */
350
directorClassName(Node * n)351 String *Language::directorClassName(Node *n) {
352 String *dirclassname;
353 String *nspace = NewString(Getattr(n, "sym:nspace"));
354 const char *attrib = "director:classname";
355 String *classname = getClassPrefix();
356
357 Replace(nspace, NSPACE_SEPARATOR, "_", DOH_REPLACE_ANY);
358 if (Len(nspace) > 0)
359 dirclassname = NewStringf("SwigDirector_%s_%s", nspace, classname);
360 else
361 dirclassname = NewStringf("SwigDirector_%s", classname);
362 Setattr(n, attrib, dirclassname);
363
364 Delete(nspace);
365 return dirclassname;
366 }
367
368 /* ----------------------------------------------------------------------
369 emit_one()
370 ---------------------------------------------------------------------- */
371
emit_one(Node * n)372 int Language::emit_one(Node *n) {
373 int ret;
374 int oldext;
375 if (!n)
376 return SWIG_OK;
377
378 if (GetFlag(n, "feature:ignore")
379 && !Getattr(n, "feature:onlychildren"))
380 return SWIG_OK;
381
382 oldext = Extend;
383 if (Getattr(n, "feature:extend"))
384 Extend = 1;
385
386 line_number = Getline(n);
387 input_file = Getfile(n);
388
389 /*
390 symtab = Getattr(n,"symtab");
391 if (symtab) {
392 symtab = Swig_symbol_setscope(symtab);
393 }
394 */
395 ret = Dispatcher::emit_one(n);
396 /*
397 if (symtab) {
398 Swig_symbol_setscope(symtab);
399 }
400 */
401 Extend = oldext;
402 return ret;
403 }
404
405
nonvoid_parms(Parm * p)406 static Parm *nonvoid_parms(Parm *p) {
407 if (p) {
408 SwigType *t = Getattr(p, "type");
409 if (SwigType_type(t) == T_VOID)
410 return 0;
411 }
412 return p;
413 }
414
415 /* -----------------------------------------------------------------------------
416 * cplus_value_type()
417 *
418 * Returns the alternative value type needed in C++ for class value
419 * types. When swig is not sure about using a plain $ltype value,
420 * since the class doesn't have a default constructor, or it can't be
421 * assigned, you will get back 'SwigValueWrapper<type >'.
422 *
423 * ----------------------------------------------------------------------------- */
424
cplus_value_type(SwigType * t)425 SwigType *cplus_value_type(SwigType *t) {
426 return SwigType_alttype(t, 0);
427 }
428
first_nontemplate(Node * n)429 static Node *first_nontemplate(Node *n) {
430 while (n) {
431 if (Strcmp(nodeType(n), "template") != 0)
432 return n;
433 n = Getattr(n, "sym:nextSibling");
434 }
435 return n;
436 }
437
438
439
440 /* --------------------------------------------------------------------------
441 * swig_pragma()
442 *
443 * Handle swig pragma directives.
444 * -------------------------------------------------------------------------- */
445
swig_pragma(char * lang,char * name,char * value)446 void swig_pragma(char *lang, char *name, char *value) {
447 if (strcmp(lang, "swig") == 0) {
448 if ((strcmp(name, "make_default") == 0) || ((strcmp(name, "makedefault") == 0))) {
449 GenerateDefault = 1;
450 } else if ((strcmp(name, "no_default") == 0) || ((strcmp(name, "nodefault") == 0))) {
451 Swig_warning(WARN_DEPRECATED_NODEFAULT, "SWIG", 1, "dangerous, use %%nodefaultctor, %%nodefaultdtor instead.\n");
452 GenerateDefault = 0;
453 } else if (strcmp(name, "attributefunction") == 0) {
454 String *nvalue = NewString(value);
455 char *s = strchr(Char(nvalue), ':');
456 if (!s) {
457 Swig_error(input_file, line_number, "Bad value for attributefunction. Expected \"fmtget:fmtset\".\n");
458 } else {
459 *s = 0;
460 AttributeFunctionGet = NewString(Char(nvalue));
461 AttributeFunctionSet = NewString(s + 1);
462 }
463 Delete(nvalue);
464 } else if (strcmp(name, "noattributefunction") == 0) {
465 AttributeFunctionGet = 0;
466 AttributeFunctionSet = 0;
467 }
468 }
469 }
470
471 /* --------------------------------------------------------------------------
472 * Language::use_naturalvar_mode()
473 *
474 * Determine whether to use const ref typemaps instead of pointer typemaps
475 * for variable access.
476 * -------------------------------------------------------------------------- */
use_naturalvar_mode(Node * n) const477 int Language::use_naturalvar_mode(Node *n) const {
478 if (Getattr(n, "unnamed"))
479 return 0;
480
481 // The naturalvar feature can be attached to either the variable name or the variable's type
482 // naturalvar on the variable name is more specific and overrides naturalvar on the variable's type
483 String *naturalvar = Getattr(n, "feature:naturalvar");
484 bool explicitly_off = naturalvar && Strcmp(naturalvar, "0") == 0;
485 int nvar = GetFlag(n, "feature:naturalvar");
486
487 if (!explicitly_off && !nvar) {
488 /* look for feature in the class */
489 SwigType *ty = Getattr(n, "type");
490 SwigType *fullty = SwigType_typedef_resolve_all(ty);
491 if (SwigType_isclass(fullty)) {
492 SwigType *tys = SwigType_strip_qualifiers(fullty);
493 if (!CPlusPlus) {
494 Replaceall(tys, "struct ", "");
495 Replaceall(tys, "union ", "");
496 Replaceall(tys, "class ", "");
497 }
498 Node *typenode = Swig_symbol_clookup(tys, 0);
499 if (typenode) {
500 naturalvar = Getattr(typenode, "feature:naturalvar");
501 explicitly_off = naturalvar && Strcmp(naturalvar, "0") == 0;
502 nvar = nvar || GetFlag(typenode, "feature:naturalvar");
503 }
504 Delete(tys);
505 }
506 Delete(fullty);
507 }
508 nvar = nvar || naturalvar_mode;
509 return explicitly_off ? 0 : nvar ? CWRAP_NATURAL_VAR : 0;
510 }
511
512 /* ----------------------------------------------------------------------
513 * Language::top() - Top of parsing tree
514 * ---------------------------------------------------------------------- */
515
top(Node * n)516 int Language::top(Node *n) {
517 Node *mod = Getattr(n, "module");
518 if (mod) {
519 Node *options = Getattr(mod, "options");
520 if (options) {
521 if (Getattr(options, "naturalvar")) {
522 naturalvar_mode = 1;
523 }
524 }
525 }
526 classhash = Getattr(n, "classes");
527 return emit_children(n);
528 }
529
530 /* ----------------------------------------------------------------------
531 * Language::extendDirective()
532 * ---------------------------------------------------------------------- */
533
extendDirective(Node * n)534 int Language::extendDirective(Node *n) {
535 save_value<int> oldam(Extend, CWRAP_EXTEND);
536 save_value<AccessMode> oldmode(cplus_mode, PUBLIC);
537 emit_children(n);
538 return SWIG_OK;
539 }
540
541 /* ----------------------------------------------------------------------
542 * Language::applyDirective()
543 * ---------------------------------------------------------------------- */
544
applyDirective(Node * n)545 int Language::applyDirective(Node *n) {
546
547 Parm *pattern = Getattr(n, "pattern");
548 Node *c = firstChild(n);
549 while (c) {
550 Parm *apattern = Getattr(c, "pattern");
551 if (ParmList_len(pattern) != ParmList_len(apattern)) {
552 Swig_error(input_file, line_number, "Can't apply (%s) to (%s). Number of arguments don't match.\n", ParmList_str(pattern), ParmList_str(apattern));
553 } else {
554 if (!Swig_typemap_apply(pattern, apattern)) {
555 Swig_warning(WARN_TYPEMAP_APPLY_UNDEF, input_file, line_number, "Can't apply (%s). No typemaps are defined.\n", ParmList_str(pattern));
556 }
557 }
558 c = nextSibling(c);
559 }
560 return SWIG_OK;
561 }
562
563 /* ----------------------------------------------------------------------
564 * Language::clearDirective()
565 * ---------------------------------------------------------------------- */
566
clearDirective(Node * n)567 int Language::clearDirective(Node *n) {
568 Node *p;
569 for (p = firstChild(n); p; p = nextSibling(p)) {
570 ParmList *pattern = Getattr(p, "pattern");
571 Swig_typemap_clear_apply(pattern);
572 }
573 return SWIG_OK;
574 }
575
576 /* ----------------------------------------------------------------------
577 * Language::constantDirective()
578 * ---------------------------------------------------------------------- */
579
constantDirective(Node * n)580 int Language::constantDirective(Node *n) {
581
582 if (CurrentClass && (cplus_mode != PUBLIC))
583 return SWIG_NOWRAP;
584
585 if (!GetFlag(n, "feature:allowexcept")) {
586 UnsetFlag(n, "feature:except");
587 }
588 if (Getattr(n, "feature:exceptvar")) {
589 Setattr(n, "feature:except", Getattr(n, "feature:exceptvar"));
590 }
591
592 if (!ImportMode) {
593 Swig_require("constantDirective", n, "name", "?value", NIL);
594 String *name = Getattr(n, "name");
595 String *value = Getattr(n, "value");
596 if (!value) {
597 value = Copy(name);
598 } else {
599 /* if (checkAttribute(n,"type","char")) {
600 value = NewString(value);
601 } else {
602 value = NewStringf("%(escape)s", value);
603 }
604 */
605 Setattr(n, "rawvalue", value);
606 value = NewStringf("%(escape)s", value);
607 if (!Len(value))
608 Append(value, "\\0");
609 /* Printf(stdout,"'%s' = '%s'\n", name, value); */
610 }
611 Setattr(n, "value", value);
612 this->constantWrapper(n);
613 Swig_restore(n);
614 return SWIG_OK;
615 }
616 return SWIG_NOWRAP;
617 }
618
619 /* ----------------------------------------------------------------------
620 * Language::fragmentDirective()
621 * ---------------------------------------------------------------------- */
622
fragmentDirective(Node * n)623 int Language::fragmentDirective(Node *n) {
624 if (!(Getattr(n, "emitonly") && ImportMode))
625 Swig_fragment_register(n);
626 return SWIG_OK;
627 }
628
629 /* ----------------------------------------------------------------------
630 * Language::importDirective()
631 * ---------------------------------------------------------------------- */
632
importDirective(Node * n)633 int Language::importDirective(Node *n) {
634 int oldim = ImportMode;
635 ImportMode = IMPORT_MODE;
636 emit_children(n);
637 ImportMode = oldim;
638 return SWIG_OK;
639 }
640
641 /* ----------------------------------------------------------------------
642 * Language::includeDirective()
643 * ---------------------------------------------------------------------- */
644
includeDirective(Node * n)645 int Language::includeDirective(Node *n) {
646 emit_children(n);
647 return SWIG_OK;
648 }
649
650 /* ----------------------------------------------------------------------
651 * Language::insertDirective()
652 * ---------------------------------------------------------------------- */
653
insertDirective(Node * n)654 int Language::insertDirective(Node *n) {
655 /* %insert directive */
656 if ((!ImportMode) || Getattr(n, "generated")) {
657 String *code = Getattr(n, "code");
658 String *section = Getattr(n, "section");
659 File *f = 0;
660 if (!section) { /* %{ ... %} */
661 f = Swig_filebyname("header");
662 } else {
663 f = Swig_filebyname(section);
664 }
665 if (f) {
666 Printf(f, "%s\n", code);
667 } else {
668 Swig_error(input_file, line_number, "Unknown target '%s' for %%insert directive.\n", section);
669 }
670 return SWIG_OK;
671 } else {
672 return SWIG_NOWRAP;
673 }
674 }
675
676 /* ----------------------------------------------------------------------
677 * Language::moduleDirective()
678 * ---------------------------------------------------------------------- */
679
moduleDirective(Node * n)680 int Language::moduleDirective(Node *n) {
681 (void) n;
682 /* %module directive */
683 return SWIG_OK;
684 }
685
686 /* ----------------------------------------------------------------------
687 * Language::nativeDirective()
688 * ---------------------------------------------------------------------- */
689
nativeDirective(Node * n)690 int Language::nativeDirective(Node *n) {
691 if (!ImportMode) {
692 return nativeWrapper(n);
693 } else {
694 return SWIG_NOWRAP;
695 }
696 }
697
698 /* ----------------------------------------------------------------------
699 * Language::pragmaDirective()
700 * ---------------------------------------------------------------------- */
701
pragmaDirective(Node * n)702 int Language::pragmaDirective(Node *n) {
703 /* %pragma directive */
704 if (!ImportMode) {
705 String *lan = Getattr(n, "lang");
706 String *name = Getattr(n, "name");
707 String *value = Getattr(n, "value");
708 swig_pragma(Char(lan), Char(name), Char(value));
709 /* pragma(Char(lan),Char(name),Char(value)); */
710 return SWIG_OK;
711 }
712 return SWIG_OK;
713 }
714
715 /* ----------------------------------------------------------------------
716 * Language::typemapDirective()
717 * ---------------------------------------------------------------------- */
718
typemapDirective(Node * n)719 int Language::typemapDirective(Node *n) {
720 /* %typemap directive */
721 String *method = Getattr(n, "method");
722 String *code = Getattr(n, "code");
723 Parm *kwargs = Getattr(n, "kwargs");
724 Node *items = firstChild(n);
725 static int namewarn = 0;
726
727
728 if (code && (Strstr(code, "$source") || (Strstr(code, "$target")))) {
729 Swig_warning(WARN_TYPEMAP_SOURCETARGET, Getfile(n), Getline(n), "Deprecated typemap feature ($source/$target).\n");
730 if (!namewarn) {
731 Swig_warning(WARN_TYPEMAP_SOURCETARGET, Getfile(n), Getline(n), "The use of $source and $target in a typemap declaration is deprecated.\n\
732 For typemaps related to argument input (in,ignore,default,arginit,check), replace\n\
733 $source by $input and $target by $1. For typemaps related to return values (out,\n\
734 argout,ret,except), replace $source by $1 and $target by $result. See the file\n\
735 Doc/Manual/Typemaps.html for complete details.\n");
736 namewarn = 1;
737 }
738 }
739
740 if (Strcmp(method, "except") == 0) {
741 Swig_warning(WARN_DEPRECATED_EXCEPT_TM, Getfile(n), Getline(n), "%%typemap(except) is deprecated. Use the %%exception directive.\n");
742 }
743
744 if (Strcmp(method, "in") == 0) {
745 Hash *k;
746 k = kwargs;
747 while (k) {
748 if (checkAttribute(k, "name", "numinputs")) {
749 if (!multiinput && (GetInt(k, "value") > 1)) {
750 Swig_error(Getfile(n), Getline(n), "Multiple-input typemaps (numinputs > 1) not supported by this target language module.\n");
751 return SWIG_ERROR;
752 }
753 break;
754 }
755 k = nextSibling(k);
756 }
757 if (!k) {
758 k = NewHash();
759 Setattr(k, "name", "numinputs");
760 Setattr(k, "value", "1");
761 set_nextSibling(k, kwargs);
762 Setattr(n, "kwargs", k);
763 kwargs = k;
764 }
765 }
766
767 if (Strcmp(method, "ignore") == 0) {
768 Swig_warning(WARN_DEPRECATED_IGNORE_TM, Getfile(n), Getline(n), "%%typemap(ignore) has been replaced by %%typemap(in,numinputs=0).\n");
769
770 Clear(method);
771 Append(method, "in");
772 Hash *k = NewHash();
773 Setattr(k, "name", "numinputs");
774 Setattr(k, "value", "0");
775 set_nextSibling(k, kwargs);
776 Setattr(n, "kwargs", k);
777 kwargs = k;
778 }
779
780 /* Replace $descriptor() macros */
781
782 if (code) {
783 Setfile(code, Getfile(n));
784 Setline(code, Getline(n));
785 Swig_cparse_replace_descriptor(code);
786 }
787
788 while (items) {
789 Parm *pattern = Getattr(items, "pattern");
790 Parm *parms = Getattr(items, "parms");
791
792 if (code) {
793 Swig_typemap_register(method, pattern, code, parms, kwargs);
794 } else {
795 Swig_typemap_clear(method, pattern);
796 }
797 items = nextSibling(items);
798 }
799 return SWIG_OK;
800
801 }
802
803 /* ----------------------------------------------------------------------
804 * Language::typemapcopyDirective()
805 * ---------------------------------------------------------------------- */
806
typemapcopyDirective(Node * n)807 int Language::typemapcopyDirective(Node *n) {
808 String *method = Getattr(n, "method");
809 Parm *pattern = Getattr(n, "pattern");
810 Node *items = firstChild(n);
811 int nsrc = 0;
812 nsrc = ParmList_len(pattern);
813 while (items) {
814 ParmList *npattern = Getattr(items, "pattern");
815 if (nsrc != ParmList_len(npattern)) {
816 Swig_error(input_file, line_number, "Can't copy typemap. Number of types differ.\n");
817 } else {
818 if (Swig_typemap_copy(method, pattern, npattern) < 0) {
819 Swig_error(input_file, line_number, "Can't copy typemap (%s) %s = %s\n", method, ParmList_str(pattern), ParmList_str(npattern));
820 }
821 }
822 items = nextSibling(items);
823 }
824 return SWIG_OK;
825 }
826
827 /* ----------------------------------------------------------------------
828 * Language::typesDirective()
829 * ---------------------------------------------------------------------- */
830
typesDirective(Node * n)831 int Language::typesDirective(Node *n) {
832 Parm *parms = Getattr(n, "parms");
833 String *convcode = Getattr(n, "convcode"); /* optional user supplied conversion code for custom casting */
834 while (parms) {
835 SwigType *t = Getattr(parms, "type");
836 String *v = Getattr(parms, "value");
837 if (!v) {
838 SwigType_remember(t);
839 } else {
840 if (SwigType_issimple(t)) {
841 SwigType_inherit(t, v, 0, convcode);
842 }
843 }
844 parms = nextSibling(parms);
845 }
846 return SWIG_OK;
847 }
848
849 /* ----------------------------------------------------------------------
850 * Language::cDeclaration()
851 * ---------------------------------------------------------------------- */
852
cDeclaration(Node * n)853 int Language::cDeclaration(Node *n) {
854
855 String *name = Getattr(n, "name");
856 String *symname = Getattr(n, "sym:name");
857 SwigType *type = Getattr(n, "type");
858 SwigType *decl = Getattr(n, "decl");
859 String *storage = Getattr(n, "storage");
860 Node *over;
861 File *f_header = 0;
862 SwigType *ty, *fullty;
863
864 if (Getattr(n, "feature:onlychildren")) {
865 if (GetFlag(n, "feature:ignore")) {
866 return SWIG_NOWRAP;
867 } else {
868 // Found an unignored templated method that has an empty template instantiation (%template())
869 // Ignore it unless it has been %rename'd
870 if (Strncmp(symname, "__dummy_", 8) == 0 && Cmp(storage, "typedef") != 0) {
871 SetFlag(n, "feature:ignore");
872 Swig_warning(WARN_LANG_TEMPLATE_METHOD_IGNORE, input_file, line_number,
873 "%%template() contains no name. Template method ignored: %s\n", Swig_name_decl(n));
874 return SWIG_NOWRAP;
875 }
876 }
877 }
878
879 /* discards nodes following the access control rules */
880 if (cplus_mode != PUBLIC || !is_public(n)) {
881 /* except for friends, they are not affected by access control */
882 int isfriend = Cmp(storage, "friend") == 0;
883 if (!isfriend) {
884 /* Check what the director needs. If the method is pure virtual, it is always needed.
885 * Also wrap non-virtual protected members if asked for (allprotected mode). */
886 if (!(directorsEnabled() && ((is_member_director(CurrentClass, n) && need_nonpublic_member(n)) || isNonVirtualProtectedAccess(n)))) {
887 return SWIG_NOWRAP;
888 }
889 // Prevent wrapping protected overloaded director methods more than once -
890 // This bit of code is only needed due to the cDeclaration call in classHandler()
891 String *wrapname = NewStringf("nonpublic_%s%s", symname, Getattr(n, "sym:overname"));
892 if (Getattr(CurrentClass, wrapname)) {
893 Delete(wrapname);
894 return SWIG_NOWRAP;
895 }
896 SetFlag(CurrentClass, wrapname);
897 Delete(wrapname);
898 }
899 }
900
901 if (Cmp(storage, "typedef") == 0) {
902 Swig_save("cDeclaration", n, "type", NIL);
903 SwigType *t = Copy(type);
904 if (t) {
905 SwigType_push(t, decl);
906 Setattr(n, "type", t);
907 typedefHandler(n);
908 }
909 Swig_restore(n);
910 return SWIG_OK;
911 }
912
913 /* If in import mode, we proceed no further */
914 if (ImportMode)
915 return SWIG_NOWRAP;
916
917 /* If we're in extend mode and there is code, replace the $descriptor macros */
918 if (Extend) {
919 String *code = Getattr(n, "code");
920 if (code) {
921 Setfile(code, Getfile(n));
922 Setline(code, Getline(n));
923 Swig_cparse_replace_descriptor(code);
924 }
925 }
926
927 /* Overloaded symbol check */
928 over = Swig_symbol_isoverloaded(n);
929 if (!overloading) {
930 if (over)
931 over = first_nontemplate(over);
932 if (over && (over != n)) {
933 Swig_warning(WARN_LANG_OVERLOAD_DECL, input_file, line_number, "Overloaded declaration ignored. %s\n", Swig_name_decl(n));
934 Swig_warning(WARN_LANG_OVERLOAD_DECL, Getfile(over), Getline(over), "Previous declaration is %s\n", Swig_name_decl(over));
935 return SWIG_NOWRAP;
936 }
937 }
938
939 if (!validIdentifier(symname)) {
940 Swig_warning(WARN_LANG_IDENTIFIER, input_file, line_number, "Can't wrap '%s' unless renamed to a valid identifier.\n", SwigType_namestr(symname));
941 return SWIG_NOWRAP;
942 }
943
944 ty = NewString(type);
945 SwigType_push(ty, decl);
946 fullty = SwigType_typedef_resolve_all(ty);
947 if (SwigType_isfunction(fullty)) {
948 if (!SwigType_isfunction(ty)) {
949 Delete(ty);
950 ty = fullty;
951 fullty = 0;
952 ParmList *parms = SwigType_function_parms(ty, n);
953 Setattr(n, "parms", parms);
954 }
955 /* Transform the node into a 'function' node and emit */
956 if (!CurrentClass) {
957 f_header = Swig_filebyname("header");
958
959 if (AddExtern) {
960 if (f_header) {
961 if (Swig_storage_isextern(n) || (ForceExtern && !storage)) {
962 /* we don't need the 'extern' part in the C/C++ declaration,
963 and it produces some problems when namespace and SUN
964 Studio is used.
965
966 Printf(f_header,"extern %s", SwigType_str(ty,name));
967
968 In fact generating extern declarations is quite error prone and is
969 no longer the default. Getting it right seems impossible with namespaces
970 and default arguments and when a method is declared with the various Windows
971 calling conventions - SWIG doesn't understand Windows (non standard) calling
972 conventions in the first place, so can't regenerate them.
973 */
974 String *str = SwigType_str(ty, name);
975 Printf(f_header, "%s", str);
976 Delete(str);
977 {
978 DOH *t = Getattr(n, "throws");
979 if (t) {
980 Printf(f_header, " throw(");
981 while (t) {
982 Printf(f_header, "%s", Getattr(t, "type"));
983 t = nextSibling(t);
984 if (t)
985 Printf(f_header, ",");
986 }
987 Printf(f_header, ")");
988 }
989 }
990 Printf(f_header, ";\n");
991 } else if (Swig_storage_isexternc(n)) {
992 /* here 'extern "C"' is needed */
993 String *str = SwigType_str(ty, name);
994 Printf(f_header, "extern \"C\" %s;\n", str);
995 Delete(str);
996 }
997 }
998 }
999 }
1000 /* This needs to check qualifiers */
1001 if (SwigType_isqualifier(ty)) {
1002 SwigType *qual = SwigType_pop(ty);
1003 Setattr(n, "qualifier", qual);
1004 Delete(qual);
1005 }
1006 Delete(SwigType_pop_function(ty));
1007 DohIncref(type);
1008 Setattr(n, "type", ty);
1009
1010 functionHandler(n);
1011
1012 Setattr(n, "type", type);
1013 Delete(ty);
1014 Delete(type);
1015 return SWIG_OK;
1016 } else {
1017 /* Some kind of variable declaration */
1018 String *declaration = Copy(decl);
1019 Delattr(n, "decl");
1020 if (!CurrentClass) {
1021 if (Swig_storage_isextern(n) || ForceExtern) {
1022 if (AddExtern) {
1023 f_header = Swig_filebyname("header");
1024 if (f_header) {
1025 String *str = SwigType_str(ty, name);
1026 Printf(f_header, "%s %s;\n", Getattr(n, "storage"), str);
1027 Delete(str);
1028 }
1029 }
1030 }
1031 }
1032 if (!SwigType_ismutable(ty)) {
1033 SetFlag(n, "feature:immutable");
1034 }
1035 /* If an array and elements are const, then read-only */
1036 if (SwigType_isarray(ty)) {
1037 SwigType *tya = SwigType_array_type(ty);
1038 if (SwigType_isconst(tya)) {
1039 SetFlag(n, "feature:immutable");
1040 }
1041 Delete(tya);
1042 }
1043 DohIncref(type);
1044 Setattr(n, "type", ty);
1045 variableHandler(n);
1046 Setattr(n, "type", type);
1047 Setattr(n, "decl", declaration);
1048 Delete(ty);
1049 Delete(type);
1050 Delete(fullty);
1051 return SWIG_OK;
1052 }
1053 }
1054
1055 /* ----------------------------------------------------------------------
1056 * Language::functionHandler()
1057 * ---------------------------------------------------------------------- */
1058
functionHandler(Node * n)1059 int Language::functionHandler(Node *n) {
1060 String *storage = Getattr(n, "storage");
1061 int isfriend = CurrentClass && Cmp(storage, "friend") == 0;
1062 int isstatic = CurrentClass && Swig_storage_isstatic(n) && !(SmartPointer && Getattr(n, "allocate:smartpointeraccess"));
1063 Parm *p = Getattr(n, "parms");
1064 if (GetFlag(n, "feature:del")) {
1065 /* the method acts like a delete operator, ie, we need to disown the parameter */
1066 if (CurrentClass && !isstatic && !isfriend) {
1067 SetFlag(n, "feature:self:disown");
1068 } else {
1069 if (p)
1070 SetFlag(p, "wrap:disown");
1071 }
1072 }
1073 if (!CurrentClass) {
1074 globalfunctionHandler(n);
1075 } else {
1076 if (isstatic) {
1077 staticmemberfunctionHandler(n);
1078 } else if (isfriend) {
1079 int oldInClass = InClass;
1080 InClass = 0;
1081 globalfunctionHandler(n);
1082 InClass = oldInClass;
1083 } else {
1084 // This is a member function, set a flag so the documentation type is correct
1085 SetFlag(n, "memberfunction");
1086 Node *explicit_n = 0;
1087 if (directorsEnabled() && is_member_director(CurrentClass, n) && !extraDirectorProtectedCPPMethodsRequired()) {
1088 bool virtual_but_not_pure_virtual = (!(Cmp(storage, "virtual")) && (Cmp(Getattr(n, "value"), "0") != 0));
1089 if (virtual_but_not_pure_virtual) {
1090 // Add additional wrapper which makes an explicit call to the virtual method (ie not a virtual call)
1091 explicit_n = Copy(n);
1092 String *new_symname = Copy(Getattr(n, "sym:name"));
1093 String *suffix = Getattr(parentNode(n), "sym:name");
1094 Printv(new_symname, "SwigExplicit", suffix, NIL);
1095 Setattr(explicit_n, "sym:name", new_symname);
1096 Delattr(explicit_n, "storage");
1097 Delattr(explicit_n, "override");
1098 Delattr(explicit_n, "hides");
1099 SetFlag(explicit_n, "explicitcall");
1100 Setattr(n, "explicitcallnode", explicit_n);
1101 }
1102 }
1103
1104 memberfunctionHandler(n);
1105
1106 if (explicit_n) {
1107 memberfunctionHandler(explicit_n);
1108 Delattr(explicit_n, "explicitcall");
1109 Delete(explicit_n);
1110 }
1111 }
1112 }
1113 return SWIG_OK;
1114 }
1115
1116 /* ----------------------------------------------------------------------
1117 * Language::globalfunctionHandler()
1118 * ---------------------------------------------------------------------- */
1119
globalfunctionHandler(Node * n)1120 int Language::globalfunctionHandler(Node *n) {
1121
1122 Swig_require("globalfunctionHandler", n, "name", "sym:name", "type", "?parms", NIL);
1123
1124 String *name = Getattr(n, "name");
1125 String *symname = Getattr(n, "sym:name");
1126 SwigType *type = Getattr(n, "type");
1127 ParmList *parms = Getattr(n, "parms");
1128
1129 /* Check for callback mode */
1130 String *cb = GetFlagAttr(n, "feature:callback");
1131 if (cb) {
1132 String *cbname = Getattr(n, "feature:callback:name");
1133 if (!cbname) {
1134 cbname = NewStringf(cb, symname);
1135 Setattr(n, "feature:callback:name", cbname);
1136 }
1137
1138 callbackfunctionHandler(n);
1139 if (Cmp(cbname, symname) == 0) {
1140 Delete(cbname);
1141 Swig_restore(n);
1142 return SWIG_NOWRAP;
1143 }
1144 Delete(cbname);
1145 }
1146 Setattr(n, "parms", nonvoid_parms(parms));
1147
1148 String *extendname = Getattr(n, "extendname");
1149 String *call = Swig_cfunction_call(extendname ? extendname : name, parms);
1150 String *cres = Swig_cresult(type, Swig_cresult_name(), call);
1151 Setattr(n, "wrap:action", cres);
1152 Delete(cres);
1153 Delete(call);
1154 functionWrapper(n);
1155
1156 Swig_restore(n);
1157 return SWIG_OK;
1158 }
1159
1160 /* ----------------------------------------------------------------------
1161 * Language::callbackfunctionHandler()
1162 * ---------------------------------------------------------------------- */
1163
callbackfunctionHandler(Node * n)1164 int Language::callbackfunctionHandler(Node *n) {
1165 Swig_require("callbackfunctionHandler", n, "name", "*sym:name", "*type", "?value", NIL);
1166 String *type = Getattr(n, "type");
1167 String *name = Getattr(n, "name");
1168 String *parms = Getattr(n, "parms");
1169 String *cbname = Getattr(n, "feature:callback:name");
1170 String *calltype = NewStringf("(%s (*)(%s))(%s)", SwigType_str(type, 0), ParmList_str(parms), SwigType_namestr(name));
1171 SwigType *cbty = Copy(type);
1172 SwigType_add_function(cbty, parms);
1173 SwigType_add_pointer(cbty);
1174
1175 Setattr(n, "sym:name", cbname);
1176 Setattr(n, "type", cbty);
1177 Setattr(n, "value", calltype);
1178
1179 Node *ns = symbolLookup(cbname);
1180 if (!ns)
1181 constantWrapper(n);
1182
1183 Delete(cbty);
1184
1185 Swig_restore(n);
1186 return SWIG_OK;
1187 }
1188
1189 /* ----------------------------------------------------------------------
1190 * Language::memberfunctionHandler()
1191 * ---------------------------------------------------------------------- */
1192
memberfunctionHandler(Node * n)1193 int Language::memberfunctionHandler(Node *n) {
1194
1195 Swig_require("memberfunctionHandler", n, "*name", "*sym:name", "*type", "?parms", "?value", NIL);
1196
1197 String *storage = Getattr(n, "storage");
1198 String *name = Getattr(n, "name");
1199 String *symname = Getattr(n, "sym:name");
1200 SwigType *type = Getattr(n, "type");
1201 String *value = Getattr(n, "value");
1202 ParmList *parms = Getattr(n, "parms");
1203 String *cb = GetFlagAttr(n, "feature:callback");
1204
1205 if (Cmp(storage, "virtual") == 0) {
1206 if (Cmp(value, "0") == 0) {
1207 IsVirtual = PURE_VIRTUAL;
1208 } else {
1209 IsVirtual = PLAIN_VIRTUAL;
1210 }
1211 } else {
1212 IsVirtual = 0;
1213 }
1214 if (cb) {
1215 Node *cbn = NewHash();
1216 String *cbname = Getattr(n, "feature:callback:name");
1217 if (!cbname) {
1218 cbname = NewStringf(cb, symname);
1219 }
1220
1221 SwigType *cbty = Copy(type);
1222 SwigType_add_function(cbty, parms);
1223 SwigType_add_memberpointer(cbty, ClassName);
1224 String *cbvalue = NewStringf("&%s::%s", ClassName, name);
1225 Setattr(cbn, "sym:name", cbname);
1226 Setattr(cbn, "type", cbty);
1227 Setattr(cbn, "value", cbvalue);
1228 Setattr(cbn, "name", name);
1229 Setfile(cbn, Getfile(n));
1230 Setline(cbn, Getline(n));
1231
1232 memberconstantHandler(cbn);
1233 Setattr(n, "feature:callback:name", Swig_name_member(NSpace, ClassPrefix, cbname));
1234
1235 Delete(cb);
1236 Delete(cbn);
1237 Delete(cbvalue);
1238 Delete(cbty);
1239 Delete(cbname);
1240 if (Cmp(cbname, symname) == 0) {
1241 Swig_restore(n);
1242 return SWIG_NOWRAP;
1243 }
1244 }
1245
1246 String *fname = Swig_name_member(NSpace, ClassPrefix, symname);
1247 if (Extend && SmartPointer) {
1248 if (!Getattr(n, "extendsmartclassname")) {
1249 Setattr(n, "extendsmartclassname", Getattr(CurrentClass, "allocate:smartpointerpointeeclassname"));
1250 }
1251 }
1252 // Set up the type for the cast to this class for use when wrapping const director (virtual) methods.
1253 // Note: protected director methods or when allprotected mode turned on.
1254 String *director_type = 0;
1255 if (!is_public(n) && (is_member_director(CurrentClass, n) || GetFlag(n, "explicitcall") || isNonVirtualProtectedAccess(n))) {
1256 director_type = Copy(DirectorClassName);
1257 String *qualifier = Getattr(n, "qualifier");
1258 if (qualifier)
1259 SwigType_push(director_type, qualifier);
1260 SwigType_add_pointer(director_type);
1261 }
1262
1263 int DirectorExtraCall = 0;
1264 if (directorsEnabled() && is_member_director(CurrentClass, n) && !SmartPointer)
1265 if (extraDirectorProtectedCPPMethodsRequired())
1266 DirectorExtraCall = CWRAP_DIRECTOR_TWO_CALLS;
1267
1268 if (GetFlag(n, "explicitcall"))
1269 DirectorExtraCall = CWRAP_DIRECTOR_ONE_CALL;
1270
1271 int extendmember = GetFlag(n, "isextendmember") ? Extend : 0;
1272 int flags = Getattr(n, "template") ? extendmember | SmartPointer : Extend | SmartPointer | DirectorExtraCall;
1273 Swig_MethodToFunction(n, NSpace, ClassType, flags, director_type, is_member_director(CurrentClass, n));
1274 Setattr(n, "sym:name", fname);
1275 /* Explicitly save low-level and high-level documentation names */
1276 Setattr(n, "doc:low:name", fname);
1277 Setattr(n, "doc:high:name", symname);
1278
1279 functionWrapper(n);
1280
1281 Delete(director_type);
1282 Delete(fname);
1283 Swig_restore(n);
1284 return SWIG_OK;
1285 }
1286
1287 /* ----------------------------------------------------------------------
1288 * Language::staticmemberfunctionHandler()
1289 * ---------------------------------------------------------------------- */
1290
staticmemberfunctionHandler(Node * n)1291 int Language::staticmemberfunctionHandler(Node *n) {
1292
1293 Swig_require("staticmemberfunctionHandler", n, "*name", "*sym:name", "*type", NIL);
1294 Swig_save("staticmemberfunctionHandler", n, "storage", NIL);
1295 String *name = Getattr(n, "name");
1296 String *symname = Getattr(n, "sym:name");
1297 SwigType *type = Getattr(n, "type");
1298 ParmList *parms = Getattr(n, "parms");
1299 String *cb = GetFlagAttr(n, "feature:callback");
1300 String *cname, *mrename;
1301
1302 if (!Extend) {
1303 Node *sb = Getattr(n, "cplus:staticbase");
1304 String *sname = Getattr(sb, "name");
1305 if (isNonVirtualProtectedAccess(n))
1306 cname = NewStringf("%s::%s", DirectorClassName, name);
1307 else
1308 cname = NewStringf("%s::%s", sname, name);
1309 } else {
1310 String *mname = Swig_name_mangle(ClassName);
1311 cname = Swig_name_member(NSpace, mname, name);
1312 Delete(mname);
1313 }
1314 mrename = Swig_name_member(NSpace, ClassPrefix, symname);
1315
1316 if (Extend) {
1317 String *code = Getattr(n, "code");
1318 String *defaultargs = Getattr(n, "defaultargs");
1319 String *mangled = Swig_name_mangle(mrename);
1320 Delete(mrename);
1321 mrename = mangled;
1322
1323 if (Getattr(n, "sym:overloaded") && code) {
1324 Append(cname, Getattr(defaultargs ? defaultargs : n, "sym:overname"));
1325 }
1326
1327 if (!defaultargs && code) {
1328 /* Hmmm. An added static member. We have to create a little wrapper for this */
1329 String *mangled_cname = Swig_name_mangle(cname);
1330 Swig_add_extension_code(n, mangled_cname, parms, type, code, CPlusPlus, 0);
1331 Setattr(n, "extendname", mangled_cname);
1332 Delete(mangled_cname);
1333 }
1334 }
1335
1336 Setattr(n, "name", cname);
1337 Setattr(n, "sym:name", mrename);
1338 /* Explicitly save low-level and high-level documentation names */
1339 Setattr(n, "doc:low:name", mrename);
1340 Setattr(n, "doc:high:name", symname);
1341
1342 if (cb) {
1343 String *cbname = NewStringf(cb, symname);
1344 Setattr(n, "feature:callback:name", Swig_name_member(NSpace, ClassPrefix, cbname));
1345 Setattr(n, "feature:callback:staticname", name);
1346 }
1347 Delattr(n, "storage");
1348
1349 globalfunctionHandler(n);
1350
1351 Delete(cname);
1352 Delete(mrename);
1353 Swig_restore(n);
1354 return SWIG_OK;
1355 }
1356
1357 /* ----------------------------------------------------------------------
1358 * Language::variableHandler()
1359 * ---------------------------------------------------------------------- */
1360
variableHandler(Node * n)1361 int Language::variableHandler(Node *n) {
1362
1363 /* If not a smart-pointer access or added method. We clear
1364 feature:except. There is no way C++ or C would throw
1365 an exception merely for accessing a member data.
1366
1367 Caveat: Some compilers seem to route attribute access through
1368 methods which can generate exceptions. The feature:allowexcept
1369 allows this. Also, the feature:exceptvar can be used to match
1370 only variables.
1371 */
1372 if (!(Extend | SmartPointer)) {
1373 if (!GetFlag(n, "feature:allowexcept")) {
1374 UnsetFlag(n, "feature:except");
1375 }
1376 if (Getattr(n, "feature:exceptvar")) {
1377 Setattr(n, "feature:except", Getattr(n, "feature:exceptvar"));
1378 }
1379 }
1380
1381 if (!CurrentClass) {
1382 globalvariableHandler(n);
1383 } else {
1384 Swig_save("variableHandler", n, "feature:immutable", NIL);
1385 if (SmartPointer) {
1386 /* If a smart-pointer and it's a constant access, we have to set immutable */
1387 if (!Getattr(CurrentClass, "allocate:smartpointermutable")) {
1388 SetFlag(n, "feature:immutable");
1389 }
1390 }
1391 if (Swig_storage_isstatic(n) && !(SmartPointer && Getattr(n, "allocate:smartpointeraccess"))) {
1392 staticmembervariableHandler(n);
1393 } else {
1394 membervariableHandler(n);
1395 }
1396 Swig_restore(n);
1397 }
1398 return SWIG_OK;
1399 }
1400
1401 /* ----------------------------------------------------------------------
1402 * Language::globalvariableHandler()
1403 * ---------------------------------------------------------------------- */
1404
globalvariableHandler(Node * n)1405 int Language::globalvariableHandler(Node *n) {
1406 variableWrapper(n);
1407 return SWIG_OK;
1408 }
1409
1410 /* ----------------------------------------------------------------------
1411 * Language::membervariableHandler()
1412 * ---------------------------------------------------------------------- */
1413
membervariableHandler(Node * n)1414 int Language::membervariableHandler(Node *n) {
1415
1416 Swig_require("membervariableHandler", n, "*name", "*sym:name", "*type", NIL);
1417 Swig_save("membervariableHandler", n, "parms", NIL);
1418
1419 String *name = Getattr(n, "name");
1420 String *symname = Getattr(n, "sym:name");
1421 SwigType *type = Getattr(n, "type");
1422
1423 if (!AttributeFunctionGet) {
1424 String *mname = Swig_name_member(0, ClassPrefix, symname);
1425 String *mrename_get = Swig_name_get(NSpace, mname);
1426 String *mrename_set = Swig_name_set(NSpace, mname);
1427 Delete(mname);
1428
1429 /* Create a function to set the value of the variable */
1430
1431 int assignable = is_assignable(n);
1432
1433 if (SmartPointer) {
1434 if (!Getattr(CurrentClass, "allocate:smartpointermutable")) {
1435 assignable = 0;
1436 }
1437 }
1438
1439 if (assignable) {
1440 int make_set_wrapper = 1;
1441 String *tm = 0;
1442 String *target = 0;
1443 if (!Extend) {
1444 if (SmartPointer) {
1445 if (Swig_storage_isstatic(n)) {
1446 Node *sn = Getattr(n, "cplus:staticbase");
1447 String *base = Getattr(sn, "name");
1448 target = NewStringf("%s::%s", base, name);
1449 } else {
1450 String *pname = Swig_cparm_name(0, 0);
1451 target = NewStringf("(*%s)->%s", pname, name);
1452 Delete(pname);
1453 }
1454 } else {
1455 String *pname = isNonVirtualProtectedAccess(n) ? NewString("darg") : Swig_cparm_name(0, 0);
1456 target = NewStringf("%s->%s", pname, name);
1457 Delete(pname);
1458 }
1459
1460 // This is an input type typemap lookup and so it should not use Node n
1461 // otherwise qualification is done on the parameter name for the setter function
1462 Parm *nin = NewParm(type, name, n);
1463 tm = Swig_typemap_lookup("memberin", nin, target, 0);
1464 Delete(nin);
1465 }
1466
1467 int flags = Extend | SmartPointer | use_naturalvar_mode(n);
1468 if (isNonVirtualProtectedAccess(n))
1469 flags = flags | CWRAP_ALL_PROTECTED_ACCESS;
1470
1471 Swig_MembersetToFunction(n, ClassType, flags);
1472 Setattr(n, "memberset", "1");
1473 if (!Extend) {
1474 /* Check for a member in typemap here */
1475
1476 if (!tm) {
1477 if (SwigType_isarray(type)) {
1478 Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(type, 0));
1479 make_set_wrapper = 0;
1480 }
1481 } else {
1482 String *pname0 = Swig_cparm_name(0, 0);
1483 String *pname1 = Swig_cparm_name(0, 1);
1484 Replace(tm, "$source", pname1, DOH_REPLACE_ANY);
1485 Replace(tm, "$target", target, DOH_REPLACE_ANY);
1486 Replace(tm, "$input", pname1, DOH_REPLACE_ANY);
1487 Replace(tm, "$self", pname0, DOH_REPLACE_ANY);
1488 Setattr(n, "wrap:action", tm);
1489 Delete(tm);
1490 Delete(pname0);
1491 Delete(pname1);
1492 }
1493 Delete(target);
1494 }
1495 if (make_set_wrapper) {
1496 Setattr(n, "sym:name", mrename_set);
1497 functionWrapper(n);
1498 } else {
1499 SetFlag(n, "feature:immutable");
1500 }
1501 /* Restore parameters */
1502 Setattr(n, "type", type);
1503 Setattr(n, "name", name);
1504 Setattr(n, "sym:name", symname);
1505 Delattr(n, "memberset");
1506
1507 /* Delete all attached typemaps and typemap attributes */
1508 Iterator ki;
1509 for (ki = First(n); ki.key; ki = Next(ki)) {
1510 if (Strncmp(ki.key, "tmap:", 5) == 0)
1511 Delattr(n, ki.key);
1512 }
1513 }
1514 /* Emit get function */
1515 {
1516 int flags = Extend | SmartPointer | use_naturalvar_mode(n);
1517 if (isNonVirtualProtectedAccess(n))
1518 flags = flags | CWRAP_ALL_PROTECTED_ACCESS;
1519 Swig_MembergetToFunction(n, ClassType, flags);
1520 Setattr(n, "sym:name", mrename_get);
1521 Setattr(n, "memberget", "1");
1522 functionWrapper(n);
1523 Delattr(n, "memberget");
1524 }
1525 Delete(mrename_get);
1526 Delete(mrename_set);
1527
1528 } else {
1529
1530 /* This code is used to support the attributefunction directive
1531 where member variables are converted automagically to
1532 accessor functions */
1533
1534 #if 0
1535 Parm *p;
1536 String *gname;
1537 SwigType *vty;
1538 p = NewParm(type, 0, n);
1539 gname = NewStringf(AttributeFunctionGet, symname);
1540 if (!Extend) {
1541 ActionFunc = Copy(Swig_cmemberget_call(name, type));
1542 cpp_member_func(Char(gname), Char(gname), type, 0);
1543 Delete(ActionFunc);
1544 } else {
1545 String *cname = Swig_name_get(NSpace, name);
1546 cpp_member_func(Char(cname), Char(gname), type, 0);
1547 Delete(cname);
1548 }
1549 Delete(gname);
1550 if (!GetFlag(n, "feature:immutable")) {
1551 gname = NewStringf(AttributeFunctionSet, symname);
1552 vty = NewString("void");
1553 if (!Extend) {
1554 ActionFunc = Copy(Swig_cmemberset_call(name, type));
1555 cpp_member_func(Char(gname), Char(gname), vty, p);
1556 Delete(ActionFunc);
1557 } else {
1558 String *cname = Swig_name_set(NSpace, name);
1559 cpp_member_func(Char(cname), Char(gname), vty, p);
1560 Delete(cname);
1561 }
1562 Delete(gname);
1563 }
1564 ActionFunc = 0;
1565 #endif
1566 }
1567 Swig_restore(n);
1568 return SWIG_OK;
1569 }
1570
1571 /* ----------------------------------------------------------------------
1572 * Language::staticmembervariableHandler()
1573 * ---------------------------------------------------------------------- */
1574
staticmembervariableHandler(Node * n)1575 int Language::staticmembervariableHandler(Node *n) {
1576 Swig_require("staticmembervariableHandler", n, "*name", "*sym:name", "*type", "?value", NIL);
1577 String *value = Getattr(n, "value");
1578 String *classname = !SmartPointer ? (isNonVirtualProtectedAccess(n) ? DirectorClassName : ClassName) : Getattr(CurrentClass, "allocate:smartpointerpointeeclassname");
1579
1580 if (!value || !Getattr(n, "hasconsttype")) {
1581 String *name = Getattr(n, "name");
1582 String *symname = Getattr(n, "sym:name");
1583 String *cname, *mrename;
1584
1585 /* Create the variable name */
1586 mrename = Swig_name_member(0, ClassPrefix, symname);
1587 cname = NewStringf("%s::%s", classname, name);
1588
1589 Setattr(n, "sym:name", mrename);
1590 Setattr(n, "name", cname);
1591
1592 /* Wrap as an ordinary global variable */
1593 variableWrapper(n);
1594
1595 Delete(mrename);
1596 Delete(cname);
1597 } else {
1598
1599 /* This is a C++ static member declaration with an initializer and it's const.
1600 Certain C++ compilers optimize this out so that there is no linkage to a
1601 memory address. Example:
1602
1603 class Foo {
1604 public:
1605 static const int x = 3;
1606 };
1607
1608 Some discussion of this in section 9.4 of the C++ draft standard.
1609
1610 Also, we have to manage the case:
1611
1612 class Foo {
1613 public:
1614 %extend {
1615 static const int x = 3;
1616 }
1617 };
1618
1619 in which there's no actual Foo::x variable to refer to. In this case,
1620 the best we can do is to wrap the given value verbatim.
1621 */
1622
1623
1624 String *name = Getattr(n, "name");
1625 String *cname = NewStringf("%s::%s", classname, name);
1626 if (Extend) {
1627 /* the variable is a synthesized one.
1628 There's nothing we can do; we just keep the given value */
1629 } else {
1630 /* we refer to the value as Foo::x */
1631 String *value = SwigType_namestr(cname);
1632 Setattr(n, "value", value);
1633 }
1634
1635 SwigType *t1 = SwigType_typedef_resolve_all(Getattr(n, "type"));
1636 SwigType *t2 = SwigType_strip_qualifiers(t1);
1637 Setattr(n, "type", t2);
1638 Delete(t1);
1639 Delete(t2);
1640 SetFlag(n, "wrappedasconstant");
1641 memberconstantHandler(n);
1642 Delete(cname);
1643 }
1644
1645 Swig_restore(n);
1646 return SWIG_OK;
1647 }
1648
1649
1650 /* ----------------------------------------------------------------------
1651 * Language::externDeclaration()
1652 * ---------------------------------------------------------------------- */
1653
externDeclaration(Node * n)1654 int Language::externDeclaration(Node *n) {
1655 return emit_children(n);
1656 }
1657
1658 /* ----------------------------------------------------------------------
1659 * Language::enumDeclaration()
1660 * ---------------------------------------------------------------------- */
1661
enumDeclaration(Node * n)1662 int Language::enumDeclaration(Node *n) {
1663 if (CurrentClass && (cplus_mode != PUBLIC))
1664 return SWIG_NOWRAP;
1665
1666 String *oldNSpace = NSpace;
1667 NSpace = Getattr(n, "sym:nspace");
1668
1669 String *oldEnumClassPrefix = EnumClassPrefix;
1670 if (GetFlag(n, "scopedenum")) {
1671 assert(Getattr(n, "sym:name"));
1672 assert(Getattr(n, "name"));
1673 EnumClassPrefix = ClassPrefix ? NewStringf("%s_", ClassPrefix) : NewString("");
1674 Printv(EnumClassPrefix, Getattr(n, "sym:name"), NIL);
1675 EnumClassName = Copy(Getattr(n, "name"));
1676 }
1677 if (!ImportMode) {
1678 emit_children(n);
1679 }
1680
1681 if (GetFlag(n, "scopedenum")) {
1682 Delete(EnumClassName);
1683 EnumClassName = 0;
1684 Delete(EnumClassPrefix);
1685 EnumClassPrefix = oldEnumClassPrefix;
1686 }
1687 NSpace = oldNSpace;
1688
1689 return SWIG_OK;
1690 }
1691
1692 /* ----------------------------------------------------------------------
1693 * Language::enumvalueDeclaration()
1694 * ---------------------------------------------------------------------- */
1695
enumvalueDeclaration(Node * n)1696 int Language::enumvalueDeclaration(Node *n) {
1697 if (CurrentClass && (cplus_mode != PUBLIC))
1698 return SWIG_NOWRAP;
1699
1700 Swig_require("enumvalueDeclaration", n, "*name", "*sym:name", "?value", NIL);
1701 String *value = Getattr(n, "value");
1702 String *name = Getattr(n, "name");
1703 String *tmpValue;
1704
1705 if (value)
1706 tmpValue = NewString(value);
1707 else
1708 tmpValue = NewString(name);
1709 Setattr(n, "value", tmpValue);
1710
1711 Node *parent = parentNode(n);
1712 if (GetFlag(parent, "scopedenum")) {
1713 String *symname = Swig_name_member(0, Getattr(parent, "sym:name"), Getattr(n, "sym:name"));
1714 Setattr(n, "sym:name", symname);
1715 Delete(symname);
1716 }
1717
1718 if (!CurrentClass || !cparse_cplusplus) {
1719 Setattr(n, "name", tmpValue); /* for wrapping of enums in a namespace when emit_action is used */
1720 constantWrapper(n);
1721 } else {
1722 memberconstantHandler(n);
1723 }
1724
1725 Delete(tmpValue);
1726 Swig_restore(n);
1727 return SWIG_OK;
1728 }
1729
1730 /* ----------------------------------------------------------------------
1731 * Language::enumforwardDeclaration()
1732 * ---------------------------------------------------------------------- */
1733
enumforwardDeclaration(Node * n)1734 int Language::enumforwardDeclaration(Node *n) {
1735 (void) n;
1736 if (GetFlag(n, "enumMissing"))
1737 enumDeclaration(n); // Generate an empty enum in target language
1738 return SWIG_OK;
1739 }
1740
1741 /* -----------------------------------------------------------------------------
1742 * Language::memberconstantHandler()
1743 * ----------------------------------------------------------------------------- */
1744
memberconstantHandler(Node * n)1745 int Language::memberconstantHandler(Node *n) {
1746
1747 Swig_require("memberconstantHandler", n, "*name", "*sym:name", "value", NIL);
1748
1749 if (!GetFlag(n, "feature:allowexcept")) {
1750 UnsetFlag(n, "feature:except");
1751 }
1752 if (Getattr(n, "feature:exceptvar")) {
1753 Setattr(n, "feature:except", Getattr(n, "feature:exceptvar"));
1754 }
1755
1756 String *enumvalue_symname = Getattr(n, "enumvalueDeclaration:sym:name"); // Only set if a strongly typed enum
1757 String *name = Getattr(n, "name");
1758 String *symname = Getattr(n, "sym:name");
1759 String *value = Getattr(n, "value");
1760
1761 String *mrename = Swig_name_member(0, EnumClassPrefix, enumvalue_symname ? enumvalue_symname : symname);
1762 Setattr(n, "sym:name", mrename);
1763
1764 String *new_name = 0;
1765 if (Extend)
1766 new_name = Copy(value);
1767 else if (EnumClassName)
1768 new_name = NewStringf("%s::%s", isNonVirtualProtectedAccess(n) ? DirectorClassName : EnumClassName, name);
1769 else
1770 new_name = NewStringf("%s::%s", isNonVirtualProtectedAccess(n) ? DirectorClassName : ClassName, name);
1771 Setattr(n, "name", new_name);
1772
1773 constantWrapper(n);
1774 Delete(mrename);
1775 Delete(new_name);
1776 Swig_restore(n);
1777 return SWIG_OK;
1778 }
1779
1780 /* ----------------------------------------------------------------------
1781 * Language::typedefHandler()
1782 * ---------------------------------------------------------------------- */
1783
typedefHandler(Node * n)1784 int Language::typedefHandler(Node *n) {
1785 /* since this is a recurring issue, we are going to remember the
1786 typedef pointer, if already it is not a pointer or reference, as
1787 in
1788
1789 typedef void NT;
1790 int func(NT *p);
1791
1792 see director_basic.i for example.
1793 */
1794 SwigType *name = Getattr(n, "name");
1795 SwigType *decl = Getattr(n, "decl");
1796 if (!SwigType_ispointer(decl) && !SwigType_isreference(decl)) {
1797 SwigType *pname = Copy(name);
1798 SwigType_add_pointer(pname);
1799 SwigType_remember(pname);
1800 Delete(pname);
1801 }
1802 return SWIG_OK;
1803 }
1804
1805 /* ----------------------------------------------------------------------
1806 * Language::classDirectorMethod()
1807 * ---------------------------------------------------------------------- */
1808
classDirectorMethod(Node * n,Node * parent,String * super)1809 int Language::classDirectorMethod(Node *n, Node *parent, String *super) {
1810 (void) n;
1811 (void) parent;
1812 (void) super;
1813 return SWIG_OK;
1814 }
1815
1816 /* ----------------------------------------------------------------------
1817 * Language::classDirectorConstructor()
1818 * ---------------------------------------------------------------------- */
1819
classDirectorConstructor(Node * n)1820 int Language::classDirectorConstructor(Node *n) {
1821 (void) n;
1822 return SWIG_OK;
1823 }
1824
1825 /* ----------------------------------------------------------------------
1826 * Language::classDirectorDefaultConstructor()
1827 * ---------------------------------------------------------------------- */
1828
classDirectorDefaultConstructor(Node * n)1829 int Language::classDirectorDefaultConstructor(Node *n) {
1830 (void) n;
1831 return SWIG_OK;
1832 }
1833
vtable_method_id(Node * n)1834 static String *vtable_method_id(Node *n) {
1835 String *nodeType = Getattr(n, "nodeType");
1836 int is_destructor = (Cmp(nodeType, "destructor") == 0);
1837 if (is_destructor)
1838 return 0;
1839 String *name = Getattr(n, "name");
1840 String *decl = Getattr(n, "decl");
1841 String *local_decl = SwigType_typedef_resolve_all(decl);
1842 String *tmp = SwigType_pop_function(local_decl);
1843 Delete(local_decl);
1844 local_decl = tmp;
1845 Node *method_id = NewStringf("%s|%s", name, local_decl);
1846 Delete(local_decl);
1847 return method_id;
1848 }
1849
1850
1851 /* ----------------------------------------------------------------------
1852 * Language::unrollVirtualMethods()
1853 * ---------------------------------------------------------------------- */
unrollVirtualMethods(Node * n,Node * parent,List * vm,int default_director,int & virtual_destructor,int protectedbase)1854 int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int default_director, int &virtual_destructor, int protectedbase) {
1855 Node *ni;
1856 String *nodeType;
1857 String *classname;
1858 String *decl;
1859 bool first_base = false;
1860 // recurse through all base classes to build the vtable
1861 List *bl = Getattr(n, "bases");
1862 if (bl) {
1863 Iterator bi;
1864 for (bi = First(bl); bi.item; bi = Next(bi)) {
1865 if (first_base && !director_multiple_inheritance)
1866 break;
1867 unrollVirtualMethods(bi.item, parent, vm, default_director, virtual_destructor);
1868 first_base = true;
1869 }
1870 }
1871 // recurse through all protected base classes to build the vtable, as needed
1872 bl = Getattr(n, "protectedbases");
1873 if (bl) {
1874 Iterator bi;
1875 for (bi = First(bl); bi.item; bi = Next(bi)) {
1876 if (first_base && !director_multiple_inheritance)
1877 break;
1878 unrollVirtualMethods(bi.item, parent, vm, default_director, virtual_destructor, 1);
1879 first_base = true;
1880 }
1881 }
1882 // find the methods that need directors
1883 classname = Getattr(n, "name");
1884 for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
1885 /* we only need to check the virtual members */
1886 nodeType = Getattr(ni, "nodeType");
1887 int is_using = (Cmp(nodeType, "using") == 0);
1888 Node *nn = is_using ? firstChild(ni) : ni; /* assume there is only one child node for "using" nodes */
1889 if (is_using) {
1890 if (nn)
1891 nodeType = Getattr(nn, "nodeType");
1892 else
1893 continue; // A private "using" node
1894 }
1895 if (!checkAttribute(nn, "storage", "virtual"))
1896 continue;
1897 if (GetFlag(nn, "final"))
1898 continue;
1899 /* we need to add methods(cdecl) and destructor (to check for throw decl) */
1900 int is_destructor = (Cmp(nodeType, "destructor") == 0);
1901 if ((Cmp(nodeType, "cdecl") == 0) || is_destructor) {
1902 decl = Getattr(nn, "decl");
1903 /* extra check for function type and proper access */
1904 if (SwigType_isfunction(decl) && (((!protectedbase || dirprot_mode()) && is_public(nn)) || need_nonpublic_member(nn))) {
1905 String *name = Getattr(nn, "name");
1906 Node *method_id = is_destructor ? NewStringf("~destructor") : vtable_method_id(nn);
1907 /* Make sure that the new method overwrites the existing: */
1908 int len = Len(vm);
1909 const int DO_NOT_REPLACE = -1;
1910 int replace = DO_NOT_REPLACE;
1911 for (int i = 0; i < len; i++) {
1912 Node *item = Getitem(vm, i);
1913 String *check_vmid = Getattr(item, "vmid");
1914
1915 if (Strcmp(method_id, check_vmid) == 0) {
1916 replace = i;
1917 break;
1918 }
1919 }
1920 /* filling a new method item */
1921 String *fqdname = NewStringf("%s::%s", classname, name);
1922 Hash *item = NewHash();
1923 Setattr(item, "fqdname", fqdname);
1924 Node *m = Copy(nn);
1925
1926 /* Store the complete return type - needed for non-simple return types (pointers, references etc.) */
1927 SwigType *ty = NewString(Getattr(m, "type"));
1928 SwigType_push(ty, decl);
1929 if (SwigType_isqualifier(ty)) {
1930 Delete(SwigType_pop(ty));
1931 }
1932 Delete(SwigType_pop_function(ty));
1933 Setattr(m, "returntype", ty);
1934
1935 String *mname = NewStringf("%s::%s", Getattr(parent, "name"), name);
1936 /* apply the features of the original method found in the base class */
1937 Swig_features_get(Swig_cparse_features(), 0, mname, Getattr(m, "decl"), m);
1938 Setattr(item, "methodNode", m);
1939 Setattr(item, "vmid", method_id);
1940 if (replace == DO_NOT_REPLACE)
1941 Append(vm, item);
1942 else
1943 Setitem(vm, replace, item);
1944 Setattr(nn, "directorNode", m);
1945
1946 Delete(mname);
1947 }
1948 if (is_destructor) {
1949 virtual_destructor = 1;
1950 }
1951 }
1952 }
1953
1954 /*
1955 We delete all the nodirector methods. This prevents the
1956 generation of 'empty' director classes.
1957
1958 But this has to be done outside the previous 'for'
1959 and the recursive loop!.
1960 */
1961 if (n == parent) {
1962 int len = Len(vm);
1963 for (int i = 0; i < len; i++) {
1964 Node *item = Getitem(vm, i);
1965 Node *m = Getattr(item, "methodNode");
1966 /* retrieve the director features */
1967 int mdir = GetFlag(m, "feature:director");
1968 int mndir = GetFlag(m, "feature:nodirector");
1969 /* 'nodirector' has precedence over 'director' */
1970 int dir = (mdir || mndir) ? (mdir && !mndir) : 1;
1971 /* check if the method was found only in a base class */
1972 Node *p = Getattr(m, "parentNode");
1973 if (p != n) {
1974 Node *c = Copy(m);
1975 Setattr(c, "parentNode", n);
1976 int cdir = GetFlag(c, "feature:director");
1977 int cndir = GetFlag(c, "feature:nodirector");
1978 dir = (cdir || cndir) ? (cdir && !cndir) : dir;
1979 Delete(c);
1980 }
1981 if (dir) {
1982 /* be sure the 'nodirector' feature is disabled */
1983 if (mndir)
1984 Delattr(m, "feature:nodirector");
1985 } else {
1986 /* or just delete from the vm, since is not a director method */
1987 Delitem(vm, i);
1988 len--;
1989 i--;
1990 }
1991 }
1992 }
1993
1994 return SWIG_OK;
1995 }
1996
1997
1998 /* ----------------------------------------------------------------------
1999 * Language::classDirectorDisown()
2000 * ---------------------------------------------------------------------- */
2001
classDirectorDisown(Node * n)2002 int Language::classDirectorDisown(Node *n) {
2003 Node *disown = NewHash();
2004 String *mrename;
2005 String *symname = Getattr(n, "sym:name");
2006 mrename = Swig_name_disown(NSpace, symname);
2007 String *type = NewString(ClassType);
2008 String *name = NewString("self");
2009 SwigType_add_pointer(type);
2010 Parm *p = NewParm(type, name, n);
2011 Delete(name);
2012 Delete(type);
2013 type = NewString("void");
2014 String *action = NewString("");
2015 Printv(action, "{\n", "Swig::Director *director = SWIG_DIRECTOR_CAST(arg1);\n", "if (director) director->swig_disown();\n", "}\n", NULL);
2016 Setfile(disown, Getfile(n));
2017 Setline(disown, Getline(n));
2018 Setattr(disown, "wrap:action", action);
2019 Setattr(disown, "name", mrename);
2020 Setattr(disown, "sym:name", mrename);
2021 Setattr(disown, "type", type);
2022 Setattr(disown, "parms", p);
2023 Delete(action);
2024 Delete(mrename);
2025 Delete(type);
2026 Delete(p);
2027
2028 functionWrapper(disown);
2029 Delete(disown);
2030 return SWIG_OK;
2031 }
2032
2033 /* ----------------------------------------------------------------------
2034 * Language::classDirectorConstructors()
2035 * ---------------------------------------------------------------------- */
2036
classDirectorConstructors(Node * n)2037 int Language::classDirectorConstructors(Node *n) {
2038 Node *ni;
2039 String *nodeType;
2040 Node *parent = Swig_methodclass(n);
2041 int default_ctor = Getattr(parent, "allocate:default_constructor") ? 1 : 0;
2042 int protected_ctor = 0;
2043 int constructor = 0;
2044
2045 /* emit constructors */
2046 for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
2047 nodeType = Getattr(ni, "nodeType");
2048 if (Cmp(nodeType, "constructor") == 0) {
2049 if (GetFlag(ni, "feature:ignore"))
2050 continue;
2051
2052 Parm *parms = Getattr(ni, "parms");
2053 if (is_public(ni)) {
2054 /* emit public constructor */
2055 classDirectorConstructor(ni);
2056 constructor = 1;
2057 if (default_ctor)
2058 default_ctor = !ParmList_numrequired(parms);
2059 } else {
2060 /* emit protected constructor if needed */
2061 if (need_nonpublic_ctor(ni)) {
2062 classDirectorConstructor(ni);
2063 constructor = 1;
2064 protected_ctor = 1;
2065 if (default_ctor)
2066 default_ctor = !ParmList_numrequired(parms);
2067 }
2068 }
2069 }
2070 }
2071 /* emit default constructor if needed */
2072 if (!constructor) {
2073 if (!default_ctor) {
2074 /* we get here because the class has no public, protected or
2075 default constructor, therefore, the director class can't be
2076 created, ie, is kind of abstract. */
2077 Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n), "Director class '%s' can't be constructed\n", SwigType_namestr(Getattr(n, "name")));
2078 return SWIG_OK;
2079 }
2080 classDirectorDefaultConstructor(n);
2081 default_ctor = 1;
2082 }
2083 /* this is just to support old java behavior, ie, the default
2084 constructor is always emitted, even when protected, and not
2085 needed, since there is a public constructor already defined.
2086
2087 (scottm) This code is needed here to make the director_abstract +
2088 test generate compilable code (Example2 in director_abstract.i).
2089
2090 (mmatus) This is very strange, since swig compiled with gcc3.2.3
2091 doesn't need it here....
2092 */
2093 if (!default_ctor && !protected_ctor) {
2094 if (Getattr(parent, "allocate:default_base_constructor")) {
2095 classDirectorDefaultConstructor(n);
2096 }
2097 }
2098
2099 return SWIG_OK;
2100 }
2101
2102 /* ----------------------------------------------------------------------
2103 * Language::classDirectorMethods()
2104 * ---------------------------------------------------------------------- */
2105
classDirectorMethods(Node * n)2106 int Language::classDirectorMethods(Node *n) {
2107 Node *vtable = Getattr(n, "vtable");
2108
2109 int len = Len(vtable);
2110 for (int i = 0; i < len; i++) {
2111 Node *item = Getitem(vtable, i);
2112 String *method = Getattr(item, "methodNode");
2113 String *fqdname = Getattr(item, "fqdname");
2114 if (GetFlag(method, "feature:nodirector") || GetFlag(method, "final"))
2115 continue;
2116
2117 String *wrn = Getattr(method, "feature:warnfilter");
2118 if (wrn)
2119 Swig_warnfilter(wrn, 1);
2120
2121 String *type = Getattr(method, "nodeType");
2122 if (!Cmp(type, "destructor")) {
2123 classDirectorDestructor(method);
2124 } else {
2125 Swig_require("classDirectorMethods", method, "*type", NIL);
2126 assert(Getattr(method, "returntype"));
2127 Setattr(method, "type", Getattr(method, "returntype"));
2128 if (classDirectorMethod(method, n, fqdname) == SWIG_OK)
2129 SetFlag(item, "director");
2130 Swig_restore(method);
2131 }
2132 if (wrn)
2133 Swig_warnfilter(wrn, 0);
2134 }
2135
2136 return SWIG_OK;
2137 }
2138
2139 /* ----------------------------------------------------------------------
2140 * Language::classDirectorInit()
2141 * ---------------------------------------------------------------------- */
2142
classDirectorInit(Node * n)2143 int Language::classDirectorInit(Node *n) {
2144 (void) n;
2145 return SWIG_OK;
2146 }
2147
2148 /* ----------------------------------------------------------------------
2149 * Language::classDirectorDestructor()
2150 * ---------------------------------------------------------------------- */
2151
classDirectorDestructor(Node * n)2152 int Language::classDirectorDestructor(Node *n) {
2153 /*
2154 Always emit the virtual destructor in the declaration and in the
2155 compilation unit. Been explicit here can't make any damage, and
2156 can solve some nasty C++ compiler problems.
2157 */
2158 File *f_directors = Swig_filebyname("director");
2159 File *f_directors_h = Swig_filebyname("director_h");
2160 if (Getattr(n, "throw")) {
2161 Printf(f_directors_h, " virtual ~%s() throw();\n", DirectorClassName);
2162 Printf(f_directors, "%s::~%s() throw() {\n}\n\n", DirectorClassName, DirectorClassName);
2163 } else {
2164 Printf(f_directors_h, " virtual ~%s();\n", DirectorClassName);
2165 Printf(f_directors, "%s::~%s() {\n}\n\n", DirectorClassName, DirectorClassName);
2166 }
2167 return SWIG_OK;
2168 }
2169
2170 /* ----------------------------------------------------------------------
2171 * Language::classDirectorEnd()
2172 * ---------------------------------------------------------------------- */
2173
classDirectorEnd(Node * n)2174 int Language::classDirectorEnd(Node *n) {
2175 (void) n;
2176 return SWIG_OK;
2177 }
2178
2179 /* ----------------------------------------------------------------------
2180 * Language::classDirector()
2181 * ---------------------------------------------------------------------- */
2182
classDirector(Node * n)2183 int Language::classDirector(Node *n) {
2184 Node *module = Getattr(n, "module");
2185 String *classtype = Getattr(n, "classtype");
2186 Hash *directormap = 0;
2187 if (module) {
2188 directormap = Getattr(module, "wrap:directormap");
2189 if (directormap == 0) {
2190 directormap = NewHash();
2191 Setattr(module, "wrap:directormap", directormap);
2192 }
2193 }
2194 List *vtable = NewList();
2195 int virtual_destructor = 0;
2196 unrollVirtualMethods(n, n, vtable, 0, virtual_destructor);
2197
2198 // Emit all the using base::member statements for non virtual members (allprotected mode)
2199 Node *ni;
2200 String *using_protected_members_code = NewString("");
2201 for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
2202 Node *nodeType = Getattr(ni, "nodeType");
2203 if (Cmp(nodeType, "destructor") == 0 && GetFlag(ni, "final")) {
2204 String *classtype = Getattr(n, "classtype");
2205 SWIG_WARN_NODE_BEGIN(ni);
2206 Swig_warning(WARN_LANG_DIRECTOR_FINAL, input_file, line_number, "Destructor %s is final, %s cannot be a director class.\n", Swig_name_decl(ni), classtype);
2207 SWIG_WARN_NODE_END(ni);
2208 SetFlag(n, "feature:nodirector");
2209 Delete(vtable);
2210 Delete(using_protected_members_code);
2211 return SWIG_OK;
2212 }
2213 bool cdeclaration = (Cmp(nodeType, "cdecl") == 0);
2214 if (cdeclaration && !GetFlag(ni, "feature:ignore")) {
2215 if (isNonVirtualProtectedAccess(ni)) {
2216 Node *overloaded = Getattr(ni, "sym:overloaded");
2217 // emit the using base::member statement (but only once if the method is overloaded)
2218 if (!overloaded || (overloaded && (overloaded == ni)))
2219 Printf(using_protected_members_code, " using %s::%s;\n", SwigType_namestr(ClassName), Getattr(ni, "name"));
2220 }
2221 }
2222 }
2223
2224 if (virtual_destructor || Len(vtable) > 0) {
2225 if (!virtual_destructor) {
2226 String *classtype = Getattr(n, "classtype");
2227 Swig_warning(WARN_LANG_DIRECTOR_VDESTRUCT, input_file, line_number, "Director base class %s has no virtual destructor.\n", classtype);
2228 }
2229
2230 Setattr(n, "vtable", vtable);
2231 if (directormap != 0) {
2232 Setattr(directormap, classtype, n);
2233 }
2234 classDirectorInit(n);
2235 classDirectorConstructors(n);
2236 classDirectorMethods(n);
2237
2238 File *f_directors_h = Swig_filebyname("director_h");
2239 Printv(f_directors_h, using_protected_members_code, NIL);
2240
2241 classDirectorEnd(n);
2242 }
2243 Delete(vtable);
2244 Delete(using_protected_members_code);
2245 return SWIG_OK;
2246 }
2247
2248 /* ----------------------------------------------------------------------
2249 * Language::classDeclaration()
2250 * ---------------------------------------------------------------------- */
2251
addCopyConstructor(Node * n)2252 static void addCopyConstructor(Node *n) {
2253 Node *cn = NewHash();
2254 set_nodeType(cn, "constructor");
2255 Setattr(cn, "access", "public");
2256 Setfile(cn, Getfile(n));
2257 Setline(cn, Getline(n));
2258
2259 String *cname = Getattr(n, "name");
2260 SwigType *type = Copy(cname);
2261 String *name = Swig_scopename_last(cname);
2262 String *cc = NewStringf("r.q(const).%s", type);
2263 String *decl = NewStringf("f(%s).", cc);
2264 String *oldname = Getattr(n, "sym:name");
2265
2266 if (Getattr(n, "allocate:has_constructor")) {
2267 // to work properly with '%rename Class', we must look
2268 // for any other constructor in the class, which has not been
2269 // renamed, and use its name as oldname.
2270 Node *c;
2271 for (c = firstChild(n); c; c = nextSibling(c)) {
2272 const char *tag = Char(nodeType(c));
2273 if (strcmp(tag, "constructor") == 0) {
2274 String *cname = Getattr(c, "name");
2275 String *csname = Getattr(c, "sym:name");
2276 String *clast = Swig_scopename_last(cname);
2277 if (Equal(csname, clast)) {
2278 oldname = csname;
2279 break;
2280 }
2281 }
2282 }
2283 }
2284
2285 String *symname = Swig_name_make(cn, cname, name, decl, oldname);
2286 if (Strcmp(symname, "$ignore") != 0) {
2287 Parm *p = NewParm(cc, "other", n);
2288
2289 Setattr(cn, "name", name);
2290 Setattr(cn, "sym:name", symname);
2291 SetFlag(cn, "feature:new");
2292 Setattr(cn, "decl", decl);
2293 Setattr(cn, "parentNode", n);
2294 Setattr(cn, "parms", p);
2295 Setattr(cn, "copy_constructor", "1");
2296
2297 Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
2298 Node *on = Swig_symbol_add(symname, cn);
2299 Swig_features_get(Swig_cparse_features(), Swig_symbol_qualifiedscopename(0), name, decl, cn);
2300 Swig_symbol_setscope(oldscope);
2301
2302 if (on == cn) {
2303 Node *access = NewHash();
2304 set_nodeType(access, "access");
2305 Setattr(access, "kind", "public");
2306 appendChild(n, access);
2307 appendChild(n, cn);
2308 Setattr(n, "has_copy_constructor", "1");
2309 Setattr(n, "copy_constructor_decl", decl);
2310 Setattr(n, "allocate:copy_constructor", "1");
2311 Delete(access);
2312 }
2313 }
2314 Delete(cn);
2315 Delete(name);
2316 Delete(decl);
2317 Delete(symname);
2318 }
2319
addDefaultConstructor(Node * n)2320 static void addDefaultConstructor(Node *n) {
2321 Node *cn = NewHash();
2322 set_nodeType(cn, "constructor");
2323 Setattr(cn, "access", "public");
2324 Setfile(cn, Getfile(n));
2325 Setline(cn, Getline(n));
2326
2327 String *cname = Getattr(n, "name");
2328 String *name = Swig_scopename_last(cname);
2329 String *decl = NewString("f().");
2330 String *oldname = Getattr(n, "sym:name");
2331 String *symname = Swig_name_make(cn, cname, name, decl, oldname);
2332 if (Strcmp(symname, "$ignore") != 0) {
2333 Setattr(cn, "name", name);
2334 Setattr(cn, "sym:name", symname);
2335 SetFlag(cn, "feature:new");
2336 Setattr(cn, "decl", decl);
2337 Setattr(cn, "parentNode", n);
2338 Setattr(cn, "default_constructor", "1");
2339 Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
2340 Node *on = Swig_symbol_add(symname, cn);
2341 Swig_features_get(Swig_cparse_features(), Swig_symbol_qualifiedscopename(0), name, decl, cn);
2342 Swig_symbol_setscope(oldscope);
2343
2344 if (on == cn) {
2345 Node *access = NewHash();
2346 set_nodeType(access, "access");
2347 Setattr(access, "kind", "public");
2348 appendChild(n, access);
2349 appendChild(n, cn);
2350 Setattr(n, "has_default_constructor", "1");
2351 Setattr(n, "allocate:default_constructor", "1");
2352 Delete(access);
2353 }
2354 }
2355 Delete(cn);
2356 Delete(name);
2357 Delete(decl);
2358 Delete(symname);
2359 }
2360
addDestructor(Node * n)2361 static void addDestructor(Node *n) {
2362 Node *cn = NewHash();
2363 set_nodeType(cn, "destructor");
2364 Setattr(cn, "access", "public");
2365 Setfile(cn, Getfile(n));
2366 Setline(cn, Getline(n));
2367
2368 String *cname = Getattr(n, "name");
2369 String *name = Swig_scopename_last(cname);
2370 Insert(name, 0, "~");
2371 String *decl = NewString("f().");
2372 String *symname = Swig_name_make(cn, cname, name, decl, 0);
2373 if (Strcmp(symname, "$ignore") != 0) {
2374 String *possible_nonstandard_symname = NewStringf("~%s", Getattr(n, "sym:name"));
2375
2376 Setattr(cn, "name", name);
2377 Setattr(cn, "sym:name", symname);
2378 Setattr(cn, "decl", "f().");
2379 Setattr(cn, "parentNode", n);
2380
2381 Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
2382 Node *nonstandard_destructor = Equal(possible_nonstandard_symname, symname) ? 0 : Swig_symbol_clookup(possible_nonstandard_symname, 0);
2383 Node *on = Swig_symbol_add(symname, cn);
2384 Swig_features_get(Swig_cparse_features(), Swig_symbol_qualifiedscopename(0), name, decl, cn);
2385 Swig_symbol_setscope(oldscope);
2386
2387 if (on == cn) {
2388 // SWIG accepts a non-standard named destructor in %extend that uses a typedef for the destructor name
2389 // For example: typedef struct X {} XX; %extend X { ~XX() {...} }
2390 // Don't add another destructor if a nonstandard one has been declared
2391 if (!nonstandard_destructor) {
2392 Node *access = NewHash();
2393 set_nodeType(access, "access");
2394 Setattr(access, "kind", "public");
2395 appendChild(n, access);
2396 appendChild(n, cn);
2397 Setattr(n, "has_destructor", "1");
2398 Setattr(n, "allocate:destructor", "1");
2399 Delete(access);
2400 }
2401 }
2402 Delete(possible_nonstandard_symname);
2403 }
2404 Delete(cn);
2405 Delete(name);
2406 Delete(decl);
2407 Delete(symname);
2408 }
2409
classDeclaration(Node * n)2410 int Language::classDeclaration(Node *n) {
2411 String *ochildren = Getattr(n, "feature:onlychildren");
2412 if (ochildren) {
2413 Setattr(n, "feature:emitonlychildren", ochildren);
2414 emit_children(n);
2415 Delattr(n, "feature:emitonlychildren");
2416 SetFlag(n, "feature:ignore");
2417 return SWIG_NOWRAP;
2418 }
2419
2420 // save class local variables for nested classes support
2421 int oldInClass = InClass;
2422 String *oldClassType = ClassType;
2423 String *oldClassPrefix = ClassPrefix;
2424 String *oldEnumClassPrefix = EnumClassPrefix;
2425 String *oldClassName = ClassName;
2426 String *oldDirectorClassName = DirectorClassName;
2427 String *oldNSpace = NSpace;
2428 Node *oldCurrentClass = CurrentClass;
2429 int dir = 0;
2430
2431 String *kind = Getattr(n, "kind");
2432 String *name = Getattr(n, "name");
2433 String *tdname = Getattr(n, "tdname");
2434 String *unnamed = Getattr(n, "unnamed");
2435 String *symname = Getattr(n, "sym:name");
2436
2437 int strip = CPlusPlus ? 1 : unnamed && tdname;
2438
2439 if (cplus_mode != PUBLIC)
2440 return SWIG_NOWRAP;
2441 if (!name) {
2442 Swig_warning(WARN_LANG_CLASS_UNNAMED, input_file, line_number, "Can't generate wrappers for unnamed struct/class.\n");
2443 return SWIG_NOWRAP;
2444 }
2445
2446 /* Check symbol name for template. If not renamed. Issue a warning */
2447 if (!validIdentifier(symname)) {
2448 Swig_warning(WARN_LANG_IDENTIFIER, input_file, line_number, "Can't wrap class %s unless renamed to a valid identifier.\n", SwigType_namestr(symname));
2449 return SWIG_NOWRAP;
2450 }
2451 AccessMode oldAccessMode = cplus_mode;
2452 Node *outerClass = Getattr(n, "nested:outer");
2453 if (outerClass && oldAccessMode != PUBLIC)
2454 return SWIG_NOWRAP;
2455 ClassName = Copy(name);
2456 ClassPrefix = Copy(symname);
2457 if (Cmp(kind, "class") == 0) {
2458 cplus_mode = PRIVATE;
2459 } else {
2460 cplus_mode = PUBLIC;
2461 }
2462 for (; outerClass; outerClass = Getattr(outerClass, "nested:outer")) {
2463 Push(ClassPrefix, "_");
2464 Push(ClassPrefix, Getattr(outerClass, "sym:name"));
2465 }
2466 EnumClassPrefix = Copy(ClassPrefix);
2467 if (strip) {
2468 ClassType = Copy(name);
2469 } else {
2470 ClassType = NewStringf("%s %s", kind, name);
2471 }
2472 Setattr(n, "classtypeobj", Copy(ClassType));
2473 Setattr(n, "classtype", SwigType_namestr(ClassType));
2474
2475 InClass = 1;
2476 CurrentClass = n;
2477 NSpace = Getattr(n, "sym:nspace");
2478 int oldAbstract = Abstract;
2479
2480 /* Call classHandler() here */
2481 if (!ImportMode) {
2482 if (directorsEnabled()) {
2483 int ndir = GetFlag(n, "feature:director");
2484 int nndir = GetFlag(n, "feature:nodirector");
2485 /* 'nodirector' has precedence over 'director' */
2486 dir = (ndir || nndir) ? (ndir && !nndir) : 0;
2487 }
2488 int abstract = !dir && abstractClassTest(n);
2489 int odefault = (GenerateDefault && !GetFlag(n, "feature:nodefault"));
2490
2491 /* default constructor */
2492 if (!abstract && !GetFlag(n, "feature:nodefaultctor") && odefault) {
2493 if (!Getattr(n, "has_constructor") && !Getattr(n, "allocate:has_constructor") && (Getattr(n, "allocate:default_constructor"))) {
2494 addDefaultConstructor(n);
2495 }
2496 }
2497 /* copy constructor */
2498 if (CPlusPlus && !abstract && GetFlag(n, "feature:copyctor")) {
2499 if (!Getattr(n, "has_copy_constructor") && !Getattr(n, "allocate:has_copy_constructor")
2500 && (Getattr(n, "allocate:copy_constructor"))
2501 && (!GetFlag(n, "feature:ignore"))) {
2502 addCopyConstructor(n);
2503 }
2504 }
2505 /* default destructor */
2506 if (!GetFlag(n, "feature:nodefaultdtor") && odefault) {
2507 if (!Getattr(n, "has_destructor") && (!Getattr(n, "allocate:has_destructor"))
2508 && (Getattr(n, "allocate:default_destructor"))
2509 && (!GetFlag(n, "feature:ignore"))) {
2510 addDestructor(n);
2511 }
2512 }
2513
2514 if (dir) {
2515 DirectorClassName = directorClassName(n);
2516 classDirector(n);
2517 }
2518 /* check for abstract after resolving directors */
2519
2520 Abstract = abstractClassTest(n);
2521 classHandler(n);
2522 } else {
2523 Abstract = abstractClassTest(n);
2524 Language::classHandler(n);
2525 }
2526
2527 Abstract = oldAbstract;
2528 cplus_mode = oldAccessMode;
2529 NSpace = oldNSpace;
2530 InClass = oldInClass;
2531 CurrentClass = oldCurrentClass;
2532 Delete(ClassType);
2533 ClassType = oldClassType;
2534 Delete(EnumClassPrefix);
2535 EnumClassPrefix = oldEnumClassPrefix;
2536 Delete(ClassPrefix);
2537 ClassPrefix = oldClassPrefix;
2538 Delete(ClassName);
2539 ClassName = oldClassName;
2540 if (dir) {
2541 Delete(DirectorClassName);
2542 }
2543 DirectorClassName = oldDirectorClassName;
2544 return SWIG_OK;
2545 }
2546
2547 /* ----------------------------------------------------------------------
2548 * Language::classHandler()
2549 * ---------------------------------------------------------------------- */
2550
classHandler(Node * n)2551 int Language::classHandler(Node *n) {
2552 save_value<int> oldExtend(Extend);
2553 if (Getattr(n, "template"))
2554 Extend = 0;
2555 bool hasDirector = Swig_directorclass(n) ? true : false;
2556
2557 /* Emit all of the class members */
2558 emit_children(n);
2559
2560 /* Look for smart pointer handling */
2561 if (Getattr(n, "allocate:smartpointer")) {
2562 List *methods = Getattr(n, "allocate:smartpointer");
2563 cplus_mode = PUBLIC;
2564 SmartPointer = CWRAP_SMART_POINTER;
2565 if (Getattr(n, "allocate:smartpointerconst") && Getattr(n, "allocate:smartpointermutable")) {
2566 SmartPointer |= CWRAP_SMART_POINTER_OVERLOAD;
2567 }
2568 Iterator c;
2569 for (c = First(methods); c.item; c = Next(c)) {
2570 emit_one(c.item);
2571 }
2572 SmartPointer = 0;
2573 }
2574
2575 cplus_mode = PUBLIC;
2576
2577 /* emit director disown method */
2578 if (hasDirector) {
2579 classDirectorDisown(n);
2580
2581 /* Emit additional protected virtual methods - only needed if the language module
2582 * codes logic in the C++ layer instead of the director proxy class method - primarily
2583 * to catch public use of protected methods by the scripting languages. */
2584 if (dirprot_mode() && extraDirectorProtectedCPPMethodsRequired()) {
2585 Node *vtable = Getattr(n, "vtable");
2586 String *symname = Getattr(n, "sym:name");
2587 save_value<AccessMode> old_mode(cplus_mode);
2588 cplus_mode = PROTECTED;
2589 int len = Len(vtable);
2590 for (int i = 0; i < len; i++) {
2591 Node *item = Getitem(vtable, i);
2592 Node *method = Getattr(item, "methodNode");
2593 SwigType *type = Getattr(method, "nodeType");
2594 if (Strcmp(type, "cdecl") != 0)
2595 continue;
2596 if (GetFlag(method, "feature:ignore"))
2597 continue;
2598 String *methodname = Getattr(method, "sym:name");
2599 String *wrapname = NewStringf("%s_%s", symname, methodname);
2600 if (!symbolLookup(wrapname, "") && (!is_public(method))) {
2601 Node *m = Copy(method);
2602 Setattr(m, "director", "1");
2603 Setattr(m, "parentNode", n);
2604 /*
2605 * There is a bug that needs fixing still...
2606 * This area of code is creating methods which have not been overridden in a derived class (director methods that are protected in the base)
2607 * If the method is overloaded, then Swig_overload_dispatch() incorrectly generates a call to the base wrapper, _wrap_xxx method
2608 * See director_protected_overloaded.i - Possibly sym:overname needs correcting here.
2609 Printf(stdout, "new method: %s::%s(%s)\n", Getattr(parentNode(m), "name"), Getattr(m, "name"), ParmList_str_defaultargs(Getattr(m, "parms")));
2610 */
2611 cDeclaration(m);
2612 Delete(m);
2613 }
2614 Delete(wrapname);
2615 }
2616 }
2617 }
2618
2619 return SWIG_OK;
2620 }
2621
2622 /* ----------------------------------------------------------------------
2623 * Language::classforwardDeclaration()
2624 * ---------------------------------------------------------------------- */
2625
classforwardDeclaration(Node * n)2626 int Language::classforwardDeclaration(Node *n) {
2627 (void) n;
2628 return SWIG_OK;
2629 }
2630
2631 /* ----------------------------------------------------------------------
2632 * Language::constructorDeclaration()
2633 * ---------------------------------------------------------------------- */
2634
constructorDeclaration(Node * n)2635 int Language::constructorDeclaration(Node *n) {
2636 String *name = Getattr(n, "name");
2637 String *symname = Getattr(n, "sym:name");
2638
2639 if (!symname)
2640 return SWIG_NOWRAP;
2641 if (!CurrentClass)
2642 return SWIG_NOWRAP;
2643 if (ImportMode)
2644 return SWIG_NOWRAP;
2645
2646 if (Extend) {
2647 /* extend default constructor can be safely ignored if there is already one */
2648 int num_required = ParmList_numrequired(Getattr(n, "parms"));
2649 if ((num_required == 0) && Getattr(CurrentClass, "has_default_constructor")) {
2650 return SWIG_NOWRAP;
2651 }
2652 if ((num_required == 1) && Getattr(CurrentClass, "has_copy_constructor")) {
2653 String *ccdecl = Getattr(CurrentClass, "copy_constructor_decl");
2654 if (ccdecl && (Strcmp(ccdecl, Getattr(n, "decl")) == 0)) {
2655 return SWIG_NOWRAP;
2656 }
2657 }
2658 }
2659
2660 /* clean protected overloaded constructors, in case they are not needed anymore */
2661 Node *over = Swig_symbol_isoverloaded(n);
2662 if (over && !Getattr(CurrentClass, "sym:cleanconstructor")) {
2663 int dirclass = Swig_directorclass(CurrentClass);
2664 Node *nn = over;
2665 while (nn) {
2666 if (!is_public(nn)) {
2667 if (!dirclass || !need_nonpublic_ctor(nn)) {
2668 SetFlag(nn, "feature:ignore");
2669 }
2670 }
2671 nn = Getattr(nn, "sym:nextSibling");
2672 }
2673 clean_overloaded(over);
2674 Setattr(CurrentClass, "sym:cleanconstructor", "1");
2675 }
2676
2677 if ((cplus_mode != PUBLIC)) {
2678 /* check only for director classes */
2679 if (!Swig_directorclass(CurrentClass) || !need_nonpublic_ctor(n))
2680 return SWIG_NOWRAP;
2681 }
2682
2683 /* Name adjustment for %name */
2684 Swig_save("constructorDeclaration", n, "sym:name", NIL);
2685
2686 {
2687 String *base = Swig_scopename_last(name);
2688 if ((Strcmp(base, symname) == 0) && (Strcmp(symname, ClassPrefix) != 0)) {
2689 Setattr(n, "sym:name", ClassPrefix);
2690 }
2691 Delete(base);
2692 }
2693
2694 /* Only create a constructor if the class is not abstract */
2695 if (!Abstract) {
2696 Node *over;
2697 over = Swig_symbol_isoverloaded(n);
2698 if (over)
2699 over = first_nontemplate(over);
2700 if ((over) && (!overloading)) {
2701 /* If the symbol is overloaded. We check to see if it is a copy constructor. If so,
2702 we invoke copyconstructorHandler() as a special case. */
2703 if (Getattr(n, "copy_constructor") && (!Getattr(CurrentClass, "has_copy_constructor"))) {
2704 copyconstructorHandler(n);
2705 Setattr(CurrentClass, "has_copy_constructor", "1");
2706 } else {
2707 if (Getattr(over, "copy_constructor"))
2708 over = Getattr(over, "sym:nextSibling");
2709 if (over != n) {
2710 Swig_warning(WARN_LANG_OVERLOAD_CONSTRUCT, input_file, line_number,
2711 "Overloaded constructor ignored. %s\n", Swig_name_decl(n));
2712 Swig_warning(WARN_LANG_OVERLOAD_CONSTRUCT, Getfile(over), Getline(over),
2713 "Previous declaration is %s\n", Swig_name_decl(over));
2714 } else {
2715 constructorHandler(n);
2716 }
2717 }
2718 } else {
2719 String *expected_name = ClassName;
2720 String *scope = Swig_scopename_check(ClassName) ? Swig_scopename_prefix(ClassName) : 0;
2721 String *actual_name = scope ? NewStringf("%s::%s", scope, name) : NewString(name);
2722 Delete(scope);
2723 if (!Equal(actual_name, expected_name) && !SwigType_istemplate(expected_name) && !SwigType_istemplate(actual_name)) {
2724 // Checking templates is skipped but they ought to be checked... they are just somewhat more tricky to check correctly
2725 bool illegal_name = true;
2726 if (Extend) {
2727 // Check for typedef names used as a constructor name in %extend. This is deprecated except for anonymous
2728 // typedef structs which have had their symbol names adjusted to the typedef name in the parser.
2729 SwigType *name_resolved = SwigType_typedef_resolve_all(actual_name);
2730 SwigType *expected_name_resolved = SwigType_typedef_resolve_all(expected_name);
2731
2732 if (!CPlusPlus) {
2733 if (Strncmp(name_resolved, "struct ", 7) == 0)
2734 Replace(name_resolved, "struct ", "", DOH_REPLACE_FIRST);
2735 else if (Strncmp(name_resolved, "union ", 6) == 0)
2736 Replace(name_resolved, "union ", "", DOH_REPLACE_FIRST);
2737 }
2738
2739 illegal_name = !Equal(name_resolved, expected_name_resolved);
2740 if (!illegal_name)
2741 Swig_warning(WARN_LANG_EXTEND_CONSTRUCTOR, input_file, line_number, "Use of an illegal constructor name '%s' in %%extend is deprecated, the constructor name should be '%s'.\n",
2742 SwigType_str(Swig_scopename_last(actual_name), 0), SwigType_str(Swig_scopename_last(expected_name), 0));
2743 Delete(name_resolved);
2744 Delete(expected_name_resolved);
2745 }
2746 if (illegal_name) {
2747 Swig_warning(WARN_LANG_RETURN_TYPE, input_file, line_number, "Function %s must have a return type. Ignored.\n", Swig_name_decl(n));
2748 Swig_restore(n);
2749 return SWIG_NOWRAP;
2750 }
2751 }
2752 constructorHandler(n);
2753 }
2754 }
2755 Setattr(CurrentClass, "has_constructor", "1");
2756
2757 Swig_restore(n);
2758 return SWIG_OK;
2759 }
2760
2761 /* ----------------------------------------------------------------------
2762 * get_director_ctor_code()
2763 * ---------------------------------------------------------------------- */
2764
get_director_ctor_code(Node * n,String * director_ctor_code,String * director_prot_ctor_code,List * & abstracts)2765 static String *get_director_ctor_code(Node *n, String *director_ctor_code, String *director_prot_ctor_code, List *&abstracts) {
2766 String *director_ctor = director_ctor_code;
2767 int use_director = Swig_directorclass(n);
2768 if (use_director) {
2769 Node *pn = Swig_methodclass(n);
2770 abstracts = Getattr(pn, "abstracts");
2771 if (director_prot_ctor_code) {
2772 int is_notabstract = GetFlag(pn, "feature:notabstract");
2773 int is_abstract = abstracts && !is_notabstract;
2774 if (is_protected(n) || is_abstract) {
2775 director_ctor = director_prot_ctor_code;
2776 abstracts = Copy(abstracts);
2777 Delattr(pn, "abstracts");
2778 } else {
2779 if (is_notabstract) {
2780 abstracts = Copy(abstracts);
2781 Delattr(pn, "abstracts");
2782 } else {
2783 abstracts = 0;
2784 }
2785 }
2786 }
2787 }
2788 return director_ctor;
2789 }
2790
2791
2792 /* ----------------------------------------------------------------------
2793 * Language::constructorHandler()
2794 * ---------------------------------------------------------------------- */
2795
constructorHandler(Node * n)2796 int Language::constructorHandler(Node *n) {
2797 Swig_require("constructorHandler", n, "?name", "*sym:name", "?type", "?parms", NIL);
2798 String *symname = Getattr(n, "sym:name");
2799 String *mrename = Swig_name_construct(NSpace, symname);
2800 String *nodeType = Getattr(n, "nodeType");
2801 int constructor = (!Cmp(nodeType, "constructor"));
2802 List *abstracts = 0;
2803 String *director_ctor = get_director_ctor_code(n, director_ctor_code,
2804 director_prot_ctor_code,
2805 abstracts);
2806 if (!constructor) {
2807 /* if not originally a constructor, still handle it as one */
2808 Setattr(n, "handled_as_constructor", "1");
2809 }
2810
2811 int extendmember = GetFlag(n, "isextendmember") ? Extend : 0;
2812 int flags = Getattr(n, "template") ? extendmember : Extend;
2813 Swig_ConstructorToFunction(n, NSpace, ClassType, none_comparison, director_ctor, CPlusPlus, flags, DirectorClassName);
2814 Setattr(n, "sym:name", mrename);
2815 functionWrapper(n);
2816 Delete(mrename);
2817 Swig_restore(n);
2818 if (abstracts)
2819 Setattr(Swig_methodclass(n), "abstracts", abstracts);
2820 return SWIG_OK;
2821 }
2822
2823 /* ----------------------------------------------------------------------
2824 * Language::copyconstructorHandler()
2825 * ---------------------------------------------------------------------- */
2826
copyconstructorHandler(Node * n)2827 int Language::copyconstructorHandler(Node *n) {
2828 Swig_require("copyconstructorHandler", n, "?name", "*sym:name", "?type", "?parms", NIL);
2829 String *symname = Getattr(n, "sym:name");
2830 String *mrename = Swig_name_copyconstructor(NSpace, symname);
2831 List *abstracts = 0;
2832 String *director_ctor = get_director_ctor_code(n, director_ctor_code,
2833 director_prot_ctor_code,
2834 abstracts);
2835 Swig_ConstructorToFunction(n, NSpace, ClassType, none_comparison, director_ctor, CPlusPlus, Getattr(n, "template") ? 0 : Extend, DirectorClassName);
2836 Setattr(n, "sym:name", mrename);
2837 functionWrapper(n);
2838 Delete(mrename);
2839 Swig_restore(n);
2840 if (abstracts)
2841 Setattr(Swig_methodclass(n), "abstracts", abstracts);
2842 return SWIG_OK;
2843 }
2844
2845 /* ----------------------------------------------------------------------
2846 * Language::destructorDeclaration()
2847 * ---------------------------------------------------------------------- */
2848
destructorDeclaration(Node * n)2849 int Language::destructorDeclaration(Node *n) {
2850
2851 if (!CurrentClass)
2852 return SWIG_NOWRAP;
2853 if (cplus_mode != PUBLIC && !Getattr(CurrentClass, "feature:unref"))
2854 return SWIG_NOWRAP;
2855 if (ImportMode)
2856 return SWIG_NOWRAP;
2857
2858 Swig_save("destructorDeclaration", n, "name", "sym:name", NIL);
2859
2860 char *c = GetChar(n, "sym:name");
2861 if (c && (*c == '~')) {
2862 Setattr(n, "sym:name", c + 1);
2863 }
2864
2865 String *name = Getattr(n, "name");
2866 String *symname = Getattr(n, "sym:name");
2867
2868 if ((Strcmp(name, symname) == 0) || (Strcmp(symname, ClassPrefix) != 0)) {
2869 Setattr(n, "sym:name", ClassPrefix);
2870 }
2871
2872 String *expected_name = ClassName;
2873 String *scope = Swig_scopename_check(ClassName) ? Swig_scopename_prefix(ClassName) : 0;
2874 String *actual_name = scope ? NewStringf("%s::%s", scope, name) : NewString(name);
2875 Delete(scope);
2876 Replace(actual_name, "~", "", DOH_REPLACE_FIRST);
2877 if (!Equal(actual_name, expected_name) && !(Getattr(n, "template"))) {
2878 bool illegal_name = true;
2879 if (Extend) {
2880 // Check for typedef names used as a destructor name in %extend. This is deprecated except for anonymous
2881 // typedef structs which have had their symbol names adjusted to the typedef name in the parser.
2882 SwigType *name_resolved = SwigType_typedef_resolve_all(actual_name);
2883 SwigType *expected_name_resolved = SwigType_typedef_resolve_all(expected_name);
2884
2885 if (!CPlusPlus) {
2886 if (Strncmp(name_resolved, "struct ", 7) == 0)
2887 Replace(name_resolved, "struct ", "", DOH_REPLACE_FIRST);
2888 else if (Strncmp(name_resolved, "union ", 6) == 0)
2889 Replace(name_resolved, "union ", "", DOH_REPLACE_FIRST);
2890 }
2891
2892 illegal_name = !Equal(name_resolved, expected_name_resolved);
2893 if (!illegal_name)
2894 Swig_warning(WARN_LANG_EXTEND_DESTRUCTOR, input_file, line_number, "Use of an illegal destructor name '%s' in %%extend is deprecated, the destructor name should be '%s'.\n",
2895 SwigType_str(Swig_scopename_last(actual_name), 0), SwigType_str(Swig_scopename_last(expected_name), 0));
2896 Delete(name_resolved);
2897 Delete(expected_name_resolved);
2898 }
2899
2900 if (illegal_name) {
2901 Swig_warning(WARN_LANG_ILLEGAL_DESTRUCTOR, input_file, line_number, "Illegal destructor name %s. Ignored.\n", Swig_name_decl(n));
2902 Swig_restore(n);
2903 return SWIG_NOWRAP;
2904 }
2905 }
2906 destructorHandler(n);
2907
2908 Setattr(CurrentClass, "has_destructor", "1");
2909 Swig_restore(n);
2910 return SWIG_OK;
2911 }
2912
2913 /* ----------------------------------------------------------------------
2914 * Language::destructorHandler()
2915 * ---------------------------------------------------------------------- */
2916
destructorHandler(Node * n)2917 int Language::destructorHandler(Node *n) {
2918 Swig_require("destructorHandler", n, "?name", "*sym:name", NIL);
2919 Swig_save("destructorHandler", n, "type", "parms", NIL);
2920
2921 String *symname = Getattr(n, "sym:name");
2922 String *mrename;
2923 char *csymname = Char(symname);
2924 if (*csymname == '~')
2925 csymname += 1;
2926
2927 mrename = Swig_name_destroy(NSpace, csymname);
2928
2929 Swig_DestructorToFunction(n, NSpace, ClassType, CPlusPlus, Extend);
2930 Setattr(n, "sym:name", mrename);
2931 functionWrapper(n);
2932 Delete(mrename);
2933 Swig_restore(n);
2934 return SWIG_OK;
2935 }
2936
2937 /* ----------------------------------------------------------------------
2938 * Language::accessDeclaration()
2939 * ---------------------------------------------------------------------- */
2940
accessDeclaration(Node * n)2941 int Language::accessDeclaration(Node *n) {
2942 String *kind = Getattr(n, "kind");
2943 if (Cmp(kind, "public") == 0) {
2944 cplus_mode = PUBLIC;
2945 } else if (Cmp(kind, "private") == 0) {
2946 cplus_mode = PRIVATE;
2947 } else if (Cmp(kind, "protected") == 0) {
2948 cplus_mode = PROTECTED;
2949 }
2950 return SWIG_OK;
2951 }
2952
2953 /* -----------------------------------------------------------------------------
2954 * Language::namespaceDeclaration()
2955 * ----------------------------------------------------------------------------- */
2956
namespaceDeclaration(Node * n)2957 int Language::namespaceDeclaration(Node *n) {
2958 if (Getattr(n, "alias"))
2959 return SWIG_OK;
2960 if (Getattr(n, "unnamed"))
2961 return SWIG_OK;
2962 emit_children(n);
2963 return SWIG_OK;
2964 }
2965
validIdentifier(String * s)2966 int Language::validIdentifier(String *s) {
2967 char *c = Char(s);
2968 while (*c) {
2969 if (!(isalnum(*c) || (*c == '_')))
2970 return 0;
2971 c++;
2972 }
2973 return 1;
2974 }
2975
2976 /* -----------------------------------------------------------------------------
2977 * Language::usingDeclaration()
2978 * ----------------------------------------------------------------------------- */
2979
usingDeclaration(Node * n)2980 int Language::usingDeclaration(Node *n) {
2981 if ((cplus_mode == PUBLIC) || (!is_public(n) && dirprot_mode())) {
2982 Node *np = Copy(n);
2983 Node *c;
2984 for (c = firstChild(np); c; c = nextSibling(c)) {
2985 /* it seems for some cases this is needed, like A* A::boo() */
2986 if (CurrentClass)
2987 Setattr(c, "parentNode", CurrentClass);
2988 emit_one(c);
2989 }
2990 Delete(np);
2991 }
2992 return SWIG_OK;
2993 }
2994
2995 /* Stubs. Language modules need to implement these */
2996
2997 /* ----------------------------------------------------------------------
2998 * Language::constantWrapper()
2999 * ---------------------------------------------------------------------- */
3000
constantWrapper(Node * n)3001 int Language::constantWrapper(Node *n) {
3002 String *name = Getattr(n, "sym:name");
3003 SwigType *type = Getattr(n, "type");
3004 String *value = Getattr(n, "value");
3005 String *str = SwigType_str(type, name);
3006 Printf(stdout, "constantWrapper : %s = %s\n", str, value);
3007 Delete(str);
3008 return SWIG_OK;
3009 }
3010
3011 /* ----------------------------------------------------------------------
3012 * Language::variableWrapper()
3013 * ---------------------------------------------------------------------- */
3014
variableWrapper(Node * n)3015 int Language::variableWrapper(Node *n) {
3016 Swig_require("variableWrapper", n, "*name", "*sym:name", "*type", "?parms", "?varset", "?varget", NIL);
3017 String *symname = Getattr(n, "sym:name");
3018 SwigType *type = Getattr(n, "type");
3019 String *name = Getattr(n, "name");
3020
3021 Delattr(n,"varset");
3022 Delattr(n,"varget");
3023
3024 String *newsymname = 0;
3025 if (!CurrentClass && EnumClassPrefix) {
3026 newsymname = Swig_name_member(0, EnumClassPrefix, symname);
3027 symname = newsymname;
3028 }
3029
3030 /* If no way to set variables. We simply create functions */
3031 int assignable = is_assignable(n);
3032 int flags = use_naturalvar_mode(n);
3033 if (!GetFlag(n, "wrappedasconstant"))
3034 flags = flags | Extend;
3035
3036 if (assignable) {
3037 int make_set_wrapper = 1;
3038 String *tm = Swig_typemap_lookup("globalin", n, name, 0);
3039
3040 Swig_VarsetToFunction(n, flags);
3041 String *sname = Swig_name_set(NSpace, symname);
3042 Setattr(n, "sym:name", sname);
3043 Delete(sname);
3044
3045 if (!tm) {
3046 if (SwigType_isarray(type)) {
3047 Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(type, 0));
3048 make_set_wrapper = 0;
3049 }
3050 } else {
3051 String *pname0 = Swig_cparm_name(0, 0);
3052 Replace(tm, "$source", pname0, DOH_REPLACE_ANY);
3053 Replace(tm, "$target", name, DOH_REPLACE_ANY);
3054 Replace(tm, "$input", pname0, DOH_REPLACE_ANY);
3055 Setattr(n, "wrap:action", tm);
3056 Delete(tm);
3057 Delete(pname0);
3058 }
3059 if (make_set_wrapper) {
3060 Setattr(n, "varset", "1");
3061 functionWrapper(n);
3062 } else {
3063 SetFlag(n, "feature:immutable");
3064 }
3065 /* Restore parameters */
3066 Setattr(n, "sym:name", symname);
3067 Setattr(n, "type", type);
3068 Setattr(n, "name", name);
3069 Delattr(n, "varset");
3070
3071 /* Delete all attached typemaps and typemap attributes */
3072 Iterator ki;
3073 for (ki = First(n); ki.key; ki = Next(ki)) {
3074 if (Strncmp(ki.key, "tmap:", 5) == 0)
3075 Delattr(n, ki.key);
3076 }
3077 }
3078
3079 Swig_VargetToFunction(n, flags);
3080 String *gname = Swig_name_get(NSpace, symname);
3081 Setattr(n, "sym:name", gname);
3082 Delete(gname);
3083 Setattr(n, "varget", "1");
3084 functionWrapper(n);
3085 Delattr(n, "varget");
3086 Swig_restore(n);
3087 Delete(newsymname);
3088 return SWIG_OK;
3089 }
3090
3091 /* ----------------------------------------------------------------------
3092 * Language::functionWrapper()
3093 * ---------------------------------------------------------------------- */
3094
functionWrapper(Node * n)3095 int Language::functionWrapper(Node *n) {
3096 String *name = Getattr(n, "sym:name");
3097 SwigType *type = Getattr(n, "type");
3098 ParmList *parms = Getattr(n, "parms");
3099
3100 Printf(stdout, "functionWrapper : %s\n", SwigType_str(type, NewStringf("%s(%s)", name, ParmList_str_defaultargs(parms))));
3101 Printf(stdout, " action : %s\n", Getattr(n, "wrap:action"));
3102 return SWIG_OK;
3103 }
3104
3105 /* -----------------------------------------------------------------------------
3106 * Language::nativeWrapper()
3107 * ----------------------------------------------------------------------------- */
3108
nativeWrapper(Node * n)3109 int Language::nativeWrapper(Node *n) {
3110 (void) n;
3111 return SWIG_OK;
3112 }
3113
main(int argc,char * argv[])3114 void Language::main(int argc, char *argv[]) {
3115 (void) argc;
3116 (void) argv;
3117 }
3118
3119 /* -----------------------------------------------------------------------------
3120 * Language::addSymbol()
3121 *
3122 * Adds a symbol entry into the target language symbol tables.
3123 * Returns 1 if the symbol is added successfully.
3124 * Prints an error message and returns 0 if a conflict occurs.
3125 * The scope is optional for target languages and if supplied must be a fully
3126 * qualified scope and the symbol s must not contain any scope qualifiers.
3127 * ----------------------------------------------------------------------------- */
3128
addSymbol(const String * s,const Node * n,const_String_or_char_ptr scope)3129 int Language::addSymbol(const String *s, const Node *n, const_String_or_char_ptr scope) {
3130 //Printf( stdout, "addSymbol: %s %s\n", s, scope );
3131 Hash *symbols = Getattr(symtabs, scope ? scope : "");
3132 if (!symbols) {
3133 symbols = symbolAddScope(scope);
3134 } else {
3135 Node *c = Getattr(symbols, s);
3136 if (c && (c != n)) {
3137 if (scope && Len(scope) > 0)
3138 Swig_error(input_file, line_number, "'%s' is multiply defined in the generated target language module in scope '%s'.\n", s, scope);
3139 else
3140 Swig_error(input_file, line_number, "'%s' is multiply defined in the generated target language module.\n", s);
3141 Swig_error(Getfile(c), Getline(c), "Previous declaration of '%s'\n", s);
3142 return 0;
3143 }
3144 }
3145 Setattr(symbols, s, n);
3146 return 1;
3147 }
3148
3149 /* -----------------------------------------------------------------------------
3150 * Language::addInterfaceSymbol()
3151 *
3152 * Adds a symbol entry into the target language symbol tables - for the interface
3153 * feature only.
3154 * Returns 1 if the symbol is added successfully.
3155 * The scope is as per addSymbol.
3156 * ----------------------------------------------------------------------------- */
3157
addInterfaceSymbol(const String * interface_name,Node * n,const_String_or_char_ptr scope)3158 int Language::addInterfaceSymbol(const String *interface_name, Node *n, const_String_or_char_ptr scope) {
3159 if (interface_name) {
3160 Node *existing_symbol = symbolLookup(interface_name, scope);
3161 if (existing_symbol) {
3162 String *proxy_class_name = Getattr(n, "sym:name");
3163 Swig_error(input_file, line_number, "The interface feature name '%s' for proxy class '%s' is already defined in the generated target language module in scope '%s'.\n",
3164 interface_name, proxy_class_name, scope);
3165 Swig_error(Getfile(existing_symbol), Getline(existing_symbol), "Previous declaration of '%s'\n", interface_name);
3166 return 0;
3167 }
3168 if (!addSymbol(interface_name, n, scope))
3169 return 0;
3170 }
3171 return 1;
3172 }
3173
3174 /* -----------------------------------------------------------------------------
3175 * Language::symbolAddScope()
3176 *
3177 * Creates a scope (symbols Hash) for given name. This method is auxiliary,
3178 * you don't have to call it - addSymbols will lazily create scopes automatically.
3179 * If scope with given name already exists, then do nothing.
3180 * Returns newly created (or already existing) scope.
3181 * ----------------------------------------------------------------------------- */
symbolAddScope(const_String_or_char_ptr scope)3182 Hash* Language::symbolAddScope(const_String_or_char_ptr scope) {
3183 Hash *symbols = symbolScopeLookup(scope);
3184 if(!symbols) {
3185 // The order in which the following code is executed is important. In the Language
3186 // constructor addScope("") is called to create a top level scope.
3187 // Thus we must first add a symbols hash to symtab and only then add pseudo
3188 // symbols to the top-level scope.
3189
3190 // New scope which has not been added by the target language - lazily created.
3191 symbols = NewHash();
3192 Setattr(symtabs, scope, symbols);
3193
3194 // Add the new scope as a symbol in the top level scope.
3195 // Alternatively the target language must add it in before attempting to add symbols into the scope.
3196 const_String_or_char_ptr top_scope = "";
3197 Hash *topscope_symbols = Getattr(symtabs, top_scope);
3198 Hash *pseudo_symbol = NewHash();
3199 Setattr(pseudo_symbol, "sym:scope", "1");
3200 Setattr(topscope_symbols, scope, pseudo_symbol);
3201 }
3202 return symbols;
3203 }
3204
3205 /* -----------------------------------------------------------------------------
3206 * Language::symbolScopeLookup()
3207 *
3208 * Lookup and returns a symtable (hash) representing given scope. Hash contains
3209 * all symbols in this scope.
3210 * ----------------------------------------------------------------------------- */
symbolScopeLookup(const_String_or_char_ptr scope)3211 Hash* Language::symbolScopeLookup( const_String_or_char_ptr scope ) {
3212 Hash *symbols = Getattr(symtabs, scope ? scope : "");
3213 return symbols;
3214 }
3215
3216 /* -----------------------------------------------------------------------------
3217 * Language::symbolScopePseudoSymbolLookup()
3218 *
3219 * For every scope there is a special pseudo-symbol in the top scope (""). It
3220 * exists solely to detect name clashes. This pseudo symbol may contain a few properties,
3221 * but more could be added. This is also true for the top level scope ("").
3222 * It contains a pseudo symbol with name "" (empty). Pseudo symbol contains the
3223 * following properties:
3224 * sym:scope = "1" - a flag that this is a scope pseudo symbol
3225 *
3226 * Pseudo symbols are a Hash*, not a Node*.
3227 * There is no difference from symbolLookup() method except for signature
3228 * and return type.
3229 * ----------------------------------------------------------------------------- */
symbolScopePseudoSymbolLookup(const_String_or_char_ptr scope)3230 Hash* Language::symbolScopePseudoSymbolLookup( const_String_or_char_ptr scope )
3231 {
3232 /* Getting top scope */
3233 const_String_or_char_ptr top_scope = "";
3234 Hash *symbols = Getattr(symtabs, top_scope);
3235 return Getattr(symbols, scope);
3236 }
3237
3238 /* -----------------------------------------------------------------------------
3239 * Language::dumpSymbols()
3240 * ----------------------------------------------------------------------------- */
3241
dumpSymbols()3242 void Language::dumpSymbols() {
3243 Printf(stdout, "LANGUAGE SYMBOLS start =======================================\n");
3244
3245 Node *table = symtabs;
3246 Iterator ki = First(table);
3247 while (ki.key) {
3248 String *k = ki.key;
3249 Printf(stdout, "===================================================\n");
3250 Printf(stdout, "%s -\n", k);
3251 {
3252 Symtab *symtab = Getattr(table, k);
3253 Iterator it = First(symtab);
3254 while (it.key) {
3255 String *symname = it.key;
3256 Printf(stdout, " %s\n", symname);
3257 it = Next(it);
3258 }
3259 }
3260 ki = Next(ki);
3261 }
3262
3263 Printf(stdout, "LANGUAGE SYMBOLS finish =======================================\n");
3264 }
3265
3266 /* -----------------------------------------------------------------------------
3267 * Language::symbolLookup()
3268 * ----------------------------------------------------------------------------- */
3269
symbolLookup(const String * s,const_String_or_char_ptr scope)3270 Node *Language::symbolLookup(const String *s, const_String_or_char_ptr scope) {
3271 Hash *symbols = Getattr(symtabs, scope ? scope : "");
3272 if (!symbols) {
3273 return NULL;
3274 }
3275 return Getattr(symbols, s);
3276 }
3277
3278 /* -----------------------------------------------------------------------------
3279 * Language::classLookup()
3280 *
3281 * Tries to locate a class from a type definition
3282 * ----------------------------------------------------------------------------- */
3283
classLookup(const SwigType * s)3284 Node *Language::classLookup(const SwigType *s) {
3285 static Hash *classtypes = 0;
3286
3287 Node *n = 0;
3288
3289 /* Look in hash of cached values */
3290 n = classtypes ? Getattr(classtypes, s) : 0;
3291 if (!n) {
3292 Symtab *stab = 0;
3293 SwigType *ty1 = SwigType_typedef_resolve_all(s);
3294 SwigType *ty2 = SwigType_strip_qualifiers(ty1);
3295
3296 String *base = SwigType_base(ty2);
3297
3298 Replaceall(base, "class ", "");
3299 Replaceall(base, "struct ", "");
3300 Replaceall(base, "union ", "");
3301
3302 if (strncmp(Char(base), "::", 2) == 0) {
3303 String *oldbase = base;
3304 base = NewString(Char(base) + 2);
3305 Delete(oldbase);
3306 }
3307
3308 String *prefix = SwigType_prefix(ty2);
3309
3310 /* Do a symbol table search on the base type */
3311 while (!n) {
3312 Hash *nstab;
3313 n = Swig_symbol_clookup(base, stab);
3314 if (!n)
3315 break;
3316 if (Strcmp(nodeType(n), "class") == 0)
3317 break;
3318 Node *sibling = n;
3319 while (sibling) {
3320 sibling = Getattr(sibling, "csym:nextSibling");
3321 if (sibling && Strcmp(nodeType(sibling), "class") == 0)
3322 break;
3323 }
3324 if (sibling)
3325 break;
3326 n = parentNode(n);
3327 if (!n)
3328 break;
3329 nstab = Getattr(n, "sym:symtab");
3330 n = 0;
3331 if ((!nstab) || (nstab == stab)) {
3332 break;
3333 }
3334 stab = nstab;
3335 }
3336 if (n) {
3337 /* Found a match. Look at the prefix. We only allow
3338 the cases where we want a proxy class for the particular type */
3339 bool acceptable_prefix =
3340 (Len(prefix) == 0) || // simple type (pass by value)
3341 (Strcmp(prefix, "p.") == 0) || // pointer
3342 (Strcmp(prefix, "r.") == 0) || // reference
3343 (Strcmp(prefix, "z.") == 0) || // rvalue reference
3344 SwigType_prefix_is_simple_1D_array(prefix); // Simple 1D array (not arrays of pointers/references)
3345 // Also accept pointer by const reference, not non-const pointer reference
3346 if (!acceptable_prefix && (Strcmp(prefix, "r.p.") == 0)) {
3347 Delete(prefix);
3348 prefix = SwigType_prefix(ty1);
3349 acceptable_prefix = (Strncmp(prefix, "r.q(const", 9) == 0);
3350 }
3351 if (acceptable_prefix) {
3352 SwigType *cs = Copy(s);
3353 if (!classtypes)
3354 classtypes = NewHash();
3355 Setattr(classtypes, cs, n);
3356 Delete(cs);
3357 } else {
3358 n = 0;
3359 }
3360 }
3361 Delete(prefix);
3362 Delete(base);
3363 Delete(ty2);
3364 Delete(ty1);
3365 }
3366 if (n && (GetFlag(n, "feature:ignore") || Getattr(n, "feature:onlychildren"))) {
3367 n = 0;
3368 }
3369
3370 return n;
3371 }
3372
3373 /* -----------------------------------------------------------------------------
3374 * Language::enumLookup()
3375 *
3376 * Finds and returns the Node containing the enum declaration for the (enum)
3377 * type passed in.
3378 * ----------------------------------------------------------------------------- */
3379
enumLookup(SwigType * s)3380 Node *Language::enumLookup(SwigType *s) {
3381 static Hash *enumtypes = 0;
3382
3383 Node *n = 0;
3384
3385 /* Look in hash of cached values */
3386 n = enumtypes ? Getattr(enumtypes, s) : 0;
3387 if (!n) {
3388 Symtab *stab = 0;
3389 SwigType *lt = SwigType_ltype(s);
3390 SwigType *ty1 = SwigType_typedef_resolve_all(lt);
3391 SwigType *ty2 = SwigType_strip_qualifiers(ty1);
3392
3393 String *base = SwigType_base(ty2);
3394
3395 Replaceall(base, "enum ", "");
3396 String *prefix = SwigType_prefix(ty2);
3397
3398 if (strncmp(Char(base), "::", 2) == 0) {
3399 String *oldbase = base;
3400 base = NewString(Char(base) + 2);
3401 Delete(oldbase);
3402 }
3403
3404 /* Look for type in symbol table */
3405 while (!n) {
3406 Hash *nstab;
3407 n = Swig_symbol_clookup(base, stab);
3408 if (!n)
3409 break;
3410 if (Equal(nodeType(n), "enum"))
3411 break;
3412 if (Equal(nodeType(n), "enumforward") && GetFlag(n, "enumMissing"))
3413 break;
3414 n = parentNode(n);
3415 if (!n)
3416 break;
3417 nstab = Getattr(n, "sym:symtab");
3418 n = 0;
3419 if ((!nstab) || (nstab == stab)) {
3420 break;
3421 }
3422 stab = nstab;
3423 }
3424 if (n) {
3425 /* Found a match. Look at the prefix. We only allow simple types. */
3426 if (Len(prefix) == 0) { /* Simple type */
3427 if (!enumtypes)
3428 enumtypes = NewHash();
3429 Setattr(enumtypes, Copy(s), n);
3430 } else {
3431 n = 0;
3432 }
3433 }
3434 Delete(prefix);
3435 Delete(base);
3436 Delete(ty2);
3437 Delete(ty1);
3438 Delete(lt);
3439 }
3440 if (n && (GetFlag(n, "feature:ignore"))) {
3441 n = 0;
3442 }
3443
3444 return n;
3445 }
3446
3447 /* -----------------------------------------------------------------------------
3448 * Language::allow_overloading()
3449 * ----------------------------------------------------------------------------- */
3450
allow_overloading(int val)3451 void Language::allow_overloading(int val) {
3452 overloading = val;
3453 }
3454
3455 /* -----------------------------------------------------------------------------
3456 * Language::allow_multiple_input()
3457 * ----------------------------------------------------------------------------- */
3458
allow_multiple_input(int val)3459 void Language::allow_multiple_input(int val) {
3460 multiinput = val;
3461 }
3462
3463 /* -----------------------------------------------------------------------------
3464 * Language::enable_cplus_runtime_mode()
3465 * ----------------------------------------------------------------------------- */
3466
enable_cplus_runtime_mode()3467 void Language::enable_cplus_runtime_mode() {
3468 cplus_runtime = 1;
3469 }
3470
3471 /* -----------------------------------------------------------------------------
3472 * Language::cplus_runtime_mode()
3473 * ----------------------------------------------------------------------------- */
3474
cplus_runtime_mode()3475 int Language::cplus_runtime_mode() {
3476 return cplus_runtime;
3477 }
3478
3479 /* -----------------------------------------------------------------------------
3480 * Language::allow_directors()
3481 * ----------------------------------------------------------------------------- */
3482
allow_directors(int val)3483 void Language::allow_directors(int val) {
3484 directors = val;
3485 }
3486
3487 /* -----------------------------------------------------------------------------
3488 * Language::directorsEnabled()
3489 * ----------------------------------------------------------------------------- */
3490
directorsEnabled() const3491 int Language::directorsEnabled() const {
3492 return director_language && CPlusPlus && (directors || director_mode);
3493 }
3494
3495 /* -----------------------------------------------------------------------------
3496 * Language::allow_dirprot()
3497 * ----------------------------------------------------------------------------- */
3498
allow_dirprot(int val)3499 void Language::allow_dirprot(int val) {
3500 director_protected_mode = val;
3501 }
3502
3503 /* -----------------------------------------------------------------------------
3504 * Language::allow_allprotected()
3505 * ----------------------------------------------------------------------------- */
3506
allow_allprotected(int val)3507 void Language::allow_allprotected(int val) {
3508 all_protected_mode = val;
3509 }
3510
3511 /* -----------------------------------------------------------------------------
3512 * Language::dirprot_mode()
3513 * ----------------------------------------------------------------------------- */
3514
dirprot_mode() const3515 int Language::dirprot_mode() const {
3516 return directorsEnabled() ? director_protected_mode : 0;
3517 }
3518
3519 /* -----------------------------------------------------------------------------
3520 * Language::need_nonpublic_ctor()
3521 * ----------------------------------------------------------------------------- */
3522
need_nonpublic_ctor(Node * n)3523 int Language::need_nonpublic_ctor(Node *n) {
3524 /*
3525 detects when a protected constructor is needed, which is always
3526 the case if 'dirprot' mode is used. However, if that is not the
3527 case, we will try to strictly emit what is minimal to don't break
3528 the generated, while preserving compatibility with java, which
3529 always try to emit the default constructor.
3530
3531 rules:
3532
3533 - when dirprot mode is used, the protected constructors are
3534 always needed.
3535
3536 - the protected default constructor is always needed.
3537
3538 - if dirprot mode is not used, the protected constructors will be
3539 needed only if:
3540
3541 - there is no any public constructor in the class, and
3542 - there is no protected default constructor
3543
3544 In that case, all the declared protected constructors are
3545 needed since we don't know which one to pick up.
3546
3547 Note: given all the complications here, I am always in favor to
3548 always enable 'dirprot', since is the C++ idea of protected
3549 members, and use %ignore for the method you don't want to add in
3550 the director class.
3551 */
3552 if (directorsEnabled()) {
3553 if (is_protected(n)) {
3554 if (dirprot_mode()) {
3555 /* when using dirprot mode, the protected constructors are
3556 always needed */
3557 return 1;
3558 } else {
3559 int is_default_ctor = !ParmList_numrequired(Getattr(n, "parms"));
3560 if (is_default_ctor) {
3561 /* the default protected constructor is always needed, for java compatibility */
3562 return 1;
3563 } else {
3564 /* check if there is a public constructor */
3565 Node *parent = Swig_methodclass(n);
3566 int public_ctor = Getattr(parent, "allocate:default_constructor")
3567 || Getattr(parent, "allocate:public_constructor");
3568 if (!public_ctor) {
3569 /* if not, the protected constructor will be needed only
3570 if there is no protected default constructor declared */
3571 int no_prot_default_ctor = !Getattr(parent, "allocate:default_base_constructor");
3572 return no_prot_default_ctor;
3573 }
3574 }
3575 }
3576 }
3577 }
3578 return 0;
3579 }
3580
3581 /* -----------------------------------------------------------------------------
3582 * Language::need_nonpublic_member()
3583 * ----------------------------------------------------------------------------- */
need_nonpublic_member(Node * n)3584 int Language::need_nonpublic_member(Node *n) {
3585 if (directorsEnabled() && DirectorClassName) {
3586 if (is_protected(n)) {
3587 if (dirprot_mode()) {
3588 /* when using dirprot mode, the protected members are always needed. */
3589 return 1;
3590 } else {
3591 /* if the method is pure virtual, we need it. */
3592 int pure_virtual = (Cmp(Getattr(n, "value"), "0") == 0);
3593 return pure_virtual;
3594 }
3595 }
3596 }
3597 return 0;
3598 }
3599
3600
3601 /* -----------------------------------------------------------------------------
3602 * Language::is_smart_pointer()
3603 * ----------------------------------------------------------------------------- */
3604
is_smart_pointer() const3605 int Language::is_smart_pointer() const {
3606 return SmartPointer;
3607 }
3608
3609 /* -----------------------------------------------------------------------------
3610 * Language::makeParameterName()
3611 *
3612 * Inputs:
3613 * n - Node
3614 * p - parameter node
3615 * arg_num - parameter argument number
3616 * setter - set this flag when wrapping variables
3617 * Return:
3618 * arg - a unique parameter name
3619 * ----------------------------------------------------------------------------- */
makeParameterName(Node * n,Parm * p,int arg_num,bool setter) const3620 String *Language::makeParameterName(Node *n, Parm *p, int arg_num, bool setter) const {
3621
3622 String *arg = 0;
3623 String *pn = Getattr(p, "name");
3624
3625 // Check if parameter name is a duplicate.
3626 int count = 0;
3627 ParmList *plist = Getattr(n, "parms");
3628 while (plist) {
3629 if ((Cmp(pn, Getattr(plist, "name")) == 0))
3630 count++;
3631 plist = nextSibling(plist);
3632 }
3633
3634 // If the parameter has no name at all or has a non-unique name, replace it with "argN".
3635 if (!pn || count > 1) {
3636 arg = NewStringf("arg%d", arg_num);
3637 } else {
3638 // Otherwise, try to use the original C name, but modify it if necessary to avoid conflicting with the language keywords.
3639 arg = Swig_name_make(p, 0, pn, 0, 0);
3640 }
3641
3642 if (setter && Cmp(arg, "self") != 0) {
3643 // Some languages (C#) insist on calling the input variable "value" while
3644 // others (D, Java) could, in principle, use something different but this
3645 // would require more work, and so we just use "value" for them too.
3646 // For setters the parameter name sometimes includes C++ scope resolution which needs removing.
3647 Delete(arg);
3648 arg = NewString("value");
3649 }
3650
3651 return arg;
3652 }
3653
3654 /* -----------------------------------------------------------------------------
3655 * Language::()
3656 * ----------------------------------------------------------------------------- */
3657
isNonVirtualProtectedAccess(Node * n) const3658 bool Language::isNonVirtualProtectedAccess(Node *n) const {
3659 // Ideally is_non_virtual_protected_access() would contain all this logic, see
3660 // comments therein about vtable.
3661 return DirectorClassName && is_non_virtual_protected_access(n);
3662 }
3663
3664 /* -----------------------------------------------------------------------------
3665 * Language::extraDirectorProtectedCPPMethodsRequired()
3666 * ----------------------------------------------------------------------------- */
3667
extraDirectorProtectedCPPMethodsRequired() const3668 bool Language::extraDirectorProtectedCPPMethodsRequired() const {
3669 return true;
3670 }
3671
3672 /* -----------------------------------------------------------------------------
3673 * Language::nestedClassesSupport()
3674 * ----------------------------------------------------------------------------- */
3675
nestedClassesSupport() const3676 Language::NestedClassSupport Language::nestedClassesSupport() const {
3677 return NCS_Unknown;
3678 }
3679
3680 /* -----------------------------------------------------------------------------
3681 * Language::kwargsSupport()
3682 * ----------------------------------------------------------------------------- */
3683
kwargsSupport() const3684 bool Language::kwargsSupport() const {
3685 return false;
3686 }
3687
3688 /* -----------------------------------------------------------------------------
3689 * Language::is_wrapping_class()
3690 * ----------------------------------------------------------------------------- */
3691
is_wrapping_class() const3692 int Language::is_wrapping_class() const {
3693 return InClass;
3694 }
3695
3696 /* -----------------------------------------------------------------------------
3697 * Language::getCurrentClass()
3698 * ----------------------------------------------------------------------------- */
3699
getCurrentClass() const3700 Node *Language::getCurrentClass() const {
3701 return CurrentClass;
3702 }
3703
3704 /* -----------------------------------------------------------------------------
3705 * Language::getNSpace()
3706 * ----------------------------------------------------------------------------- */
3707
getNSpace() const3708 String *Language::getNSpace() const {
3709 return NSpace;
3710 }
3711
3712 /* -----------------------------------------------------------------------------
3713 * Language::getClassName()
3714 * ----------------------------------------------------------------------------- */
3715
getClassName() const3716 String *Language::getClassName() const {
3717 return ClassName;
3718 }
3719
3720 /* -----------------------------------------------------------------------------
3721 * Language::getClassPrefix()
3722 * ----------------------------------------------------------------------------- */
3723
getClassPrefix() const3724 String *Language::getClassPrefix() const {
3725 return ClassPrefix;
3726 }
3727
3728 /* -----------------------------------------------------------------------------
3729 * Language::getEnumClassPrefix()
3730 * ----------------------------------------------------------------------------- */
3731
getEnumClassPrefix() const3732 String *Language::getEnumClassPrefix() const {
3733 return EnumClassPrefix;
3734 }
3735
3736 /* -----------------------------------------------------------------------------
3737 * Language::getClassType()
3738 * ----------------------------------------------------------------------------- */
3739
getClassType() const3740 String *Language::getClassType() const {
3741 return ClassType;
3742 }
3743
3744 /* -----------------------------------------------------------------------------
3745 * Language::abstractClassTest()
3746 * ----------------------------------------------------------------------------- */
3747 //#define SWIG_DEBUG
abstractClassTest(Node * n)3748 int Language::abstractClassTest(Node *n) {
3749 /* check for non public operator new */
3750 if (GetFlag(n, "feature:notabstract"))
3751 return 0;
3752 if (Getattr(n, "allocate:nonew"))
3753 return 1;
3754
3755 // A class cannot be instantiated if one of its bases has a private destructor
3756 // Note that if the above does not hold the class can be instantiated if its own destructor is private
3757 List *bases = Getattr(n, "bases");
3758 if (bases) {
3759 for (int i = 0; i < Len(bases); i++) {
3760 Node *b = Getitem(bases, i);
3761 if (GetFlag(b, "allocate:private_destructor"))
3762 return 1;
3763 }
3764 }
3765
3766 /* now check for the rest */
3767 List *abstracts = Getattr(n, "abstracts");
3768 if (!abstracts)
3769 return 0;
3770 int labs = Len(abstracts);
3771 #ifdef SWIG_DEBUG
3772 List *allbases = Getattr(n, "allbases");
3773 Printf(stderr, "testing %s %d %d\n", Getattr(n, "name"), labs, Len(allbases));
3774 #endif
3775 if (!labs)
3776 return 0; /*strange, but need to be fixed */
3777 if (abstracts && !directorsEnabled())
3778 return 1;
3779 if (!GetFlag(n, "feature:director"))
3780 return 1;
3781
3782 Node *dirabstract = 0;
3783 Node *vtable = Getattr(n, "vtable");
3784 if (vtable) {
3785 #ifdef SWIG_DEBUG
3786 Printf(stderr, "vtable %s %d %d\n", Getattr(n, "name"), Len(vtable), labs);
3787 #endif
3788 for (int i = 0; i < labs; i++) {
3789 Node *ni = Getitem(abstracts, i);
3790 Node *method_id = vtable_method_id(ni);
3791 if (!method_id)
3792 continue;
3793 bool exists_item = false;
3794 int len = Len(vtable);
3795 for (int i = 0; i < len; i++) {
3796 Node *item = Getitem(vtable, i);
3797 String *check_item = Getattr(item, "vmid");
3798 if (Strcmp(method_id, check_item) == 0) {
3799 exists_item = true;
3800 break;
3801 }
3802 }
3803 #ifdef SWIG_DEBUG
3804 Printf(stderr, "method %s %d\n", method_id, exists_item ? 1 : 0);
3805 #endif
3806 Delete(method_id);
3807 if (!exists_item) {
3808 dirabstract = ni;
3809 break;
3810 }
3811 }
3812 if (dirabstract) {
3813 if (is_public(dirabstract)) {
3814 Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n),
3815 "Director class '%s' is abstract, abstract method '%s' is not accessible, maybe due to multiple inheritance or 'nodirector' feature\n",
3816 SwigType_namestr(Getattr(n, "name")), Getattr(dirabstract, "name"));
3817 } else {
3818 Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n),
3819 "Director class '%s' is abstract, abstract method '%s' is private\n", SwigType_namestr(Getattr(n, "name")), Getattr(dirabstract, "name"));
3820 }
3821 return 1;
3822 }
3823 } else {
3824 return 1;
3825 }
3826 return 0;
3827 }
3828
setSubclassInstanceCheck(String * nc)3829 void Language::setSubclassInstanceCheck(String *nc) {
3830 none_comparison = nc;
3831 }
3832
setOverloadResolutionTemplates(String * argc,String * argv)3833 void Language::setOverloadResolutionTemplates(String *argc, String *argv) {
3834 Delete(argc_template_string);
3835 argc_template_string = Copy(argc);
3836 Delete(argv_template_string);
3837 argv_template_string = Copy(argv);
3838 }
3839
is_assignable(Node * n)3840 int Language::is_assignable(Node *n) {
3841 if (GetFlag(n, "feature:immutable"))
3842 return 0;
3843 SwigType *type = Getattr(n, "type");
3844 Node *cn = 0;
3845 SwigType *ftd = SwigType_typedef_resolve_all(type);
3846 SwigType *td = SwigType_strip_qualifiers(ftd);
3847 if (SwigType_type(td) == T_USER) {
3848 cn = Swig_symbol_clookup(td, 0);
3849 if (cn) {
3850 if ((Strcmp(nodeType(cn), "class") == 0)) {
3851 if (Getattr(cn, "allocate:noassign")) {
3852 SetFlag(n, "feature:immutable");
3853 Delete(ftd);
3854 Delete(td);
3855 return 0;
3856 }
3857 }
3858 }
3859 }
3860 Delete(ftd);
3861 Delete(td);
3862 return 1;
3863 }
3864
runtimeCode()3865 String *Language::runtimeCode() {
3866 return NewString("");
3867 }
3868
defaultExternalRuntimeFilename()3869 String *Language::defaultExternalRuntimeFilename() {
3870 return 0;
3871 }
3872
3873 /* -----------------------------------------------------------------------------
3874 * Language::replaceSpecialVariables()
3875 *
3876 * Language modules should implement this if special variables are to be handled
3877 * correctly in the $typemap(...) special variable macro.
3878 * method - typemap method name
3879 * tm - string containing typemap contents
3880 * parm - a parameter describing the typemap type to be handled
3881 * ----------------------------------------------------------------------------- */
replaceSpecialVariables(String * method,String * tm,Parm * parm)3882 void Language::replaceSpecialVariables(String *method, String *tm, Parm *parm) {
3883 (void)method;
3884 (void)tm;
3885 (void)parm;
3886 }
3887
instance()3888 Language *Language::instance() {
3889 return this_;
3890 }
3891
getClassHash() const3892 Hash *Language::getClassHash() const {
3893 return classhash;
3894 }
3895
3896