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