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 * YACC parser for SWIG. The grammar is a somewhat broken subset of C/C++.
8 * This file is a bit of a mess and probably needs to be rewritten at
10 * ----------------------------------------------------------------------------- */
16 char cvsroot_parser_y[] = "$Id: parser.y 11582 2009-08-15 10:40:19Z wsfulton $";
20 #include "preprocessor.h"
23 /* We do this for portability */
27 /* -----------------------------------------------------------------------------
29 * ----------------------------------------------------------------------------- */
35 static Node *top = 0; /* Top of the generated parse tree */
36 static int unnamed = 0; /* Unnamed datatype counter */
37 static Hash *extendhash = 0; /* Hash table of added methods */
38 static Hash *classes = 0; /* Hash table of classes */
39 static Symtab *prev_symtab = 0;
40 static Node *current_class = 0;
41 String *ModuleName = 0;
42 static Node *module_node = 0;
43 static String *Classprefix = 0;
44 static String *Namespaceprefix = 0;
45 static int inclass = 0;
46 static char *last_cpptype = 0;
47 static int inherit_list = 0;
48 static Parm *template_parameters = 0;
49 static int extendmode = 0;
50 static int compact_default_args = 0;
51 static int template_reduce = 0;
52 static int cparse_externc = 0;
54 static int max_class_levels = 0;
55 static int class_level = 0;
56 static Node **class_decl = NULL;
58 /* -----------------------------------------------------------------------------
60 * ----------------------------------------------------------------------------- */
64 /* Called by the parser (yyparse) when an error is found.*/
65 static void yyerror (const char *e) {
69 static Node *new_node(const_String_or_char_ptr tag) {
72 Setfile(n,cparse_file);
73 Setline(n,cparse_line);
77 /* Copies a node. Does not copy tree links or symbol table data (except for
80 static Node *copy_node(Node *n) {
84 Setfile(nn,Getfile(n));
85 Setline(nn,Getline(n));
86 for (k = First(n); k.key; k = Next(k)) {
89 char *ckey = Char(key);
90 if ((strcmp(ckey,"nextSibling") == 0) ||
91 (strcmp(ckey,"previousSibling") == 0) ||
92 (strcmp(ckey,"parentNode") == 0) ||
93 (strcmp(ckey,"lastChild") == 0)) {
96 if (Strncmp(key,"csym:",5) == 0) continue;
97 /* We do copy sym:name. For templates */
98 if ((strcmp(ckey,"sym:name") == 0) ||
99 (strcmp(ckey,"sym:weak") == 0) ||
100 (strcmp(ckey,"sym:typename") == 0)) {
101 String *ci = Copy(k.item);
106 if (strcmp(ckey,"sym:symtab") == 0) {
107 Setattr(nn,"sym:needs_symtab", "1");
109 /* We don't copy any other symbol table attributes */
110 if (strncmp(ckey,"sym:",4) == 0) {
113 /* If children. We copy them recursively using this function */
114 if (strcmp(ckey,"firstChild") == 0) {
118 Node *copy = copy_node(cn);
119 appendChild(nn,copy);
121 cn = nextSibling(cn);
125 /* We don't copy the symbol table. But we drop an attribute
126 requires_symtab so that functions know it needs to be built */
128 if (strcmp(ckey,"symtab") == 0) {
129 /* Node defined a symbol table. */
130 Setattr(nn,"requires_symtab","1");
133 /* Can't copy nodes */
134 if (strcmp(ckey,"node") == 0) {
137 if ((strcmp(ckey,"parms") == 0) || (strcmp(ckey,"pattern") == 0) || (strcmp(ckey,"throws") == 0)
138 || (strcmp(ckey,"kwargs") == 0)) {
139 ParmList *pl = CopyParmList(k.item);
144 /* Looks okay. Just copy the data using Copy */
146 Setattr(nn, key, ci);
152 /* -----------------------------------------------------------------------------
154 * ----------------------------------------------------------------------------- */
156 static char *typemap_lang = 0; /* Current language setting */
158 static int cplus_mode = 0;
159 static String *class_rename = 0;
163 #define CPLUS_PUBLIC 1
164 #define CPLUS_PRIVATE 2
165 #define CPLUS_PROTECTED 3
168 static int import_mode = 0;
170 void SWIG_typemap_lang(const char *tm_lang) {
171 typemap_lang = Swig_copy_string(tm_lang);
174 void SWIG_cparse_set_compact_default_args(int defargs) {
175 compact_default_args = defargs;
178 int SWIG_cparse_template_reduce(int treduce) {
179 template_reduce = treduce;
183 /* -----------------------------------------------------------------------------
185 * ----------------------------------------------------------------------------- */
187 static int promote_type(int t) {
188 if (t <= T_UCHAR || t == T_CHAR) return T_INT;
192 /* Perform type-promotion for binary operators */
193 static int promote(int t1, int t2) {
194 t1 = promote_type(t1);
195 t2 = promote_type(t2);
196 return t1 > t2 ? t1 : t2;
199 static String *yyrename = 0;
201 /* Forward renaming operator */
203 static String *resolve_node_scope(String *cname);
206 Hash *Swig_cparse_features(void) {
207 static Hash *features_hash = 0;
208 if (!features_hash) features_hash = NewHash();
209 return features_hash;
212 static String *feature_identifier_fix(String *s) {
213 if (SwigType_istemplate(s)) {
214 String *tp, *ts, *ta, *tq;
215 tp = SwigType_templateprefix(s);
216 ts = SwigType_templatesuffix(s);
217 ta = SwigType_templateargs(s);
218 tq = Swig_symbol_type_qualify(ta,0);
230 /* Generate the symbol table name for an object */
231 /* This is a bit of a mess. Need to clean up */
232 static String *add_oldname = 0;
236 static String *make_name(Node *n, String *name,SwigType *decl) {
237 int destructor = name && (*(Char(name)) == '~');
240 String *s = NewString(yyrename);
243 if (destructor && (*(Char(s)) != '~')) {
250 return Swig_name_make(n,Namespaceprefix,name,decl,add_oldname);
253 /* Generate an unnamed identifier */
254 static String *make_unnamed() {
256 return NewStringf("$unnamed%d$",unnamed);
259 /* Return if the node is a friend declaration */
260 static int is_friend(Node *n) {
261 return Cmp(Getattr(n,"storage"),"friend") == 0;
264 static int is_operator(String *name) {
265 return Strncmp(name,"operator ", 9) == 0;
269 /* Add declaration list to symbol table */
270 static int add_only_one = 0;
272 static void add_symbols(Node *n) {
276 cparse_normalize_void(n);
280 /* for friends, we need to pop the scope once */
281 String *old_prefix = 0;
282 Symtab *old_scope = 0;
283 int isfriend = inclass && is_friend(n);
284 int iscdecl = Cmp(nodeType(n),"cdecl") == 0;
285 int only_csymbol = 0;
287 Setattr(n,"isextension","1");
291 String *name = Getattr(n, "name");
293 /* for friends, we need to add the scopename if needed */
294 String *prefix = name ? Swig_scopename_prefix(name) : 0;
295 old_prefix = Namespaceprefix;
296 old_scope = Swig_symbol_popscope();
297 Namespaceprefix = Swig_symbol_qualifiedscopename(0);
299 if (name && !is_operator(name) && Namespaceprefix) {
300 String *nname = NewStringf("%s::%s", Namespaceprefix, name);
301 Setattr(n,"name",nname);
305 Symtab *st = Swig_symbol_getscope(prefix);
306 String *ns = st ? Getattr(st,"name") : prefix;
307 String *base = Swig_scopename_last(name);
308 String *nname = NewStringf("%s::%s", ns, base);
309 Setattr(n,"name",nname);
316 /* for member functions, we need to remove the redundant
317 class scope if provided, as in
320 int Foo::method(int a);
324 String *prefix = name ? Swig_scopename_prefix(name) : 0;
326 if (Classprefix && (Equal(prefix,Classprefix))) {
327 String *base = Swig_scopename_last(name);
328 Setattr(n,"name",base);
335 if (!Getattr(n,"parentNode") && class_level) set_parentNode(n,class_decl[class_level - 1]);
337 Setattr(n,"ismember","1");
340 if (!isfriend && inclass) {
341 if ((cplus_mode != CPLUS_PUBLIC)) {
343 if (cplus_mode == CPLUS_PROTECTED) {
344 Setattr(n,"access", "protected");
345 only_csymbol = !Swig_need_protected(n);
347 Setattr(n,"access", "private");
348 /* private are needed only when they are pure virtuals - why? */
349 if ((Cmp(Getattr(n,"storage"),"virtual") == 0) && (Cmp(Getattr(n,"value"),"0") == 0)) {
354 Setattr(n,"access", "public");
357 if (Getattr(n,"sym:name")) {
361 decl = Getattr(n,"decl");
362 if (!SwigType_isfunction(decl)) {
363 String *name = Getattr(n,"name");
364 String *makename = Getattr(n,"parser:makename");
366 String *storage = Getattr(n, "storage");
367 if (Cmp(storage,"typedef") == 0) {
368 Setattr(n,"kind","typedef");
370 SwigType *type = Getattr(n,"type");
371 String *value = Getattr(n,"value");
372 Setattr(n,"kind","variable");
373 if (value && Len(value)) {
374 Setattr(n,"hasvalue","1");
380 ty = tmp = Copy(type);
381 SwigType_push(ty,decl);
385 if (!SwigType_ismutable(ty)) {
386 SetFlag(n,"hasconsttype");
387 SetFlag(n,"feature:immutable");
389 if (tmp) Delete(tmp);
392 Printf(stderr,"notype name %s\n", name);
396 Swig_features_get(Swig_cparse_features(), Namespaceprefix, name, 0, n);
398 symname = make_name(n, makename,0);
399 Delattr(n,"parser:makename"); /* temporary information, don't leave it hanging around */
402 symname = make_name(n, makename,0);
406 symname = Copy(Getattr(n,"unnamed"));
409 wrn = Swig_name_warning(n, Namespaceprefix, symname,0);
412 String *name = Getattr(n,"name");
413 SwigType *fdecl = Copy(decl);
414 SwigType *fun = SwigType_pop_function(fdecl);
416 Setattr(n,"kind","function");
419 Swig_features_get(Swig_cparse_features(),Namespaceprefix,name,fun,n);
421 symname = make_name(n, name,fun);
422 wrn = Swig_name_warning(n, Namespaceprefix,symname,fun);
432 if (only_csymbol || GetFlag(n,"feature:ignore")) {
433 /* Only add to C symbol table and continue */
434 Swig_symbol_add(0, n);
435 } else if (strncmp(Char(symname),"$ignore",7) == 0) {
436 char *c = Char(symname)+7;
437 SetFlag(n,"feature:ignore");
439 SWIG_WARN_NODE_BEGIN(n);
440 Swig_warning(0,Getfile(n), Getline(n), "%s\n",c+1);
441 SWIG_WARN_NODE_END(n);
443 Swig_symbol_add(0, n);
446 if ((wrn) && (Len(wrn))) {
447 String *metaname = symname;
448 if (!Getmeta(metaname,"already_warned")) {
449 SWIG_WARN_NODE_BEGIN(n);
450 Swig_warning(0,Getfile(n),Getline(n), "%s\n", wrn);
451 SWIG_WARN_NODE_END(n);
452 Setmeta(metaname,"already_warned","1");
455 c = Swig_symbol_add(symname,n);
458 /* symbol conflict attempting to add in the new symbol */
459 if (Getattr(n,"sym:weak")) {
460 Setattr(n,"sym:name",symname);
462 String *e = NewStringEmpty();
463 String *en = NewStringEmpty();
464 String *ec = NewStringEmpty();
465 int redefined = Swig_need_redefined_warn(n,c,inclass);
467 Printf(en,"Identifier '%s' redefined (ignored)",symname);
468 Printf(ec,"previous definition of '%s'",symname);
470 Printf(en,"Redundant redeclaration of '%s'",symname);
471 Printf(ec,"previous declaration of '%s'",symname);
473 if (Cmp(symname,Getattr(n,"name"))) {
474 Printf(en," (Renamed from '%s')", SwigType_namestr(Getattr(n,"name")));
477 if (Cmp(symname,Getattr(c,"name"))) {
478 Printf(ec," (Renamed from '%s')", SwigType_namestr(Getattr(c,"name")));
481 SWIG_WARN_NODE_BEGIN(n);
483 Swig_warning(WARN_PARSE_REDEFINED,Getfile(n),Getline(n),"%s\n",en);
484 Swig_warning(WARN_PARSE_REDEFINED,Getfile(c),Getline(c),"%s\n",ec);
485 } else if (!is_friend(n) && !is_friend(c)) {
486 Swig_warning(WARN_PARSE_REDUNDANT,Getfile(n),Getline(n),"%s\n",en);
487 Swig_warning(WARN_PARSE_REDUNDANT,Getfile(c),Getline(c),"%s\n",ec);
489 SWIG_WARN_NODE_END(n);
490 Printf(e,"%s:%d:%s\n%s:%d:%s\n",Getfile(n),Getline(n),en,
491 Getfile(c),Getline(c),ec);
492 Setattr(n,"error",e);
499 /* restore the class scope if needed */
501 Swig_symbol_setscope(old_scope);
503 Delete(Namespaceprefix);
504 Namespaceprefix = old_prefix;
509 if (add_only_one) return;
515 /* add symbols a parse tree node copy */
517 static void add_symbols_copy(Node *n) {
521 char *cnodeType = Char(nodeType(n));
523 if (strcmp(cnodeType,"access") == 0) {
524 String *kind = Getattr(n,"kind");
525 if (Strcmp(kind,"public") == 0) {
526 cplus_mode = CPLUS_PUBLIC;
527 } else if (Strcmp(kind,"private") == 0) {
528 cplus_mode = CPLUS_PRIVATE;
529 } else if (Strcmp(kind,"protected") == 0) {
530 cplus_mode = CPLUS_PROTECTED;
536 add_oldname = Getattr(n,"sym:name");
537 if ((add_oldname) || (Getattr(n,"sym:needs_symtab"))) {
539 DohIncref(add_oldname);
540 /* Disable this, it prevents %rename to work with templates */
541 /* If already renamed, we used that name */
543 if (Strcmp(add_oldname, Getattr(n,"name")) != 0) {
545 yyrename = Copy(add_oldname);
549 Delattr(n,"sym:needs_symtab");
550 Delattr(n,"sym:name");
555 if (Getattr(n,"partialargs")) {
556 Swig_symbol_cadd(Getattr(n,"partialargs"),n);
559 name = Getattr(n,"name");
560 if (Getattr(n,"requires_symtab")) {
561 Swig_symbol_newscope();
562 Swig_symbol_setscopename(name);
563 Delete(Namespaceprefix);
564 Namespaceprefix = Swig_symbol_qualifiedscopename(0);
566 if (strcmp(cnodeType,"class") == 0) {
569 if (Strcmp(Getattr(n,"kind"),"class") == 0) {
570 cplus_mode = CPLUS_PRIVATE;
572 cplus_mode = CPLUS_PUBLIC;
575 if (strcmp(cnodeType,"extend") == 0) {
577 cplus_mode = CPLUS_PUBLIC;
579 add_symbols_copy(firstChild(n));
580 if (strcmp(cnodeType,"extend") == 0) {
583 if (Getattr(n,"requires_symtab")) {
584 Setattr(n,"symtab", Swig_symbol_popscope());
585 Delattr(n,"requires_symtab");
586 Delete(Namespaceprefix);
587 Namespaceprefix = Swig_symbol_qualifiedscopename(0);
593 if (strcmp(cnodeType,"class") == 0) {
598 if (strcmp(cnodeType,"extend") == 0) {
600 cplus_mode = CPLUS_PUBLIC;
602 add_symbols_copy(firstChild(n));
603 if (strcmp(cnodeType,"extend") == 0) {
611 /* Extension merge. This function is used to handle the %extend directive
612 when it appears before a class definition. To handle this, the %extend
613 actually needs to take precedence. Therefore, we will selectively nuke symbols
614 from the current symbol table, replacing them with the added methods */
616 static void merge_extensions(Node *cls, Node *am) {
623 if (Strcmp(nodeType(n),"constructor") == 0) {
624 symname = Getattr(n,"sym:name");
626 if (Strcmp(symname,Getattr(n,"name")) == 0) {
627 /* If the name and the sym:name of a constructor are the same,
628 then it hasn't been renamed. However---the name of the class
629 itself might have been renamed so we need to do a consistency
631 if (Getattr(cls,"sym:name")) {
632 Setattr(n,"sym:name", Getattr(cls,"sym:name"));
638 symname = Getattr(n,"sym:name");
640 if ((symname) && (!Getattr(n,"error"))) {
641 /* Remove node from its symbol table */
642 Swig_symbol_remove(n);
643 csym = Swig_symbol_add(symname,n);
645 /* Conflict with previous definition. Nuke previous definition */
646 String *e = NewStringEmpty();
647 String *en = NewStringEmpty();
648 String *ec = NewStringEmpty();
649 Printf(ec,"Identifier '%s' redefined by %%extend (ignored),",symname);
650 Printf(en,"%%extend definition of '%s'.",symname);
651 SWIG_WARN_NODE_BEGIN(n);
652 Swig_warning(WARN_PARSE_REDEFINED,Getfile(csym),Getline(csym),"%s\n",ec);
653 Swig_warning(WARN_PARSE_REDEFINED,Getfile(n),Getline(n),"%s\n",en);
654 SWIG_WARN_NODE_END(n);
655 Printf(e,"%s:%d:%s\n%s:%d:%s\n",Getfile(csym),Getline(csym),ec,
656 Getfile(n),Getline(n),en);
657 Setattr(csym,"error",e);
661 Swig_symbol_remove(csym); /* Remove class definition */
662 Swig_symbol_add(symname,n); /* Insert extend definition */
669 static void append_previous_extension(Node *cls, Node *am) {
679 set_nextSibling(n,0);
680 /* typemaps and fragments need to be prepended */
681 if (((Cmp(nodeType(n),"typemap") == 0) || (Cmp(nodeType(n),"fragment") == 0))) {
682 if (!pe) pe = new_node("extend");
685 if (!ae) ae = new_node("extend");
690 if (pe) prependChild(cls,pe);
691 if (ae) appendChild(cls,ae);
695 /* Check for unused %extend. Special case, don't report unused
696 extensions for templates */
698 static void check_extensions() {
701 if (!extendhash) return;
702 for (ki = First(extendhash); ki.key; ki = Next(ki)) {
703 if (!Strchr(ki.key,'<')) {
704 SWIG_WARN_NODE_BEGIN(ki.item);
705 Swig_warning(WARN_PARSE_EXTEND_UNDEF,Getfile(ki.item), Getline(ki.item), "%%extend defined for an undeclared class %s.\n", ki.key);
706 SWIG_WARN_NODE_END(ki.item);
711 /* Check a set of declarations to see if any are pure-abstract */
713 static List *pure_abstract(Node *n) {
716 if (Cmp(nodeType(n),"cdecl") == 0) {
717 String *decl = Getattr(n,"decl");
718 if (SwigType_isfunction(decl)) {
719 String *init = Getattr(n,"value");
720 if (Cmp(init,"0") == 0) {
725 Setattr(n,"abstract","1");
728 } else if (Cmp(nodeType(n),"destructor") == 0) {
729 if (Cmp(Getattr(n,"value"),"0") == 0) {
734 Setattr(n,"abstract","1");
742 /* Make a classname */
744 static String *make_class_name(String *name) {
746 if (Namespaceprefix) {
747 nname= NewStringf("%s::%s", Namespaceprefix, name);
749 nname = NewString(name);
751 if (SwigType_istemplate(nname)) {
752 String *prefix, *args, *qargs;
753 prefix = SwigType_templateprefix(nname);
754 args = SwigType_templateargs(nname);
755 qargs = Swig_symbol_type_qualify(args,0);
756 Append(prefix,qargs);
765 static List *make_inherit_list(String *clsname, List *names) {
768 List *bases = NewList();
770 if (Namespaceprefix) derived = NewStringf("%s::%s", Namespaceprefix,clsname);
771 else derived = NewString(clsname);
774 for (i = 0; i < ilen; i++) {
777 String *n = Getitem(names,i);
778 /* Try to figure out where this symbol is */
779 s = Swig_symbol_clookup(n,0);
781 while (s && (Strcmp(nodeType(s),"class") != 0)) {
782 /* Not a class. Could be a typedef though. */
783 String *storage = Getattr(s,"storage");
784 if (storage && (Strcmp(storage,"typedef") == 0)) {
785 String *nn = Getattr(s,"type");
786 s = Swig_symbol_clookup(nn,Getattr(s,"sym:symtab"));
791 if (s && ((Strcmp(nodeType(s),"class") == 0) || (Strcmp(nodeType(s),"template") == 0))) {
792 String *q = Swig_symbol_qualified(s);
795 base = NewStringf("%s::%s", q, Getattr(s,"name"));
798 base = NewString(Getattr(s,"name"));
807 Swig_name_inherit(base,derived);
814 /* If the class name is qualified. We need to create or lookup namespace entries */
816 static Symtab *get_global_scope() {
817 Symtab *symtab = Swig_symbol_current();
818 Node *pn = parentNode(symtab);
821 pn = parentNode(symtab);
824 Swig_symbol_setscope(symtab);
828 /* Remove the block braces, { and }, if the 'noblock' attribute is set.
829 * Node *kw can be either a Hash or Parmlist. */
830 static String *remove_block(Node *kw, const String *inputcode) {
831 String *modified_code = 0;
833 String *name = Getattr(kw,"name");
834 if (name && (Cmp(name,"noblock") == 0)) {
835 char *cstr = Char(inputcode);
836 size_t len = Len(inputcode);
837 if (len && cstr[0] == '{') {
839 if (len && cstr[len - 1] == '}') { --len; }
840 /* we now remove the extra spaces */
841 while (len && isspace((int)cstr[0])) { --len; ++cstr; }
842 while (len && isspace((int)cstr[len - 1])) { --len; }
843 modified_code = NewStringWithSize(cstr, len);
847 kw = nextSibling(kw);
849 return modified_code;
853 static Node *nscope = 0;
854 static Node *nscope_inner = 0;
855 static String *resolve_node_scope(String *cname) {
859 if (Swig_scopename_check(cname)) {
861 String *prefix = Swig_scopename_prefix(cname);
862 String *base = Swig_scopename_last(cname);
863 if (prefix && (Strncmp(prefix,"::",2) == 0)) {
864 /* Use the global scope */
865 String *nprefix = NewString(Char(prefix)+2);
868 gscope = get_global_scope();
870 if (!prefix || (Len(prefix) == 0)) {
871 /* Use the global scope, but we need to add a 'global' namespace. */
872 if (!gscope) gscope = get_global_scope();
873 /* note that this namespace is not the "unnamed" one,
874 and we don't use Setattr(nscope,"name", ""),
875 because the unnamed namespace is private */
876 nscope = new_node("namespace");
877 Setattr(nscope,"symtab", gscope);;
878 nscope_inner = nscope;
881 /* Try to locate the scope */
882 ns = Swig_symbol_clookup(prefix,0);
884 Swig_error(cparse_file,cparse_line,"Undefined scope '%s'\n", prefix);
886 Symtab *nstab = Getattr(ns,"symtab");
888 Swig_error(cparse_file,cparse_line,
889 "'%s' is not defined as a valid scope.\n", prefix);
892 /* Check if the node scope is the current scope */
893 String *tname = Swig_symbol_qualifiedscopename(0);
894 String *nname = Swig_symbol_qualifiedscopename(nstab);
895 if (tname && (Strcmp(tname,nname) == 0)) {
903 /* we will try to create a new node using the namespaces we
904 can find in the scope name */
908 String *name = NewString(prefix);
911 String *base = Swig_scopename_last(name);
912 String *tprefix = Swig_scopename_prefix(name);
913 Insert(scopes,0,base);
918 for (si = First(scopes); si.item; si = Next(si)) {
921 ns1 = Swig_symbol_clookup(sname,0);
923 if (Strcmp(nodeType(ns1),"namespace") == 0) {
924 if (Getattr(ns1,"alias")) {
925 ns1 = Getattr(ns1,"namespace");
928 /* now this last part is a class */
930 ns1 = Swig_symbol_clookup(sname,0);
931 /* or a nested class tree, which is unrolled here */
932 for (; si.item; si = Next(si)) {
934 Printf(sname,"::%s",si.item);
937 /* we get the 'inner' class */
938 nscope_inner = Swig_symbol_clookup(sname,0);
939 /* set the scope to the inner class */
940 Swig_symbol_setscope(Getattr(nscope_inner,"symtab"));
941 /* save the last namespace prefix */
942 Delete(Namespaceprefix);
943 Namespaceprefix = Swig_symbol_qualifiedscopename(0);
944 /* and return the node name, including the inner class prefix */
947 /* here we just populate the namespace tree as usual */
948 ns2 = new_node("namespace");
949 Setattr(ns2,"name",sname);
950 Setattr(ns2,"symtab", Getattr(ns1,"symtab"));
952 Swig_symbol_setscope(Getattr(ns1,"symtab"));
953 Delete(Namespaceprefix);
954 Namespaceprefix = Swig_symbol_qualifiedscopename(0);
956 if (Getattr(nscope_inner,"symtab") != Getattr(ns2,"symtab")) {
957 appendChild(nscope_inner,ns2);
962 if (!nscope) nscope = ns2;
977 /* Structures for handling code fragments built for nested classes */
979 typedef struct Nested {
980 String *code; /* Associated code fragment */
981 int line; /* line number where it starts */
982 char *name; /* Name associated with this nested class */
983 char *kind; /* Kind of class */
984 int unnamed; /* unnamed class */
985 SwigType *type; /* Datatype associated with the name */
986 struct Nested *next; /* Next code fragment in list */
989 /* Some internal variables for saving nested class information */
991 static Nested *nested_list = 0;
993 /* Add a function to the nested list */
995 static void add_nested(Nested *n) {
997 if (!nested_list) nested_list = n;
1000 while (n1->next) n1 = n1->next;
1005 /* Strips C-style and C++-style comments from string in-place. */
1006 static void strip_comments(char *string) {
1008 * 0 - not in comment
1009 * 1 - in c-style comment
1010 * 2 - in c++-style comment
1012 * 4 - after reading / not in comments
1013 * 5 - after reading * in c-style comments
1014 * 6 - after reading \ in strings
1039 else if (*c == '\\')
1047 } else if (*c == '*') {
1069 /* Dump all of the nested class declarations to the inline processor
1070 * However. We need to do a few name replacements and other munging
1071 * first. This function must be called before closing a class! */
1073 static Node *dump_nested(const char *parent) {
1084 /* Token replace the name of the parent class */
1085 Replace(n->code, "$classname", parent, DOH_REPLACE_ANY);
1087 /* Fix up the name of the datatype (for building typedefs and other stuff) */
1088 Append(n->type,parent);
1089 Append(n->type,"_");
1090 Append(n->type,n->name);
1092 /* Add the appropriate declaration to the C++ processor */
1093 retx = new_node("cdecl");
1094 Setattr(retx,"name",n->name);
1096 Setattr(retx,"type",nt);
1098 Setattr(retx,"nested",parent);
1100 Setattr(retx,"unnamed","1");
1105 set_nextSibling(retx,ret);
1110 /* Insert a forward class declaration */
1111 /* Disabled: [ 597599 ] union in class: incorrect scope
1112 retx = new_node("classforward");
1113 Setattr(retx,"kind",n->kind);
1114 Setattr(retx,"name",Copy(n->type));
1115 Setattr(retx,"sym:name", make_name(n->type,0));
1116 set_nextSibling(retx,ret);
1120 /* Strip comments - further code may break in presence of comments. */
1121 strip_comments(Char(n->code));
1123 /* Make all SWIG created typedef structs/unions/classes unnamed else
1124 redefinition errors occur - nasty hack alert.*/
1127 const char* types_array[3] = {"struct", "union", "class"};
1129 for (i=0; i<3; i++) {
1130 char* code_ptr = Char(n->code);
1132 /* Replace struct name (as in 'struct name {...}' ) with whitespace
1133 name will be between struct and opening brace */
1135 code_ptr = strstr(code_ptr, types_array[i]);
1137 char *open_bracket_pos;
1138 code_ptr += strlen(types_array[i]);
1139 open_bracket_pos = strchr(code_ptr, '{');
1140 if (open_bracket_pos) {
1141 /* Make sure we don't have something like struct A a; */
1142 char* semi_colon_pos = strchr(code_ptr, ';');
1143 if (!(semi_colon_pos && (semi_colon_pos < open_bracket_pos)))
1144 while (code_ptr < open_bracket_pos)
1153 /* Remove SWIG directive %constant which may be left in the SWIG created typedefs */
1154 char* code_ptr = Char(n->code);
1156 code_ptr = strstr(code_ptr, "%constant");
1158 char* directive_end_pos = strchr(code_ptr, ';');
1159 if (directive_end_pos) {
1160 while (code_ptr <= directive_end_pos)
1167 Node *head = new_node("insert");
1168 String *code = NewStringf("\n%s\n",n->code);
1169 Setattr(head,"code", code);
1171 set_nextSibling(head,ret);
1176 /* Dump the code to the scanner */
1177 start_inline(Char(n->code),n->line);
1188 Node *Swig_cparse(File *f) {
1195 static void single_new_feature(const char *featurename, String *val, Hash *featureattribs, char *declaratorid, SwigType *type, ParmList *declaratorparms, String *qualifier) {
1199 SwigType *t = Copy(type);
1201 /* Printf(stdout, "single_new_feature: [%s] [%s] [%s] [%s] [%s] [%s]\n", featurename, val, declaratorid, t, ParmList_str_defaultargs(declaratorparms), qualifier); */
1203 fname = NewStringf("feature:%s",featurename);
1205 fixname = feature_identifier_fix(declaratorid);
1207 fixname = NewStringEmpty();
1209 if (Namespaceprefix) {
1210 name = NewStringf("%s::%s",Namespaceprefix, fixname);
1215 if (declaratorparms) Setmeta(val,"parms",declaratorparms);
1218 if (qualifier) SwigType_push(t,qualifier);
1219 if (SwigType_isfunction(t)) {
1220 SwigType *decl = SwigType_pop_function(t);
1221 if (SwigType_ispointer(t)) {
1222 String *nname = NewStringf("*%s",name);
1223 Swig_feature_set(Swig_cparse_features(), nname, decl, fname, val, featureattribs);
1226 Swig_feature_set(Swig_cparse_features(), name, decl, fname, val, featureattribs);
1229 } else if (SwigType_ispointer(t)) {
1230 String *nname = NewStringf("*%s",name);
1231 Swig_feature_set(Swig_cparse_features(),nname,0,fname,val, featureattribs);
1235 /* Global feature, that is, feature not associated with any particular symbol */
1236 Swig_feature_set(Swig_cparse_features(),name,0,fname,val, featureattribs);
1242 /* Add a new feature to the Hash. Additional features are added if the feature has a parameter list (declaratorparms)
1243 * and one or more of the parameters have a default argument. An extra feature is added for each defaulted parameter,
1244 * simulating the equivalent overloaded method. */
1245 static void new_feature(const char *featurename, String *val, Hash *featureattribs, char *declaratorid, SwigType *type, ParmList *declaratorparms, String *qualifier) {
1247 ParmList *declparms = declaratorparms;
1249 /* remove the { and } braces if the noblock attribute is set */
1250 String *newval = remove_block(featureattribs, val);
1251 val = newval ? newval : val;
1253 /* Add the feature */
1254 single_new_feature(featurename, val, featureattribs, declaratorid, type, declaratorparms, qualifier);
1256 /* Add extra features if there are default parameters in the parameter list */
1259 if (ParmList_has_defaultargs(declparms)) {
1261 /* Create a parameter list for the new feature by copying all
1262 but the last (defaulted) parameter */
1263 ParmList* newparms = CopyParmListMax(declparms, ParmList_len(declparms)-1);
1265 /* Create new declaration - with the last parameter removed */
1266 SwigType *newtype = Copy(type);
1267 Delete(SwigType_pop_function(newtype)); /* remove the old parameter list from newtype */
1268 SwigType_add_function(newtype,newparms);
1270 single_new_feature(featurename, Copy(val), featureattribs, declaratorid, newtype, newparms, qualifier);
1271 declparms = newparms;
1279 /* check if a function declaration is a plain C object */
1280 static int is_cfunction(Node *n) {
1281 if (!cparse_cplusplus || cparse_externc) return 1;
1282 if (Cmp(Getattr(n,"storage"),"externc") == 0) {
1288 /* If the Node is a function with parameters, check to see if any of the parameters
1289 * have default arguments. If so create a new function for each defaulted argument.
1290 * The additional functions form a linked list of nodes with the head being the original Node n. */
1291 static void default_arguments(Node *n) {
1295 ParmList *varargs = Getattr(function,"feature:varargs");
1297 /* Handles the %varargs directive by looking for "feature:varargs" and
1298 * substituting ... with an alternative set of arguments. */
1299 Parm *p = Getattr(function,"parms");
1302 SwigType *t = Getattr(p,"type");
1303 if (Strcmp(t,"v(...)") == 0) {
1305 ParmList *cv = Copy(varargs);
1306 set_nextSibling(pp,cv);
1309 ParmList *cv = Copy(varargs);
1310 Setattr(function,"parms", cv);
1320 /* Do not add in functions if kwargs is being used or if user wants old default argument wrapping
1321 (one wrapped method per function irrespective of number of default arguments) */
1322 if (compact_default_args
1323 || is_cfunction(function)
1324 || GetFlag(function,"feature:compactdefaultargs")
1325 || GetFlag(function,"feature:kwargs")) {
1326 ParmList *p = Getattr(function,"parms");
1328 Setattr(p,"compactdefargs", "1"); /* mark parameters for special handling */
1329 function = 0; /* don't add in extra methods */
1334 ParmList *parms = Getattr(function,"parms");
1335 if (ParmList_has_defaultargs(parms)) {
1337 /* Create a parameter list for the new function by copying all
1338 but the last (defaulted) parameter */
1339 ParmList* newparms = CopyParmListMax(parms,ParmList_len(parms)-1);
1341 /* Create new function and add to symbol table */
1343 SwigType *ntype = Copy(nodeType(function));
1344 char *cntype = Char(ntype);
1345 Node *new_function = new_node(ntype);
1346 SwigType *decl = Copy(Getattr(function,"decl"));
1347 int constqualifier = SwigType_isconst(decl);
1348 String *ccode = Copy(Getattr(function,"code"));
1349 String *cstorage = Copy(Getattr(function,"storage"));
1350 String *cvalue = Copy(Getattr(function,"value"));
1351 SwigType *ctype = Copy(Getattr(function,"type"));
1352 String *cthrow = Copy(Getattr(function,"throw"));
1354 Delete(SwigType_pop_function(decl)); /* remove the old parameter list from decl */
1355 SwigType_add_function(decl,newparms);
1357 SwigType_add_qualifier(decl,"const");
1359 Setattr(new_function,"name", Getattr(function,"name"));
1360 Setattr(new_function,"code", ccode);
1361 Setattr(new_function,"decl", decl);
1362 Setattr(new_function,"parms", newparms);
1363 Setattr(new_function,"storage", cstorage);
1364 Setattr(new_function,"value", cvalue);
1365 Setattr(new_function,"type", ctype);
1366 Setattr(new_function,"throw", cthrow);
1376 Node *throws = Getattr(function,"throws");
1377 ParmList *pl = CopyParmList(throws);
1378 if (throws) Setattr(new_function,"throws",pl);
1382 /* copy specific attributes for global (or in a namespace) template functions - these are not templated class methods */
1383 if (strcmp(cntype,"template") == 0) {
1384 Node *templatetype = Getattr(function,"templatetype");
1385 Node *symtypename = Getattr(function,"sym:typename");
1386 Parm *templateparms = Getattr(function,"templateparms");
1388 Node *tmp = Copy(templatetype);
1389 Setattr(new_function,"templatetype",tmp);
1393 Node *tmp = Copy(symtypename);
1394 Setattr(new_function,"sym:typename",tmp);
1397 if (templateparms) {
1398 Parm *tmp = CopyParmList(templateparms);
1399 Setattr(new_function,"templateparms",tmp);
1402 } else if (strcmp(cntype,"constructor") == 0) {
1403 /* only copied for constructors as this is not a user defined feature - it is hard coded in the parser */
1404 if (GetFlag(function,"feature:new")) SetFlag(new_function,"feature:new");
1407 add_symbols(new_function);
1408 /* mark added functions as ones with overloaded parameters and point to the parsed method */
1409 Setattr(new_function,"defaultargs", n);
1411 /* Point to the new function, extending the linked list */
1412 set_nextSibling(function, new_function);
1413 Delete(new_function);
1414 function = new_function;
1424 /* -----------------------------------------------------------------------------
1427 * Used by the parser to mark subtypes with extra information.
1428 * ----------------------------------------------------------------------------- */
1430 static void tag_nodes(Node *n, const_String_or_char_ptr attrname, DOH *value) {
1432 Setattr(n, attrname, value);
1433 tag_nodes(firstChild(n), attrname, value);
1487 %token <loc> INCLUDE IMPORT INSERT
1488 %token <str> CHARCONST
1489 %token <dtype> NUM_INT NUM_FLOAT NUM_UNSIGNED NUM_LONG NUM_ULONG NUM_LONGLONG NUM_ULONGLONG
1490 %token <ivalue> TYPEDEF
1491 %token <type> TYPE_INT TYPE_UNSIGNED TYPE_SHORT TYPE_LONG TYPE_FLOAT TYPE_DOUBLE TYPE_CHAR TYPE_WCHAR TYPE_VOID TYPE_SIGNED TYPE_BOOL TYPE_COMPLEX TYPE_TYPEDEF TYPE_RAW TYPE_NON_ISO_INT8 TYPE_NON_ISO_INT16 TYPE_NON_ISO_INT32 TYPE_NON_ISO_INT64
1492 %token LPAREN RPAREN COMMA SEMI EXTERN INIT LBRACE RBRACE PERIOD
1493 %token CONST_QUAL VOLATILE REGISTER STRUCT UNION EQUAL SIZEOF MODULE LBRACKET RBRACKET
1494 %token ILLEGAL CONSTANT
1495 %token NAME RENAME NAMEWARN EXTEND PRAGMA FEATURE VARARGS
1497 %token CLASS TYPENAME PRIVATE PUBLIC PROTECTED COLON STATIC VIRTUAL FRIEND THROW CATCH EXPLICIT
1499 %token <node> NAMESPACE
1500 %token NATIVE INLINE
1501 %token TYPEMAP EXCEPT ECHO APPLY CLEAR SWIGTEMPLATE FRAGMENT
1503 %token LESSTHAN GREATERTHAN MODULO DELETE_KW
1504 %token LESSTHANOREQUALTO GREATERTHANOREQUALTO EQUALTO NOTEQUALTO
1507 %token NONID DSTAR DCNOT
1508 %token <ivalue> TEMPLATE
1509 %token <str> OPERATOR
1510 %token <str> COPERATOR
1511 %token PARSETYPE PARSEPARM PARSEPARMS
1520 %left EQUALTO NOTEQUALTO
1521 %left GREATERTHAN LESSTHAN GREATERTHANOREQUALTO LESSTHANOREQUALTO
1524 %left STAR SLASH MODULUS
1525 %left UMINUS NOT LNOT
1528 %type <node> program interface declaration swig_directive ;
1530 /* SWIG directives */
1531 %type <node> extend_directive apply_directive clear_directive constant_directive ;
1532 %type <node> echo_directive except_directive fragment_directive include_directive inline_directive ;
1533 %type <node> insert_directive module_directive name_directive native_directive ;
1534 %type <node> pragma_directive rename_directive feature_directive varargs_directive typemap_directive ;
1535 %type <node> types_directive template_directive warn_directive ;
1537 /* C declarations */
1538 %type <node> c_declaration c_decl c_decl_tail c_enum_decl c_enum_forward_decl c_constructor_decl ;
1539 %type <node> enumlist edecl;
1541 /* C++ declarations */
1542 %type <node> cpp_declaration cpp_class_decl cpp_forward_class_decl cpp_template_decl;
1543 %type <node> cpp_members cpp_member;
1544 %type <node> cpp_constructor_decl cpp_destructor_decl cpp_protection_decl cpp_conversion_operator;
1545 %type <node> cpp_swig_directive cpp_temp_possible cpp_nested cpp_opt_declarators ;
1546 %type <node> cpp_using_decl cpp_namespace_decl cpp_catch_decl ;
1547 %type <node> kwargs options;
1550 %type <dtype> initializer cpp_const ;
1551 %type <id> storage_class;
1552 %type <pl> parms ptail rawparms varargs_parms;
1553 %type <pl> templateparameters templateparameterstail;
1554 %type <p> parm valparm rawvalparms valparms valptail ;
1555 %type <p> typemap_parm tm_list tm_tail ;
1556 %type <p> templateparameter ;
1557 %type <id> templcpptype cpptype access_specifier;
1558 %type <node> base_specifier
1559 %type <type> type rawtype type_right ;
1560 %type <bases> base_list inherit raw_inherit;
1561 %type <dtype> definetype def_args etype;
1562 %type <dtype> expr exprnum exprcompound valexpr;
1564 %type <id> template_decl;
1565 %type <str> type_qualifier ;
1566 %type <id> type_qualifier_raw;
1567 %type <id> idstring idstringopt;
1568 %type <id> pragma_lang;
1569 %type <str> pragma_arg;
1570 %type <loc> includetype;
1571 %type <type> pointer primitive_type;
1572 %type <decl> declarator direct_declarator notso_direct_declarator parameter_declarator typemap_parameter_declarator nested_decl;
1573 %type <decl> abstract_declarator direct_abstract_declarator ctor_end;
1574 %type <tmap> typemap_type;
1575 %type <str> idcolon idcolontail idcolonnt idcolontailnt idtemplate stringbrace stringbracesemi;
1576 %type <id> string stringnum ;
1577 %type <tparms> template_parms;
1578 %type <dtype> cpp_end cpp_vend;
1579 %type <ivalue> rename_namewarn;
1580 %type <ptype> type_specifier primitive_type_list ;
1581 %type <node> fname stringtype;
1582 %type <node> featattr;
1586 /* ======================================================================
1587 * High-level Interface file
1589 * An interface is just a sequence of declarations which may be SWIG directives
1590 * or normal C declarations.
1591 * ====================================================================== */
1593 program : interface {
1594 if (!classes) classes = NewHash();
1595 Setattr($1,"classes",classes);
1596 Setattr($1,"name",ModuleName);
1598 if ((!module_node) && ModuleName) {
1599 module_node = new_node("module");
1600 Setattr(module_node,"name",ModuleName);
1602 Setattr($1,"module",module_node);
1606 | PARSETYPE parm SEMI {
1607 top = Copy(Getattr($2,"type"));
1613 | PARSEPARM parm SEMI {
1619 | PARSEPARMS LPAREN parms RPAREN SEMI {
1622 | PARSEPARMS error SEMI {
1627 interface : interface declaration {
1628 /* add declaration to end of linked list (the declaration isn't always a single declaration, sometimes it is a linked list itself) */
1633 $$ = new_node("top");
1637 declaration : swig_directive { $$ = $1; }
1638 | c_declaration { $$ = $1; }
1639 | cpp_declaration { $$ = $1; }
1643 Swig_error(cparse_file, cparse_line,"Syntax error in input(1).\n");
1646 /* Out of class constructor/destructor declarations */
1647 | c_constructor_decl {
1654 /* Out of class conversion operator. For example:
1655 inline A::operator char *() const { ... }.
1657 This is nearly impossible to parse normally. We just let the
1658 first part generate a syntax error and then resynchronize on the
1659 COPERATOR token---discarding the rest of the definition. Ugh.
1669 /* ======================================================================
1671 * ====================================================================== */
1673 swig_directive : extend_directive { $$ = $1; }
1674 | apply_directive { $$ = $1; }
1675 | clear_directive { $$ = $1; }
1676 | constant_directive { $$ = $1; }
1677 | echo_directive { $$ = $1; }
1678 | except_directive { $$ = $1; }
1679 | fragment_directive { $$ = $1; }
1680 | include_directive { $$ = $1; }
1681 | inline_directive { $$ = $1; }
1682 | insert_directive { $$ = $1; }
1683 | module_directive { $$ = $1; }
1684 | name_directive { $$ = $1; }
1685 | native_directive { $$ = $1; }
1686 | pragma_directive { $$ = $1; }
1687 | rename_directive { $$ = $1; }
1688 | feature_directive { $$ = $1; }
1689 | varargs_directive { $$ = $1; }
1690 | typemap_directive { $$ = $1; }
1691 | types_directive { $$ = $1; }
1692 | template_directive { $$ = $1; }
1693 | warn_directive { $$ = $1; }
1696 /* ------------------------------------------------------------
1697 %extend classname { ... }
1698 ------------------------------------------------------------ */
1700 extend_directive : EXTEND options idcolon LBRACE {
1703 cplus_mode = CPLUS_PUBLIC;
1704 if (!classes) classes = NewHash();
1705 if (!extendhash) extendhash = NewHash();
1706 clsname = make_class_name($3);
1707 cls = Getattr(classes,clsname);
1709 /* No previous definition. Create a new scope */
1710 Node *am = Getattr(extendhash,clsname);
1712 Swig_symbol_newscope();
1713 Swig_symbol_setscopename($3);
1716 prev_symtab = Swig_symbol_setscope(Getattr(am,"symtab"));
1720 /* Previous class definition. Use its symbol table */
1721 prev_symtab = Swig_symbol_setscope(Getattr(cls,"symtab"));
1722 current_class = cls;
1725 Classprefix = NewString($3);
1726 Namespaceprefix= Swig_symbol_qualifiedscopename(0);
1728 } cpp_members RBRACE {
1731 $$ = new_node("extend");
1732 Setattr($$,"symtab",Swig_symbol_popscope());
1734 Swig_symbol_setscope(prev_symtab);
1736 Namespaceprefix = Swig_symbol_qualifiedscopename(0);
1737 clsname = make_class_name($3);
1738 Setattr($$,"name",clsname);
1740 /* Mark members as extend */
1742 tag_nodes($6,"feature:extend",(char*) "1");
1743 if (current_class) {
1744 /* We add the extension to the previously defined class */
1746 appendChild(current_class,$$);
1748 /* We store the extensions in the extensions hash */
1749 Node *am = Getattr(extendhash,clsname);
1751 /* Append the members to the previous extend methods */
1755 Setattr(extendhash,clsname,$$);
1759 Delete(Classprefix);
1768 /* ------------------------------------------------------------
1770 ------------------------------------------------------------ */
1772 apply_directive : APPLY typemap_parm LBRACE tm_list RBRACE {
1773 $$ = new_node("apply");
1774 Setattr($$,"pattern",Getattr($2,"pattern"));
1778 /* ------------------------------------------------------------
1780 ------------------------------------------------------------ */
1782 clear_directive : CLEAR tm_list SEMI {
1783 $$ = new_node("clear");
1788 /* ------------------------------------------------------------
1789 %constant name = value;
1790 %constant type name = value;
1791 ------------------------------------------------------------ */
1793 constant_directive : CONSTANT ID EQUAL definetype SEMI {
1794 if (($4.type != T_ERROR) && ($4.type != T_SYMBOL)) {
1795 SwigType *type = NewSwigType($4.type);
1796 $$ = new_node("constant");
1797 Setattr($$,"name",$2);
1798 Setattr($$,"type",type);
1799 Setattr($$,"value",$4.val);
1800 if ($4.rawval) Setattr($$,"rawval", $4.rawval);
1801 Setattr($$,"storage","%constant");
1802 SetFlag($$,"feature:immutable");
1806 if ($4.type == T_ERROR) {
1807 Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line,"Unsupported constant value (ignored)\n");
1814 | CONSTANT type declarator def_args SEMI {
1815 if (($4.type != T_ERROR) && ($4.type != T_SYMBOL)) {
1816 SwigType_push($2,$3.type);
1817 /* Sneaky callback function trick */
1818 if (SwigType_isfunction($2)) {
1819 SwigType_add_pointer($2);
1821 $$ = new_node("constant");
1822 Setattr($$,"name",$3.id);
1823 Setattr($$,"type",$2);
1824 Setattr($$,"value",$4.val);
1825 if ($4.rawval) Setattr($$,"rawval", $4.rawval);
1826 Setattr($$,"storage","%constant");
1827 SetFlag($$,"feature:immutable");
1830 if ($4.type == T_ERROR) {
1831 Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line,"Unsupported constant value\n");
1836 | CONSTANT error SEMI {
1837 Swig_warning(WARN_PARSE_BAD_VALUE,cparse_file,cparse_line,"Bad constant value (ignored).\n");
1842 /* ------------------------------------------------------------
1845 ------------------------------------------------------------ */
1847 echo_directive : ECHO HBLOCK {
1849 Replace($2,"$file",cparse_file, DOH_REPLACE_ANY);
1850 sprintf(temp,"%d", cparse_line);
1851 Replace($2,"$line",temp,DOH_REPLACE_ANY);
1852 Printf(stderr,"%s\n", $2);
1858 String *s = NewString($2);
1859 Replace(s,"$file",cparse_file, DOH_REPLACE_ANY);
1860 sprintf(temp,"%d", cparse_line);
1861 Replace(s,"$line",temp,DOH_REPLACE_ANY);
1862 Printf(stderr,"%s\n", s);
1868 /* ------------------------------------------------------------
1869 %except(lang) { ... }
1873 ------------------------------------------------------------ */
1875 except_directive : EXCEPT LPAREN ID RPAREN LBRACE {
1876 skip_balanced('{','}');
1878 Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n");
1882 skip_balanced('{','}');
1884 Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n");
1887 | EXCEPT LPAREN ID RPAREN SEMI {
1889 Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n");
1894 Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n");
1898 /* fragment keyword arguments */
1899 stringtype : string LBRACE parm RBRACE {
1901 Setattr($$,"value",$1);
1902 Setattr($$,"type",Getattr($3,"type"));
1908 Setattr($$,"value",$1);
1915 /* ------------------------------------------------------------
1916 %fragment(name, section) %{ ... %}
1917 %fragment("name" {type}, "section") %{ ... %}
1918 %fragment("name", "section", fragment="fragment1", fragment="fragment2") %{ ... %}
1919 Also as above but using { ... }
1921 ------------------------------------------------------------ */
1923 fragment_directive: FRAGMENT LPAREN fname COMMA kwargs RPAREN HBLOCK {
1925 $$ = new_node("fragment");
1926 Setattr($$,"value",Getattr($3,"value"));
1927 Setattr($$,"type",Getattr($3,"type"));
1928 Setattr($$,"section",Getattr(p,"name"));
1929 Setattr($$,"kwargs",nextSibling(p));
1930 Setattr($$,"code",$7);
1932 | FRAGMENT LPAREN fname COMMA kwargs RPAREN LBRACE {
1935 skip_balanced('{','}');
1936 $$ = new_node("fragment");
1937 Setattr($$,"value",Getattr($3,"value"));
1938 Setattr($$,"type",Getattr($3,"type"));
1939 Setattr($$,"section",Getattr(p,"name"));
1940 Setattr($$,"kwargs",nextSibling(p));
1941 Delitem(scanner_ccode,0);
1942 Delitem(scanner_ccode,DOH_END);
1943 code = Copy(scanner_ccode);
1944 Setattr($$,"code",code);
1947 | FRAGMENT LPAREN fname RPAREN SEMI {
1948 $$ = new_node("fragment");
1949 Setattr($$,"value",Getattr($3,"value"));
1950 Setattr($$,"type",Getattr($3,"type"));
1951 Setattr($$,"emitonly","1");
1955 /* ------------------------------------------------------------
1956 %includefile "filename" [option1="xyz", ...] [ declarations ]
1957 %importfile "filename" [option1="xyz", ...] [ declarations ]
1958 ------------------------------------------------------------ */
1960 include_directive: includetype options string LBRACKET {
1961 $1.filename = Copy(cparse_file);
1962 $1.line = cparse_line;
1963 scanner_set_location(NewString($3),1);
1965 String *maininput = Getattr($2, "maininput");
1967 scanner_set_main_input_file(NewString(maininput));
1969 } interface RBRACKET {
1972 scanner_set_location($1.filename,$1.line);
1973 if (strcmp($1.type,"include") == 0) set_nodeType($$,"include");
1974 if (strcmp($1.type,"import") == 0) {
1975 mname = $2 ? Getattr($2,"module") : 0;
1976 set_nodeType($$,"import");
1977 if (import_mode) --import_mode;
1980 Setattr($$,"name",$3);
1981 /* Search for the module (if any) */
1983 Node *n = firstChild($$);
1985 if (Strcmp(nodeType(n),"module") == 0) {
1987 Setattr(n,"name", mname);
1990 Setattr($$,"module",Getattr(n,"name"));
1996 /* There is no module node in the import
1997 node, ie, you imported a .h file
1998 directly. We are forced then to create
1999 a new import node with a module node.
2001 Node *nint = new_node("import");
2002 Node *mnode = new_node("module");
2003 Setattr(mnode,"name", mname);
2004 appendChild(nint,mnode);
2006 appendChild(nint,firstChild($$));
2008 Setattr($$,"module",mname);
2011 Setattr($$,"options",$2);
2015 includetype : INCLUDE { $$.type = (char *) "include"; }
2016 | IMPORT { $$.type = (char *) "import"; ++import_mode;}
2019 /* ------------------------------------------------------------
2021 ------------------------------------------------------------ */
2023 inline_directive : INLINE HBLOCK {
2025 if (Namespaceprefix) {
2026 Swig_error(cparse_file, cparse_start_line, "%%inline directive inside a namespace is disallowed.\n");
2030 $$ = new_node("insert");
2031 Setattr($$,"code",$2);
2032 /* Need to run through the preprocessor */
2033 Setline($2,cparse_start_line);
2034 Setfile($2,cparse_file);
2035 Seek($2,0,SEEK_SET);
2036 cpps = Preprocessor_parse($2);
2037 start_inline(Char(cpps), cparse_start_line);
2045 int start_line = cparse_line;
2046 skip_balanced('{','}');
2047 if (Namespaceprefix) {
2048 Swig_error(cparse_file, cparse_start_line, "%%inline directive inside a namespace is disallowed.\n");
2053 $$ = new_node("insert");
2054 Delitem(scanner_ccode,0);
2055 Delitem(scanner_ccode,DOH_END);
2056 code = Copy(scanner_ccode);
2057 Setattr($$,"code", code);
2059 cpps=Copy(scanner_ccode);
2060 start_inline(Char(cpps), start_line);
2066 /* ------------------------------------------------------------
2068 %insert(section) "filename"
2069 %insert("section") "filename"
2070 %insert(section) %{ ... %}
2071 %insert("section") %{ ... %}
2072 ------------------------------------------------------------ */
2074 insert_directive : HBLOCK {
2075 $$ = new_node("insert");
2076 Setattr($$,"code",$1);
2078 | INSERT LPAREN idstring RPAREN string {
2079 String *code = NewStringEmpty();
2080 $$ = new_node("insert");
2081 Setattr($$,"section",$3);
2082 Setattr($$,"code",code);
2083 if (Swig_insert_file($5,code) < 0) {
2084 Swig_error(cparse_file, cparse_line, "Couldn't find '%s'.\n", $5);
2088 | INSERT LPAREN idstring RPAREN HBLOCK {
2089 $$ = new_node("insert");
2090 Setattr($$,"section",$3);
2091 Setattr($$,"code",$5);
2093 | INSERT LPAREN idstring RPAREN LBRACE {
2095 skip_balanced('{','}');
2096 $$ = new_node("insert");
2097 Setattr($$,"section",$3);
2098 Delitem(scanner_ccode,0);
2099 Delitem(scanner_ccode,DOH_END);
2100 code = Copy(scanner_ccode);
2101 Setattr($$,"code", code);
2106 /* ------------------------------------------------------------
2109 ------------------------------------------------------------ */
2111 module_directive: MODULE options idstring {
2112 $$ = new_node("module");
2114 Setattr($$,"options",$2);
2115 if (Getattr($2,"directors")) {
2116 Wrapper_director_mode_set(1);
2118 if (Getattr($2,"dirprot")) {
2119 Wrapper_director_protected_mode_set(1);
2121 if (Getattr($2,"allprotected")) {
2122 Wrapper_all_protected_mode_set(1);
2124 if (Getattr($2,"templatereduce")) {
2125 template_reduce = 1;
2127 if (Getattr($2,"notemplatereduce")) {
2128 template_reduce = 0;
2131 if (!ModuleName) ModuleName = NewString($3);
2133 /* first module included, we apply global
2134 ModuleName, which can be modify by -module */
2135 String *mname = Copy(ModuleName);
2136 Setattr($$,"name",mname);
2139 /* import mode, we just pass the idstring */
2140 Setattr($$,"name",$3);
2142 if (!module_node) module_node = $$;
2146 /* ------------------------------------------------------------
2147 %name(newname) declaration
2148 %name("newname") declaration
2149 ------------------------------------------------------------ */
2151 name_directive : NAME LPAREN idstring RPAREN {
2152 Swig_warning(WARN_DEPRECATED_NAME,cparse_file,cparse_line, "%%name is deprecated. Use %%rename instead.\n");
2154 yyrename = NewString($3);
2157 | NAME LPAREN RPAREN {
2158 Swig_warning(WARN_DEPRECATED_NAME,cparse_file,cparse_line, "%%name is deprecated. Use %%rename instead.\n");
2160 Swig_error(cparse_file,cparse_line,"Missing argument to %%name directive.\n");
2165 /* ------------------------------------------------------------
2166 %native(scriptname) name;
2167 %native(scriptname) type name (parms);
2168 ------------------------------------------------------------ */
2170 native_directive : NATIVE LPAREN ID RPAREN storage_class ID SEMI {
2171 $$ = new_node("native");
2172 Setattr($$,"name",$3);
2173 Setattr($$,"wrap:name",$6);
2176 | NATIVE LPAREN ID RPAREN storage_class type declarator SEMI {
2177 if (!SwigType_isfunction($7.type)) {
2178 Swig_error(cparse_file,cparse_line,"%%native declaration '%s' is not a function.\n", $7.id);
2181 Delete(SwigType_pop_function($7.type));
2182 /* Need check for function here */
2183 SwigType_push($6,$7.type);
2184 $$ = new_node("native");
2185 Setattr($$,"name",$3);
2186 Setattr($$,"wrap:name",$7.id);
2187 Setattr($$,"type",$6);
2188 Setattr($$,"parms",$7.parms);
2189 Setattr($$,"decl",$7.type);
2195 /* ------------------------------------------------------------
2196 %pragma(lang) name=value
2198 %pragma name = value
2200 ------------------------------------------------------------ */
2202 pragma_directive : PRAGMA pragma_lang ID EQUAL pragma_arg {
2203 $$ = new_node("pragma");
2204 Setattr($$,"lang",$2);
2205 Setattr($$,"name",$3);
2206 Setattr($$,"value",$5);
2208 | PRAGMA pragma_lang ID {
2209 $$ = new_node("pragma");
2210 Setattr($$,"lang",$2);
2211 Setattr($$,"name",$3);
2215 pragma_arg : string { $$ = NewString($1); }
2216 | HBLOCK { $$ = $1; }
2219 pragma_lang : LPAREN ID RPAREN { $$ = $2; }
2220 | empty { $$ = (char *) "swig"; }
2223 /* ------------------------------------------------------------
2224 %rename identifier newname;
2225 %rename identifier "newname";
2226 ------------------------------------------------------------ */
2228 rename_directive : rename_namewarn declarator idstring SEMI {
2229 SwigType *t = $2.type;
2230 Hash *kws = NewHash();
2232 fixname = feature_identifier_fix($2.id);
2233 Setattr(kws,"name",$3);
2235 /* Special declarator check */
2237 if (SwigType_isfunction(t)) {
2238 SwigType *decl = SwigType_pop_function(t);
2239 if (SwigType_ispointer(t)) {
2240 String *nname = NewStringf("*%s",fixname);
2242 Swig_name_rename_add(Namespaceprefix, nname,decl,kws,$2.parms);
2244 Swig_name_namewarn_add(Namespaceprefix,nname,decl,kws);
2249 Swig_name_rename_add(Namespaceprefix,(fixname),decl,kws,$2.parms);
2251 Swig_name_namewarn_add(Namespaceprefix,(fixname),decl,kws);
2255 } else if (SwigType_ispointer(t)) {
2256 String *nname = NewStringf("*%s",fixname);
2258 Swig_name_rename_add(Namespaceprefix,(nname),0,kws,$2.parms);
2260 Swig_name_namewarn_add(Namespaceprefix,(nname),0,kws);
2266 Swig_name_rename_add(Namespaceprefix,(fixname),0,kws,$2.parms);
2268 Swig_name_namewarn_add(Namespaceprefix,(fixname),0,kws);
2272 scanner_clear_rename();
2274 | rename_namewarn LPAREN kwargs RPAREN declarator cpp_const SEMI {
2277 SwigType *t = $5.type;
2278 fixname = feature_identifier_fix($5.id);
2280 /* Special declarator check */
2282 if ($6.qualifier) SwigType_push(t,$6.qualifier);
2283 if (SwigType_isfunction(t)) {
2284 SwigType *decl = SwigType_pop_function(t);
2285 if (SwigType_ispointer(t)) {
2286 String *nname = NewStringf("*%s",fixname);
2288 Swig_name_rename_add(Namespaceprefix, nname,decl,kws,$5.parms);
2290 Swig_name_namewarn_add(Namespaceprefix,nname,decl,kws);
2295 Swig_name_rename_add(Namespaceprefix,(fixname),decl,kws,$5.parms);
2297 Swig_name_namewarn_add(Namespaceprefix,(fixname),decl,kws);
2301 } else if (SwigType_ispointer(t)) {
2302 String *nname = NewStringf("*%s",fixname);
2304 Swig_name_rename_add(Namespaceprefix,(nname),0,kws,$5.parms);
2306 Swig_name_namewarn_add(Namespaceprefix,(nname),0,kws);
2312 Swig_name_rename_add(Namespaceprefix,(fixname),0,kws,$5.parms);
2314 Swig_name_namewarn_add(Namespaceprefix,(fixname),0,kws);
2318 scanner_clear_rename();
2320 | rename_namewarn LPAREN kwargs RPAREN string SEMI {
2322 Swig_name_rename_add(Namespaceprefix,$5,0,$3,0);
2324 Swig_name_namewarn_add(Namespaceprefix,$5,0,$3);
2327 scanner_clear_rename();
2331 rename_namewarn : RENAME {
2339 /* ------------------------------------------------------------
2340 Feature targeting a symbol name (non-global feature):
2342 %feature(featurename) name "val";
2343 %feature(featurename, val) name;
2345 where "val" could instead be the other bracket types, that is,
2346 { val } or %{ val %} or indeed omitted whereupon it defaults to "1".
2347 Or, the global feature which does not target a symbol name:
2349 %feature(featurename) "val";
2350 %feature(featurename, val);
2352 An empty val (empty string) clears the feature.
2353 Any number of feature attributes can optionally be added, for example
2354 a non-global feature with 2 attributes:
2356 %feature(featurename, attrib1="attribval1", attrib2="attribval2") name "val";
2357 %feature(featurename, val, attrib1="attribval1", attrib2="attribval2") name;
2358 ------------------------------------------------------------ */
2360 /* Non-global feature */
2361 feature_directive : FEATURE LPAREN idstring RPAREN declarator cpp_const stringbracesemi {
2362 String *val = $7 ? NewString($7) : NewString("1");
2363 new_feature($3, val, 0, $5.id, $5.type, $5.parms, $6.qualifier);
2365 scanner_clear_rename();
2367 | FEATURE LPAREN idstring COMMA stringnum RPAREN declarator cpp_const SEMI {
2368 String *val = Len($5) ? NewString($5) : 0;
2369 new_feature($3, val, 0, $7.id, $7.type, $7.parms, $8.qualifier);
2371 scanner_clear_rename();
2373 | FEATURE LPAREN idstring featattr RPAREN declarator cpp_const stringbracesemi {
2374 String *val = $8 ? NewString($8) : NewString("1");
2375 new_feature($3, val, $4, $6.id, $6.type, $6.parms, $7.qualifier);
2377 scanner_clear_rename();
2379 | FEATURE LPAREN idstring COMMA stringnum featattr RPAREN declarator cpp_const SEMI {
2380 String *val = Len($5) ? NewString($5) : 0;
2381 new_feature($3, val, $6, $8.id, $8.type, $8.parms, $9.qualifier);
2383 scanner_clear_rename();
2386 /* Global feature */
2387 | FEATURE LPAREN idstring RPAREN stringbracesemi {
2388 String *val = $5 ? NewString($5) : NewString("1");
2389 new_feature($3, val, 0, 0, 0, 0, 0);
2391 scanner_clear_rename();
2393 | FEATURE LPAREN idstring COMMA stringnum RPAREN SEMI {
2394 String *val = Len($5) ? NewString($5) : 0;
2395 new_feature($3, val, 0, 0, 0, 0, 0);
2397 scanner_clear_rename();
2399 | FEATURE LPAREN idstring featattr RPAREN stringbracesemi {
2400 String *val = $6 ? NewString($6) : NewString("1");
2401 new_feature($3, val, $4, 0, 0, 0, 0);
2403 scanner_clear_rename();
2405 | FEATURE LPAREN idstring COMMA stringnum featattr RPAREN SEMI {
2406 String *val = Len($5) ? NewString($5) : 0;
2407 new_feature($3, val, $6, 0, 0, 0, 0);
2409 scanner_clear_rename();
2413 stringbracesemi : stringbrace { $$ = $1; }
2415 | PARMS LPAREN parms RPAREN SEMI { $$ = $3; }
2418 featattr : COMMA idstring EQUAL stringnum {
2420 Setattr($$,"name",$2);
2421 Setattr($$,"value",$4);
2423 | COMMA idstring EQUAL stringnum featattr {
2425 Setattr($$,"name",$2);
2426 Setattr($$,"value",$4);
2427 set_nextSibling($$,$5);
2431 /* %varargs() directive. */
2433 varargs_directive : VARARGS LPAREN varargs_parms RPAREN declarator cpp_const SEMI {
2437 if (Namespaceprefix) name = NewStringf("%s::%s", Namespaceprefix, $5.id);
2438 else name = NewString($5.id);
2441 Setmeta(val,"parms",$5.parms);
2446 if ($6.qualifier) SwigType_push(t,$6.qualifier);
2447 if (SwigType_isfunction(t)) {
2448 SwigType *decl = SwigType_pop_function(t);
2449 if (SwigType_ispointer(t)) {
2450 String *nname = NewStringf("*%s",name);
2451 Swig_feature_set(Swig_cparse_features(), nname, decl, "feature:varargs", val, 0);
2454 Swig_feature_set(Swig_cparse_features(), name, decl, "feature:varargs", val, 0);
2457 } else if (SwigType_ispointer(t)) {
2458 String *nname = NewStringf("*%s",name);
2459 Swig_feature_set(Swig_cparse_features(),nname,0,"feature:varargs",val, 0);
2463 Swig_feature_set(Swig_cparse_features(),name,0,"feature:varargs",val, 0);
2469 varargs_parms : parms { $$ = $1; }
2470 | NUM_INT COMMA parm {
2474 n = atoi(Char($1.val));
2476 Swig_error(cparse_file, cparse_line,"Argument count in %%varargs must be positive.\n");
2480 Setattr($$,"name","VARARGS_SENTINEL");
2481 for (i = 0; i < n; i++) {
2483 set_nextSibling(p,$$);
2492 /* ------------------------------------------------------------
2493 %typemap(method) type { ... }
2494 %typemap(method) type "..."
2495 %typemap(method) type; - typemap deletion
2496 %typemap(method) type1,type2,... = type; - typemap copy
2497 %typemap type1,type2,... = type; - typemap copy
2498 ------------------------------------------------------------ */
2500 typemap_directive : TYPEMAP LPAREN typemap_type RPAREN tm_list stringbrace {
2504 $$ = new_node("typemap");
2505 Setattr($$,"method",$3.method);
2507 ParmList *kw = $3.kwargs;
2508 code = remove_block(kw, $6);
2509 Setattr($$,"kwargs", $3.kwargs);
2511 code = code ? code : NewString($6);
2512 Setattr($$,"code", code);
2517 | TYPEMAP LPAREN typemap_type RPAREN tm_list SEMI {
2520 $$ = new_node("typemap");
2521 Setattr($$,"method",$3.method);
2525 | TYPEMAP LPAREN typemap_type RPAREN tm_list EQUAL typemap_parm SEMI {
2528 $$ = new_node("typemapcopy");
2529 Setattr($$,"method",$3.method);
2530 Setattr($$,"pattern", Getattr($7,"pattern"));
2536 /* typemap method type (lang,method) or (method) */
2538 typemap_type : kwargs {
2541 p = nextSibling($1);
2542 if (p && (!Getattr(p,"value"))) {
2543 /* this is the deprecated two argument typemap form */
2544 Swig_warning(WARN_DEPRECATED_TYPEMAP_LANG,cparse_file, cparse_line,
2545 "Specifying the language name in %%typemap is deprecated - use #ifdef SWIG<LANG> instead.\n");
2546 /* two argument typemap form */
2547 name = Getattr($1,"name");
2548 if (!name || (Strcmp(name,typemap_lang))) {
2552 $$.method = Getattr(p,"name");
2553 $$.kwargs = nextSibling(p);
2556 /* one-argument typemap-form */
2557 $$.method = Getattr($1,"name");
2563 tm_list : typemap_parm tm_tail {
2565 set_nextSibling($$,$2);
2569 tm_tail : COMMA typemap_parm tm_tail {
2571 set_nextSibling($$,$3);
2576 typemap_parm : type typemap_parameter_declarator {
2578 SwigType_push($1,$2.type);
2579 $$ = new_node("typemapitem");
2580 parm = NewParm($1,$2.id);
2581 Setattr($$,"pattern",parm);
2582 Setattr($$,"parms", $2.parms);
2584 /* $$ = NewParm($1,$2.id);
2585 Setattr($$,"parms",$2.parms); */
2587 | LPAREN parms RPAREN {
2588 $$ = new_node("typemapitem");
2589 Setattr($$,"pattern",$2);
2590 /* Setattr($$,"multitype",$2); */
2592 | LPAREN parms RPAREN LPAREN parms RPAREN {
2593 $$ = new_node("typemapitem");
2594 Setattr($$,"pattern", $2);
2595 /* Setattr($$,"multitype",$2); */
2596 Setattr($$,"parms",$5);
2600 /* ------------------------------------------------------------
2602 %types(parmlist) %{ ... %}
2603 ------------------------------------------------------------ */
2605 types_directive : TYPES LPAREN parms RPAREN stringbracesemi {
2606 $$ = new_node("types");
2607 Setattr($$,"parms",$3);
2609 Setattr($$,"convcode",NewString($5));
2613 /* ------------------------------------------------------------
2614 %template(name) tname<args>;
2615 ------------------------------------------------------------ */
2617 template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN valparms GREATERTHAN SEMI {
2622 int specialized = 0;
2626 tscope = Swig_symbol_current(); /* Get the current scope */
2628 /* If the class name is qualified, we need to create or lookup namespace entries */
2630 $5 = resolve_node_scope($5);
2634 We use the new namespace entry 'nscope' only to
2635 emit the template node. The template parameters are
2636 resolved in the current 'tscope'.
2638 This is closer to the C++ (typedef) behavior.
2640 n = Swig_cparse_template_locate($5,$7,tscope);
2642 /* Patch the argument types to respect namespaces */
2645 SwigType *value = Getattr(p,"value");
2647 SwigType *ty = Getattr(p,"type");
2650 int reduce = template_reduce;
2651 if (reduce || !SwigType_ispointer(ty)) {
2652 rty = Swig_symbol_typedef_reduce(ty,tscope);
2653 if (!reduce) reduce = SwigType_ispointer(rty);
2655 ty = reduce ? Swig_symbol_type_qualify(rty,tscope) : Swig_symbol_type_qualify(ty,tscope);
2656 Setattr(p,"type",ty);
2661 value = Swig_symbol_type_qualify(value,tscope);
2662 Setattr(p,"value",value);
2669 /* Look for the template */
2672 Node *linklistend = 0;
2674 Node *templnode = 0;
2675 if (Strcmp(nodeType(nn),"template") == 0) {
2676 int nnisclass = (Strcmp(Getattr(nn,"templatetype"),"class") == 0); /* if not a templated class it is a templated function */
2677 Parm *tparms = Getattr(nn,"templateparms");
2681 if (nnisclass && !specialized && ((ParmList_len($7) > ParmList_len(tparms)))) {
2682 Swig_error(cparse_file, cparse_line, "Too many template parameters. Maximum of %d.\n", ParmList_len(tparms));
2683 } else if (nnisclass && !specialized && ((ParmList_len($7) < ParmList_numrequired(tparms)))) {
2684 Swig_error(cparse_file, cparse_line, "Not enough template parameters specified. %d required.\n", ParmList_numrequired(tparms));
2685 } else if (!nnisclass && ((ParmList_len($7) != ParmList_len(tparms)))) {
2686 /* must be an overloaded templated method - ignore it as it is overloaded with a different number of template parameters */
2687 nn = Getattr(nn,"sym:nextSibling"); /* repeat for overloaded templated functions */
2690 String *tname = Copy($5);
2691 int def_supplied = 0;
2692 /* Expand the template */
2693 Node *templ = Swig_symbol_clookup($5,0);
2694 Parm *targs = templ ? Getattr(templ,"templateparms") : 0;
2697 if (specialized) temparms = CopyParmList($7);
2698 else temparms = CopyParmList(tparms);
2700 /* Create typedef's and arguments */
2703 if (!p && ParmList_len(p) != ParmList_len(temparms)) {
2704 /* we have no template parameters supplied in %template for a template that has default args*/
2710 String *value = Getattr(p,"value");
2712 Setattr(p,"default","1");
2715 Setattr(tp,"value",value);
2717 SwigType *ty = Getattr(p,"type");
2719 Setattr(tp,"type",ty);
2721 Delattr(tp,"value");
2723 /* fix default arg values */
2725 Parm *pi = temparms;
2727 String *tv = Getattr(tp,"value");
2728 if (!tv) tv = Getattr(tp,"type");
2729 while(pi != tp && ti && pi) {
2730 String *name = Getattr(ti,"name");
2731 String *value = Getattr(pi,"value");
2732 if (!value) value = Getattr(pi,"type");
2733 Replaceid(tv, name, value);
2734 pi = nextSibling(pi);
2735 ti = nextSibling(ti);
2739 tp = nextSibling(tp);
2746 templnode = copy_node(nn);
2747 /* We need to set the node name based on name used to instantiate */
2748 Setattr(templnode,"name",tname);
2751 Delattr(templnode,"sym:typename");
2753 Setattr(templnode,"sym:typename","1");
2757 Comment this out for 1.3.28. We need to
2758 re-enable it later but first we need to
2759 move %ignore from using %rename to use
2762 String *symname = Swig_name_make(templnode,0,$3,0,0);
2764 String *symname = $3;
2765 Swig_cparse_template_expand(templnode,symname,temparms,tscope);
2766 Setattr(templnode,"sym:name",symname);
2769 String *nname = NewStringf("__dummy_%d__", cnt++);
2770 Swig_cparse_template_expand(templnode,nname,temparms,tscope);
2771 Setattr(templnode,"sym:name",nname);
2773 Setattr(templnode,"feature:onlychildren",
2774 "typemap,typemapitem,typemapcopy,typedef,types,fragment");
2776 Delattr(templnode,"templatetype");
2777 Setattr(templnode,"template",nn);
2779 Setfile(templnode,cparse_file);
2780 Setline(templnode,cparse_line);
2783 add_symbols_copy(templnode);
2785 if (Strcmp(nodeType(templnode),"class") == 0) {
2787 /* Identify pure abstract methods */
2788 Setattr(templnode,"abstract", pure_abstract(firstChild(templnode)));
2790 /* Set up inheritance in symbol table */
2793 List *baselist = Getattr(templnode,"baselist");
2794 csyms = Swig_symbol_current();
2795 Swig_symbol_setscope(Getattr(templnode,"symtab"));
2797 List *bases = make_inherit_list(Getattr(templnode,"name"),baselist);
2800 for (s = First(bases); s.item; s = Next(s)) {
2801 Symtab *st = Getattr(s.item,"symtab");
2803 Setfile(st,Getfile(s.item));
2804 Setline(st,Getline(s.item));
2805 Swig_symbol_inherit(st);
2811 Swig_symbol_setscope(csyms);
2814 /* Merge in addmethods for this class */
2816 /* !!! This may be broken. We may have to add the
2817 addmethods at the beginning of the class */
2823 if (Namespaceprefix) {
2824 clsname = stmp = NewStringf("%s::%s", Namespaceprefix, Getattr(templnode,"name"));
2826 clsname = Getattr(templnode,"name");
2828 am = Getattr(extendhash,clsname);
2830 Symtab *st = Swig_symbol_current();
2831 Swig_symbol_setscope(Getattr(templnode,"symtab"));
2832 /* Printf(stdout,"%s: %s %x %x\n", Getattr(templnode,"name"), clsname, Swig_symbol_current(), Getattr(templnode,"symtab")); */
2833 merge_extensions(templnode,am);
2834 Swig_symbol_setscope(st);
2835 append_previous_extension(templnode,am);
2836 Delattr(extendhash,clsname);
2838 if (stmp) Delete(stmp);
2840 /* Add to classes hash */
2841 if (!classes) classes = NewHash();
2844 if (Namespaceprefix) {
2845 String *temp = NewStringf("%s::%s", Namespaceprefix, Getattr(templnode,"name"));
2846 Setattr(classes,temp,templnode);
2849 String *qs = Swig_symbol_qualifiedscopename(templnode);
2850 Setattr(classes, qs,templnode);
2857 /* all the overloaded templated functions are added into a linked list */
2859 /* non-global namespace */
2861 appendChild(nscope_inner,templnode);
2863 if (nscope) $$ = nscope;
2866 /* global namespace */
2870 set_nextSibling(linklistend,templnode);
2873 linklistend = templnode;
2876 nn = Getattr(nn,"sym:nextSibling"); /* repeat for overloaded templated functions. If a templated class there will never be a sibling. */
2879 Swig_symbol_setscope(tscope);
2880 Delete(Namespaceprefix);
2881 Namespaceprefix = Swig_symbol_qualifiedscopename(0);
2885 /* ------------------------------------------------------------
2888 ------------------------------------------------------------ */
2890 warn_directive : WARN string {
2891 Swig_warning(0,cparse_file, cparse_line,"%s\n", $2);
2896 /* ======================================================================
2898 * ====================================================================== */
2900 c_declaration : c_decl {
2904 default_arguments($$);
2907 | c_enum_decl { $$ = $1; }
2908 | c_enum_forward_decl { $$ = $1; }
2910 /* An extern C type declaration, disable cparse_cplusplus if needed. */
2912 | EXTERN string LBRACE {
2913 if (Strcmp($2,"C") == 0) {
2916 } interface RBRACE {
2918 if (Strcmp($2,"C") == 0) {
2919 Node *n = firstChild($5);
2920 $$ = new_node("extern");
2921 Setattr($$,"name",$2);
2924 SwigType *decl = Getattr(n,"decl");
2925 if (SwigType_isfunction(decl)) {
2926 Setattr(n,"storage","externc");
2931 Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\".\n", $2);
2932 $$ = new_node("extern");
2933 Setattr($$,"name",$2);
2934 appendChild($$,firstChild($5));
2939 /* ------------------------------------------------------------
2940 A C global declaration of some kind (may be variable, function, typedef, etc.)
2941 ------------------------------------------------------------ */
2943 c_decl : storage_class type declarator initializer c_decl_tail {
2944 $$ = new_node("cdecl");
2945 if ($4.qualifier) SwigType_push($3.type,$4.qualifier);
2946 Setattr($$,"type",$2);
2947 Setattr($$,"storage",$1);
2948 Setattr($$,"name",$3.id);
2949 Setattr($$,"decl",$3.type);
2950 Setattr($$,"parms",$3.parms);
2951 Setattr($$,"value",$4.val);
2952 Setattr($$,"throws",$4.throws);
2953 Setattr($$,"throw",$4.throwf);
2955 if (Len(scanner_ccode)) {
2956 String *code = Copy(scanner_ccode);
2957 Setattr($$,"code",code);
2962 /* Inherit attributes */
2964 String *type = Copy($2);
2965 Setattr(n,"type",type);
2966 Setattr(n,"storage",$1);
2972 Setattr($$,"bitfield", $4.bitfield);
2975 /* Look for "::" declarations (ignored) */
2976 if (Strstr($3.id,"::")) {
2977 /* This is a special case. If the scope name of the declaration exactly
2978 matches that of the declaration, then we will allow it. Otherwise, delete. */
2979 String *p = Swig_scopename_prefix($3.id);
2981 if ((Namespaceprefix && Strcmp(p,Namespaceprefix) == 0) ||
2982 (inclass && Strcmp(p,Classprefix) == 0)) {
2983 String *lstr = Swig_scopename_last($3.id);
2984 Setattr($$,"name",lstr);
2986 set_nextSibling($$,$5);
2997 set_nextSibling($$,$5);
3002 /* Allow lists of variables and functions to be built up */
3004 c_decl_tail : SEMI {
3006 Clear(scanner_ccode);
3008 | COMMA declarator initializer c_decl_tail {
3009 $$ = new_node("cdecl");
3010 if ($3.qualifier) SwigType_push($2.type,$3.qualifier);
3011 Setattr($$,"name",$2.id);
3012 Setattr($$,"decl",$2.type);
3013 Setattr($$,"parms",$2.parms);
3014 Setattr($$,"value",$3.val);
3015 Setattr($$,"throws",$3.throws);
3016 Setattr($$,"throw",$3.throwf);
3018 Setattr($$,"bitfield", $3.bitfield);
3021 if (Len(scanner_ccode)) {
3022 String *code = Copy(scanner_ccode);
3023 Setattr($$,"code",code);
3027 set_nextSibling($$,$4);
3031 skip_balanced('{','}');
3036 initializer : def_args {
3042 | type_qualifier def_args {
3048 | THROW LPAREN parms RPAREN def_args {
3052 $$.throwf = NewString("1");
3054 | type_qualifier THROW LPAREN parms RPAREN def_args {
3058 $$.throwf = NewString("1");
3063 /* ------------------------------------------------------------
3065 ------------------------------------------------------------ */
3067 c_enum_forward_decl : storage_class ENUM ID SEMI {
3069 $$ = new_node("enumforward");
3070 ty = NewStringf("enum %s", $3);
3071 Setattr($$,"name",$3);
3072 Setattr($$,"type",ty);
3073 Setattr($$,"sym:weak", "1");
3078 /* ------------------------------------------------------------
3080 * ------------------------------------------------------------ */
3082 c_enum_decl : storage_class ENUM ename LBRACE enumlist RBRACE SEMI {
3084 $$ = new_node("enum");
3085 ty = NewStringf("enum %s", $3);
3086 Setattr($$,"name",$3);
3087 Setattr($$,"type",ty);
3089 add_symbols($$); /* Add to tag space */
3090 add_symbols($5); /* Add enum values to id space */
3092 | storage_class ENUM ename LBRACE enumlist RBRACE declarator c_decl_tail {
3095 String *unnamed = 0;
3096 int unnamedinstance = 0;
3098 $$ = new_node("enum");
3100 Setattr($$,"name",$3);
3101 ty = NewStringf("enum %s", $3);
3103 unnamed = make_unnamed();
3104 ty = NewStringf("enum %s", unnamed);
3105 Setattr($$,"unnamed",unnamed);
3106 /* name is not set for unnamed enum instances, e.g. enum { foo } Instance; */
3107 if ($1 && Cmp($1,"typedef") == 0) {
3108 Setattr($$,"name",$7.id);
3110 unnamedinstance = 1;
3112 Setattr($$,"storage",$1);
3114 if ($7.id && Cmp($1,"typedef") == 0) {
3115 Setattr($$,"tdname",$7.id);
3116 Setattr($$,"allows_typedef","1");
3119 n = new_node("cdecl");
3120 Setattr(n,"type",ty);
3121 Setattr(n,"name",$7.id);
3122 Setattr(n,"storage",$1);
3123 Setattr(n,"decl",$7.type);
3124 Setattr(n,"parms",$7.parms);
3125 Setattr(n,"unnamed",unnamed);
3127 if (unnamedinstance) {
3128 SwigType *cty = NewString("enum ");
3129 Setattr($$,"type",cty);
3130 Setattr($$,"unnamedinstance","1");
3131 Setattr(n,"unnamedinstance","1");
3136 set_nextSibling(n,p);
3138 SwigType *cty = Copy(ty);
3139 Setattr(p,"type",cty);
3140 Setattr(p,"unnamed",unnamed);
3141 Setattr(p,"storage",$1);
3146 if (Len(scanner_ccode)) {
3147 String *code = Copy(scanner_ccode);
3148 Setattr(n,"code",code);
3153 /* Ensure that typedef enum ABC {foo} XYZ; uses XYZ for sym:name, like structs.
3154 * Note that class_rename/yyrename are bit of a mess so used this simple approach to change the name. */
3155 if ($7.id && $3 && Cmp($1,"typedef") == 0) {
3156 String *name = NewString($7.id);
3157 Setattr($$, "parser:makename", name);
3161 add_symbols($$); /* Add enum to tag space */
3162 set_nextSibling($$,n);
3164 add_symbols($5); /* Add enum values to id space */
3170 c_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end {
3171 /* This is a sick hack. If the ctor_end has parameters,
3172 and the parms parameter only has 1 parameter, this
3173 could be a declaration of the form:
3177 Otherwise it's an error. */
3181 if ((ParmList_len($4) == 1) && (!Swig_scopename_check($2))) {
3182 SwigType *ty = Getattr($4,"type");
3183 String *name = Getattr($4,"name");
3186 $$ = new_node("cdecl");
3187 Setattr($$,"type",$2);
3188 Setattr($$,"storage",$1);
3189 Setattr($$,"name",ty);
3191 if ($6.have_parms) {
3192 SwigType *decl = NewStringEmpty();
3193 SwigType_add_function(decl,$6.parms);
3194 Setattr($$,"decl",decl);
3195 Setattr($$,"parms",$6.parms);
3196 if (Len(scanner_ccode)) {
3197 String *code = Copy(scanner_ccode);
3198 Setattr($$,"code",code);
3203 Setattr($$,"value",$6.defarg);
3205 Setattr($$,"throws",$6.throws);
3206 Setattr($$,"throw",$6.throwf);
3211 Swig_error(cparse_file,cparse_line,"Syntax error in input(2).\n");
3217 /* ======================================================================
3219 * ====================================================================== */
3221 cpp_declaration : cpp_class_decl { $$ = $1; }
3222 | cpp_forward_class_decl { $$ = $1; }
3223 | cpp_template_decl { $$ = $1; }
3224 | cpp_using_decl { $$ = $1; }
3225 | cpp_namespace_decl { $$ = $1; }
3226 | cpp_catch_decl { $$ = 0; }
3231 /* A simple class/struct/union definition */
3232 storage_class cpptype idcolon inherit LBRACE {
3235 $<node>$ = new_node("class");
3236 Setline($<node>$,cparse_start_line);
3237 Setattr($<node>$,"kind",$2);
3239 Setattr($<node>$,"baselist", Getattr($4,"public"));
3240 Setattr($<node>$,"protectedbaselist", Getattr($4,"protected"));
3241 Setattr($<node>$,"privatebaselist", Getattr($4,"private"));
3243 Setattr($<node>$,"allows_typedef","1");
3245 /* preserve the current scope */
3246 prev_symtab = Swig_symbol_current();
3248 /* If the class name is qualified. We need to create or lookup namespace/scope entries */
3249 scope = resolve_node_scope($3);
3250 Setfile(scope,cparse_file);
3251 Setline(scope,cparse_line);
3254 /* support for old nested classes "pseudo" support, such as:
3256 %rename(Ala__Ola) Ala::Ola;
3262 this should disappear when a proper implementation is added.
3264 if (nscope_inner && Strcmp(nodeType(nscope_inner),"namespace") != 0) {
3265 if (Namespaceprefix) {
3266 String *name = NewStringf("%s::%s", Namespaceprefix, $3);
3268 Namespaceprefix = 0;
3272 Setattr($<node>$,"name",$3);
3274 Delete(class_rename);
3275 class_rename = make_name($<node>$,$3,0);
3276 Classprefix = NewString($3);
3277 /* Deal with inheritance */
3279 bases = make_inherit_list($3,Getattr($4,"public"));
3281 if (SwigType_istemplate($3)) {
3282 String *fbase, *tbase, *prefix;
3283 prefix = SwigType_templateprefix($3);
3284 if (Namespaceprefix) {
3285 fbase = NewStringf("%s::%s", Namespaceprefix,$3);
3286 tbase = NewStringf("%s::%s", Namespaceprefix, prefix);
3289 tbase = Copy(prefix);
3291 Swig_name_inherit(tbase,fbase);
3296 if (strcmp($2,"class") == 0) {
3297 cplus_mode = CPLUS_PRIVATE;
3299 cplus_mode = CPLUS_PUBLIC;
3301 Swig_symbol_newscope();
3302 Swig_symbol_setscopename($3);
3305 for (s = First(bases); s.item; s = Next(s)) {
3306 Symtab *st = Getattr(s.item,"symtab");
3308 Setfile(st,Getfile(s.item));
3309 Setline(st,Getline(s.item));
3310 Swig_symbol_inherit(st);
3315 Delete(Namespaceprefix);
3316 Namespaceprefix = Swig_symbol_qualifiedscopename(0);
3317 cparse_start_line = cparse_line;
3319 /* If there are active template parameters, we need to make sure they are
3320 placed in the class symbol table so we can catch shadows */
3322 if (template_parameters) {
3323 Parm *tp = template_parameters;
3325 String *tpname = Copy(Getattr(tp,"name"));
3326 Node *tn = new_node("templateparm");
3327 Setattr(tn,"name",tpname);
3328 Swig_symbol_cadd(tpname,tn);
3329 tp = nextSibling(tp);
3333 if (class_level >= max_class_levels) {
3334 if (!max_class_levels) {
3335 max_class_levels = 16;
3337 max_class_levels *= 2;
3339 class_decl = (Node**) realloc(class_decl, sizeof(Node*) * max_class_levels);
3341 Swig_error(cparse_file, cparse_line, "realloc() failed\n");
3344 class_decl[class_level++] = $<node>$;
3346 } cpp_members RBRACE cpp_opt_declarators {
3349 Symtab *cscope = prev_symtab;
3351 String *scpname = 0;
3352 $$ = class_decl[--class_level];
3355 /* Check for pure-abstract class */
3356 Setattr($$,"abstract", pure_abstract($7));
3358 /* This bit of code merges in a previously defined %extend directive (if any) */
3361 String *clsname = Swig_symbol_qualifiedscopename(0);
3362 am = Getattr(extendhash,clsname);
3364 merge_extensions($$,am);
3365 Delattr(extendhash,clsname);
3369 if (!classes) classes = NewHash();
3370 scpname = Swig_symbol_qualifiedscopename(0);
3371 Setattr(classes,scpname,$$);
3376 if (am) append_previous_extension($$,am);
3380 set_nextSibling($$,p);
3383 if (cparse_cplusplus && !cparse_externc) {
3386 ty = NewStringf("%s %s", $2,$3);
3389 Setattr(p,"storage",$1);
3390 Setattr(p,"type",ty);
3393 /* Dump nested classes */
3397 SwigType *decltype = Getattr($9,"decl");
3398 if (Cmp($1,"typedef") == 0) {
3399 if (!decltype || !Len(decltype)) {
3401 name = Getattr($9,"name");
3403 Setattr($$,"tdname",cname);
3406 /* Use typedef name as class name */
3407 if (class_rename && (Strcmp(class_rename,$3) == 0)) {
3408 Delete(class_rename);
3409 class_rename = NewString(name);
3411 if (!Getattr(classes,name)) {
3412 Setattr(classes,name,$$);
3414 Setattr($$,"decl",decltype);
3418 appendChild($$,dump_nested(Char(name)));
3421 if (cplus_mode != CPLUS_PUBLIC) {
3422 /* we 'open' the class at the end, to allow %template
3423 to add new members */
3424 Node *pa = new_node("access");
3425 Setattr(pa,"kind","public");
3426 cplus_mode = CPLUS_PUBLIC;
3431 Setattr($$,"symtab",Swig_symbol_popscope());
3435 /* this is tricky */
3436 /* we add the declaration in the original namespace */
3437 appendChild(nscope_inner,$$);
3438 Swig_symbol_setscope(Getattr(nscope_inner,"symtab"));
3439 Delete(Namespaceprefix);
3440 Namespaceprefix = Swig_symbol_qualifiedscopename(0);
3442 if (nscope) $$ = nscope;
3443 /* but the variable definition in the current scope */
3444 Swig_symbol_setscope(cscope);
3445 Delete(Namespaceprefix);
3446 Namespaceprefix = Swig_symbol_qualifiedscopename(0);
3450 yyrename = Copy(class_rename);
3451 Delete(Namespaceprefix);
3452 Namespaceprefix = Swig_symbol_qualifiedscopename(0);
3457 Swig_symbol_setscope(cscope);
3458 Delete(Namespaceprefix);
3459 Namespaceprefix = Swig_symbol_qualifiedscopename(0);
3462 /* An unnamed struct, possibly with a typedef */
3464 | storage_class cpptype LBRACE {
3466 unnamed = make_unnamed();
3467 $<node>$ = new_node("class");
3468 Setline($<node>$,cparse_start_line);
3469 Setattr($<node>$,"kind",$2);
3470 Setattr($<node>$,"storage",$1);
3471 Setattr($<node>$,"unnamed",unnamed);
3472 Setattr($<node>$,"allows_typedef","1");
3473 Delete(class_rename);
3474 class_rename = make_name($<node>$,0,0);
3475 if (strcmp($2,"class") == 0) {
3476 cplus_mode = CPLUS_PRIVATE;
3478 cplus_mode = CPLUS_PUBLIC;
3480 Swig_symbol_newscope();
3481 cparse_start_line = cparse_line;
3482 if (class_level >= max_class_levels) {
3483 if (!max_class_levels) {
3484 max_class_levels = 16;
3486 max_class_levels *= 2;
3488 class_decl = (Node**) realloc(class_decl, sizeof(Node*) * max_class_levels);
3490 Swig_error(cparse_file, cparse_line, "realloc() failed\n");
3493 class_decl[class_level++] = $<node>$;
3495 Classprefix = NewStringEmpty();
3496 Delete(Namespaceprefix);
3497 Namespaceprefix = Swig_symbol_qualifiedscopename(0);
3498 } cpp_members RBRACE declarator c_decl_tail {
3502 $$ = class_decl[--class_level];
3504 unnamed = Getattr($$,"unnamed");
3506 /* Check for pure-abstract class */
3507 Setattr($$,"abstract", pure_abstract($5));
3509 n = new_node("cdecl");
3510 Setattr(n,"name",$7.id);
3511 Setattr(n,"unnamed",unnamed);
3512 Setattr(n,"type",unnamed);
3513 Setattr(n,"decl",$7.type);
3514 Setattr(n,"parms",$7.parms);
3515 Setattr(n,"storage",$1);
3518 set_nextSibling(n,p);
3520 String *type = Copy(unnamed);
3521 Setattr(p,"name",$7.id);
3522 Setattr(p,"unnamed",unnamed);
3523 Setattr(p,"type",type);
3525 Setattr(p,"storage",$1);
3529 set_nextSibling($$,n);
3532 /* If a proper typedef name was given, we'll use it to set the scope name */
3534 if ($1 && (strcmp($1,"typedef") == 0)) {
3535 if (!Len($7.type)) {
3536 String *scpname = 0;
3538 Setattr($$,"tdname",name);
3539 Setattr($$,"name",name);
3540 Swig_symbol_setscopename(name);
3542 /* If a proper name was given, we use that as the typedef, not unnamed */
3544 Append(unnamed, name);
3547 set_nextSibling($$,n);
3549 /* Check for previous extensions */
3551 String *clsname = Swig_symbol_qualifiedscopename(0);
3552 Node *am = Getattr(extendhash,clsname);
3554 /* Merge the extension into the symbol table */
3555 merge_extensions($$,am);
3556 append_previous_extension($$,am);
3557 Delattr(extendhash,clsname);
3561 if (!classes) classes = NewHash();
3562 scpname = Swig_symbol_qualifiedscopename(0);
3563 Setattr(classes,scpname,$$);
3566 Swig_symbol_setscopename((char*)"<unnamed>");
3570 appendChild($$,dump_nested(Char(name)));
3573 Setattr($$,"symtab",Swig_symbol_popscope());
3576 yyrename = NewString(class_rename);
3578 Delete(Namespaceprefix);
3579 Namespaceprefix = Swig_symbol_qualifiedscopename(0);
3586 cpp_opt_declarators : SEMI { $$ = 0; }
3587 | declarator c_decl_tail {
3588 $$ = new_node("cdecl");
3589 Setattr($$,"name",$1.id);
3590 Setattr($$,"decl",$1.type);
3591 Setattr($$,"parms",$1.parms);
3592 set_nextSibling($$,$2);
3595 /* ------------------------------------------------------------
3597 ------------------------------------------------------------ */
3599 cpp_forward_class_decl : storage_class cpptype idcolon SEMI {
3600 if ($1 && (Strcmp($1,"friend") == 0)) {
3604 $$ = new_node("classforward");
3605 Setfile($$,cparse_file);
3606 Setline($$,cparse_line);
3607 Setattr($$,"kind",$2);
3608 Setattr($$,"name",$3);
3609 Setattr($$,"sym:weak", "1");
3615 /* ------------------------------------------------------------
3617 ------------------------------------------------------------ */
3619 cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { template_parameters = $3; } cpp_temp_possible {
3623 /* check if we get a namespace node with a class declaration, and retrieve the class */
3624 Symtab *cscope = Swig_symbol_current();
3628 SwigType *ntype = ni ? nodeType(ni) : 0;
3629 while (ni && Strcmp(ntype,"namespace") == 0) {
3630 sti = Getattr(ni,"symtab");
3631 ni = firstChild(ni);
3632 ntype = nodeType(ni);
3635 Swig_symbol_setscope(sti);
3636 Delete(Namespaceprefix);
3637 Namespaceprefix = Swig_symbol_qualifiedscopename(0);
3641 template_parameters = 0;
3643 if ($$) tname = Getattr($$,"name");
3645 /* Check if the class is a template specialization */
3646 if (($$) && (Strchr(tname,'<')) && (!is_operator(tname))) {
3647 /* If a specialization. Check if defined. */
3650 String *tbase = SwigType_templateprefix(tname);
3651 tempn = Swig_symbol_clookup_local(tbase,0);
3652 if (!tempn || (Strcmp(nodeType(tempn),"template") != 0)) {
3653 SWIG_WARN_NODE_BEGIN(tempn);
3654 Swig_warning(WARN_PARSE_TEMPLATE_SP_UNDEF, Getfile($$),Getline($$),"Specialization of non-template '%s'.\n", tbase);
3655 SWIG_WARN_NODE_END(tempn);
3661 Setattr($$,"specialization","1");
3662 Setattr($$,"templatetype",nodeType($$));
3663 set_nodeType($$,"template");
3664 /* Template partial specialization */
3665 if (tempn && ($3) && ($6)) {
3667 String *targs = SwigType_templateargs(tname);
3668 tlist = SwigType_parmlist(targs);
3669 /* Printf(stdout,"targs = '%s' %s\n", targs, tlist); */
3670 if (!Getattr($$,"sym:weak")) {
3671 Setattr($$,"sym:typename","1");
3674 if (Len(tlist) != ParmList_len(Getattr(tempn,"templateparms"))) {
3675 Swig_error(Getfile($$),Getline($$),"Inconsistent argument count in template partial specialization. %d %d\n", Len(tlist), ParmList_len(Getattr(tempn,"templateparms")));
3679 /* This code builds the argument list for the partial template
3680 specialization. This is a little hairy, but the idea is as
3683 $3 contains a list of arguments supplied for the template.
3684 For example template<class T>.
3686 tlist is a list of the specialization arguments--which may be
3687 different. For example class<int,T>.
3689 tp is a copy of the arguments in the original template definition.
3691 The patching algorithm walks through the list of supplied
3692 arguments ($3), finds the position in the specialization arguments
3693 (tlist), and then patches the name in the argument list of the
3701 Parm *tp = CopyParmList(Getattr(tempn,"templateparms"));
3705 for (i = 0; i < nargs; i++){
3706 pn = Getattr(p,"name");
3707 if (Strcmp(pn,SwigType_base(Getitem(tlist,i))) == 0) {
3710 for (j = 0; j < i; j++) {
3711 p1 = nextSibling(p1);
3713 Setattr(p1,"name",pn);
3714 Setattr(p1,"partialarg","1");
3722 if (!Getattr(p1,"partialarg")) {
3724 Setattr(p1,"type", Getitem(tlist,i));
3727 p1 = nextSibling(p1);
3729 Setattr($$,"templateparms",tp);
3733 /* Patch the parameter list */
3736 ParmList *tp = CopyParmList(Getattr(tempn,"templateparms"));
3740 String *pn = Getattr(p,"name");
3741 Printf(stdout,"pn = '%s'\n", pn);
3742 if (pn) Setattr(p1,"name",pn);
3743 else Delattr(p1,"name");
3744 pn = Getattr(p,"type");
3745 if (pn) Setattr(p1,"type",pn);
3747 p1 = nextSibling(p1);
3749 Setattr($$,"templateparms",tp);
3752 Setattr($$,"templateparms",$3);
3755 Delattr($$,"specialization");
3756 Setattr($$,"partialspecialization","1");
3757 /* Create a specialized name for matching */
3760 String *fname = NewString(Getattr($$,"name"));
3766 String *n = Getattr(p,"name");
3772 for (i = 0; i < ilen; i++) {
3773 if (Strstr(Getitem(tlist,i),n)) {
3774 sprintf(tmp,"$%d",i+1);
3775 Replaceid(fname,n,tmp);
3780 /* Patch argument names with typedef */
3783 List *tparms = SwigType_parmlist(fname);
3784 ffname = SwigType_templateprefix(fname);
3785 Append(ffname,"<(");
3786 for (tt = First(tparms); tt.item; ) {
3787 SwigType *rtt = Swig_symbol_typedef_reduce(tt.item,0);
3788 SwigType *ttr = Swig_symbol_type_qualify(rtt,0);
3791 if (tt.item) Putc(',',ffname);
3796 Append(ffname,")>");
3799 String *partials = Getattr(tempn,"partials");
3801 partials = NewList();
3802 Setattr(tempn,"partials",partials);
3805 /* Printf(stdout,"partial: fname = '%s', '%s'\n", fname, Swig_symbol_typedef_reduce(fname,0)); */
3806 Append(partials,ffname);
3808 Setattr($$,"partialargs",ffname);
3809 Swig_symbol_cadd(ffname,$$);
3815 /* Need to resolve exact specialization name */
3816 /* add default args from generic template */
3817 String *ty = Swig_symbol_template_deftype(tname,0);
3818 String *fname = Swig_symbol_type_qualify(ty,0);
3819 Swig_symbol_cadd(fname,$$);
3824 Setattr($$,"templatetype",nodeType($6));
3825 set_nodeType($$,"template");
3826 Setattr($$,"templateparms", $3);
3827 if (!Getattr($$,"sym:weak")) {
3828 Setattr($$,"sym:typename","1");
3831 default_arguments($$);
3832 /* We also place a fully parameterized version in the symbol table */
3835 String *fname = NewStringf("%s<(", Getattr($$,"name"));
3838 String *n = Getattr(p,"name");
3839 if (!n) n = Getattr(p,"type");
3842 if (p) Putc(',',fname);
3845 Swig_symbol_cadd(fname,$$);
3849 Swig_symbol_setscope(cscope);
3850 Delete(Namespaceprefix);
3851 Namespaceprefix = Swig_symbol_qualifiedscopename(0);
3854 | TEMPLATE cpptype idcolon {
3855 Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit template instantiation ignored.\n");
3860 cpp_temp_possible: c_decl {
3866 | cpp_constructor_decl {
3869 | cpp_template_decl {
3872 | cpp_forward_class_decl {
3875 | cpp_conversion_operator {
3880 template_parms : templateparameters {
3881 /* Rip out the parameter names */
3886 String *name = Getattr(p,"name");
3888 /* Hmmm. Maybe it's a 'class T' parameter */
3889 char *type = Char(Getattr(p,"type"));
3890 /* Template template parameter */
3891 if (strncmp(type,"template<class> ",16) == 0) {
3894 if ((strncmp(type,"class ",6) == 0) || (strncmp(type,"typename ", 9) == 0)) {
3895 char *t = strchr(type,' ');
3896 Setattr(p,"name", t+1);
3899 Swig_error(cparse_file, cparse_line, "Missing template parameter name\n");
3910 templateparameters : templateparameter templateparameterstail {
3911 set_nextSibling($1,$2);
3917 templateparameter : templcpptype {
3918 $$ = NewParm(NewString($1), 0);
3925 templateparameterstail : COMMA templateparameter templateparameterstail {
3926 set_nextSibling($2,$3);
3932 /* Namespace support */
3934 cpp_using_decl : USING idcolon SEMI {
3935 String *uname = Swig_symbol_type_qualify($2,0);
3936 String *name = Swig_scopename_last($2);
3937 $$ = new_node("using");
3938 Setattr($$,"uname",uname);
3939 Setattr($$,"name", name);
3944 | USING NAMESPACE idcolon SEMI {
3945 Node *n = Swig_symbol_clookup($3,0);
3947 Swig_error(cparse_file, cparse_line, "Nothing known about namespace '%s'\n", $3);
3951 while (Strcmp(nodeType(n),"using") == 0) {
3952 n = Getattr(n,"node");
3955 if (Strcmp(nodeType(n),"namespace") == 0) {
3956 Symtab *current = Swig_symbol_current();
3957 Symtab *symtab = Getattr(n,"symtab");
3958 $$ = new_node("using");
3959 Setattr($$,"node",n);
3960 Setattr($$,"namespace", $3);
3961 if (current != symtab) {
3962 Swig_symbol_inherit(symtab);
3965 Swig_error(cparse_file, cparse_line, "'%s' is not a namespace.\n", $3);
3975 cpp_namespace_decl : NAMESPACE idcolon LBRACE {
3977 $1 = Swig_symbol_current();
3978 h = Swig_symbol_clookup($2,0);
3979 if (h && ($1 == Getattr(h,"sym:symtab")) && (Strcmp(nodeType(h),"namespace") == 0)) {
3980 if (Getattr(h,"alias")) {
3981 h = Getattr(h,"namespace");
3982 Swig_warning(WARN_PARSE_NAMESPACE_ALIAS, cparse_file, cparse_line, "Namespace alias '%s' not allowed here. Assuming '%s'\n",
3983 $2, Getattr(h,"name"));
3984 $2 = Getattr(h,"name");
3986 Swig_symbol_setscope(Getattr(h,"symtab"));
3988 Swig_symbol_newscope();
3989 Swig_symbol_setscopename($2);
3991 Delete(Namespaceprefix);
3992 Namespaceprefix = Swig_symbol_qualifiedscopename(0);
3993 } interface RBRACE {
3995 set_nodeType(n,"namespace");
3996 Setattr(n,"name",$2);
3997 Setattr(n,"symtab", Swig_symbol_popscope());
3998 Swig_symbol_setscope($1);
4000 Delete(Namespaceprefix);
4001 Namespaceprefix = Swig_symbol_qualifiedscopename(0);
4004 | NAMESPACE LBRACE {
4006 $1 = Swig_symbol_current();
4007 h = Swig_symbol_clookup((char *)" ",0);
4008 if (h && (Strcmp(nodeType(h),"namespace") == 0)) {
4009 Swig_symbol_setscope(Getattr(h,"symtab"));
4011 Swig_symbol_newscope();
4012 /* we don't use "__unnamed__", but a long 'empty' name */
4013 Swig_symbol_setscopename(" ");
4015 Namespaceprefix = 0;
4016 } interface RBRACE {
4018 set_nodeType($$,"namespace");
4019 Setattr($$,"unnamed","1");
4020 Setattr($$,"symtab", Swig_symbol_popscope());
4021 Swig_symbol_setscope($1);
4022 Delete(Namespaceprefix);
4023 Namespaceprefix = Swig_symbol_qualifiedscopename(0);
4026 | NAMESPACE ID EQUAL idcolon SEMI {
4027 /* Namespace alias */
4029 $$ = new_node("namespace");
4030 Setattr($$,"name",$2);
4031 Setattr($$,"alias",$4);
4032 n = Swig_symbol_clookup($4,0);
4034 Swig_error(cparse_file, cparse_line, "Unknown namespace '%s'\n", $4);
4037 if (Strcmp(nodeType(n),"namespace") != 0) {
4038 Swig_error(cparse_file, cparse_line, "'%s' is not a namespace\n",$4);
4041 while (Getattr(n,"alias")) {
4042 n = Getattr(n,"namespace");
4044 Setattr($$,"namespace",n);
4046 /* Set up a scope alias */
4047 Swig_symbol_alias($2,Getattr(n,"symtab"));
4053 cpp_members : cpp_member cpp_members {
4055 /* Insert cpp_member (including any siblings) to the front of the cpp_members linked list */
4063 set_nextSibling(pp,$2);
4069 if (cplus_mode != CPLUS_PUBLIC) {
4070 Swig_error(cparse_file,cparse_line,"%%extend can only be used in a public section\n");
4072 } cpp_members RBRACE cpp_members {
4073 $$ = new_node("extend");
4074 tag_nodes($4,"feature:extend",(char*) "1");
4076 set_nextSibling($$,$6);
4078 | include_directive { $$ = $1; }
4081 int start_line = cparse_line;
4083 Swig_error(cparse_file,start_line,"Syntax error in input(3).\n");
4090 /* ======================================================================
4092 * ====================================================================== */
4094 /* A class member. May be data or a function. Static or virtual as well */
4096 cpp_member : c_declaration { $$ = $1; }
4097 | cpp_constructor_decl {
4101 symname= make_name($$,Getattr($$,"name"), Getattr($$,"decl"));
4102 if (Strcmp(symname,Getattr($$,"name")) == 0) {
4103 /* No renaming operation. Set name to class name */
4105 yyrename = NewString(Getattr(current_class,"sym:name"));
4112 default_arguments($$);
4114 | cpp_destructor_decl { $$ = $1; }
4115 | cpp_protection_decl { $$ = $1; }
4116 | cpp_swig_directive { $$ = $1; }
4117 | cpp_conversion_operator { $$ = $1; }
4118 | cpp_forward_class_decl { $$ = $1; }
4119 | cpp_nested { $$ = $1; }
4120 | storage_class idcolon SEMI { $$ = 0; }
4121 | cpp_using_decl { $$ = $1; }
4122 | cpp_template_decl { $$ = $1; }
4123 | cpp_catch_decl { $$ = 0; }
4124 | template_directive { $$ = $1; }
4125 | warn_directive { $$ = $1; }
4126 | anonymous_bitfield { $$ = 0; }
4127 | fragment_directive {$$ = $1; }
4128 | types_directive {$$ = $1; }
4132 /* Possibly a constructor */
4133 /* Note: the use of 'type' is here to resolve a shift-reduce conflict. For example:
4135 typedef Foo (*ptr)();
4138 cpp_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end {
4140 SwigType *decl = NewStringEmpty();
4141 $$ = new_node("constructor");
4142 Setattr($$,"storage",$1);
4143 Setattr($$,"name",$2);
4144 Setattr($$,"parms",$4);
4145 SwigType_add_function(decl,$4);
4146 Setattr($$,"decl",decl);
4147 Setattr($$,"throws",$6.throws);
4148 Setattr($$,"throw",$6.throwf);
4149 if (Len(scanner_ccode)) {
4150 String *code = Copy(scanner_ccode);
4151 Setattr($$,"code",code);
4154 SetFlag($$,"feature:new");
4161 /* A destructor (hopefully) */
4163 cpp_destructor_decl : NOT idtemplate LPAREN parms RPAREN cpp_end {
4164 String *name = NewStringf("%s",$2);
4165 if (*(Char(name)) != '~') Insert(name,0,"~");
4166 $$ = new_node("destructor");
4167 Setattr($$,"name",name);
4169 if (Len(scanner_ccode)) {
4170 String *code = Copy(scanner_ccode);
4171 Setattr($$,"code",code);
4175 String *decl = NewStringEmpty();
4176 SwigType_add_function(decl,$4);
4177 Setattr($$,"decl",decl);
4180 Setattr($$,"throws",$6.throws);
4181 Setattr($$,"throw",$6.throwf);
4185 /* A virtual destructor */
4187 | VIRTUAL NOT idtemplate LPAREN parms RPAREN cpp_vend {
4190 $$ = new_node("destructor");
4191 /* Check for template names. If the class is a template
4192 and the constructor is missing the template part, we
4195 c = strchr(Char(Classprefix),'<');
4196 if (c && !Strchr($3,'<')) {
4197 $3 = NewStringf("%s%s",$3,c);
4200 Setattr($$,"storage","virtual");
4201 name = NewStringf("%s",$3);
4202 if (*(Char(name)) != '~') Insert(name,0,"~");
4203 Setattr($$,"name",name);
4205 Setattr($$,"throws",$7.throws);
4206 Setattr($$,"throw",$7.throwf);
4208 Setattr($$,"value","0");
4210 if (Len(scanner_ccode)) {
4211 String *code = Copy(scanner_ccode);
4212 Setattr($$,"code",code);
4216 String *decl = NewStringEmpty();
4217 SwigType_add_function(decl,$5);
4218 Setattr($$,"decl",decl);
4227 /* C++ type conversion operator */
4228 cpp_conversion_operator : storage_class COPERATOR type pointer LPAREN parms RPAREN cpp_vend {
4229 $$ = new_node("cdecl");
4230 Setattr($$,"type",$3);
4231 Setattr($$,"name",$2);
4232 Setattr($$,"storage",$1);
4234 SwigType_add_function($4,$6);
4236 SwigType_push($4,$8.qualifier);
4238 Setattr($$,"decl",$4);
4239 Setattr($$,"parms",$6);
4240 Setattr($$,"conversion_operator","1");
4243 | storage_class COPERATOR type AND LPAREN parms RPAREN cpp_vend {
4245 $$ = new_node("cdecl");
4246 Setattr($$,"type",$3);
4247 Setattr($$,"name",$2);
4248 Setattr($$,"storage",$1);
4249 decl = NewStringEmpty();
4250 SwigType_add_reference(decl);
4251 SwigType_add_function(decl,$6);
4253 SwigType_push(decl,$8.qualifier);
4255 Setattr($$,"decl",decl);
4256 Setattr($$,"parms",$6);
4257 Setattr($$,"conversion_operator","1");
4261 | storage_class COPERATOR type LPAREN parms RPAREN cpp_vend {
4262 String *t = NewStringEmpty();
4263 $$ = new_node("cdecl");
4264 Setattr($$,"type",$3);
4265 Setattr($$,"name",$2);
4266 Setattr($$,"storage",$1);
4267 SwigType_add_function(t,$5);
4269 SwigType_push(t,$7.qualifier);
4271 Setattr($$,"decl",t);
4272 Setattr($$,"parms",$5);
4273 Setattr($$,"conversion_operator","1");
4278 /* isolated catch clause. */
4280 cpp_catch_decl : CATCH LPAREN parms RPAREN LBRACE {
4281 skip_balanced('{','}');
4287 cpp_protection_decl : PUBLIC COLON {
4288 $$ = new_node("access");
4289 Setattr($$,"kind","public");
4290 cplus_mode = CPLUS_PUBLIC;
4295 $$ = new_node("access");
4296 Setattr($$,"kind","private");
4297 cplus_mode = CPLUS_PRIVATE;
4303 $$ = new_node("access");
4304 Setattr($$,"kind","protected");
4305 cplus_mode = CPLUS_PROTECTED;
4310 /* ----------------------------------------------------------------------
4311 Nested structure. This is a sick "hack". If we encounter
4312 a nested structure, we're going to grab the text of its definition and
4313 feed it back into the scanner. In the meantime, we need to grab
4314 variable declaration information and generate the associated wrapper
4317 This really only works in a limited sense. Since we use the
4318 code attached to the nested class to generate both C/C++ code,
4319 it can't have any SWIG directives in it. It also needs to be parsable
4320 by SWIG or this whole thing is going to puke.
4321 ---------------------------------------------------------------------- */
4323 /* A struct sname { } id; declaration */
4325 cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
4326 } nested_decl SEMI {
4328 if (cplus_mode == CPLUS_PUBLIC) {
4329 if ($6.id && strcmp($2, "class") != 0) {
4330 Nested *n = (Nested *) malloc(sizeof(Nested));
4331 n->code = NewStringEmpty();
4332 Printv(n->code, "typedef ", $2, " ",
4333 Char(scanner_ccode), " $classname_", $6.id, ";\n", NIL);
4335 n->name = Swig_copy_string($6.id);
4336 n->line = cparse_start_line;
4337 n->type = NewStringEmpty();
4340 SwigType_push(n->type, $6.type);
4344 Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2);
4345 if (strcmp($2, "class") == 0) {
4346 /* For now, just treat the nested class as a forward
4347 * declaration (SF bug #909387). */
4348 $$ = new_node("classforward");
4349 Setfile($$,cparse_file);
4350 Setline($$,cparse_line);
4351 Setattr($$,"kind",$2);
4352 Setattr($$,"name",$3);
4353 Setattr($$,"sym:weak", "1");
4359 /* A struct { } id; declaration */
4360 | storage_class cpptype LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
4361 } nested_decl SEMI {
4363 if (cplus_mode == CPLUS_PUBLIC) {
4364 if (strcmp($2,"class") == 0) {
4365 Swig_warning(WARN_PARSE_NESTED_CLASS,cparse_file, cparse_line,"Nested class not currently supported (ignored)\n");
4366 /* Generate some code for a new class */
4368 /* Generate some code for a new class */
4369 Nested *n = (Nested *) malloc(sizeof(Nested));
4370 n->code = NewStringEmpty();
4371 Printv(n->code, "typedef ", $2, " " ,
4372 Char(scanner_ccode), " $classname_", $5.id, ";\n",NIL);
4373 n->name = Swig_copy_string($5.id);
4374 n->line = cparse_start_line;
4375 n->type = NewStringEmpty();
4378 SwigType_push(n->type,$5.type);
4382 Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2);
4386 /* A 'class name : base_list { };' declaration, always ignored */
4388 This fixes derived_nested.i, but it adds one shift/reduce. Anyway,
4389 we are waiting for the nested class support.
4391 | storage_class cpptype idcolon COLON base_list LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
4394 if (cplus_mode == CPLUS_PUBLIC) {
4395 Swig_warning(WARN_PARSE_NESTED_CLASS,cparse_file, cparse_line,"Nested class not currently supported (ignored)\n");
4399 | TEMPLATE LESSTHAN template_parms GREATERTHAN cpptype idcolon LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
4402 if (cplus_mode == CPLUS_PUBLIC) {
4403 Swig_warning(WARN_PARSE_NESTED_CLASS,cparse_file, cparse_line,"Nested class not currently supported (ignored)\n");
4409 nested_decl : declarator { $$ = $1;}
4410 | empty { $$.id = 0; }
4414 /* These directives can be included inside a class definition */
4416 cpp_swig_directive: pragma_directive { $$ = $1; }
4418 /* A constant (includes #defines) inside a class */
4419 | constant_directive { $$ = $1; }
4421 /* This is the new style rename */
4423 | name_directive { $$ = $1; }
4425 /* rename directive */
4426 | rename_directive { $$ = $1; }
4427 | feature_directive { $$ = $1; }
4428 | varargs_directive { $$ = $1; }
4429 | insert_directive { $$ = $1; }
4430 | typemap_directive { $$ = $1; }
4431 | apply_directive { $$ = $1; }
4432 | clear_directive { $$ = $1; }
4433 | echo_directive { $$ = $1; }
4436 cpp_end : cpp_const SEMI {
4437 Clear(scanner_ccode);
4438 $$.throws = $1.throws;
4439 $$.throwf = $1.throwf;
4441 | cpp_const LBRACE {
4442 skip_balanced('{','}');
4443 $$.throws = $1.throws;
4444 $$.throwf = $1.throwf;
4448 cpp_vend : cpp_const SEMI {
4449 Clear(scanner_ccode);
4451 $$.qualifier = $1.qualifier;
4453 $$.throws = $1.throws;
4454 $$.throwf = $1.throwf;
4456 | cpp_const EQUAL definetype SEMI {
4457 Clear(scanner_ccode);
4459 $$.qualifier = $1.qualifier;
4461 $$.throws = $1.throws;
4462 $$.throwf = $1.throwf;
4464 | cpp_const LBRACE {
4465 skip_balanced('{','}');
4467 $$.qualifier = $1.qualifier;
4469 $$.throws = $1.throws;
4470 $$.throwf = $1.throwf;
4475 anonymous_bitfield : storage_class type COLON expr SEMI { };
4477 /* ======================================================================
4479 * ====================================================================== */
4481 storage_class : EXTERN { $$ = "extern"; }
4483 if (strcmp($2,"C") == 0) {
4486 Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\".\n", $2);
4490 | STATIC { $$ = "static"; }
4491 | TYPEDEF { $$ = "typedef"; }
4492 | VIRTUAL { $$ = "virtual"; }
4493 | FRIEND { $$ = "friend"; }
4494 | EXPLICIT { $$ = "explicit"; }
4498 /* ------------------------------------------------------------------------------
4499 Function parameter lists
4500 ------------------------------------------------------------------------------ */
4507 Replace(Getattr(p,"type"),"typename ", "", DOH_REPLACE_ANY);
4513 rawparms : parm ptail {
4514 set_nextSibling($1,$2);
4520 ptail : COMMA parm ptail {
4521 set_nextSibling($2,$3);
4528 parm : rawtype parameter_declarator {
4529 SwigType_push($1,$2.type);
4530 $$ = NewParm($1,$2.id);
4531 Setfile($$,cparse_file);
4532 Setline($$,cparse_line);
4534 Setattr($$,"value",$2.defarg);
4538 | TEMPLATE LESSTHAN cpptype GREATERTHAN cpptype idcolon def_args {
4539 $$ = NewParm(NewStringf("template<class> %s %s", $5,$6), 0);
4540 Setfile($$,cparse_file);
4541 Setline($$,cparse_line);
4543 Setattr($$,"value",$7.val);
4546 | PERIOD PERIOD PERIOD {
4547 SwigType *t = NewString("v(...)");
4549 Setfile($$,cparse_file);
4550 Setline($$,cparse_line);
4554 valparms : rawvalparms {
4559 if (Getattr(p,"type")) {
4560 Replace(Getattr(p,"type"),"typename ", "", DOH_REPLACE_ANY);
4567 rawvalparms : valparm valptail {
4568 set_nextSibling($1,$2);
4574 valptail : COMMA valparm valptail {
4575 set_nextSibling($2,$3);
4585 /* We need to make a possible adjustment for integer parameters. */
4590 type = Getattr($1,"type");
4591 n = Swig_symbol_clookup(type,0); /* See if we can find a node that matches the typename */
4592 if ((n) && (Strcmp(nodeType(n),"cdecl") == 0)) {
4593 SwigType *decl = Getattr(n,"decl");
4594 if (!SwigType_isfunction(decl)) {
4595 String *value = Getattr(n,"value");
4597 String *v = Copy(value);
4598 Setattr($1,"type",v);
4612 Setfile($$,cparse_file);
4613 Setline($$,cparse_line);
4614 Setattr($$,"value",$1.val);
4618 def_args : EQUAL definetype {
4620 if ($2.type == T_ERROR) {
4621 Swig_warning(WARN_PARSE_BAD_DEFAULT,cparse_file, cparse_line, "Can't set default argument (ignored)\n");
4629 | EQUAL definetype LBRACKET expr RBRACKET {
4631 if ($2.type == T_ERROR) {
4632 Swig_warning(WARN_PARSE_BAD_DEFAULT,cparse_file, cparse_line, "Can't set default argument (ignored)\n");
4640 $$.val = NewStringf("%s[%s]",$2.val,$4.val);
4644 skip_balanced('{','}');
4656 $$.bitfield = $2.val;
4670 parameter_declarator : declarator def_args {
4672 $$.defarg = $2.rawval ? $2.rawval : $2.val;
4674 | abstract_declarator def_args {
4676 $$.defarg = $2.rawval ? $2.rawval : $2.val;
4681 $$.defarg = $1.rawval ? $1.rawval : $1.val;
4685 typemap_parameter_declarator : declarator {
4687 if (SwigType_isfunction($1.type)) {
4688 Delete(SwigType_pop_function($1.type));
4689 } else if (SwigType_isarray($1.type)) {
4690 SwigType *ta = SwigType_pop_arrays($1.type);
4691 if (SwigType_isfunction($1.type)) {
4692 Delete(SwigType_pop_function($1.type));
4696 SwigType_push($1.type,ta);
4702 | abstract_declarator {
4704 if (SwigType_isfunction($1.type)) {
4705 Delete(SwigType_pop_function($1.type));
4706 } else if (SwigType_isarray($1.type)) {
4707 SwigType *ta = SwigType_pop_arrays($1.type);
4708 if (SwigType_isfunction($1.type)) {
4709 Delete(SwigType_pop_function($1.type));
4713 SwigType_push($1.type,ta);
4727 declarator : pointer notso_direct_declarator {
4730 SwigType_push($1,$$.type);
4735 | pointer AND notso_direct_declarator {
4737 SwigType_add_reference($1);
4739 SwigType_push($1,$$.type);
4744 | direct_declarator {
4746 if (!$$.type) $$.type = NewStringEmpty();
4748 | AND notso_direct_declarator {
4750 $$.type = NewStringEmpty();
4751 SwigType_add_reference($$.type);
4753 SwigType_push($$.type,$2.type);
4757 | idcolon DSTAR notso_direct_declarator {
4758 SwigType *t = NewStringEmpty();
4761 SwigType_add_memberpointer(t,$1);
4763 SwigType_push(t,$$.type);
4768 | pointer idcolon DSTAR notso_direct_declarator {
4769 SwigType *t = NewStringEmpty();
4771 SwigType_add_memberpointer(t,$2);
4772 SwigType_push($1,t);
4774 SwigType_push($1,$$.type);
4780 | pointer idcolon DSTAR AND notso_direct_declarator {
4782 SwigType_add_memberpointer($1,$2);
4783 SwigType_add_reference($1);
4785 SwigType_push($1,$$.type);
4790 | idcolon DSTAR AND notso_direct_declarator {
4791 SwigType *t = NewStringEmpty();
4793 SwigType_add_memberpointer(t,$1);
4794 SwigType_add_reference(t);
4796 SwigType_push(t,$$.type);
4803 notso_direct_declarator : idcolon {
4804 /* Note: This is non-standard C. Template declarator is allowed to follow an identifier */
4811 $$.id = Char(NewStringf("~%s",$2));
4817 /* This generate a shift-reduce conflict with constructors */
4818 | LPAREN idcolon RPAREN {
4826 | LPAREN AND idcolon RPAREN {
4833 /* Technically, this should be LPAREN declarator RPAREN, but we get reduce/reduce conflicts */
4834 | LPAREN pointer notso_direct_declarator RPAREN {
4837 SwigType_push($2,$$.type);
4842 | LPAREN idcolon DSTAR notso_direct_declarator RPAREN {
4845 t = NewStringEmpty();
4846 SwigType_add_memberpointer(t,$2);
4848 SwigType_push(t,$$.type);
4853 | notso_direct_declarator LBRACKET RBRACKET {
4856 t = NewStringEmpty();
4857 SwigType_add_array(t,(char*)"");
4859 SwigType_push(t,$$.type);
4864 | notso_direct_declarator LBRACKET expr RBRACKET {
4867 t = NewStringEmpty();
4868 SwigType_add_array(t,$3.val);
4870 SwigType_push(t,$$.type);
4875 | notso_direct_declarator LPAREN parms RPAREN {
4878 t = NewStringEmpty();
4879 SwigType_add_function(t,$3);
4880 if (!$$.have_parms) {
4887 SwigType_push(t, $$.type);
4894 direct_declarator : idcolon {
4895 /* Note: This is non-standard C. Template declarator is allowed to follow an identifier */
4903 $$.id = Char(NewStringf("~%s",$2));
4909 /* This generate a shift-reduce conflict with constructors */
4911 | LPAREN idcolon RPAREN {
4918 /* Technically, this should be LPAREN declarator RPAREN, but we get reduce/reduce conflicts */
4919 | LPAREN pointer direct_declarator RPAREN {
4922 SwigType_push($2,$$.type);
4927 | LPAREN AND direct_declarator RPAREN {
4930 $$.type = NewStringEmpty();
4932 SwigType_add_reference($$.type);
4934 | LPAREN idcolon DSTAR direct_declarator RPAREN {
4937 t = NewStringEmpty();
4938 SwigType_add_memberpointer(t,$2);
4940 SwigType_push(t,$$.type);
4945 | direct_declarator LBRACKET RBRACKET {
4948 t = NewStringEmpty();
4949 SwigType_add_array(t,(char*)"");
4951 SwigType_push(t,$$.type);
4956 | direct_declarator LBRACKET expr RBRACKET {
4959 t = NewStringEmpty();
4960 SwigType_add_array(t,$3.val);
4962 SwigType_push(t,$$.type);
4967 | direct_declarator LPAREN parms RPAREN {
4970 t = NewStringEmpty();
4971 SwigType_add_function(t,$3);
4972 if (!$$.have_parms) {
4979 SwigType_push(t, $$.type);
4986 abstract_declarator : pointer {
4992 | pointer direct_abstract_declarator {
4994 SwigType_push($1,$2.type);
5000 SwigType_add_reference($$.type);
5005 | pointer AND direct_abstract_declarator {
5007 SwigType_add_reference($1);
5009 SwigType_push($1,$$.type);
5014 | direct_abstract_declarator {
5017 | AND direct_abstract_declarator {
5019 $$.type = NewStringEmpty();
5020 SwigType_add_reference($$.type);
5022 SwigType_push($$.type,$2.type);
5030 $$.type = NewStringEmpty();
5031 SwigType_add_reference($$.type);
5034 $$.type = NewStringEmpty();
5035 SwigType_add_memberpointer($$.type,$1);
5040 | pointer idcolon DSTAR {
5041 SwigType *t = NewStringEmpty();
5046 SwigType_add_memberpointer(t,$2);
5047 SwigType_push($$.type,t);
5050 | pointer idcolon DSTAR direct_abstract_declarator {
5052 SwigType_add_memberpointer($1,$2);
5054 SwigType_push($1,$$.type);
5061 direct_abstract_declarator : direct_abstract_declarator LBRACKET RBRACKET {
5064 t = NewStringEmpty();
5065 SwigType_add_array(t,(char*)"");
5067 SwigType_push(t,$$.type);
5072 | direct_abstract_declarator LBRACKET expr RBRACKET {
5075 t = NewStringEmpty();
5076 SwigType_add_array(t,$3.val);
5078 SwigType_push(t,$$.type);
5083 | LBRACKET RBRACKET {
5084 $$.type = NewStringEmpty();
5088 SwigType_add_array($$.type,(char*)"");
5090 | LBRACKET expr RBRACKET {
5091 $$.type = NewStringEmpty();
5095 SwigType_add_array($$.type,$2.val);
5097 | LPAREN abstract_declarator RPAREN {
5100 | direct_abstract_declarator LPAREN parms RPAREN {
5103 t = NewStringEmpty();
5104 SwigType_add_function(t,$3);
5108 SwigType_push(t,$$.type);
5112 if (!$$.have_parms) {
5117 | LPAREN parms RPAREN {
5118 $$.type = NewStringEmpty();
5119 SwigType_add_function($$.type,$2);
5127 pointer : STAR type_qualifier pointer {
5128 $$ = NewStringEmpty();
5129 SwigType_add_pointer($$);
5130 SwigType_push($$,$2);
5131 SwigType_push($$,$3);
5135 $$ = NewStringEmpty();
5136 SwigType_add_pointer($$);
5137 SwigType_push($$,$2);
5140 | STAR type_qualifier {
5141 $$ = NewStringEmpty();
5142 SwigType_add_pointer($$);
5143 SwigType_push($$,$2);
5146 $$ = NewStringEmpty();
5147 SwigType_add_pointer($$);
5151 type_qualifier : type_qualifier_raw {
5152 $$ = NewStringEmpty();
5153 if ($1) SwigType_add_qualifier($$,$1);
5155 | type_qualifier_raw type_qualifier {
5157 if ($1) SwigType_add_qualifier($$,$1);
5161 type_qualifier_raw : CONST_QUAL { $$ = "const"; }
5162 | VOLATILE { $$ = "volatile"; }
5163 | REGISTER { $$ = 0; }
5166 /* Data type must be a built in type or an identifier for user-defined types
5167 This type can be preceded by a modifier. */
5171 Replace($$,"typename ","", DOH_REPLACE_ANY);
5175 rawtype : type_qualifier type_right {
5177 SwigType_push($$,$1);
5179 | type_right { $$ = $1; }
5180 | type_right type_qualifier {
5182 SwigType_push($$,$2);
5184 | type_qualifier type_right type_qualifier {
5186 SwigType_push($$,$3);
5187 SwigType_push($$,$1);
5191 type_right : primitive_type { $$ = $1;
5192 /* Printf(stdout,"primitive = '%s'\n", $$);*/
5194 | TYPE_BOOL { $$ = $1; }
5195 | TYPE_VOID { $$ = $1; }
5196 | TYPE_TYPEDEF template_decl { $$ = NewStringf("%s%s",$1,$2); }
5197 | ENUM idcolon { $$ = NewStringf("enum %s", $2); }
5198 | TYPE_RAW { $$ = $1; }
5204 $$ = NewStringf("%s %s", $1, $2);
5208 primitive_type : primitive_type_list {
5209 if (!$1.type) $1.type = NewString("int");
5211 $$ = NewStringf("%s %s", $1.us, $1.type);
5217 if (Cmp($$,"signed int") == 0) {
5219 $$ = NewString("int");
5220 } else if (Cmp($$,"signed long") == 0) {
5222 $$ = NewString("long");
5223 } else if (Cmp($$,"signed short") == 0) {
5225 $$ = NewString("short");
5226 } else if (Cmp($$,"signed long long") == 0) {
5228 $$ = NewString("long long");
5233 primitive_type_list : type_specifier {
5236 | type_specifier primitive_type_list {
5237 if ($1.us && $2.us) {
5238 Swig_error(cparse_file, cparse_line, "Extra %s specifier.\n", $2.us);
5241 if ($1.us) $$.us = $1.us;
5243 if (!$2.type) $$.type = $1.type;
5246 if ((Cmp($1.type,"long") == 0)) {
5247 if ((Cmp($2.type,"long") == 0) || (Strncmp($2.type,"double",6) == 0)) {
5248 $$.type = NewStringf("long %s", $2.type);
5249 } else if (Cmp($2.type,"int") == 0) {
5254 } else if ((Cmp($1.type,"short")) == 0) {
5255 if (Cmp($2.type,"int") == 0) {
5260 } else if (Cmp($1.type,"int") == 0) {
5262 } else if (Cmp($1.type,"double") == 0) {
5263 if (Cmp($2.type,"long") == 0) {
5264 $$.type = NewString("long double");
5265 } else if (Cmp($2.type,"complex") == 0) {
5266 $$.type = NewString("double complex");
5270 } else if (Cmp($1.type,"float") == 0) {
5271 if (Cmp($2.type,"complex") == 0) {
5272 $$.type = NewString("float complex");
5276 } else if (Cmp($1.type,"complex") == 0) {
5277 $$.type = NewStringf("%s complex", $2.type);
5282 Swig_error(cparse_file, cparse_line, "Extra %s specifier.\n", $1.type);
5290 type_specifier : TYPE_INT {
5291 $$.type = NewString("int");
5295 $$.type = NewString("short");
5299 $$.type = NewString("long");
5303 $$.type = NewString("char");
5307 $$.type = NewString("wchar_t");
5311 $$.type = NewString("float");
5315 $$.type = NewString("double");
5319 $$.us = NewString("signed");
5323 $$.us = NewString("unsigned");
5327 $$.type = NewString("complex");
5330 | TYPE_NON_ISO_INT8 {
5331 $$.type = NewString("__int8");
5334 | TYPE_NON_ISO_INT16 {
5335 $$.type = NewString("__int16");
5338 | TYPE_NON_ISO_INT32 {
5339 $$.type = NewString("__int32");
5342 | TYPE_NON_ISO_INT64 {
5343 $$.type = NewString("__int64");
5348 definetype : { /* scanner_check_typedef(); */ } expr {
5350 if ($$.type == T_STRING) {
5351 $$.rawval = NewStringf("\"%(escape)s\"",$$.val);
5352 } else if ($$.type != T_CHAR) {
5358 scanner_ignore_typedef();
5362 $$.val = NewString($1);
5363 $$.rawval = NewStringf("\"%(escape)s\"",$$.val);
5372 /* Some stuff for handling enums */
5374 ename : ID { $$ = $1; }
5375 | empty { $$ = (char *) 0;}
5378 enumlist : enumlist COMMA edecl {
5380 /* Ignore if there is a trailing comma in the enum list */
5382 Node *leftSibling = Getattr($1,"_last");
5386 set_nextSibling(leftSibling,$3);
5387 Setattr($1,"_last",$3);
5394 Setattr($1,"_last",$1);
5400 SwigType *type = NewSwigType(T_INT);
5401 $$ = new_node("enumitem");
5402 Setattr($$,"name",$1);
5403 Setattr($$,"type",type);
5404 SetFlag($$,"feature:immutable");
5408 $$ = new_node("enumitem");
5409 Setattr($$,"name",$1);
5410 Setattr($$,"enumvalue", $3.val);
5411 if ($3.type == T_CHAR) {
5412 SwigType *type = NewSwigType(T_CHAR);
5413 Setattr($$,"value",NewStringf("\'%(escape)s\'", $3.val));
5414 Setattr($$,"type",type);
5417 SwigType *type = NewSwigType(T_INT);
5418 Setattr($$,"value",$1);
5419 Setattr($$,"type",type);
5422 SetFlag($$,"feature:immutable");
5429 if (($$.type != T_INT) && ($$.type != T_UINT) &&
5430 ($$.type != T_LONG) && ($$.type != T_ULONG) &&
5431 ($$.type != T_SHORT) && ($$.type != T_USHORT) &&
5432 ($$.type != T_SCHAR) && ($$.type != T_UCHAR) &&
5433 ($$.type != T_CHAR)) {
5434 Swig_error(cparse_file,cparse_line,"Type error. Expecting an int\n");
5436 if ($$.type == T_CHAR) $$.type = T_INT;
5440 /* Arithmetic expressions. Used for constants, C++ templates, and other cool stuff. */
5442 expr : valexpr { $$ = $1; }
5447 /* Check if value is in scope */
5448 n = Swig_symbol_clookup($1,0);
5450 /* A band-aid for enum values used in expressions. */
5451 if (Strcmp(nodeType(n),"enumitem") == 0) {
5452 String *q = Swig_symbol_qualified(n);
5454 $$.val = NewStringf("%s::%s", q, Getattr(n,"name"));
5462 valexpr : exprnum { $$ = $1; }
5464 $$.val = NewString($1);
5467 | SIZEOF LPAREN type parameter_declarator RPAREN {
5468 SwigType_push($3,$4.type);
5469 $$.val = NewStringf("sizeof(%s)",SwigType_str($3,0));
5472 | exprcompound { $$ = $1; }
5474 $$.val = NewString($1);
5476 $$.rawval = NewStringf("'%(escape)s'", $$.val);
5478 $$.rawval = NewString("'\\0'");
5487 | LPAREN expr RPAREN %prec CAST {
5488 $$.val = NewStringf("(%s)",$2.val);
5492 /* A few common casting operations */
5494 | LPAREN expr RPAREN expr %prec CAST {
5496 if ($4.type != T_STRING) {
5503 $$.val = NewStringf("(%s)%s", $2.val, $4.val); /* SwigType_str and decimal points don't mix! */
5506 $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $4.val);
5511 | LPAREN expr pointer RPAREN expr %prec CAST {
5513 if ($5.type != T_STRING) {
5514 SwigType_push($2.val,$3);
5515 $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val);
5518 | LPAREN expr AND RPAREN expr %prec CAST {
5520 if ($5.type != T_STRING) {
5521 SwigType_add_reference($2.val);
5522 $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val);
5525 | LPAREN expr pointer AND RPAREN expr %prec CAST {
5527 if ($6.type != T_STRING) {
5528 SwigType_push($2.val,$3);
5529 SwigType_add_reference($2.val);
5530 $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $6.val);
5535 $$.val = NewStringf("&%s",$2.val);
5539 $$.val = NewStringf("*%s",$2.val);
5543 exprnum : NUM_INT { $$ = $1; }
5544 | NUM_FLOAT { $$ = $1; }
5545 | NUM_UNSIGNED { $$ = $1; }
5546 | NUM_LONG { $$ = $1; }
5547 | NUM_ULONG { $$ = $1; }
5548 | NUM_LONGLONG { $$ = $1; }
5549 | NUM_ULONGLONG { $$ = $1; }
5552 exprcompound : expr PLUS expr {
5553 $$.val = NewStringf("%s+%s",$1.val,$3.val);
5554 $$.type = promote($1.type,$3.type);
5557 $$.val = NewStringf("%s-%s",$1.val,$3.val);
5558 $$.type = promote($1.type,$3.type);
5561 $$.val = NewStringf("%s*%s",$1.val,$3.val);
5562 $$.type = promote($1.type,$3.type);
5565 $$.val = NewStringf("%s/%s",$1.val,$3.val);
5566 $$.type = promote($1.type,$3.type);
5568 | expr MODULUS expr {
5569 $$.val = NewStringf("%s%%%s",$1.val,$3.val);
5570 $$.type = promote($1.type,$3.type);
5573 $$.val = NewStringf("%s&%s",$1.val,$3.val);
5574 $$.type = promote($1.type,$3.type);
5577 $$.val = NewStringf("%s|%s",$1.val,$3.val);
5578 $$.type = promote($1.type,$3.type);
5581 $$.val = NewStringf("%s^%s",$1.val,$3.val);
5582 $$.type = promote($1.type,$3.type);
5584 | expr LSHIFT expr {
5585 $$.val = NewStringf("%s << %s",$1.val,$3.val);
5586 $$.type = promote_type($1.type);
5588 | expr RSHIFT expr {
5589 $$.val = NewStringf("%s >> %s",$1.val,$3.val);
5590 $$.type = promote_type($1.type);
5593 $$.val = NewStringf("%s&&%s",$1.val,$3.val);
5597 $$.val = NewStringf("%s||%s",$1.val,$3.val);
5600 | expr EQUALTO expr {
5601 $$.val = NewStringf("%s==%s",$1.val,$3.val);
5604 | expr NOTEQUALTO expr {
5605 $$.val = NewStringf("%s!=%s",$1.val,$3.val);
5608 /* Sadly this causes 2 reduce-reduce conflicts with templates. FIXME resolve these.
5609 | expr GREATERTHAN expr {
5610 $$.val = NewStringf("%s SWIG_LT %s", $1.val, $3.val);
5613 | expr LESSTHAN expr {
5614 $$.val = NewStringf("%s SWIG_GT %s", $1.val, $3.val);
5618 | expr GREATERTHANOREQUALTO expr {
5619 /* Putting >= in the expression literally causes an infinite
5620 * loop somewhere in the type system. Just workaround for now
5621 * - SWIG_GE is defined in swiglabels.swg. */
5622 $$.val = NewStringf("%s SWIG_GE %s", $1.val, $3.val);
5625 | expr LESSTHANOREQUALTO expr {
5626 $$.val = NewStringf("%s SWIG_LE %s", $1.val, $3.val);
5629 | expr QUESTIONMARK expr COLON expr %prec QUESTIONMARK {
5630 $$.val = NewStringf("%s?%s:%s", $1.val, $3.val, $5.val);
5631 /* This may not be exactly right, but is probably good enough
5632 * for the purposes of parsing constant expressions. */
5633 $$.type = promote($3.type, $5.type);
5635 | MINUS expr %prec UMINUS {
5636 $$.val = NewStringf("-%s",$2.val);
5639 | PLUS expr %prec UMINUS {
5640 $$.val = NewStringf("+%s",$2.val);
5644 $$.val = NewStringf("~%s",$2.val);
5648 $$.val = NewStringf("!%s",$2.val);
5653 skip_balanced('(',')');
5654 qty = Swig_symbol_type_qualify($1,0);
5655 if (SwigType_istemplate(qty)) {
5656 String *nstr = SwigType_namestr(qty);
5660 $$.val = NewStringf("%s%s",qty,scanner_ccode);
5661 Clear(scanner_ccode);
5667 inherit : raw_inherit {
5672 raw_inherit : COLON { inherit_list = 1; } base_list { $$ = $3; inherit_list = 0; }
5676 base_list : base_specifier {
5677 Hash *list = NewHash();
5679 Node *name = Getattr(base,"name");
5680 List *lpublic = NewList();
5681 List *lprotected = NewList();
5682 List *lprivate = NewList();
5683 Setattr(list,"public",lpublic);
5684 Setattr(list,"protected",lprotected);
5685 Setattr(list,"private",lprivate);
5689 Append(Getattr(list,Getattr(base,"access")),name);
5693 | base_list COMMA base_specifier {
5696 Node *name = Getattr(base,"name");
5697 Append(Getattr(list,Getattr(base,"access")),name);
5702 base_specifier : opt_virtual idcolon {
5704 Setfile($$,cparse_file);
5705 Setline($$,cparse_line);
5706 Setattr($$,"name",$2);
5707 if (last_cpptype && (Strcmp(last_cpptype,"struct") != 0)) {
5708 Setattr($$,"access","private");
5709 Swig_warning(WARN_PARSE_NO_ACCESS,cparse_file,cparse_line,
5710 "No access specifier given for base class %s (ignored).\n",$2);
5712 Setattr($$,"access","public");
5715 | opt_virtual access_specifier opt_virtual idcolon {
5717 Setfile($$,cparse_file);
5718 Setline($$,cparse_line);
5719 Setattr($$,"name",$4);
5720 Setattr($$,"access",$2);
5721 if (Strcmp($2,"public") != 0) {
5722 Swig_warning(WARN_PARSE_PRIVATE_INHERIT, cparse_file,
5723 cparse_line,"%s inheritance ignored.\n", $2);
5728 access_specifier : PUBLIC { $$ = (char*)"public"; }
5729 | PRIVATE { $$ = (char*)"private"; }
5730 | PROTECTED { $$ = (char*)"protected"; }
5734 templcpptype : CLASS {
5735 $$ = (char*)"class";
5736 if (!inherit_list) last_cpptype = $$;
5739 $$ = (char *)"typename";
5740 if (!inherit_list) last_cpptype = $$;
5744 cpptype : templcpptype {
5748 $$ = (char*)"struct";
5749 if (!inherit_list) last_cpptype = $$;
5752 $$ = (char*)"union";
5753 if (!inherit_list) last_cpptype = $$;
5757 opt_virtual : VIRTUAL
5761 cpp_const : type_qualifier {
5766 | THROW LPAREN parms RPAREN {
5769 $$.throwf = NewString("1");
5771 | type_qualifier THROW LPAREN parms RPAREN {
5774 $$.throwf = NewString("1");
5783 ctor_end : cpp_const ctor_initializer SEMI {
5784 Clear(scanner_ccode);
5787 $$.throws = $1.throws;
5788 $$.throwf = $1.throwf;
5790 | cpp_const ctor_initializer LBRACE {
5791 skip_balanced('{','}');
5794 $$.throws = $1.throws;
5795 $$.throwf = $1.throwf;
5797 | LPAREN parms RPAREN SEMI {
5798 Clear(scanner_ccode);
5805 | LPAREN parms RPAREN LBRACE {
5806 skip_balanced('{','}');
5813 | EQUAL definetype SEMI {
5821 ctor_initializer : COLON mem_initializer_list
5825 mem_initializer_list : mem_initializer
5826 | mem_initializer_list COMMA mem_initializer
5829 mem_initializer : idcolon LPAREN {
5830 skip_balanced('(',')');
5831 Clear(scanner_ccode);
5835 template_decl : LESSTHAN valparms GREATERTHAN {
5836 String *s = NewStringEmpty();
5837 SwigType_add_template(s,$2);
5841 | empty { $$ = (char*)""; }
5844 idstring : ID { $$ = $1; }
5845 | string { $$ = $1; }
5848 idstringopt : idstring { $$ = $1; }
5852 idcolon : idtemplate idcolontail {
5854 if (!$$) $$ = NewStringf("%s%s", $1,$2);
5857 | NONID DCOLON idtemplate idcolontail {
5858 $$ = NewStringf("::%s%s",$3,$4);
5864 | NONID DCOLON idtemplate {
5865 $$ = NewStringf("::%s",$3);
5870 | NONID DCOLON OPERATOR {
5871 $$ = NewStringf("::%s",$3);
5875 idcolontail : DCOLON idtemplate idcolontail {
5876 $$ = NewStringf("::%s%s",$2,$3);
5879 | DCOLON idtemplate {
5880 $$ = NewStringf("::%s",$2);
5883 $$ = NewStringf("::%s",$2);
5885 /* | DCOLON COPERATOR {
5889 | DCNOT idtemplate {
5890 $$ = NewStringf("::~%s",$2);
5895 idtemplate : ID template_decl {
5896 $$ = NewStringf("%s%s",$1,$2);
5903 /* Identifier, but no templates */
5904 idcolonnt : ID idcolontailnt {
5906 if (!$$) $$ = NewStringf("%s%s", $1,$2);
5909 | NONID DCOLON ID idcolontailnt {
5910 $$ = NewStringf("::%s%s",$3,$4);
5917 $$ = NewStringf("::%s",$3);
5922 | NONID DCOLON OPERATOR {
5923 $$ = NewStringf("::%s",$3);
5927 idcolontailnt : DCOLON ID idcolontailnt {
5928 $$ = NewStringf("::%s%s",$2,$3);
5932 $$ = NewStringf("::%s",$2);
5935 $$ = NewStringf("::%s",$2);
5938 $$ = NewStringf("::~%s",$2);
5942 /* Concatenated strings */
5943 string : string STRING {
5944 $$ = (char *) malloc(strlen($1)+strlen($2)+1);
5948 | STRING { $$ = $1;}
5951 stringbrace : string {
5955 skip_balanced('{','}');
5956 $$ = NewString(scanner_ccode);
5963 options : LPAREN kwargs RPAREN {
5968 String *name, *value;
5969 name = Getattr(n,"name");
5970 value = Getattr(n,"value");
5971 if (!value) value = (String *) "1";
5972 Setattr($$,name, value);
5976 | empty { $$ = 0; };
5979 /* Keyword arguments */
5980 kwargs : idstring EQUAL stringnum {
5982 Setattr($$,"name",$1);
5983 Setattr($$,"value",$3);
5985 | idstring EQUAL stringnum COMMA kwargs {
5987 Setattr($$,"name",$1);
5988 Setattr($$,"value",$3);
5989 set_nextSibling($$,$5);
5993 Setattr($$,"name",$1);
5995 | idstring COMMA kwargs {
5997 Setattr($$,"name",$1);
5998 set_nextSibling($$,$3);
6000 | idstring EQUAL stringtype {
6002 Setattr($$,"name",$1);
6004 | idstring EQUAL stringtype COMMA kwargs {
6006 Setattr($$,"name",$1);
6007 set_nextSibling($$,$5);
6011 stringnum : string {
6023 SwigType *Swig_cparse_type(String *s) {
6025 ns = NewStringf("%s;",s);
6026 Seek(ns,0,SEEK_SET);
6029 scanner_next_token(PARSETYPE);
6031 /* Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */
6036 Parm *Swig_cparse_parm(String *s) {
6038 ns = NewStringf("%s;",s);
6039 Seek(ns,0,SEEK_SET);
6042 scanner_next_token(PARSEPARM);
6044 /* Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */
6050 ParmList *Swig_cparse_parms(String *s) {
6053 if (cs && cs[0] != '(') {
6054 ns = NewStringf("(%s);",s);
6056 ns = NewStringf("%s;",s);
6058 Seek(ns,0,SEEK_SET);
6061 scanner_next_token(PARSEPARMS);
6063 /* Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */