1/* -----------------------------------------------------------------------------
2 * See the LICENSE file for information on copyright, usage and redistribution
3 * of SWIG, and the README file for authors - http://www.swig.org/release.html.
4 *
5 * parser.y
6 *
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
9 * some point.  Beware.
10 * ----------------------------------------------------------------------------- */
11
12%{
13
14#define yylex yylex
15
16char cvsroot_parser_y[] = "$Id: parser.y 11582 2009-08-15 10:40:19Z wsfulton $";
17
18#include "swig.h"
19#include "cparse.h"
20#include "preprocessor.h"
21#include <ctype.h>
22
23/* We do this for portability */
24#undef alloca
25#define alloca malloc
26
27/* -----------------------------------------------------------------------------
28 *                               Externals
29 * ----------------------------------------------------------------------------- */
30
31int  yyparse();
32
33/* NEW Variables */
34
35static Node    *top = 0;      /* Top of the generated parse tree */
36static int      unnamed = 0;  /* Unnamed datatype counter */
37static Hash    *extendhash = 0;     /* Hash table of added methods */
38static Hash    *classes = 0;        /* Hash table of classes */
39static Symtab  *prev_symtab = 0;
40static Node    *current_class = 0;
41String  *ModuleName = 0;
42static Node    *module_node = 0;
43static String  *Classprefix = 0;
44static String  *Namespaceprefix = 0;
45static int      inclass = 0;
46static char    *last_cpptype = 0;
47static int      inherit_list = 0;
48static Parm    *template_parameters = 0;
49static int      extendmode   = 0;
50static int      compact_default_args = 0;
51static int      template_reduce = 0;
52static int      cparse_externc = 0;
53
54static int      max_class_levels = 0;
55static int      class_level = 0;
56static Node   **class_decl = NULL;
57
58/* -----------------------------------------------------------------------------
59 *                            Assist Functions
60 * ----------------------------------------------------------------------------- */
61
62
63
64/* Called by the parser (yyparse) when an error is found.*/
65static void yyerror (const char *e) {
66  (void)e;
67}
68
69static Node *new_node(const_String_or_char_ptr tag) {
70  Node *n = NewHash();
71  set_nodeType(n,tag);
72  Setfile(n,cparse_file);
73  Setline(n,cparse_line);
74  return n;
75}
76
77/* Copies a node.  Does not copy tree links or symbol table data (except for
78   sym:name) */
79
80static Node *copy_node(Node *n) {
81  Node *nn;
82  Iterator k;
83  nn = NewHash();
84  Setfile(nn,Getfile(n));
85  Setline(nn,Getline(n));
86  for (k = First(n); k.key; k = Next(k)) {
87    String *ci;
88    String *key = k.key;
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)) {
94      continue;
95    }
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);
102      Setattr(nn,key, ci);
103      Delete(ci);
104      continue;
105    }
106    if (strcmp(ckey,"sym:symtab") == 0) {
107      Setattr(nn,"sym:needs_symtab", "1");
108    }
109    /* We don't copy any other symbol table attributes */
110    if (strncmp(ckey,"sym:",4) == 0) {
111      continue;
112    }
113    /* If children.  We copy them recursively using this function */
114    if (strcmp(ckey,"firstChild") == 0) {
115      /* Copy children */
116      Node *cn = k.item;
117      while (cn) {
118	Node *copy = copy_node(cn);
119	appendChild(nn,copy);
120	Delete(copy);
121	cn = nextSibling(cn);
122      }
123      continue;
124    }
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 */
127
128    if (strcmp(ckey,"symtab") == 0) {
129      /* Node defined a symbol table. */
130      Setattr(nn,"requires_symtab","1");
131      continue;
132    }
133    /* Can't copy nodes */
134    if (strcmp(ckey,"node") == 0) {
135      continue;
136    }
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);
140      Setattr(nn,key,pl);
141      Delete(pl);
142      continue;
143    }
144    /* Looks okay.  Just copy the data using Copy */
145    ci = Copy(k.item);
146    Setattr(nn, key, ci);
147    Delete(ci);
148  }
149  return nn;
150}
151
152/* -----------------------------------------------------------------------------
153 *                              Variables
154 * ----------------------------------------------------------------------------- */
155
156static char  *typemap_lang = 0;    /* Current language setting */
157
158static int cplus_mode  = 0;
159static String  *class_rename = 0;
160
161/* C++ modes */
162
163#define  CPLUS_PUBLIC    1
164#define  CPLUS_PRIVATE   2
165#define  CPLUS_PROTECTED 3
166
167/* include types */
168static int   import_mode = 0;
169
170void SWIG_typemap_lang(const char *tm_lang) {
171  typemap_lang = Swig_copy_string(tm_lang);
172}
173
174void SWIG_cparse_set_compact_default_args(int defargs) {
175  compact_default_args = defargs;
176}
177
178int SWIG_cparse_template_reduce(int treduce) {
179  template_reduce = treduce;
180  return treduce;
181}
182
183/* -----------------------------------------------------------------------------
184 *                           Assist functions
185 * ----------------------------------------------------------------------------- */
186
187static int promote_type(int t) {
188  if (t <= T_UCHAR || t == T_CHAR) return T_INT;
189  return t;
190}
191
192/* Perform type-promotion for binary operators */
193static int promote(int t1, int t2) {
194  t1 = promote_type(t1);
195  t2 = promote_type(t2);
196  return t1 > t2 ? t1 : t2;
197}
198
199static String *yyrename = 0;
200
201/* Forward renaming operator */
202
203static String *resolve_node_scope(String *cname);
204
205
206Hash *Swig_cparse_features(void) {
207  static Hash   *features_hash = 0;
208  if (!features_hash) features_hash = NewHash();
209  return features_hash;
210}
211
212static 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);
219    Append(tp,tq);
220    Append(tp,ts);
221    Delete(ts);
222    Delete(ta);
223    Delete(tq);
224    return tp;
225  } else {
226    return NewString(s);
227  }
228}
229
230/* Generate the symbol table name for an object */
231/* This is a bit of a mess. Need to clean up */
232static String *add_oldname = 0;
233
234
235
236static String *make_name(Node *n, String *name,SwigType *decl) {
237  int destructor = name && (*(Char(name)) == '~');
238
239  if (yyrename) {
240    String *s = NewString(yyrename);
241    Delete(yyrename);
242    yyrename = 0;
243    if (destructor  && (*(Char(s)) != '~')) {
244      Insert(s,0,"~");
245    }
246    return s;
247  }
248
249  if (!name) return 0;
250  return Swig_name_make(n,Namespaceprefix,name,decl,add_oldname);
251}
252
253/* Generate an unnamed identifier */
254static String *make_unnamed() {
255  unnamed++;
256  return NewStringf("$unnamed%d$",unnamed);
257}
258
259/* Return if the node is a friend declaration */
260static int is_friend(Node *n) {
261  return Cmp(Getattr(n,"storage"),"friend") == 0;
262}
263
264static int is_operator(String *name) {
265  return Strncmp(name,"operator ", 9) == 0;
266}
267
268
269/* Add declaration list to symbol table */
270static int  add_only_one = 0;
271
272static void add_symbols(Node *n) {
273  String *decl;
274  String *wrn = 0;
275  if (inclass && n) {
276    cparse_normalize_void(n);
277  }
278  while (n) {
279    String *symname = 0;
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;
286    if (extendmode) {
287      Setattr(n,"isextension","1");
288    }
289
290    if (inclass) {
291      String *name = Getattr(n, "name");
292      if (isfriend) {
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);
298	if (!prefix) {
299	  if (name && !is_operator(name) && Namespaceprefix) {
300	    String *nname = NewStringf("%s::%s", Namespaceprefix, name);
301	    Setattr(n,"name",nname);
302	    Delete(nname);
303	  }
304	} else {
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);
310	  Delete(nname);
311	  Delete(base);
312	  Delete(prefix);
313	}
314	Namespaceprefix = 0;
315      } else {
316	/* for member functions, we need to remove the redundant
317	   class scope if provided, as in
318
319	   struct Foo {
320	   int Foo::method(int a);
321	   };
322
323	*/
324	String *prefix = name ? Swig_scopename_prefix(name) : 0;
325	if (prefix) {
326	  if (Classprefix && (Equal(prefix,Classprefix))) {
327	    String *base = Swig_scopename_last(name);
328	    Setattr(n,"name",base);
329	    Delete(base);
330	  }
331	  Delete(prefix);
332	}
333
334        /*
335	if (!Getattr(n,"parentNode") && class_level) set_parentNode(n,class_decl[class_level - 1]);
336        */
337	Setattr(n,"ismember","1");
338      }
339    }
340    if (!isfriend && inclass) {
341      if ((cplus_mode != CPLUS_PUBLIC)) {
342	only_csymbol = 1;
343	if (cplus_mode == CPLUS_PROTECTED) {
344	  Setattr(n,"access", "protected");
345	  only_csymbol = !Swig_need_protected(n);
346	} else {
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)) {
350	    only_csymbol = 0;
351	  }
352	}
353      } else {
354	  Setattr(n,"access", "public");
355      }
356    }
357    if (Getattr(n,"sym:name")) {
358      n = nextSibling(n);
359      continue;
360    }
361    decl = Getattr(n,"decl");
362    if (!SwigType_isfunction(decl)) {
363      String *name = Getattr(n,"name");
364      String *makename = Getattr(n,"parser:makename");
365      if (iscdecl) {
366	String *storage = Getattr(n, "storage");
367	if (Cmp(storage,"typedef") == 0) {
368	  Setattr(n,"kind","typedef");
369	} else {
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");
375	  }
376	  if (type) {
377	    SwigType *ty;
378	    SwigType *tmp = 0;
379	    if (decl) {
380	      ty = tmp = Copy(type);
381	      SwigType_push(ty,decl);
382	    } else {
383	      ty = type;
384	    }
385	    if (!SwigType_ismutable(ty)) {
386	      SetFlag(n,"hasconsttype");
387	      SetFlag(n,"feature:immutable");
388	    }
389	    if (tmp) Delete(tmp);
390	  }
391	  if (!type) {
392	    Printf(stderr,"notype name %s\n", name);
393	  }
394	}
395      }
396      Swig_features_get(Swig_cparse_features(), Namespaceprefix, name, 0, n);
397      if (makename) {
398	symname = make_name(n, makename,0);
399        Delattr(n,"parser:makename"); /* temporary information, don't leave it hanging around */
400      } else {
401        makename = name;
402	symname = make_name(n, makename,0);
403      }
404
405      if (!symname) {
406	symname = Copy(Getattr(n,"unnamed"));
407      }
408      if (symname) {
409	wrn = Swig_name_warning(n, Namespaceprefix, symname,0);
410      }
411    } else {
412      String *name = Getattr(n,"name");
413      SwigType *fdecl = Copy(decl);
414      SwigType *fun = SwigType_pop_function(fdecl);
415      if (iscdecl) {
416	Setattr(n,"kind","function");
417      }
418
419      Swig_features_get(Swig_cparse_features(),Namespaceprefix,name,fun,n);
420
421      symname = make_name(n, name,fun);
422      wrn = Swig_name_warning(n, Namespaceprefix,symname,fun);
423
424      Delete(fdecl);
425      Delete(fun);
426
427    }
428    if (!symname) {
429      n = nextSibling(n);
430      continue;
431    }
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");
438      if (strlen(c)) {
439	SWIG_WARN_NODE_BEGIN(n);
440	Swig_warning(0,Getfile(n), Getline(n), "%s\n",c+1);
441	SWIG_WARN_NODE_END(n);
442      }
443      Swig_symbol_add(0, n);
444    } else {
445      Node *c;
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");
453	}
454      }
455      c = Swig_symbol_add(symname,n);
456
457      if (c != n) {
458        /* symbol conflict attempting to add in the new symbol */
459        if (Getattr(n,"sym:weak")) {
460          Setattr(n,"sym:name",symname);
461        } else {
462          String *e = NewStringEmpty();
463          String *en = NewStringEmpty();
464          String *ec = NewStringEmpty();
465          int redefined = Swig_need_redefined_warn(n,c,inclass);
466          if (redefined) {
467            Printf(en,"Identifier '%s' redefined (ignored)",symname);
468            Printf(ec,"previous definition of '%s'",symname);
469          } else {
470            Printf(en,"Redundant redeclaration of '%s'",symname);
471            Printf(ec,"previous declaration of '%s'",symname);
472          }
473          if (Cmp(symname,Getattr(n,"name"))) {
474            Printf(en," (Renamed from '%s')", SwigType_namestr(Getattr(n,"name")));
475          }
476          Printf(en,",");
477          if (Cmp(symname,Getattr(c,"name"))) {
478            Printf(ec," (Renamed from '%s')", SwigType_namestr(Getattr(c,"name")));
479          }
480          Printf(ec,".");
481	  SWIG_WARN_NODE_BEGIN(n);
482          if (redefined) {
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);
488          }
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);
493	  Delete(e);
494          Delete(en);
495          Delete(ec);
496        }
497      }
498    }
499    /* restore the class scope if needed */
500    if (isfriend) {
501      Swig_symbol_setscope(old_scope);
502      if (old_prefix) {
503	Delete(Namespaceprefix);
504	Namespaceprefix = old_prefix;
505      }
506    }
507    Delete(symname);
508
509    if (add_only_one) return;
510    n = nextSibling(n);
511  }
512}
513
514
515/* add symbols a parse tree node copy */
516
517static void add_symbols_copy(Node *n) {
518  String *name;
519  int    emode = 0;
520  while (n) {
521    char *cnodeType = Char(nodeType(n));
522
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;
531      }
532      n = nextSibling(n);
533      continue;
534    }
535
536    add_oldname = Getattr(n,"sym:name");
537    if ((add_oldname) || (Getattr(n,"sym:needs_symtab"))) {
538      if (add_oldname) {
539	DohIncref(add_oldname);
540	/*  Disable this, it prevents %rename to work with templates */
541	/* If already renamed, we used that name  */
542	/*
543	if (Strcmp(add_oldname, Getattr(n,"name")) != 0) {
544	  Delete(yyrename);
545	  yyrename = Copy(add_oldname);
546	}
547	*/
548      }
549      Delattr(n,"sym:needs_symtab");
550      Delattr(n,"sym:name");
551
552      add_only_one = 1;
553      add_symbols(n);
554
555      if (Getattr(n,"partialargs")) {
556	Swig_symbol_cadd(Getattr(n,"partialargs"),n);
557      }
558      add_only_one = 0;
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);
565      }
566      if (strcmp(cnodeType,"class") == 0) {
567	inclass = 1;
568	current_class = n;
569	if (Strcmp(Getattr(n,"kind"),"class") == 0) {
570	  cplus_mode = CPLUS_PRIVATE;
571	} else {
572	  cplus_mode = CPLUS_PUBLIC;
573	}
574      }
575      if (strcmp(cnodeType,"extend") == 0) {
576	emode = cplus_mode;
577	cplus_mode = CPLUS_PUBLIC;
578      }
579      add_symbols_copy(firstChild(n));
580      if (strcmp(cnodeType,"extend") == 0) {
581	cplus_mode = emode;
582      }
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);
588      }
589      if (add_oldname) {
590	Delete(add_oldname);
591	add_oldname = 0;
592      }
593      if (strcmp(cnodeType,"class") == 0) {
594	inclass = 0;
595	current_class = 0;
596      }
597    } else {
598      if (strcmp(cnodeType,"extend") == 0) {
599	emode = cplus_mode;
600	cplus_mode = CPLUS_PUBLIC;
601      }
602      add_symbols_copy(firstChild(n));
603      if (strcmp(cnodeType,"extend") == 0) {
604	cplus_mode = emode;
605      }
606    }
607    n = nextSibling(n);
608  }
609}
610
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 */
615
616static void merge_extensions(Node *cls, Node *am) {
617  Node *n;
618  Node *csym;
619
620  n = firstChild(am);
621  while (n) {
622    String *symname;
623    if (Strcmp(nodeType(n),"constructor") == 0) {
624      symname = Getattr(n,"sym:name");
625      if (symname) {
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
630             check here */
631	  if (Getattr(cls,"sym:name")) {
632	    Setattr(n,"sym:name", Getattr(cls,"sym:name"));
633	  }
634	}
635      }
636    }
637
638    symname = Getattr(n,"sym:name");
639    DohIncref(symname);
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);
644      if (csym != 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);
658	Delete(e);
659	Delete(en);
660	Delete(ec);
661	Swig_symbol_remove(csym);              /* Remove class definition */
662	Swig_symbol_add(symname,n);            /* Insert extend definition */
663      }
664    }
665    n = nextSibling(n);
666  }
667}
668
669static void append_previous_extension(Node *cls, Node *am) {
670  Node *n, *ne;
671  Node *pe = 0;
672  Node *ae = 0;
673
674  if (!am) return;
675
676  n = firstChild(am);
677  while (n) {
678    ne = nextSibling(n);
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");
683      appendChild(pe, n);
684    } else {
685      if (!ae) ae = new_node("extend");
686      appendChild(ae, n);
687    }
688    n = ne;
689  }
690  if (pe) prependChild(cls,pe);
691  if (ae) appendChild(cls,ae);
692}
693
694
695/* Check for unused %extend.  Special case, don't report unused
696   extensions for templates */
697
698static void check_extensions() {
699  Iterator ki;
700
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);
707    }
708  }
709}
710
711/* Check a set of declarations to see if any are pure-abstract */
712
713static List *pure_abstract(Node *n) {
714  List *abs = 0;
715  while (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) {
721	  if (!abs) {
722	    abs = NewList();
723	  }
724	  Append(abs,n);
725	  Setattr(n,"abstract","1");
726	}
727      }
728    } else if (Cmp(nodeType(n),"destructor") == 0) {
729      if (Cmp(Getattr(n,"value"),"0") == 0) {
730	if (!abs) {
731	  abs = NewList();
732	}
733	Append(abs,n);
734	Setattr(n,"abstract","1");
735      }
736    }
737    n = nextSibling(n);
738  }
739  return abs;
740}
741
742/* Make a classname */
743
744static String *make_class_name(String *name) {
745  String *nname = 0;
746  if (Namespaceprefix) {
747    nname= NewStringf("%s::%s", Namespaceprefix, name);
748  } else {
749    nname = NewString(name);
750  }
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);
757    Delete(nname);
758    Delete(args);
759    Delete(qargs);
760    nname = prefix;
761  }
762  return nname;
763}
764
765static List *make_inherit_list(String *clsname, List *names) {
766  int i, ilen;
767  String *derived;
768  List *bases = NewList();
769
770  if (Namespaceprefix) derived = NewStringf("%s::%s", Namespaceprefix,clsname);
771  else derived = NewString(clsname);
772
773  ilen = Len(names);
774  for (i = 0; i < ilen; i++) {
775    Node *s;
776    String *base;
777    String *n = Getitem(names,i);
778    /* Try to figure out where this symbol is */
779    s = Swig_symbol_clookup(n,0);
780    if (s) {
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"));
787	} else {
788	  break;
789	}
790      }
791      if (s && ((Strcmp(nodeType(s),"class") == 0) || (Strcmp(nodeType(s),"template") == 0))) {
792	String *q = Swig_symbol_qualified(s);
793	Append(bases,s);
794	if (q) {
795	  base = NewStringf("%s::%s", q, Getattr(s,"name"));
796	  Delete(q);
797	} else {
798	  base = NewString(Getattr(s,"name"));
799	}
800      } else {
801	base = NewString(n);
802      }
803    } else {
804      base = NewString(n);
805    }
806    if (base) {
807      Swig_name_inherit(base,derived);
808      Delete(base);
809    }
810  }
811  return bases;
812}
813
814/* If the class name is qualified.  We need to create or lookup namespace entries */
815
816static Symtab *get_global_scope() {
817  Symtab *symtab = Swig_symbol_current();
818  Node   *pn = parentNode(symtab);
819  while (pn) {
820    symtab = pn;
821    pn = parentNode(symtab);
822    if (!pn) break;
823  }
824  Swig_symbol_setscope(symtab);
825  return symtab;
826}
827
828/* Remove the block braces, { and }, if the 'noblock' attribute is set.
829 * Node *kw can be either a Hash or Parmlist. */
830static String *remove_block(Node *kw, const String *inputcode) {
831  String *modified_code = 0;
832  while (kw) {
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] == '{') {
838       --len; ++cstr;
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);
844       break;
845     }
846   }
847   kw = nextSibling(kw);
848  }
849  return modified_code;
850}
851
852
853static Node *nscope = 0;
854static Node *nscope_inner = 0;
855static String *resolve_node_scope(String *cname) {
856  Symtab *gscope = 0;
857  nscope = 0;
858  nscope_inner = 0;
859  if (Swig_scopename_check(cname)) {
860    Node   *ns;
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);
866      Delete(prefix);
867      prefix= nprefix;
868      gscope = get_global_scope();
869    }
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;
879      return base;
880    }
881    /* Try to locate the scope */
882    ns = Swig_symbol_clookup(prefix,0);
883    if (!ns) {
884      Swig_error(cparse_file,cparse_line,"Undefined scope '%s'\n", prefix);
885    } else {
886      Symtab *nstab = Getattr(ns,"symtab");
887      if (!nstab) {
888	Swig_error(cparse_file,cparse_line,
889		   "'%s' is not defined as a valid scope.\n", prefix);
890	ns = 0;
891      } else {
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)) {
896	  ns = 0;
897	  cname = base;
898	}
899	Delete(tname);
900	Delete(nname);
901      }
902      if (ns) {
903	/* we will try to create a new node using the namespaces we
904	   can find in the scope name */
905	List *scopes;
906	String *sname;
907	Iterator si;
908	String *name = NewString(prefix);
909	scopes = NewList();
910	while (name) {
911	  String *base = Swig_scopename_last(name);
912	  String *tprefix = Swig_scopename_prefix(name);
913	  Insert(scopes,0,base);
914	  Delete(base);
915	  Delete(name);
916	  name = tprefix;
917	}
918	for (si = First(scopes); si.item; si = Next(si)) {
919	  Node *ns1,*ns2;
920	  sname = si.item;
921	  ns1 = Swig_symbol_clookup(sname,0);
922	  assert(ns1);
923	  if (Strcmp(nodeType(ns1),"namespace") == 0) {
924	    if (Getattr(ns1,"alias")) {
925	      ns1 = Getattr(ns1,"namespace");
926	    }
927	  } else {
928	    /* now this last part is a class */
929	    si = Next(si);
930	    ns1 = Swig_symbol_clookup(sname,0);
931	    /*  or a nested class tree, which is unrolled here */
932	    for (; si.item; si = Next(si)) {
933	      if (si.item) {
934		Printf(sname,"::%s",si.item);
935	      }
936	    }
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 */
945	    break;
946	  }
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"));
951	  add_symbols(ns2);
952	  Swig_symbol_setscope(Getattr(ns1,"symtab"));
953	  Delete(Namespaceprefix);
954	  Namespaceprefix = Swig_symbol_qualifiedscopename(0);
955	  if (nscope_inner) {
956	    if (Getattr(nscope_inner,"symtab") != Getattr(ns2,"symtab")) {
957	      appendChild(nscope_inner,ns2);
958	      Delete(ns2);
959	    }
960	  }
961	  nscope_inner = ns2;
962	  if (!nscope) nscope = ns2;
963	}
964	cname = base;
965	Delete(scopes);
966      }
967    }
968    Delete(prefix);
969  }
970  return cname;
971}
972
973
974
975
976
977/* Structures for handling code fragments built for nested classes */
978
979typedef 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 */
987} Nested;
988
989/* Some internal variables for saving nested class information */
990
991static Nested      *nested_list = 0;
992
993/* Add a function to the nested list */
994
995static void add_nested(Nested *n) {
996  Nested *n1;
997  if (!nested_list) nested_list = n;
998  else {
999    n1 = nested_list;
1000    while (n1->next) n1 = n1->next;
1001    n1->next = n;
1002  }
1003}
1004
1005/* Strips C-style and C++-style comments from string in-place. */
1006static void strip_comments(char *string) {
1007  int state = 0; /*
1008                  * 0 - not in comment
1009                  * 1 - in c-style comment
1010                  * 2 - in c++-style comment
1011                  * 3 - in string
1012                  * 4 - after reading / not in comments
1013                  * 5 - after reading * in c-style comments
1014                  * 6 - after reading \ in strings
1015                  */
1016  char * c = string;
1017  while (*c) {
1018    switch (state) {
1019    case 0:
1020      if (*c == '\"')
1021        state = 3;
1022      else if (*c == '/')
1023        state = 4;
1024      break;
1025    case 1:
1026      if (*c == '*')
1027        state = 5;
1028      *c = ' ';
1029      break;
1030    case 2:
1031      if (*c == '\n')
1032        state = 0;
1033      else
1034        *c = ' ';
1035      break;
1036    case 3:
1037      if (*c == '\"')
1038        state = 0;
1039      else if (*c == '\\')
1040        state = 6;
1041      break;
1042    case 4:
1043      if (*c == '/') {
1044        *(c-1) = ' ';
1045        *c = ' ';
1046        state = 2;
1047      } else if (*c == '*') {
1048        *(c-1) = ' ';
1049        *c = ' ';
1050        state = 1;
1051      } else
1052        state = 0;
1053      break;
1054    case 5:
1055      if (*c == '/')
1056        state = 0;
1057      else
1058        state = 1;
1059      *c = ' ';
1060      break;
1061    case 6:
1062      state = 3;
1063      break;
1064    }
1065    ++c;
1066  }
1067}
1068
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! */
1072
1073static Node *dump_nested(const char *parent) {
1074  Nested *n,*n1;
1075  Node *ret = 0;
1076  n = nested_list;
1077  if (!parent) {
1078    nested_list = 0;
1079    return 0;
1080  }
1081  while (n) {
1082    Node *retx;
1083    SwigType *nt;
1084    /* Token replace the name of the parent class */
1085    Replace(n->code, "$classname", parent, DOH_REPLACE_ANY);
1086
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);
1091
1092    /* Add the appropriate declaration to the C++ processor */
1093    retx = new_node("cdecl");
1094    Setattr(retx,"name",n->name);
1095    nt = Copy(n->type);
1096    Setattr(retx,"type",nt);
1097    Delete(nt);
1098    Setattr(retx,"nested",parent);
1099    if (n->unnamed) {
1100      Setattr(retx,"unnamed","1");
1101    }
1102
1103    add_symbols(retx);
1104    if (ret) {
1105      set_nextSibling(retx,ret);
1106      Delete(ret);
1107    }
1108    ret = retx;
1109
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);
1117       ret = retx;
1118    */
1119
1120    /* Strip comments - further code may break in presence of comments. */
1121    strip_comments(Char(n->code));
1122
1123    /* Make all SWIG created typedef structs/unions/classes unnamed else
1124       redefinition errors occur - nasty hack alert.*/
1125
1126    {
1127      const char* types_array[3] = {"struct", "union", "class"};
1128      int i;
1129      for (i=0; i<3; i++) {
1130	char* code_ptr = Char(n->code);
1131	while (code_ptr) {
1132	  /* Replace struct name (as in 'struct name {...}' ) with whitespace
1133	     name will be between struct and opening brace */
1134
1135	  code_ptr = strstr(code_ptr, types_array[i]);
1136	  if (code_ptr) {
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)
1145		  *code_ptr++ = ' ';
1146	    }
1147	  }
1148	}
1149      }
1150    }
1151
1152    {
1153      /* Remove SWIG directive %constant which may be left in the SWIG created typedefs */
1154      char* code_ptr = Char(n->code);
1155      while (code_ptr) {
1156	code_ptr = strstr(code_ptr, "%constant");
1157	if (code_ptr) {
1158	  char* directive_end_pos = strchr(code_ptr, ';');
1159	  if (directive_end_pos) {
1160            while (code_ptr <= directive_end_pos)
1161              *code_ptr++ = ' ';
1162	  }
1163	}
1164      }
1165    }
1166    {
1167      Node *head = new_node("insert");
1168      String *code = NewStringf("\n%s\n",n->code);
1169      Setattr(head,"code", code);
1170      Delete(code);
1171      set_nextSibling(head,ret);
1172      Delete(ret);
1173      ret = head;
1174    }
1175
1176    /* Dump the code to the scanner */
1177    start_inline(Char(n->code),n->line);
1178
1179    n1 = n->next;
1180    Delete(n->code);
1181    free(n);
1182    n = n1;
1183  }
1184  nested_list = 0;
1185  return ret;
1186}
1187
1188Node *Swig_cparse(File *f) {
1189  scanner_file(f);
1190  top = 0;
1191  yyparse();
1192  return top;
1193}
1194
1195static void single_new_feature(const char *featurename, String *val, Hash *featureattribs, char *declaratorid, SwigType *type, ParmList *declaratorparms, String *qualifier) {
1196  String *fname;
1197  String *name;
1198  String *fixname;
1199  SwigType *t = Copy(type);
1200
1201  /* Printf(stdout, "single_new_feature: [%s] [%s] [%s] [%s] [%s] [%s]\n", featurename, val, declaratorid, t, ParmList_str_defaultargs(declaratorparms), qualifier); */
1202
1203  fname = NewStringf("feature:%s",featurename);
1204  if (declaratorid) {
1205    fixname = feature_identifier_fix(declaratorid);
1206  } else {
1207    fixname = NewStringEmpty();
1208  }
1209  if (Namespaceprefix) {
1210    name = NewStringf("%s::%s",Namespaceprefix, fixname);
1211  } else {
1212    name = fixname;
1213  }
1214
1215  if (declaratorparms) Setmeta(val,"parms",declaratorparms);
1216  if (!Len(t)) t = 0;
1217  if (t) {
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);
1224	Delete(nname);
1225      } else {
1226	Swig_feature_set(Swig_cparse_features(), name, decl, fname, val, featureattribs);
1227      }
1228      Delete(decl);
1229    } else if (SwigType_ispointer(t)) {
1230      String *nname = NewStringf("*%s",name);
1231      Swig_feature_set(Swig_cparse_features(),nname,0,fname,val, featureattribs);
1232      Delete(nname);
1233    }
1234  } else {
1235    /* Global feature, that is, feature not associated with any particular symbol */
1236    Swig_feature_set(Swig_cparse_features(),name,0,fname,val, featureattribs);
1237  }
1238  Delete(fname);
1239  Delete(name);
1240}
1241
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. */
1245static void new_feature(const char *featurename, String *val, Hash *featureattribs, char *declaratorid, SwigType *type, ParmList *declaratorparms, String *qualifier) {
1246
1247  ParmList *declparms = declaratorparms;
1248
1249  /* remove the { and } braces if the noblock attribute is set */
1250  String *newval = remove_block(featureattribs, val);
1251  val = newval ? newval : val;
1252
1253  /* Add the feature */
1254  single_new_feature(featurename, val, featureattribs, declaratorid, type, declaratorparms, qualifier);
1255
1256  /* Add extra features if there are default parameters in the parameter list */
1257  if (type) {
1258    while (declparms) {
1259      if (ParmList_has_defaultargs(declparms)) {
1260
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);
1264
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);
1269
1270        single_new_feature(featurename, Copy(val), featureattribs, declaratorid, newtype, newparms, qualifier);
1271        declparms = newparms;
1272      } else {
1273        declparms = 0;
1274      }
1275    }
1276  }
1277}
1278
1279/* check if a function declaration is a plain C object */
1280static int is_cfunction(Node *n) {
1281  if (!cparse_cplusplus || cparse_externc) return 1;
1282  if (Cmp(Getattr(n,"storage"),"externc") == 0) {
1283    return 1;
1284  }
1285  return 0;
1286}
1287
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. */
1291static void default_arguments(Node *n) {
1292  Node *function = n;
1293
1294  if (function) {
1295    ParmList *varargs = Getattr(function,"feature:varargs");
1296    if (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");
1300      Parm     *pp = 0;
1301      while (p) {
1302	SwigType *t = Getattr(p,"type");
1303	if (Strcmp(t,"v(...)") == 0) {
1304	  if (pp) {
1305	    ParmList *cv = Copy(varargs);
1306	    set_nextSibling(pp,cv);
1307	    Delete(cv);
1308	  } else {
1309	    ParmList *cv =  Copy(varargs);
1310	    Setattr(function,"parms", cv);
1311	    Delete(cv);
1312	  }
1313	  break;
1314	}
1315	pp = p;
1316	p = nextSibling(p);
1317      }
1318    }
1319
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");
1327      if (p)
1328        Setattr(p,"compactdefargs", "1"); /* mark parameters for special handling */
1329      function = 0; /* don't add in extra methods */
1330    }
1331  }
1332
1333  while (function) {
1334    ParmList *parms = Getattr(function,"parms");
1335    if (ParmList_has_defaultargs(parms)) {
1336
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);
1340
1341      /* Create new function and add to symbol table */
1342      {
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"));
1353
1354        Delete(SwigType_pop_function(decl)); /* remove the old parameter list from decl */
1355        SwigType_add_function(decl,newparms);
1356        if (constqualifier)
1357          SwigType_add_qualifier(decl,"const");
1358
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);
1367
1368	Delete(ccode);
1369	Delete(cstorage);
1370	Delete(cvalue);
1371	Delete(ctype);
1372	Delete(cthrow);
1373	Delete(decl);
1374
1375        {
1376          Node *throws = Getattr(function,"throws");
1377	  ParmList *pl = CopyParmList(throws);
1378          if (throws) Setattr(new_function,"throws",pl);
1379	  Delete(pl);
1380        }
1381
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");
1387          if (templatetype) {
1388	    Node *tmp = Copy(templatetype);
1389	    Setattr(new_function,"templatetype",tmp);
1390	    Delete(tmp);
1391	  }
1392          if (symtypename) {
1393	    Node *tmp = Copy(symtypename);
1394	    Setattr(new_function,"sym:typename",tmp);
1395	    Delete(tmp);
1396	  }
1397          if (templateparms) {
1398	    Parm *tmp = CopyParmList(templateparms);
1399	    Setattr(new_function,"templateparms",tmp);
1400	    Delete(tmp);
1401	  }
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");
1405        }
1406
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);
1410
1411        /* Point to the new function, extending the linked list */
1412        set_nextSibling(function, new_function);
1413	Delete(new_function);
1414        function = new_function;
1415
1416	Delete(ntype);
1417      }
1418    } else {
1419      function = 0;
1420    }
1421  }
1422}
1423
1424/* -----------------------------------------------------------------------------
1425 * tag_nodes()
1426 *
1427 * Used by the parser to mark subtypes with extra information.
1428 * ----------------------------------------------------------------------------- */
1429
1430static void tag_nodes(Node *n, const_String_or_char_ptr attrname, DOH *value) {
1431  while (n) {
1432    Setattr(n, attrname, value);
1433    tag_nodes(firstChild(n), attrname, value);
1434    n = nextSibling(n);
1435  }
1436}
1437
1438%}
1439
1440%union {
1441  char  *id;
1442  List  *bases;
1443  struct Define {
1444    String *val;
1445    String *rawval;
1446    int     type;
1447    String *qualifier;
1448    String *bitfield;
1449    Parm   *throws;
1450    String *throwf;
1451  } dtype;
1452  struct {
1453    char *type;
1454    String *filename;
1455    int   line;
1456  } loc;
1457  struct {
1458    char      *id;
1459    SwigType  *type;
1460    String    *defarg;
1461    ParmList  *parms;
1462    short      have_parms;
1463    ParmList  *throws;
1464    String    *throwf;
1465  } decl;
1466  Parm         *tparms;
1467  struct {
1468    String     *method;
1469    Hash       *kwargs;
1470  } tmap;
1471  struct {
1472    String     *type;
1473    String     *us;
1474  } ptype;
1475  SwigType     *type;
1476  String       *str;
1477  Parm         *p;
1478  ParmList     *pl;
1479  int           ivalue;
1480  Node         *node;
1481};
1482
1483%token <id> ID
1484%token <str> HBLOCK
1485%token <id> POUND
1486%token <id> STRING
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
1496%token ENUM
1497%token CLASS TYPENAME PRIVATE PUBLIC PROTECTED COLON STATIC VIRTUAL FRIEND THROW CATCH EXPLICIT
1498%token USING
1499%token <node> NAMESPACE
1500%token NATIVE INLINE
1501%token TYPEMAP EXCEPT ECHO APPLY CLEAR SWIGTEMPLATE FRAGMENT
1502%token WARN
1503%token LESSTHAN GREATERTHAN MODULO DELETE_KW
1504%token LESSTHANOREQUALTO GREATERTHANOREQUALTO EQUALTO NOTEQUALTO
1505%token QUESTIONMARK
1506%token TYPES PARMS
1507%token NONID DSTAR DCNOT
1508%token <ivalue> TEMPLATE
1509%token <str> OPERATOR
1510%token <str> COPERATOR
1511%token PARSETYPE PARSEPARM PARSEPARMS
1512
1513%left  CAST
1514%left  QUESTIONMARK
1515%left  LOR
1516%left  LAND
1517%left  OR
1518%left  XOR
1519%left  AND
1520%left  EQUALTO NOTEQUALTO
1521%left  GREATERTHAN LESSTHAN GREATERTHANOREQUALTO LESSTHANOREQUALTO
1522%left  LSHIFT RSHIFT
1523%left  PLUS MINUS
1524%left  STAR SLASH MODULUS
1525%left  UMINUS NOT LNOT
1526%left  DCOLON
1527
1528%type <node>     program interface declaration swig_directive ;
1529
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 ;
1536
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;
1540
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;
1548
1549/* Misc */
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;
1563%type <id>       ename ;
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;
1583
1584%%
1585
1586/* ======================================================================
1587 *                          High-level Interface file
1588 *
1589 * An interface is just a sequence of declarations which may be SWIG directives
1590 * or normal C declarations.
1591 * ====================================================================== */
1592
1593program        :  interface {
1594                   if (!classes) classes = NewHash();
1595		   Setattr($1,"classes",classes);
1596		   Setattr($1,"name",ModuleName);
1597
1598		   if ((!module_node) && ModuleName) {
1599		     module_node = new_node("module");
1600		     Setattr(module_node,"name",ModuleName);
1601		   }
1602		   Setattr($1,"module",module_node);
1603		   check_extensions();
1604	           top = $1;
1605               }
1606               | PARSETYPE parm SEMI {
1607                 top = Copy(Getattr($2,"type"));
1608		 Delete($2);
1609               }
1610               | PARSETYPE error {
1611                 top = 0;
1612               }
1613               | PARSEPARM parm SEMI {
1614                 top = $2;
1615               }
1616               | PARSEPARM error {
1617                 top = 0;
1618               }
1619               | PARSEPARMS LPAREN parms RPAREN SEMI {
1620                 top = $3;
1621               }
1622               | PARSEPARMS error SEMI {
1623                 top = 0;
1624               }
1625               ;
1626
1627interface      : 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) */
1629                   appendChild($1,$2);
1630                   $$ = $1;
1631               }
1632               | empty {
1633                   $$ = new_node("top");
1634               }
1635               ;
1636
1637declaration    : swig_directive { $$ = $1; }
1638               | c_declaration { $$ = $1; }
1639               | cpp_declaration { $$ = $1; }
1640               | SEMI { $$ = 0; }
1641               | error {
1642                  $$ = 0;
1643		  Swig_error(cparse_file, cparse_line,"Syntax error in input(1).\n");
1644		  exit(1);
1645               }
1646/* Out of class constructor/destructor declarations */
1647               | c_constructor_decl {
1648                  if ($$) {
1649   		      add_symbols($$);
1650                  }
1651                  $$ = $1;
1652	       }
1653
1654/* Out of class conversion operator.  For example:
1655     inline A::operator char *() const { ... }.
1656
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.
1660
1661 */
1662
1663               | error COPERATOR {
1664                  $$ = 0;
1665                  skip_decl();
1666               }
1667               ;
1668
1669/* ======================================================================
1670 *                           SWIG DIRECTIVES
1671 * ====================================================================== */
1672
1673swig_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; }
1694               ;
1695
1696/* ------------------------------------------------------------
1697   %extend classname { ... }
1698   ------------------------------------------------------------ */
1699
1700extend_directive : EXTEND options idcolon LBRACE {
1701               Node *cls;
1702	       String *clsname;
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);
1708	       if (!cls) {
1709		 /* No previous definition. Create a new scope */
1710		 Node *am = Getattr(extendhash,clsname);
1711		 if (!am) {
1712		   Swig_symbol_newscope();
1713		   Swig_symbol_setscopename($3);
1714		   prev_symtab = 0;
1715		 } else {
1716		   prev_symtab = Swig_symbol_setscope(Getattr(am,"symtab"));
1717		 }
1718		 current_class = 0;
1719	       } else {
1720		 /* Previous class definition.  Use its symbol table */
1721		 prev_symtab = Swig_symbol_setscope(Getattr(cls,"symtab"));
1722		 current_class = cls;
1723		 extendmode = 1;
1724	       }
1725	       Classprefix = NewString($3);
1726	       Namespaceprefix= Swig_symbol_qualifiedscopename(0);
1727	       Delete(clsname);
1728	     } cpp_members RBRACE {
1729               String *clsname;
1730	       extendmode = 0;
1731               $$ = new_node("extend");
1732	       Setattr($$,"symtab",Swig_symbol_popscope());
1733	       if (prev_symtab) {
1734		 Swig_symbol_setscope(prev_symtab);
1735	       }
1736	       Namespaceprefix = Swig_symbol_qualifiedscopename(0);
1737               clsname = make_class_name($3);
1738	       Setattr($$,"name",clsname);
1739
1740	       /* Mark members as extend */
1741
1742	       tag_nodes($6,"feature:extend",(char*) "1");
1743	       if (current_class) {
1744		 /* We add the extension to the previously defined class */
1745		 appendChild($$,$6);
1746		 appendChild(current_class,$$);
1747	       } else {
1748		 /* We store the extensions in the extensions hash */
1749		 Node *am = Getattr(extendhash,clsname);
1750		 if (am) {
1751		   /* Append the members to the previous extend methods */
1752		   appendChild(am,$6);
1753		 } else {
1754		   appendChild($$,$6);
1755		   Setattr(extendhash,clsname,$$);
1756		 }
1757	       }
1758	       current_class = 0;
1759	       Delete(Classprefix);
1760	       Delete(clsname);
1761	       Classprefix = 0;
1762	       prev_symtab = 0;
1763	       $$ = 0;
1764
1765	     }
1766             ;
1767
1768/* ------------------------------------------------------------
1769   %apply
1770   ------------------------------------------------------------ */
1771
1772apply_directive : APPLY typemap_parm LBRACE tm_list RBRACE {
1773                    $$ = new_node("apply");
1774                    Setattr($$,"pattern",Getattr($2,"pattern"));
1775		    appendChild($$,$4);
1776               };
1777
1778/* ------------------------------------------------------------
1779   %clear
1780   ------------------------------------------------------------ */
1781
1782clear_directive : CLEAR tm_list SEMI {
1783		 $$ = new_node("clear");
1784		 appendChild($$,$2);
1785               }
1786               ;
1787
1788/* ------------------------------------------------------------
1789   %constant name = value;
1790   %constant type name = value;
1791   ------------------------------------------------------------ */
1792
1793constant_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");
1803		     add_symbols($$);
1804		     Delete(type);
1805		   } else {
1806		     if ($4.type == T_ERROR) {
1807		       Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line,"Unsupported constant value (ignored)\n");
1808		     }
1809		     $$ = 0;
1810		   }
1811
1812	       }
1813
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);
1820		   }
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");
1828		   add_symbols($$);
1829		 } else {
1830		     if ($4.type == T_ERROR) {
1831		       Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line,"Unsupported constant value\n");
1832		     }
1833		   $$ = 0;
1834		 }
1835               }
1836               | CONSTANT error SEMI {
1837		 Swig_warning(WARN_PARSE_BAD_VALUE,cparse_file,cparse_line,"Bad constant value (ignored).\n");
1838		 $$ = 0;
1839	       }
1840               ;
1841
1842/* ------------------------------------------------------------
1843   %echo "text"
1844   %echo %{ ... %}
1845   ------------------------------------------------------------ */
1846
1847echo_directive : ECHO HBLOCK {
1848		 char temp[64];
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);
1853		 Delete($2);
1854                 $$ = 0;
1855	       }
1856               | ECHO string {
1857		 char temp[64];
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);
1863		 Delete(s);
1864                 $$ = 0;
1865               }
1866               ;
1867
1868/* ------------------------------------------------------------
1869   %except(lang) { ... }
1870   %except { ... }
1871   %except(lang);
1872   %except;
1873   ------------------------------------------------------------ */
1874
1875except_directive : EXCEPT LPAREN ID RPAREN LBRACE {
1876                    skip_balanced('{','}');
1877		    $$ = 0;
1878		    Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated.  Use %%exception instead.\n");
1879	       }
1880
1881               | EXCEPT LBRACE {
1882                    skip_balanced('{','}');
1883		    $$ = 0;
1884		    Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated.  Use %%exception instead.\n");
1885               }
1886
1887               | EXCEPT LPAREN ID RPAREN SEMI {
1888		 $$ = 0;
1889		 Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated.  Use %%exception instead.\n");
1890               }
1891
1892               | EXCEPT SEMI {
1893		 $$ = 0;
1894		 Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated.  Use %%exception instead.\n");
1895	       }
1896               ;
1897
1898/* fragment keyword arguments */
1899stringtype    : string LBRACE parm RBRACE {
1900                 $$ = NewHash();
1901                 Setattr($$,"value",$1);
1902		 Setattr($$,"type",Getattr($3,"type"));
1903               }
1904               ;
1905
1906fname         : string {
1907                 $$ = NewHash();
1908                 Setattr($$,"value",$1);
1909              }
1910              | stringtype {
1911                $$ = $1;
1912              }
1913              ;
1914
1915/* ------------------------------------------------------------
1916   %fragment(name, section) %{ ... %}
1917   %fragment("name" {type}, "section") %{ ... %}
1918   %fragment("name", "section", fragment="fragment1", fragment="fragment2") %{ ... %}
1919   Also as above but using { ... }
1920   %fragment("name");
1921   ------------------------------------------------------------ */
1922
1923fragment_directive: FRAGMENT LPAREN fname COMMA kwargs RPAREN HBLOCK {
1924                   Hash *p = $5;
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);
1931                 }
1932                 | FRAGMENT LPAREN fname COMMA kwargs RPAREN LBRACE {
1933		   Hash *p = $5;
1934		   String *code;
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);
1945		   Delete(code);
1946                 }
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");
1952		 }
1953                 ;
1954
1955/* ------------------------------------------------------------
1956   %includefile "filename" [option1="xyz", ...] [ declarations ]
1957   %importfile  "filename" [option1="xyz", ...] [ declarations ]
1958   ------------------------------------------------------------ */
1959
1960include_directive: includetype options string LBRACKET {
1961                     $1.filename = Copy(cparse_file);
1962		     $1.line = cparse_line;
1963		     scanner_set_location(NewString($3),1);
1964                     if ($2) {
1965		       String *maininput = Getattr($2, "maininput");
1966		       if (maininput)
1967		         scanner_set_main_input_file(NewString(maininput));
1968		     }
1969               } interface RBRACKET {
1970                     String *mname = 0;
1971                     $$ = $6;
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;
1978		     }
1979
1980		     Setattr($$,"name",$3);
1981		     /* Search for the module (if any) */
1982		     {
1983			 Node *n = firstChild($$);
1984			 while (n) {
1985			     if (Strcmp(nodeType(n),"module") == 0) {
1986			         if (mname) {
1987				   Setattr(n,"name", mname);
1988				   mname = 0;
1989				 }
1990				 Setattr($$,"module",Getattr(n,"name"));
1991				 break;
1992			     }
1993			     n = nextSibling(n);
1994			 }
1995			 if (mname) {
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.
2000			   */
2001			   Node *nint = new_node("import");
2002			   Node *mnode = new_node("module");
2003			   Setattr(mnode,"name", mname);
2004			   appendChild(nint,mnode);
2005			   Delete(mnode);
2006			   appendChild(nint,firstChild($$));
2007			   $$ = nint;
2008			   Setattr($$,"module",mname);
2009			 }
2010		     }
2011		     Setattr($$,"options",$2);
2012               }
2013               ;
2014
2015includetype    : INCLUDE { $$.type = (char *) "include"; }
2016               | IMPORT  { $$.type = (char *) "import"; ++import_mode;}
2017               ;
2018
2019/* ------------------------------------------------------------
2020   %inline %{ ... %}
2021   ------------------------------------------------------------ */
2022
2023inline_directive : INLINE HBLOCK {
2024                 String *cpps;
2025		 if (Namespaceprefix) {
2026		   Swig_error(cparse_file, cparse_start_line, "%%inline directive inside a namespace is disallowed.\n");
2027
2028		   $$ = 0;
2029		 } else {
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);
2038		   Delete($2);
2039		   Delete(cpps);
2040		 }
2041
2042	       }
2043               | INLINE LBRACE {
2044                 String *cpps;
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");
2049
2050		   $$ = 0;
2051		 } else {
2052		   String *code;
2053                   $$ = new_node("insert");
2054		   Delitem(scanner_ccode,0);
2055		   Delitem(scanner_ccode,DOH_END);
2056		   code = Copy(scanner_ccode);
2057		   Setattr($$,"code", code);
2058		   Delete(code);
2059		   cpps=Copy(scanner_ccode);
2060		   start_inline(Char(cpps), start_line);
2061		   Delete(cpps);
2062		 }
2063               }
2064                ;
2065
2066/* ------------------------------------------------------------
2067   %{ ... %}
2068   %insert(section) "filename"
2069   %insert("section") "filename"
2070   %insert(section) %{ ... %}
2071   %insert("section") %{ ... %}
2072   ------------------------------------------------------------ */
2073
2074insert_directive : HBLOCK {
2075                 $$ = new_node("insert");
2076		 Setattr($$,"code",$1);
2077	       }
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);
2085		   $$ = 0;
2086		 }
2087               }
2088               | INSERT LPAREN idstring RPAREN HBLOCK {
2089		 $$ = new_node("insert");
2090		 Setattr($$,"section",$3);
2091		 Setattr($$,"code",$5);
2092               }
2093               | INSERT LPAREN idstring RPAREN LBRACE {
2094		 String *code;
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);
2102		 Delete(code);
2103	       }
2104               ;
2105
2106/* ------------------------------------------------------------
2107    %module modname
2108    %module "modname"
2109   ------------------------------------------------------------ */
2110
2111module_directive: MODULE options idstring {
2112                 $$ = new_node("module");
2113		 if ($2) {
2114		   Setattr($$,"options",$2);
2115		   if (Getattr($2,"directors")) {
2116		     Wrapper_director_mode_set(1);
2117		   }
2118		   if (Getattr($2,"dirprot")) {
2119		     Wrapper_director_protected_mode_set(1);
2120		   }
2121		   if (Getattr($2,"allprotected")) {
2122		     Wrapper_all_protected_mode_set(1);
2123		   }
2124		   if (Getattr($2,"templatereduce")) {
2125		     template_reduce = 1;
2126		   }
2127		   if (Getattr($2,"notemplatereduce")) {
2128		     template_reduce = 0;
2129		   }
2130		 }
2131		 if (!ModuleName) ModuleName = NewString($3);
2132		 if (!import_mode) {
2133		   /* first module included, we apply global
2134		      ModuleName, which can be modify by -module */
2135		   String *mname = Copy(ModuleName);
2136		   Setattr($$,"name",mname);
2137		   Delete(mname);
2138		 } else {
2139		   /* import mode, we just pass the idstring */
2140		   Setattr($$,"name",$3);
2141		 }
2142		 if (!module_node) module_node = $$;
2143	       }
2144               ;
2145
2146/* ------------------------------------------------------------
2147   %name(newname)    declaration
2148   %name("newname")  declaration
2149   ------------------------------------------------------------ */
2150
2151name_directive : NAME LPAREN idstring RPAREN {
2152                 Swig_warning(WARN_DEPRECATED_NAME,cparse_file,cparse_line, "%%name is deprecated.  Use %%rename instead.\n");
2153		 Delete(yyrename);
2154                 yyrename = NewString($3);
2155		 $$ = 0;
2156               }
2157               | NAME LPAREN RPAREN {
2158		 Swig_warning(WARN_DEPRECATED_NAME,cparse_file,cparse_line, "%%name is deprecated.  Use %%rename instead.\n");
2159		 $$ = 0;
2160		 Swig_error(cparse_file,cparse_line,"Missing argument to %%name directive.\n");
2161	       }
2162               ;
2163
2164
2165/* ------------------------------------------------------------
2166   %native(scriptname) name;
2167   %native(scriptname) type name (parms);
2168   ------------------------------------------------------------ */
2169
2170native_directive : NATIVE LPAREN ID RPAREN storage_class ID SEMI {
2171                 $$ = new_node("native");
2172		 Setattr($$,"name",$3);
2173		 Setattr($$,"wrap:name",$6);
2174	         add_symbols($$);
2175	       }
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);
2179		   $$ = 0;
2180		 } else {
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);
2190		 }
2191	         add_symbols($$);
2192	       }
2193               ;
2194
2195/* ------------------------------------------------------------
2196   %pragma(lang) name=value
2197   %pragma(lang) name
2198   %pragma name = value
2199   %pragma name
2200   ------------------------------------------------------------ */
2201
2202pragma_directive : PRAGMA pragma_lang ID EQUAL pragma_arg {
2203                 $$ = new_node("pragma");
2204		 Setattr($$,"lang",$2);
2205		 Setattr($$,"name",$3);
2206		 Setattr($$,"value",$5);
2207	       }
2208              | PRAGMA pragma_lang ID {
2209		$$ = new_node("pragma");
2210		Setattr($$,"lang",$2);
2211		Setattr($$,"name",$3);
2212	      }
2213              ;
2214
2215pragma_arg    : string { $$ = NewString($1); }
2216              | HBLOCK { $$ = $1; }
2217              ;
2218
2219pragma_lang   : LPAREN ID RPAREN { $$ = $2; }
2220              | empty { $$ = (char *) "swig"; }
2221              ;
2222
2223/* ------------------------------------------------------------
2224   %rename identifier newname;
2225   %rename identifier "newname";
2226   ------------------------------------------------------------ */
2227
2228rename_directive : rename_namewarn declarator idstring SEMI {
2229                SwigType *t = $2.type;
2230		Hash *kws = NewHash();
2231		String *fixname;
2232		fixname = feature_identifier_fix($2.id);
2233		Setattr(kws,"name",$3);
2234		if (!Len(t)) t = 0;
2235		/* Special declarator check */
2236		if (t) {
2237		  if (SwigType_isfunction(t)) {
2238		    SwigType *decl = SwigType_pop_function(t);
2239		    if (SwigType_ispointer(t)) {
2240		      String *nname = NewStringf("*%s",fixname);
2241		      if ($1) {
2242			Swig_name_rename_add(Namespaceprefix, nname,decl,kws,$2.parms);
2243		      } else {
2244			Swig_name_namewarn_add(Namespaceprefix,nname,decl,kws);
2245		      }
2246		      Delete(nname);
2247		    } else {
2248		      if ($1) {
2249			Swig_name_rename_add(Namespaceprefix,(fixname),decl,kws,$2.parms);
2250		      } else {
2251			Swig_name_namewarn_add(Namespaceprefix,(fixname),decl,kws);
2252		      }
2253		    }
2254		    Delete(decl);
2255		  } else if (SwigType_ispointer(t)) {
2256		    String *nname = NewStringf("*%s",fixname);
2257		    if ($1) {
2258		      Swig_name_rename_add(Namespaceprefix,(nname),0,kws,$2.parms);
2259		    } else {
2260		      Swig_name_namewarn_add(Namespaceprefix,(nname),0,kws);
2261		    }
2262		    Delete(nname);
2263		  }
2264		} else {
2265		  if ($1) {
2266		    Swig_name_rename_add(Namespaceprefix,(fixname),0,kws,$2.parms);
2267		  } else {
2268		    Swig_name_namewarn_add(Namespaceprefix,(fixname),0,kws);
2269		  }
2270		}
2271                $$ = 0;
2272		scanner_clear_rename();
2273              }
2274              | rename_namewarn LPAREN kwargs RPAREN declarator cpp_const SEMI {
2275		String *fixname;
2276		Hash *kws = $3;
2277		SwigType *t = $5.type;
2278		fixname = feature_identifier_fix($5.id);
2279		if (!Len(t)) t = 0;
2280		/* Special declarator check */
2281		if (t) {
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);
2287		      if ($1) {
2288			Swig_name_rename_add(Namespaceprefix, nname,decl,kws,$5.parms);
2289		      } else {
2290			Swig_name_namewarn_add(Namespaceprefix,nname,decl,kws);
2291		      }
2292		      Delete(nname);
2293		    } else {
2294		      if ($1) {
2295			Swig_name_rename_add(Namespaceprefix,(fixname),decl,kws,$5.parms);
2296		      } else {
2297			Swig_name_namewarn_add(Namespaceprefix,(fixname),decl,kws);
2298		      }
2299		    }
2300		    Delete(decl);
2301		  } else if (SwigType_ispointer(t)) {
2302		    String *nname = NewStringf("*%s",fixname);
2303		    if ($1) {
2304		      Swig_name_rename_add(Namespaceprefix,(nname),0,kws,$5.parms);
2305		    } else {
2306		      Swig_name_namewarn_add(Namespaceprefix,(nname),0,kws);
2307		    }
2308		    Delete(nname);
2309		  }
2310		} else {
2311		  if ($1) {
2312		    Swig_name_rename_add(Namespaceprefix,(fixname),0,kws,$5.parms);
2313		  } else {
2314		    Swig_name_namewarn_add(Namespaceprefix,(fixname),0,kws);
2315		  }
2316		}
2317                $$ = 0;
2318		scanner_clear_rename();
2319              }
2320              | rename_namewarn LPAREN kwargs RPAREN string SEMI {
2321		if ($1) {
2322		  Swig_name_rename_add(Namespaceprefix,$5,0,$3,0);
2323		} else {
2324		  Swig_name_namewarn_add(Namespaceprefix,$5,0,$3);
2325		}
2326		$$ = 0;
2327		scanner_clear_rename();
2328              }
2329              ;
2330
2331rename_namewarn : RENAME {
2332		    $$ = 1;
2333                }
2334                | NAMEWARN {
2335                    $$ = 0;
2336                };
2337
2338
2339/* ------------------------------------------------------------
2340   Feature targeting a symbol name (non-global feature):
2341
2342     %feature(featurename) name "val";
2343     %feature(featurename, val) name;
2344
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:
2348
2349     %feature(featurename) "val";
2350     %feature(featurename, val);
2351
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:
2355
2356     %feature(featurename, attrib1="attribval1", attrib2="attribval2") name "val";
2357     %feature(featurename, val, attrib1="attribval1", attrib2="attribval2") name;
2358   ------------------------------------------------------------ */
2359
2360                  /* Non-global feature */
2361feature_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);
2364                    $$ = 0;
2365                    scanner_clear_rename();
2366                  }
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);
2370                    $$ = 0;
2371                    scanner_clear_rename();
2372                  }
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);
2376                    $$ = 0;
2377                    scanner_clear_rename();
2378                  }
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);
2382                    $$ = 0;
2383                    scanner_clear_rename();
2384                  }
2385
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);
2390                    $$ = 0;
2391                    scanner_clear_rename();
2392                  }
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);
2396                    $$ = 0;
2397                    scanner_clear_rename();
2398                  }
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);
2402                    $$ = 0;
2403                    scanner_clear_rename();
2404                  }
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);
2408                    $$ = 0;
2409                    scanner_clear_rename();
2410                  }
2411                  ;
2412
2413stringbracesemi : stringbrace { $$ = $1; }
2414                | SEMI { $$ = 0; }
2415                | PARMS LPAREN parms RPAREN SEMI { $$ = $3; }
2416                ;
2417
2418featattr        : COMMA idstring EQUAL stringnum {
2419		  $$ = NewHash();
2420		  Setattr($$,"name",$2);
2421		  Setattr($$,"value",$4);
2422                }
2423                | COMMA idstring EQUAL stringnum featattr {
2424		  $$ = NewHash();
2425		  Setattr($$,"name",$2);
2426		  Setattr($$,"value",$4);
2427                  set_nextSibling($$,$5);
2428                }
2429		;
2430
2431/* %varargs() directive. */
2432
2433varargs_directive : VARARGS LPAREN varargs_parms RPAREN declarator cpp_const SEMI {
2434                 Parm *val;
2435		 String *name;
2436		 SwigType *t;
2437		 if (Namespaceprefix) name = NewStringf("%s::%s", Namespaceprefix, $5.id);
2438		 else name = NewString($5.id);
2439		 val = $3;
2440		 if ($5.parms) {
2441		   Setmeta(val,"parms",$5.parms);
2442		 }
2443		 t = $5.type;
2444		 if (!Len(t)) t = 0;
2445		 if (t) {
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);
2452		       Delete(nname);
2453		     } else {
2454		       Swig_feature_set(Swig_cparse_features(), name, decl, "feature:varargs", val, 0);
2455		     }
2456		     Delete(decl);
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);
2460		     Delete(nname);
2461		   }
2462		 } else {
2463		   Swig_feature_set(Swig_cparse_features(),name,0,"feature:varargs",val, 0);
2464		 }
2465		 Delete(name);
2466		 $$ = 0;
2467              };
2468
2469varargs_parms   : parms { $$ = $1; }
2470                | NUM_INT COMMA parm {
2471		  int i;
2472		  int n;
2473		  Parm *p;
2474		  n = atoi(Char($1.val));
2475		  if (n <= 0) {
2476		    Swig_error(cparse_file, cparse_line,"Argument count in %%varargs must be positive.\n");
2477		    $$ = 0;
2478		  } else {
2479		    $$ = Copy($3);
2480		    Setattr($$,"name","VARARGS_SENTINEL");
2481		    for (i = 0; i < n; i++) {
2482		      p = Copy($3);
2483		      set_nextSibling(p,$$);
2484		      Delete($$);
2485		      $$ = p;
2486		    }
2487		  }
2488                }
2489               ;
2490
2491
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   ------------------------------------------------------------ */
2499
2500typemap_directive :  TYPEMAP LPAREN typemap_type RPAREN tm_list stringbrace {
2501		   $$ = 0;
2502		   if ($3.method) {
2503		     String *code = 0;
2504		     $$ = new_node("typemap");
2505		     Setattr($$,"method",$3.method);
2506		     if ($3.kwargs) {
2507		       ParmList *kw = $3.kwargs;
2508                       code = remove_block(kw, $6);
2509		       Setattr($$,"kwargs", $3.kwargs);
2510		     }
2511		     code = code ? code : NewString($6);
2512		     Setattr($$,"code", code);
2513		     Delete(code);
2514		     appendChild($$,$5);
2515		   }
2516	       }
2517               | TYPEMAP LPAREN typemap_type RPAREN tm_list SEMI {
2518		 $$ = 0;
2519		 if ($3.method) {
2520		   $$ = new_node("typemap");
2521		   Setattr($$,"method",$3.method);
2522		   appendChild($$,$5);
2523		 }
2524	       }
2525               | TYPEMAP LPAREN typemap_type RPAREN tm_list EQUAL typemap_parm SEMI {
2526		   $$ = 0;
2527		   if ($3.method) {
2528		     $$ = new_node("typemapcopy");
2529		     Setattr($$,"method",$3.method);
2530		     Setattr($$,"pattern", Getattr($7,"pattern"));
2531		     appendChild($$,$5);
2532		   }
2533	       }
2534               ;
2535
2536/* typemap method type (lang,method) or (method) */
2537
2538typemap_type   : kwargs {
2539		 Hash *p;
2540		 String *name;
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))) {
2549		     $$.method = 0;
2550		     $$.kwargs = 0;
2551		   } else {
2552		     $$.method = Getattr(p,"name");
2553		     $$.kwargs = nextSibling(p);
2554		   }
2555		 } else {
2556		   /* one-argument typemap-form */
2557		   $$.method = Getattr($1,"name");
2558		   $$.kwargs = p;
2559		 }
2560                }
2561               ;
2562
2563tm_list        : typemap_parm tm_tail {
2564                 $$ = $1;
2565		 set_nextSibling($$,$2);
2566		}
2567               ;
2568
2569tm_tail        : COMMA typemap_parm tm_tail {
2570                 $$ = $2;
2571		 set_nextSibling($$,$3);
2572                }
2573               | empty { $$ = 0;}
2574               ;
2575
2576typemap_parm   : type typemap_parameter_declarator {
2577                  Parm *parm;
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);
2583		  Delete(parm);
2584		  /*		  $$ = NewParm($1,$2.id);
2585				  Setattr($$,"parms",$2.parms); */
2586                }
2587               | LPAREN parms RPAREN {
2588                  $$ = new_node("typemapitem");
2589		  Setattr($$,"pattern",$2);
2590		  /*		  Setattr($$,"multitype",$2); */
2591               }
2592               | LPAREN parms RPAREN LPAREN parms RPAREN {
2593		 $$ = new_node("typemapitem");
2594		 Setattr($$,"pattern", $2);
2595		 /*                 Setattr($$,"multitype",$2); */
2596		 Setattr($$,"parms",$5);
2597               }
2598               ;
2599
2600/* ------------------------------------------------------------
2601   %types(parmlist);
2602   %types(parmlist) %{ ... %}
2603   ------------------------------------------------------------ */
2604
2605types_directive : TYPES LPAREN parms RPAREN stringbracesemi {
2606                   $$ = new_node("types");
2607		   Setattr($$,"parms",$3);
2608                   if ($5)
2609		     Setattr($$,"convcode",NewString($5));
2610               }
2611               ;
2612
2613/* ------------------------------------------------------------
2614   %template(name) tname<args>;
2615   ------------------------------------------------------------ */
2616
2617template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN valparms GREATERTHAN SEMI {
2618                  Parm *p, *tp;
2619		  Node *n;
2620		  Node *tnode = 0;
2621		  Symtab *tscope = 0;
2622		  int     specialized = 0;
2623
2624		  $$ = 0;
2625
2626		  tscope = Swig_symbol_current();          /* Get the current scope */
2627
2628		  /* If the class name is qualified, we need to create or lookup namespace entries */
2629		  if (!inclass) {
2630		    $5 = resolve_node_scope($5);
2631		  }
2632
2633		  /*
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'.
2637
2638		    This is closer to the C++ (typedef) behavior.
2639		  */
2640		  n = Swig_cparse_template_locate($5,$7,tscope);
2641
2642		  /* Patch the argument types to respect namespaces */
2643		  p = $7;
2644		  while (p) {
2645		    SwigType *value = Getattr(p,"value");
2646		    if (!value) {
2647		      SwigType *ty = Getattr(p,"type");
2648		      if (ty) {
2649			SwigType *rty = 0;
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);
2654			}
2655			ty = reduce ? Swig_symbol_type_qualify(rty,tscope) : Swig_symbol_type_qualify(ty,tscope);
2656			Setattr(p,"type",ty);
2657			Delete(ty);
2658			Delete(rty);
2659		      }
2660		    } else {
2661		      value = Swig_symbol_type_qualify(value,tscope);
2662		      Setattr(p,"value",value);
2663		      Delete(value);
2664		    }
2665
2666		    p = nextSibling(p);
2667		  }
2668
2669		  /* Look for the template */
2670		  {
2671                    Node *nn = n;
2672                    Node *linklistend = 0;
2673                    while (nn) {
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");
2678                        if (!tparms) {
2679                          specialized = 1;
2680                        }
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 */
2688                          continue;
2689                        } else {
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;
2695
2696                          ParmList *temparms;
2697                          if (specialized) temparms = CopyParmList($7);
2698                          else temparms = CopyParmList(tparms);
2699
2700                          /* Create typedef's and arguments */
2701                          p = $7;
2702                          tp = temparms;
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*/
2705                            p = tp;
2706                            def_supplied = 1;
2707                          }
2708
2709                          while (p) {
2710                            String *value = Getattr(p,"value");
2711                            if (def_supplied) {
2712                              Setattr(p,"default","1");
2713                            }
2714                            if (value) {
2715                              Setattr(tp,"value",value);
2716                            } else {
2717                              SwigType *ty = Getattr(p,"type");
2718                              if (ty) {
2719                                Setattr(tp,"type",ty);
2720                              }
2721                              Delattr(tp,"value");
2722                            }
2723			    /* fix default arg values */
2724			    if (targs) {
2725			      Parm *pi = temparms;
2726			      Parm *ti = targs;
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);
2736			      }
2737			    }
2738                            p = nextSibling(p);
2739                            tp = nextSibling(tp);
2740                            if (!p && tp) {
2741                              p = tp;
2742                              def_supplied = 1;
2743                            }
2744                          }
2745
2746                          templnode = copy_node(nn);
2747                          /* We need to set the node name based on name used to instantiate */
2748                          Setattr(templnode,"name",tname);
2749			  Delete(tname);
2750                          if (!specialized) {
2751                            Delattr(templnode,"sym:typename");
2752                          } else {
2753                            Setattr(templnode,"sym:typename","1");
2754                          }
2755                          if ($3) {
2756			    /*
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
2760			       %feature(ignore).
2761
2762			       String *symname = Swig_name_make(templnode,0,$3,0,0);
2763			    */
2764			    String *symname = $3;
2765                            Swig_cparse_template_expand(templnode,symname,temparms,tscope);
2766                            Setattr(templnode,"sym:name",symname);
2767                          } else {
2768                            static int cnt = 0;
2769                            String *nname = NewStringf("__dummy_%d__", cnt++);
2770                            Swig_cparse_template_expand(templnode,nname,temparms,tscope);
2771                            Setattr(templnode,"sym:name",nname);
2772			    Delete(nname);
2773                            Setattr(templnode,"feature:onlychildren",
2774                                    "typemap,typemapitem,typemapcopy,typedef,types,fragment");
2775                          }
2776                          Delattr(templnode,"templatetype");
2777                          Setattr(templnode,"template",nn);
2778                          tnode = templnode;
2779                          Setfile(templnode,cparse_file);
2780                          Setline(templnode,cparse_line);
2781                          Delete(temparms);
2782
2783                          add_symbols_copy(templnode);
2784
2785                          if (Strcmp(nodeType(templnode),"class") == 0) {
2786
2787                            /* Identify pure abstract methods */
2788                            Setattr(templnode,"abstract", pure_abstract(firstChild(templnode)));
2789
2790                            /* Set up inheritance in symbol table */
2791                            {
2792                              Symtab  *csyms;
2793                              List *baselist = Getattr(templnode,"baselist");
2794                              csyms = Swig_symbol_current();
2795                              Swig_symbol_setscope(Getattr(templnode,"symtab"));
2796                              if (baselist) {
2797                                List *bases = make_inherit_list(Getattr(templnode,"name"),baselist);
2798                                if (bases) {
2799                                  Iterator s;
2800                                  for (s = First(bases); s.item; s = Next(s)) {
2801                                    Symtab *st = Getattr(s.item,"symtab");
2802                                    if (st) {
2803				      Setfile(st,Getfile(s.item));
2804				      Setline(st,Getline(s.item));
2805                                      Swig_symbol_inherit(st);
2806                                    }
2807                                  }
2808				  Delete(bases);
2809                                }
2810                              }
2811                              Swig_symbol_setscope(csyms);
2812                            }
2813
2814                            /* Merge in addmethods for this class */
2815
2816			    /* !!! This may be broken.  We may have to add the
2817			       addmethods at the beginning of the class */
2818
2819                            if (extendhash) {
2820                              String *stmp = 0;
2821                              String *clsname;
2822                              Node *am;
2823                              if (Namespaceprefix) {
2824                                clsname = stmp = NewStringf("%s::%s", Namespaceprefix, Getattr(templnode,"name"));
2825                              } else {
2826                                clsname = Getattr(templnode,"name");
2827                              }
2828                              am = Getattr(extendhash,clsname);
2829                              if (am) {
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);
2837                              }
2838			      if (stmp) Delete(stmp);
2839                            }
2840                            /* Add to classes hash */
2841                            if (!classes) classes = NewHash();
2842
2843                            {
2844                              if (Namespaceprefix) {
2845                                String *temp = NewStringf("%s::%s", Namespaceprefix, Getattr(templnode,"name"));
2846                                Setattr(classes,temp,templnode);
2847				Delete(temp);
2848                              } else {
2849				String *qs = Swig_symbol_qualifiedscopename(templnode);
2850                                Setattr(classes, qs,templnode);
2851				Delete(qs);
2852                              }
2853                            }
2854                          }
2855                        }
2856
2857                        /* all the overloaded templated functions are added into a linked list */
2858                        if (nscope_inner) {
2859                          /* non-global namespace */
2860                          if (templnode) {
2861                            appendChild(nscope_inner,templnode);
2862			    Delete(templnode);
2863                            if (nscope) $$ = nscope;
2864                          }
2865                        } else {
2866                          /* global namespace */
2867                          if (!linklistend) {
2868                            $$ = templnode;
2869                          } else {
2870                            set_nextSibling(linklistend,templnode);
2871			    Delete(templnode);
2872                          }
2873                          linklistend = templnode;
2874                        }
2875                      }
2876                      nn = Getattr(nn,"sym:nextSibling"); /* repeat for overloaded templated functions. If a templated class there will never be a sibling. */
2877                    }
2878		  }
2879	          Swig_symbol_setscope(tscope);
2880		  Delete(Namespaceprefix);
2881		  Namespaceprefix = Swig_symbol_qualifiedscopename(0);
2882                }
2883               ;
2884
2885/* ------------------------------------------------------------
2886   %warn "text"
2887   %warn(no)
2888   ------------------------------------------------------------ */
2889
2890warn_directive : WARN string {
2891		  Swig_warning(0,cparse_file, cparse_line,"%s\n", $2);
2892		  $$ = 0;
2893               }
2894               ;
2895
2896/* ======================================================================
2897 *                              C Parsing
2898 * ====================================================================== */
2899
2900c_declaration   : c_decl {
2901                    $$ = $1;
2902                    if ($$) {
2903   		      add_symbols($$);
2904                      default_arguments($$);
2905   	            }
2906                }
2907                | c_enum_decl { $$ = $1; }
2908                | c_enum_forward_decl { $$ = $1; }
2909
2910/* An extern C type declaration, disable cparse_cplusplus if needed. */
2911
2912                | EXTERN string LBRACE {
2913		  if (Strcmp($2,"C") == 0) {
2914		    cparse_externc = 1;
2915		  }
2916		} interface RBRACE {
2917		  cparse_externc = 0;
2918		  if (Strcmp($2,"C") == 0) {
2919		    Node *n = firstChild($5);
2920		    $$ = new_node("extern");
2921		    Setattr($$,"name",$2);
2922		    appendChild($$,n);
2923		    while (n) {
2924		      SwigType *decl = Getattr(n,"decl");
2925		      if (SwigType_isfunction(decl)) {
2926			Setattr(n,"storage","externc");
2927		      }
2928		      n = nextSibling(n);
2929		    }
2930		  } else {
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));
2935		  }
2936                }
2937                ;
2938
2939/* ------------------------------------------------------------
2940   A C global declaration of some kind (may be variable, function, typedef, etc.)
2941   ------------------------------------------------------------ */
2942
2943c_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);
2954	      if (!$5) {
2955		if (Len(scanner_ccode)) {
2956		  String *code = Copy(scanner_ccode);
2957		  Setattr($$,"code",code);
2958		  Delete(code);
2959		}
2960	      } else {
2961		Node *n = $5;
2962		/* Inherit attributes */
2963		while (n) {
2964		  String *type = Copy($2);
2965		  Setattr(n,"type",type);
2966		  Setattr(n,"storage",$1);
2967		  n = nextSibling(n);
2968		  Delete(type);
2969		}
2970	      }
2971	      if ($4.bitfield) {
2972		Setattr($$,"bitfield", $4.bitfield);
2973	      }
2974
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);
2980		if (p) {
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);
2985		    Delete(lstr);
2986		    set_nextSibling($$,$5);
2987		  } else {
2988		    Delete($$);
2989		    $$ = $5;
2990		  }
2991		  Delete(p);
2992		} else {
2993		  Delete($$);
2994		  $$ = $5;
2995		}
2996	      } else {
2997		set_nextSibling($$,$5);
2998	      }
2999           }
3000           ;
3001
3002/* Allow lists of variables and functions to be built up */
3003
3004c_decl_tail    : SEMI {
3005                   $$ = 0;
3006                   Clear(scanner_ccode);
3007               }
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);
3017		 if ($3.bitfield) {
3018		   Setattr($$,"bitfield", $3.bitfield);
3019		 }
3020		 if (!$4) {
3021		   if (Len(scanner_ccode)) {
3022		     String *code = Copy(scanner_ccode);
3023		     Setattr($$,"code",code);
3024		     Delete(code);
3025		   }
3026		 } else {
3027		   set_nextSibling($$,$4);
3028		 }
3029	       }
3030               | LBRACE {
3031                   skip_balanced('{','}');
3032                   $$ = 0;
3033               }
3034              ;
3035
3036initializer   : def_args {
3037                   $$ = $1;
3038                   $$.qualifier = 0;
3039		   $$.throws = 0;
3040		   $$.throwf = 0;
3041              }
3042              | type_qualifier def_args {
3043                   $$ = $2;
3044		   $$.qualifier = $1;
3045		   $$.throws = 0;
3046		   $$.throwf = 0;
3047	      }
3048              | THROW LPAREN parms RPAREN def_args {
3049		   $$ = $5;
3050                   $$.qualifier = 0;
3051		   $$.throws = $3;
3052		   $$.throwf = NewString("1");
3053              }
3054              | type_qualifier THROW LPAREN parms RPAREN def_args {
3055                   $$ = $6;
3056                   $$.qualifier = $1;
3057		   $$.throws = $4;
3058		   $$.throwf = NewString("1");
3059              }
3060              ;
3061
3062
3063/* ------------------------------------------------------------
3064   enum Name;
3065   ------------------------------------------------------------ */
3066
3067c_enum_forward_decl : storage_class ENUM ID SEMI {
3068		   SwigType *ty = 0;
3069		   $$ = new_node("enumforward");
3070		   ty = NewStringf("enum %s", $3);
3071		   Setattr($$,"name",$3);
3072		   Setattr($$,"type",ty);
3073		   Setattr($$,"sym:weak", "1");
3074		   add_symbols($$);
3075	      }
3076              ;
3077
3078/* ------------------------------------------------------------
3079   enum { ... }
3080 * ------------------------------------------------------------ */
3081
3082c_enum_decl : storage_class ENUM ename LBRACE enumlist RBRACE SEMI {
3083		  SwigType *ty = 0;
3084                  $$ = new_node("enum");
3085		  ty = NewStringf("enum %s", $3);
3086		  Setattr($$,"name",$3);
3087		  Setattr($$,"type",ty);
3088		  appendChild($$,$5);
3089		  add_symbols($$);       /* Add to tag space */
3090		  add_symbols($5);       /* Add enum values to id space */
3091               }
3092               | storage_class ENUM ename LBRACE enumlist RBRACE declarator c_decl_tail {
3093		 Node *n;
3094		 SwigType *ty = 0;
3095		 String   *unnamed = 0;
3096		 int       unnamedinstance = 0;
3097
3098		 $$ = new_node("enum");
3099		 if ($3) {
3100		   Setattr($$,"name",$3);
3101		   ty = NewStringf("enum %s", $3);
3102		 } else if ($7.id) {
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);
3109                   } else {
3110                     unnamedinstance = 1;
3111                   }
3112		   Setattr($$,"storage",$1);
3113		 }
3114		 if ($7.id && Cmp($1,"typedef") == 0) {
3115		   Setattr($$,"tdname",$7.id);
3116                   Setattr($$,"allows_typedef","1");
3117                 }
3118		 appendChild($$,$5);
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);
3126
3127                 if (unnamedinstance) {
3128		   SwigType *cty = NewString("enum ");
3129		   Setattr($$,"type",cty);
3130		   Setattr($$,"unnamedinstance","1");
3131		   Setattr(n,"unnamedinstance","1");
3132		   Delete(cty);
3133                 }
3134		 if ($8) {
3135		   Node *p = $8;
3136		   set_nextSibling(n,p);
3137		   while (p) {
3138		     SwigType *cty = Copy(ty);
3139		     Setattr(p,"type",cty);
3140		     Setattr(p,"unnamed",unnamed);
3141		     Setattr(p,"storage",$1);
3142		     Delete(cty);
3143		     p = nextSibling(p);
3144		   }
3145		 } else {
3146		   if (Len(scanner_ccode)) {
3147		     String *code = Copy(scanner_ccode);
3148		     Setattr(n,"code",code);
3149		     Delete(code);
3150		   }
3151		 }
3152
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);
3158		   Delete(name);
3159                 }
3160
3161		 add_symbols($$);       /* Add enum to tag space */
3162		 set_nextSibling($$,n);
3163		 Delete(n);
3164		 add_symbols($5);       /* Add enum values to id space */
3165	         add_symbols(n);
3166		 Delete(unnamed);
3167	       }
3168               ;
3169
3170c_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:
3174
3175                         type (id)(parms)
3176
3177			 Otherwise it's an error. */
3178                    int err = 0;
3179                    $$ = 0;
3180
3181		    if ((ParmList_len($4) == 1) && (!Swig_scopename_check($2))) {
3182		      SwigType *ty = Getattr($4,"type");
3183		      String *name = Getattr($4,"name");
3184		      err = 1;
3185		      if (!name) {
3186			$$ = new_node("cdecl");
3187			Setattr($$,"type",$2);
3188			Setattr($$,"storage",$1);
3189			Setattr($$,"name",ty);
3190
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);
3199			    Delete(code);
3200			  }
3201			}
3202			if ($6.defarg) {
3203			  Setattr($$,"value",$6.defarg);
3204			}
3205			Setattr($$,"throws",$6.throws);
3206			Setattr($$,"throw",$6.throwf);
3207			err = 0;
3208		      }
3209		    }
3210		    if (err) {
3211		      Swig_error(cparse_file,cparse_line,"Syntax error in input(2).\n");
3212		      exit(1);
3213		    }
3214                }
3215                ;
3216
3217/* ======================================================================
3218 *                       C++ Support
3219 * ====================================================================== */
3220
3221cpp_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; }
3227                ;
3228
3229cpp_class_decl  :
3230
3231/* A simple class/struct/union definition */
3232                storage_class cpptype idcolon inherit LBRACE {
3233                   List *bases = 0;
3234		   Node *scope = 0;
3235		   $<node>$ = new_node("class");
3236		   Setline($<node>$,cparse_start_line);
3237		   Setattr($<node>$,"kind",$2);
3238		   if ($4) {
3239		     Setattr($<node>$,"baselist", Getattr($4,"public"));
3240		     Setattr($<node>$,"protectedbaselist", Getattr($4,"protected"));
3241		     Setattr($<node>$,"privatebaselist", Getattr($4,"private"));
3242		   }
3243		   Setattr($<node>$,"allows_typedef","1");
3244
3245		   /* preserve the current scope */
3246		   prev_symtab = Swig_symbol_current();
3247
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);
3252		   $3 = scope;
3253
3254		   /* support for old nested classes "pseudo" support, such as:
3255
3256		         %rename(Ala__Ola) Ala::Ola;
3257			class Ala::Ola {
3258			public:
3259			    Ola() {}
3260		         };
3261
3262		      this should disappear when a proper implementation is added.
3263		   */
3264		   if (nscope_inner && Strcmp(nodeType(nscope_inner),"namespace") != 0) {
3265		     if (Namespaceprefix) {
3266		       String *name = NewStringf("%s::%s", Namespaceprefix, $3);
3267		       $3 = name;
3268		       Namespaceprefix = 0;
3269		       nscope_inner = 0;
3270		     }
3271		   }
3272		   Setattr($<node>$,"name",$3);
3273
3274		   Delete(class_rename);
3275                   class_rename = make_name($<node>$,$3,0);
3276		   Classprefix = NewString($3);
3277		   /* Deal with inheritance  */
3278		   if ($4) {
3279		     bases = make_inherit_list($3,Getattr($4,"public"));
3280		   }
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);
3287		     } else {
3288		       fbase = Copy($3);
3289		       tbase = Copy(prefix);
3290		     }
3291		     Swig_name_inherit(tbase,fbase);
3292		     Delete(fbase);
3293		     Delete(tbase);
3294		     Delete(prefix);
3295		   }
3296                   if (strcmp($2,"class") == 0) {
3297		     cplus_mode = CPLUS_PRIVATE;
3298		   } else {
3299		     cplus_mode = CPLUS_PUBLIC;
3300		   }
3301		   Swig_symbol_newscope();
3302		   Swig_symbol_setscopename($3);
3303		   if (bases) {
3304		     Iterator s;
3305		     for (s = First(bases); s.item; s = Next(s)) {
3306		       Symtab *st = Getattr(s.item,"symtab");
3307		       if (st) {
3308			 Setfile(st,Getfile(s.item));
3309			 Setline(st,Getline(s.item));
3310			 Swig_symbol_inherit(st);
3311		       }
3312		     }
3313		     Delete(bases);
3314		   }
3315		   Delete(Namespaceprefix);
3316		   Namespaceprefix = Swig_symbol_qualifiedscopename(0);
3317		   cparse_start_line = cparse_line;
3318
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 */
3321
3322		   if (template_parameters) {
3323		     Parm *tp = template_parameters;
3324		     while(tp) {
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);
3330		       Delete(tpname);
3331		     }
3332		   }
3333		   if (class_level >= max_class_levels) {
3334		       if (!max_class_levels) {
3335			   max_class_levels = 16;
3336		       } else {
3337			   max_class_levels *= 2;
3338		       }
3339		       class_decl = (Node**) realloc(class_decl, sizeof(Node*) * max_class_levels);
3340		       if (!class_decl) {
3341			   Swig_error(cparse_file, cparse_line, "realloc() failed\n");
3342		       }
3343		   }
3344		   class_decl[class_level++] = $<node>$;
3345		   inclass = 1;
3346               } cpp_members RBRACE cpp_opt_declarators {
3347		 Node *p;
3348		 SwigType *ty;
3349		 Symtab *cscope = prev_symtab;
3350		 Node *am = 0;
3351		 String *scpname = 0;
3352		 $$ = class_decl[--class_level];
3353		 inclass = 0;
3354
3355		 /* Check for pure-abstract class */
3356		 Setattr($$,"abstract", pure_abstract($7));
3357
3358		 /* This bit of code merges in a previously defined %extend directive (if any) */
3359
3360		 if (extendhash) {
3361		   String *clsname = Swig_symbol_qualifiedscopename(0);
3362		   am = Getattr(extendhash,clsname);
3363		   if (am) {
3364		     merge_extensions($$,am);
3365		     Delattr(extendhash,clsname);
3366		   }
3367		   Delete(clsname);
3368		 }
3369		 if (!classes) classes = NewHash();
3370		 scpname = Swig_symbol_qualifiedscopename(0);
3371		 Setattr(classes,scpname,$$);
3372		 Delete(scpname);
3373
3374		 appendChild($$,$7);
3375
3376		 if (am) append_previous_extension($$,am);
3377
3378		 p = $9;
3379		 if (p) {
3380		   set_nextSibling($$,p);
3381		 }
3382
3383		 if (cparse_cplusplus && !cparse_externc) {
3384		   ty = NewString($3);
3385		 } else {
3386		   ty = NewStringf("%s %s", $2,$3);
3387		 }
3388		 while (p) {
3389		   Setattr(p,"storage",$1);
3390		   Setattr(p,"type",ty);
3391		   p = nextSibling(p);
3392		 }
3393		 /* Dump nested classes */
3394		 {
3395		   String *name = $3;
3396		   if ($9) {
3397		     SwigType *decltype = Getattr($9,"decl");
3398		     if (Cmp($1,"typedef") == 0) {
3399		       if (!decltype || !Len(decltype)) {
3400			 String *cname;
3401			 name = Getattr($9,"name");
3402			 cname = Copy(name);
3403			 Setattr($$,"tdname",cname);
3404			 Delete(cname);
3405
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);
3410			 }
3411			 if (!Getattr(classes,name)) {
3412			   Setattr(classes,name,$$);
3413			 }
3414			 Setattr($$,"decl",decltype);
3415		       }
3416		     }
3417		   }
3418		   appendChild($$,dump_nested(Char(name)));
3419		 }
3420
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;
3427		   appendChild($$,pa);
3428		   Delete(pa);
3429		 }
3430
3431		 Setattr($$,"symtab",Swig_symbol_popscope());
3432
3433		 Classprefix = 0;
3434		 if (nscope_inner) {
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);
3441		   add_symbols($$);
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);
3447		   add_symbols($9);
3448		 } else {
3449		   Delete(yyrename);
3450		   yyrename = Copy(class_rename);
3451		   Delete(Namespaceprefix);
3452		   Namespaceprefix = Swig_symbol_qualifiedscopename(0);
3453
3454		   add_symbols($$);
3455		   add_symbols($9);
3456		 }
3457		 Swig_symbol_setscope(cscope);
3458		 Delete(Namespaceprefix);
3459		 Namespaceprefix = Swig_symbol_qualifiedscopename(0);
3460	       }
3461
3462/* An unnamed struct, possibly with a typedef */
3463
3464             | storage_class cpptype LBRACE {
3465	       String *unnamed;
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;
3477	       } else {
3478		 cplus_mode = CPLUS_PUBLIC;
3479	       }
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;
3485		   } else {
3486		       max_class_levels *= 2;
3487		   }
3488		   class_decl = (Node**) realloc(class_decl, sizeof(Node*) * max_class_levels);
3489		   if (!class_decl) {
3490		       Swig_error(cparse_file, cparse_line, "realloc() failed\n");
3491		   }
3492	       }
3493	       class_decl[class_level++] = $<node>$;
3494	       inclass = 1;
3495	       Classprefix = NewStringEmpty();
3496	       Delete(Namespaceprefix);
3497	       Namespaceprefix = Swig_symbol_qualifiedscopename(0);
3498             } cpp_members RBRACE declarator c_decl_tail {
3499	       String *unnamed;
3500	       Node *n;
3501	       Classprefix = 0;
3502	       $$ = class_decl[--class_level];
3503	       inclass = 0;
3504	       unnamed = Getattr($$,"unnamed");
3505
3506	       /* Check for pure-abstract class */
3507	       Setattr($$,"abstract", pure_abstract($5));
3508
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);
3516	       if ($8) {
3517		 Node *p = $8;
3518		 set_nextSibling(n,p);
3519		 while (p) {
3520		   String *type = Copy(unnamed);
3521		   Setattr(p,"name",$7.id);
3522		   Setattr(p,"unnamed",unnamed);
3523		   Setattr(p,"type",type);
3524		   Delete(type);
3525		   Setattr(p,"storage",$1);
3526		   p = nextSibling(p);
3527		 }
3528	       }
3529	       set_nextSibling($$,n);
3530	       Delete(n);
3531	       {
3532		 /* If a proper typedef name was given, we'll use it to set the scope name */
3533		 String *name = 0;
3534		 if ($1 && (strcmp($1,"typedef") == 0)) {
3535		   if (!Len($7.type)) {
3536		     String *scpname = 0;
3537		     name = $7.id;
3538		     Setattr($$,"tdname",name);
3539		     Setattr($$,"name",name);
3540		     Swig_symbol_setscopename(name);
3541
3542		     /* If a proper name was given, we use that as the typedef, not unnamed */
3543		     Clear(unnamed);
3544		     Append(unnamed, name);
3545
3546		     n = nextSibling(n);
3547		     set_nextSibling($$,n);
3548
3549		     /* Check for previous extensions */
3550		     if (extendhash) {
3551		       String *clsname = Swig_symbol_qualifiedscopename(0);
3552		       Node *am = Getattr(extendhash,clsname);
3553		       if (am) {
3554			 /* Merge the extension into the symbol table */
3555			 merge_extensions($$,am);
3556			 append_previous_extension($$,am);
3557			 Delattr(extendhash,clsname);
3558		       }
3559		       Delete(clsname);
3560		     }
3561		     if (!classes) classes = NewHash();
3562		     scpname = Swig_symbol_qualifiedscopename(0);
3563		     Setattr(classes,scpname,$$);
3564		     Delete(scpname);
3565		   } else {
3566		     Swig_symbol_setscopename((char*)"<unnamed>");
3567		   }
3568		 }
3569		 appendChild($$,$5);
3570		 appendChild($$,dump_nested(Char(name)));
3571	       }
3572	       /* Pop the scope */
3573	       Setattr($$,"symtab",Swig_symbol_popscope());
3574	       if (class_rename) {
3575		 Delete(yyrename);
3576		 yyrename = NewString(class_rename);
3577	       }
3578	       Delete(Namespaceprefix);
3579	       Namespaceprefix = Swig_symbol_qualifiedscopename(0);
3580	       add_symbols($$);
3581	       add_symbols(n);
3582	       Delete(unnamed);
3583              }
3584             ;
3585
3586cpp_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);
3593                    }
3594                    ;
3595/* ------------------------------------------------------------
3596   class Name;
3597   ------------------------------------------------------------ */
3598
3599cpp_forward_class_decl : storage_class cpptype idcolon SEMI {
3600              if ($1 && (Strcmp($1,"friend") == 0)) {
3601		/* Ignore */
3602                $$ = 0;
3603	      } else {
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");
3610		add_symbols($$);
3611	      }
3612             }
3613             ;
3614
3615/* ------------------------------------------------------------
3616   template<...> decl
3617   ------------------------------------------------------------ */
3618
3619cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { template_parameters = $3; } cpp_temp_possible {
3620		      String *tname = 0;
3621		      int     error = 0;
3622
3623		      /* check if we get a namespace node with a class declaration, and retrieve the class */
3624		      Symtab *cscope = Swig_symbol_current();
3625		      Symtab *sti = 0;
3626		      Node *ntop = $6;
3627		      Node *ni = ntop;
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);
3633		      }
3634		      if (sti) {
3635			Swig_symbol_setscope(sti);
3636			Delete(Namespaceprefix);
3637			Namespaceprefix = Swig_symbol_qualifiedscopename(0);
3638			$6 = ni;
3639		      }
3640
3641                      template_parameters = 0;
3642                      $$ = $6;
3643		      if ($$) tname = Getattr($$,"name");
3644
3645		      /* Check if the class is a template specialization */
3646		      if (($$) && (Strchr(tname,'<')) && (!is_operator(tname))) {
3647			/* If a specialization.  Check if defined. */
3648			Node *tempn = 0;
3649			{
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);
3656			    tempn = 0;
3657			    error = 1;
3658			  }
3659			  Delete(tbase);
3660			}
3661			Setattr($$,"specialization","1");
3662			Setattr($$,"templatetype",nodeType($$));
3663			set_nodeType($$,"template");
3664			/* Template partial specialization */
3665			if (tempn && ($3) && ($6)) {
3666			  List   *tlist;
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");
3672			  }
3673
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")));
3676
3677			  } else {
3678
3679			  /* This code builds the argument list for the partial template
3680                             specialization.  This is a little hairy, but the idea is as
3681                             follows:
3682
3683                             $3 contains a list of arguments supplied for the template.
3684                             For example template<class T>.
3685
3686                             tlist is a list of the specialization arguments--which may be
3687                             different.  For example class<int,T>.
3688
3689                             tp is a copy of the arguments in the original template definition.
3690
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
3694                             original template.
3695			  */
3696
3697			  {
3698			    String *pn;
3699			    Parm *p, *p1;
3700			    int i, nargs;
3701			    Parm *tp = CopyParmList(Getattr(tempn,"templateparms"));
3702			    nargs = Len(tlist);
3703			    p = $3;
3704			    while (p) {
3705			      for (i = 0; i < nargs; i++){
3706				pn = Getattr(p,"name");
3707				if (Strcmp(pn,SwigType_base(Getitem(tlist,i))) == 0) {
3708				  int j;
3709				  Parm *p1 = tp;
3710				  for (j = 0; j < i; j++) {
3711				    p1 = nextSibling(p1);
3712				  }
3713				  Setattr(p1,"name",pn);
3714				  Setattr(p1,"partialarg","1");
3715				}
3716			      }
3717			      p = nextSibling(p);
3718			    }
3719			    p1 = tp;
3720			    i = 0;
3721			    while (p1) {
3722			      if (!Getattr(p1,"partialarg")) {
3723				Delattr(p1,"name");
3724				Setattr(p1,"type", Getitem(tlist,i));
3725			      }
3726			      i++;
3727			      p1 = nextSibling(p1);
3728			    }
3729			    Setattr($$,"templateparms",tp);
3730			    Delete(tp);
3731			  }
3732#if 0
3733			  /* Patch the parameter list */
3734			  if (tempn) {
3735			    Parm *p,*p1;
3736			    ParmList *tp = CopyParmList(Getattr(tempn,"templateparms"));
3737			    p = $3;
3738			    p1 = tp;
3739			    while (p && p1) {
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);
3746			      p = nextSibling(p);
3747			      p1 = nextSibling(p1);
3748			    }
3749			    Setattr($$,"templateparms",tp);
3750			    Delete(tp);
3751			  } else {
3752			    Setattr($$,"templateparms",$3);
3753			  }
3754#endif
3755			  Delattr($$,"specialization");
3756			  Setattr($$,"partialspecialization","1");
3757			  /* Create a specialized name for matching */
3758			  {
3759			    Parm *p = $3;
3760			    String *fname = NewString(Getattr($$,"name"));
3761			    String *ffname = 0;
3762
3763			    char   tmp[32];
3764			    int    i, ilen;
3765			    while (p) {
3766			      String *n = Getattr(p,"name");
3767			      if (!n) {
3768				p = nextSibling(p);
3769				continue;
3770			      }
3771			      ilen = Len(tlist);
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);
3776				}
3777			      }
3778			      p = nextSibling(p);
3779			    }
3780			    /* Patch argument names with typedef */
3781			    {
3782			      Iterator tt;
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);
3789				Append(ffname,ttr);
3790				tt = Next(tt);
3791				if (tt.item) Putc(',',ffname);
3792				Delete(rtt);
3793				Delete(ttr);
3794			      }
3795			      Delete(tparms);
3796			      Append(ffname,")>");
3797			    }
3798			    {
3799			      String *partials = Getattr(tempn,"partials");
3800			      if (!partials) {
3801				partials = NewList();
3802				Setattr(tempn,"partials",partials);
3803				Delete(partials);
3804			      }
3805			      /*			      Printf(stdout,"partial: fname = '%s', '%s'\n", fname, Swig_symbol_typedef_reduce(fname,0)); */
3806			      Append(partials,ffname);
3807			    }
3808			    Setattr($$,"partialargs",ffname);
3809			    Swig_symbol_cadd(ffname,$$);
3810			  }
3811			  }
3812			  Delete(tlist);
3813			  Delete(targs);
3814			} else {
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,$$);
3820			  Delete(ty);
3821			  Delete(fname);
3822			}
3823		      }  else if ($$) {
3824			Setattr($$,"templatetype",nodeType($6));
3825			set_nodeType($$,"template");
3826			Setattr($$,"templateparms", $3);
3827			if (!Getattr($$,"sym:weak")) {
3828			  Setattr($$,"sym:typename","1");
3829			}
3830			add_symbols($$);
3831                        default_arguments($$);
3832			/* We also place a fully parameterized version in the symbol table */
3833			{
3834			  Parm *p;
3835			  String *fname = NewStringf("%s<(", Getattr($$,"name"));
3836			  p = $3;
3837			  while (p) {
3838			    String *n = Getattr(p,"name");
3839			    if (!n) n = Getattr(p,"type");
3840			    Append(fname,n);
3841			    p = nextSibling(p);
3842			    if (p) Putc(',',fname);
3843			  }
3844			  Append(fname,")>");
3845			  Swig_symbol_cadd(fname,$$);
3846			}
3847		      }
3848		      $$ = ntop;
3849		      Swig_symbol_setscope(cscope);
3850		      Delete(Namespaceprefix);
3851		      Namespaceprefix = Swig_symbol_qualifiedscopename(0);
3852		      if (error) $$ = 0;
3853                  }
3854                | TEMPLATE cpptype idcolon {
3855		  Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit template instantiation ignored.\n");
3856                   $$ = 0;
3857                }
3858                ;
3859
3860cpp_temp_possible:  c_decl {
3861		  $$ = $1;
3862                }
3863                | cpp_class_decl {
3864                   $$ = $1;
3865                }
3866                | cpp_constructor_decl {
3867                   $$ = $1;
3868                }
3869                | cpp_template_decl {
3870		  $$ = 0;
3871                }
3872                | cpp_forward_class_decl {
3873                  $$ = $1;
3874                }
3875                | cpp_conversion_operator {
3876                  $$ = $1;
3877                }
3878                ;
3879
3880template_parms  : templateparameters {
3881		   /* Rip out the parameter names */
3882		  Parm *p = $1;
3883		  $$ = $1;
3884
3885		  while (p) {
3886		    String *name = Getattr(p,"name");
3887		    if (!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) {
3892			type += 16;
3893		      }
3894		      if ((strncmp(type,"class ",6) == 0) || (strncmp(type,"typename ", 9) == 0)) {
3895			char *t = strchr(type,' ');
3896			Setattr(p,"name", t+1);
3897		      } else {
3898			/*
3899			 Swig_error(cparse_file, cparse_line, "Missing template parameter name\n");
3900			 $$.rparms = 0;
3901			 $$.parms = 0;
3902			 break; */
3903		      }
3904		    }
3905		    p = nextSibling(p);
3906		  }
3907                 }
3908                 ;
3909
3910templateparameters : templateparameter templateparameterstail {
3911                      set_nextSibling($1,$2);
3912                      $$ = $1;
3913                   }
3914                   | empty { $$ = 0; }
3915                   ;
3916
3917templateparameter : templcpptype {
3918		    $$ = NewParm(NewString($1), 0);
3919                  }
3920                  | parm {
3921                    $$ = $1;
3922                  }
3923                  ;
3924
3925templateparameterstail : COMMA templateparameter templateparameterstail {
3926                         set_nextSibling($2,$3);
3927                         $$ = $2;
3928                       }
3929                       | empty { $$ = 0; }
3930                       ;
3931
3932/* Namespace support */
3933
3934cpp_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);
3940		  Delete(uname);
3941		  Delete(name);
3942		  add_symbols($$);
3943             }
3944             | USING NAMESPACE idcolon SEMI {
3945	       Node *n = Swig_symbol_clookup($3,0);
3946	       if (!n) {
3947		 Swig_error(cparse_file, cparse_line, "Nothing known about namespace '%s'\n", $3);
3948		 $$ = 0;
3949	       } else {
3950
3951		 while (Strcmp(nodeType(n),"using") == 0) {
3952		   n = Getattr(n,"node");
3953		 }
3954		 if (n) {
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);
3963		     }
3964		   } else {
3965		     Swig_error(cparse_file, cparse_line, "'%s' is not a namespace.\n", $3);
3966		     $$ = 0;
3967		   }
3968		 } else {
3969		   $$ = 0;
3970		 }
3971	       }
3972             }
3973             ;
3974
3975cpp_namespace_decl : NAMESPACE idcolon LBRACE {
3976                Hash *h;
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");
3985		  }
3986		  Swig_symbol_setscope(Getattr(h,"symtab"));
3987		} else {
3988		  Swig_symbol_newscope();
3989		  Swig_symbol_setscopename($2);
3990		}
3991		Delete(Namespaceprefix);
3992		Namespaceprefix = Swig_symbol_qualifiedscopename(0);
3993             } interface RBRACE {
3994                Node *n = $5;
3995		set_nodeType(n,"namespace");
3996		Setattr(n,"name",$2);
3997                Setattr(n,"symtab", Swig_symbol_popscope());
3998		Swig_symbol_setscope($1);
3999		$$ = n;
4000		Delete(Namespaceprefix);
4001		Namespaceprefix = Swig_symbol_qualifiedscopename(0);
4002		add_symbols($$);
4003             }
4004             | NAMESPACE LBRACE {
4005	       Hash *h;
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"));
4010	       } else {
4011		 Swig_symbol_newscope();
4012		 /* we don't use "__unnamed__", but a long 'empty' name */
4013		 Swig_symbol_setscopename("    ");
4014	       }
4015	       Namespaceprefix = 0;
4016             } interface RBRACE {
4017	       $$ = $4;
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);
4024	       add_symbols($$);
4025             }
4026             | NAMESPACE ID EQUAL idcolon SEMI {
4027	       /* Namespace alias */
4028	       Node *n;
4029	       $$ = new_node("namespace");
4030	       Setattr($$,"name",$2);
4031	       Setattr($$,"alias",$4);
4032	       n = Swig_symbol_clookup($4,0);
4033	       if (!n) {
4034		 Swig_error(cparse_file, cparse_line, "Unknown namespace '%s'\n", $4);
4035		 $$ = 0;
4036	       } else {
4037		 if (Strcmp(nodeType(n),"namespace") != 0) {
4038		   Swig_error(cparse_file, cparse_line, "'%s' is not a namespace\n",$4);
4039		   $$ = 0;
4040		 } else {
4041		   while (Getattr(n,"alias")) {
4042		     n = Getattr(n,"namespace");
4043		   }
4044		   Setattr($$,"namespace",n);
4045		   add_symbols($$);
4046		   /* Set up a scope alias */
4047		   Swig_symbol_alias($2,Getattr(n,"symtab"));
4048		 }
4049	       }
4050             }
4051             ;
4052
4053cpp_members  : cpp_member cpp_members {
4054                   $$ = $1;
4055                   /* Insert cpp_member (including any siblings) to the front of the cpp_members linked list */
4056		   if ($$) {
4057		     Node *p = $$;
4058		     Node *pp =0;
4059		     while (p) {
4060		       pp = p;
4061		       p = nextSibling(p);
4062		     }
4063		     set_nextSibling(pp,$2);
4064		   } else {
4065		     $$ = $2;
4066		   }
4067             }
4068             | EXTEND LBRACE {
4069                  if (cplus_mode != CPLUS_PUBLIC) {
4070		     Swig_error(cparse_file,cparse_line,"%%extend can only be used in a public section\n");
4071		  }
4072             } cpp_members RBRACE cpp_members {
4073	       $$ = new_node("extend");
4074	       tag_nodes($4,"feature:extend",(char*) "1");
4075	       appendChild($$,$4);
4076	       set_nextSibling($$,$6);
4077	     }
4078             | include_directive { $$ = $1; }
4079             | empty { $$ = 0;}
4080	     | error {
4081	       int start_line = cparse_line;
4082	       skip_decl();
4083	       Swig_error(cparse_file,start_line,"Syntax error in input(3).\n");
4084	       exit(1);
4085	       } cpp_members {
4086		 $$ = $3;
4087   	     }
4088             ;
4089
4090/* ======================================================================
4091 *                         C++ Class members
4092 * ====================================================================== */
4093
4094/* A class member.  May be data or a function. Static or virtual as well */
4095
4096cpp_member   : c_declaration { $$ = $1; }
4097             | cpp_constructor_decl {
4098                 $$ = $1;
4099		 if (extendmode) {
4100		   String *symname;
4101		   symname= make_name($$,Getattr($$,"name"), Getattr($$,"decl"));
4102		   if (Strcmp(symname,Getattr($$,"name")) == 0) {
4103		     /* No renaming operation.  Set name to class name */
4104		     Delete(yyrename);
4105		     yyrename = NewString(Getattr(current_class,"sym:name"));
4106		   } else {
4107		     Delete(yyrename);
4108		     yyrename = symname;
4109		   }
4110		 }
4111		 add_symbols($$);
4112                 default_arguments($$);
4113             }
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; }
4129             | SEMI { $$ = 0; }
4130             ;
4131
4132/* Possibly a constructor */
4133/* Note: the use of 'type' is here to resolve a shift-reduce conflict.  For example:
4134            typedef Foo ();
4135            typedef Foo (*ptr)();
4136*/
4137
4138cpp_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end {
4139              if (Classprefix) {
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);
4152		   Delete(code);
4153		 }
4154		 SetFlag($$,"feature:new");
4155	      } else {
4156		$$ = 0;
4157              }
4158              }
4159              ;
4160
4161/* A destructor (hopefully) */
4162
4163cpp_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);
4168	       Delete(name);
4169	       if (Len(scanner_ccode)) {
4170		 String *code = Copy(scanner_ccode);
4171		 Setattr($$,"code",code);
4172		 Delete(code);
4173	       }
4174	       {
4175		 String *decl = NewStringEmpty();
4176		 SwigType_add_function(decl,$4);
4177		 Setattr($$,"decl",decl);
4178		 Delete(decl);
4179	       }
4180	       Setattr($$,"throws",$6.throws);
4181	       Setattr($$,"throw",$6.throwf);
4182	       add_symbols($$);
4183	      }
4184
4185/* A virtual destructor */
4186
4187              | VIRTUAL NOT idtemplate LPAREN parms RPAREN cpp_vend {
4188		String *name;
4189		char *c = 0;
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
4193		  add it */
4194	        if (Classprefix) {
4195                  c = strchr(Char(Classprefix),'<');
4196                  if (c && !Strchr($3,'<')) {
4197                    $3 = NewStringf("%s%s",$3,c);
4198                  }
4199		}
4200		Setattr($$,"storage","virtual");
4201	        name = NewStringf("%s",$3);
4202		if (*(Char(name)) != '~') Insert(name,0,"~");
4203		Setattr($$,"name",name);
4204		Delete(name);
4205		Setattr($$,"throws",$7.throws);
4206		Setattr($$,"throw",$7.throwf);
4207		if ($7.val) {
4208		  Setattr($$,"value","0");
4209		}
4210		if (Len(scanner_ccode)) {
4211		  String *code = Copy(scanner_ccode);
4212		  Setattr($$,"code",code);
4213		  Delete(code);
4214		}
4215		{
4216		  String *decl = NewStringEmpty();
4217		  SwigType_add_function(decl,$5);
4218		  Setattr($$,"decl",decl);
4219		  Delete(decl);
4220		}
4221
4222		add_symbols($$);
4223	      }
4224              ;
4225
4226
4227/* C++ type conversion operator */
4228cpp_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);
4233
4234		 SwigType_add_function($4,$6);
4235		 if ($8.qualifier) {
4236		   SwigType_push($4,$8.qualifier);
4237		 }
4238		 Setattr($$,"decl",$4);
4239		 Setattr($$,"parms",$6);
4240		 Setattr($$,"conversion_operator","1");
4241		 add_symbols($$);
4242              }
4243               | storage_class COPERATOR type AND LPAREN parms RPAREN cpp_vend {
4244		 SwigType *decl;
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);
4252		 if ($8.qualifier) {
4253		   SwigType_push(decl,$8.qualifier);
4254		 }
4255		 Setattr($$,"decl",decl);
4256		 Setattr($$,"parms",$6);
4257		 Setattr($$,"conversion_operator","1");
4258		 add_symbols($$);
4259	       }
4260
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);
4268		if ($7.qualifier) {
4269		  SwigType_push(t,$7.qualifier);
4270		}
4271		Setattr($$,"decl",t);
4272		Setattr($$,"parms",$5);
4273		Setattr($$,"conversion_operator","1");
4274		add_symbols($$);
4275              }
4276              ;
4277
4278/* isolated catch clause. */
4279
4280cpp_catch_decl : CATCH LPAREN parms RPAREN LBRACE {
4281                 skip_balanced('{','}');
4282                 $$ = 0;
4283               }
4284               ;
4285
4286/* public: */
4287cpp_protection_decl : PUBLIC COLON {
4288                $$ = new_node("access");
4289		Setattr($$,"kind","public");
4290                cplus_mode = CPLUS_PUBLIC;
4291              }
4292
4293/* private: */
4294              | PRIVATE COLON {
4295                $$ = new_node("access");
4296                Setattr($$,"kind","private");
4297		cplus_mode = CPLUS_PRIVATE;
4298	      }
4299
4300/* protected: */
4301
4302              | PROTECTED COLON {
4303		$$ = new_node("access");
4304		Setattr($$,"kind","protected");
4305		cplus_mode = CPLUS_PROTECTED;
4306	      }
4307              ;
4308
4309
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
4315   code later.  Yikes!
4316
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   ---------------------------------------------------------------------- */
4322
4323/* A struct sname { } id;  declaration */
4324
4325cpp_nested :   storage_class cpptype ID LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
4326	      } nested_decl SEMI {
4327	        $$ = 0;
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);
4334
4335		    n->name = Swig_copy_string($6.id);
4336		    n->line = cparse_start_line;
4337		    n->type = NewStringEmpty();
4338		    n->kind = $2;
4339		    n->unnamed = 0;
4340		    SwigType_push(n->type, $6.type);
4341		    n->next = 0;
4342		    add_nested(n);
4343		  } else {
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");
4354		      add_symbols($$);
4355		    }
4356		  }
4357		}
4358	      }
4359/* A struct { } id;  declaration */
4360              | storage_class cpptype LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
4361              } nested_decl SEMI {
4362	        $$ = 0;
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 */
4367		  } else if ($5.id) {
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();
4376		    n->kind = $2;
4377		    n->unnamed = 1;
4378		    SwigType_push(n->type,$5.type);
4379		    n->next = 0;
4380		    add_nested(n);
4381		  } else {
4382		    Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2);
4383		  }
4384		}
4385	      }
4386/* A  'class name : base_list { };'  declaration, always ignored */
4387/*****
4388     This fixes derived_nested.i, but it adds one shift/reduce. Anyway,
4389     we are waiting for the nested class support.
4390 *****/
4391              | storage_class cpptype idcolon COLON base_list LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
4392              } SEMI {
4393	        $$ = 0;
4394		if (cplus_mode == CPLUS_PUBLIC) {
4395		  Swig_warning(WARN_PARSE_NESTED_CLASS,cparse_file, cparse_line,"Nested class not currently supported (ignored)\n");
4396		}
4397	      }
4398/*
4399              | TEMPLATE LESSTHAN template_parms GREATERTHAN cpptype idcolon LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
4400              } SEMI {
4401	        $$ = 0;
4402		if (cplus_mode == CPLUS_PUBLIC) {
4403		  Swig_warning(WARN_PARSE_NESTED_CLASS,cparse_file, cparse_line,"Nested class not currently supported (ignored)\n");
4404		}
4405	      }
4406*/
4407              ;
4408
4409nested_decl   : declarator { $$ = $1;}
4410              | empty { $$.id = 0; }
4411              ;
4412
4413
4414/* These directives can be included inside a class definition */
4415
4416cpp_swig_directive: pragma_directive { $$ = $1; }
4417
4418/* A constant (includes #defines) inside a class */
4419             | constant_directive { $$ = $1; }
4420
4421/* This is the new style rename */
4422
4423             | name_directive { $$ = $1; }
4424
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; }
4434             ;
4435
4436cpp_end        : cpp_const SEMI {
4437	            Clear(scanner_ccode);
4438		    $$.throws = $1.throws;
4439		    $$.throwf = $1.throwf;
4440               }
4441               | cpp_const LBRACE {
4442		    skip_balanced('{','}');
4443		    $$.throws = $1.throws;
4444		    $$.throwf = $1.throwf;
4445	       }
4446               ;
4447
4448cpp_vend       : cpp_const SEMI {
4449                     Clear(scanner_ccode);
4450                     $$.val = 0;
4451                     $$.qualifier = $1.qualifier;
4452                     $$.bitfield = 0;
4453                     $$.throws = $1.throws;
4454                     $$.throwf = $1.throwf;
4455                }
4456               | cpp_const EQUAL definetype SEMI {
4457                     Clear(scanner_ccode);
4458                     $$.val = $3.val;
4459                     $$.qualifier = $1.qualifier;
4460                     $$.bitfield = 0;
4461                     $$.throws = $1.throws;
4462                     $$.throwf = $1.throwf;
4463               }
4464               | cpp_const LBRACE {
4465                     skip_balanced('{','}');
4466                     $$.val = 0;
4467                     $$.qualifier = $1.qualifier;
4468                     $$.bitfield = 0;
4469                     $$.throws = $1.throws;
4470                     $$.throwf = $1.throwf;
4471               }
4472               ;
4473
4474
4475anonymous_bitfield :  storage_class type COLON expr SEMI { };
4476
4477/* ======================================================================
4478 *                       PRIMITIVES
4479 * ====================================================================== */
4480
4481storage_class  : EXTERN { $$ = "extern"; }
4482               | EXTERN string {
4483                   if (strcmp($2,"C") == 0) {
4484		     $$ = "externc";
4485		   } else {
4486		     Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\".\n", $2);
4487		     $$ = 0;
4488		   }
4489               }
4490               | STATIC { $$ = "static"; }
4491               | TYPEDEF { $$ = "typedef"; }
4492               | VIRTUAL { $$ = "virtual"; }
4493               | FRIEND { $$ = "friend"; }
4494               | EXPLICIT { $$ = "explicit"; }
4495               | empty { $$ = 0; }
4496               ;
4497
4498/* ------------------------------------------------------------------------------
4499   Function parameter lists
4500   ------------------------------------------------------------------------------ */
4501
4502parms          : rawparms {
4503                 Parm *p;
4504		 $$ = $1;
4505		 p = $1;
4506                 while (p) {
4507		   Replace(Getattr(p,"type"),"typename ", "", DOH_REPLACE_ANY);
4508		   p = nextSibling(p);
4509                 }
4510               }
4511    	       ;
4512
4513rawparms          : parm ptail {
4514                  set_nextSibling($1,$2);
4515                  $$ = $1;
4516		}
4517               | empty { $$ = 0; }
4518               ;
4519
4520ptail          : COMMA parm ptail {
4521                 set_nextSibling($2,$3);
4522		 $$ = $2;
4523                }
4524               | empty { $$ = 0; }
4525               ;
4526
4527
4528parm           : rawtype parameter_declarator {
4529                   SwigType_push($1,$2.type);
4530		   $$ = NewParm($1,$2.id);
4531		   Setfile($$,cparse_file);
4532		   Setline($$,cparse_line);
4533		   if ($2.defarg) {
4534		     Setattr($$,"value",$2.defarg);
4535		   }
4536		}
4537
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);
4542                  if ($7.val) {
4543                    Setattr($$,"value",$7.val);
4544                  }
4545                }
4546                | PERIOD PERIOD PERIOD {
4547		  SwigType *t = NewString("v(...)");
4548		  $$ = NewParm(t, 0);
4549		  Setfile($$,cparse_file);
4550		  Setline($$,cparse_line);
4551		}
4552		;
4553
4554valparms        : rawvalparms {
4555                 Parm *p;
4556		 $$ = $1;
4557		 p = $1;
4558                 while (p) {
4559		   if (Getattr(p,"type")) {
4560		     Replace(Getattr(p,"type"),"typename ", "", DOH_REPLACE_ANY);
4561		   }
4562		   p = nextSibling(p);
4563                 }
4564               }
4565    	       ;
4566
4567rawvalparms     : valparm valptail {
4568                  set_nextSibling($1,$2);
4569                  $$ = $1;
4570		}
4571               | empty { $$ = 0; }
4572               ;
4573
4574valptail       : COMMA valparm valptail {
4575                 set_nextSibling($2,$3);
4576		 $$ = $2;
4577                }
4578               | empty { $$ = 0; }
4579               ;
4580
4581
4582valparm        : parm {
4583		  $$ = $1;
4584		  {
4585		    /* We need to make a possible adjustment for integer parameters. */
4586		    SwigType *type;
4587		    Node     *n = 0;
4588
4589		    while (!n) {
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");
4596			  if (value) {
4597			    String *v = Copy(value);
4598			    Setattr($1,"type",v);
4599			    Delete(v);
4600			    n = 0;
4601			  }
4602			}
4603		      } else {
4604			break;
4605		      }
4606		    }
4607		  }
4608
4609               }
4610               | valexpr {
4611                  $$ = NewParm(0,0);
4612                  Setfile($$,cparse_file);
4613		  Setline($$,cparse_line);
4614		  Setattr($$,"value",$1.val);
4615               }
4616               ;
4617
4618def_args       : EQUAL definetype {
4619                  $$ = $2;
4620		  if ($2.type == T_ERROR) {
4621		    Swig_warning(WARN_PARSE_BAD_DEFAULT,cparse_file, cparse_line, "Can't set default argument (ignored)\n");
4622		    $$.val = 0;
4623		    $$.rawval = 0;
4624		    $$.bitfield = 0;
4625		    $$.throws = 0;
4626		    $$.throwf = 0;
4627		  }
4628               }
4629               | EQUAL definetype LBRACKET expr RBRACKET {
4630		  $$ = $2;
4631		  if ($2.type == T_ERROR) {
4632		    Swig_warning(WARN_PARSE_BAD_DEFAULT,cparse_file, cparse_line, "Can't set default argument (ignored)\n");
4633		    $$ = $2;
4634		    $$.val = 0;
4635		    $$.rawval = 0;
4636		    $$.bitfield = 0;
4637		    $$.throws = 0;
4638		    $$.throwf = 0;
4639		  } else {
4640		    $$.val = NewStringf("%s[%s]",$2.val,$4.val);
4641		  }
4642               }
4643               | EQUAL LBRACE {
4644		 skip_balanced('{','}');
4645		 $$.val = 0;
4646		 $$.rawval = 0;
4647                 $$.type = T_INT;
4648		 $$.bitfield = 0;
4649		 $$.throws = 0;
4650		 $$.throwf = 0;
4651	       }
4652               | COLON expr {
4653		 $$.val = 0;
4654		 $$.rawval = 0;
4655		 $$.type = 0;
4656		 $$.bitfield = $2.val;
4657		 $$.throws = 0;
4658		 $$.throwf = 0;
4659	       }
4660               | empty {
4661                 $$.val = 0;
4662                 $$.rawval = 0;
4663                 $$.type = T_INT;
4664		 $$.bitfield = 0;
4665		 $$.throws = 0;
4666		 $$.throwf = 0;
4667               }
4668               ;
4669
4670parameter_declarator : declarator def_args {
4671                 $$ = $1;
4672		 $$.defarg = $2.rawval ? $2.rawval : $2.val;
4673            }
4674            | abstract_declarator def_args {
4675              $$ = $1;
4676	      $$.defarg = $2.rawval ? $2.rawval : $2.val;
4677            }
4678            | def_args {
4679   	      $$.type = 0;
4680              $$.id = 0;
4681	      $$.defarg = $1.rawval ? $1.rawval : $1.val;
4682            }
4683            ;
4684
4685typemap_parameter_declarator : declarator {
4686                 $$ = $1;
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));
4693		   } else {
4694		     $$.parms = 0;
4695		   }
4696		   SwigType_push($1.type,ta);
4697		   Delete(ta);
4698		 } else {
4699		   $$.parms = 0;
4700		 }
4701            }
4702            | abstract_declarator {
4703              $$ = $1;
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));
4710		} else {
4711		  $$.parms = 0;
4712		}
4713		SwigType_push($1.type,ta);
4714		Delete(ta);
4715	      } else {
4716		$$.parms = 0;
4717	      }
4718            }
4719            | empty {
4720   	      $$.type = 0;
4721              $$.id = 0;
4722	      $$.parms = 0;
4723	      }
4724            ;
4725
4726
4727declarator :  pointer notso_direct_declarator {
4728              $$ = $2;
4729	      if ($$.type) {
4730		SwigType_push($1,$$.type);
4731		Delete($$.type);
4732	      }
4733	      $$.type = $1;
4734           }
4735           | pointer AND notso_direct_declarator {
4736              $$ = $3;
4737	      SwigType_add_reference($1);
4738              if ($$.type) {
4739		SwigType_push($1,$$.type);
4740		Delete($$.type);
4741	      }
4742	      $$.type = $1;
4743           }
4744           | direct_declarator {
4745              $$ = $1;
4746	      if (!$$.type) $$.type = NewStringEmpty();
4747           }
4748           | AND notso_direct_declarator {
4749	     $$ = $2;
4750	     $$.type = NewStringEmpty();
4751	     SwigType_add_reference($$.type);
4752	     if ($2.type) {
4753	       SwigType_push($$.type,$2.type);
4754	       Delete($2.type);
4755	     }
4756           }
4757           | idcolon DSTAR notso_direct_declarator {
4758	     SwigType *t = NewStringEmpty();
4759
4760	     $$ = $3;
4761	     SwigType_add_memberpointer(t,$1);
4762	     if ($$.type) {
4763	       SwigType_push(t,$$.type);
4764	       Delete($$.type);
4765	     }
4766	     $$.type = t;
4767	     }
4768           | pointer idcolon DSTAR notso_direct_declarator {
4769	     SwigType *t = NewStringEmpty();
4770	     $$ = $4;
4771	     SwigType_add_memberpointer(t,$2);
4772	     SwigType_push($1,t);
4773	     if ($$.type) {
4774	       SwigType_push($1,$$.type);
4775	       Delete($$.type);
4776	     }
4777	     $$.type = $1;
4778	     Delete(t);
4779	   }
4780           | pointer idcolon DSTAR AND notso_direct_declarator {
4781	     $$ = $5;
4782	     SwigType_add_memberpointer($1,$2);
4783	     SwigType_add_reference($1);
4784	     if ($$.type) {
4785	       SwigType_push($1,$$.type);
4786	       Delete($$.type);
4787	     }
4788	     $$.type = $1;
4789	   }
4790           | idcolon DSTAR AND notso_direct_declarator {
4791	     SwigType *t = NewStringEmpty();
4792	     $$ = $4;
4793	     SwigType_add_memberpointer(t,$1);
4794	     SwigType_add_reference(t);
4795	     if ($$.type) {
4796	       SwigType_push(t,$$.type);
4797	       Delete($$.type);
4798	     }
4799	     $$.type = t;
4800	   }
4801           ;
4802
4803notso_direct_declarator : idcolon {
4804                /* Note: This is non-standard C.  Template declarator is allowed to follow an identifier */
4805                 $$.id = Char($1);
4806		 $$.type = 0;
4807		 $$.parms = 0;
4808		 $$.have_parms = 0;
4809                  }
4810                  | NOT idcolon {
4811                  $$.id = Char(NewStringf("~%s",$2));
4812                  $$.type = 0;
4813                  $$.parms = 0;
4814                  $$.have_parms = 0;
4815                  }
4816
4817/* This generate a shift-reduce conflict with constructors */
4818                 | LPAREN idcolon RPAREN {
4819                  $$.id = Char($2);
4820                  $$.type = 0;
4821                  $$.parms = 0;
4822                  $$.have_parms = 0;
4823                  }
4824
4825/*
4826                  | LPAREN AND idcolon RPAREN {
4827                     $$.id = Char($3);
4828                     $$.type = 0;
4829                     $$.parms = 0;
4830                     $$.have_parms = 0;
4831                  }
4832*/
4833/* Technically, this should be LPAREN declarator RPAREN, but we get reduce/reduce conflicts */
4834                  | LPAREN pointer notso_direct_declarator RPAREN {
4835		    $$ = $3;
4836		    if ($$.type) {
4837		      SwigType_push($2,$$.type);
4838		      Delete($$.type);
4839		    }
4840		    $$.type = $2;
4841                  }
4842                  | LPAREN idcolon DSTAR notso_direct_declarator RPAREN {
4843		    SwigType *t;
4844		    $$ = $4;
4845		    t = NewStringEmpty();
4846		    SwigType_add_memberpointer(t,$2);
4847		    if ($$.type) {
4848		      SwigType_push(t,$$.type);
4849		      Delete($$.type);
4850		    }
4851		    $$.type = t;
4852		    }
4853                  | notso_direct_declarator LBRACKET RBRACKET {
4854		    SwigType *t;
4855		    $$ = $1;
4856		    t = NewStringEmpty();
4857		    SwigType_add_array(t,(char*)"");
4858		    if ($$.type) {
4859		      SwigType_push(t,$$.type);
4860		      Delete($$.type);
4861		    }
4862		    $$.type = t;
4863                  }
4864                  | notso_direct_declarator LBRACKET expr RBRACKET {
4865		    SwigType *t;
4866		    $$ = $1;
4867		    t = NewStringEmpty();
4868		    SwigType_add_array(t,$3.val);
4869		    if ($$.type) {
4870		      SwigType_push(t,$$.type);
4871		      Delete($$.type);
4872		    }
4873		    $$.type = t;
4874                  }
4875                  | notso_direct_declarator LPAREN parms RPAREN {
4876		    SwigType *t;
4877                    $$ = $1;
4878		    t = NewStringEmpty();
4879		    SwigType_add_function(t,$3);
4880		    if (!$$.have_parms) {
4881		      $$.parms = $3;
4882		      $$.have_parms = 1;
4883		    }
4884		    if (!$$.type) {
4885		      $$.type = t;
4886		    } else {
4887		      SwigType_push(t, $$.type);
4888		      Delete($$.type);
4889		      $$.type = t;
4890		    }
4891		  }
4892                  ;
4893
4894direct_declarator : idcolon {
4895                /* Note: This is non-standard C.  Template declarator is allowed to follow an identifier */
4896                 $$.id = Char($1);
4897		 $$.type = 0;
4898		 $$.parms = 0;
4899		 $$.have_parms = 0;
4900                  }
4901
4902                  | NOT idcolon {
4903                  $$.id = Char(NewStringf("~%s",$2));
4904                  $$.type = 0;
4905                  $$.parms = 0;
4906                  $$.have_parms = 0;
4907                  }
4908
4909/* This generate a shift-reduce conflict with constructors */
4910/*
4911                  | LPAREN idcolon RPAREN {
4912                  $$.id = Char($2);
4913                  $$.type = 0;
4914                  $$.parms = 0;
4915                  $$.have_parms = 0;
4916                  }
4917*/
4918/* Technically, this should be LPAREN declarator RPAREN, but we get reduce/reduce conflicts */
4919                  | LPAREN pointer direct_declarator RPAREN {
4920		    $$ = $3;
4921		    if ($$.type) {
4922		      SwigType_push($2,$$.type);
4923		      Delete($$.type);
4924		    }
4925		    $$.type = $2;
4926                  }
4927                  | LPAREN AND direct_declarator RPAREN {
4928                    $$ = $3;
4929		    if (!$$.type) {
4930		      $$.type = NewStringEmpty();
4931		    }
4932		    SwigType_add_reference($$.type);
4933                  }
4934                  | LPAREN idcolon DSTAR direct_declarator RPAREN {
4935		    SwigType *t;
4936		    $$ = $4;
4937		    t = NewStringEmpty();
4938		    SwigType_add_memberpointer(t,$2);
4939		    if ($$.type) {
4940		      SwigType_push(t,$$.type);
4941		      Delete($$.type);
4942		    }
4943		    $$.type = t;
4944		    }
4945                  | direct_declarator LBRACKET RBRACKET {
4946		    SwigType *t;
4947		    $$ = $1;
4948		    t = NewStringEmpty();
4949		    SwigType_add_array(t,(char*)"");
4950		    if ($$.type) {
4951		      SwigType_push(t,$$.type);
4952		      Delete($$.type);
4953		    }
4954		    $$.type = t;
4955                  }
4956                  | direct_declarator LBRACKET expr RBRACKET {
4957		    SwigType *t;
4958		    $$ = $1;
4959		    t = NewStringEmpty();
4960		    SwigType_add_array(t,$3.val);
4961		    if ($$.type) {
4962		      SwigType_push(t,$$.type);
4963		      Delete($$.type);
4964		    }
4965		    $$.type = t;
4966                  }
4967                  | direct_declarator LPAREN parms RPAREN {
4968		    SwigType *t;
4969                    $$ = $1;
4970		    t = NewStringEmpty();
4971		    SwigType_add_function(t,$3);
4972		    if (!$$.have_parms) {
4973		      $$.parms = $3;
4974		      $$.have_parms = 1;
4975		    }
4976		    if (!$$.type) {
4977		      $$.type = t;
4978		    } else {
4979		      SwigType_push(t, $$.type);
4980		      Delete($$.type);
4981		      $$.type = t;
4982		    }
4983		  }
4984                  ;
4985
4986abstract_declarator : pointer {
4987		    $$.type = $1;
4988                    $$.id = 0;
4989		    $$.parms = 0;
4990		    $$.have_parms = 0;
4991                  }
4992                  | pointer direct_abstract_declarator {
4993                     $$ = $2;
4994                     SwigType_push($1,$2.type);
4995		     $$.type = $1;
4996		     Delete($2.type);
4997                  }
4998                  | pointer AND {
4999		    $$.type = $1;
5000		    SwigType_add_reference($$.type);
5001		    $$.id = 0;
5002		    $$.parms = 0;
5003		    $$.have_parms = 0;
5004		  }
5005                  | pointer AND direct_abstract_declarator {
5006		    $$ = $3;
5007		    SwigType_add_reference($1);
5008		    if ($$.type) {
5009		      SwigType_push($1,$$.type);
5010		      Delete($$.type);
5011		    }
5012		    $$.type = $1;
5013                  }
5014                  | direct_abstract_declarator {
5015		    $$ = $1;
5016                  }
5017                  | AND direct_abstract_declarator {
5018		    $$ = $2;
5019		    $$.type = NewStringEmpty();
5020		    SwigType_add_reference($$.type);
5021		    if ($2.type) {
5022		      SwigType_push($$.type,$2.type);
5023		      Delete($2.type);
5024		    }
5025                  }
5026                  | AND {
5027                    $$.id = 0;
5028                    $$.parms = 0;
5029		    $$.have_parms = 0;
5030                    $$.type = NewStringEmpty();
5031		    SwigType_add_reference($$.type);
5032                  }
5033                  | idcolon DSTAR {
5034		    $$.type = NewStringEmpty();
5035                    SwigType_add_memberpointer($$.type,$1);
5036                    $$.id = 0;
5037                    $$.parms = 0;
5038		    $$.have_parms = 0;
5039      	          }
5040                  | pointer idcolon DSTAR {
5041		    SwigType *t = NewStringEmpty();
5042                    $$.type = $1;
5043		    $$.id = 0;
5044		    $$.parms = 0;
5045		    $$.have_parms = 0;
5046		    SwigType_add_memberpointer(t,$2);
5047		    SwigType_push($$.type,t);
5048		    Delete(t);
5049                  }
5050                  | pointer idcolon DSTAR direct_abstract_declarator {
5051		    $$ = $4;
5052		    SwigType_add_memberpointer($1,$2);
5053		    if ($$.type) {
5054		      SwigType_push($1,$$.type);
5055		      Delete($$.type);
5056		    }
5057		    $$.type = $1;
5058                  }
5059                  ;
5060
5061direct_abstract_declarator : direct_abstract_declarator LBRACKET RBRACKET {
5062		    SwigType *t;
5063		    $$ = $1;
5064		    t = NewStringEmpty();
5065		    SwigType_add_array(t,(char*)"");
5066		    if ($$.type) {
5067		      SwigType_push(t,$$.type);
5068		      Delete($$.type);
5069		    }
5070		    $$.type = t;
5071                  }
5072                  | direct_abstract_declarator LBRACKET expr RBRACKET {
5073		    SwigType *t;
5074		    $$ = $1;
5075		    t = NewStringEmpty();
5076		    SwigType_add_array(t,$3.val);
5077		    if ($$.type) {
5078		      SwigType_push(t,$$.type);
5079		      Delete($$.type);
5080		    }
5081		    $$.type = t;
5082                  }
5083                  | LBRACKET RBRACKET {
5084		    $$.type = NewStringEmpty();
5085		    $$.id = 0;
5086		    $$.parms = 0;
5087		    $$.have_parms = 0;
5088		    SwigType_add_array($$.type,(char*)"");
5089                  }
5090                  | LBRACKET expr RBRACKET {
5091		    $$.type = NewStringEmpty();
5092		    $$.id = 0;
5093		    $$.parms = 0;
5094		    $$.have_parms = 0;
5095		    SwigType_add_array($$.type,$2.val);
5096		  }
5097                  | LPAREN abstract_declarator RPAREN {
5098                    $$ = $2;
5099		  }
5100                  | direct_abstract_declarator LPAREN parms RPAREN {
5101		    SwigType *t;
5102                    $$ = $1;
5103		    t = NewStringEmpty();
5104                    SwigType_add_function(t,$3);
5105		    if (!$$.type) {
5106		      $$.type = t;
5107		    } else {
5108		      SwigType_push(t,$$.type);
5109		      Delete($$.type);
5110		      $$.type = t;
5111		    }
5112		    if (!$$.have_parms) {
5113		      $$.parms = $3;
5114		      $$.have_parms = 1;
5115		    }
5116		  }
5117                  | LPAREN parms RPAREN {
5118                    $$.type = NewStringEmpty();
5119                    SwigType_add_function($$.type,$2);
5120		    $$.parms = $2;
5121		    $$.have_parms = 1;
5122		    $$.id = 0;
5123                  }
5124                  ;
5125
5126
5127pointer    : STAR type_qualifier pointer {
5128               $$ = NewStringEmpty();
5129               SwigType_add_pointer($$);
5130	       SwigType_push($$,$2);
5131	       SwigType_push($$,$3);
5132	       Delete($3);
5133           }
5134           | STAR pointer {
5135	     $$ = NewStringEmpty();
5136	     SwigType_add_pointer($$);
5137	     SwigType_push($$,$2);
5138	     Delete($2);
5139	     }
5140           | STAR type_qualifier {
5141	     	$$ = NewStringEmpty();
5142		SwigType_add_pointer($$);
5143	        SwigType_push($$,$2);
5144           }
5145           | STAR {
5146	      $$ = NewStringEmpty();
5147	      SwigType_add_pointer($$);
5148           }
5149           ;
5150
5151type_qualifier : type_qualifier_raw {
5152	          $$ = NewStringEmpty();
5153	          if ($1) SwigType_add_qualifier($$,$1);
5154               }
5155               | type_qualifier_raw type_qualifier {
5156		  $$ = $2;
5157	          if ($1) SwigType_add_qualifier($$,$1);
5158               }
5159               ;
5160
5161type_qualifier_raw :  CONST_QUAL { $$ = "const"; }
5162                   |  VOLATILE { $$ = "volatile"; }
5163                   |  REGISTER { $$ = 0; }
5164                   ;
5165
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. */
5168
5169type            : rawtype {
5170                   $$ = $1;
5171                   Replace($$,"typename ","", DOH_REPLACE_ANY);
5172                }
5173                ;
5174
5175rawtype       : type_qualifier type_right {
5176                   $$ = $2;
5177	           SwigType_push($$,$1);
5178               }
5179               | type_right { $$ = $1; }
5180               | type_right type_qualifier {
5181		  $$ = $1;
5182	          SwigType_push($$,$2);
5183	       }
5184               | type_qualifier type_right type_qualifier {
5185		  $$ = $2;
5186	          SwigType_push($$,$3);
5187	          SwigType_push($$,$1);
5188	       }
5189               ;
5190
5191type_right     : primitive_type { $$ = $1;
5192                  /* Printf(stdout,"primitive = '%s'\n", $$);*/
5193                }
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; }
5199
5200               | idcolon {
5201		  $$ = $1;
5202               }
5203               | cpptype idcolon {
5204		 $$ = NewStringf("%s %s", $1, $2);
5205               }
5206               ;
5207
5208primitive_type : primitive_type_list {
5209		 if (!$1.type) $1.type = NewString("int");
5210		 if ($1.us) {
5211		   $$ = NewStringf("%s %s", $1.us, $1.type);
5212		   Delete($1.us);
5213                   Delete($1.type);
5214		 } else {
5215                   $$ = $1.type;
5216		 }
5217		 if (Cmp($$,"signed int") == 0) {
5218		   Delete($$);
5219		   $$ = NewString("int");
5220                 } else if (Cmp($$,"signed long") == 0) {
5221		   Delete($$);
5222                   $$ = NewString("long");
5223                 } else if (Cmp($$,"signed short") == 0) {
5224		   Delete($$);
5225		   $$ = NewString("short");
5226		 } else if (Cmp($$,"signed long long") == 0) {
5227		   Delete($$);
5228		   $$ = NewString("long long");
5229		 }
5230               }
5231               ;
5232
5233primitive_type_list : type_specifier {
5234                 $$ = $1;
5235               }
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);
5239		    }
5240                    $$ = $2;
5241                    if ($1.us) $$.us = $1.us;
5242		    if ($1.type) {
5243		      if (!$2.type) $$.type = $1.type;
5244		      else {
5245			int err = 0;
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) {
5250			    $$.type = $1.type;
5251			  } else {
5252			    err = 1;
5253			  }
5254			} else if ((Cmp($1.type,"short")) == 0) {
5255			  if (Cmp($2.type,"int") == 0) {
5256			    $$.type = $1.type;
5257			  } else {
5258			    err = 1;
5259			  }
5260			} else if (Cmp($1.type,"int") == 0) {
5261			  $$.type = $2.type;
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");
5267			  } else {
5268			    err = 1;
5269			  }
5270			} else if (Cmp($1.type,"float") == 0) {
5271			  if (Cmp($2.type,"complex") == 0) {
5272			    $$.type = NewString("float complex");
5273			  } else {
5274			    err = 1;
5275			  }
5276			} else if (Cmp($1.type,"complex") == 0) {
5277			  $$.type = NewStringf("%s complex", $2.type);
5278			} else {
5279			  err = 1;
5280			}
5281			if (err) {
5282			  Swig_error(cparse_file, cparse_line, "Extra %s specifier.\n", $1.type);
5283			}
5284		      }
5285		    }
5286               }
5287               ;
5288
5289
5290type_specifier : TYPE_INT {
5291		    $$.type = NewString("int");
5292                    $$.us = 0;
5293               }
5294               | TYPE_SHORT {
5295                    $$.type = NewString("short");
5296                    $$.us = 0;
5297                }
5298               | TYPE_LONG {
5299                    $$.type = NewString("long");
5300                    $$.us = 0;
5301                }
5302               | TYPE_CHAR {
5303                    $$.type = NewString("char");
5304                    $$.us = 0;
5305                }
5306               | TYPE_WCHAR {
5307                    $$.type = NewString("wchar_t");
5308                    $$.us = 0;
5309                }
5310               | TYPE_FLOAT {
5311                    $$.type = NewString("float");
5312                    $$.us = 0;
5313                }
5314               | TYPE_DOUBLE {
5315                    $$.type = NewString("double");
5316                    $$.us = 0;
5317                }
5318               | TYPE_SIGNED {
5319                    $$.us = NewString("signed");
5320                    $$.type = 0;
5321                }
5322               | TYPE_UNSIGNED {
5323                    $$.us = NewString("unsigned");
5324                    $$.type = 0;
5325                }
5326               | TYPE_COMPLEX {
5327                    $$.type = NewString("complex");
5328                    $$.us = 0;
5329                }
5330               | TYPE_NON_ISO_INT8 {
5331                    $$.type = NewString("__int8");
5332                    $$.us = 0;
5333                }
5334               | TYPE_NON_ISO_INT16 {
5335                    $$.type = NewString("__int16");
5336                    $$.us = 0;
5337                }
5338               | TYPE_NON_ISO_INT32 {
5339                    $$.type = NewString("__int32");
5340                    $$.us = 0;
5341                }
5342               | TYPE_NON_ISO_INT64 {
5343                    $$.type = NewString("__int64");
5344                    $$.us = 0;
5345                }
5346               ;
5347
5348definetype     : { /* scanner_check_typedef(); */ } expr {
5349                   $$ = $2;
5350		   if ($$.type == T_STRING) {
5351		     $$.rawval = NewStringf("\"%(escape)s\"",$$.val);
5352		   } else if ($$.type != T_CHAR) {
5353		     $$.rawval = 0;
5354		   }
5355		   $$.bitfield = 0;
5356		   $$.throws = 0;
5357		   $$.throwf = 0;
5358		   scanner_ignore_typedef();
5359                }
5360/*
5361                | string {
5362                   $$.val = NewString($1);
5363		   $$.rawval = NewStringf("\"%(escape)s\"",$$.val);
5364                   $$.type = T_STRING;
5365		   $$.bitfield = 0;
5366		   $$.throws = 0;
5367		   $$.throwf = 0;
5368		}
5369*/
5370                ;
5371
5372/* Some stuff for handling enums */
5373
5374ename          :  ID { $$ = $1; }
5375               |  empty { $$ = (char *) 0;}
5376               ;
5377
5378enumlist       :  enumlist COMMA edecl {
5379
5380                  /* Ignore if there is a trailing comma in the enum list */
5381                  if ($3) {
5382                    Node *leftSibling = Getattr($1,"_last");
5383                    if (!leftSibling) {
5384                      leftSibling=$1;
5385                    }
5386                    set_nextSibling(leftSibling,$3);
5387                    Setattr($1,"_last",$3);
5388                  }
5389		  $$ = $1;
5390               }
5391               |  edecl {
5392                   $$ = $1;
5393                   if ($1) {
5394                     Setattr($1,"_last",$1);
5395                   }
5396               }
5397               ;
5398
5399edecl          :  ID {
5400		   SwigType *type = NewSwigType(T_INT);
5401		   $$ = new_node("enumitem");
5402		   Setattr($$,"name",$1);
5403		   Setattr($$,"type",type);
5404		   SetFlag($$,"feature:immutable");
5405		   Delete(type);
5406		 }
5407                 | ID EQUAL etype {
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);
5415		     Delete(type);
5416		   } else {
5417		     SwigType *type = NewSwigType(T_INT);
5418		     Setattr($$,"value",$1);
5419		     Setattr($$,"type",type);
5420		     Delete(type);
5421		   }
5422		   SetFlag($$,"feature:immutable");
5423                 }
5424                 | empty { $$ = 0; }
5425                 ;
5426
5427etype            : expr {
5428                   $$ = $1;
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");
5435		   }
5436		   if ($$.type == T_CHAR) $$.type = T_INT;
5437                }
5438               ;
5439
5440/* Arithmetic expressions.  Used for constants, C++ templates, and other cool stuff. */
5441
5442expr           : valexpr { $$ = $1; }
5443               | type {
5444		 Node *n;
5445		 $$.val = $1;
5446		 $$.type = T_INT;
5447		 /* Check if value is in scope */
5448		 n = Swig_symbol_clookup($1,0);
5449		 if (n) {
5450                   /* A band-aid for enum values used in expressions. */
5451                   if (Strcmp(nodeType(n),"enumitem") == 0) {
5452                     String *q = Swig_symbol_qualified(n);
5453                     if (q) {
5454                       $$.val = NewStringf("%s::%s", q, Getattr(n,"name"));
5455                       Delete(q);
5456                     }
5457                   }
5458		 }
5459               }
5460	       ;
5461
5462valexpr        : exprnum { $$ = $1; }
5463               | string {
5464		    $$.val = NewString($1);
5465                    $$.type = T_STRING;
5466               }
5467               | SIZEOF LPAREN type parameter_declarator RPAREN {
5468		  SwigType_push($3,$4.type);
5469		  $$.val = NewStringf("sizeof(%s)",SwigType_str($3,0));
5470		  $$.type = T_ULONG;
5471               }
5472               | exprcompound { $$ = $1; }
5473               | CHARCONST {
5474		  $$.val = NewString($1);
5475		  if (Len($$.val)) {
5476		    $$.rawval = NewStringf("'%(escape)s'", $$.val);
5477		  } else {
5478		    $$.rawval = NewString("'\\0'");
5479		  }
5480		  $$.type = T_CHAR;
5481		  $$.bitfield = 0;
5482		  $$.throws = 0;
5483		  $$.throwf = 0;
5484	       }
5485
5486/* grouping */
5487               |  LPAREN expr RPAREN %prec CAST {
5488   	            $$.val = NewStringf("(%s)",$2.val);
5489		    $$.type = $2.type;
5490   	       }
5491
5492/* A few common casting operations */
5493
5494               | LPAREN expr RPAREN expr %prec CAST {
5495                 $$ = $4;
5496		 if ($4.type != T_STRING) {
5497		   switch ($2.type) {
5498		     case T_FLOAT:
5499		     case T_DOUBLE:
5500		     case T_LONGDOUBLE:
5501		     case T_FLTCPLX:
5502		     case T_DBLCPLX:
5503		       $$.val = NewStringf("(%s)%s", $2.val, $4.val); /* SwigType_str and decimal points don't mix! */
5504		       break;
5505		     default:
5506		       $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $4.val);
5507		       break;
5508		   }
5509		 }
5510 	       }
5511               | LPAREN expr pointer RPAREN expr %prec CAST {
5512                 $$ = $5;
5513		 if ($5.type != T_STRING) {
5514		   SwigType_push($2.val,$3);
5515		   $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val);
5516		 }
5517 	       }
5518               | LPAREN expr AND RPAREN expr %prec CAST {
5519                 $$ = $5;
5520		 if ($5.type != T_STRING) {
5521		   SwigType_add_reference($2.val);
5522		   $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val);
5523		 }
5524 	       }
5525               | LPAREN expr pointer AND RPAREN expr %prec CAST {
5526                 $$ = $6;
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);
5531		 }
5532 	       }
5533               | AND expr {
5534		 $$ = $2;
5535                 $$.val = NewStringf("&%s",$2.val);
5536	       }
5537               | STAR expr {
5538		 $$ = $2;
5539                 $$.val = NewStringf("*%s",$2.val);
5540	       }
5541               ;
5542
5543exprnum        :  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; }
5550               ;
5551
5552exprcompound   : expr PLUS expr {
5553		 $$.val = NewStringf("%s+%s",$1.val,$3.val);
5554		 $$.type = promote($1.type,$3.type);
5555	       }
5556               | expr MINUS expr {
5557		 $$.val = NewStringf("%s-%s",$1.val,$3.val);
5558		 $$.type = promote($1.type,$3.type);
5559	       }
5560               | expr STAR expr {
5561		 $$.val = NewStringf("%s*%s",$1.val,$3.val);
5562		 $$.type = promote($1.type,$3.type);
5563	       }
5564               | expr SLASH expr {
5565		 $$.val = NewStringf("%s/%s",$1.val,$3.val);
5566		 $$.type = promote($1.type,$3.type);
5567	       }
5568               | expr MODULUS expr {
5569		 $$.val = NewStringf("%s%%%s",$1.val,$3.val);
5570		 $$.type = promote($1.type,$3.type);
5571	       }
5572               | expr AND expr {
5573		 $$.val = NewStringf("%s&%s",$1.val,$3.val);
5574		 $$.type = promote($1.type,$3.type);
5575	       }
5576               | expr OR expr {
5577		 $$.val = NewStringf("%s|%s",$1.val,$3.val);
5578		 $$.type = promote($1.type,$3.type);
5579	       }
5580               | expr XOR expr {
5581		 $$.val = NewStringf("%s^%s",$1.val,$3.val);
5582		 $$.type = promote($1.type,$3.type);
5583	       }
5584               | expr LSHIFT expr {
5585		 $$.val = NewStringf("%s << %s",$1.val,$3.val);
5586		 $$.type = promote_type($1.type);
5587	       }
5588               | expr RSHIFT expr {
5589		 $$.val = NewStringf("%s >> %s",$1.val,$3.val);
5590		 $$.type = promote_type($1.type);
5591	       }
5592               | expr LAND expr {
5593		 $$.val = NewStringf("%s&&%s",$1.val,$3.val);
5594		 $$.type = T_INT;
5595	       }
5596               | expr LOR expr {
5597		 $$.val = NewStringf("%s||%s",$1.val,$3.val);
5598		 $$.type = T_INT;
5599	       }
5600               | expr EQUALTO expr {
5601		 $$.val = NewStringf("%s==%s",$1.val,$3.val);
5602		 $$.type = T_INT;
5603	       }
5604               | expr NOTEQUALTO expr {
5605		 $$.val = NewStringf("%s!=%s",$1.val,$3.val);
5606		 $$.type = T_INT;
5607	       }
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);
5611		 $$.type = T_INT;
5612	       }
5613               | expr LESSTHAN expr {
5614		 $$.val = NewStringf("%s SWIG_GT %s", $1.val, $3.val);
5615		 $$.type = T_INT;
5616	       }
5617*/
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);
5623		 $$.type = T_INT;
5624	       }
5625               | expr LESSTHANOREQUALTO expr {
5626		 $$.val = NewStringf("%s SWIG_LE %s", $1.val, $3.val);
5627		 $$.type = T_INT;
5628	       }
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);
5634	       }
5635               | MINUS expr %prec UMINUS {
5636		 $$.val = NewStringf("-%s",$2.val);
5637		 $$.type = $2.type;
5638	       }
5639               | PLUS expr %prec UMINUS {
5640                 $$.val = NewStringf("+%s",$2.val);
5641		 $$.type = $2.type;
5642	       }
5643               | NOT expr {
5644		 $$.val = NewStringf("~%s",$2.val);
5645		 $$.type = $2.type;
5646	       }
5647               | LNOT expr {
5648                 $$.val = NewStringf("!%s",$2.val);
5649		 $$.type = T_INT;
5650	       }
5651               | type LPAREN {
5652		 String *qty;
5653                 skip_balanced('(',')');
5654		 qty = Swig_symbol_type_qualify($1,0);
5655		 if (SwigType_istemplate(qty)) {
5656		   String *nstr = SwigType_namestr(qty);
5657		   Delete(qty);
5658		   qty = nstr;
5659		 }
5660		 $$.val = NewStringf("%s%s",qty,scanner_ccode);
5661		 Clear(scanner_ccode);
5662		 $$.type = T_INT;
5663		 Delete(qty);
5664               }
5665               ;
5666
5667inherit        : raw_inherit {
5668		 $$ = $1;
5669               }
5670               ;
5671
5672raw_inherit     : COLON { inherit_list = 1; } base_list { $$ = $3; inherit_list = 0; }
5673                | empty { $$ = 0; }
5674                ;
5675
5676base_list      : base_specifier {
5677		   Hash *list = NewHash();
5678		   Node *base = $1;
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);
5686		   Delete(lpublic);
5687		   Delete(lprotected);
5688		   Delete(lprivate);
5689		   Append(Getattr(list,Getattr(base,"access")),name);
5690	           $$ = list;
5691               }
5692
5693               | base_list COMMA base_specifier {
5694		   Hash *list = $1;
5695		   Node *base = $3;
5696		   Node *name = Getattr(base,"name");
5697		   Append(Getattr(list,Getattr(base,"access")),name);
5698                   $$ = list;
5699               }
5700               ;
5701
5702base_specifier : opt_virtual idcolon {
5703		 $$ = NewHash();
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);
5711                 } else {
5712		   Setattr($$,"access","public");
5713		 }
5714               }
5715	       | opt_virtual access_specifier opt_virtual idcolon {
5716		 $$ = NewHash();
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);
5724		 }
5725               }
5726               ;
5727
5728access_specifier :  PUBLIC { $$ = (char*)"public"; }
5729               | PRIVATE { $$ = (char*)"private"; }
5730               | PROTECTED { $$ = (char*)"protected"; }
5731               ;
5732
5733
5734templcpptype   : CLASS {
5735                   $$ = (char*)"class";
5736		   if (!inherit_list) last_cpptype = $$;
5737               }
5738               | TYPENAME {
5739                   $$ = (char *)"typename";
5740		   if (!inherit_list) last_cpptype = $$;
5741               }
5742               ;
5743
5744cpptype        : templcpptype {
5745                 $$ = $1;
5746               }
5747               | STRUCT {
5748                   $$ = (char*)"struct";
5749		   if (!inherit_list) last_cpptype = $$;
5750               }
5751               | UNION {
5752                   $$ = (char*)"union";
5753		   if (!inherit_list) last_cpptype = $$;
5754               }
5755               ;
5756
5757opt_virtual    : VIRTUAL
5758               | empty
5759               ;
5760
5761cpp_const      : type_qualifier {
5762                    $$.qualifier = $1;
5763                    $$.throws = 0;
5764                    $$.throwf = 0;
5765               }
5766               | THROW LPAREN parms RPAREN {
5767                    $$.qualifier = 0;
5768                    $$.throws = $3;
5769                    $$.throwf = NewString("1");
5770               }
5771               | type_qualifier THROW LPAREN parms RPAREN {
5772                    $$.qualifier = $1;
5773                    $$.throws = $4;
5774                    $$.throwf = NewString("1");
5775               }
5776               | empty {
5777                    $$.qualifier = 0;
5778                    $$.throws = 0;
5779                    $$.throwf = 0;
5780               }
5781               ;
5782
5783ctor_end       : cpp_const ctor_initializer SEMI {
5784                    Clear(scanner_ccode);
5785                    $$.have_parms = 0;
5786                    $$.defarg = 0;
5787		    $$.throws = $1.throws;
5788		    $$.throwf = $1.throwf;
5789               }
5790               | cpp_const ctor_initializer LBRACE {
5791                    skip_balanced('{','}');
5792                    $$.have_parms = 0;
5793                    $$.defarg = 0;
5794                    $$.throws = $1.throws;
5795                    $$.throwf = $1.throwf;
5796               }
5797               | LPAREN parms RPAREN SEMI {
5798                    Clear(scanner_ccode);
5799                    $$.parms = $2;
5800                    $$.have_parms = 1;
5801                    $$.defarg = 0;
5802		    $$.throws = 0;
5803		    $$.throwf = 0;
5804               }
5805               | LPAREN parms RPAREN LBRACE {
5806                    skip_balanced('{','}');
5807                    $$.parms = $2;
5808                    $$.have_parms = 1;
5809                    $$.defarg = 0;
5810                    $$.throws = 0;
5811                    $$.throwf = 0;
5812               }
5813               | EQUAL definetype SEMI {
5814                    $$.have_parms = 0;
5815                    $$.defarg = $2.val;
5816                    $$.throws = 0;
5817                    $$.throwf = 0;
5818               }
5819               ;
5820
5821ctor_initializer : COLON mem_initializer_list
5822               | empty
5823               ;
5824
5825mem_initializer_list : mem_initializer
5826               | mem_initializer_list COMMA mem_initializer
5827               ;
5828
5829mem_initializer : idcolon LPAREN {
5830	            skip_balanced('(',')');
5831                    Clear(scanner_ccode);
5832            	}
5833                ;
5834
5835template_decl : LESSTHAN valparms GREATERTHAN {
5836                     String *s = NewStringEmpty();
5837                     SwigType_add_template(s,$2);
5838                     $$ = Char(s);
5839		     scanner_last_id(1);
5840                 }
5841               | empty { $$ = (char*)"";  }
5842               ;
5843
5844idstring       : ID { $$ = $1; }
5845               | string { $$ = $1; }
5846               ;
5847
5848idstringopt    : idstring { $$ = $1; }
5849               | empty { $$ = 0; }
5850               ;
5851
5852idcolon        : idtemplate idcolontail {
5853                  $$ = 0;
5854		  if (!$$) $$ = NewStringf("%s%s", $1,$2);
5855      	          Delete($2);
5856               }
5857               | NONID DCOLON idtemplate idcolontail {
5858		 $$ = NewStringf("::%s%s",$3,$4);
5859                 Delete($4);
5860               }
5861               | idtemplate {
5862		 $$ = NewString($1);
5863   	       }
5864               | NONID DCOLON idtemplate {
5865		 $$ = NewStringf("::%s",$3);
5866               }
5867               | OPERATOR {
5868                 $$ = NewString($1);
5869	       }
5870               | NONID DCOLON OPERATOR {
5871                 $$ = NewStringf("::%s",$3);
5872               }
5873               ;
5874
5875idcolontail    : DCOLON idtemplate idcolontail {
5876                   $$ = NewStringf("::%s%s",$2,$3);
5877		   Delete($3);
5878               }
5879               | DCOLON idtemplate {
5880                   $$ = NewStringf("::%s",$2);
5881               }
5882               | DCOLON OPERATOR {
5883                   $$ = NewStringf("::%s",$2);
5884               }
5885/*               | DCOLON COPERATOR {
5886                 $$ = NewString($2);
5887		 } */
5888
5889               | DCNOT idtemplate {
5890		 $$ = NewStringf("::~%s",$2);
5891               }
5892               ;
5893
5894
5895idtemplate    : ID template_decl {
5896                  $$ = NewStringf("%s%s",$1,$2);
5897		  /*		  if (Len($2)) {
5898		    scanner_last_id(1);
5899		    } */
5900              }
5901              ;
5902
5903/* Identifier, but no templates */
5904idcolonnt     : ID idcolontailnt {
5905                  $$ = 0;
5906		  if (!$$) $$ = NewStringf("%s%s", $1,$2);
5907      	          Delete($2);
5908               }
5909               | NONID DCOLON ID idcolontailnt {
5910		 $$ = NewStringf("::%s%s",$3,$4);
5911                 Delete($4);
5912               }
5913               | ID {
5914		 $$ = NewString($1);
5915   	       }
5916               | NONID DCOLON ID {
5917		 $$ = NewStringf("::%s",$3);
5918               }
5919               | OPERATOR {
5920                 $$ = NewString($1);
5921	       }
5922               | NONID DCOLON OPERATOR {
5923                 $$ = NewStringf("::%s",$3);
5924               }
5925               ;
5926
5927idcolontailnt   : DCOLON ID idcolontailnt {
5928                   $$ = NewStringf("::%s%s",$2,$3);
5929		   Delete($3);
5930               }
5931               | DCOLON ID {
5932                   $$ = NewStringf("::%s",$2);
5933               }
5934               | DCOLON OPERATOR {
5935                   $$ = NewStringf("::%s",$2);
5936               }
5937               | DCNOT ID {
5938		 $$ = NewStringf("::~%s",$2);
5939               }
5940               ;
5941
5942/* Concatenated strings */
5943string         : string STRING {
5944                   $$ = (char *) malloc(strlen($1)+strlen($2)+1);
5945                   strcpy($$,$1);
5946                   strcat($$,$2);
5947               }
5948               | STRING { $$ = $1;}
5949               ;
5950
5951stringbrace    : string {
5952		 $$ = NewString($1);
5953               }
5954               | LBRACE {
5955                  skip_balanced('{','}');
5956		  $$ = NewString(scanner_ccode);
5957               }
5958              | HBLOCK {
5959		 $$ = $1;
5960              }
5961               ;
5962
5963options        : LPAREN kwargs RPAREN {
5964                  Hash *n;
5965                  $$ = NewHash();
5966                  n = $2;
5967                  while(n) {
5968                     String *name, *value;
5969                     name = Getattr(n,"name");
5970                     value = Getattr(n,"value");
5971		     if (!value) value = (String *) "1";
5972                     Setattr($$,name, value);
5973		     n = nextSibling(n);
5974		  }
5975               }
5976               | empty { $$ = 0; };
5977
5978
5979/* Keyword arguments */
5980kwargs         : idstring EQUAL stringnum {
5981		 $$ = NewHash();
5982		 Setattr($$,"name",$1);
5983		 Setattr($$,"value",$3);
5984               }
5985               | idstring EQUAL stringnum COMMA kwargs {
5986		 $$ = NewHash();
5987		 Setattr($$,"name",$1);
5988		 Setattr($$,"value",$3);
5989		 set_nextSibling($$,$5);
5990               }
5991               | idstring {
5992                 $$ = NewHash();
5993                 Setattr($$,"name",$1);
5994	       }
5995               | idstring COMMA kwargs {
5996                 $$ = NewHash();
5997                 Setattr($$,"name",$1);
5998                 set_nextSibling($$,$3);
5999               }
6000               | idstring EQUAL stringtype  {
6001                 $$ = $3;
6002		 Setattr($$,"name",$1);
6003               }
6004               | idstring EQUAL stringtype COMMA kwargs {
6005                 $$ = $3;
6006		 Setattr($$,"name",$1);
6007		 set_nextSibling($$,$5);
6008               }
6009               ;
6010
6011stringnum      : string {
6012		 $$ = $1;
6013               }
6014               | exprnum {
6015                 $$ = Char($1.val);
6016               }
6017               ;
6018
6019empty          :   ;
6020
6021%%
6022
6023SwigType *Swig_cparse_type(String *s) {
6024   String *ns;
6025   ns = NewStringf("%s;",s);
6026   Seek(ns,0,SEEK_SET);
6027   scanner_file(ns);
6028   top = 0;
6029   scanner_next_token(PARSETYPE);
6030   yyparse();
6031   /*   Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */
6032   return top;
6033}
6034
6035
6036Parm *Swig_cparse_parm(String *s) {
6037   String *ns;
6038   ns = NewStringf("%s;",s);
6039   Seek(ns,0,SEEK_SET);
6040   scanner_file(ns);
6041   top = 0;
6042   scanner_next_token(PARSEPARM);
6043   yyparse();
6044   /*   Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */
6045   Delete(ns);
6046   return top;
6047}
6048
6049
6050ParmList *Swig_cparse_parms(String *s) {
6051   String *ns;
6052   char *cs = Char(s);
6053   if (cs && cs[0] != '(') {
6054     ns = NewStringf("(%s);",s);
6055   } else {
6056     ns = NewStringf("%s;",s);
6057   }
6058   Seek(ns,0,SEEK_SET);
6059   scanner_file(ns);
6060   top = 0;
6061   scanner_next_token(PARSEPARMS);
6062   yyparse();
6063   /*   Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */
6064   return top;
6065}
6066
6067