1 /* -----------------------------------------------------------------------------
2 * See the LICENSE file for information on copyright, usage and redistribution
3 * of SWIG, and the README file for authors - http://www.swig.org/release.html.
7 * SWIG type system management. These functions are used to manage
8 * the C++ type system including typenames, typedef, type scopes,
9 * inheritance, and namespaces. Generation of support code for the
10 * run-time type checker is also handled here.
11 * ----------------------------------------------------------------------------- */
13 char cvsroot_typesys_c[] = "$Id: typesys.c 11097 2009-01-30 10:27:37Z bhy $";
18 /* -----------------------------------------------------------------------------
21 * The purpose of this module is to manage type names and scoping issues related
22 * to the C++ type system. The primary use is tracking typenames through typedef
25 * New typenames are introduced by typedef, class, and enum declarations.
26 * Each type is declared in a scope. This is either the global scope, a
27 * class, or a namespace. For example:
29 * typedef int A; // Typename A, in global scope
31 * typedef int A; // Typename A, in scope Foo::
33 * class Bar { // Typename Bar, in global scope
34 * typedef int A; // Typename A, in scope Bar::
37 * To manage scopes, the type system is constructed as a tree of hash tables. Each
38 * hash table contains the following attributes:
41 * "qname" - Fully qualified typename
42 * "typetab" - Type table containing typenames and typedef information
43 * "symtab" - Hash table of symbols defined in a scope
44 * "inherit" - List of inherited scopes
45 * "parent" - Parent scope
47 * Typedef information is stored in the "typetab" hash table. For example,
48 * if you have these declarations:
54 * typetab is built as follows:
60 * To resolve a type back to its root type, one repeatedly expands on the type base.
63 * C *[40] ---> a(40).p.C (string type representation, see stype.c)
64 * ---> a(40).p.p.B (C --> p.B)
65 * ---> a(40).p.p.A (B --> A)
66 * ---> a(40).p.p.int (A --> int)
68 * For inheritance, SWIG tries to resolve types back to the base class. For instance, if
73 * typedef int Integer;
76 * class Bar : public Foo {
77 * void blah(Integer x);
80 * The argument type of Bar::blah will be set to Foo::Integer.
82 * The scope-inheritance mechanism is used to manage C++ namespace aliases.
83 * For example, if you have this:
86 * typedef int Integer;
91 * In this case, "F::" is defined as a scope that "inherits" from Foo. Internally,
92 * "F::" will merely be an empty scope that refers to Foo. SWIG will never
93 * place new type information into a namespace alias---attempts to do so
94 * will generate a warning message (in the parser) and will place information into
97 *----------------------------------------------------------------------------- */
99 static Typetab *current_scope = 0; /* Current type scope */
100 static Hash *current_typetab = 0; /* Current type table */
101 static Hash *current_symtab = 0; /* Current symbol table */
102 static Typetab *global_scope = 0; /* The global scope */
103 static Hash *scopes = 0; /* Hash table containing fully qualified scopes */
105 /* Performance optimization */
106 #define SWIG_TYPEDEF_RESOLVE_CACHE
107 static Hash *typedef_resolve_cache = 0;
108 static Hash *typedef_all_cache = 0;
109 static Hash *typedef_qualified_cache = 0;
111 static Typetab *SwigType_find_scope(Typetab *s, String *nameprefix);
113 /* common attribute keys, to avoid calling find_key all the times */
116 Enable this one if your language fully support SwigValueWrapper<T>.
118 Leaving at '0' keeps the old swig behavior, which is not
119 always safe, but is well known.
121 Setting at '1' activates the new scheme, which is always safe but
122 it requires all the typemaps to be ready for that.
125 static int value_wrapper_mode = 0;
126 int Swig_value_wrapper_mode(int mode) {
127 value_wrapper_mode = mode;
132 static void flush_cache() {
133 typedef_resolve_cache = 0;
134 typedef_all_cache = 0;
135 typedef_qualified_cache = 0;
138 /* Initialize the scoping system */
140 void SwigType_typesystem_init() {
142 Delete(global_scope);
146 current_scope = NewHash();
147 global_scope = current_scope;
149 Setattr(current_scope, "name", ""); /* No name for global scope */
150 current_typetab = NewHash();
151 Setattr(current_scope, "typetab", current_typetab);
155 Setattr(scopes, "", current_scope);
159 /* -----------------------------------------------------------------------------
162 * Defines a new typedef in the current scope. Returns -1 if the type name is
164 * ----------------------------------------------------------------------------- */
166 int SwigType_typedef(SwigType *type, const_String_or_char_ptr name) {
167 if (Getattr(current_typetab, name))
168 return -1; /* Already defined */
169 if (Strcmp(type, name) == 0) { /* Can't typedef a name to itself */
173 /* Check if 'type' is already a scope. If so, we create an alias in the type
174 system for it. This is needed to make strange nested scoping problems work
177 Typetab *t = SwigType_find_scope(current_scope, type);
179 SwigType_new_scope(name);
180 SwigType_inherit_scope(t);
181 SwigType_pop_scope();
184 Setattr(current_typetab, name, type);
190 /* -----------------------------------------------------------------------------
191 * SwigType_typedef_class()
193 * Defines a class in the current scope.
194 * ----------------------------------------------------------------------------- */
196 int SwigType_typedef_class(const_String_or_char_ptr name) {
198 /* Printf(stdout,"class : '%s'\n", name); */
199 if (Getattr(current_typetab, name))
200 return -1; /* Already defined */
201 cname = NewString(name);
202 Setmeta(cname, "class", "1");
203 Setattr(current_typetab, cname, cname);
209 /* -----------------------------------------------------------------------------
210 * SwigType_scope_name()
212 * Returns the qualified scope name of a type table
213 * ----------------------------------------------------------------------------- */
215 String *SwigType_scope_name(Typetab *ttab) {
216 String *qname = NewString(Getattr(ttab, "name"));
217 ttab = Getattr(ttab, "parent");
219 String *pname = Getattr(ttab, "name");
221 Insert(qname, 0, "::");
222 Insert(qname, 0, pname);
224 ttab = Getattr(ttab, "parent");
229 /* -----------------------------------------------------------------------------
230 * SwigType_new_scope()
232 * Creates a new scope
233 * ----------------------------------------------------------------------------- */
235 void SwigType_new_scope(const_String_or_char_ptr name) {
244 Setattr(s, "name", name);
245 Setattr(s, "parent", current_scope);
247 Setattr(s, "typetab", ttab);
249 /* Build fully qualified name and */
250 qname = SwigType_scope_name(s);
251 Setattr(scopes, qname, s);
252 Setattr(s, "qname", qname);
256 current_typetab = ttab;
261 /* -----------------------------------------------------------------------------
262 * SwigType_inherit_scope()
264 * Makes the current scope inherit from another scope. This is used for both
265 * C++ class inheritance, namespaces, and namespace aliases.
266 * ----------------------------------------------------------------------------- */
268 void SwigType_inherit_scope(Typetab *scope) {
271 inherits = Getattr(current_scope, "inherit");
273 inherits = NewList();
274 Setattr(current_scope, "inherit", inherits);
277 assert(scope != current_scope);
280 for (i = 0; i < len; i++) {
281 Node *n = Getitem(inherits, i);
285 Append(inherits, scope);
288 /* -----------------------------------------------------------------------------
289 * SwigType_scope_alias()
291 * Creates a scope-alias.
292 * ----------------------------------------------------------------------------- */
294 void SwigType_scope_alias(String *aliasname, Typetab *ttab) {
296 /* Printf(stdout,"alias: '%s' '%x'\n", aliasname, ttab); */
297 q = SwigType_scope_name(current_scope);
301 Append(q, aliasname);
302 Setattr(scopes, q, ttab);
306 /* -----------------------------------------------------------------------------
307 * SwigType_using_scope()
309 * Import another scope into this scope.
310 * ----------------------------------------------------------------------------- */
312 void SwigType_using_scope(Typetab *scope) {
313 SwigType_inherit_scope(scope);
317 ulist = Getattr(current_scope, "using");
320 Setattr(current_scope, "using", ulist);
323 assert(scope != current_scope);
325 for (i = 0; i < len; i++) {
326 Typetab *n = Getitem(ulist, i);
330 Append(ulist, scope);
335 /* -----------------------------------------------------------------------------
336 * SwigType_pop_scope()
338 * Pop off the last scope and perform a merge operation. Returns the hash
339 * table for the scope that was popped off.
340 * ----------------------------------------------------------------------------- */
342 Typetab *SwigType_pop_scope() {
343 Typetab *t, *old = current_scope;
344 t = Getattr(current_scope, "parent");
348 current_typetab = Getattr(t, "typetab");
349 current_symtab = Getattr(t, "symtab");
354 /* -----------------------------------------------------------------------------
355 * SwigType_set_scope()
357 * Set the scope. Returns the old scope.
358 * ----------------------------------------------------------------------------- */
360 Typetab *SwigType_set_scope(Typetab *t) {
361 Typetab *old = current_scope;
365 current_typetab = Getattr(t, "typetab");
366 current_symtab = Getattr(t, "symtab");
371 /* -----------------------------------------------------------------------------
372 * SwigType_attach_symtab()
374 * Attaches a symbol table to a type scope
375 * ----------------------------------------------------------------------------- */
377 void SwigType_attach_symtab(Symtab *sym) {
378 Setattr(current_scope, "symtab", sym);
379 current_symtab = sym;
382 /* -----------------------------------------------------------------------------
383 * SwigType_print_scope()
385 * Debugging function for printing out current scope
386 * ----------------------------------------------------------------------------- */
388 void SwigType_print_scope(Typetab *t) {
392 for (i = First(scopes); i.key; i = Next(i)) {
394 ttab = Getattr(i.item, "typetab");
396 Printf(stdout, "Type scope '%s' (%x)\n", i.key, i.item);
398 List *inherit = Getattr(i.item, "inherit");
401 for (j = First(inherit); j.item; j = Next(j)) {
402 Printf(stdout, " Inherits from '%s' (%x)\n", Getattr(j.item, "qname"), j.item);
406 Printf(stdout, "-------------------------------------------------------------\n");
407 for (j = First(ttab); j.key; j = Next(j)) {
408 Printf(stdout, "%40s -> %s\n", j.key, j.item);
413 static Typetab *SwigType_find_scope(Typetab *s, String *nameprefix) {
415 String *nnameprefix = 0;
416 static int check_parent = 1;
418 /* Printf(stdout,"find_scope: %x(%s) '%s'\n", s, Getattr(s,"name"), nameprefix); */
420 if (SwigType_istemplate(nameprefix)) {
421 nnameprefix = SwigType_typedef_resolve_all(nameprefix);
422 nameprefix = nnameprefix;
428 String *qname = Getattr(ss, "qname");
430 full = NewStringf("%s::%s", qname, nameprefix);
432 full = NewString(nameprefix);
434 if (Getattr(scopes, full)) {
435 s = Getattr(scopes, full);
446 /* Check inheritance */
448 inherit = Getattr(ss, "using");
453 for (i = 0; i < len; i++) {
454 int oldcp = check_parent;
455 ttab = Getitem(inherit, i);
457 s = SwigType_find_scope(ttab, nameprefix);
458 check_parent = oldcp;
469 ss = Getattr(ss, "parent");
476 /* -----------------------------------------------------------------------------
479 * Resolves a typedef and returns a new type string. Returns 0 if there is no
480 * typedef mapping. base is a name without qualification.
482 * ----------------------------------------------------------------------------- */
484 static Typetab *resolved_scope = 0;
486 /* Internal function */
488 static SwigType *_typedef_resolve(Typetab *s, String *base, int look_parent) {
494 /* if (!s) return 0; *//* now is checked bellow */
495 /* Printf(stdout,"Typetab %s : %s\n", Getattr(s,"name"), base); */
500 ttab = Getattr(s, "typetab");
501 type = Getattr(ttab, base);
506 /* Hmmm. Not found in my scope. It could be in an inherited scope */
507 inherit = Getattr(s, "inherit");
511 for (i = 0; i < len; i++) {
512 type = _typedef_resolve(Getitem(inherit, i), base, 0);
520 /* Hmmm. Not found in my scope. check parent */
522 parent = Getattr(s, "parent");
523 type = parent ? _typedef_resolve(parent, base, 1) : 0;
532 static SwigType *typedef_resolve(Typetab *s, String *base) {
533 return _typedef_resolve(s, base, 1);
537 /* -----------------------------------------------------------------------------
538 * SwigType_typedef_resolve()
539 * ----------------------------------------------------------------------------- */
541 /* #define SWIG_DEBUG */
542 SwigType *SwigType_typedef_resolve(const SwigType *t) {
548 String *namebase = 0;
549 String *nameprefix = 0;
554 noscope = NewStringEmpty();
560 #ifdef SWIG_TYPEDEF_RESOLVE_CACHE
561 if (!typedef_resolve_cache) {
562 typedef_resolve_cache = NewHash();
564 r = Getattr(typedef_resolve_cache, t);
566 resolved_scope = Getmeta(r, "scope");
571 base = SwigType_base(t);
574 Printf(stdout, "base = '%s' t='%s'\n", base, t);
577 if (SwigType_issimple(base)) {
579 ttab = current_typetab;
580 if (strncmp(Char(base), "::", 2) == 0) {
582 ttab = Getattr(s, "typetab");
586 /* Do a quick check in the local scope */
587 type = Getattr(ttab, base);
592 /* Didn't find in this scope. We need to do a little more searching */
593 if (Swig_scopename_check(base)) {
594 /* A qualified name. */
595 Swig_scopename_split(base, &nameprefix, &namebase);
597 Printf(stdout, "nameprefix = '%s'\n", nameprefix);
600 /* Name had a prefix on it. See if we can locate the proper scope for it */
601 s = SwigType_find_scope(s, nameprefix);
603 /* Couldn't locate a scope for the type. */
611 /* Try to locate the name starting in the scope */
613 Printf(stdout, "namebase = '%s'\n", namebase);
615 type = typedef_resolve(s, namebase);
617 /* we need to look for the resolved type, this will also
618 fix the resolved_scope if 'type' and 'namebase' are
619 declared in different scopes */
621 rtype = typedef_resolve(resolved_scope, type);
626 Printf(stdout, "%s type = '%s'\n", Getattr(s, "name"), type);
628 if ((type) && (!Swig_scopename_check(type)) && resolved_scope) {
629 Typetab *rtab = resolved_scope;
630 String *qname = Getattr(resolved_scope, "qname");
631 /* If qualified *and* the typename is defined from the resolved scope, we qualify */
632 if ((qname) && typedef_resolve(resolved_scope, type)) {
634 Insert(type, 0, "::");
635 Insert(type, 0, qname);
637 Printf(stdout, "qual %s \n", type);
641 resolved_scope = rtab;
644 /* Name is unqualified. */
645 type = typedef_resolve(s, base);
648 /* Name is unqualified. */
649 type = typedef_resolve(s, base);
653 if (type && (Equal(base, type))) {
663 /* If the type is a template, and no typedef was found, we need to check the
664 template arguments one by one to see if they can be resolved. */
666 if (!type && SwigType_istemplate(base)) {
671 type = SwigType_templateprefix(base);
673 suffix = SwigType_templatesuffix(base);
675 tparms = SwigType_parmlist(base);
677 for (i = 0; i < sz; i++) {
679 SwigType *tp = Getitem(tparms, i);
681 tpr = SwigType_typedef_resolve(tp);
696 Append(type, suffix);
709 if (SwigType_isfunction(base)) {
713 type = NewString("f(");
715 parms = SwigType_parmlist(base);
717 for (i = 0; i < sz; i++) {
719 SwigType *tp = Getitem(parms, i);
721 tpr = SwigType_typedef_resolve(tp);
741 } else if (SwigType_ismemberpointer(base)) {
743 String *mtype = SwigType_parm(base);
744 rt = SwigType_typedef_resolve(mtype);
746 type = NewStringf("m(%s).", rt);
755 r = SwigType_prefix(t);
759 if ((strstr(cr, "f(") || (strstr(cr, "m(")))) {
760 SwigType *rt = SwigType_typedef_resolve(r);
782 #ifdef SWIG_TYPEDEF_RESOLVE_CACHE
784 String *key = NewString(t);
787 Setattr(typedef_resolve_cache, key, r);
788 Setmeta(r, "scope", resolved_scope);
799 /* -----------------------------------------------------------------------------
800 * SwigType_typedef_resolve_all()
802 * Fully resolve a type down to its most basic datatype
803 * ----------------------------------------------------------------------------- */
805 SwigType *SwigType_typedef_resolve_all(SwigType *t) {
809 /* Check to see if the typedef resolve has been done before by checking the cache */
810 if (!typedef_all_cache) {
811 typedef_all_cache = NewHash();
813 r = Getattr(typedef_all_cache, t);
818 /* Recursively resolve the typedef */
820 while ((n = SwigType_typedef_resolve(r))) {
825 /* Add the typedef to the cache for next time it is looked up */
828 SwigType *rr = Copy(r);
830 Setattr(typedef_all_cache, key, rr);
838 /* -----------------------------------------------------------------------------
839 * SwigType_typedef_qualified()
841 * Given a type declaration, this function tries to fully qualify it according to
842 * typedef scope rules.
843 * Inconsistency to be fixed: ::Foo returns ::Foo, whereas ::Foo * returns Foo *
844 * ----------------------------------------------------------------------------- */
846 SwigType *SwigType_typedef_qualified(SwigType *t) {
851 if (strncmp(Char(t), "::", 2) == 0) {
855 if (!typedef_qualified_cache)
856 typedef_qualified_cache = NewHash();
857 result = Getattr(typedef_qualified_cache, t);
859 String *rc = Copy(result);
863 result = NewStringEmpty();
864 elements = SwigType_split(t);
866 for (i = 0; i < len; i++) {
868 String *e = Getitem(elements, i);
869 if (SwigType_issimple(e)) {
870 if (!SwigType_istemplate(e)) {
872 if (SwigType_isenum(e)) {
873 isenum = NewString("enum ");
874 ty = NewString(Char(e) + 5);
878 if (typedef_resolve(current_scope, e)) {
879 /* resolved_scope contains the scope that actually resolved the symbol */
880 String *qname = Getattr(resolved_scope, "qname");
886 if (Swig_scopename_check(e)) {
889 Swig_scopename_split(e, &qname, &qlast);
891 String *tqname = SwigType_typedef_qualified(qname);
893 Printf(e, "%s::%s", tqname, qlast);
899 /* Automatic template instantiation might go here??? */
901 /* It's a bare name. It's entirely possible, that the
902 name is part of a namespace. We'll check this by unrolling
903 out of the current scope */
905 Typetab *cs = current_scope;
907 String *qs = SwigType_scope_name(cs);
912 if (Getattr(scopes, qs)) {
919 cs = Getattr(cs, "parent");
924 Insert(e, 0, isenum);
928 /* Template. We need to qualify template parameters as well as the template itself */
929 String *tprefix, *qprefix;
934 ty = Swig_symbol_template_deftype(e, current_symtab);
936 parms = SwigType_parmlist(e);
937 tprefix = SwigType_templateprefix(e);
938 tsuffix = SwigType_templatesuffix(e);
939 qprefix = SwigType_typedef_qualified(tprefix);
940 Append(qprefix, "<(");
942 while ((p = pi.item)) {
943 String *qt = SwigType_typedef_qualified(p);
944 if (Equal(qt, p)) { /* && (!Swig_scopename_check(qt))) */
945 /* No change in value. It is entirely possible that the parameter is an integer value.
946 If there is a symbol table associated with this scope, we're going to check for this */
948 if (current_symtab) {
950 String *value = Copy(p);
952 Node *n = Swig_symbol_clookup(value, current_symtab);
957 char *ntype = Char(nodeType(n));
958 if (strcmp(ntype, "enumitem") == 0) {
959 /* An enum item. Generate a fully qualified name */
960 String *qn = Swig_symbol_qualified(n);
963 Append(qn, Getattr(n, "name"));
971 } else if ((strcmp(ntype, "cdecl") == 0) && (Getattr(n, "value"))) {
973 value = Copy(Getattr(n, "value"));
979 Append(qprefix, value);
990 Append(qprefix, ",");
993 Append(qprefix, ")>");
994 Append(qprefix, tsuffix);
1002 if (strncmp(Char(e), "::", 2) == 0) {
1008 } else if (SwigType_isfunction(e)) {
1009 List *parms = SwigType_parmlist(e);
1010 String *s = NewString("f(");
1014 String *pq = SwigType_typedef_qualified(pi.item);
1026 } else if (SwigType_isarray(e)) {
1028 String *dim = SwigType_parm(e);
1029 ndim = Swig_symbol_string_qualify(dim, 0);
1030 Printf(result, "a(%s).", ndim);
1039 String *key, *cresult;
1041 cresult = NewString(result);
1042 Setattr(typedef_qualified_cache, key, cresult);
1049 /* -----------------------------------------------------------------------------
1050 * SwigType_istypedef()
1052 * Checks a typename to see if it is a typedef.
1053 * ----------------------------------------------------------------------------- */
1055 int SwigType_istypedef(SwigType *t) {
1058 type = SwigType_typedef_resolve(t);
1068 /* -----------------------------------------------------------------------------
1069 * SwigType_typedef_using()
1071 * Processes a 'using' declaration to import types from one scope into another.
1072 * Name is a qualified name like A::B.
1073 * ----------------------------------------------------------------------------- */
1075 int SwigType_typedef_using(const_String_or_char_ptr name) {
1082 String *defined_name = 0;
1084 /* Printf(stdout,"using %s\n", name); */
1086 if (!Swig_scopename_check(name))
1087 return -1; /* Not properly qualified */
1088 base = Swig_scopename_last(name);
1090 /* See if the base is already defined in this scope */
1091 if (Getattr(current_typetab, base)) {
1096 /* See if the using name is a scope */
1097 /* tt = SwigType_find_scope(current_scope,name);
1098 Printf(stdout,"tt = %x, name = '%s'\n", tt, name); */
1100 /* We set up a typedef B --> A::B */
1101 Setattr(current_typetab, base, name);
1103 /* Find the scope name where the symbol is defined */
1104 td = SwigType_typedef_resolve(name);
1105 /* Printf(stdout,"td = '%s' %x\n", td, resolved_scope); */
1106 if (resolved_scope) {
1107 defined_name = Getattr(resolved_scope, "qname");
1109 defined_name = Copy(defined_name);
1110 Append(defined_name, "::");
1111 Append(defined_name, base);
1112 /* Printf(stdout,"defined_name = '%s'\n", defined_name); */
1113 tt = SwigType_find_scope(current_scope, defined_name);
1120 /* Figure out the scope the using directive refers to */
1122 prefix = Swig_scopename_prefix(name);
1123 s = SwigType_find_scope(current_scope, prefix);
1125 Hash *ttab = Getattr(s, "typetab");
1126 if (!Getattr(ttab, base) && defined_name) {
1127 Setattr(ttab, base, defined_name);
1133 /* Using directive had its own scope. We need to create a new scope for it */
1134 SwigType_new_scope(base);
1135 SwigType_inherit_scope(tt);
1136 SwigType_pop_scope();
1140 Delete(defined_name);
1146 /* -----------------------------------------------------------------------------
1147 * SwigType_isclass()
1149 * Determines if a type defines a class or not. A class is defined by
1150 * its type-table entry maps to itself. Note: a pointer to a class is not
1152 * ----------------------------------------------------------------------------- */
1154 int SwigType_isclass(SwigType *t) {
1155 SwigType *qty, *qtys;
1158 qty = SwigType_typedef_resolve_all(t);
1159 qtys = SwigType_strip_qualifiers(qty);
1160 if (SwigType_issimple(qtys)) {
1161 String *td = SwigType_typedef_resolve(qtys);
1165 if (resolved_scope) {
1168 /* Hmmm. Not a class. If a template, it might be uninstantiated */
1169 if (!isclass && SwigType_istemplate(qtys)) {
1170 String *tp = SwigType_templateprefix(qtys);
1171 if (Strcmp(tp, t) != 0) {
1172 isclass = SwigType_isclass(tp);
1182 /* -----------------------------------------------------------------------------
1185 * Returns an integer code describing the datatype. This is only used for
1186 * compatibility with SWIG1.1 language modules and is likely to go away once
1187 * everything is based on typemaps.
1188 * ----------------------------------------------------------------------------- */
1190 int SwigType_type(SwigType *t) {
1192 /* Check for the obvious stuff */
1195 if (strncmp(c, "p.", 2) == 0) {
1196 if (SwigType_type(c + 2) == T_CHAR)
1201 if (strncmp(c, "a(", 2) == 0)
1203 if (strncmp(c, "r.", 2) == 0)
1205 if (strncmp(c, "m(", 2) == 0)
1207 if (strncmp(c, "q(", 2) == 0) {
1208 while (*c && (*c != '.'))
1211 return SwigType_type(c + 1);
1214 if (strncmp(c, "f(", 2) == 0)
1217 /* Look for basic types */
1218 if (strcmp(c, "int") == 0)
1220 if (strcmp(c, "long") == 0)
1222 if (strcmp(c, "short") == 0)
1224 if (strcmp(c, "unsigned") == 0)
1226 if (strcmp(c, "unsigned short") == 0)
1228 if (strcmp(c, "unsigned long") == 0)
1230 if (strcmp(c, "unsigned int") == 0)
1232 if (strcmp(c, "char") == 0)
1234 if (strcmp(c, "signed char") == 0)
1236 if (strcmp(c, "unsigned char") == 0)
1238 if (strcmp(c, "float") == 0)
1240 if (strcmp(c, "double") == 0)
1242 if (strcmp(c, "long double") == 0)
1243 return T_LONGDOUBLE;
1244 if (!cparse_cplusplus && (strcmp(c, "float complex") == 0))
1246 if (!cparse_cplusplus && (strcmp(c, "double complex") == 0))
1248 if (!cparse_cplusplus && (strcmp(c, "complex") == 0))
1250 if (strcmp(c, "void") == 0)
1252 if (strcmp(c, "bool") == 0)
1254 if (strcmp(c, "long long") == 0)
1256 if (strcmp(c, "unsigned long long") == 0)
1258 if (strncmp(c, "enum ", 5) == 0)
1261 if (strcmp(c, "v(...)") == 0)
1263 /* Hmmm. Unknown type */
1264 if (SwigType_istypedef(t)) {
1266 SwigType *nt = SwigType_typedef_resolve(t);
1267 r = SwigType_type(nt);
1274 /* -----------------------------------------------------------------------------
1275 * SwigType_alttype()
1277 * Returns the alternative value type needed in C++ for class value
1278 * types. When swig is not sure about using a plain $ltype value,
1279 * since the class doesn't have a default constructor, or it can't be
1280 * assigned, you will get back 'SwigValueWrapper<type >'.
1282 * This is the default behavior unless:
1284 * 1.- swig detects a default_constructor and 'setallocate:default_constructor'
1287 * 2.- swig doesn't mark 'type' as non-assignable.
1289 * 3.- the user specify that the value wrapper is not needed by using
1290 * the %feature("novaluewrapper"), in that case the user need to type
1292 * %feature("novaluewrapper") MyOpaqueClass;
1293 * class MyOpaqueClass;
1295 * Users can also force the use of the value wrapper by using the
1296 * %feature("valuewrapper").
1297 * ----------------------------------------------------------------------------- */
1299 SwigType *SwigType_alttype(SwigType *t, int local_tmap) {
1302 int use_wrapper = 0;
1305 if (!cparse_cplusplus)
1308 if (value_wrapper_mode == 0) {
1309 /* old partial use of SwigValueTypes, it can fail for opaque types */
1312 if (SwigType_isclass(t)) {
1313 SwigType *ftd = SwigType_typedef_resolve_all(t);
1314 td = SwigType_strip_qualifiers(ftd);
1316 n = Swig_symbol_clookup(td, 0);
1318 if (GetFlag(n, "feature:valuewrapper")) {
1321 if (Checkattr(n, "nodeType", "class")
1322 && (!Getattr(n, "allocate:default_constructor")
1323 || (Getattr(n, "allocate:noassign")))) {
1324 use_wrapper = !GetFlag(n, "feature:novaluewrapper") || GetFlag(n, "feature:nodefault");
1328 if (SwigType_issimple(td) && SwigType_istemplate(td)) {
1329 use_wrapper = !n || !GetFlag(n, "feature:novaluewrapper");
1334 /* safe use of SwigValueTypes, it can fail with some typemaps */
1335 SwigType *ftd = SwigType_typedef_resolve_all(t);
1336 td = SwigType_strip_qualifiers(ftd);
1338 if (SwigType_type(td) == T_USER) {
1340 n = Swig_symbol_clookup(td, 0);
1342 if ((Checkattr(n, "nodeType", "class")
1343 && !Getattr(n, "allocate:noassign")
1344 && (Getattr(n, "allocate:default_constructor")))
1345 || (GetFlag(n, "feature:novaluewrapper"))) {
1346 use_wrapper = GetFlag(n, "feature:valuewrapper");
1353 /* Need a space before the type in case it starts "::" (since the <:
1354 * token is a digraph for [ in C++. Also need a space after the
1355 * type in case it ends with ">" since then we form the token ">>".
1357 w = NewStringf("SwigValueWrapper< %s >", td);
1363 /* ----------------------------------------------------------------------------
1364 * * * * WARNING * * * ***
1366 * Don't even think about modifying anything below this line unless you ***
1367 * are completely on top of *EVERY* subtle aspect of the C++ type system ***
1368 * and you are prepared to suffer endless hours of agony trying to ***
1369 * debug the SWIG run-time type checker after you break it. ***
1370 * ------------------------------------------------------------------------- */
1372 /* -----------------------------------------------------------------------------
1373 * SwigType_remember()
1375 * This function "remembers" a datatype that was used during wrapper code generation
1376 * so that a type-checking table can be generated later on. It is up to the language
1377 * modules to actually call this function--it is not done automatically.
1379 * Type tracking is managed through two separate hash tables. The hash 'r_mangled'
1380 * is mapping between mangled type names (used in the target language) and
1381 * fully-resolved C datatypes used in the source input. The second hash 'r_resolved'
1382 * is the inverse mapping that maps fully-resolved C datatypes to all of the mangled
1383 * names in the scripting languages. For example, consider the following set of
1384 * typedef declarations:
1386 * typedef double Real;
1387 * typedef double Float;
1388 * typedef double Point[3];
1390 * Now, suppose that the types 'double *', 'Real *', 'Float *', 'double[3]', and
1391 * 'Point' were used in an interface file and "remembered" using this function.
1392 * The hash tables would look like this:
1395 * _p_double : [ p.double, a(3).double ]
1396 * _p_Real : [ p.double ]
1397 * _p_Float : [ p.double ]
1398 * _Point : [ a(3).double ]
1401 * p.double : [ _p_double, _p_Real, _p_Float ]
1402 * a(3).double : [ _p_double, _Point ]
1405 * Together these two hash tables can be used to determine type-equivalency between
1406 * mangled typenames. To do this, we view the two hash tables as a large graph and
1407 * compute the transitive closure.
1408 * ----------------------------------------------------------------------------- */
1410 static Hash *r_mangled = 0; /* Hash mapping mangled types to fully resolved types */
1411 static Hash *r_resolved = 0; /* Hash mapping resolved types to mangled types */
1412 static Hash *r_ltype = 0; /* Hash mapping mangled names to their local c type */
1413 static Hash *r_clientdata = 0; /* Hash mapping resolved types to client data */
1414 static Hash *r_mangleddata = 0; /* Hash mapping mangled types to client data */
1415 static Hash *r_remembered = 0; /* Hash of types we remembered already */
1417 static void (*r_tracefunc) (SwigType *t, String *mangled, String *clientdata) = 0;
1419 void SwigType_remember_mangleddata(String *mangled, const_String_or_char_ptr clientdata) {
1420 if (!r_mangleddata) {
1421 r_mangleddata = NewHash();
1423 Setattr(r_mangleddata, mangled, clientdata);
1427 void SwigType_remember_clientdata(SwigType *t, const_String_or_char_ptr clientdata) {
1438 r_mangled = NewHash();
1439 r_resolved = NewHash();
1440 r_ltype = NewHash();
1441 r_clientdata = NewHash();
1442 r_remembered = NewHash();
1447 last = Getattr(r_remembered, t);
1448 if (last && (Cmp(last, clientdata) == 0))
1453 cd = clientdata ? NewString(clientdata) : NewStringEmpty();
1454 Setattr(r_remembered, tkey, cd);
1458 mt = SwigType_manglestr(t); /* Create mangled string */
1461 (*r_tracefunc) (t, mt, (String *) clientdata);
1464 if (SwigType_istypedef(t)) {
1467 lt = SwigType_ltype(t);
1470 lthash = Getattr(r_ltype, mt);
1473 Setattr(r_ltype, mt, lthash);
1475 Setattr(lthash, lt, "1");
1478 fr = SwigType_typedef_resolve_all(t); /* Create fully resolved type */
1479 qr = SwigType_typedef_qualified(fr);
1482 /* Added to deal with possible table bug */
1483 fr = SwigType_strip_qualifiers(qr);
1486 /*Printf(stdout,"t = '%s'\n", t);
1487 Printf(stdout,"fr= '%s'\n\n", fr); */
1491 if (strchr(ct, '<') && !(strstr(ct, "<("))) {
1492 Printf(stdout, "Bad template type passed to SwigType_remember: %s\n", t);
1497 h = Getattr(r_mangled, mt);
1500 Setattr(r_mangled, mt, h);
1505 h = Getattr(r_resolved, fr);
1508 Setattr(r_resolved, fr, h);
1514 String *cd = Getattr(r_clientdata, fr);
1516 if (Strcmp(clientdata, cd) != 0) {
1517 Printf(stderr, "*** Internal error. Inconsistent clientdata for type '%s'\n", SwigType_str(fr, 0));
1518 Printf(stderr, "*** '%s' != '%s'\n", clientdata, cd);
1522 String *cstr = NewString(clientdata);
1523 Setattr(r_clientdata, fr, cstr);
1528 /* If the remembered type is a reference, we also remember the pointer version.
1529 This is to prevent odd problems with mixing pointers and references--especially
1530 when different functions are using different typenames (via typedef). */
1532 if (SwigType_isreference(t)) {
1533 SwigType *tt = Copy(t);
1534 SwigType_del_reference(tt);
1535 SwigType_add_pointer(tt);
1536 SwigType_remember_clientdata(tt, clientdata);
1540 void SwigType_remember(SwigType *ty) {
1541 SwigType_remember_clientdata(ty, 0);
1544 void (*SwigType_remember_trace(void (*tf) (SwigType *, String *, String *))) (SwigType *, String *, String *) {
1545 void (*o) (SwigType *, String *, String *) = r_tracefunc;
1550 /* -----------------------------------------------------------------------------
1551 * SwigType_equivalent_mangle()
1553 * Return a list of all of the mangled typenames that are equivalent to another
1554 * mangled name. This works as follows: For each fully qualified C datatype
1555 * in the r_mangled hash entry, we collect all of the mangled names from the
1556 * r_resolved hash and combine them together in a list (removing duplicate entries).
1557 * ----------------------------------------------------------------------------- */
1559 List *SwigType_equivalent_mangle(String *ms, Hash *checked, Hash *found) {
1575 if (Getattr(ch, ms))
1576 goto check_exit; /* Already checked this type */
1577 Setattr(h, ms, "1");
1578 Setattr(ch, ms, "1");
1579 mh = Getattr(r_mangled, ms);
1585 if (Getattr(ch, ki.key)) {
1589 Setattr(ch, ki.key, "1");
1590 rh = Getattr(r_resolved, ki.key);
1595 Setattr(h, rk.key, "1");
1596 SwigType_equivalent_mangle(rk.key, ch, h);
1614 /* -----------------------------------------------------------------------------
1615 * SwigType_clientdata_collect()
1617 * Returns the clientdata field for a mangled type-string.
1618 * ----------------------------------------------------------------------------- */
1621 String *SwigType_clientdata_collect(String *ms) {
1623 String *clientdata = 0;
1625 if (r_mangleddata) {
1626 clientdata = Getattr(r_mangleddata, ms);
1631 mh = Getattr(r_mangled, ms);
1636 clientdata = Getattr(r_clientdata, ki.key);
1648 /* -----------------------------------------------------------------------------
1649 * SwigType_inherit()
1651 * Record information about inheritance. We keep a hash table that keeps
1652 * a mapping between base classes and all of the classes that are derived
1655 * subclass is a hash that maps base-classes to all of the classes derived from them.
1657 * derived - name of derived class
1658 * base - name of base class
1659 * cast - additional casting code when casting from derived to base
1660 * conversioncode - if set, overrides the default code in the function when casting
1661 * from derived to base
1662 * ----------------------------------------------------------------------------- */
1664 static Hash *subclass = 0;
1665 static Hash *conversions = 0;
1667 void SwigType_inherit(String *derived, String *base, String *cast, String *conversioncode) {
1672 subclass = NewHash();
1674 /* Printf(stdout,"'%s' --> '%s' '%s'\n", derived, base, cast); */
1676 if (SwigType_istemplate(derived)) {
1677 String *ty = SwigType_typedef_resolve_all(derived);
1678 dd = SwigType_typedef_qualified(ty);
1682 if (SwigType_istemplate(base)) {
1683 String *ty = SwigType_typedef_resolve_all(base);
1684 bb = SwigType_typedef_qualified(ty);
1689 /* Printf(stdout,"'%s' --> '%s' '%s'\n", derived, base, cast); */
1691 h = Getattr(subclass, base);
1694 Setattr(subclass, base, h);
1697 if (!Getattr(h, derived)) {
1698 Hash *c = NewHash();
1700 Setattr(c, "cast", cast);
1702 Setattr(c, "convcode", conversioncode);
1703 Setattr(h, derived, c);
1711 /* -----------------------------------------------------------------------------
1712 * SwigType_issubtype()
1714 * Determines if a t1 is a subtype of t2, ie, is t1 derived from t2
1715 * ----------------------------------------------------------------------------- */
1717 int SwigType_issubtype(SwigType *t1, SwigType *t2) {
1718 SwigType *ft1, *ft2;
1726 ft1 = SwigType_typedef_resolve_all(t1);
1727 ft2 = SwigType_typedef_resolve_all(t2);
1728 b1 = SwigType_base(ft1);
1729 b2 = SwigType_base(ft2);
1731 h = Getattr(subclass, b2);
1733 if (Getattr(h, b1)) {
1741 /* Printf(stdout, "issubtype(%s,%s) --> %d\n", t1, t2, r); */
1745 /* -----------------------------------------------------------------------------
1746 * SwigType_inherit_equiv()
1748 * Modify the type table to handle C++ inheritance
1749 * ----------------------------------------------------------------------------- */
1751 void SwigType_inherit_equiv(File *out) {
1753 String *prefix, *base;
1754 String *mprefix, *mkey;
1758 Iterator rk, bk, ck;
1761 conversions = NewHash();
1763 subclass = NewHash();
1765 rk = First(r_resolved);
1767 /* rkey is a fully qualified type. We strip all of the type constructors off of it just to get the base */
1768 base = SwigType_base(rk.key);
1769 /* Check to see whether the base is recorded in the subclass table */
1770 sub = Getattr(subclass, base);
1777 /* This type has subclasses. We now need to walk through these subtypes and generate pointer converion functions */
1779 rh = Getattr(r_resolved, rk.key);
1781 for (ck = First(rh); ck.key; ck = Next(ck)) {
1782 Append(rlist, ck.key);
1784 /* Printf(stdout,"rk.key = '%s'\n", rk.key);
1785 Printf(stdout,"rh = %x '%s'\n", rh,rh); */
1789 prefix = SwigType_prefix(rk.key);
1790 Append(prefix, bk.key);
1791 /* Printf(stdout,"set %x = '%s' : '%s'\n", rh, SwigType_manglestr(prefix),prefix); */
1792 mprefix = SwigType_manglestr(prefix);
1793 Setattr(rh, mprefix, prefix);
1794 mkey = SwigType_manglestr(rk.key);
1795 ckey = NewStringf("%s+%s", mprefix, mkey);
1796 if (!Getattr(conversions, ckey)) {
1797 String *convname = NewStringf("%sTo%s", mprefix, mkey);
1798 String *lkey = SwigType_lstr(rk.key, 0);
1799 String *lprefix = SwigType_lstr(prefix, 0);
1800 Hash *subhash = Getattr(sub, bk.key);
1801 String *convcode = Getattr(subhash, "convcode");
1803 char *newmemoryused = Strstr(convcode, "newmemory"); /* see if newmemory parameter is used in order to avoid unused parameter warnings */
1804 String *fn = Copy(convcode);
1805 Replaceall(fn, "$from", "x");
1806 Printf(out, "static void *%s(void *x, int *%s) {", convname, newmemoryused ? "newmemory" : "SWIGUNUSEDPARM(newmemory)");
1807 Printf(out, "%s", fn);
1809 String *cast = Getattr(subhash, "cast");
1810 Printf(out, "static void *%s(void *x, int *SWIGUNUSEDPARM(newmemory)) {", convname);
1811 Printf(out, "\n return (void *)((%s) ", lkey);
1813 Printf(out, "%s", cast);
1814 Printf(out, " ((%s) x));\n", lprefix);
1817 Setattr(conversions, ckey, convname);
1822 /* This inserts conversions for typedefs */
1824 Hash *r = Getattr(r_resolved, prefix);
1832 /* Make sure this name equivalence is not due to inheritance */
1833 if (Cmp(prefix, Getattr(r, rrk.key)) == 0) {
1834 rkeymangle = Copy(mkey);
1835 ckey = NewStringf("%s+%s", rrk.key, rkeymangle);
1836 if (!Getattr(conversions, ckey)) {
1837 Setattr(conversions, ckey, convname);
1840 for (rlk = First(rlist); rlk.item; rlk = Next(rlk)) {
1841 ckey = NewStringf("%s+%s", rrk.key, rlk.item);
1842 Setattr(conversions, ckey, convname);
1846 /* This is needed to pick up other alternative names for the same type.
1847 Needed to make templates work */
1848 Setattr(rh, rrk.key, rrk.item);
1866 /* Helper function to sort the mangled list */
1867 static int SwigType_compare_mangled(const DOH *a, const DOH *b) {
1868 return strcmp((char *) Data(a), (char *) Data(b));
1871 /* -----------------------------------------------------------------------------
1872 * SwigType_get_sorted_mangled_list()
1874 * Returns the sorted list of mangled type names that should be exported into the
1876 * ----------------------------------------------------------------------------- */
1877 List *SwigType_get_sorted_mangled_list() {
1878 List *l = Keys(r_mangled);
1879 SortList(l, SwigType_compare_mangled);
1884 /* -----------------------------------------------------------------------------
1885 * SwigType_type_table()
1887 * Generate the type-table for the type-checker.
1888 * ----------------------------------------------------------------------------- */
1890 void SwigType_emit_type_table(File *f_forward, File *f_table) {
1892 String *types, *table, *cast, *cast_init, *cast_temp;
1893 Hash *imported_types;
1895 List *table_list = NewList();
1899 r_mangled = NewHash();
1900 r_resolved = NewHash();
1903 Printf(f_table, "\n/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */\n\n");
1905 SwigType_inherit_equiv(f_table);
1909 Printf(stdout, "---r_mangled---\n");
1910 Printf(stdout, "%s\n", r_mangled);
1912 Printf(stdout, "---r_resolved---\n");
1913 Printf(stdout, "%s\n", r_resolved);
1915 Printf(stdout, "---r_ltype---\n");
1916 Printf(stdout, "%s\n", r_ltype);
1918 Printf(stdout, "---subclass---\n");
1919 Printf(stdout, "%s\n", subclass);
1921 Printf(stdout, "---conversions---\n");
1922 Printf(stdout, "%s\n", conversions);
1924 Printf(stdout, "---r_clientdata---\n");
1925 Printf(stdout, "%s\n", r_clientdata);
1928 table = NewStringEmpty();
1929 types = NewStringEmpty();
1930 cast = NewStringEmpty();
1931 cast_init = NewStringEmpty();
1932 imported_types = NewHash();
1934 Printf(table, "static swig_type_info *swig_type_initial[] = {\n");
1935 Printf(cast_init, "static swig_cast_info *swig_cast_initial[] = {\n");
1937 Printf(f_forward, "\n/* -------- TYPES TABLE (BEGIN) -------- */\n\n");
1939 mangled_list = SwigType_get_sorted_mangled_list();
1940 for (ki = First(mangled_list); ki.item; ki = Next(ki)) {
1953 cast_temp = NewStringEmpty();
1955 Printv(types, "static swig_type_info _swigt_", ki.item, " = {", NIL);
1956 Append(table_list, ki.item);
1957 Printf(cast_temp, "static swig_cast_info _swigc_%s[] = {", ki.item);
1960 cd = SwigType_clientdata_collect(ki.item);
1964 lthash = Getattr(r_ltype, ki.item);
1967 ltiter = First(lthash);
1968 while (ltiter.key) {
1970 rt = SwigType_typedef_resolve_all(lt);
1971 /* we save the original type and the fully resolved version */
1972 ln = SwigType_lstr(lt, 0);
1973 rn = SwigType_lstr(rt, 0);
1974 if (Equal(ln, rn)) {
1975 Setattr(nthash, ln, "1");
1977 Setattr(nthash, rn, "1");
1978 Setattr(nthash, ln, "1");
1980 if (SwigType_istemplate(rt)) {
1981 String *dt = Swig_symbol_template_deftype(rt, 0);
1982 String *dn = SwigType_lstr(dt, 0);
1983 if (!Equal(dn, rn) && !Equal(dn, ln)) {
1984 Setattr(nthash, dn, "1");
1990 ltiter = Next(ltiter);
1994 ltiter = First(nthash);
1996 while (ltiter.key) {
1998 Printf(nt, "|%s", ltiter.key);
2000 nt = NewString(ltiter.key);
2002 ltiter = Next(ltiter);
2006 Printf(types, "\"%s\", \"%s\", 0, 0, (void*)%s, 0};\n", ki.item, nt, cd);
2008 el = SwigType_equivalent_mangle(ki.item, 0, 0);
2009 for (ei = First(el); ei.item; ei = Next(ei)) {
2012 ckey = NewStringf("%s+%s", ei.item, ki.item);
2013 conv = Getattr(conversions, ckey);
2015 Printf(cast_temp, " {&_swigt_%s, %s, 0, 0},", ei.item, conv);
2017 Printf(cast_temp, " {&_swigt_%s, 0, 0, 0},", ei.item);
2021 if (!Getattr(r_mangled, ei.item) && !Getattr(imported_types, ei.item)) {
2022 Printf(types, "static swig_type_info _swigt_%s = {\"%s\", 0, 0, 0, 0, 0};\n", ei.item, ei.item);
2023 Append(table_list, ei.item);
2025 Printf(cast, "static swig_cast_info _swigc_%s[] = {{&_swigt_%s, 0, 0, 0},{0, 0, 0, 0}};\n", ei.item, ei.item);
2028 Setattr(imported_types, ei.item, "1");
2032 Printf(cast, "%s{0, 0, 0, 0}};\n", cast_temp);
2037 /* print the tables in the proper order */
2038 SortList(table_list, SwigType_compare_mangled);
2040 for (ki = First(table_list); ki.item; ki = Next(ki)) {
2041 Printf(f_forward, "#define SWIGTYPE%s swig_types[%d]\n", ki.item, i++);
2042 Printf(table, " &_swigt_%s,\n", ki.item);
2043 Printf(cast_init, " _swigc_%s,\n", ki.item);
2046 /* empty arrays are not allowed by ISO C */
2047 Printf(table, " NULL\n");
2048 Printf(cast_init, " NULL\n");
2053 Delete(mangled_list);
2055 Printf(table, "};\n");
2056 Printf(cast_init, "};\n");
2057 Printf(f_table, "%s\n", types);
2058 Printf(f_table, "%s\n", table);
2059 Printf(f_table, "%s\n", cast);
2060 Printf(f_table, "%s\n", cast_init);
2061 Printf(f_table, "\n/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */\n\n");
2063 Printf(f_forward, "static swig_type_info *swig_types[%d];\n", i + 1);
2064 Printf(f_forward, "static swig_module_info swig_module = {swig_types, %d, 0, 0, 0, 0};\n", i);
2065 Printf(f_forward, "#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)\n");
2066 Printf(f_forward, "#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)\n");
2067 Printf(f_forward, "\n/* -------- TYPES TABLE (END) -------- */\n\n");
2073 Delete(imported_types);