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