PageRenderTime 98ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/Source/CParse/parser.y

https://github.com/sunaku/swig-ruby-ffi
Happy | 6160 lines | 5664 code | 496 blank | 0 comment | 0 complexity | 5047041a5413e359e0c7cf3902b63bb0 MD5 | raw file
Possible License(s): 0BSD, GPL-2.0, LGPL-2.1
  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. #define yylex yylex
  13. char cvsroot_parser_y[] = "$Id$";
  14. #include "swig.h"
  15. #include "cparse.h"
  16. #include "preprocessor.h"
  17. #include <ctype.h>
  18. /* We do this for portability */
  19. #undef alloca
  20. #define alloca malloc
  21. /* -----------------------------------------------------------------------------
  22. * Externals
  23. * ----------------------------------------------------------------------------- */
  24. int yyparse();
  25. /* NEW Variables */
  26. static Node *top = 0; /* Top of the generated parse tree */
  27. static int unnamed = 0; /* Unnamed datatype counter */
  28. static Hash *extendhash = 0; /* Hash table of added methods */
  29. static Hash *classes = 0; /* Hash table of classes */
  30. static Symtab *prev_symtab = 0;
  31. static Node *current_class = 0;
  32. String *ModuleName = 0;
  33. static Node *module_node = 0;
  34. static String *Classprefix = 0;
  35. static String *Namespaceprefix = 0;
  36. static int inclass = 0;
  37. static int nested_template = 0; /* template class/function definition within a class */
  38. static char *last_cpptype = 0;
  39. static int inherit_list = 0;
  40. static Parm *template_parameters = 0;
  41. static int extendmode = 0;
  42. static int compact_default_args = 0;
  43. static int template_reduce = 0;
  44. static int cparse_externc = 0;
  45. static int max_class_levels = 0;
  46. static int class_level = 0;
  47. static Node **class_decl = NULL;
  48. /* -----------------------------------------------------------------------------
  49. * Assist Functions
  50. * ----------------------------------------------------------------------------- */
  51. /* Called by the parser (yyparse) when an error is found.*/
  52. static void yyerror (const char *e) {
  53. (void)e;
  54. }
  55. static Node *new_node(const_String_or_char_ptr tag) {
  56. Node *n = NewHash();
  57. set_nodeType(n,tag);
  58. Setfile(n,cparse_file);
  59. Setline(n,cparse_line);
  60. return n;
  61. }
  62. /* Copies a node. Does not copy tree links or symbol table data (except for
  63. sym:name) */
  64. static Node *copy_node(Node *n) {
  65. Node *nn;
  66. Iterator k;
  67. nn = NewHash();
  68. Setfile(nn,Getfile(n));
  69. Setline(nn,Getline(n));
  70. for (k = First(n); k.key; k = Next(k)) {
  71. String *ci;
  72. String *key = k.key;
  73. char *ckey = Char(key);
  74. if ((strcmp(ckey,"nextSibling") == 0) ||
  75. (strcmp(ckey,"previousSibling") == 0) ||
  76. (strcmp(ckey,"parentNode") == 0) ||
  77. (strcmp(ckey,"lastChild") == 0)) {
  78. continue;
  79. }
  80. if (Strncmp(key,"csym:",5) == 0) continue;
  81. /* We do copy sym:name. For templates */
  82. if ((strcmp(ckey,"sym:name") == 0) ||
  83. (strcmp(ckey,"sym:weak") == 0) ||
  84. (strcmp(ckey,"sym:typename") == 0)) {
  85. String *ci = Copy(k.item);
  86. Setattr(nn,key, ci);
  87. Delete(ci);
  88. continue;
  89. }
  90. if (strcmp(ckey,"sym:symtab") == 0) {
  91. Setattr(nn,"sym:needs_symtab", "1");
  92. }
  93. /* We don't copy any other symbol table attributes */
  94. if (strncmp(ckey,"sym:",4) == 0) {
  95. continue;
  96. }
  97. /* If children. We copy them recursively using this function */
  98. if (strcmp(ckey,"firstChild") == 0) {
  99. /* Copy children */
  100. Node *cn = k.item;
  101. while (cn) {
  102. Node *copy = copy_node(cn);
  103. appendChild(nn,copy);
  104. Delete(copy);
  105. cn = nextSibling(cn);
  106. }
  107. continue;
  108. }
  109. /* We don't copy the symbol table. But we drop an attribute
  110. requires_symtab so that functions know it needs to be built */
  111. if (strcmp(ckey,"symtab") == 0) {
  112. /* Node defined a symbol table. */
  113. Setattr(nn,"requires_symtab","1");
  114. continue;
  115. }
  116. /* Can't copy nodes */
  117. if (strcmp(ckey,"node") == 0) {
  118. continue;
  119. }
  120. if ((strcmp(ckey,"parms") == 0) || (strcmp(ckey,"pattern") == 0) || (strcmp(ckey,"throws") == 0)
  121. || (strcmp(ckey,"kwargs") == 0)) {
  122. ParmList *pl = CopyParmList(k.item);
  123. Setattr(nn,key,pl);
  124. Delete(pl);
  125. continue;
  126. }
  127. /* Looks okay. Just copy the data using Copy */
  128. ci = Copy(k.item);
  129. Setattr(nn, key, ci);
  130. Delete(ci);
  131. }
  132. return nn;
  133. }
  134. /* -----------------------------------------------------------------------------
  135. * Variables
  136. * ----------------------------------------------------------------------------- */
  137. static char *typemap_lang = 0; /* Current language setting */
  138. static int cplus_mode = 0;
  139. static String *class_rename = 0;
  140. /* C++ modes */
  141. #define CPLUS_PUBLIC 1
  142. #define CPLUS_PRIVATE 2
  143. #define CPLUS_PROTECTED 3
  144. /* include types */
  145. static int import_mode = 0;
  146. void SWIG_typemap_lang(const char *tm_lang) {
  147. typemap_lang = Swig_copy_string(tm_lang);
  148. }
  149. void SWIG_cparse_set_compact_default_args(int defargs) {
  150. compact_default_args = defargs;
  151. }
  152. int SWIG_cparse_template_reduce(int treduce) {
  153. template_reduce = treduce;
  154. return treduce;
  155. }
  156. /* -----------------------------------------------------------------------------
  157. * Assist functions
  158. * ----------------------------------------------------------------------------- */
  159. static int promote_type(int t) {
  160. if (t <= T_UCHAR || t == T_CHAR) return T_INT;
  161. return t;
  162. }
  163. /* Perform type-promotion for binary operators */
  164. static int promote(int t1, int t2) {
  165. t1 = promote_type(t1);
  166. t2 = promote_type(t2);
  167. return t1 > t2 ? t1 : t2;
  168. }
  169. static String *yyrename = 0;
  170. /* Forward renaming operator */
  171. static String *resolve_node_scope(String *cname);
  172. Hash *Swig_cparse_features(void) {
  173. static Hash *features_hash = 0;
  174. if (!features_hash) features_hash = NewHash();
  175. return features_hash;
  176. }
  177. static String *feature_identifier_fix(String *s) {
  178. if (SwigType_istemplate(s)) {
  179. String *tp, *ts, *ta, *tq;
  180. tp = SwigType_templateprefix(s);
  181. ts = SwigType_templatesuffix(s);
  182. ta = SwigType_templateargs(s);
  183. tq = Swig_symbol_type_qualify(ta,0);
  184. Append(tp,tq);
  185. Append(tp,ts);
  186. Delete(ts);
  187. Delete(ta);
  188. Delete(tq);
  189. return tp;
  190. } else {
  191. return NewString(s);
  192. }
  193. }
  194. /* Generate the symbol table name for an object */
  195. /* This is a bit of a mess. Need to clean up */
  196. static String *add_oldname = 0;
  197. static String *make_name(Node *n, String *name,SwigType *decl) {
  198. int destructor = name && (*(Char(name)) == '~');
  199. if (yyrename) {
  200. String *s = NewString(yyrename);
  201. Delete(yyrename);
  202. yyrename = 0;
  203. if (destructor && (*(Char(s)) != '~')) {
  204. Insert(s,0,"~");
  205. }
  206. return s;
  207. }
  208. if (!name) return 0;
  209. return Swig_name_make(n,Namespaceprefix,name,decl,add_oldname);
  210. }
  211. /* Generate an unnamed identifier */
  212. static String *make_unnamed() {
  213. unnamed++;
  214. return NewStringf("$unnamed%d$",unnamed);
  215. }
  216. /* Return if the node is a friend declaration */
  217. static int is_friend(Node *n) {
  218. return Cmp(Getattr(n,"storage"),"friend") == 0;
  219. }
  220. static int is_operator(String *name) {
  221. return Strncmp(name,"operator ", 9) == 0;
  222. }
  223. /* Add declaration list to symbol table */
  224. static int add_only_one = 0;
  225. static void add_symbols(Node *n) {
  226. String *decl;
  227. String *wrn = 0;
  228. if (nested_template) {
  229. if (!(n && Equal(nodeType(n), "template"))) {
  230. return;
  231. }
  232. /* continue if template function, but not template class, declared within a class */
  233. }
  234. if (inclass && n) {
  235. cparse_normalize_void(n);
  236. }
  237. while (n) {
  238. String *symname = 0;
  239. /* for friends, we need to pop the scope once */
  240. String *old_prefix = 0;
  241. Symtab *old_scope = 0;
  242. int isfriend = inclass && is_friend(n);
  243. int iscdecl = Cmp(nodeType(n),"cdecl") == 0;
  244. int only_csymbol = 0;
  245. if (extendmode) {
  246. Setattr(n,"isextension","1");
  247. }
  248. if (inclass) {
  249. String *name = Getattr(n, "name");
  250. if (isfriend) {
  251. /* for friends, we need to add the scopename if needed */
  252. String *prefix = name ? Swig_scopename_prefix(name) : 0;
  253. old_prefix = Namespaceprefix;
  254. old_scope = Swig_symbol_popscope();
  255. Namespaceprefix = Swig_symbol_qualifiedscopename(0);
  256. if (!prefix) {
  257. if (name && !is_operator(name) && Namespaceprefix) {
  258. String *nname = NewStringf("%s::%s", Namespaceprefix, name);
  259. Setattr(n,"name",nname);
  260. Delete(nname);
  261. }
  262. } else {
  263. Symtab *st = Swig_symbol_getscope(prefix);
  264. String *ns = st ? Getattr(st,"name") : prefix;
  265. String *base = Swig_scopename_last(name);
  266. String *nname = NewStringf("%s::%s", ns, base);
  267. Setattr(n,"name",nname);
  268. Delete(nname);
  269. Delete(base);
  270. Delete(prefix);
  271. }
  272. Namespaceprefix = 0;
  273. } else {
  274. /* for member functions, we need to remove the redundant
  275. class scope if provided, as in
  276. struct Foo {
  277. int Foo::method(int a);
  278. };
  279. */
  280. String *prefix = name ? Swig_scopename_prefix(name) : 0;
  281. if (prefix) {
  282. if (Classprefix && (Equal(prefix,Classprefix))) {
  283. String *base = Swig_scopename_last(name);
  284. Setattr(n,"name",base);
  285. Delete(base);
  286. }
  287. Delete(prefix);
  288. }
  289. /*
  290. if (!Getattr(n,"parentNode") && class_level) set_parentNode(n,class_decl[class_level - 1]);
  291. */
  292. Setattr(n,"ismember","1");
  293. }
  294. }
  295. if (!isfriend && inclass) {
  296. if ((cplus_mode != CPLUS_PUBLIC)) {
  297. only_csymbol = 1;
  298. if (cplus_mode == CPLUS_PROTECTED) {
  299. Setattr(n,"access", "protected");
  300. only_csymbol = !Swig_need_protected(n);
  301. } else {
  302. Setattr(n,"access", "private");
  303. /* private are needed only when they are pure virtuals - why? */
  304. if ((Cmp(Getattr(n,"storage"),"virtual") == 0) && (Cmp(Getattr(n,"value"),"0") == 0)) {
  305. only_csymbol = 0;
  306. }
  307. }
  308. } else {
  309. Setattr(n,"access", "public");
  310. }
  311. }
  312. if (Getattr(n,"sym:name")) {
  313. n = nextSibling(n);
  314. continue;
  315. }
  316. decl = Getattr(n,"decl");
  317. if (!SwigType_isfunction(decl)) {
  318. String *name = Getattr(n,"name");
  319. String *makename = Getattr(n,"parser:makename");
  320. if (iscdecl) {
  321. String *storage = Getattr(n, "storage");
  322. if (Cmp(storage,"typedef") == 0) {
  323. Setattr(n,"kind","typedef");
  324. } else {
  325. SwigType *type = Getattr(n,"type");
  326. String *value = Getattr(n,"value");
  327. Setattr(n,"kind","variable");
  328. if (value && Len(value)) {
  329. Setattr(n,"hasvalue","1");
  330. }
  331. if (type) {
  332. SwigType *ty;
  333. SwigType *tmp = 0;
  334. if (decl) {
  335. ty = tmp = Copy(type);
  336. SwigType_push(ty,decl);
  337. } else {
  338. ty = type;
  339. }
  340. if (!SwigType_ismutable(ty)) {
  341. SetFlag(n,"hasconsttype");
  342. SetFlag(n,"feature:immutable");
  343. }
  344. if (tmp) Delete(tmp);
  345. }
  346. if (!type) {
  347. Printf(stderr,"notype name %s\n", name);
  348. }
  349. }
  350. }
  351. Swig_features_get(Swig_cparse_features(), Namespaceprefix, name, 0, n);
  352. if (makename) {
  353. symname = make_name(n, makename,0);
  354. Delattr(n,"parser:makename"); /* temporary information, don't leave it hanging around */
  355. } else {
  356. makename = name;
  357. symname = make_name(n, makename,0);
  358. }
  359. if (!symname) {
  360. symname = Copy(Getattr(n,"unnamed"));
  361. }
  362. if (symname) {
  363. wrn = Swig_name_warning(n, Namespaceprefix, symname,0);
  364. }
  365. } else {
  366. String *name = Getattr(n,"name");
  367. SwigType *fdecl = Copy(decl);
  368. SwigType *fun = SwigType_pop_function(fdecl);
  369. if (iscdecl) {
  370. Setattr(n,"kind","function");
  371. }
  372. Swig_features_get(Swig_cparse_features(),Namespaceprefix,name,fun,n);
  373. symname = make_name(n, name,fun);
  374. wrn = Swig_name_warning(n, Namespaceprefix,symname,fun);
  375. Delete(fdecl);
  376. Delete(fun);
  377. }
  378. if (!symname) {
  379. n = nextSibling(n);
  380. continue;
  381. }
  382. if (only_csymbol || GetFlag(n,"feature:ignore")) {
  383. /* Only add to C symbol table and continue */
  384. Swig_symbol_add(0, n);
  385. } else if (strncmp(Char(symname),"$ignore",7) == 0) {
  386. char *c = Char(symname)+7;
  387. SetFlag(n,"feature:ignore");
  388. if (strlen(c)) {
  389. SWIG_WARN_NODE_BEGIN(n);
  390. Swig_warning(0,Getfile(n), Getline(n), "%s\n",c+1);
  391. SWIG_WARN_NODE_END(n);
  392. }
  393. Swig_symbol_add(0, n);
  394. } else {
  395. Node *c;
  396. if ((wrn) && (Len(wrn))) {
  397. String *metaname = symname;
  398. if (!Getmeta(metaname,"already_warned")) {
  399. SWIG_WARN_NODE_BEGIN(n);
  400. Swig_warning(0,Getfile(n),Getline(n), "%s\n", wrn);
  401. SWIG_WARN_NODE_END(n);
  402. Setmeta(metaname,"already_warned","1");
  403. }
  404. }
  405. c = Swig_symbol_add(symname,n);
  406. if (c != n) {
  407. /* symbol conflict attempting to add in the new symbol */
  408. if (Getattr(n,"sym:weak")) {
  409. Setattr(n,"sym:name",symname);
  410. } else {
  411. String *e = NewStringEmpty();
  412. String *en = NewStringEmpty();
  413. String *ec = NewStringEmpty();
  414. int redefined = Swig_need_redefined_warn(n,c,inclass);
  415. if (redefined) {
  416. Printf(en,"Identifier '%s' redefined (ignored)",symname);
  417. Printf(ec,"previous definition of '%s'",symname);
  418. } else {
  419. Printf(en,"Redundant redeclaration of '%s'",symname);
  420. Printf(ec,"previous declaration of '%s'",symname);
  421. }
  422. if (Cmp(symname,Getattr(n,"name"))) {
  423. Printf(en," (Renamed from '%s')", SwigType_namestr(Getattr(n,"name")));
  424. }
  425. Printf(en,",");
  426. if (Cmp(symname,Getattr(c,"name"))) {
  427. Printf(ec," (Renamed from '%s')", SwigType_namestr(Getattr(c,"name")));
  428. }
  429. Printf(ec,".");
  430. SWIG_WARN_NODE_BEGIN(n);
  431. if (redefined) {
  432. Swig_warning(WARN_PARSE_REDEFINED,Getfile(n),Getline(n),"%s\n",en);
  433. Swig_warning(WARN_PARSE_REDEFINED,Getfile(c),Getline(c),"%s\n",ec);
  434. } else if (!is_friend(n) && !is_friend(c)) {
  435. Swig_warning(WARN_PARSE_REDUNDANT,Getfile(n),Getline(n),"%s\n",en);
  436. Swig_warning(WARN_PARSE_REDUNDANT,Getfile(c),Getline(c),"%s\n",ec);
  437. }
  438. SWIG_WARN_NODE_END(n);
  439. Printf(e,"%s:%d:%s\n%s:%d:%s\n",Getfile(n),Getline(n),en,
  440. Getfile(c),Getline(c),ec);
  441. Setattr(n,"error",e);
  442. Delete(e);
  443. Delete(en);
  444. Delete(ec);
  445. }
  446. }
  447. }
  448. /* restore the class scope if needed */
  449. if (isfriend) {
  450. Swig_symbol_setscope(old_scope);
  451. if (old_prefix) {
  452. Delete(Namespaceprefix);
  453. Namespaceprefix = old_prefix;
  454. }
  455. }
  456. Delete(symname);
  457. if (add_only_one) return;
  458. n = nextSibling(n);
  459. }
  460. }
  461. /* add symbols a parse tree node copy */
  462. static void add_symbols_copy(Node *n) {
  463. String *name;
  464. int emode = 0;
  465. while (n) {
  466. char *cnodeType = Char(nodeType(n));
  467. if (strcmp(cnodeType,"access") == 0) {
  468. String *kind = Getattr(n,"kind");
  469. if (Strcmp(kind,"public") == 0) {
  470. cplus_mode = CPLUS_PUBLIC;
  471. } else if (Strcmp(kind,"private") == 0) {
  472. cplus_mode = CPLUS_PRIVATE;
  473. } else if (Strcmp(kind,"protected") == 0) {
  474. cplus_mode = CPLUS_PROTECTED;
  475. }
  476. n = nextSibling(n);
  477. continue;
  478. }
  479. add_oldname = Getattr(n,"sym:name");
  480. if ((add_oldname) || (Getattr(n,"sym:needs_symtab"))) {
  481. int old_inclass = -1;
  482. Node *old_current_class = 0;
  483. if (add_oldname) {
  484. DohIncref(add_oldname);
  485. /* Disable this, it prevents %rename to work with templates */
  486. /* If already renamed, we used that name */
  487. /*
  488. if (Strcmp(add_oldname, Getattr(n,"name")) != 0) {
  489. Delete(yyrename);
  490. yyrename = Copy(add_oldname);
  491. }
  492. */
  493. }
  494. Delattr(n,"sym:needs_symtab");
  495. Delattr(n,"sym:name");
  496. add_only_one = 1;
  497. add_symbols(n);
  498. if (Getattr(n,"partialargs")) {
  499. Swig_symbol_cadd(Getattr(n,"partialargs"),n);
  500. }
  501. add_only_one = 0;
  502. name = Getattr(n,"name");
  503. if (Getattr(n,"requires_symtab")) {
  504. Swig_symbol_newscope();
  505. Swig_symbol_setscopename(name);
  506. Delete(Namespaceprefix);
  507. Namespaceprefix = Swig_symbol_qualifiedscopename(0);
  508. }
  509. if (strcmp(cnodeType,"class") == 0) {
  510. old_inclass = inclass;
  511. inclass = 1;
  512. old_current_class = current_class;
  513. current_class = n;
  514. if (Strcmp(Getattr(n,"kind"),"class") == 0) {
  515. cplus_mode = CPLUS_PRIVATE;
  516. } else {
  517. cplus_mode = CPLUS_PUBLIC;
  518. }
  519. }
  520. if (strcmp(cnodeType,"extend") == 0) {
  521. emode = cplus_mode;
  522. cplus_mode = CPLUS_PUBLIC;
  523. }
  524. add_symbols_copy(firstChild(n));
  525. if (strcmp(cnodeType,"extend") == 0) {
  526. cplus_mode = emode;
  527. }
  528. if (Getattr(n,"requires_symtab")) {
  529. Setattr(n,"symtab", Swig_symbol_popscope());
  530. Delattr(n,"requires_symtab");
  531. Delete(Namespaceprefix);
  532. Namespaceprefix = Swig_symbol_qualifiedscopename(0);
  533. }
  534. if (add_oldname) {
  535. Delete(add_oldname);
  536. add_oldname = 0;
  537. }
  538. if (strcmp(cnodeType,"class") == 0) {
  539. inclass = old_inclass;
  540. current_class = old_current_class;
  541. }
  542. } else {
  543. if (strcmp(cnodeType,"extend") == 0) {
  544. emode = cplus_mode;
  545. cplus_mode = CPLUS_PUBLIC;
  546. }
  547. add_symbols_copy(firstChild(n));
  548. if (strcmp(cnodeType,"extend") == 0) {
  549. cplus_mode = emode;
  550. }
  551. }
  552. n = nextSibling(n);
  553. }
  554. }
  555. /* Extension merge. This function is used to handle the %extend directive
  556. when it appears before a class definition. To handle this, the %extend
  557. actually needs to take precedence. Therefore, we will selectively nuke symbols
  558. from the current symbol table, replacing them with the added methods */
  559. static void merge_extensions(Node *cls, Node *am) {
  560. Node *n;
  561. Node *csym;
  562. n = firstChild(am);
  563. while (n) {
  564. String *symname;
  565. if (Strcmp(nodeType(n),"constructor") == 0) {
  566. symname = Getattr(n,"sym:name");
  567. if (symname) {
  568. if (Strcmp(symname,Getattr(n,"name")) == 0) {
  569. /* If the name and the sym:name of a constructor are the same,
  570. then it hasn't been renamed. However---the name of the class
  571. itself might have been renamed so we need to do a consistency
  572. check here */
  573. if (Getattr(cls,"sym:name")) {
  574. Setattr(n,"sym:name", Getattr(cls,"sym:name"));
  575. }
  576. }
  577. }
  578. }
  579. symname = Getattr(n,"sym:name");
  580. DohIncref(symname);
  581. if ((symname) && (!Getattr(n,"error"))) {
  582. /* Remove node from its symbol table */
  583. Swig_symbol_remove(n);
  584. csym = Swig_symbol_add(symname,n);
  585. if (csym != n) {
  586. /* Conflict with previous definition. Nuke previous definition */
  587. String *e = NewStringEmpty();
  588. String *en = NewStringEmpty();
  589. String *ec = NewStringEmpty();
  590. Printf(ec,"Identifier '%s' redefined by %%extend (ignored),",symname);
  591. Printf(en,"%%extend definition of '%s'.",symname);
  592. SWIG_WARN_NODE_BEGIN(n);
  593. Swig_warning(WARN_PARSE_REDEFINED,Getfile(csym),Getline(csym),"%s\n",ec);
  594. Swig_warning(WARN_PARSE_REDEFINED,Getfile(n),Getline(n),"%s\n",en);
  595. SWIG_WARN_NODE_END(n);
  596. Printf(e,"%s:%d:%s\n%s:%d:%s\n",Getfile(csym),Getline(csym),ec,
  597. Getfile(n),Getline(n),en);
  598. Setattr(csym,"error",e);
  599. Delete(e);
  600. Delete(en);
  601. Delete(ec);
  602. Swig_symbol_remove(csym); /* Remove class definition */
  603. Swig_symbol_add(symname,n); /* Insert extend definition */
  604. }
  605. }
  606. n = nextSibling(n);
  607. }
  608. }
  609. static void append_previous_extension(Node *cls, Node *am) {
  610. Node *n, *ne;
  611. Node *pe = 0;
  612. Node *ae = 0;
  613. if (!am) return;
  614. n = firstChild(am);
  615. while (n) {
  616. ne = nextSibling(n);
  617. set_nextSibling(n,0);
  618. /* typemaps and fragments need to be prepended */
  619. if (((Cmp(nodeType(n),"typemap") == 0) || (Cmp(nodeType(n),"fragment") == 0))) {
  620. if (!pe) pe = new_node("extend");
  621. appendChild(pe, n);
  622. } else {
  623. if (!ae) ae = new_node("extend");
  624. appendChild(ae, n);
  625. }
  626. n = ne;
  627. }
  628. if (pe) prependChild(cls,pe);
  629. if (ae) appendChild(cls,ae);
  630. }
  631. /* Check for unused %extend. Special case, don't report unused
  632. extensions for templates */
  633. static void check_extensions() {
  634. Iterator ki;
  635. if (!extendhash) return;
  636. for (ki = First(extendhash); ki.key; ki = Next(ki)) {
  637. if (!Strchr(ki.key,'<')) {
  638. SWIG_WARN_NODE_BEGIN(ki.item);
  639. Swig_warning(WARN_PARSE_EXTEND_UNDEF,Getfile(ki.item), Getline(ki.item), "%%extend defined for an undeclared class %s.\n", ki.key);
  640. SWIG_WARN_NODE_END(ki.item);
  641. }
  642. }
  643. }
  644. /* Check a set of declarations to see if any are pure-abstract */
  645. static List *pure_abstract(Node *n) {
  646. List *abs = 0;
  647. while (n) {
  648. if (Cmp(nodeType(n),"cdecl") == 0) {
  649. String *decl = Getattr(n,"decl");
  650. if (SwigType_isfunction(decl)) {
  651. String *init = Getattr(n,"value");
  652. if (Cmp(init,"0") == 0) {
  653. if (!abs) {
  654. abs = NewList();
  655. }
  656. Append(abs,n);
  657. Setattr(n,"abstract","1");
  658. }
  659. }
  660. } else if (Cmp(nodeType(n),"destructor") == 0) {
  661. if (Cmp(Getattr(n,"value"),"0") == 0) {
  662. if (!abs) {
  663. abs = NewList();
  664. }
  665. Append(abs,n);
  666. Setattr(n,"abstract","1");
  667. }
  668. }
  669. n = nextSibling(n);
  670. }
  671. return abs;
  672. }
  673. /* Make a classname */
  674. static String *make_class_name(String *name) {
  675. String *nname = 0;
  676. if (Namespaceprefix) {
  677. nname= NewStringf("%s::%s", Namespaceprefix, name);
  678. } else {
  679. nname = NewString(name);
  680. }
  681. if (SwigType_istemplate(nname)) {
  682. String *prefix, *args, *qargs;
  683. prefix = SwigType_templateprefix(nname);
  684. args = SwigType_templateargs(nname);
  685. qargs = Swig_symbol_type_qualify(args,0);
  686. Append(prefix,qargs);
  687. Delete(nname);
  688. Delete(args);
  689. Delete(qargs);
  690. nname = prefix;
  691. }
  692. return nname;
  693. }
  694. static List *make_inherit_list(String *clsname, List *names) {
  695. int i, ilen;
  696. String *derived;
  697. List *bases = NewList();
  698. if (Namespaceprefix) derived = NewStringf("%s::%s", Namespaceprefix,clsname);
  699. else derived = NewString(clsname);
  700. ilen = Len(names);
  701. for (i = 0; i < ilen; i++) {
  702. Node *s;
  703. String *base;
  704. String *n = Getitem(names,i);
  705. /* Try to figure out where this symbol is */
  706. s = Swig_symbol_clookup(n,0);
  707. if (s) {
  708. while (s && (Strcmp(nodeType(s),"class") != 0)) {
  709. /* Not a class. Could be a typedef though. */
  710. String *storage = Getattr(s,"storage");
  711. if (storage && (Strcmp(storage,"typedef") == 0)) {
  712. String *nn = Getattr(s,"type");
  713. s = Swig_symbol_clookup(nn,Getattr(s,"sym:symtab"));
  714. } else {
  715. break;
  716. }
  717. }
  718. if (s && ((Strcmp(nodeType(s),"class") == 0) || (Strcmp(nodeType(s),"template") == 0))) {
  719. String *q = Swig_symbol_qualified(s);
  720. Append(bases,s);
  721. if (q) {
  722. base = NewStringf("%s::%s", q, Getattr(s,"name"));
  723. Delete(q);
  724. } else {
  725. base = NewString(Getattr(s,"name"));
  726. }
  727. } else {
  728. base = NewString(n);
  729. }
  730. } else {
  731. base = NewString(n);
  732. }
  733. if (base) {
  734. Swig_name_inherit(base,derived);
  735. Delete(base);
  736. }
  737. }
  738. return bases;
  739. }
  740. /* If the class name is qualified. We need to create or lookup namespace entries */
  741. static Symtab *set_scope_to_global() {
  742. Symtab *symtab = Swig_symbol_global_scope();
  743. Swig_symbol_setscope(symtab);
  744. return symtab;
  745. }
  746. /* Remove the block braces, { and }, if the 'noblock' attribute is set.
  747. * Node *kw can be either a Hash or Parmlist. */
  748. static String *remove_block(Node *kw, const String *inputcode) {
  749. String *modified_code = 0;
  750. while (kw) {
  751. String *name = Getattr(kw,"name");
  752. if (name && (Cmp(name,"noblock") == 0)) {
  753. char *cstr = Char(inputcode);
  754. size_t len = Len(inputcode);
  755. if (len && cstr[0] == '{') {
  756. --len; ++cstr;
  757. if (len && cstr[len - 1] == '}') { --len; }
  758. /* we now remove the extra spaces */
  759. while (len && isspace((int)cstr[0])) { --len; ++cstr; }
  760. while (len && isspace((int)cstr[len - 1])) { --len; }
  761. modified_code = NewStringWithSize(cstr, len);
  762. break;
  763. }
  764. }
  765. kw = nextSibling(kw);
  766. }
  767. return modified_code;
  768. }
  769. static Node *nscope = 0;
  770. static Node *nscope_inner = 0;
  771. /* Remove the scope prefix from cname and return the base name without the prefix.
  772. * The scopes specified in the prefix are found, or created in the current namespace.
  773. * So ultimately the scope is changed to that required for the base name.
  774. * For example AA::BB::CC as input returns CC and creates the namespace AA then inner
  775. * namespace BB in the current scope. If no scope separator (::) in the input, then nothing happens! */
  776. static String *resolve_node_scope(String *cname) {
  777. Symtab *gscope = 0;
  778. nscope = 0;
  779. nscope_inner = 0;
  780. if (Swig_scopename_check(cname)) {
  781. Node *ns;
  782. String *prefix = Swig_scopename_prefix(cname);
  783. String *base = Swig_scopename_last(cname);
  784. if (prefix && (Strncmp(prefix,"::",2) == 0)) {
  785. /* Use the global scope */
  786. String *nprefix = NewString(Char(prefix)+2);
  787. Delete(prefix);
  788. prefix= nprefix;
  789. gscope = set_scope_to_global();
  790. }
  791. if (!prefix || (Len(prefix) == 0)) {
  792. /* Use the global scope, but we need to add a 'global' namespace. */
  793. if (!gscope) gscope = set_scope_to_global();
  794. /* note that this namespace is not the "unnamed" one,
  795. and we don't use Setattr(nscope,"name", ""),
  796. because the unnamed namespace is private */
  797. nscope = new_node("namespace");
  798. Setattr(nscope,"symtab", gscope);;
  799. nscope_inner = nscope;
  800. return base;
  801. }
  802. /* Try to locate the scope */
  803. ns = Swig_symbol_clookup(prefix,0);
  804. if (!ns) {
  805. Swig_error(cparse_file,cparse_line,"Undefined scope '%s'\n", prefix);
  806. } else {
  807. Symtab *nstab = Getattr(ns,"symtab");
  808. if (!nstab) {
  809. Swig_error(cparse_file,cparse_line,
  810. "'%s' is not defined as a valid scope.\n", prefix);
  811. ns = 0;
  812. } else {
  813. /* Check if the node scope is the current scope */
  814. String *tname = Swig_symbol_qualifiedscopename(0);
  815. String *nname = Swig_symbol_qualifiedscopename(nstab);
  816. if (tname && (Strcmp(tname,nname) == 0)) {
  817. ns = 0;
  818. cname = base;
  819. }
  820. Delete(tname);
  821. Delete(nname);
  822. }
  823. if (ns) {
  824. /* we will try to create a new node using the namespaces we
  825. can find in the scope name */
  826. List *scopes;
  827. String *sname;
  828. Iterator si;
  829. String *name = NewString(prefix);
  830. scopes = NewList();
  831. while (name) {
  832. String *base = Swig_scopename_last(name);
  833. String *tprefix = Swig_scopename_prefix(name);
  834. Insert(scopes,0,base);
  835. Delete(base);
  836. Delete(name);
  837. name = tprefix;
  838. }
  839. for (si = First(scopes); si.item; si = Next(si)) {
  840. Node *ns1,*ns2;
  841. sname = si.item;
  842. ns1 = Swig_symbol_clookup(sname,0);
  843. assert(ns1);
  844. if (Strcmp(nodeType(ns1),"namespace") == 0) {
  845. if (Getattr(ns1,"alias")) {
  846. ns1 = Getattr(ns1,"namespace");
  847. }
  848. } else {
  849. /* now this last part is a class */
  850. si = Next(si);
  851. ns1 = Swig_symbol_clookup(sname,0);
  852. /* or a nested class tree, which is unrolled here */
  853. for (; si.item; si = Next(si)) {
  854. if (si.item) {
  855. Printf(sname,"::%s",si.item);
  856. }
  857. }
  858. /* we get the 'inner' class */
  859. nscope_inner = Swig_symbol_clookup(sname,0);
  860. /* set the scope to the inner class */
  861. Swig_symbol_setscope(Getattr(nscope_inner,"symtab"));
  862. /* save the last namespace prefix */
  863. Delete(Namespaceprefix);
  864. Namespaceprefix = Swig_symbol_qualifiedscopename(0);
  865. /* and return the node name, including the inner class prefix */
  866. break;
  867. }
  868. /* here we just populate the namespace tree as usual */
  869. ns2 = new_node("namespace");
  870. Setattr(ns2,"name",sname);
  871. Setattr(ns2,"symtab", Getattr(ns1,"symtab"));
  872. add_symbols(ns2);
  873. Swig_symbol_setscope(Getattr(ns1,"symtab"));
  874. Delete(Namespaceprefix);
  875. Namespaceprefix = Swig_symbol_qualifiedscopename(0);
  876. if (nscope_inner) {
  877. if (Getattr(nscope_inner,"symtab") != Getattr(ns2,"symtab")) {
  878. appendChild(nscope_inner,ns2);
  879. Delete(ns2);
  880. }
  881. }
  882. nscope_inner = ns2;
  883. if (!nscope) nscope = ns2;
  884. }
  885. cname = base;
  886. Delete(scopes);
  887. }
  888. }
  889. Delete(prefix);
  890. }
  891. return cname;
  892. }
  893. /* Structures for handling code fragments built for nested classes */
  894. typedef struct Nested {
  895. String *code; /* Associated code fragment */
  896. int line; /* line number where it starts */
  897. char *name; /* Name associated with this nested class */
  898. char *kind; /* Kind of class */
  899. int unnamed; /* unnamed class */
  900. SwigType *type; /* Datatype associated with the name */
  901. struct Nested *next; /* Next code fragment in list */
  902. } Nested;
  903. /* Some internal variables for saving nested class information */
  904. static Nested *nested_list = 0;
  905. /* Add a function to the nested list */
  906. static void add_nested(Nested *n) {
  907. Nested *n1;
  908. if (!nested_list) nested_list = n;
  909. else {
  910. n1 = nested_list;
  911. while (n1->next) n1 = n1->next;
  912. n1->next = n;
  913. }
  914. }
  915. /* Strips C-style and C++-style comments from string in-place. */
  916. static void strip_comments(char *string) {
  917. int state = 0; /*
  918. * 0 - not in comment
  919. * 1 - in c-style comment
  920. * 2 - in c++-style comment
  921. * 3 - in string
  922. * 4 - after reading / not in comments
  923. * 5 - after reading * in c-style comments
  924. * 6 - after reading \ in strings
  925. */
  926. char * c = string;
  927. while (*c) {
  928. switch (state) {
  929. case 0:
  930. if (*c == '\"')
  931. state = 3;
  932. else if (*c == '/')
  933. state = 4;
  934. break;
  935. case 1:
  936. if (*c == '*')
  937. state = 5;
  938. *c = ' ';
  939. break;
  940. case 2:
  941. if (*c == '\n')
  942. state = 0;
  943. else
  944. *c = ' ';
  945. break;
  946. case 3:
  947. if (*c == '\"')
  948. state = 0;
  949. else if (*c == '\\')
  950. state = 6;
  951. break;
  952. case 4:
  953. if (*c == '/') {
  954. *(c-1) = ' ';
  955. *c = ' ';
  956. state = 2;
  957. } else if (*c == '*') {
  958. *(c-1) = ' ';
  959. *c = ' ';
  960. state = 1;
  961. } else
  962. state = 0;
  963. break;
  964. case 5:
  965. if (*c == '/')
  966. state = 0;
  967. else
  968. state = 1;
  969. *c = ' ';
  970. break;
  971. case 6:
  972. state = 3;
  973. break;
  974. }
  975. ++c;
  976. }
  977. }
  978. /* Dump all of the nested class declarations to the inline processor
  979. * However. We need to do a few name replacements and other munging
  980. * first. This function must be called before closing a class! */
  981. static Node *dump_nested(const char *parent) {
  982. Nested *n,*n1;
  983. Node *ret = 0;
  984. n = nested_list;
  985. if (!parent) {
  986. nested_list = 0;
  987. return 0;
  988. }
  989. while (n) {
  990. Node *retx;
  991. SwigType *nt;
  992. /* Token replace the name of the parent class */
  993. Replace(n->code, "$classname", parent, DOH_REPLACE_ANY);
  994. /* Fix up the name of the datatype (for building typedefs and other stuff) */
  995. Append(n->type,parent);
  996. Append(n->type,"_");
  997. Append(n->type,n->name);
  998. /* Add the appropriate declaration to the C++ processor */
  999. retx = new_node("cdecl");
  1000. Setattr(retx,"name",n->name);
  1001. nt = Copy(n->type);
  1002. Setattr(retx,"type",nt);
  1003. Delete(nt);
  1004. Setattr(retx,"nested",parent);
  1005. if (n->unnamed) {
  1006. Setattr(retx,"unnamed","1");
  1007. }
  1008. add_symbols(retx);
  1009. if (ret) {
  1010. set_nextSibling(retx,ret);
  1011. Delete(ret);
  1012. }
  1013. ret = retx;
  1014. /* Insert a forward class declaration */
  1015. /* Disabled: [ 597599 ] union in class: incorrect scope
  1016. retx = new_node("classforward");
  1017. Setattr(retx,"kind",n->kind);
  1018. Setattr(retx,"name",Copy(n->type));
  1019. Setattr(retx,"sym:name", make_name(n->type,0));
  1020. set_nextSibling(retx,ret);
  1021. ret = retx;
  1022. */
  1023. /* Strip comments - further code may break in presence of comments. */
  1024. strip_comments(Char(n->code));
  1025. /* Make all SWIG created typedef structs/unions/classes unnamed else
  1026. redefinition errors occur - nasty hack alert.*/
  1027. {
  1028. const char* types_array[3] = {"struct", "union", "class"};
  1029. int i;
  1030. for (i=0; i<3; i++) {
  1031. char* code_ptr = Char(n->code);
  1032. while (code_ptr) {
  1033. /* Replace struct name (as in 'struct name {...}' ) with whitespace
  1034. name will be between struct and opening brace */
  1035. code_ptr = strstr(code_ptr, types_array[i]);
  1036. if (code_ptr) {
  1037. char *open_bracket_pos;
  1038. code_ptr += strlen(types_array[i]);
  1039. open_bracket_pos = strchr(code_ptr, '{');
  1040. if (open_bracket_pos) {
  1041. /* Make sure we don't have something like struct A a; */
  1042. char* semi_colon_pos = strchr(code_ptr, ';');
  1043. if (!(semi_colon_pos && (semi_colon_pos < open_bracket_pos)))
  1044. while (code_ptr < open_bracket_pos)
  1045. *code_ptr++ = ' ';
  1046. }
  1047. }
  1048. }
  1049. }
  1050. }
  1051. {
  1052. /* Remove SWIG directive %constant which may be left in the SWIG created typedefs */
  1053. char* code_ptr = Char(n->code);
  1054. while (code_ptr) {
  1055. code_ptr = strstr(code_ptr, "%constant");
  1056. if (code_ptr) {
  1057. char* directive_end_pos = strchr(code_ptr, ';');
  1058. if (directive_end_pos) {
  1059. while (code_ptr <= directive_end_pos)
  1060. *code_ptr++ = ' ';
  1061. }
  1062. }
  1063. }
  1064. }
  1065. {
  1066. Node *head = new_node("insert");
  1067. String *code = NewStringf("\n%s\n",n->code);
  1068. Setattr(head,"code", code);
  1069. Delete(code);
  1070. set_nextSibling(head,ret);
  1071. Delete(ret);
  1072. ret = head;
  1073. }
  1074. /* Dump the code to the scanner */
  1075. start_inline(Char(n->code),n->line);
  1076. n1 = n->next;
  1077. Delete(n->code);
  1078. free(n);
  1079. n = n1;
  1080. }
  1081. nested_list = 0;
  1082. return ret;
  1083. }
  1084. Node *Swig_cparse(File *f) {
  1085. scanner_file(f);
  1086. top = 0;
  1087. yyparse();
  1088. return top;
  1089. }
  1090. static void single_new_feature(const char *featurename, String *val, Hash *featureattribs, char *declaratorid, SwigType *type, ParmList *declaratorparms, String *qualifier) {
  1091. String *fname;
  1092. String *name;
  1093. String *fixname;
  1094. SwigType *t = Copy(type);
  1095. /* Printf(stdout, "single_new_feature: [%s] [%s] [%s] [%s] [%s] [%s]\n", featurename, val, declaratorid, t, ParmList_str_defaultargs(declaratorparms), qualifier); */
  1096. fname = NewStringf("feature:%s",featurename);
  1097. if (declaratorid) {
  1098. fixname = feature_identifier_fix(declaratorid);
  1099. } else {
  1100. fixname = NewStringEmpty();
  1101. }
  1102. if (Namespaceprefix) {
  1103. name = NewStringf("%s::%s",Namespaceprefix, fixname);
  1104. } else {
  1105. name = fixname;
  1106. }
  1107. if (declaratorparms) Setmeta(val,"parms",declaratorparms);
  1108. if (!Len(t)) t = 0;
  1109. if (t) {
  1110. if (qualifier) SwigType_push(t,qualifier);
  1111. if (SwigType_isfunction(t)) {
  1112. SwigType *decl = SwigType_pop_function(t);
  1113. if (SwigType_ispointer(t)) {
  1114. String *nname = NewStringf("*%s",name);
  1115. Swig_feature_set(Swig_cparse_features(), nname, decl, fname, val, featureattribs);
  1116. Delete(nname);
  1117. } else {
  1118. Swig_feature_set(Swig_cparse_features(), name, decl, fname, val, featureattribs);
  1119. }
  1120. Delete(decl);
  1121. } else if (SwigType_ispointer(t)) {
  1122. String *nname = NewStringf("*%s",name);
  1123. Swig_feature_set(Swig_cparse_features(),nname,0,fname,val, featureattribs);
  1124. Delete(nname);
  1125. }
  1126. } else {
  1127. /* Global feature, that is, feature not associated with any particular symbol */
  1128. Swig_feature_set(Swig_cparse_features(),name,0,fname,val, featureattribs);
  1129. }
  1130. Delete(fname);
  1131. Delete(name);
  1132. }
  1133. /* Add a new feature to the Hash. Additional features are added if the feature has a parameter list (declaratorparms)
  1134. * and one or more of the parameters have a default argument. An extra feature is added for each defaulted parameter,
  1135. * simulating the equivalent overloaded method. */
  1136. static void new_feature(const char *featurename, String *val, Hash *featureattribs, char *declaratorid, SwigType *type, ParmList *declaratorparms, String *qualifier) {
  1137. ParmList *declparms = declaratorparms;
  1138. /* remove the { and } braces if the noblock attribute is set */
  1139. String *newval = remove_block(featureattribs, val);
  1140. val = newval ? newval : val;
  1141. /* Add the feature */
  1142. single_new_feature(featurename, val, featureattribs, declaratorid, type, declaratorparms, qualifier);
  1143. /* Add extra features if there are default parameters in the parameter list */
  1144. if (type) {
  1145. while (declparms) {
  1146. if (ParmList_has_defaultargs(declparms)) {
  1147. /* Create a parameter list for the new feature by copying all
  1148. but the last (defaulted) parameter */
  1149. ParmList* newparms = CopyParmListMax(declparms, ParmList_len(declparms)-1);
  1150. /* Create new declaration - with the last parameter removed */
  1151. SwigType *newtype = Copy(type);
  1152. Delete(SwigType_pop_function(newtype)); /* remove the old parameter list from newtype */
  1153. SwigType_add_function(newtype,newparms);
  1154. single_new_feature(featurename, Copy(val), featureattribs, declaratorid, newtype, newparms, qualifier);
  1155. declparms = newparms;
  1156. } else {
  1157. declparms = 0;
  1158. }
  1159. }
  1160. }
  1161. }
  1162. /* check if a function declaration is a plain C object */
  1163. static int is_cfunction(Node *n) {
  1164. if (!cparse_cplusplus || cparse_externc) return 1;
  1165. if (Cmp(Getattr(n,"storage"),"externc") == 0) {
  1166. return 1;
  1167. }
  1168. return 0;
  1169. }
  1170. /* If the Node is a function with parameters, check to see if any of the parameters
  1171. * have default arguments. If so create a new function for each defaulted argument.
  1172. * The additional functions form a linked list of nodes with the head being the original Node n. */
  1173. static void default_arguments(Node *n) {
  1174. Node *function = n;
  1175. if (function) {
  1176. ParmList *varargs = Getattr(function,"feature:varargs");
  1177. if (varargs) {
  1178. /* Handles the %varargs directive by looking for "feature:varargs" and
  1179. * substituting ... with an alternative set of arguments. */
  1180. Parm *p = Getattr(function,"parms");
  1181. Parm *pp = 0;
  1182. while (p) {
  1183. SwigType *t = Getattr(p,"type");
  1184. if (Strcmp(t,"v(...)") == 0) {
  1185. if (pp) {
  1186. ParmList *cv = Copy(varargs);
  1187. set_nextSibling(pp,cv);
  1188. Delete(cv);
  1189. } else {
  1190. ParmList *cv = Copy(varargs);
  1191. Setattr(function,"parms", cv);
  1192. Delete(cv);
  1193. }
  1194. break;
  1195. }
  1196. pp = p;
  1197. p = nextSibling(p);
  1198. }
  1199. }
  1200. /* Do not add in functions if kwargs is being used or if user wants old default argument wrapping
  1201. (one wrapped method per function irrespective of number of default arguments) */
  1202. if (compact_default_args
  1203. || is_cfunction(function)
  1204. || GetFlag(function,"feature:compactdefaultargs")
  1205. || GetFlag(function,"feature:kwargs")) {
  1206. ParmList *p = Getattr(function,"parms");
  1207. if (p)
  1208. Setattr(p,"compactdefargs", "1"); /* mark parameters for special handling */
  1209. function = 0; /* don't add in extra methods */
  1210. }
  1211. }
  1212. while (function) {
  1213. ParmList *parms = Getattr(function,"parms");
  1214. if (ParmList_has_defaultargs(parms)) {
  1215. /* Create a parameter list for the new function by copying all
  1216. but the last (defaulted) parameter */
  1217. ParmList* newparms = CopyParmListMax(parms,ParmList_len(parms)-1);
  1218. /* Create new function and add to symbol table */
  1219. {
  1220. SwigType *ntype = Copy(nodeType(function));
  1221. char *cntype = Char(ntype);
  1222. Node *new_function = new_node(ntype);
  1223. SwigType *decl = Copy(Getattr(function,"decl"));
  1224. int constqualifier = SwigType_isconst(decl);
  1225. String *ccode = Copy(Getattr(function,"code"));
  1226. String *cstorage = Copy(Getattr(function,"storage"));
  1227. String *cvalue = Copy(Getattr(function,"value"));
  1228. SwigType *ctype = Copy(Getattr(function,"type"));
  1229. String *cthrow = Copy(Getattr(function,"throw"));
  1230. Delete(SwigType_pop_function(decl)); /* remove the old parameter list from decl */
  1231. SwigType_add_function(decl,newparms);
  1232. if (constqualifier)
  1233. SwigType_add_qualifier(decl,"const");
  1234. Setattr(new_function,"name", Getattr(function,"name"));
  1235. Setattr(new_function,"code", ccode);
  1236. Setattr(new_function,"decl", decl);
  1237. Setattr(new_function,"parms", newparms);
  1238. Setattr(new_function,"storage", cstorage);
  1239. Setattr(new_function,"value", cvalue);
  1240. Setattr(new_function,"type", ctype);
  1241. Setattr(new_function,"throw", cthrow);
  1242. Delete(ccode);
  1243. Delete(cstorage);
  1244. Delete(cvalue);
  1245. Delete(ctype);
  1246. Delete(cthrow);
  1247. Delete(decl);
  1248. {
  1249. Node *throws = Getattr(function,"throws");
  1250. ParmList *pl = CopyParmList(throws);
  1251. if (throws) Setattr(new_function,"throws",pl);
  1252. Delete(pl);
  1253. }
  1254. /* copy specific attributes for global (or in a namespace) template functions - these are not templated class methods */
  1255. if (strcmp(cntype,"template") == 0) {
  1256. Node *templatetype = Getattr(function,"templatetype");
  1257. Node *symtypename = Getattr(function,"sym:typename");
  1258. Parm *templateparms = Getattr(function,"templateparms");
  1259. if (templatetype) {
  1260. Node *tmp = Copy(templatetype);
  1261. Setattr(new_function,"templatetype",tmp);
  1262. Delete(tmp);
  1263. }
  1264. if (symtypename) {
  1265. Node *tmp = Copy(symtypename);
  1266. Setattr(new_function,"sym:typename",tmp);
  1267. Delete(tmp);
  1268. }
  1269. if (templateparms) {
  1270. Parm *tmp = CopyParmList(templateparms);
  1271. Setattr(new_function,"templateparms",tmp);
  1272. Delete(tmp);
  1273. }
  1274. } else if (strcmp(cntype,"constructor") == 0) {
  1275. /* only copied for constructors as this is not a user defined feature - it is hard coded in the parser */
  1276. if (GetFlag(function,"feature:new")) SetFlag(new_function,"feature:new");
  1277. }
  1278. add_symbols(new_function);
  1279. /* mark added functions as ones with overloaded parameters and point to the parsed method */
  1280. Setattr(new_function,"defaultargs", n);
  1281. /* Point to the new function, extending the linked list */
  1282. set_nextSibling(function, new_function);
  1283. Delete(new_function);
  1284. function = new_function;
  1285. Delete(ntype);
  1286. }
  1287. } else {
  1288. function = 0;
  1289. }
  1290. }
  1291. }
  1292. /* -----------------------------------------------------------------------------
  1293. * nested_forward_declaration()
  1294. *
  1295. * Treat the nested class/struct/union as a forward declaration until a proper
  1296. * nested class solution is implemented.
  1297. * ----------------------------------------------------------------------------- */
  1298. static Node *nested_forward_declaration(const char *kind, const char *name) {
  1299. Node *n = new_node("classforward");
  1300. Setfile(n,cparse_file);
  1301. Setline(n,cparse_line);
  1302. Setattr(n,"kind", kind);
  1303. Setattr(n,"name", name);
  1304. Setattr(n,"sym:weak", "1");
  1305. add_symbols(n);
  1306. if (GetFlag(n, "feature:nestedworkaround")) {
  1307. Swig_symbol_remove(n);
  1308. n = 0;
  1309. } else {
  1310. SWIG_WARN_NODE_BEGIN(n);
  1311. Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", kind, name);
  1312. SWIG_WARN_NODE_END(n);
  1313. }
  1314. return n;
  1315. }
  1316. /* -----------------------------------------------------------------------------
  1317. * tag_nodes()
  1318. *
  1319. * Used by the parser to mark subtypes with extra information.
  1320. * ----------------------------------------------------------------------------- */
  1321. static void tag_nodes(Node *n, const_String_or_char_ptr attrname, DOH *value) {
  1322. while (n) {
  1323. Setattr(n, attrname, value);
  1324. tag_nodes(firstChild(n), attrname, value);
  1325. n = nextSibling(n);
  1326. }
  1327. }
  1328. %}
  1329. %union {
  1330. char *id;
  1331. List *bases;
  1332. struct Define {
  1333. String *val;
  1334. String *rawval;
  1335. int type;
  1336. String *qualifier;
  1337. String *bitfield;
  1338. Parm *throws;
  1339. String *throwf;
  1340. } dtype;
  1341. struct {
  1342. char *type;
  1343. String *filename;
  1344. int line;
  1345. } loc;
  1346. struct {
  1347. char *id;
  1348. SwigType *type;
  1349. String *defarg;
  1350. ParmList *parms;
  1351. short have_parms;
  1352. ParmList *throws;
  1353. String *throwf;
  1354. } decl;
  1355. Parm *tparms;
  1356. struct {
  1357. String *method;
  1358. Hash *kwargs;
  1359. } tmap;
  1360. struct {
  1361. String *type;
  1362. String *us;
  1363. } ptype;
  1364. SwigType *type;
  1365. String *str;
  1366. Parm *p;
  1367. ParmList *pl;
  1368. int ivalue;
  1369. Node *node;
  1370. };
  1371. %token <id> ID
  1372. %token <str> HBLOCK
  1373. %token <id> POUND
  1374. %token <id> STRING
  1375. %token <loc> INCLUDE IMPORT INSERT
  1376. %token <str> CHARCONST
  1377. %token <dtype> NUM_INT NUM_FLOAT NUM_UNSIGNED NUM_LONG NUM_ULONG NUM_LONGLONG NUM_ULONGLONG NUM_BOOL
  1378. %token <ivalue> TYPEDEF
  1379. %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
  1380. %token LPAREN RPAREN COMMA SEMI EXTERN INIT LBRACE RBRACE PERIOD
  1381. %token CONST_QUAL VOLATILE REGISTER STRUCT UNION EQUAL SIZEOF MODULE LBRACKET RBRACKET
  1382. %token ILLEGAL CONSTANT
  1383. %token NAME RENAME NAMEWARN EXTEND PRAGMA FEATURE VARARGS
  1384. %token ENUM
  1385. %token CLASS TYPENAME PRIVATE PUBLIC PROTECTED COLON STATIC VIRTUAL FRIEND THROW CATCH EXPLICIT
  1386. %token USING
  1387. %token <node> NAMESPACE
  1388. %token NATIVE INLINE
  1389. %token TYPEMAP EXCEPT ECHO APPLY CLEAR SWIGTEMPLATE FRAGMENT
  1390. %token WARN
  1391. %token LESSTHAN GREATERTHAN MODULO DELETE_KW
  1392. %token LESSTHANOREQUALTO GREATERTHANOREQUALTO EQUALTO NOTEQUALTO
  1393. %token QUESTIONMARK
  1394. %token TYPES PARMS
  1395. %token NONID DSTAR DCNOT
  1396. %token <ivalue> TEMPLATE
  1397. %token <str> OPERATOR
  1398. %token <str> COPERATOR
  1399. %token PARSETYPE PARSEPARM PARSEPARMS
  1400. %left CAST
  1401. %left QUESTIONMARK
  1402. %left LOR
  1403. %left LAND
  1404. %left OR
  1405. %left XOR
  1406. %left AND
  1407. %left EQUALTO NOTEQUALTO
  1408. %left GREATERTHAN LESSTHAN GREATERTHANOREQUALTO LESSTHANOREQUALTO
  1409. %left LSHIFT RSHIFT
  1410. %left PLUS MINUS
  1411. %left STAR SLASH MODULUS
  1412. %left UMINUS NOT LNOT
  1413. %left DCOLON
  1414. %type <node> program interface declaration swig_directive ;
  1415. /* SWIG directives */
  1416. %type <node> extend_directive apply_directive clear_directive constant_directive ;
  1417. %type <node> echo_directive except_directive fragment_directive include_directive inline_directive ;
  1418. %type <node> insert_directive module_directive name_directive native_directive ;
  1419. %type <node> pragma_directive rename_directive feature_directive varargs_directive typemap_directive ;
  1420. %type <node> types_directive template_directive warn_directive ;
  1421. /* C declarations */
  1422. %type <node> c_declaration c_decl c_decl_tail c_enum_decl c_enum_forward_decl c_constructor_decl ;
  1423. %type <node> enumlist edecl;
  1424. /* C++ declarations */
  1425. %type <node> cpp_declaration cpp_class_decl cpp_forward_class_decl cpp_template_decl;
  1426. %type <node> cpp_members cpp_member;
  1427. %type <node> cpp_constructor_decl cpp_destructor_decl cpp_protection_decl cpp_conversion_operator;
  1428. %type <node> cpp_swig_directive cpp_temp_possible cpp_nested cpp_opt_declarators ;
  1429. %type <node> cpp_using_decl cpp_namespace_decl cpp_catch_decl ;
  1430. %type <node> kwargs options;
  1431. /* Misc */
  1432. %type <dtype> initializer cpp_const ;
  1433. %type <id> storage_class;
  1434. %type <pl> parms ptail rawparms varargs_parms;
  1435. %type <pl> templateparameters templateparameterstail;
  1436. %type <p> parm valparm rawvalparms valparms valptail ;
  1437. %type <p> typemap_parm tm_list tm_tail ;
  1438. %type <p> templateparameter ;
  1439. %type <id> templcpptype cpptype access_specifier;
  1440. %type <node> base_specifier
  1441. %type <type> type rawtype type_right ;
  1442. %type <bases> base_list inherit raw_inherit;
  1443. %type <dtype> definetype def_args etype;
  1444. %type <dtype> expr exprnum exprcompound valexpr;
  1445. %type <id> ename ;
  1446. %type <id> template_decl;
  1447. %type <str> type_qualifier ;
  1448. %type <id> type_qualifier_raw;
  1449. %type <id> idstring idstringopt;
  1450. %type <id> pragma_lang;
  1451. %type <str> pragma_arg;
  1452. %type <loc> includetype;
  1453. %type <type> pointer primitive_type;
  1454. %type <decl> declarator direct_declarator notso_direct_declarator parameter_declarator typemap_parameter_declarator nested_decl;
  1455. %type <decl> abstract_declarator direct_abstract_declarator ctor_end;
  1456. %type <tmap> typemap_type;
  1457. %type <str> idcolon idcolontail idcolonnt idcolontailnt idtemplate stringbrace stringbracesemi;
  1458. %type <id> string stringnum ;
  1459. %type <tparms> template_parms;
  1460. %type <dtype> cpp_end cpp_vend;
  1461. %type <ivalue> rename_namewarn;
  1462. %type <ptype> type_specifier primitive_type_list ;
  1463. %type <node> fname stringtype;
  1464. %type <node> featattr;
  1465. %%
  1466. /* ======================================================================
  1467. * High-level Interface file
  1468. *
  1469. * An interface is just a sequence of declarations which may be SWIG directives
  1470. * or normal C declarations.
  1471. * ====================================================================== */
  1472. program : interface {
  1473. if (!classes) classes = NewHash();
  1474. Setattr($1,"classes",classes);
  1475. Setattr($1,"name",ModuleName);
  1476. if ((!module_node) && ModuleName) {
  1477. module_node = new_node("module");
  1478. Setattr(module_node,"name",ModuleName);
  1479. }
  1480. Setattr($1,"module",module_node);
  1481. check_extensions();
  1482. top = $1;
  1483. }
  1484. | PARSETYPE parm SEMI {
  1485. top = Copy(Getattr($2,"type"));
  1486. Delete($2);
  1487. }
  1488. | PARSETYPE error {
  1489. top = 0;
  1490. }
  1491. | PARSEPARM parm SEMI {
  1492. top = $2;
  1493. }
  1494. | PARSEPARM error {
  1495. top = 0;
  1496. }
  1497. | PARSEPARMS LPAREN parms RPAREN SEMI {
  1498. top = $3;
  1499. }
  1500. | PARSEPARMS error SEMI {
  1501. top = 0;
  1502. }
  1503. ;
  1504. interface : interface declaration {
  1505. /* add declaration to end of linked list (the declaration isn't always a single declaration, sometimes it is a linked list itself) */
  1506. appendChild($1,$2);
  1507. $$ = $1;
  1508. }
  1509. | empty {
  1510. $$ = new_node("top");
  1511. }
  1512. ;
  1513. declaration : swig_directive { $$ = $1; }
  1514. | c_declaration { $$ = $1; }
  1515. | cpp_declaration { $$ = $1; }
  1516. | SEMI { $$ = 0; }
  1517. | error {
  1518. $$ = 0;
  1519. Swig_error(cparse_file, cparse_line,"Syntax error in input(1).\n");
  1520. exit(1);
  1521. }
  1522. /* Out of class constructor/destructor declarations */
  1523. | c_constructor_decl {
  1524. if ($$) {
  1525. add_symbols($$);
  1526. }
  1527. $$ = $1;
  1528. }
  1529. /* Out of class conversion operator. For example:
  1530. inline A::operator char *() const { ... }.
  1531. This is nearly impossible to parse normally. We just let the
  1532. first part generate a syntax error and then resynchronize on the
  1533. COPERATOR token---discarding the rest of the definition. Ugh.
  1534. */
  1535. | error COPERATOR {
  1536. $$ = 0;
  1537. skip_decl();
  1538. }
  1539. ;
  1540. /* ======================================================================
  1541. * SWIG DIRECTIVES
  1542. * ====================================================================== */
  1543. swig_directive : extend_directive { $$ = $1; }
  1544. | apply_directive { $$ = $1; }
  1545. | clear_directive { $$ = $1; }
  1546. | constant_directive { $$ = $1; }
  1547. | echo_directive { $$ = $1; }
  1548. | except_directive { $$ = $1; }
  1549. | fragment_directive { $$ = $1; }
  1550. | include_directive { $$ = $1; }
  1551. | inline_directive { $$ = $1; }
  1552. | insert_directive { $$ = $1; }
  1553. | module_directive { $$ = $1; }
  1554. | name_directive { $$ = $1; }
  1555. | native_directive { $$ = $1; }
  1556. | pragma_directive { $$ = $1; }
  1557. | rename_directive { $$ = $1; }
  1558. | feature_directive { $$ = $1; }
  1559. | varargs_directive { $$ = $1; }
  1560. | typemap_directive { $$ = $1; }
  1561. | types_directive { $$ = $1; }
  1562. | template_directive { $$ = $1; }
  1563. | warn_directive { $$ = $1; }
  1564. ;
  1565. /* ------------------------------------------------------------
  1566. %extend classname { ... }
  1567. ------------------------------------------------------------ */
  1568. extend_directive : EXTEND options idcolon LBRACE {
  1569. Node *cls;
  1570. String *clsname;
  1571. cplus_mode = CPLUS_PUBLIC;
  1572. if (!classes) classes = NewHash();
  1573. if (!extendhash) extendhash = NewHash();
  1574. clsname = make_class_name($3);
  1575. cls = Getattr(classes,clsname);
  1576. if (!cls) {
  1577. /* No previous definition. Create a new scope */
  1578. Node *am = Getattr(extendhash,clsname);
  1579. if (!am) {
  1580. Swig_symbol_newscope();
  1581. Swig_symbol_setscopename($3);
  1582. prev_symtab = 0;
  1583. } else {
  1584. prev_symtab = Swig_symbol_setscope(Getattr(am,"symtab"));
  1585. }
  1586. current_class = 0;
  1587. } else {
  1588. /* Previous class definition. Use its symbol table */
  1589. prev_symtab = Swig_symbol_setscope(Getattr(cls,"symtab"));
  1590. current_class = cls;
  1591. extendmode = 1;
  1592. }
  1593. Classprefix = NewString($3);
  1594. Namespaceprefix= Swig_symbol_qualifiedscopename(0);
  1595. Delete(clsname);
  1596. } cpp_members RBRACE {
  1597. String *clsname;
  1598. extendmode = 0;
  1599. $$ = new_node("extend");
  1600. Setattr($$,"symtab",Swig_symbol_popscope());
  1601. if (prev_symtab) {
  1602. Swig_symbol_setscope(prev_symtab);
  1603. }
  1604. Namespaceprefix = Swig_symbol_qualifiedscopename(0);
  1605. clsname = make_class_name($3);
  1606. Setattr($$,"name",clsname);
  1607. /* Mark members as extend */
  1608. tag_nodes($6,"feature:extend",(char*) "1");
  1609. if (current_class) {
  1610. /* We add the extension to the previously defined class */
  1611. appendChild($$,$6);
  1612. appendChild(current_class,$$);
  1613. } else {
  1614. /* We store the extensions in the extensions hash */
  1615. Node *am = Getattr(extendhash,clsname);
  1616. if (am) {
  1617. /* Append the members to the previous extend methods */
  1618. appendChild(am,$6);
  1619. } else {
  1620. appendChild($$,$6);
  1621. Setattr(extendhash,clsname,$$);
  1622. }
  1623. }
  1624. current_class = 0;
  1625. Delete(Classprefix);
  1626. Delete(clsname);
  1627. Classprefix = 0;
  1628. prev_symtab = 0;
  1629. $$ = 0;
  1630. }
  1631. ;
  1632. /* ------------------------------------------------------------
  1633. %apply
  1634. ------------------------------------------------------------ */
  1635. apply_directive : APPLY typemap_parm LBRACE tm_list RBRACE {
  1636. $$ = new_node("apply");
  1637. Setattr($$,"pattern",Getattr($2,"pattern"));
  1638. appendChild($$,$4);
  1639. };
  1640. /* ------------------------------------------------------------
  1641. %clear
  1642. ------------------------------------------------------------ */
  1643. clear_directive : CLEAR tm_list SEMI {
  1644. $$ = new_node("clear");
  1645. appendChild($$,$2);
  1646. }
  1647. ;
  1648. /* ------------------------------------------------------------
  1649. %constant name = value;
  1650. %constant type name = value;
  1651. ------------------------------------------------------------ */
  1652. constant_directive : CONSTANT ID EQUAL definetype SEMI {
  1653. if (($4.type != T_ERROR) && ($4.type != T_SYMBOL)) {
  1654. SwigType *type = NewSwigType($4.type);
  1655. $$ = new_node("constant");
  1656. Setattr($$,"name",$2);
  1657. Setattr($$,"type",type);
  1658. Setattr($$,"value",$4.val);
  1659. if ($4.rawval) Setattr($$,"rawval", $4.rawval);
  1660. Setattr($$,"storage","%constant");
  1661. SetFlag($$,"feature:immutable");
  1662. add_symbols($$);
  1663. Delete(type);
  1664. } else {
  1665. if ($4.type == T_ERROR) {
  1666. Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line,"Unsupported constant value (ignored)\n");
  1667. }
  1668. $$ = 0;
  1669. }
  1670. }
  1671. | CONSTANT type declarator def_args SEMI {
  1672. if (($4.type != T_ERROR) && ($4.type != T_SYMBOL)) {
  1673. SwigType_push($2,$3.type);
  1674. /* Sneaky callback function trick */
  1675. if (SwigType_isfunction($2)) {
  1676. SwigType_add_pointer($2);
  1677. }
  1678. $$ = new_node("constant");
  1679. Setattr($$,"name",$3.id);
  1680. Setattr($$,"type",$2);
  1681. Setattr($$,"value",$4.val);
  1682. if ($4.rawval) Setattr($$,"rawval", $4.rawval);
  1683. Setattr($$,"storage","%constant");
  1684. SetFlag($$,"feature:immutable");
  1685. add_symbols($$);
  1686. } else {
  1687. if ($4.type == T_ERROR) {
  1688. Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line,"Unsupported constant value\n");
  1689. }
  1690. $$ = 0;
  1691. }
  1692. }
  1693. | CONSTANT error SEMI {
  1694. Swig_warning(WARN_PARSE_BAD_VALUE,cparse_file,cparse_line,"Bad constant value (ignored).\n");
  1695. $$ = 0;
  1696. }
  1697. ;
  1698. /* ------------------------------------------------------------
  1699. %echo "text"
  1700. %echo %{ ... %}
  1701. ------------------------------------------------------------ */
  1702. echo_directive : ECHO HBLOCK {
  1703. char temp[64];
  1704. Replace($2,"$file",cparse_file, DOH_REPLACE_ANY);
  1705. sprintf(temp,"%d", cparse_line);
  1706. Replace($2,"$line",temp,DOH_REPLACE_ANY);
  1707. Printf(stderr,"%s\n", $2);
  1708. Delete($2);
  1709. $$ = 0;
  1710. }
  1711. | ECHO string {
  1712. char temp[64];
  1713. String *s = NewString($2);
  1714. Replace(s,"$file",cparse_file, DOH_REPLACE_ANY);
  1715. sprintf(temp,"%d", cparse_line);
  1716. Replace(s,"$line",temp,DOH_REPLACE_ANY);
  1717. Printf(stderr,"%s\n", s);
  1718. Delete(s);
  1719. $$ = 0;
  1720. }
  1721. ;
  1722. /* ------------------------------------------------------------
  1723. %except(lang) { ... }
  1724. %except { ... }
  1725. %except(lang);
  1726. %except;
  1727. ------------------------------------------------------------ */
  1728. except_directive : EXCEPT LPAREN ID RPAREN LBRACE {
  1729. skip_balanced('{','}');
  1730. $$ = 0;
  1731. Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n");
  1732. }
  1733. | EXCEPT LBRACE {
  1734. skip_balanced('{','}');
  1735. $$ = 0;
  1736. Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n");
  1737. }
  1738. | EXCEPT LPAREN ID RPAREN SEMI {
  1739. $$ = 0;
  1740. Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n");
  1741. }
  1742. | EXCEPT SEMI {
  1743. $$ = 0;
  1744. Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n");
  1745. }
  1746. ;
  1747. /* fragment keyword arguments */
  1748. stringtype : string LBRACE parm RBRACE {
  1749. $$ = NewHash();
  1750. Setattr($$,"value",$1);
  1751. Setattr($$,"type",Getattr($3,"type"));
  1752. }
  1753. ;
  1754. fname : string {
  1755. $$ = NewHash();
  1756. Setattr($$,"value",$1);
  1757. }
  1758. | stringtype {
  1759. $$ = $1;
  1760. }
  1761. ;
  1762. /* ------------------------------------------------------------
  1763. %fragment(name, section) %{ ... %}
  1764. %fragment("name" {type}, "section") %{ ... %}
  1765. %fragment("name", "section", fragment="fragment1", fragment="fragment2") %{ ... %}
  1766. Also as above but using { ... }
  1767. %fragment("name");
  1768. ------------------------------------------------------------ */
  1769. fragment_directive: FRAGMENT LPAREN fname COMMA kwargs RPAREN HBLOCK {
  1770. Hash *p = $5;
  1771. $$ = new_node("fragment");
  1772. Setattr($$,"value",Getattr($3,"value"));
  1773. Setattr($$,"type",Getattr($3,"type"));
  1774. Setattr($$,"section",Getattr(p,"name"));
  1775. Setattr($$,"kwargs",nextSibling(p));
  1776. Setattr($$,"code",$7);
  1777. }
  1778. | FRAGMENT LPAREN fname COMMA kwargs RPAREN LBRACE {
  1779. Hash *p = $5;
  1780. String *code;
  1781. skip_balanced('{','}');
  1782. $$ = new_node("fragment");
  1783. Setattr($$,"value",Getattr($3,"value"));
  1784. Setattr($$,"type",Getattr($3,"type"));
  1785. Setattr($$,"section",Getattr(p,"name"));
  1786. Setattr($$,"kwargs",nextSibling(p));
  1787. Delitem(scanner_ccode,0);
  1788. Delitem(scanner_ccode,DOH_END);
  1789. code = Copy(scanner_ccode);
  1790. Setattr($$,"code",code);
  1791. Delete(code);
  1792. }
  1793. | FRAGMENT LPAREN fname RPAREN SEMI {
  1794. $$ = new_node("fragment");
  1795. Setattr($$,"value",Getattr($3,"value"));
  1796. Setattr($$,"type",Getattr($3,"type"));
  1797. Setattr($$,"emitonly","1");
  1798. }
  1799. ;
  1800. /* ------------------------------------------------------------
  1801. %includefile "filename" [option1="xyz", ...] [ declarations ]
  1802. %importfile "filename" [option1="xyz", ...] [ declarations ]
  1803. ------------------------------------------------------------ */
  1804. include_directive: includetype options string LBRACKET {
  1805. $1.filename = Copy(cparse_file);
  1806. $1.line = cparse_line;
  1807. scanner_set_location(NewString($3),1);
  1808. if ($2) {
  1809. String *maininput = Getattr($2, "maininput");
  1810. if (maininput)
  1811. scanner_set_main_input_file(NewString(maininput));
  1812. }
  1813. } interface RBRACKET {
  1814. String *mname = 0;
  1815. $$ = $6;
  1816. scanner_set_location($1.filename,$1.line);
  1817. if (strcmp($1.type,"include") == 0) set_nodeType($$,"include");
  1818. if (strcmp($1.type,"import") == 0) {
  1819. mname = $2 ? Getattr($2,"module") : 0;
  1820. set_nodeType($$,"import");
  1821. if (import_mode) --import_mode;
  1822. }
  1823. Setattr($$,"name",$3);
  1824. /* Search for the module (if any) */
  1825. {
  1826. Node *n = firstChild($$);
  1827. while (n) {
  1828. if (Strcmp(nodeType(n),"module") == 0) {
  1829. if (mname) {
  1830. Setattr(n,"name", mname);
  1831. mname = 0;
  1832. }
  1833. Setattr($$,"module",Getattr(n,"name"));
  1834. break;
  1835. }
  1836. n = nextSibling(n);
  1837. }
  1838. if (mname) {
  1839. /* There is no module node in the import
  1840. node, ie, you imported a .h file
  1841. directly. We are forced then to create
  1842. a new import node with a module node.
  1843. */
  1844. Node *nint = new_node("import");
  1845. Node *mnode = new_node("module");
  1846. Setattr(mnode,"name", mname);
  1847. appendChild(nint,mnode);
  1848. Delete(mnode);
  1849. appendChild(nint,firstChild($$));
  1850. $$ = nint;
  1851. Setattr($$,"module",mname);
  1852. }
  1853. }
  1854. Setattr($$,"options",$2);
  1855. }
  1856. ;
  1857. includetype : INCLUDE { $$.type = (char *) "include"; }
  1858. | IMPORT { $$.type = (char *) "import"; ++import_mode;}
  1859. ;
  1860. /* ------------------------------------------------------------
  1861. %inline %{ ... %}
  1862. ------------------------------------------------------------ */
  1863. inline_directive : INLINE HBLOCK {
  1864. String *cpps;
  1865. if (Namespaceprefix) {
  1866. Swig_error(cparse_file, cparse_start_line, "%%inline directive inside a namespace is disallowed.\n");
  1867. $$ = 0;
  1868. } else {
  1869. $$ = new_node("insert");
  1870. Setattr($$,"code",$2);
  1871. /* Need to run through the preprocessor */
  1872. Setline($2,cparse_start_line);
  1873. Setfile($2,cparse_file);
  1874. Seek($2,0,SEEK_SET);
  1875. cpps = Preprocessor_parse($2);
  1876. start_inline(Char(cpps), cparse_start_line);
  1877. Delete($2);
  1878. Delete(cpps);
  1879. }
  1880. }
  1881. | INLINE LBRACE {
  1882. String *cpps;
  1883. int start_line = cparse_line;
  1884. skip_balanced('{','}');
  1885. if (Namespaceprefix) {
  1886. Swig_error(cparse_file, cparse_start_line, "%%inline directive inside a namespace is disallowed.\n");
  1887. $$ = 0;
  1888. } else {
  1889. String *code;
  1890. $$ = new_node("insert");
  1891. Delitem(scanner_ccode,0);
  1892. Delitem(scanner_ccode,DOH_END);
  1893. code = Copy(scanner_ccode);
  1894. Setattr($$,"code", code);
  1895. Delete(code);
  1896. cpps=Copy(scanner_ccode);
  1897. start_inline(Char(cpps), start_line);
  1898. Delete(cpps);
  1899. }
  1900. }
  1901. ;
  1902. /* ------------------------------------------------------------
  1903. %{ ... %}
  1904. %insert(section) "filename"
  1905. %insert("section") "filename"
  1906. %insert(section) %{ ... %}
  1907. %insert("section") %{ ... %}
  1908. ------------------------------------------------------------ */
  1909. insert_directive : HBLOCK {
  1910. $$ = new_node("insert");
  1911. Setattr($$,"code",$1);
  1912. }
  1913. | INSERT LPAREN idstring RPAREN string {
  1914. String *code = NewStringEmpty();
  1915. $$ = new_node("insert");
  1916. Setattr($$,"section",$3);
  1917. Setattr($$,"code",code);
  1918. if (Swig_insert_file($5,code) < 0) {
  1919. Swig_error(cparse_file, cparse_line, "Couldn't find '%s'.\n", $5);
  1920. $$ = 0;
  1921. }
  1922. }
  1923. | INSERT LPAREN idstring RPAREN HBLOCK {
  1924. $$ = new_node("insert");
  1925. Setattr($$,"section",$3);
  1926. Setattr($$,"code",$5);
  1927. }
  1928. | INSERT LPAREN idstring RPAREN LBRACE {
  1929. String *code;
  1930. skip_balanced('{','}');
  1931. $$ = new_node("insert");
  1932. Setattr($$,"section",$3);
  1933. Delitem(scanner_ccode,0);
  1934. Delitem(scanner_ccode,DOH_END);
  1935. code = Copy(scanner_ccode);
  1936. Setattr($$,"code", code);
  1937. Delete(code);
  1938. }
  1939. ;
  1940. /* ------------------------------------------------------------
  1941. %module modname
  1942. %module "modname"
  1943. ------------------------------------------------------------ */
  1944. module_directive: MODULE options idstring {
  1945. $$ = new_node("module");
  1946. if ($2) {
  1947. Setattr($$,"options",$2);
  1948. if (Getattr($2,"directors")) {
  1949. Wrapper_director_mode_set(1);
  1950. }
  1951. if (Getattr($2,"dirprot")) {
  1952. Wrapper_director_protected_mode_set(1);
  1953. }
  1954. if (Getattr($2,"allprotected")) {
  1955. Wrapper_all_protected_mode_set(1);
  1956. }
  1957. if (Getattr($2,"templatereduce")) {
  1958. template_reduce = 1;
  1959. }
  1960. if (Getattr($2,"notemplatereduce")) {
  1961. template_reduce = 0;
  1962. }
  1963. }
  1964. if (!ModuleName) ModuleName = NewString($3);
  1965. if (!import_mode) {
  1966. /* first module included, we apply global
  1967. ModuleName, which can be modify by -module */
  1968. String *mname = Copy(ModuleName);
  1969. Setattr($$,"name",mname);
  1970. Delete(mname);
  1971. } else {
  1972. /* import mode, we just pass the idstring */
  1973. Setattr($$,"name",$3);
  1974. }
  1975. if (!module_node) module_node = $$;
  1976. }
  1977. ;
  1978. /* ------------------------------------------------------------
  1979. %name(newname) declaration
  1980. %name("newname") declaration
  1981. ------------------------------------------------------------ */
  1982. name_directive : NAME LPAREN idstring RPAREN {
  1983. Swig_warning(WARN_DEPRECATED_NAME,cparse_file,cparse_line, "%%name is deprecated. Use %%rename instead.\n");
  1984. Delete(yyrename);
  1985. yyrename = NewString($3);
  1986. $$ = 0;
  1987. }
  1988. | NAME LPAREN RPAREN {
  1989. Swig_warning(WARN_DEPRECATED_NAME,cparse_file,cparse_line, "%%name is deprecated. Use %%rename instead.\n");
  1990. $$ = 0;
  1991. Swig_error(cparse_file,cparse_line,"Missing argument to %%name directive.\n");
  1992. }
  1993. ;
  1994. /* ------------------------------------------------------------
  1995. %native(scriptname) name;
  1996. %native(scriptname) type name (parms);
  1997. ------------------------------------------------------------ */
  1998. native_directive : NATIVE LPAREN ID RPAREN storage_class ID SEMI {
  1999. $$ = new_node("native");
  2000. Setattr($$,"name",$3);
  2001. Setattr($$,"wrap:name",$6);
  2002. add_symbols($$);
  2003. }
  2004. | NATIVE LPAREN ID RPAREN storage_class type declarator SEMI {
  2005. if (!SwigType_isfunction($7.type)) {
  2006. Swig_error(cparse_file,cparse_line,"%%native declaration '%s' is not a function.\n", $7.id);
  2007. $$ = 0;
  2008. } else {
  2009. Delete(SwigType_pop_function($7.type));
  2010. /* Need check for function here */
  2011. SwigType_push($6,$7.type);
  2012. $$ = new_node("native");
  2013. Setattr($$,"name",$3);
  2014. Setattr($$,"wrap:name",$7.id);
  2015. Setattr($$,"type",$6);
  2016. Setattr($$,"parms",$7.parms);
  2017. Setattr($$,"decl",$7.type);
  2018. }
  2019. add_symbols($$);
  2020. }
  2021. ;
  2022. /* ------------------------------------------------------------
  2023. %pragma(lang) name=value
  2024. %pragma(lang) name
  2025. %pragma name = value
  2026. %pragma name
  2027. ------------------------------------------------------------ */
  2028. pragma_directive : PRAGMA pragma_lang ID EQUAL pragma_arg {
  2029. $$ = new_node("pragma");
  2030. Setattr($$,"lang",$2);
  2031. Setattr($$,"name",$3);
  2032. Setattr($$,"value",$5);
  2033. }
  2034. | PRAGMA pragma_lang ID {
  2035. $$ = new_node("pragma");
  2036. Setattr($$,"lang",$2);
  2037. Setattr($$,"name",$3);
  2038. }
  2039. ;
  2040. pragma_arg : string { $$ = NewString($1); }
  2041. | HBLOCK { $$ = $1; }
  2042. ;
  2043. pragma_lang : LPAREN ID RPAREN { $$ = $2; }
  2044. | empty { $$ = (char *) "swig"; }
  2045. ;
  2046. /* ------------------------------------------------------------
  2047. %rename identifier newname;
  2048. %rename identifier "newname";
  2049. ------------------------------------------------------------ */
  2050. rename_directive : rename_namewarn declarator idstring SEMI {
  2051. SwigType *t = $2.type;
  2052. Hash *kws = NewHash();
  2053. String *fixname;
  2054. fixname = feature_identifier_fix($2.id);
  2055. Setattr(kws,"name",$3);
  2056. if (!Len(t)) t = 0;
  2057. /* Special declarator check */
  2058. if (t) {
  2059. if (SwigType_isfunction(t)) {
  2060. SwigType *decl = SwigType_pop_function(t);
  2061. if (SwigType_ispointer(t)) {
  2062. String *nname = NewStringf("*%s",fixname);
  2063. if ($1) {
  2064. Swig_name_rename_add(Namespaceprefix, nname,decl,kws,$2.parms);
  2065. } else {
  2066. Swig_name_namewarn_add(Namespaceprefix,nname,decl,kws);
  2067. }
  2068. Delete(nname);
  2069. } else {
  2070. if ($1) {
  2071. Swig_name_rename_add(Namespaceprefix,(fixname),decl,kws,$2.parms);
  2072. } else {
  2073. Swig_name_namewarn_add(Namespaceprefix,(fixname),decl,kws);
  2074. }
  2075. }
  2076. Delete(decl);
  2077. } else if (SwigType_ispointer(t)) {
  2078. String *nname = NewStringf("*%s",fixname);
  2079. if ($1) {
  2080. Swig_name_rename_add(Namespaceprefix,(nname),0,kws,$2.parms);
  2081. } else {
  2082. Swig_name_namewarn_add(Namespaceprefix,(nname),0,kws);
  2083. }
  2084. Delete(nname);
  2085. }
  2086. } else {
  2087. if ($1) {
  2088. Swig_name_rename_add(Namespaceprefix,(fixname),0,kws,$2.parms);
  2089. } else {
  2090. Swig_name_namewarn_add(Namespaceprefix,(fixname),0,kws);
  2091. }
  2092. }
  2093. $$ = 0;
  2094. scanner_clear_rename();
  2095. }
  2096. | rename_namewarn LPAREN kwargs RPAREN declarator cpp_const SEMI {
  2097. String *fixname;
  2098. Hash *kws = $3;
  2099. SwigType *t = $5.type;
  2100. fixname = feature_identifier_fix($5.id);
  2101. if (!Len(t)) t = 0;
  2102. /* Special declarator check */
  2103. if (t) {
  2104. if ($6.qualifier) SwigType_push(t,$6.qualifier);
  2105. if (SwigType_isfunction(t)) {
  2106. SwigType *decl = SwigType_pop_function(t);
  2107. if (SwigType_ispointer(t)) {
  2108. String *nname = NewStringf("*%s",fixname);
  2109. if ($1) {
  2110. Swig_name_rename_add(Namespaceprefix, nname,decl,kws,$5.parms);
  2111. } else {
  2112. Swig_name_namewarn_add(Namespaceprefix,nname,decl,kws);
  2113. }
  2114. Delete(nname);
  2115. } else {
  2116. if ($1) {
  2117. Swig_name_rename_add(Namespaceprefix,(fixname),decl,kws,$5.parms);
  2118. } else {
  2119. Swig_name_namewarn_add(Namespaceprefix,(fixname),decl,kws);
  2120. }
  2121. }
  2122. Delete(decl);
  2123. } else if (SwigType_ispointer(t)) {
  2124. String *nname = NewStringf("*%s",fixname);
  2125. if ($1) {
  2126. Swig_name_rename_add(Namespaceprefix,(nname),0,kws,$5.parms);
  2127. } else {
  2128. Swig_name_namewarn_add(Namespaceprefix,(nname),0,kws);
  2129. }
  2130. Delete(nname);
  2131. }
  2132. } else {
  2133. if ($1) {
  2134. Swig_name_rename_add(Namespaceprefix,(fixname),0,kws,$5.parms);
  2135. } else {
  2136. Swig_name_namewarn_add(Namespaceprefix,(fixname),0,kws);
  2137. }
  2138. }
  2139. $$ = 0;
  2140. scanner_clear_rename();
  2141. }
  2142. | rename_namewarn LPAREN kwargs RPAREN string SEMI {
  2143. if ($1) {
  2144. Swig_name_rename_add(Namespaceprefix,$5,0,$3,0);
  2145. } else {
  2146. Swig_name_namewarn_add(Namespaceprefix,$5,0,$3);
  2147. }
  2148. $$ = 0;
  2149. scanner_clear_rename();
  2150. }
  2151. ;
  2152. rename_namewarn : RENAME {
  2153. $$ = 1;
  2154. }
  2155. | NAMEWARN {
  2156. $$ = 0;
  2157. };
  2158. /* ------------------------------------------------------------
  2159. Feature targeting a symbol name (non-global feature):
  2160. %feature(featurename) name "val";
  2161. %feature(featurename, val) name;
  2162. where "val" could instead be the other bracket types, that is,
  2163. { val } or %{ val %} or indeed omitted whereupon it defaults to "1".
  2164. Or, the global feature which does not target a symbol name:
  2165. %feature(featurename) "val";
  2166. %feature(featurename, val);
  2167. An empty val (empty string) clears the feature.
  2168. Any number of feature attributes can optionally be added, for example
  2169. a non-global feature with 2 attributes:
  2170. %feature(featurename, attrib1="attribval1", attrib2="attribval2") name "val";
  2171. %feature(featurename, val, attrib1="attribval1", attrib2="attribval2") name;
  2172. ------------------------------------------------------------ */
  2173. /* Non-global feature */
  2174. feature_directive : FEATURE LPAREN idstring RPAREN declarator cpp_const stringbracesemi {
  2175. String *val = $7 ? NewString($7) : NewString("1");
  2176. new_feature($3, val, 0, $5.id, $5.type, $5.parms, $6.qualifier);
  2177. $$ = 0;
  2178. scanner_clear_rename();
  2179. }
  2180. | FEATURE LPAREN idstring COMMA stringnum RPAREN declarator cpp_const SEMI {
  2181. String *val = Len($5) ? NewString($5) : 0;
  2182. new_feature($3, val, 0, $7.id, $7.type, $7.parms, $8.qualifier);
  2183. $$ = 0;
  2184. scanner_clear_rename();
  2185. }
  2186. | FEATURE LPAREN idstring featattr RPAREN declarator cpp_const stringbracesemi {
  2187. String *val = $8 ? NewString($8) : NewString("1");
  2188. new_feature($3, val, $4, $6.id, $6.type, $6.parms, $7.qualifier);
  2189. $$ = 0;
  2190. scanner_clear_rename();
  2191. }
  2192. | FEATURE LPAREN idstring COMMA stringnum featattr RPAREN declarator cpp_const SEMI {
  2193. String *val = Len($5) ? NewString($5) : 0;
  2194. new_feature($3, val, $6, $8.id, $8.type, $8.parms, $9.qualifier);
  2195. $$ = 0;
  2196. scanner_clear_rename();
  2197. }
  2198. /* Global feature */
  2199. | FEATURE LPAREN idstring RPAREN stringbracesemi {
  2200. String *val = $5 ? NewString($5) : NewString("1");
  2201. new_feature($3, val, 0, 0, 0, 0, 0);
  2202. $$ = 0;
  2203. scanner_clear_rename();
  2204. }
  2205. | FEATURE LPAREN idstring COMMA stringnum RPAREN SEMI {
  2206. String *val = Len($5) ? NewString($5) : 0;
  2207. new_feature($3, val, 0, 0, 0, 0, 0);
  2208. $$ = 0;
  2209. scanner_clear_rename();
  2210. }
  2211. | FEATURE LPAREN idstring featattr RPAREN stringbracesemi {
  2212. String *val = $6 ? NewString($6) : NewString("1");
  2213. new_feature($3, val, $4, 0, 0, 0, 0);
  2214. $$ = 0;
  2215. scanner_clear_rename();
  2216. }
  2217. | FEATURE LPAREN idstring COMMA stringnum featattr RPAREN SEMI {
  2218. String *val = Len($5) ? NewString($5) : 0;
  2219. new_feature($3, val, $6, 0, 0, 0, 0);
  2220. $$ = 0;
  2221. scanner_clear_rename();
  2222. }
  2223. ;
  2224. stringbracesemi : stringbrace { $$ = $1; }
  2225. | SEMI { $$ = 0; }
  2226. | PARMS LPAREN parms RPAREN SEMI { $$ = $3; }
  2227. ;
  2228. featattr : COMMA idstring EQUAL stringnum {
  2229. $$ = NewHash();
  2230. Setattr($$,"name",$2);
  2231. Setattr($$,"value",$4);
  2232. }
  2233. | COMMA idstring EQUAL stringnum featattr {
  2234. $$ = NewHash();
  2235. Setattr($$,"name",$2);
  2236. Setattr($$,"value",$4);
  2237. set_nextSibling($$,$5);
  2238. }
  2239. ;
  2240. /* %varargs() directive. */
  2241. varargs_directive : VARARGS LPAREN varargs_parms RPAREN declarator cpp_const SEMI {
  2242. Parm *val;
  2243. String *name;
  2244. SwigType *t;
  2245. if (Namespaceprefix) name = NewStringf("%s::%s", Namespaceprefix, $5.id);
  2246. else name = NewString($5.id);
  2247. val = $3;
  2248. if ($5.parms) {
  2249. Setmeta(val,"parms",$5.parms);
  2250. }
  2251. t = $5.type;
  2252. if (!Len(t)) t = 0;
  2253. if (t) {
  2254. if ($6.qualifier) SwigType_push(t,$6.qualifier);
  2255. if (SwigType_isfunction(t)) {
  2256. SwigType *decl = SwigType_pop_function(t);
  2257. if (SwigType_ispointer(t)) {
  2258. String *nname = NewStringf("*%s",name);
  2259. Swig_feature_set(Swig_cparse_features(), nname, decl, "feature:varargs", val, 0);
  2260. Delete(nname);
  2261. } else {
  2262. Swig_feature_set(Swig_cparse_features(), name, decl, "feature:varargs", val, 0);
  2263. }
  2264. Delete(decl);
  2265. } else if (SwigType_ispointer(t)) {
  2266. String *nname = NewStringf("*%s",name);
  2267. Swig_feature_set(Swig_cparse_features(),nname,0,"feature:varargs",val, 0);
  2268. Delete(nname);
  2269. }
  2270. } else {
  2271. Swig_feature_set(Swig_cparse_features(),name,0,"feature:varargs",val, 0);
  2272. }
  2273. Delete(name);
  2274. $$ = 0;
  2275. };
  2276. varargs_parms : parms { $$ = $1; }
  2277. | NUM_INT COMMA parm {
  2278. int i;
  2279. int n;
  2280. Parm *p;
  2281. n = atoi(Char($1.val));
  2282. if (n <= 0) {
  2283. Swig_error(cparse_file, cparse_line,"Argument count in %%varargs must be positive.\n");
  2284. $$ = 0;
  2285. } else {
  2286. $$ = Copy($3);
  2287. Setattr($$,"name","VARARGS_SENTINEL");
  2288. for (i = 0; i < n; i++) {
  2289. p = Copy($3);
  2290. set_nextSibling(p,$$);
  2291. Delete($$);
  2292. $$ = p;
  2293. }
  2294. }
  2295. }
  2296. ;
  2297. /* ------------------------------------------------------------
  2298. %typemap(method) type { ... }
  2299. %typemap(method) type "..."
  2300. %typemap(method) type; - typemap deletion
  2301. %typemap(method) type1,type2,... = type; - typemap copy
  2302. %typemap type1,type2,... = type; - typemap copy
  2303. ------------------------------------------------------------ */
  2304. typemap_directive : TYPEMAP LPAREN typemap_type RPAREN tm_list stringbrace {
  2305. $$ = 0;
  2306. if ($3.method) {
  2307. String *code = 0;
  2308. $$ = new_node("typemap");
  2309. Setattr($$,"method",$3.method);
  2310. if ($3.kwargs) {
  2311. ParmList *kw = $3.kwargs;
  2312. code = remove_block(kw, $6);
  2313. Setattr($$,"kwargs", $3.kwargs);
  2314. }
  2315. code = code ? code : NewString($6);
  2316. Setattr($$,"code", code);
  2317. Delete(code);
  2318. appendChild($$,$5);
  2319. }
  2320. }
  2321. | TYPEMAP LPAREN typemap_type RPAREN tm_list SEMI {
  2322. $$ = 0;
  2323. if ($3.method) {
  2324. $$ = new_node("typemap");
  2325. Setattr($$,"method",$3.method);
  2326. appendChild($$,$5);
  2327. }
  2328. }
  2329. | TYPEMAP LPAREN typemap_type RPAREN tm_list EQUAL typemap_parm SEMI {
  2330. $$ = 0;
  2331. if ($3.method) {
  2332. $$ = new_node("typemapcopy");
  2333. Setattr($$,"method",$3.method);
  2334. Setattr($$,"pattern", Getattr($7,"pattern"));
  2335. appendChild($$,$5);
  2336. }
  2337. }
  2338. ;
  2339. /* typemap method type (lang,method) or (method) */
  2340. typemap_type : kwargs {
  2341. Hash *p;
  2342. String *name;
  2343. p = nextSibling($1);
  2344. if (p && (!Getattr(p,"value"))) {
  2345. /* this is the deprecated two argument typemap form */
  2346. Swig_warning(WARN_DEPRECATED_TYPEMAP_LANG,cparse_file, cparse_line,
  2347. "Specifying the language name in %%typemap is deprecated - use #ifdef SWIG<LANG> instead.\n");
  2348. /* two argument typemap form */
  2349. name = Getattr($1,"name");
  2350. if (!name || (Strcmp(name,typemap_lang))) {
  2351. $$.method = 0;
  2352. $$.kwargs = 0;
  2353. } else {
  2354. $$.method = Getattr(p,"name");
  2355. $$.kwargs = nextSibling(p);
  2356. }
  2357. } else {
  2358. /* one-argument typemap-form */
  2359. $$.method = Getattr($1,"name");
  2360. $$.kwargs = p;
  2361. }
  2362. }
  2363. ;
  2364. tm_list : typemap_parm tm_tail {
  2365. $$ = $1;
  2366. set_nextSibling($$,$2);
  2367. }
  2368. ;
  2369. tm_tail : COMMA typemap_parm tm_tail {
  2370. $$ = $2;
  2371. set_nextSibling($$,$3);
  2372. }
  2373. | empty { $$ = 0;}
  2374. ;
  2375. typemap_parm : type typemap_parameter_declarator {
  2376. Parm *parm;
  2377. SwigType_push($1,$2.type);
  2378. $$ = new_node("typemapitem");
  2379. parm = NewParm($1,$2.id);
  2380. Setattr($$,"pattern",parm);
  2381. Setattr($$,"parms", $2.parms);
  2382. Delete(parm);
  2383. /* $$ = NewParm($1,$2.id);
  2384. Setattr($$,"parms",$2.parms); */
  2385. }
  2386. | LPAREN parms RPAREN {
  2387. $$ = new_node("typemapitem");
  2388. Setattr($$,"pattern",$2);
  2389. /* Setattr($$,"multitype",$2); */
  2390. }
  2391. | LPAREN parms RPAREN LPAREN parms RPAREN {
  2392. $$ = new_node("typemapitem");
  2393. Setattr($$,"pattern", $2);
  2394. /* Setattr($$,"multitype",$2); */
  2395. Setattr($$,"parms",$5);
  2396. }
  2397. ;
  2398. /* ------------------------------------------------------------
  2399. %types(parmlist);
  2400. %types(parmlist) %{ ... %}
  2401. ------------------------------------------------------------ */
  2402. types_directive : TYPES LPAREN parms RPAREN stringbracesemi {
  2403. $$ = new_node("types");
  2404. Setattr($$,"parms",$3);
  2405. if ($5)
  2406. Setattr($$,"convcode",NewString($5));
  2407. }
  2408. ;
  2409. /* ------------------------------------------------------------
  2410. %template(name) tname<args>;
  2411. ------------------------------------------------------------ */
  2412. template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN valparms GREATERTHAN SEMI {
  2413. Parm *p, *tp;
  2414. Node *n;
  2415. Node *tnode = 0;
  2416. Symtab *tscope = 0;
  2417. int specialized = 0;
  2418. $$ = 0;
  2419. tscope = Swig_symbol_current(); /* Get the current scope */
  2420. /* If the class name is qualified, we need to create or lookup namespace entries */
  2421. if (!inclass) {
  2422. $5 = resolve_node_scope($5);
  2423. }
  2424. /*
  2425. We use the new namespace entry 'nscope' only to
  2426. emit the template node. The template parameters are
  2427. resolved in the current 'tscope'.
  2428. This is closer to the C++ (typedef) behavior.
  2429. */
  2430. n = Swig_cparse_template_locate($5,$7,tscope);
  2431. /* Patch the argument types to respect namespaces */
  2432. p = $7;
  2433. while (p) {
  2434. SwigType *value = Getattr(p,"value");
  2435. if (!value) {
  2436. SwigType *ty = Getattr(p,"type");
  2437. if (ty) {
  2438. SwigType *rty = 0;
  2439. int reduce = template_reduce;
  2440. if (reduce || !SwigType_ispointer(ty)) {
  2441. rty = Swig_symbol_typedef_reduce(ty,tscope);
  2442. if (!reduce) reduce = SwigType_ispointer(rty);
  2443. }
  2444. ty = reduce ? Swig_symbol_type_qualify(rty,tscope) : Swig_symbol_type_qualify(ty,tscope);
  2445. Setattr(p,"type",ty);
  2446. Delete(ty);
  2447. Delete(rty);
  2448. }
  2449. } else {
  2450. value = Swig_symbol_type_qualify(value,tscope);
  2451. Setattr(p,"value",value);
  2452. Delete(value);
  2453. }
  2454. p = nextSibling(p);
  2455. }
  2456. /* Look for the template */
  2457. {
  2458. Node *nn = n;
  2459. Node *linklistend = 0;
  2460. while (nn) {
  2461. Node *templnode = 0;
  2462. if (Strcmp(nodeType(nn),"template") == 0) {
  2463. int nnisclass = (Strcmp(Getattr(nn,"templatetype"),"class") == 0); /* if not a templated class it is a templated function */
  2464. Parm *tparms = Getattr(nn,"templateparms");
  2465. if (!tparms) {
  2466. specialized = 1;
  2467. }
  2468. if (nnisclass && !specialized && ((ParmList_len($7) > ParmList_len(tparms)))) {
  2469. Swig_error(cparse_file, cparse_line, "Too many template parameters. Maximum of %d.\n", ParmList_len(tparms));
  2470. } else if (nnisclass && !specialized && ((ParmList_len($7) < ParmList_numrequired(tparms)))) {
  2471. Swig_error(cparse_file, cparse_line, "Not enough template parameters specified. %d required.\n", ParmList_numrequired(tparms));
  2472. } else if (!nnisclass && ((ParmList_len($7) != ParmList_len(tparms)))) {
  2473. /* must be an overloaded templated method - ignore it as it is overloaded with a different number of template parameters */
  2474. nn = Getattr(nn,"sym:nextSibling"); /* repeat for overloaded templated functions */
  2475. continue;
  2476. } else {
  2477. String *tname = Copy($5);
  2478. int def_supplied = 0;
  2479. /* Expand the template */
  2480. Node *templ = Swig_symbol_clookup($5,0);
  2481. Parm *targs = templ ? Getattr(templ,"templateparms") : 0;
  2482. ParmList *temparms;
  2483. if (specialized) temparms = CopyParmList($7);
  2484. else temparms = CopyParmList(tparms);
  2485. /* Create typedef's and arguments */
  2486. p = $7;
  2487. tp = temparms;
  2488. if (!p && ParmList_len(p) != ParmList_len(temparms)) {
  2489. /* we have no template parameters supplied in %template for a template that has default args*/
  2490. p = tp;
  2491. def_supplied = 1;
  2492. }
  2493. while (p) {
  2494. String *value = Getattr(p,"value");
  2495. if (def_supplied) {
  2496. Setattr(p,"default","1");
  2497. }
  2498. if (value) {
  2499. Setattr(tp,"value",value);
  2500. } else {
  2501. SwigType *ty = Getattr(p,"type");
  2502. if (ty) {
  2503. Setattr(tp,"type",ty);
  2504. }
  2505. Delattr(tp,"value");
  2506. }
  2507. /* fix default arg values */
  2508. if (targs) {
  2509. Parm *pi = temparms;
  2510. Parm *ti = targs;
  2511. String *tv = Getattr(tp,"value");
  2512. if (!tv) tv = Getattr(tp,"type");
  2513. while(pi != tp && ti && pi) {
  2514. String *name = Getattr(ti,"name");
  2515. String *value = Getattr(pi,"value");
  2516. if (!value) value = Getattr(pi,"type");
  2517. Replaceid(tv, name, value);
  2518. pi = nextSibling(pi);
  2519. ti = nextSibling(ti);
  2520. }
  2521. }
  2522. p = nextSibling(p);
  2523. tp = nextSibling(tp);
  2524. if (!p && tp) {
  2525. p = tp;
  2526. def_supplied = 1;
  2527. }
  2528. }
  2529. templnode = copy_node(nn);
  2530. /* We need to set the node name based on name used to instantiate */
  2531. Setattr(templnode,"name",tname);
  2532. Delete(tname);
  2533. if (!specialized) {
  2534. Delattr(templnode,"sym:typename");
  2535. } else {
  2536. Setattr(templnode,"sym:typename","1");
  2537. }
  2538. if ($3 && !inclass) {
  2539. /*
  2540. Comment this out for 1.3.28. We need to
  2541. re-enable it later but first we need to
  2542. move %ignore from using %rename to use
  2543. %feature(ignore).
  2544. String *symname = Swig_name_make(templnode,0,$3,0,0);
  2545. */
  2546. String *symname = $3;
  2547. Swig_cparse_template_expand(templnode,symname,temparms,tscope);
  2548. Setattr(templnode,"sym:name",symname);
  2549. } else {
  2550. static int cnt = 0;
  2551. String *nname = NewStringf("__dummy_%d__", cnt++);
  2552. Swig_cparse_template_expand(templnode,nname,temparms,tscope);
  2553. Setattr(templnode,"sym:name",nname);
  2554. Delete(nname);
  2555. Setattr(templnode,"feature:onlychildren", "typemap,typemapitem,typemapcopy,typedef,types,fragment");
  2556. if ($3) {
  2557. Swig_warning(WARN_PARSE_NESTED_TEMPLATE, cparse_file, cparse_line, "Named nested template instantiations not supported. Processing as if no name was given to %%template().\n");
  2558. }
  2559. }
  2560. Delattr(templnode,"templatetype");
  2561. Setattr(templnode,"template",nn);
  2562. tnode = templnode;
  2563. Setfile(templnode,cparse_file);
  2564. Setline(templnode,cparse_line);
  2565. Delete(temparms);
  2566. add_symbols_copy(templnode);
  2567. if (Strcmp(nodeType(templnode),"class") == 0) {
  2568. /* Identify pure abstract methods */
  2569. Setattr(templnode,"abstract", pure_abstract(firstChild(templnode)));
  2570. /* Set up inheritance in symbol table */
  2571. {
  2572. Symtab *csyms;
  2573. List *baselist = Getattr(templnode,"baselist");
  2574. csyms = Swig_symbol_current();
  2575. Swig_symbol_setscope(Getattr(templnode,"symtab"));
  2576. if (baselist) {
  2577. List *bases = make_inherit_list(Getattr(templnode,"name"),baselist);
  2578. if (bases) {
  2579. Iterator s;
  2580. for (s = First(bases); s.item; s = Next(s)) {
  2581. Symtab *st = Getattr(s.item,"symtab");
  2582. if (st) {
  2583. Setfile(st,Getfile(s.item));
  2584. Setline(st,Getline(s.item));
  2585. Swig_symbol_inherit(st);
  2586. }
  2587. }
  2588. Delete(bases);
  2589. }
  2590. }
  2591. Swig_symbol_setscope(csyms);
  2592. }
  2593. /* Merge in %extend methods for this class */
  2594. /* !!! This may be broken. We may have to add the
  2595. %extend methods at the beginning of the class */
  2596. if (extendhash) {
  2597. String *stmp = 0;
  2598. String *clsname;
  2599. Node *am;
  2600. if (Namespaceprefix) {
  2601. clsname = stmp = NewStringf("%s::%s", Namespaceprefix, Getattr(templnode,"name"));
  2602. } else {
  2603. clsname = Getattr(templnode,"name");
  2604. }
  2605. am = Getattr(extendhash,clsname);
  2606. if (am) {
  2607. Symtab *st = Swig_symbol_current();
  2608. Swig_symbol_setscope(Getattr(templnode,"symtab"));
  2609. /* Printf(stdout,"%s: %s %x %x\n", Getattr(templnode,"name"), clsname, Swig_symbol_current(), Getattr(templnode,"symtab")); */
  2610. merge_extensions(templnode,am);
  2611. Swig_symbol_setscope(st);
  2612. append_previous_extension(templnode,am);
  2613. Delattr(extendhash,clsname);
  2614. }
  2615. if (stmp) Delete(stmp);
  2616. }
  2617. /* Add to classes hash */
  2618. if (!classes) classes = NewHash();
  2619. {
  2620. if (Namespaceprefix) {
  2621. String *temp = NewStringf("%s::%s", Namespaceprefix, Getattr(templnode,"name"));
  2622. Setattr(classes,temp,templnode);
  2623. Delete(temp);
  2624. } else {
  2625. String *qs = Swig_symbol_qualifiedscopename(templnode);
  2626. Setattr(classes, qs,templnode);
  2627. Delete(qs);
  2628. }
  2629. }
  2630. }
  2631. }
  2632. /* all the overloaded templated functions are added into a linked list */
  2633. if (nscope_inner) {
  2634. /* non-global namespace */
  2635. if (templnode) {
  2636. appendChild(nscope_inner,templnode);
  2637. Delete(templnode);
  2638. if (nscope) $$ = nscope;
  2639. }
  2640. } else {
  2641. /* global namespace */
  2642. if (!linklistend) {
  2643. $$ = templnode;
  2644. } else {
  2645. set_nextSibling(linklistend,templnode);
  2646. Delete(templnode);
  2647. }
  2648. linklistend = templnode;
  2649. }
  2650. }
  2651. nn = Getattr(nn,"sym:nextSibling"); /* repeat for overloaded templated functions. If a templated class there will never be a sibling. */
  2652. }
  2653. }
  2654. Swig_symbol_setscope(tscope);
  2655. Delete(Namespaceprefix);
  2656. Namespaceprefix = Swig_symbol_qualifiedscopename(0);
  2657. }
  2658. ;
  2659. /* ------------------------------------------------------------
  2660. %warn "text"
  2661. %warn(no)
  2662. ------------------------------------------------------------ */
  2663. warn_directive : WARN string {
  2664. Swig_warning(0,cparse_file, cparse_line,"%s\n", $2);
  2665. $$ = 0;
  2666. }
  2667. ;
  2668. /* ======================================================================
  2669. * C Parsing
  2670. * ====================================================================== */
  2671. c_declaration : c_decl {
  2672. $$ = $1;
  2673. if ($$) {
  2674. add_symbols($$);
  2675. default_arguments($$);
  2676. }
  2677. }
  2678. | c_enum_decl { $$ = $1; }
  2679. | c_enum_forward_decl { $$ = $1; }
  2680. /* An extern C type declaration, disable cparse_cplusplus if needed. */
  2681. | EXTERN string LBRACE {
  2682. if (Strcmp($2,"C") == 0) {
  2683. cparse_externc = 1;
  2684. }
  2685. } interface RBRACE {
  2686. cparse_externc = 0;
  2687. if (Strcmp($2,"C") == 0) {
  2688. Node *n = firstChild($5);
  2689. $$ = new_node("extern");
  2690. Setattr($$,"name",$2);
  2691. appendChild($$,n);
  2692. while (n) {
  2693. SwigType *decl = Getattr(n,"decl");
  2694. if (SwigType_isfunction(decl) && Strcmp(Getattr(n, "storage"), "typedef") != 0) {
  2695. Setattr(n,"storage","externc");
  2696. }
  2697. n = nextSibling(n);
  2698. }
  2699. } else {
  2700. Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\".\n", $2);
  2701. $$ = new_node("extern");
  2702. Setattr($$,"name",$2);
  2703. appendChild($$,firstChild($5));
  2704. }
  2705. }
  2706. ;
  2707. /* ------------------------------------------------------------
  2708. A C global declaration of some kind (may be variable, function, typedef, etc.)
  2709. ------------------------------------------------------------ */
  2710. c_decl : storage_class type declarator initializer c_decl_tail {
  2711. $$ = new_node("cdecl");
  2712. if ($4.qualifier) SwigType_push($3.type,$4.qualifier);
  2713. Setattr($$,"type",$2);
  2714. Setattr($$,"storage",$1);
  2715. Setattr($$,"name",$3.id);
  2716. Setattr($$,"decl",$3.type);
  2717. Setattr($$,"parms",$3.parms);
  2718. Setattr($$,"value",$4.val);
  2719. Setattr($$,"throws",$4.throws);
  2720. Setattr($$,"throw",$4.throwf);
  2721. if (!$5) {
  2722. if (Len(scanner_ccode)) {
  2723. String *code = Copy(scanner_ccode);
  2724. Setattr($$,"code",code);
  2725. Delete(code);
  2726. }
  2727. } else {
  2728. Node *n = $5;
  2729. /* Inherit attributes */
  2730. while (n) {
  2731. String *type = Copy($2);
  2732. Setattr(n,"type",type);
  2733. Setattr(n,"storage",$1);
  2734. n = nextSibling(n);
  2735. Delete(type);
  2736. }
  2737. }
  2738. if ($4.bitfield) {
  2739. Setattr($$,"bitfield", $4.bitfield);
  2740. }
  2741. /* Look for "::" declarations (ignored) */
  2742. if (Strstr($3.id,"::")) {
  2743. /* This is a special case. If the scope name of the declaration exactly
  2744. matches that of the declaration, then we will allow it. Otherwise, delete. */
  2745. String *p = Swig_scopename_prefix($3.id);
  2746. if (p) {
  2747. if ((Namespaceprefix && Strcmp(p,Namespaceprefix) == 0) ||
  2748. (inclass && Strcmp(p,Classprefix) == 0)) {
  2749. String *lstr = Swig_scopename_last($3.id);
  2750. Setattr($$,"name",lstr);
  2751. Delete(lstr);
  2752. set_nextSibling($$,$5);
  2753. } else {
  2754. Delete($$);
  2755. $$ = $5;
  2756. }
  2757. Delete(p);
  2758. } else {
  2759. Delete($$);
  2760. $$ = $5;
  2761. }
  2762. } else {
  2763. set_nextSibling($$,$5);
  2764. }
  2765. }
  2766. ;
  2767. /* Allow lists of variables and functions to be built up */
  2768. c_decl_tail : SEMI {
  2769. $$ = 0;
  2770. Clear(scanner_ccode);
  2771. }
  2772. | COMMA declarator initializer c_decl_tail {
  2773. $$ = new_node("cdecl");
  2774. if ($3.qualifier) SwigType_push($2.type,$3.qualifier);
  2775. Setattr($$,"name",$2.id);
  2776. Setattr($$,"decl",$2.type);
  2777. Setattr($$,"parms",$2.parms);
  2778. Setattr($$,"value",$3.val);
  2779. Setattr($$,"throws",$3.throws);
  2780. Setattr($$,"throw",$3.throwf);
  2781. if ($3.bitfield) {
  2782. Setattr($$,"bitfield", $3.bitfield);
  2783. }
  2784. if (!$4) {
  2785. if (Len(scanner_ccode)) {
  2786. String *code = Copy(scanner_ccode);
  2787. Setattr($$,"code",code);
  2788. Delete(code);
  2789. }
  2790. } else {
  2791. set_nextSibling($$,$4);
  2792. }
  2793. }
  2794. | LBRACE {
  2795. skip_balanced('{','}');
  2796. $$ = 0;
  2797. }
  2798. ;
  2799. initializer : def_args {
  2800. $$ = $1;
  2801. $$.qualifier = 0;
  2802. $$.throws = 0;
  2803. $$.throwf = 0;
  2804. }
  2805. | type_qualifier def_args {
  2806. $$ = $2;
  2807. $$.qualifier = $1;
  2808. $$.throws = 0;
  2809. $$.throwf = 0;
  2810. }
  2811. | THROW LPAREN parms RPAREN def_args {
  2812. $$ = $5;
  2813. $$.qualifier = 0;
  2814. $$.throws = $3;
  2815. $$.throwf = NewString("1");
  2816. }
  2817. | type_qualifier THROW LPAREN parms RPAREN def_args {
  2818. $$ = $6;
  2819. $$.qualifier = $1;
  2820. $$.throws = $4;
  2821. $$.throwf = NewString("1");
  2822. }
  2823. ;
  2824. /* ------------------------------------------------------------
  2825. enum Name;
  2826. ------------------------------------------------------------ */
  2827. c_enum_forward_decl : storage_class ENUM ID SEMI {
  2828. SwigType *ty = 0;
  2829. $$ = new_node("enumforward");
  2830. ty = NewStringf("enum %s", $3);
  2831. Setattr($$,"name",$3);
  2832. Setattr($$,"type",ty);
  2833. Setattr($$,"sym:weak", "1");
  2834. add_symbols($$);
  2835. }
  2836. ;
  2837. /* ------------------------------------------------------------
  2838. enum { ... }
  2839. * ------------------------------------------------------------ */
  2840. c_enum_decl : storage_class ENUM ename LBRACE enumlist RBRACE SEMI {
  2841. SwigType *ty = 0;
  2842. $$ = new_node("enum");
  2843. ty = NewStringf("enum %s", $3);
  2844. Setattr($$,"name",$3);
  2845. Setattr($$,"type",ty);
  2846. appendChild($$,$5);
  2847. add_symbols($$); /* Add to tag space */
  2848. add_symbols($5); /* Add enum values to id space */
  2849. }
  2850. | storage_class ENUM ename LBRACE enumlist RBRACE declarator c_decl_tail {
  2851. Node *n;
  2852. SwigType *ty = 0;
  2853. String *unnamed = 0;
  2854. int unnamedinstance = 0;
  2855. $$ = new_node("enum");
  2856. if ($3) {
  2857. Setattr($$,"name",$3);
  2858. ty = NewStringf("enum %s", $3);
  2859. } else if ($7.id) {
  2860. unnamed = make_unnamed();
  2861. ty = NewStringf("enum %s", unnamed);
  2862. Setattr($$,"unnamed",unnamed);
  2863. /* name is not set for unnamed enum instances, e.g. enum { foo } Instance; */
  2864. if ($1 && Cmp($1,"typedef") == 0) {
  2865. Setattr($$,"name",$7.id);
  2866. } else {
  2867. unnamedinstance = 1;
  2868. }
  2869. Setattr($$,"storage",$1);
  2870. }
  2871. if ($7.id && Cmp($1,"typedef") == 0) {
  2872. Setattr($$,"tdname",$7.id);
  2873. Setattr($$,"allows_typedef","1");
  2874. }
  2875. appendChild($$,$5);
  2876. n = new_node("cdecl");
  2877. Setattr(n,"type",ty);
  2878. Setattr(n,"name",$7.id);
  2879. Setattr(n,"storage",$1);
  2880. Setattr(n,"decl",$7.type);
  2881. Setattr(n,"parms",$7.parms);
  2882. Setattr(n,"unnamed",unnamed);
  2883. if (unnamedinstance) {
  2884. SwigType *cty = NewString("enum ");
  2885. Setattr($$,"type",cty);
  2886. SetFlag($$,"unnamedinstance");
  2887. SetFlag(n,"unnamedinstance");
  2888. Delete(cty);
  2889. }
  2890. if ($8) {
  2891. Node *p = $8;
  2892. set_nextSibling(n,p);
  2893. while (p) {
  2894. SwigType *cty = Copy(ty);
  2895. Setattr(p,"type",cty);
  2896. Setattr(p,"unnamed",unnamed);
  2897. Setattr(p,"storage",$1);
  2898. Delete(cty);
  2899. p = nextSibling(p);
  2900. }
  2901. } else {
  2902. if (Len(scanner_ccode)) {
  2903. String *code = Copy(scanner_ccode);
  2904. Setattr(n,"code",code);
  2905. Delete(code);
  2906. }
  2907. }
  2908. /* Ensure that typedef enum ABC {foo} XYZ; uses XYZ for sym:name, like structs.
  2909. * Note that class_rename/yyrename are bit of a mess so used this simple approach to change the name. */
  2910. if ($7.id && $3 && Cmp($1,"typedef") == 0) {
  2911. String *name = NewString($7.id);
  2912. Setattr($$, "parser:makename", name);
  2913. Delete(name);
  2914. }
  2915. add_symbols($$); /* Add enum to tag space */
  2916. set_nextSibling($$,n);
  2917. Delete(n);
  2918. add_symbols($5); /* Add enum values to id space */
  2919. add_symbols(n);
  2920. Delete(unnamed);
  2921. }
  2922. ;
  2923. c_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end {
  2924. /* This is a sick hack. If the ctor_end has parameters,
  2925. and the parms parameter only has 1 parameter, this
  2926. could be a declaration of the form:
  2927. type (id)(parms)
  2928. Otherwise it's an error. */
  2929. int err = 0;
  2930. $$ = 0;
  2931. if ((ParmList_len($4) == 1) && (!Swig_scopename_check($2))) {
  2932. SwigType *ty = Getattr($4,"type");
  2933. String *name = Getattr($4,"name");
  2934. err = 1;
  2935. if (!name) {
  2936. $$ = new_node("cdecl");
  2937. Setattr($$,"type",$2);
  2938. Setattr($$,"storage",$1);
  2939. Setattr($$,"name",ty);
  2940. if ($6.have_parms) {
  2941. SwigType *decl = NewStringEmpty();
  2942. SwigType_add_function(decl,$6.parms);
  2943. Setattr($$,"decl",decl);
  2944. Setattr($$,"parms",$6.parms);
  2945. if (Len(scanner_ccode)) {
  2946. String *code = Copy(scanner_ccode);
  2947. Setattr($$,"code",code);
  2948. Delete(code);
  2949. }
  2950. }
  2951. if ($6.defarg) {
  2952. Setattr($$,"value",$6.defarg);
  2953. }
  2954. Setattr($$,"throws",$6.throws);
  2955. Setattr($$,"throw",$6.throwf);
  2956. err = 0;
  2957. }
  2958. }
  2959. if (err) {
  2960. Swig_error(cparse_file,cparse_line,"Syntax error in input(2).\n");
  2961. exit(1);
  2962. }
  2963. }
  2964. ;
  2965. /* ======================================================================
  2966. * C++ Support
  2967. * ====================================================================== */
  2968. cpp_declaration : cpp_class_decl { $$ = $1; }
  2969. | cpp_forward_class_decl { $$ = $1; }
  2970. | cpp_template_decl { $$ = $1; }
  2971. | cpp_using_decl { $$ = $1; }
  2972. | cpp_namespace_decl { $$ = $1; }
  2973. | cpp_catch_decl { $$ = 0; }
  2974. ;
  2975. /* A simple class/struct/union definition */
  2976. cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
  2977. if (nested_template == 0) {
  2978. List *bases = 0;
  2979. Node *scope = 0;
  2980. $<node>$ = new_node("class");
  2981. Setline($<node>$,cparse_start_line);
  2982. Setattr($<node>$,"kind",$2);
  2983. if ($4) {
  2984. Setattr($<node>$,"baselist", Getattr($4,"public"));
  2985. Setattr($<node>$,"protectedbaselist", Getattr($4,"protected"));
  2986. Setattr($<node>$,"privatebaselist", Getattr($4,"private"));
  2987. }
  2988. Setattr($<node>$,"allows_typedef","1");
  2989. /* preserve the current scope */
  2990. prev_symtab = Swig_symbol_current();
  2991. /* If the class name is qualified. We need to create or lookup namespace/scope entries */
  2992. scope = resolve_node_scope($3);
  2993. Setfile(scope,cparse_file);
  2994. Setline(scope,cparse_line);
  2995. $3 = scope;
  2996. /* support for old nested classes "pseudo" support, such as:
  2997. %rename(Ala__Ola) Ala::Ola;
  2998. class Ala::Ola {
  2999. public:
  3000. Ola() {}
  3001. };
  3002. this should disappear when a proper implementation is added.
  3003. */
  3004. if (nscope_inner && Strcmp(nodeType(nscope_inner),"namespace") != 0) {
  3005. if (Namespaceprefix) {
  3006. String *name = NewStringf("%s::%s", Namespaceprefix, $3);
  3007. $3 = name;
  3008. Namespaceprefix = 0;
  3009. nscope_inner = 0;
  3010. }
  3011. }
  3012. Setattr($<node>$,"name",$3);
  3013. Delete(class_rename);
  3014. class_rename = make_name($<node>$,$3,0);
  3015. Classprefix = NewString($3);
  3016. /* Deal with inheritance */
  3017. if ($4) {
  3018. bases = make_inherit_list($3,Getattr($4,"public"));
  3019. }
  3020. if (SwigType_istemplate($3)) {
  3021. String *fbase, *tbase, *prefix;
  3022. prefix = SwigType_templateprefix($3);
  3023. if (Namespaceprefix) {
  3024. fbase = NewStringf("%s::%s", Namespaceprefix,$3);
  3025. tbase = NewStringf("%s::%s", Namespaceprefix, prefix);
  3026. } else {
  3027. fbase = Copy($3);
  3028. tbase = Copy(prefix);
  3029. }
  3030. Swig_name_inherit(tbase,fbase);
  3031. Delete(fbase);
  3032. Delete(tbase);
  3033. Delete(prefix);
  3034. }
  3035. if (strcmp($2,"class") == 0) {
  3036. cplus_mode = CPLUS_PRIVATE;
  3037. } else {
  3038. cplus_mode = CPLUS_PUBLIC;
  3039. }
  3040. Swig_symbol_newscope();
  3041. Swig_symbol_setscopename($3);
  3042. if (bases) {
  3043. Iterator s;
  3044. for (s = First(bases); s.item; s = Next(s)) {
  3045. Symtab *st = Getattr(s.item,"symtab");
  3046. if (st) {
  3047. Setfile(st,Getfile(s.item));
  3048. Setline(st,Getline(s.item));
  3049. Swig_symbol_inherit(st);
  3050. }
  3051. }
  3052. Delete(bases);
  3053. }
  3054. Delete(Namespaceprefix);
  3055. Namespaceprefix = Swig_symbol_qualifiedscopename(0);
  3056. cparse_start_line = cparse_line;
  3057. /* If there are active template parameters, we need to make sure they are
  3058. placed in the class symbol table so we can catch shadows */
  3059. if (template_parameters) {
  3060. Parm *tp = template_parameters;
  3061. while(tp) {
  3062. String *tpname = Copy(Getattr(tp,"name"));
  3063. Node *tn = new_node("templateparm");
  3064. Setattr(tn,"name",tpname);
  3065. Swig_symbol_cadd(tpname,tn);
  3066. tp = nextSibling(tp);
  3067. Delete(tpname);
  3068. }
  3069. }
  3070. if (class_level >= max_class_levels) {
  3071. if (!max_class_levels) {
  3072. max_class_levels = 16;
  3073. } else {
  3074. max_class_levels *= 2;
  3075. }
  3076. class_decl = (Node**) realloc(class_decl, sizeof(Node*) * max_class_levels);
  3077. if (!class_decl) {
  3078. Swig_error(cparse_file, cparse_line, "realloc() failed\n");
  3079. }
  3080. }
  3081. class_decl[class_level++] = $<node>$;
  3082. inclass = 1;
  3083. }
  3084. } cpp_members RBRACE cpp_opt_declarators {
  3085. if (nested_template == 0) {
  3086. Node *p;
  3087. SwigType *ty;
  3088. Symtab *cscope = prev_symtab;
  3089. Node *am = 0;
  3090. String *scpname = 0;
  3091. $$ = class_decl[--class_level];
  3092. inclass = 0;
  3093. /* Check for pure-abstract class */
  3094. Setattr($$,"abstract", pure_abstract($7));
  3095. /* This bit of code merges in a previously defined %extend directive (if any) */
  3096. if (extendhash) {
  3097. String *clsname = Swig_symbol_qualifiedscopename(0);
  3098. am = Getattr(extendhash,clsname);
  3099. if (am) {
  3100. merge_extensions($$,am);
  3101. Delattr(extendhash,clsname);
  3102. }
  3103. Delete(clsname);
  3104. }
  3105. if (!classes) classes = NewHash();
  3106. scpname = Swig_symbol_qualifiedscopename(0);
  3107. Setattr(classes,scpname,$$);
  3108. Delete(scpname);
  3109. appendChild($$,$7);
  3110. if (am) append_previous_extension($$,am);
  3111. p = $9;
  3112. if (p) {
  3113. set_nextSibling($$,p);
  3114. }
  3115. if (cparse_cplusplus && !cparse_externc) {
  3116. ty = NewString($3);
  3117. } else {
  3118. ty = NewStringf("%s %s", $2,$3);
  3119. }
  3120. while (p) {
  3121. Setattr(p,"storage",$1);
  3122. Setattr(p,"type",ty);
  3123. p = nextSibling(p);
  3124. }
  3125. /* Dump nested classes */
  3126. {
  3127. String *name = $3;
  3128. if ($9) {
  3129. SwigType *decltype = Getattr($9,"decl");
  3130. if (Cmp($1,"typedef") == 0) {
  3131. if (!decltype || !Len(decltype)) {
  3132. String *cname;
  3133. name = Getattr($9,"name");
  3134. cname = Copy(name);
  3135. Setattr($$,"tdname",cname);
  3136. Delete(cname);
  3137. /* Use typedef name as class name */
  3138. if (class_rename && (Strcmp(class_rename,$3) == 0)) {
  3139. Delete(class_rename);
  3140. class_rename = NewString(name);
  3141. }
  3142. if (!Getattr(classes,name)) {
  3143. Setattr(classes,name,$$);
  3144. }
  3145. Setattr($$,"decl",decltype);
  3146. }
  3147. }
  3148. }
  3149. appendChild($$,dump_nested(Char(name)));
  3150. }
  3151. if (cplus_mode != CPLUS_PUBLIC) {
  3152. /* we 'open' the class at the end, to allow %template
  3153. to add new members */
  3154. Node *pa = new_node("access");
  3155. Setattr(pa,"kind","public");
  3156. cplus_mode = CPLUS_PUBLIC;
  3157. appendChild($$,pa);
  3158. Delete(pa);
  3159. }
  3160. Setattr($$,"symtab",Swig_symbol_popscope());
  3161. Classprefix = 0;
  3162. if (nscope_inner) {
  3163. /* this is tricky */
  3164. /* we add the declaration in the original namespace */
  3165. appendChild(nscope_inner,$$);
  3166. Swig_symbol_setscope(Getattr(nscope_inner,"symtab"));
  3167. Delete(Namespaceprefix);
  3168. Namespaceprefix = Swig_symbol_qualifiedscopename(0);
  3169. add_symbols($$);
  3170. if (nscope) $$ = nscope;
  3171. /* but the variable definition in the current scope */
  3172. Swig_symbol_setscope(cscope);
  3173. Delete(Namespaceprefix);
  3174. Namespaceprefix = Swig_symbol_qualifiedscopename(0);
  3175. add_symbols($9);
  3176. } else {
  3177. Delete(yyrename);
  3178. yyrename = Copy(class_rename);
  3179. Delete(Namespaceprefix);
  3180. Namespaceprefix = Swig_symbol_qualifiedscopename(0);
  3181. add_symbols($$);
  3182. add_symbols($9);
  3183. }
  3184. Swig_symbol_setscope(cscope);
  3185. Delete(Namespaceprefix);
  3186. Namespaceprefix = Swig_symbol_qualifiedscopename(0);
  3187. } else {
  3188. $$ = new_node("class");
  3189. Setattr($$,"kind",$2);
  3190. Setattr($$,"name",NewString($3));
  3191. SetFlag($$,"nestedtemplateclass");
  3192. }
  3193. }
  3194. /* An unnamed struct, possibly with a typedef */
  3195. | storage_class cpptype LBRACE {
  3196. String *unnamed;
  3197. unnamed = make_unnamed();
  3198. $<node>$ = new_node("class");
  3199. Setline($<node>$,cparse_start_line);
  3200. Setattr($<node>$,"kind",$2);
  3201. Setattr($<node>$,"storage",$1);
  3202. Setattr($<node>$,"unnamed",unnamed);
  3203. Setattr($<node>$,"allows_typedef","1");
  3204. Delete(class_rename);
  3205. class_rename = make_name($<node>$,0,0);
  3206. if (strcmp($2,"class") == 0) {
  3207. cplus_mode = CPLUS_PRIVATE;
  3208. } else {
  3209. cplus_mode = CPLUS_PUBLIC;
  3210. }
  3211. Swig_symbol_newscope();
  3212. cparse_start_line = cparse_line;
  3213. if (class_level >= max_class_levels) {
  3214. if (!max_class_levels) {
  3215. max_class_levels = 16;
  3216. } else {
  3217. max_class_levels *= 2;
  3218. }
  3219. class_decl = (Node**) realloc(class_decl, sizeof(Node*) * max_class_levels);
  3220. if (!class_decl) {
  3221. Swig_error(cparse_file, cparse_line, "realloc() failed\n");
  3222. }
  3223. }
  3224. class_decl[class_level++] = $<node>$;
  3225. inclass = 1;
  3226. Classprefix = NewStringEmpty();
  3227. Delete(Namespaceprefix);
  3228. Namespaceprefix = Swig_symbol_qualifiedscopename(0);
  3229. } cpp_members RBRACE declarator c_decl_tail {
  3230. String *unnamed;
  3231. Node *n;
  3232. Classprefix = 0;
  3233. $$ = class_decl[--class_level];
  3234. inclass = 0;
  3235. unnamed = Getattr($$,"unnamed");
  3236. /* Check for pure-abstract class */
  3237. Setattr($$,"abstract", pure_abstract($5));
  3238. n = new_node("cdecl");
  3239. Setattr(n,"name",$7.id);
  3240. Setattr(n,"unnamed",unnamed);
  3241. Setattr(n,"type",unnamed);
  3242. Setattr(n,"decl",$7.type);
  3243. Setattr(n,"parms",$7.parms);
  3244. Setattr(n,"storage",$1);
  3245. if ($8) {
  3246. Node *p = $8;
  3247. set_nextSibling(n,p);
  3248. while (p) {
  3249. String *type = Copy(unnamed);
  3250. Setattr(p,"name",$7.id);
  3251. Setattr(p,"unnamed",unnamed);
  3252. Setattr(p,"type",type);
  3253. Delete(type);
  3254. Setattr(p,"storage",$1);
  3255. p = nextSibling(p);
  3256. }
  3257. }
  3258. set_nextSibling($$,n);
  3259. Delete(n);
  3260. {
  3261. /* If a proper typedef name was given, we'll use it to set the scope name */
  3262. String *name = 0;
  3263. if ($1 && (strcmp($1,"typedef") == 0)) {
  3264. if (!Len($7.type)) {
  3265. String *scpname = 0;
  3266. name = $7.id;
  3267. Setattr($$,"tdname",name);
  3268. Setattr($$,"name",name);
  3269. Swig_symbol_setscopename(name);
  3270. /* If a proper name was given, we use that as the typedef, not unnamed */
  3271. Clear(unnamed);
  3272. Append(unnamed, name);
  3273. n = nextSibling(n);
  3274. set_nextSibling($$,n);
  3275. /* Check for previous extensions */
  3276. if (extendhash) {
  3277. String *clsname = Swig_symbol_qualifiedscopename(0);
  3278. Node *am = Getattr(extendhash,clsname);
  3279. if (am) {
  3280. /* Merge the extension into the symbol table */
  3281. merge_extensions($$,am);
  3282. append_previous_extension($$,am);
  3283. Delattr(extendhash,clsname);
  3284. }
  3285. Delete(clsname);
  3286. }
  3287. if (!classes) classes = NewHash();
  3288. scpname = Swig_symbol_qualifiedscopename(0);
  3289. Setattr(classes,scpname,$$);
  3290. Delete(scpname);
  3291. } else {
  3292. Swig_symbol_setscopename((char*)"<unnamed>");
  3293. }
  3294. }
  3295. appendChild($$,$5);
  3296. appendChild($$,dump_nested(Char(name)));
  3297. }
  3298. /* Pop the scope */
  3299. Setattr($$,"symtab",Swig_symbol_popscope());
  3300. if (class_rename) {
  3301. Delete(yyrename);
  3302. yyrename = NewString(class_rename);
  3303. }
  3304. Delete(Namespaceprefix);
  3305. Namespaceprefix = Swig_symbol_qualifiedscopename(0);
  3306. add_symbols($$);
  3307. add_symbols(n);
  3308. Delete(unnamed);
  3309. }
  3310. ;
  3311. cpp_opt_declarators : SEMI { $$ = 0; }
  3312. | declarator c_decl_tail {
  3313. $$ = new_node("cdecl");
  3314. Setattr($$,"name",$1.id);
  3315. Setattr($$,"decl",$1.type);
  3316. Setattr($$,"parms",$1.parms);
  3317. set_nextSibling($$,$2);
  3318. }
  3319. ;
  3320. /* ------------------------------------------------------------
  3321. class Name;
  3322. ------------------------------------------------------------ */
  3323. cpp_forward_class_decl : storage_class cpptype idcolon SEMI {
  3324. if ($1 && (Strcmp($1,"friend") == 0)) {
  3325. /* Ignore */
  3326. $$ = 0;
  3327. } else {
  3328. $$ = new_node("classforward");
  3329. Setfile($$,cparse_file);
  3330. Setline($$,cparse_line);
  3331. Setattr($$,"kind",$2);
  3332. Setattr($$,"name",$3);
  3333. Setattr($$,"sym:weak", "1");
  3334. add_symbols($$);
  3335. }
  3336. }
  3337. ;
  3338. /* ------------------------------------------------------------
  3339. template<...> decl
  3340. ------------------------------------------------------------ */
  3341. cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN {
  3342. template_parameters = $3;
  3343. if (inclass)
  3344. nested_template++;
  3345. } cpp_temp_possible {
  3346. /* Don't ignore templated functions declared within a class, unless the templated function is within a nested class */
  3347. if (nested_template <= 1) {
  3348. int is_nested_template_class = $6 && GetFlag($6, "nestedtemplateclass");
  3349. if (is_nested_template_class) {
  3350. $$ = 0;
  3351. /* Nested template classes would probably better be ignored like ordinary nested classes using cpp_nested, but that introduces shift/reduce conflicts */
  3352. if (cplus_mode == CPLUS_PUBLIC) {
  3353. /* Treat the nested class/struct/union as a forward declaration until a proper nested class solution is implemented */
  3354. String *kind = Getattr($6, "kind");
  3355. String *name = Getattr($6, "name");
  3356. $$ = new_node("template");
  3357. Setattr($$,"kind",kind);
  3358. Setattr($$,"name",name);
  3359. Setattr($$,"sym:weak", "1");
  3360. Setattr($$,"templatetype","classforward");
  3361. Setattr($$,"templateparms", $3);
  3362. add_symbols($$);
  3363. if (GetFlag($$, "feature:nestedworkaround")) {
  3364. Swig_symbol_remove($$);
  3365. $$ = 0;
  3366. } else {
  3367. SWIG_WARN_NODE_BEGIN($$);
  3368. Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested template %s not currently supported (%s ignored).\n", kind, name);
  3369. SWIG_WARN_NODE_END($$);
  3370. }
  3371. }
  3372. Delete($6);
  3373. } else {
  3374. String *tname = 0;
  3375. int error = 0;
  3376. /* check if we get a namespace node with a class declaration, and retrieve the class */
  3377. Symtab *cscope = Swig_symbol_current();
  3378. Symtab *sti = 0;
  3379. Node *ntop = $6;
  3380. Node *ni = ntop;
  3381. SwigType *ntype = ni ? nodeType(ni) : 0;
  3382. while (ni && Strcmp(ntype,"namespace") == 0) {
  3383. sti = Getattr(ni,"symtab");
  3384. ni = firstChild(ni);
  3385. ntype = nodeType(ni);
  3386. }
  3387. if (sti) {
  3388. Swig_symbol_setscope(sti);
  3389. Delete(Namespaceprefix);
  3390. Namespaceprefix = Swig_symbol_qualifiedscopename(0);
  3391. $6 = ni;
  3392. }
  3393. $$ = $6;
  3394. if ($$) tname = Getattr($$,"name");
  3395. /* Check if the class is a template specialization */
  3396. if (($$) && (Strchr(tname,'<')) && (!is_operator(tname))) {
  3397. /* If a specialization. Check if defined. */
  3398. Node *tempn = 0;
  3399. {
  3400. String *tbase = SwigType_templateprefix(tname);
  3401. tempn = Swig_symbol_clookup_local(tbase,0);
  3402. if (!tempn || (Strcmp(nodeType(tempn),"template") != 0)) {
  3403. SWIG_WARN_NODE_BEGIN(tempn);
  3404. Swig_warning(WARN_PARSE_TEMPLATE_SP_UNDEF, Getfile($$),Getline($$),"Specialization of non-template '%s'.\n", tbase);
  3405. SWIG_WARN_NODE_END(tempn);
  3406. tempn = 0;
  3407. error = 1;
  3408. }
  3409. Delete(tbase);
  3410. }
  3411. Setattr($$,"specialization","1");
  3412. Setattr($$,"templatetype",nodeType($$));
  3413. set_nodeType($$,"template");
  3414. /* Template partial specialization */
  3415. if (tempn && ($3) && ($6)) {
  3416. List *tlist;
  3417. String *targs = SwigType_templateargs(tname);
  3418. tlist = SwigType_parmlist(targs);
  3419. /* Printf(stdout,"targs = '%s' %s\n", targs, tlist); */
  3420. if (!Getattr($$,"sym:weak")) {
  3421. Setattr($$,"sym:typename","1");
  3422. }
  3423. if (Len(tlist) != ParmList_len(Getattr(tempn,"templateparms"))) {
  3424. Swig_error(Getfile($$),Getline($$),"Inconsistent argument count in template partial specialization. %d %d\n", Len(tlist), ParmList_len(Getattr(tempn,"templateparms")));
  3425. } else {
  3426. /* This code builds the argument list for the partial template
  3427. specialization. This is a little hairy, but the idea is as
  3428. follows:
  3429. $3 contains a list of arguments supplied for the template.
  3430. For example template<class T>.
  3431. tlist is a list of the specialization arguments--which may be
  3432. different. For example class<int,T>.
  3433. tp is a copy of the arguments in the original template definition.
  3434. The patching algorithm walks through the list of supplied
  3435. arguments ($3), finds the position in the specialization arguments
  3436. (tlist), and then patches the name in the argument list of the
  3437. original template.
  3438. */
  3439. {
  3440. String *pn;
  3441. Parm *p, *p1;
  3442. int i, nargs;
  3443. Parm *tp = CopyParmList(Getattr(tempn,"templateparms"));
  3444. nargs = Len(tlist);
  3445. p = $3;
  3446. while (p) {
  3447. for (i = 0; i < nargs; i++){
  3448. pn = Getattr(p,"name");
  3449. if (Strcmp(pn,SwigType_base(Getitem(tlist,i))) == 0) {
  3450. int j;
  3451. Parm *p1 = tp;
  3452. for (j = 0; j < i; j++) {
  3453. p1 = nextSibling(p1);
  3454. }
  3455. Setattr(p1,"name",pn);
  3456. Setattr(p1,"partialarg","1");
  3457. }
  3458. }
  3459. p = nextSibling(p);
  3460. }
  3461. p1 = tp;
  3462. i = 0;
  3463. while (p1) {
  3464. if (!Getattr(p1,"partialarg")) {
  3465. Delattr(p1,"name");
  3466. Setattr(p1,"type", Getitem(tlist,i));
  3467. }
  3468. i++;
  3469. p1 = nextSibling(p1);
  3470. }
  3471. Setattr($$,"templateparms",tp);
  3472. Delete(tp);
  3473. }
  3474. #if 0
  3475. /* Patch the parameter list */
  3476. if (tempn) {
  3477. Parm *p,*p1;
  3478. ParmList *tp = CopyParmList(Getattr(tempn,"templateparms"));
  3479. p = $3;
  3480. p1 = tp;
  3481. while (p && p1) {
  3482. String *pn = Getattr(p,"name");
  3483. Printf(stdout,"pn = '%s'\n", pn);
  3484. if (pn) Setattr(p1,"name",pn);
  3485. else Delattr(p1,"name");
  3486. pn = Getattr(p,"type");
  3487. if (pn) Setattr(p1,"type",pn);
  3488. p = nextSibling(p);
  3489. p1 = nextSibling(p1);
  3490. }
  3491. Setattr($$,"templateparms",tp);
  3492. Delete(tp);
  3493. } else {
  3494. Setattr($$,"templateparms",$3);
  3495. }
  3496. #endif
  3497. Delattr($$,"specialization");
  3498. Setattr($$,"partialspecialization","1");
  3499. /* Create a specialized name for matching */
  3500. {
  3501. Parm *p = $3;
  3502. String *fname = NewString(Getattr($$,"name"));
  3503. String *ffname = 0;
  3504. ParmList *partialparms = 0;
  3505. char tmp[32];
  3506. int i, ilen;
  3507. while (p) {
  3508. String *n = Getattr(p,"name");
  3509. if (!n) {
  3510. p = nextSibling(p);
  3511. continue;
  3512. }
  3513. ilen = Len(tlist);
  3514. for (i = 0; i < ilen; i++) {
  3515. if (Strstr(Getitem(tlist,i),n)) {
  3516. sprintf(tmp,"$%d",i+1);
  3517. Replaceid(fname,n,tmp);
  3518. }
  3519. }
  3520. p = nextSibling(p);
  3521. }
  3522. /* Patch argument names with typedef */
  3523. {
  3524. Iterator tt;
  3525. Parm *parm_current = 0;
  3526. List *tparms = SwigType_parmlist(fname);
  3527. ffname = SwigType_templateprefix(fname);
  3528. Append(ffname,"<(");
  3529. for (tt = First(tparms); tt.item; ) {
  3530. SwigType *rtt = Swig_symbol_typedef_reduce(tt.item,0);
  3531. SwigType *ttr = Swig_symbol_type_qualify(rtt,0);
  3532. Parm *newp = NewParm(ttr, 0);
  3533. if (partialparms)
  3534. set_nextSibling(parm_current, newp);
  3535. else
  3536. partialparms = newp;
  3537. parm_current = newp;
  3538. Append(ffname,ttr);
  3539. tt = Next(tt);
  3540. if (tt.item) Putc(',',ffname);
  3541. Delete(rtt);
  3542. Delete(ttr);
  3543. }
  3544. Delete(tparms);
  3545. Append(ffname,")>");
  3546. }
  3547. {
  3548. Node *new_partial = NewHash();
  3549. String *partials = Getattr(tempn,"partials");
  3550. if (!partials) {
  3551. partials = NewList();
  3552. Setattr(tempn,"partials",partials);
  3553. Delete(partials);
  3554. }
  3555. /* Printf(stdout,"partial: fname = '%s', '%s'\n", fname, Swig_symbol_typedef_reduce(fname,0)); */
  3556. Setattr(new_partial, "partialparms", partialparms);
  3557. Setattr(new_partial, "templcsymname", ffname);
  3558. Append(partials, new_partial);
  3559. }
  3560. Setattr($$,"partialargs",ffname);
  3561. Swig_symbol_cadd(ffname,$$);
  3562. }
  3563. }
  3564. Delete(tlist);
  3565. Delete(targs);
  3566. } else {
  3567. /* An explicit template specialization */
  3568. /* add default args from primary (unspecialized) template */
  3569. String *ty = Swig_symbol_template_deftype(tname,0);
  3570. String *fname = Swig_symbol_type_qualify(ty,0);
  3571. Swig_symbol_cadd(fname,$$);
  3572. Delete(ty);
  3573. Delete(fname);
  3574. }
  3575. } else if ($$) {
  3576. Setattr($$,"templatetype",nodeType($6));
  3577. set_nodeType($$,"template");
  3578. Setattr($$,"templateparms", $3);
  3579. if (!Getattr($$,"sym:weak")) {
  3580. Setattr($$,"sym:typename","1");
  3581. }
  3582. add_symbols($$);
  3583. default_arguments($$);
  3584. /* We also place a fully parameterized version in the symbol table */
  3585. {
  3586. Parm *p;
  3587. String *fname = NewStringf("%s<(", Getattr($$,"name"));
  3588. p = $3;
  3589. while (p) {
  3590. String *n = Getattr(p,"name");
  3591. if (!n) n = Getattr(p,"type");
  3592. Append(fname,n);
  3593. p = nextSibling(p);
  3594. if (p) Putc(',',fname);
  3595. }
  3596. Append(fname,")>");
  3597. Swig_symbol_cadd(fname,$$);
  3598. }
  3599. }
  3600. $$ = ntop;
  3601. Swig_symbol_setscope(cscope);
  3602. Delete(Namespaceprefix);
  3603. Namespaceprefix = Swig_symbol_qualifiedscopename(0);
  3604. if (error) $$ = 0;
  3605. }
  3606. } else {
  3607. $$ = 0;
  3608. }
  3609. template_parameters = 0;
  3610. if (inclass)
  3611. nested_template--;
  3612. }
  3613. | TEMPLATE cpptype idcolon {
  3614. Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit template instantiation ignored.\n");
  3615. $$ = 0;
  3616. }
  3617. ;
  3618. cpp_temp_possible: c_decl {
  3619. $$ = $1;
  3620. }
  3621. | cpp_class_decl {
  3622. $$ = $1;
  3623. }
  3624. | cpp_constructor_decl {
  3625. $$ = $1;
  3626. }
  3627. | cpp_template_decl {
  3628. $$ = 0;
  3629. }
  3630. | cpp_forward_class_decl {
  3631. $$ = $1;
  3632. }
  3633. | cpp_conversion_operator {
  3634. $$ = $1;
  3635. }
  3636. ;
  3637. template_parms : templateparameters {
  3638. /* Rip out the parameter names */
  3639. Parm *p = $1;
  3640. $$ = $1;
  3641. while (p) {
  3642. String *name = Getattr(p,"name");
  3643. if (!name) {
  3644. /* Hmmm. Maybe it's a 'class T' parameter */
  3645. char *type = Char(Getattr(p,"type"));
  3646. /* Template template parameter */
  3647. if (strncmp(type,"template<class> ",16) == 0) {
  3648. type += 16;
  3649. }
  3650. if ((strncmp(type,"class ",6) == 0) || (strncmp(type,"typename ", 9) == 0)) {
  3651. char *t = strchr(type,' ');
  3652. Setattr(p,"name", t+1);
  3653. } else {
  3654. /*
  3655. Swig_error(cparse_file, cparse_line, "Missing template parameter name\n");
  3656. $$.rparms = 0;
  3657. $$.parms = 0;
  3658. break; */
  3659. }
  3660. }
  3661. p = nextSibling(p);
  3662. }
  3663. }
  3664. ;
  3665. templateparameters : templateparameter templateparameterstail {
  3666. set_nextSibling($1,$2);
  3667. $$ = $1;
  3668. }
  3669. | empty { $$ = 0; }
  3670. ;
  3671. templateparameter : templcpptype {
  3672. $$ = NewParm(NewString($1), 0);
  3673. }
  3674. | parm {
  3675. $$ = $1;
  3676. }
  3677. ;
  3678. templateparameterstail : COMMA templateparameter templateparameterstail {
  3679. set_nextSibling($2,$3);
  3680. $$ = $2;
  3681. }
  3682. | empty { $$ = 0; }
  3683. ;
  3684. /* Namespace support */
  3685. cpp_using_decl : USING idcolon SEMI {
  3686. String *uname = Swig_symbol_type_qualify($2,0);
  3687. String *name = Swig_scopename_last($2);
  3688. $$ = new_node("using");
  3689. Setattr($$,"uname",uname);
  3690. Setattr($$,"name", name);
  3691. Delete(uname);
  3692. Delete(name);
  3693. add_symbols($$);
  3694. }
  3695. | USING NAMESPACE idcolon SEMI {
  3696. Node *n = Swig_symbol_clookup($3,0);
  3697. if (!n) {
  3698. Swig_error(cparse_file, cparse_line, "Nothing known about namespace '%s'\n", $3);
  3699. $$ = 0;
  3700. } else {
  3701. while (Strcmp(nodeType(n),"using") == 0) {
  3702. n = Getattr(n,"node");
  3703. }
  3704. if (n) {
  3705. if (Strcmp(nodeType(n),"namespace") == 0) {
  3706. Symtab *current = Swig_symbol_current();
  3707. Symtab *symtab = Getattr(n,"symtab");
  3708. $$ = new_node("using");
  3709. Setattr($$,"node",n);
  3710. Setattr($$,"namespace", $3);
  3711. if (current != symtab) {
  3712. Swig_symbol_inherit(symtab);
  3713. }
  3714. } else {
  3715. Swig_error(cparse_file, cparse_line, "'%s' is not a namespace.\n", $3);
  3716. $$ = 0;
  3717. }
  3718. } else {
  3719. $$ = 0;
  3720. }
  3721. }
  3722. }
  3723. ;
  3724. cpp_namespace_decl : NAMESPACE idcolon LBRACE {
  3725. Hash *h;
  3726. $1 = Swig_symbol_current();
  3727. h = Swig_symbol_clookup($2,0);
  3728. if (h && ($1 == Getattr(h,"sym:symtab")) && (Strcmp(nodeType(h),"namespace") == 0)) {
  3729. if (Getattr(h,"alias")) {
  3730. h = Getattr(h,"namespace");
  3731. Swig_warning(WARN_PARSE_NAMESPACE_ALIAS, cparse_file, cparse_line, "Namespace alias '%s' not allowed here. Assuming '%s'\n",
  3732. $2, Getattr(h,"name"));
  3733. $2 = Getattr(h,"name");
  3734. }
  3735. Swig_symbol_setscope(Getattr(h,"symtab"));
  3736. } else {
  3737. Swig_symbol_newscope();
  3738. Swig_symbol_setscopename($2);
  3739. }
  3740. Delete(Namespaceprefix);
  3741. Namespaceprefix = Swig_symbol_qualifiedscopename(0);
  3742. } interface RBRACE {
  3743. Node *n = $5;
  3744. set_nodeType(n,"namespace");
  3745. Setattr(n,"name",$2);
  3746. Setattr(n,"symtab", Swig_symbol_popscope());
  3747. Swig_symbol_setscope($1);
  3748. $$ = n;
  3749. Delete(Namespaceprefix);
  3750. Namespaceprefix = Swig_symbol_qualifiedscopename(0);
  3751. add_symbols($$);
  3752. }
  3753. | NAMESPACE LBRACE {
  3754. Hash *h;
  3755. $1 = Swig_symbol_current();
  3756. h = Swig_symbol_clookup((char *)" ",0);
  3757. if (h && (Strcmp(nodeType(h),"namespace") == 0)) {
  3758. Swig_symbol_setscope(Getattr(h,"symtab"));
  3759. } else {
  3760. Swig_symbol_newscope();
  3761. /* we don't use "__unnamed__", but a long 'empty' name */
  3762. Swig_symbol_setscopename(" ");
  3763. }
  3764. Namespaceprefix = 0;
  3765. } interface RBRACE {
  3766. $$ = $4;
  3767. set_nodeType($$,"namespace");
  3768. Setattr($$,"unnamed","1");
  3769. Setattr($$,"symtab", Swig_symbol_popscope());
  3770. Swig_symbol_setscope($1);
  3771. Delete(Namespaceprefix);
  3772. Namespaceprefix = Swig_symbol_qualifiedscopename(0);
  3773. add_symbols($$);
  3774. }
  3775. | NAMESPACE ID EQUAL idcolon SEMI {
  3776. /* Namespace alias */
  3777. Node *n;
  3778. $$ = new_node("namespace");
  3779. Setattr($$,"name",$2);
  3780. Setattr($$,"alias",$4);
  3781. n = Swig_symbol_clookup($4,0);
  3782. if (!n) {
  3783. Swig_error(cparse_file, cparse_line, "Unknown namespace '%s'\n", $4);
  3784. $$ = 0;
  3785. } else {
  3786. if (Strcmp(nodeType(n),"namespace") != 0) {
  3787. Swig_error(cparse_file, cparse_line, "'%s' is not a namespace\n",$4);
  3788. $$ = 0;
  3789. } else {
  3790. while (Getattr(n,"alias")) {
  3791. n = Getattr(n,"namespace");
  3792. }
  3793. Setattr($$,"namespace",n);
  3794. add_symbols($$);
  3795. /* Set up a scope alias */
  3796. Swig_symbol_alias($2,Getattr(n,"symtab"));
  3797. }
  3798. }
  3799. }
  3800. ;
  3801. cpp_members : cpp_member cpp_members {
  3802. $$ = $1;
  3803. /* Insert cpp_member (including any siblings) to the front of the cpp_members linked list */
  3804. if ($$) {
  3805. Node *p = $$;
  3806. Node *pp =0;
  3807. while (p) {
  3808. pp = p;
  3809. p = nextSibling(p);
  3810. }
  3811. set_nextSibling(pp,$2);
  3812. } else {
  3813. $$ = $2;
  3814. }
  3815. }
  3816. | EXTEND LBRACE {
  3817. if (cplus_mode != CPLUS_PUBLIC) {
  3818. Swig_error(cparse_file,cparse_line,"%%extend can only be used in a public section\n");
  3819. }
  3820. } cpp_members RBRACE cpp_members {
  3821. $$ = new_node("extend");
  3822. tag_nodes($4,"feature:extend",(char*) "1");
  3823. appendChild($$,$4);
  3824. set_nextSibling($$,$6);
  3825. }
  3826. | include_directive { $$ = $1; }
  3827. | empty { $$ = 0;}
  3828. | error {
  3829. int start_line = cparse_line;
  3830. skip_decl();
  3831. Swig_error(cparse_file,start_line,"Syntax error in input(3).\n");
  3832. exit(1);
  3833. } cpp_members {
  3834. $$ = $3;
  3835. }
  3836. ;
  3837. /* ======================================================================
  3838. * C++ Class members
  3839. * ====================================================================== */
  3840. /* A class member. May be data or a function. Static or virtual as well */
  3841. cpp_member : c_declaration { $$ = $1; }
  3842. | cpp_constructor_decl {
  3843. $$ = $1;
  3844. if (extendmode) {
  3845. String *symname;
  3846. symname= make_name($$,Getattr($$,"name"), Getattr($$,"decl"));
  3847. if (Strcmp(symname,Getattr($$,"name")) == 0) {
  3848. /* No renaming operation. Set name to class name */
  3849. Delete(yyrename);
  3850. yyrename = NewString(Getattr(current_class,"sym:name"));
  3851. } else {
  3852. Delete(yyrename);
  3853. yyrename = symname;
  3854. }
  3855. }
  3856. add_symbols($$);
  3857. default_arguments($$);
  3858. }
  3859. | cpp_destructor_decl { $$ = $1; }
  3860. | cpp_protection_decl { $$ = $1; }
  3861. | cpp_swig_directive { $$ = $1; }
  3862. | cpp_conversion_operator { $$ = $1; }
  3863. | cpp_forward_class_decl { $$ = $1; }
  3864. | cpp_nested { $$ = $1; }
  3865. | storage_class idcolon SEMI { $$ = 0; }
  3866. | cpp_using_decl { $$ = $1; }
  3867. | cpp_template_decl { $$ = $1; }
  3868. | cpp_catch_decl { $$ = 0; }
  3869. | template_directive { $$ = $1; }
  3870. | warn_directive { $$ = $1; }
  3871. | anonymous_bitfield { $$ = 0; }
  3872. | fragment_directive {$$ = $1; }
  3873. | types_directive {$$ = $1; }
  3874. | SEMI { $$ = 0; }
  3875. ;
  3876. /* Possibly a constructor */
  3877. /* Note: the use of 'type' is here to resolve a shift-reduce conflict. For example:
  3878. typedef Foo ();
  3879. typedef Foo (*ptr)();
  3880. */
  3881. cpp_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end {
  3882. if (Classprefix) {
  3883. SwigType *decl = NewStringEmpty();
  3884. $$ = new_node("constructor");
  3885. Setattr($$,"storage",$1);
  3886. Setattr($$,"name",$2);
  3887. Setattr($$,"parms",$4);
  3888. SwigType_add_function(decl,$4);
  3889. Setattr($$,"decl",decl);
  3890. Setattr($$,"throws",$6.throws);
  3891. Setattr($$,"throw",$6.throwf);
  3892. if (Len(scanner_ccode)) {
  3893. String *code = Copy(scanner_ccode);
  3894. Setattr($$,"code",code);
  3895. Delete(code);
  3896. }
  3897. SetFlag($$,"feature:new");
  3898. } else {
  3899. $$ = 0;
  3900. }
  3901. }
  3902. ;
  3903. /* A destructor (hopefully) */
  3904. cpp_destructor_decl : NOT idtemplate LPAREN parms RPAREN cpp_end {
  3905. String *name = NewStringf("%s",$2);
  3906. if (*(Char(name)) != '~') Insert(name,0,"~");
  3907. $$ = new_node("destructor");
  3908. Setattr($$,"name",name);
  3909. Delete(name);
  3910. if (Len(scanner_ccode)) {
  3911. String *code = Copy(scanner_ccode);
  3912. Setattr($$,"code",code);
  3913. Delete(code);
  3914. }
  3915. {
  3916. String *decl = NewStringEmpty();
  3917. SwigType_add_function(decl,$4);
  3918. Setattr($$,"decl",decl);
  3919. Delete(decl);
  3920. }
  3921. Setattr($$,"throws",$6.throws);
  3922. Setattr($$,"throw",$6.throwf);
  3923. add_symbols($$);
  3924. }
  3925. /* A virtual destructor */
  3926. | VIRTUAL NOT idtemplate LPAREN parms RPAREN cpp_vend {
  3927. String *name;
  3928. char *c = 0;
  3929. $$ = new_node("destructor");
  3930. /* Check for template names. If the class is a template
  3931. and the constructor is missing the template part, we
  3932. add it */
  3933. if (Classprefix) {
  3934. c = strchr(Char(Classprefix),'<');
  3935. if (c && !Strchr($3,'<')) {
  3936. $3 = NewStringf("%s%s",$3,c);
  3937. }
  3938. }
  3939. Setattr($$,"storage","virtual");
  3940. name = NewStringf("%s",$3);
  3941. if (*(Char(name)) != '~') Insert(name,0,"~");
  3942. Setattr($$,"name",name);
  3943. Delete(name);
  3944. Setattr($$,"throws",$7.throws);
  3945. Setattr($$,"throw",$7.throwf);
  3946. if ($7.val) {
  3947. Setattr($$,"value","0");
  3948. }
  3949. if (Len(scanner_ccode)) {
  3950. String *code = Copy(scanner_ccode);
  3951. Setattr($$,"code",code);
  3952. Delete(code);
  3953. }
  3954. {
  3955. String *decl = NewStringEmpty();
  3956. SwigType_add_function(decl,$5);
  3957. Setattr($$,"decl",decl);
  3958. Delete(decl);
  3959. }
  3960. add_symbols($$);
  3961. }
  3962. ;
  3963. /* C++ type conversion operator */
  3964. cpp_conversion_operator : storage_class COPERATOR type pointer LPAREN parms RPAREN cpp_vend {
  3965. $$ = new_node("cdecl");
  3966. Setattr($$,"type",$3);
  3967. Setattr($$,"name",$2);
  3968. Setattr($$,"storage",$1);
  3969. SwigType_add_function($4,$6);
  3970. if ($8.qualifier) {
  3971. SwigType_push($4,$8.qualifier);
  3972. }
  3973. Setattr($$,"decl",$4);
  3974. Setattr($$,"parms",$6);
  3975. Setattr($$,"conversion_operator","1");
  3976. add_symbols($$);
  3977. }
  3978. | storage_class COPERATOR type AND LPAREN parms RPAREN cpp_vend {
  3979. SwigType *decl;
  3980. $$ = new_node("cdecl");
  3981. Setattr($$,"type",$3);
  3982. Setattr($$,"name",$2);
  3983. Setattr($$,"storage",$1);
  3984. decl = NewStringEmpty();
  3985. SwigType_add_reference(decl);
  3986. SwigType_add_function(decl,$6);
  3987. if ($8.qualifier) {
  3988. SwigType_push(decl,$8.qualifier);
  3989. }
  3990. Setattr($$,"decl",decl);
  3991. Setattr($$,"parms",$6);
  3992. Setattr($$,"conversion_operator","1");
  3993. add_symbols($$);
  3994. }
  3995. | storage_class COPERATOR type LPAREN parms RPAREN cpp_vend {
  3996. String *t = NewStringEmpty();
  3997. $$ = new_node("cdecl");
  3998. Setattr($$,"type",$3);
  3999. Setattr($$,"name",$2);
  4000. Setattr($$,"storage",$1);
  4001. SwigType_add_function(t,$5);
  4002. if ($7.qualifier) {
  4003. SwigType_push(t,$7.qualifier);
  4004. }
  4005. Setattr($$,"decl",t);
  4006. Setattr($$,"parms",$5);
  4007. Setattr($$,"conversion_operator","1");
  4008. add_symbols($$);
  4009. }
  4010. ;
  4011. /* isolated catch clause. */
  4012. cpp_catch_decl : CATCH LPAREN parms RPAREN LBRACE {
  4013. skip_balanced('{','}');
  4014. $$ = 0;
  4015. }
  4016. ;
  4017. /* public: */
  4018. cpp_protection_decl : PUBLIC COLON {
  4019. $$ = new_node("access");
  4020. Setattr($$,"kind","public");
  4021. cplus_mode = CPLUS_PUBLIC;
  4022. }
  4023. /* private: */
  4024. | PRIVATE COLON {
  4025. $$ = new_node("access");
  4026. Setattr($$,"kind","private");
  4027. cplus_mode = CPLUS_PRIVATE;
  4028. }
  4029. /* protected: */
  4030. | PROTECTED COLON {
  4031. $$ = new_node("access");
  4032. Setattr($$,"kind","protected");
  4033. cplus_mode = CPLUS_PROTECTED;
  4034. }
  4035. ;
  4036. /* ----------------------------------------------------------------------
  4037. Nested structure. This is a sick "hack". If we encounter
  4038. a nested structure, we're going to grab the text of its definition and
  4039. feed it back into the scanner. In the meantime, we need to grab
  4040. variable declaration information and generate the associated wrapper
  4041. code later. Yikes!
  4042. This really only works in a limited sense. Since we use the
  4043. code attached to the nested class to generate both C/C++ code,
  4044. it can't have any SWIG directives in it. It also needs to be parsable
  4045. by SWIG or this whole thing is going to puke.
  4046. ---------------------------------------------------------------------- */
  4047. /* struct sname { } id; or struct sname { }; declaration */
  4048. cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
  4049. } nested_decl SEMI {
  4050. $$ = 0;
  4051. if (cplus_mode == CPLUS_PUBLIC) {
  4052. if (cparse_cplusplus) {
  4053. $$ = nested_forward_declaration($2, $3);
  4054. } else if ($6.id) {
  4055. /* Generate some code for a new struct */
  4056. Nested *n = (Nested *) malloc(sizeof(Nested));
  4057. n->code = NewStringEmpty();
  4058. Printv(n->code, "typedef ", $2, " ", Char(scanner_ccode), " $classname_", $6.id, ";\n", NIL);
  4059. n->name = Swig_copy_string($6.id);
  4060. n->line = cparse_start_line;
  4061. n->type = NewStringEmpty();
  4062. n->kind = $2;
  4063. n->unnamed = 0;
  4064. SwigType_push(n->type, $6.type);
  4065. n->next = 0;
  4066. add_nested(n);
  4067. }
  4068. }
  4069. }
  4070. /* struct { } id; or struct { }; declaration */
  4071. | storage_class cpptype LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
  4072. } nested_decl SEMI {
  4073. $$ = 0;
  4074. if (cplus_mode == CPLUS_PUBLIC) {
  4075. if ($5.id) {
  4076. if (cparse_cplusplus) {
  4077. $$ = nested_forward_declaration($2, $5.id);
  4078. } else {
  4079. /* Generate some code for a new struct */
  4080. Nested *n = (Nested *) malloc(sizeof(Nested));
  4081. n->code = NewStringEmpty();
  4082. Printv(n->code, "typedef ", $2, " " , Char(scanner_ccode), " $classname_", $5.id, ";\n",NIL);
  4083. n->name = Swig_copy_string($5.id);
  4084. n->line = cparse_start_line;
  4085. n->type = NewStringEmpty();
  4086. n->kind = $2;
  4087. n->unnamed = 1;
  4088. SwigType_push(n->type,$5.type);
  4089. n->next = 0;
  4090. add_nested(n);
  4091. }
  4092. } else {
  4093. Swig_warning(WARN_PARSE_UNNAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2);
  4094. }
  4095. }
  4096. }
  4097. /* class name : base_list { }; declaration */
  4098. /* This adds one shift/reduce. */
  4099. | storage_class cpptype idcolon COLON base_list LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
  4100. } SEMI {
  4101. $$ = 0;
  4102. if (cplus_mode == CPLUS_PUBLIC) {
  4103. $$ = nested_forward_declaration($2, $3);
  4104. }
  4105. }
  4106. /* This unfortunately introduces 4 shift/reduce conflicts, so instead the somewhat hacky nested_template is used for ignore nested template classes. */
  4107. /*
  4108. | TEMPLATE LESSTHAN template_parms GREATERTHAN cpptype idcolon LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
  4109. } SEMI {
  4110. $$ = 0;
  4111. if (cplus_mode == CPLUS_PUBLIC) {
  4112. Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", $5, $6);
  4113. }
  4114. }
  4115. */
  4116. ;
  4117. nested_decl : declarator { $$ = $1;}
  4118. | empty { $$.id = 0; }
  4119. ;
  4120. /* These directives can be included inside a class definition */
  4121. cpp_swig_directive: pragma_directive { $$ = $1; }
  4122. /* A constant (includes #defines) inside a class */
  4123. | constant_directive { $$ = $1; }
  4124. /* This is the new style rename */
  4125. | name_directive { $$ = $1; }
  4126. /* rename directive */
  4127. | rename_directive { $$ = $1; }
  4128. | feature_directive { $$ = $1; }
  4129. | varargs_directive { $$ = $1; }
  4130. | insert_directive { $$ = $1; }
  4131. | typemap_directive { $$ = $1; }
  4132. | apply_directive { $$ = $1; }
  4133. | clear_directive { $$ = $1; }
  4134. | echo_directive { $$ = $1; }
  4135. ;
  4136. cpp_end : cpp_const SEMI {
  4137. Clear(scanner_ccode);
  4138. $$.throws = $1.throws;
  4139. $$.throwf = $1.throwf;
  4140. }
  4141. | cpp_const LBRACE {
  4142. skip_balanced('{','}');
  4143. $$.throws = $1.throws;
  4144. $$.throwf = $1.throwf;
  4145. }
  4146. ;
  4147. cpp_vend : cpp_const SEMI {
  4148. Clear(scanner_ccode);
  4149. $$.val = 0;
  4150. $$.qualifier = $1.qualifier;
  4151. $$.bitfield = 0;
  4152. $$.throws = $1.throws;
  4153. $$.throwf = $1.throwf;
  4154. }
  4155. | cpp_const EQUAL definetype SEMI {
  4156. Clear(scanner_ccode);
  4157. $$.val = $3.val;
  4158. $$.qualifier = $1.qualifier;
  4159. $$.bitfield = 0;
  4160. $$.throws = $1.throws;
  4161. $$.throwf = $1.throwf;
  4162. }
  4163. | cpp_const LBRACE {
  4164. skip_balanced('{','}');
  4165. $$.val = 0;
  4166. $$.qualifier = $1.qualifier;
  4167. $$.bitfield = 0;
  4168. $$.throws = $1.throws;
  4169. $$.throwf = $1.throwf;
  4170. }
  4171. ;
  4172. anonymous_bitfield : storage_class type COLON expr SEMI { };
  4173. /* ======================================================================
  4174. * PRIMITIVES
  4175. * ====================================================================== */
  4176. storage_class : EXTERN { $$ = "extern"; }
  4177. | EXTERN string {
  4178. if (strcmp($2,"C") == 0) {
  4179. $$ = "externc";
  4180. } else {
  4181. Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\".\n", $2);
  4182. $$ = 0;
  4183. }
  4184. }
  4185. | STATIC { $$ = "static"; }
  4186. | TYPEDEF { $$ = "typedef"; }
  4187. | VIRTUAL { $$ = "virtual"; }
  4188. | FRIEND { $$ = "friend"; }
  4189. | EXPLICIT { $$ = "explicit"; }
  4190. | empty { $$ = 0; }
  4191. ;
  4192. /* ------------------------------------------------------------------------------
  4193. Function parameter lists
  4194. ------------------------------------------------------------------------------ */
  4195. parms : rawparms {
  4196. Parm *p;
  4197. $$ = $1;
  4198. p = $1;
  4199. while (p) {
  4200. Replace(Getattr(p,"type"),"typename ", "", DOH_REPLACE_ANY);
  4201. p = nextSibling(p);
  4202. }
  4203. }
  4204. ;
  4205. rawparms : parm ptail {
  4206. set_nextSibling($1,$2);
  4207. $$ = $1;
  4208. }
  4209. | empty { $$ = 0; }
  4210. ;
  4211. ptail : COMMA parm ptail {
  4212. set_nextSibling($2,$3);
  4213. $$ = $2;
  4214. }
  4215. | empty { $$ = 0; }
  4216. ;
  4217. parm : rawtype parameter_declarator {
  4218. SwigType_push($1,$2.type);
  4219. $$ = NewParm($1,$2.id);
  4220. Setfile($$,cparse_file);
  4221. Setline($$,cparse_line);
  4222. if ($2.defarg) {
  4223. Setattr($$,"value",$2.defarg);
  4224. }
  4225. }
  4226. | TEMPLATE LESSTHAN cpptype GREATERTHAN cpptype idcolon def_args {
  4227. $$ = NewParm(NewStringf("template<class> %s %s", $5,$6), 0);
  4228. Setfile($$,cparse_file);
  4229. Setline($$,cparse_line);
  4230. if ($7.val) {
  4231. Setattr($$,"value",$7.val);
  4232. }
  4233. }
  4234. | PERIOD PERIOD PERIOD {
  4235. SwigType *t = NewString("v(...)");
  4236. $$ = NewParm(t, 0);
  4237. Setfile($$,cparse_file);
  4238. Setline($$,cparse_line);
  4239. }
  4240. ;
  4241. valparms : rawvalparms {
  4242. Parm *p;
  4243. $$ = $1;
  4244. p = $1;
  4245. while (p) {
  4246. if (Getattr(p,"type")) {
  4247. Replace(Getattr(p,"type"),"typename ", "", DOH_REPLACE_ANY);
  4248. }
  4249. p = nextSibling(p);
  4250. }
  4251. }
  4252. ;
  4253. rawvalparms : valparm valptail {
  4254. set_nextSibling($1,$2);
  4255. $$ = $1;
  4256. }
  4257. | empty { $$ = 0; }
  4258. ;
  4259. valptail : COMMA valparm valptail {
  4260. set_nextSibling($2,$3);
  4261. $$ = $2;
  4262. }
  4263. | empty { $$ = 0; }
  4264. ;
  4265. valparm : parm {
  4266. $$ = $1;
  4267. {
  4268. /* We need to make a possible adjustment for integer parameters. */
  4269. SwigType *type;
  4270. Node *n = 0;
  4271. while (!n) {
  4272. type = Getattr($1,"type");
  4273. n = Swig_symbol_clookup(type,0); /* See if we can find a node that matches the typename */
  4274. if ((n) && (Strcmp(nodeType(n),"cdecl") == 0)) {
  4275. SwigType *decl = Getattr(n,"decl");
  4276. if (!SwigType_isfunction(decl)) {
  4277. String *value = Getattr(n,"value");
  4278. if (value) {
  4279. String *v = Copy(value);
  4280. Setattr($1,"type",v);
  4281. Delete(v);
  4282. n = 0;
  4283. }
  4284. }
  4285. } else {
  4286. break;
  4287. }
  4288. }
  4289. }
  4290. }
  4291. | valexpr {
  4292. $$ = NewParm(0,0);
  4293. Setfile($$,cparse_file);
  4294. Setline($$,cparse_line);
  4295. Setattr($$,"value",$1.val);
  4296. }
  4297. ;
  4298. def_args : EQUAL definetype {
  4299. $$ = $2;
  4300. if ($2.type == T_ERROR) {
  4301. Swig_warning(WARN_PARSE_BAD_DEFAULT,cparse_file, cparse_line, "Can't set default argument (ignored)\n");
  4302. $$.val = 0;
  4303. $$.rawval = 0;
  4304. $$.bitfield = 0;
  4305. $$.throws = 0;
  4306. $$.throwf = 0;
  4307. }
  4308. }
  4309. | EQUAL definetype LBRACKET expr RBRACKET {
  4310. $$ = $2;
  4311. if ($2.type == T_ERROR) {
  4312. Swig_warning(WARN_PARSE_BAD_DEFAULT,cparse_file, cparse_line, "Can't set default argument (ignored)\n");
  4313. $$ = $2;
  4314. $$.val = 0;
  4315. $$.rawval = 0;
  4316. $$.bitfield = 0;
  4317. $$.throws = 0;
  4318. $$.throwf = 0;
  4319. } else {
  4320. $$.val = NewStringf("%s[%s]",$2.val,$4.val);
  4321. }
  4322. }
  4323. | EQUAL LBRACE {
  4324. skip_balanced('{','}');
  4325. $$.val = 0;
  4326. $$.rawval = 0;
  4327. $$.type = T_INT;
  4328. $$.bitfield = 0;
  4329. $$.throws = 0;
  4330. $$.throwf = 0;
  4331. }
  4332. | COLON expr {
  4333. $$.val = 0;
  4334. $$.rawval = 0;
  4335. $$.type = 0;
  4336. $$.bitfield = $2.val;
  4337. $$.throws = 0;
  4338. $$.throwf = 0;
  4339. }
  4340. | empty {
  4341. $$.val = 0;
  4342. $$.rawval = 0;
  4343. $$.type = T_INT;
  4344. $$.bitfield = 0;
  4345. $$.throws = 0;
  4346. $$.throwf = 0;
  4347. }
  4348. ;
  4349. parameter_declarator : declarator def_args {
  4350. $$ = $1;
  4351. $$.defarg = $2.rawval ? $2.rawval : $2.val;
  4352. }
  4353. | abstract_declarator def_args {
  4354. $$ = $1;
  4355. $$.defarg = $2.rawval ? $2.rawval : $2.val;
  4356. }
  4357. | def_args {
  4358. $$.type = 0;
  4359. $$.id = 0;
  4360. $$.defarg = $1.rawval ? $1.rawval : $1.val;
  4361. }
  4362. ;
  4363. typemap_parameter_declarator : declarator {
  4364. $$ = $1;
  4365. if (SwigType_isfunction($1.type)) {
  4366. Delete(SwigType_pop_function($1.type));
  4367. } else if (SwigType_isarray($1.type)) {
  4368. SwigType *ta = SwigType_pop_arrays($1.type);
  4369. if (SwigType_isfunction($1.type)) {
  4370. Delete(SwigType_pop_function($1.type));
  4371. } else {
  4372. $$.parms = 0;
  4373. }
  4374. SwigType_push($1.type,ta);
  4375. Delete(ta);
  4376. } else {
  4377. $$.parms = 0;
  4378. }
  4379. }
  4380. | abstract_declarator {
  4381. $$ = $1;
  4382. if (SwigType_isfunction($1.type)) {
  4383. Delete(SwigType_pop_function($1.type));
  4384. } else if (SwigType_isarray($1.type)) {
  4385. SwigType *ta = SwigType_pop_arrays($1.type);
  4386. if (SwigType_isfunction($1.type)) {
  4387. Delete(SwigType_pop_function($1.type));
  4388. } else {
  4389. $$.parms = 0;
  4390. }
  4391. SwigType_push($1.type,ta);
  4392. Delete(ta);
  4393. } else {
  4394. $$.parms = 0;
  4395. }
  4396. }
  4397. | empty {
  4398. $$.type = 0;
  4399. $$.id = 0;
  4400. $$.parms = 0;
  4401. }
  4402. ;
  4403. declarator : pointer notso_direct_declarator {
  4404. $$ = $2;
  4405. if ($$.type) {
  4406. SwigType_push($1,$$.type);
  4407. Delete($$.type);
  4408. }
  4409. $$.type = $1;
  4410. }
  4411. | pointer AND notso_direct_declarator {
  4412. $$ = $3;
  4413. SwigType_add_reference($1);
  4414. if ($$.type) {
  4415. SwigType_push($1,$$.type);
  4416. Delete($$.type);
  4417. }
  4418. $$.type = $1;
  4419. }
  4420. | direct_declarator {
  4421. $$ = $1;
  4422. if (!$$.type) $$.type = NewStringEmpty();
  4423. }
  4424. | AND notso_direct_declarator {
  4425. $$ = $2;
  4426. $$.type = NewStringEmpty();
  4427. SwigType_add_reference($$.type);
  4428. if ($2.type) {
  4429. SwigType_push($$.type,$2.type);
  4430. Delete($2.type);
  4431. }
  4432. }
  4433. | idcolon DSTAR notso_direct_declarator {
  4434. SwigType *t = NewStringEmpty();
  4435. $$ = $3;
  4436. SwigType_add_memberpointer(t,$1);
  4437. if ($$.type) {
  4438. SwigType_push(t,$$.type);
  4439. Delete($$.type);
  4440. }
  4441. $$.type = t;
  4442. }
  4443. | pointer idcolon DSTAR notso_direct_declarator {
  4444. SwigType *t = NewStringEmpty();
  4445. $$ = $4;
  4446. SwigType_add_memberpointer(t,$2);
  4447. SwigType_push($1,t);
  4448. if ($$.type) {
  4449. SwigType_push($1,$$.type);
  4450. Delete($$.type);
  4451. }
  4452. $$.type = $1;
  4453. Delete(t);
  4454. }
  4455. | pointer idcolon DSTAR AND notso_direct_declarator {
  4456. $$ = $5;
  4457. SwigType_add_memberpointer($1,$2);
  4458. SwigType_add_reference($1);
  4459. if ($$.type) {
  4460. SwigType_push($1,$$.type);
  4461. Delete($$.type);
  4462. }
  4463. $$.type = $1;
  4464. }
  4465. | idcolon DSTAR AND notso_direct_declarator {
  4466. SwigType *t = NewStringEmpty();
  4467. $$ = $4;
  4468. SwigType_add_memberpointer(t,$1);
  4469. SwigType_add_reference(t);
  4470. if ($$.type) {
  4471. SwigType_push(t,$$.type);
  4472. Delete($$.type);
  4473. }
  4474. $$.type = t;
  4475. }
  4476. ;
  4477. notso_direct_declarator : idcolon {
  4478. /* Note: This is non-standard C. Template declarator is allowed to follow an identifier */
  4479. $$.id = Char($1);
  4480. $$.type = 0;
  4481. $$.parms = 0;
  4482. $$.have_parms = 0;
  4483. }
  4484. | NOT idcolon {
  4485. $$.id = Char(NewStringf("~%s",$2));
  4486. $$.type = 0;
  4487. $$.parms = 0;
  4488. $$.have_parms = 0;
  4489. }
  4490. /* This generate a shift-reduce conflict with constructors */
  4491. | LPAREN idcolon RPAREN {
  4492. $$.id = Char($2);
  4493. $$.type = 0;
  4494. $$.parms = 0;
  4495. $$.have_parms = 0;
  4496. }
  4497. /*
  4498. | LPAREN AND idcolon RPAREN {
  4499. $$.id = Char($3);
  4500. $$.type = 0;
  4501. $$.parms = 0;
  4502. $$.have_parms = 0;
  4503. }
  4504. */
  4505. /* Technically, this should be LPAREN declarator RPAREN, but we get reduce/reduce conflicts */
  4506. | LPAREN pointer notso_direct_declarator RPAREN {
  4507. $$ = $3;
  4508. if ($$.type) {
  4509. SwigType_push($2,$$.type);
  4510. Delete($$.type);
  4511. }
  4512. $$.type = $2;
  4513. }
  4514. | LPAREN idcolon DSTAR notso_direct_declarator RPAREN {
  4515. SwigType *t;
  4516. $$ = $4;
  4517. t = NewStringEmpty();
  4518. SwigType_add_memberpointer(t,$2);
  4519. if ($$.type) {
  4520. SwigType_push(t,$$.type);
  4521. Delete($$.type);
  4522. }
  4523. $$.type = t;
  4524. }
  4525. | notso_direct_declarator LBRACKET RBRACKET {
  4526. SwigType *t;
  4527. $$ = $1;
  4528. t = NewStringEmpty();
  4529. SwigType_add_array(t,(char*)"");
  4530. if ($$.type) {
  4531. SwigType_push(t,$$.type);
  4532. Delete($$.type);
  4533. }
  4534. $$.type = t;
  4535. }
  4536. | notso_direct_declarator LBRACKET expr RBRACKET {
  4537. SwigType *t;
  4538. $$ = $1;
  4539. t = NewStringEmpty();
  4540. SwigType_add_array(t,$3.val);
  4541. if ($$.type) {
  4542. SwigType_push(t,$$.type);
  4543. Delete($$.type);
  4544. }
  4545. $$.type = t;
  4546. }
  4547. | notso_direct_declarator LPAREN parms RPAREN {
  4548. SwigType *t;
  4549. $$ = $1;
  4550. t = NewStringEmpty();
  4551. SwigType_add_function(t,$3);
  4552. if (!$$.have_parms) {
  4553. $$.parms = $3;
  4554. $$.have_parms = 1;
  4555. }
  4556. if (!$$.type) {
  4557. $$.type = t;
  4558. } else {
  4559. SwigType_push(t, $$.type);
  4560. Delete($$.type);
  4561. $$.type = t;
  4562. }
  4563. }
  4564. ;
  4565. direct_declarator : idcolon {
  4566. /* Note: This is non-standard C. Template declarator is allowed to follow an identifier */
  4567. $$.id = Char($1);
  4568. $$.type = 0;
  4569. $$.parms = 0;
  4570. $$.have_parms = 0;
  4571. }
  4572. | NOT idcolon {
  4573. $$.id = Char(NewStringf("~%s",$2));
  4574. $$.type = 0;
  4575. $$.parms = 0;
  4576. $$.have_parms = 0;
  4577. }
  4578. /* This generate a shift-reduce conflict with constructors */
  4579. /*
  4580. | LPAREN idcolon RPAREN {
  4581. $$.id = Char($2);
  4582. $$.type = 0;
  4583. $$.parms = 0;
  4584. $$.have_parms = 0;
  4585. }
  4586. */
  4587. /* Technically, this should be LPAREN declarator RPAREN, but we get reduce/reduce conflicts */
  4588. | LPAREN pointer direct_declarator RPAREN {
  4589. $$ = $3;
  4590. if ($$.type) {
  4591. SwigType_push($2,$$.type);
  4592. Delete($$.type);
  4593. }
  4594. $$.type = $2;
  4595. }
  4596. | LPAREN AND direct_declarator RPAREN {
  4597. $$ = $3;
  4598. if (!$$.type) {
  4599. $$.type = NewStringEmpty();
  4600. }
  4601. SwigType_add_reference($$.type);
  4602. }
  4603. | LPAREN idcolon DSTAR direct_declarator RPAREN {
  4604. SwigType *t;
  4605. $$ = $4;
  4606. t = NewStringEmpty();
  4607. SwigType_add_memberpointer(t,$2);
  4608. if ($$.type) {
  4609. SwigType_push(t,$$.type);
  4610. Delete($$.type);
  4611. }
  4612. $$.type = t;
  4613. }
  4614. | direct_declarator LBRACKET RBRACKET {
  4615. SwigType *t;
  4616. $$ = $1;
  4617. t = NewStringEmpty();
  4618. SwigType_add_array(t,(char*)"");
  4619. if ($$.type) {
  4620. SwigType_push(t,$$.type);
  4621. Delete($$.type);
  4622. }
  4623. $$.type = t;
  4624. }
  4625. | direct_declarator LBRACKET expr RBRACKET {
  4626. SwigType *t;
  4627. $$ = $1;
  4628. t = NewStringEmpty();
  4629. SwigType_add_array(t,$3.val);
  4630. if ($$.type) {
  4631. SwigType_push(t,$$.type);
  4632. Delete($$.type);
  4633. }
  4634. $$.type = t;
  4635. }
  4636. | direct_declarator LPAREN parms RPAREN {
  4637. SwigType *t;
  4638. $$ = $1;
  4639. t = NewStringEmpty();
  4640. SwigType_add_function(t,$3);
  4641. if (!$$.have_parms) {
  4642. $$.parms = $3;
  4643. $$.have_parms = 1;
  4644. }
  4645. if (!$$.type) {
  4646. $$.type = t;
  4647. } else {
  4648. SwigType_push(t, $$.type);
  4649. Delete($$.type);
  4650. $$.type = t;
  4651. }
  4652. }
  4653. ;
  4654. abstract_declarator : pointer {
  4655. $$.type = $1;
  4656. $$.id = 0;
  4657. $$.parms = 0;
  4658. $$.have_parms = 0;
  4659. }
  4660. | pointer direct_abstract_declarator {
  4661. $$ = $2;
  4662. SwigType_push($1,$2.type);
  4663. $$.type = $1;
  4664. Delete($2.type);
  4665. }
  4666. | pointer AND {
  4667. $$.type = $1;
  4668. SwigType_add_reference($$.type);
  4669. $$.id = 0;
  4670. $$.parms = 0;
  4671. $$.have_parms = 0;
  4672. }
  4673. | pointer AND direct_abstract_declarator {
  4674. $$ = $3;
  4675. SwigType_add_reference($1);
  4676. if ($$.type) {
  4677. SwigType_push($1,$$.type);
  4678. Delete($$.type);
  4679. }
  4680. $$.type = $1;
  4681. }
  4682. | direct_abstract_declarator {
  4683. $$ = $1;
  4684. }
  4685. | AND direct_abstract_declarator {
  4686. $$ = $2;
  4687. $$.type = NewStringEmpty();
  4688. SwigType_add_reference($$.type);
  4689. if ($2.type) {
  4690. SwigType_push($$.type,$2.type);
  4691. Delete($2.type);
  4692. }
  4693. }
  4694. | AND {
  4695. $$.id = 0;
  4696. $$.parms = 0;
  4697. $$.have_parms = 0;
  4698. $$.type = NewStringEmpty();
  4699. SwigType_add_reference($$.type);
  4700. }
  4701. | idcolon DSTAR {
  4702. $$.type = NewStringEmpty();
  4703. SwigType_add_memberpointer($$.type,$1);
  4704. $$.id = 0;
  4705. $$.parms = 0;
  4706. $$.have_parms = 0;
  4707. }
  4708. | pointer idcolon DSTAR {
  4709. SwigType *t = NewStringEmpty();
  4710. $$.type = $1;
  4711. $$.id = 0;
  4712. $$.parms = 0;
  4713. $$.have_parms = 0;
  4714. SwigType_add_memberpointer(t,$2);
  4715. SwigType_push($$.type,t);
  4716. Delete(t);
  4717. }
  4718. | pointer idcolon DSTAR direct_abstract_declarator {
  4719. $$ = $4;
  4720. SwigType_add_memberpointer($1,$2);
  4721. if ($$.type) {
  4722. SwigType_push($1,$$.type);
  4723. Delete($$.type);
  4724. }
  4725. $$.type = $1;
  4726. }
  4727. ;
  4728. direct_abstract_declarator : direct_abstract_declarator LBRACKET RBRACKET {
  4729. SwigType *t;
  4730. $$ = $1;
  4731. t = NewStringEmpty();
  4732. SwigType_add_array(t,(char*)"");
  4733. if ($$.type) {
  4734. SwigType_push(t,$$.type);
  4735. Delete($$.type);
  4736. }
  4737. $$.type = t;
  4738. }
  4739. | direct_abstract_declarator LBRACKET expr RBRACKET {
  4740. SwigType *t;
  4741. $$ = $1;
  4742. t = NewStringEmpty();
  4743. SwigType_add_array(t,$3.val);
  4744. if ($$.type) {
  4745. SwigType_push(t,$$.type);
  4746. Delete($$.type);
  4747. }
  4748. $$.type = t;
  4749. }
  4750. | LBRACKET RBRACKET {
  4751. $$.type = NewStringEmpty();
  4752. $$.id = 0;
  4753. $$.parms = 0;
  4754. $$.have_parms = 0;
  4755. SwigType_add_array($$.type,(char*)"");
  4756. }
  4757. | LBRACKET expr RBRACKET {
  4758. $$.type = NewStringEmpty();
  4759. $$.id = 0;
  4760. $$.parms = 0;
  4761. $$.have_parms = 0;
  4762. SwigType_add_array($$.type,$2.val);
  4763. }
  4764. | LPAREN abstract_declarator RPAREN {
  4765. $$ = $2;
  4766. }
  4767. | direct_abstract_declarator LPAREN parms RPAREN {
  4768. SwigType *t;
  4769. $$ = $1;
  4770. t = NewStringEmpty();
  4771. SwigType_add_function(t,$3);
  4772. if (!$$.type) {
  4773. $$.type = t;
  4774. } else {
  4775. SwigType_push(t,$$.type);
  4776. Delete($$.type);
  4777. $$.type = t;
  4778. }
  4779. if (!$$.have_parms) {
  4780. $$.parms = $3;
  4781. $$.have_parms = 1;
  4782. }
  4783. }
  4784. | LPAREN parms RPAREN {
  4785. $$.type = NewStringEmpty();
  4786. SwigType_add_function($$.type,$2);
  4787. $$.parms = $2;
  4788. $$.have_parms = 1;
  4789. $$.id = 0;
  4790. }
  4791. ;
  4792. pointer : STAR type_qualifier pointer {
  4793. $$ = NewStringEmpty();
  4794. SwigType_add_pointer($$);
  4795. SwigType_push($$,$2);
  4796. SwigType_push($$,$3);
  4797. Delete($3);
  4798. }
  4799. | STAR pointer {
  4800. $$ = NewStringEmpty();
  4801. SwigType_add_pointer($$);
  4802. SwigType_push($$,$2);
  4803. Delete($2);
  4804. }
  4805. | STAR type_qualifier {
  4806. $$ = NewStringEmpty();
  4807. SwigType_add_pointer($$);
  4808. SwigType_push($$,$2);
  4809. }
  4810. | STAR {
  4811. $$ = NewStringEmpty();
  4812. SwigType_add_pointer($$);
  4813. }
  4814. ;
  4815. type_qualifier : type_qualifier_raw {
  4816. $$ = NewStringEmpty();
  4817. if ($1) SwigType_add_qualifier($$,$1);
  4818. }
  4819. | type_qualifier_raw type_qualifier {
  4820. $$ = $2;
  4821. if ($1) SwigType_add_qualifier($$,$1);
  4822. }
  4823. ;
  4824. type_qualifier_raw : CONST_QUAL { $$ = "const"; }
  4825. | VOLATILE { $$ = "volatile"; }
  4826. | REGISTER { $$ = 0; }
  4827. ;
  4828. /* Data type must be a built in type or an identifier for user-defined types
  4829. This type can be preceded by a modifier. */
  4830. type : rawtype {
  4831. $$ = $1;
  4832. Replace($$,"typename ","", DOH_REPLACE_ANY);
  4833. }
  4834. ;
  4835. rawtype : type_qualifier type_right {
  4836. $$ = $2;
  4837. SwigType_push($$,$1);
  4838. }
  4839. | type_right { $$ = $1; }
  4840. | type_right type_qualifier {
  4841. $$ = $1;
  4842. SwigType_push($$,$2);
  4843. }
  4844. | type_qualifier type_right type_qualifier {
  4845. $$ = $2;
  4846. SwigType_push($$,$3);
  4847. SwigType_push($$,$1);
  4848. }
  4849. ;
  4850. type_right : primitive_type { $$ = $1;
  4851. /* Printf(stdout,"primitive = '%s'\n", $$);*/
  4852. }
  4853. | TYPE_BOOL { $$ = $1; }
  4854. | TYPE_VOID { $$ = $1; }
  4855. | TYPE_TYPEDEF template_decl { $$ = NewStringf("%s%s",$1,$2); }
  4856. | ENUM idcolon { $$ = NewStringf("enum %s", $2); }
  4857. | TYPE_RAW { $$ = $1; }
  4858. | idcolon {
  4859. $$ = $1;
  4860. }
  4861. | cpptype idcolon {
  4862. $$ = NewStringf("%s %s", $1, $2);
  4863. }
  4864. ;
  4865. primitive_type : primitive_type_list {
  4866. if (!$1.type) $1.type = NewString("int");
  4867. if ($1.us) {
  4868. $$ = NewStringf("%s %s", $1.us, $1.type);
  4869. Delete($1.us);
  4870. Delete($1.type);
  4871. } else {
  4872. $$ = $1.type;
  4873. }
  4874. if (Cmp($$,"signed int") == 0) {
  4875. Delete($$);
  4876. $$ = NewString("int");
  4877. } else if (Cmp($$,"signed long") == 0) {
  4878. Delete($$);
  4879. $$ = NewString("long");
  4880. } else if (Cmp($$,"signed short") == 0) {
  4881. Delete($$);
  4882. $$ = NewString("short");
  4883. } else if (Cmp($$,"signed long long") == 0) {
  4884. Delete($$);
  4885. $$ = NewString("long long");
  4886. }
  4887. }
  4888. ;
  4889. primitive_type_list : type_specifier {
  4890. $$ = $1;
  4891. }
  4892. | type_specifier primitive_type_list {
  4893. if ($1.us && $2.us) {
  4894. Swig_error(cparse_file, cparse_line, "Extra %s specifier.\n", $2.us);
  4895. }
  4896. $$ = $2;
  4897. if ($1.us) $$.us = $1.us;
  4898. if ($1.type) {
  4899. if (!$2.type) $$.type = $1.type;
  4900. else {
  4901. int err = 0;
  4902. if ((Cmp($1.type,"long") == 0)) {
  4903. if ((Cmp($2.type,"long") == 0) || (Strncmp($2.type,"double",6) == 0)) {
  4904. $$.type = NewStringf("long %s", $2.type);
  4905. } else if (Cmp($2.type,"int") == 0) {
  4906. $$.type = $1.type;
  4907. } else {
  4908. err = 1;
  4909. }
  4910. } else if ((Cmp($1.type,"short")) == 0) {
  4911. if (Cmp($2.type,"int") == 0) {
  4912. $$.type = $1.type;
  4913. } else {
  4914. err = 1;
  4915. }
  4916. } else if (Cmp($1.type,"int") == 0) {
  4917. $$.type = $2.type;
  4918. } else if (Cmp($1.type,"double") == 0) {
  4919. if (Cmp($2.type,"long") == 0) {
  4920. $$.type = NewString("long double");
  4921. } else if (Cmp($2.type,"complex") == 0) {
  4922. $$.type = NewString("double complex");
  4923. } else {
  4924. err = 1;
  4925. }
  4926. } else if (Cmp($1.type,"float") == 0) {
  4927. if (Cmp($2.type,"complex") == 0) {
  4928. $$.type = NewString("float complex");
  4929. } else {
  4930. err = 1;
  4931. }
  4932. } else if (Cmp($1.type,"complex") == 0) {
  4933. $$.type = NewStringf("%s complex", $2.type);
  4934. } else {
  4935. err = 1;
  4936. }
  4937. if (err) {
  4938. Swig_error(cparse_file, cparse_line, "Extra %s specifier.\n", $1.type);
  4939. }
  4940. }
  4941. }
  4942. }
  4943. ;
  4944. type_specifier : TYPE_INT {
  4945. $$.type = NewString("int");
  4946. $$.us = 0;
  4947. }
  4948. | TYPE_SHORT {
  4949. $$.type = NewString("short");
  4950. $$.us = 0;
  4951. }
  4952. | TYPE_LONG {
  4953. $$.type = NewString("long");
  4954. $$.us = 0;
  4955. }
  4956. | TYPE_CHAR {
  4957. $$.type = NewString("char");
  4958. $$.us = 0;
  4959. }
  4960. | TYPE_WCHAR {
  4961. $$.type = NewString("wchar_t");
  4962. $$.us = 0;
  4963. }
  4964. | TYPE_FLOAT {
  4965. $$.type = NewString("float");
  4966. $$.us = 0;
  4967. }
  4968. | TYPE_DOUBLE {
  4969. $$.type = NewString("double");
  4970. $$.us = 0;
  4971. }
  4972. | TYPE_SIGNED {
  4973. $$.us = NewString("signed");
  4974. $$.type = 0;
  4975. }
  4976. | TYPE_UNSIGNED {
  4977. $$.us = NewString("unsigned");
  4978. $$.type = 0;
  4979. }
  4980. | TYPE_COMPLEX {
  4981. $$.type = NewString("complex");
  4982. $$.us = 0;
  4983. }
  4984. | TYPE_NON_ISO_INT8 {
  4985. $$.type = NewString("__int8");
  4986. $$.us = 0;
  4987. }
  4988. | TYPE_NON_ISO_INT16 {
  4989. $$.type = NewString("__int16");
  4990. $$.us = 0;
  4991. }
  4992. | TYPE_NON_ISO_INT32 {
  4993. $$.type = NewString("__int32");
  4994. $$.us = 0;
  4995. }
  4996. | TYPE_NON_ISO_INT64 {
  4997. $$.type = NewString("__int64");
  4998. $$.us = 0;
  4999. }
  5000. ;
  5001. definetype : { /* scanner_check_typedef(); */ } expr {
  5002. $$ = $2;
  5003. if ($$.type == T_STRING) {
  5004. $$.rawval = NewStringf("\"%(escape)s\"",$$.val);
  5005. } else if ($$.type != T_CHAR) {
  5006. $$.rawval = 0;
  5007. }
  5008. $$.bitfield = 0;
  5009. $$.throws = 0;
  5010. $$.throwf = 0;
  5011. scanner_ignore_typedef();
  5012. }
  5013. /*
  5014. | string {
  5015. $$.val = NewString($1);
  5016. $$.rawval = NewStringf("\"%(escape)s\"",$$.val);
  5017. $$.type = T_STRING;
  5018. $$.bitfield = 0;
  5019. $$.throws = 0;
  5020. $$.throwf = 0;
  5021. }
  5022. */
  5023. ;
  5024. /* Some stuff for handling enums */
  5025. ename : ID { $$ = $1; }
  5026. | empty { $$ = (char *) 0;}
  5027. ;
  5028. enumlist : enumlist COMMA edecl {
  5029. /* Ignore if there is a trailing comma in the enum list */
  5030. if ($3) {
  5031. Node *leftSibling = Getattr($1,"_last");
  5032. if (!leftSibling) {
  5033. leftSibling=$1;
  5034. }
  5035. set_nextSibling(leftSibling,$3);
  5036. Setattr($1,"_last",$3);
  5037. }
  5038. $$ = $1;
  5039. }
  5040. | edecl {
  5041. $$ = $1;
  5042. if ($1) {
  5043. Setattr($1,"_last",$1);
  5044. }
  5045. }
  5046. ;
  5047. edecl : ID {
  5048. SwigType *type = NewSwigType(T_INT);
  5049. $$ = new_node("enumitem");
  5050. Setattr($$,"name",$1);
  5051. Setattr($$,"type",type);
  5052. SetFlag($$,"feature:immutable");
  5053. Delete(type);
  5054. }
  5055. | ID EQUAL etype {
  5056. $$ = new_node("enumitem");
  5057. Setattr($$,"name",$1);
  5058. Setattr($$,"enumvalue", $3.val);
  5059. if ($3.type == T_CHAR) {
  5060. SwigType *type = NewSwigType(T_CHAR);
  5061. Setattr($$,"value",NewStringf("\'%(escape)s\'", $3.val));
  5062. Setattr($$,"type",type);
  5063. Delete(type);
  5064. } else {
  5065. SwigType *type = NewSwigType(T_INT);
  5066. Setattr($$,"value",$1);
  5067. Setattr($$,"type",type);
  5068. Delete(type);
  5069. }
  5070. SetFlag($$,"feature:immutable");
  5071. }
  5072. | empty { $$ = 0; }
  5073. ;
  5074. etype : expr {
  5075. $$ = $1;
  5076. if (($$.type != T_INT) && ($$.type != T_UINT) &&
  5077. ($$.type != T_LONG) && ($$.type != T_ULONG) &&
  5078. ($$.type != T_SHORT) && ($$.type != T_USHORT) &&
  5079. ($$.type != T_SCHAR) && ($$.type != T_UCHAR) &&
  5080. ($$.type != T_CHAR)) {
  5081. Swig_error(cparse_file,cparse_line,"Type error. Expecting an int\n");
  5082. }
  5083. if ($$.type == T_CHAR) $$.type = T_INT;
  5084. }
  5085. ;
  5086. /* Arithmetic expressions. Used for constants, C++ templates, and other cool stuff. */
  5087. expr : valexpr { $$ = $1; }
  5088. | type {
  5089. Node *n;
  5090. $$.val = $1;
  5091. $$.type = T_INT;
  5092. /* Check if value is in scope */
  5093. n = Swig_symbol_clookup($1,0);
  5094. if (n) {
  5095. /* A band-aid for enum values used in expressions. */
  5096. if (Strcmp(nodeType(n),"enumitem") == 0) {
  5097. String *q = Swig_symbol_qualified(n);
  5098. if (q) {
  5099. $$.val = NewStringf("%s::%s", q, Getattr(n,"name"));
  5100. Delete(q);
  5101. }
  5102. }
  5103. }
  5104. }
  5105. ;
  5106. valexpr : exprnum { $$ = $1; }
  5107. | string {
  5108. $$.val = NewString($1);
  5109. $$.type = T_STRING;
  5110. }
  5111. | SIZEOF LPAREN type parameter_declarator RPAREN {
  5112. SwigType_push($3,$4.type);
  5113. $$.val = NewStringf("sizeof(%s)",SwigType_str($3,0));
  5114. $$.type = T_ULONG;
  5115. }
  5116. | exprcompound { $$ = $1; }
  5117. | CHARCONST {
  5118. $$.val = NewString($1);
  5119. if (Len($$.val)) {
  5120. $$.rawval = NewStringf("'%(escape)s'", $$.val);
  5121. } else {
  5122. $$.rawval = NewString("'\\0'");
  5123. }
  5124. $$.type = T_CHAR;
  5125. $$.bitfield = 0;
  5126. $$.throws = 0;
  5127. $$.throwf = 0;
  5128. }
  5129. /* grouping */
  5130. | LPAREN expr RPAREN %prec CAST {
  5131. $$.val = NewStringf("(%s)",$2.val);
  5132. $$.type = $2.type;
  5133. }
  5134. /* A few common casting operations */
  5135. | LPAREN expr RPAREN expr %prec CAST {
  5136. $$ = $4;
  5137. if ($4.type != T_STRING) {
  5138. switch ($2.type) {
  5139. case T_FLOAT:
  5140. case T_DOUBLE:
  5141. case T_LONGDOUBLE:
  5142. case T_FLTCPLX:
  5143. case T_DBLCPLX:
  5144. $$.val = NewStringf("(%s)%s", $2.val, $4.val); /* SwigType_str and decimal points don't mix! */
  5145. break;
  5146. default:
  5147. $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $4.val);
  5148. break;
  5149. }
  5150. }
  5151. }
  5152. | LPAREN expr pointer RPAREN expr %prec CAST {
  5153. $$ = $5;
  5154. if ($5.type != T_STRING) {
  5155. SwigType_push($2.val,$3);
  5156. $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val);
  5157. }
  5158. }
  5159. | LPAREN expr AND RPAREN expr %prec CAST {
  5160. $$ = $5;
  5161. if ($5.type != T_STRING) {
  5162. SwigType_add_reference($2.val);
  5163. $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val);
  5164. }
  5165. }
  5166. | LPAREN expr pointer AND RPAREN expr %prec CAST {
  5167. $$ = $6;
  5168. if ($6.type != T_STRING) {
  5169. SwigType_push($2.val,$3);
  5170. SwigType_add_reference($2.val);
  5171. $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $6.val);
  5172. }
  5173. }
  5174. | AND expr {
  5175. $$ = $2;
  5176. $$.val = NewStringf("&%s",$2.val);
  5177. }
  5178. | STAR expr {
  5179. $$ = $2;
  5180. $$.val = NewStringf("*%s",$2.val);
  5181. }
  5182. ;
  5183. exprnum : NUM_INT { $$ = $1; }
  5184. | NUM_FLOAT { $$ = $1; }
  5185. | NUM_UNSIGNED { $$ = $1; }
  5186. | NUM_LONG { $$ = $1; }
  5187. | NUM_ULONG { $$ = $1; }
  5188. | NUM_LONGLONG { $$ = $1; }
  5189. | NUM_ULONGLONG { $$ = $1; }
  5190. | NUM_BOOL { $$ = $1; }
  5191. ;
  5192. exprcompound : expr PLUS expr {
  5193. $$.val = NewStringf("%s+%s",$1.val,$3.val);
  5194. $$.type = promote($1.type,$3.type);
  5195. }
  5196. | expr MINUS expr {
  5197. $$.val = NewStringf("%s-%s",$1.val,$3.val);
  5198. $$.type = promote($1.type,$3.type);
  5199. }
  5200. | expr STAR expr {
  5201. $$.val = NewStringf("%s*%s",$1.val,$3.val);
  5202. $$.type = promote($1.type,$3.type);
  5203. }
  5204. | expr SLASH expr {
  5205. $$.val = NewStringf("%s/%s",$1.val,$3.val);
  5206. $$.type = promote($1.type,$3.type);
  5207. }
  5208. | expr MODULUS expr {
  5209. $$.val = NewStringf("%s%%%s",$1.val,$3.val);
  5210. $$.type = promote($1.type,$3.type);
  5211. }
  5212. | expr AND expr {
  5213. $$.val = NewStringf("%s&%s",$1.val,$3.val);
  5214. $$.type = promote($1.type,$3.type);
  5215. }
  5216. | expr OR expr {
  5217. $$.val = NewStringf("%s|%s",$1.val,$3.val);
  5218. $$.type = promote($1.type,$3.type);
  5219. }
  5220. | expr XOR expr {
  5221. $$.val = NewStringf("%s^%s",$1.val,$3.val);
  5222. $$.type = promote($1.type,$3.type);
  5223. }
  5224. | expr LSHIFT expr {
  5225. $$.val = NewStringf("%s << %s",$1.val,$3.val);
  5226. $$.type = promote_type($1.type);
  5227. }
  5228. | expr RSHIFT expr {
  5229. $$.val = NewStringf("%s >> %s",$1.val,$3.val);
  5230. $$.type = promote_type($1.type);
  5231. }
  5232. | expr LAND expr {
  5233. $$.val = NewStringf("%s&&%s",$1.val,$3.val);
  5234. $$.type = cparse_cplusplus ? T_BOOL : T_INT;
  5235. }
  5236. | expr LOR expr {
  5237. $$.val = NewStringf("%s||%s",$1.val,$3.val);
  5238. $$.type = cparse_cplusplus ? T_BOOL : T_INT;
  5239. }
  5240. | expr EQUALTO expr {
  5241. $$.val = NewStringf("%s==%s",$1.val,$3.val);
  5242. $$.type = cparse_cplusplus ? T_BOOL : T_INT;
  5243. }
  5244. | expr NOTEQUALTO expr {
  5245. $$.val = NewStringf("%s!=%s",$1.val,$3.val);
  5246. $$.type = cparse_cplusplus ? T_BOOL : T_INT;
  5247. }
  5248. /* Sadly this causes 2 reduce-reduce conflicts with templates. FIXME resolve these.
  5249. | expr GREATERTHAN expr {
  5250. $$.val = NewStringf("%s < %s", $1.val, $3.val);
  5251. $$.type = cparse_cplusplus ? T_BOOL : T_INT;
  5252. }
  5253. | expr LESSTHAN expr {
  5254. $$.val = NewStringf("%s > %s", $1.val, $3.val);
  5255. $$.type = cparse_cplusplus ? T_BOOL : T_INT;
  5256. }
  5257. */
  5258. | expr GREATERTHANOREQUALTO expr {
  5259. $$.val = NewStringf("%s >= %s", $1.val, $3.val);
  5260. $$.type = cparse_cplusplus ? T_BOOL : T_INT;
  5261. }
  5262. | expr LESSTHANOREQUALTO expr {
  5263. $$.val = NewStringf("%s <= %s", $1.val, $3.val);
  5264. $$.type = cparse_cplusplus ? T_BOOL : T_INT;
  5265. }
  5266. | expr QUESTIONMARK expr COLON expr %prec QUESTIONMARK {
  5267. $$.val = NewStringf("%s?%s:%s", $1.val, $3.val, $5.val);
  5268. /* This may not be exactly right, but is probably good enough
  5269. * for the purposes of parsing constant expressions. */
  5270. $$.type = promote($3.type, $5.type);
  5271. }
  5272. | MINUS expr %prec UMINUS {
  5273. $$.val = NewStringf("-%s",$2.val);
  5274. $$.type = $2.type;
  5275. }
  5276. | PLUS expr %prec UMINUS {
  5277. $$.val = NewStringf("+%s",$2.val);
  5278. $$.type = $2.type;
  5279. }
  5280. | NOT expr {
  5281. $$.val = NewStringf("~%s",$2.val);
  5282. $$.type = $2.type;
  5283. }
  5284. | LNOT expr {
  5285. $$.val = NewStringf("!%s",$2.val);
  5286. $$.type = T_INT;
  5287. }
  5288. | type LPAREN {
  5289. String *qty;
  5290. skip_balanced('(',')');
  5291. qty = Swig_symbol_type_qualify($1,0);
  5292. if (SwigType_istemplate(qty)) {
  5293. String *nstr = SwigType_namestr(qty);
  5294. Delete(qty);
  5295. qty = nstr;
  5296. }
  5297. $$.val = NewStringf("%s%s",qty,scanner_ccode);
  5298. Clear(scanner_ccode);
  5299. $$.type = T_INT;
  5300. Delete(qty);
  5301. }
  5302. ;
  5303. inherit : raw_inherit {
  5304. $$ = $1;
  5305. }
  5306. ;
  5307. raw_inherit : COLON { inherit_list = 1; } base_list { $$ = $3; inherit_list = 0; }
  5308. | empty { $$ = 0; }
  5309. ;
  5310. base_list : base_specifier {
  5311. Hash *list = NewHash();
  5312. Node *base = $1;
  5313. Node *name = Getattr(base,"name");
  5314. List *lpublic = NewList();
  5315. List *lprotected = NewList();
  5316. List *lprivate = NewList();
  5317. Setattr(list,"public",lpublic);
  5318. Setattr(list,"protected",lprotected);
  5319. Setattr(list,"private",lprivate);
  5320. Delete(lpublic);
  5321. Delete(lprotected);
  5322. Delete(lprivate);
  5323. Append(Getattr(list,Getattr(base,"access")),name);
  5324. $$ = list;
  5325. }
  5326. | base_list COMMA base_specifier {
  5327. Hash *list = $1;
  5328. Node *base = $3;
  5329. Node *name = Getattr(base,"name");
  5330. Append(Getattr(list,Getattr(base,"access")),name);
  5331. $$ = list;
  5332. }
  5333. ;
  5334. base_specifier : opt_virtual idcolon {
  5335. $$ = NewHash();
  5336. Setfile($$,cparse_file);
  5337. Setline($$,cparse_line);
  5338. Setattr($$,"name",$2);
  5339. if (last_cpptype && (Strcmp(last_cpptype,"struct") != 0)) {
  5340. Setattr($$,"access","private");
  5341. Swig_warning(WARN_PARSE_NO_ACCESS,cparse_file,cparse_line,
  5342. "No access specifier given for base class %s (ignored).\n",$2);
  5343. } else {
  5344. Setattr($$,"access","public");
  5345. }
  5346. }
  5347. | opt_virtual access_specifier opt_virtual idcolon {
  5348. $$ = NewHash();
  5349. Setfile($$,cparse_file);
  5350. Setline($$,cparse_line);
  5351. Setattr($$,"name",$4);
  5352. Setattr($$,"access",$2);
  5353. if (Strcmp($2,"public") != 0) {
  5354. Swig_warning(WARN_PARSE_PRIVATE_INHERIT, cparse_file,
  5355. cparse_line,"%s inheritance ignored.\n", $2);
  5356. }
  5357. }
  5358. ;
  5359. access_specifier : PUBLIC { $$ = (char*)"public"; }
  5360. | PRIVATE { $$ = (char*)"private"; }
  5361. | PROTECTED { $$ = (char*)"protected"; }
  5362. ;
  5363. templcpptype : CLASS {
  5364. $$ = (char*)"class";
  5365. if (!inherit_list) last_cpptype = $$;
  5366. }
  5367. | TYPENAME {
  5368. $$ = (char *)"typename";
  5369. if (!inherit_list) last_cpptype = $$;
  5370. }
  5371. ;
  5372. cpptype : templcpptype {
  5373. $$ = $1;
  5374. }
  5375. | STRUCT {
  5376. $$ = (char*)"struct";
  5377. if (!inherit_list) last_cpptype = $$;
  5378. }
  5379. | UNION {
  5380. $$ = (char*)"union";
  5381. if (!inherit_list) last_cpptype = $$;
  5382. }
  5383. ;
  5384. opt_virtual : VIRTUAL
  5385. | empty
  5386. ;
  5387. cpp_const : type_qualifier {
  5388. $$.qualifier = $1;
  5389. $$.throws = 0;
  5390. $$.throwf = 0;
  5391. }
  5392. | THROW LPAREN parms RPAREN {
  5393. $$.qualifier = 0;
  5394. $$.throws = $3;
  5395. $$.throwf = NewString("1");
  5396. }
  5397. | type_qualifier THROW LPAREN parms RPAREN {
  5398. $$.qualifier = $1;
  5399. $$.throws = $4;
  5400. $$.throwf = NewString("1");
  5401. }
  5402. | empty {
  5403. $$.qualifier = 0;
  5404. $$.throws = 0;
  5405. $$.throwf = 0;
  5406. }
  5407. ;
  5408. ctor_end : cpp_const ctor_initializer SEMI {
  5409. Clear(scanner_ccode);
  5410. $$.have_parms = 0;
  5411. $$.defarg = 0;
  5412. $$.throws = $1.throws;
  5413. $$.throwf = $1.throwf;
  5414. }
  5415. | cpp_const ctor_initializer LBRACE {
  5416. skip_balanced('{','}');
  5417. $$.have_parms = 0;
  5418. $$.defarg = 0;
  5419. $$.throws = $1.throws;
  5420. $$.throwf = $1.throwf;
  5421. }
  5422. | LPAREN parms RPAREN SEMI {
  5423. Clear(scanner_ccode);
  5424. $$.parms = $2;
  5425. $$.have_parms = 1;
  5426. $$.defarg = 0;
  5427. $$.throws = 0;
  5428. $$.throwf = 0;
  5429. }
  5430. | LPAREN parms RPAREN LBRACE {
  5431. skip_balanced('{','}');
  5432. $$.parms = $2;
  5433. $$.have_parms = 1;
  5434. $$.defarg = 0;
  5435. $$.throws = 0;
  5436. $$.throwf = 0;
  5437. }
  5438. | EQUAL definetype SEMI {
  5439. $$.have_parms = 0;
  5440. $$.defarg = $2.val;
  5441. $$.throws = 0;
  5442. $$.throwf = 0;
  5443. }
  5444. ;
  5445. ctor_initializer : COLON mem_initializer_list
  5446. | empty
  5447. ;
  5448. mem_initializer_list : mem_initializer
  5449. | mem_initializer_list COMMA mem_initializer
  5450. ;
  5451. mem_initializer : idcolon LPAREN {
  5452. skip_balanced('(',')');
  5453. Clear(scanner_ccode);
  5454. }
  5455. ;
  5456. template_decl : LESSTHAN valparms GREATERTHAN {
  5457. String *s = NewStringEmpty();
  5458. SwigType_add_template(s,$2);
  5459. $$ = Char(s);
  5460. scanner_last_id(1);
  5461. }
  5462. | empty { $$ = (char*)""; }
  5463. ;
  5464. idstring : ID { $$ = $1; }
  5465. | string { $$ = $1; }
  5466. ;
  5467. idstringopt : idstring { $$ = $1; }
  5468. | empty { $$ = 0; }
  5469. ;
  5470. idcolon : idtemplate idcolontail {
  5471. $$ = 0;
  5472. if (!$$) $$ = NewStringf("%s%s", $1,$2);
  5473. Delete($2);
  5474. }
  5475. | NONID DCOLON idtemplate idcolontail {
  5476. $$ = NewStringf("::%s%s",$3,$4);
  5477. Delete($4);
  5478. }
  5479. | idtemplate {
  5480. $$ = NewString($1);
  5481. }
  5482. | NONID DCOLON idtemplate {
  5483. $$ = NewStringf("::%s",$3);
  5484. }
  5485. | OPERATOR {
  5486. $$ = NewString($1);
  5487. }
  5488. | NONID DCOLON OPERATOR {
  5489. $$ = NewStringf("::%s",$3);
  5490. }
  5491. ;
  5492. idcolontail : DCOLON idtemplate idcolontail {
  5493. $$ = NewStringf("::%s%s",$2,$3);
  5494. Delete($3);
  5495. }
  5496. | DCOLON idtemplate {
  5497. $$ = NewStringf("::%s",$2);
  5498. }
  5499. | DCOLON OPERATOR {
  5500. $$ = NewStringf("::%s",$2);
  5501. }
  5502. /* | DCOLON COPERATOR {
  5503. $$ = NewString($2);
  5504. } */
  5505. | DCNOT idtemplate {
  5506. $$ = NewStringf("::~%s",$2);
  5507. }
  5508. ;
  5509. idtemplate : ID template_decl {
  5510. $$ = NewStringf("%s%s",$1,$2);
  5511. /* if (Len($2)) {
  5512. scanner_last_id(1);
  5513. } */
  5514. }
  5515. ;
  5516. /* Identifier, but no templates */
  5517. idcolonnt : ID idcolontailnt {
  5518. $$ = 0;
  5519. if (!$$) $$ = NewStringf("%s%s", $1,$2);
  5520. Delete($2);
  5521. }
  5522. | NONID DCOLON ID idcolontailnt {
  5523. $$ = NewStringf("::%s%s",$3,$4);
  5524. Delete($4);
  5525. }
  5526. | ID {
  5527. $$ = NewString($1);
  5528. }
  5529. | NONID DCOLON ID {
  5530. $$ = NewStringf("::%s",$3);
  5531. }
  5532. | OPERATOR {
  5533. $$ = NewString($1);
  5534. }
  5535. | NONID DCOLON OPERATOR {
  5536. $$ = NewStringf("::%s",$3);
  5537. }
  5538. ;
  5539. idcolontailnt : DCOLON ID idcolontailnt {
  5540. $$ = NewStringf("::%s%s",$2,$3);
  5541. Delete($3);
  5542. }
  5543. | DCOLON ID {
  5544. $$ = NewStringf("::%s",$2);
  5545. }
  5546. | DCOLON OPERATOR {
  5547. $$ = NewStringf("::%s",$2);
  5548. }
  5549. | DCNOT ID {
  5550. $$ = NewStringf("::~%s",$2);
  5551. }
  5552. ;
  5553. /* Concatenated strings */
  5554. string : string STRING {
  5555. $$ = (char *) malloc(strlen($1)+strlen($2)+1);
  5556. strcpy($$,$1);
  5557. strcat($$,$2);
  5558. }
  5559. | STRING { $$ = $1;}
  5560. ;
  5561. stringbrace : string {
  5562. $$ = NewString($1);
  5563. }
  5564. | LBRACE {
  5565. skip_balanced('{','}');
  5566. $$ = NewString(scanner_ccode);
  5567. }
  5568. | HBLOCK {
  5569. $$ = $1;
  5570. }
  5571. ;
  5572. options : LPAREN kwargs RPAREN {
  5573. Hash *n;
  5574. $$ = NewHash();
  5575. n = $2;
  5576. while(n) {
  5577. String *name, *value;
  5578. name = Getattr(n,"name");
  5579. value = Getattr(n,"value");
  5580. if (!value) value = (String *) "1";
  5581. Setattr($$,name, value);
  5582. n = nextSibling(n);
  5583. }
  5584. }
  5585. | empty { $$ = 0; };
  5586. /* Keyword arguments */
  5587. kwargs : idstring EQUAL stringnum {
  5588. $$ = NewHash();
  5589. Setattr($$,"name",$1);
  5590. Setattr($$,"value",$3);
  5591. }
  5592. | idstring EQUAL stringnum COMMA kwargs {
  5593. $$ = NewHash();
  5594. Setattr($$,"name",$1);
  5595. Setattr($$,"value",$3);
  5596. set_nextSibling($$,$5);
  5597. }
  5598. | idstring {
  5599. $$ = NewHash();
  5600. Setattr($$,"name",$1);
  5601. }
  5602. | idstring COMMA kwargs {
  5603. $$ = NewHash();
  5604. Setattr($$,"name",$1);
  5605. set_nextSibling($$,$3);
  5606. }
  5607. | idstring EQUAL stringtype {
  5608. $$ = $3;
  5609. Setattr($$,"name",$1);
  5610. }
  5611. | idstring EQUAL stringtype COMMA kwargs {
  5612. $$ = $3;
  5613. Setattr($$,"name",$1);
  5614. set_nextSibling($$,$5);
  5615. }
  5616. ;
  5617. stringnum : string {
  5618. $$ = $1;
  5619. }
  5620. | exprnum {
  5621. $$ = Char($1.val);
  5622. }
  5623. ;
  5624. empty : ;
  5625. %%
  5626. SwigType *Swig_cparse_type(String *s) {
  5627. String *ns;
  5628. ns = NewStringf("%s;",s);
  5629. Seek(ns,0,SEEK_SET);
  5630. scanner_file(ns);
  5631. top = 0;
  5632. scanner_next_token(PARSETYPE);
  5633. yyparse();
  5634. /* Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */
  5635. return top;
  5636. }
  5637. Parm *Swig_cparse_parm(String *s) {
  5638. String *ns;
  5639. ns = NewStringf("%s;",s);
  5640. Seek(ns,0,SEEK_SET);
  5641. scanner_file(ns);
  5642. top = 0;
  5643. scanner_next_token(PARSEPARM);
  5644. yyparse();
  5645. /* Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */
  5646. Delete(ns);
  5647. return top;
  5648. }
  5649. ParmList *Swig_cparse_parms(String *s) {
  5650. String *ns;
  5651. char *cs = Char(s);
  5652. if (cs && cs[0] != '(') {
  5653. ns = NewStringf("(%s);",s);
  5654. } else {
  5655. ns = NewStringf("%s;",s);
  5656. }
  5657. Seek(ns,0,SEEK_SET);
  5658. scanner_file(ns);
  5659. top = 0;
  5660. scanner_next_token(PARSEPARMS);
  5661. yyparse();
  5662. /* Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */
  5663. return top;
  5664. }