swig/Source/CParse/templ.c
Maciej Drwal e058e1f42f Merged revisions 10498-10499,10503-10504,10506,10508,10511,10515-10516,10518-10519,10527,10530-10531,10536-10537,10539-10552,10558-10568,10574-10580,10582,10584,10588-10589,10594 via svnmerge from
https://swig.svn.sourceforge.net/svnroot/swig/trunk

........
  r10498 | talby | 2008-05-26 22:09:56 +0200 (Pn, 26 maj 2008) | 2 lines
  
  run test cases in the Perl set by the --with-perl5 configure option.
........
  r10499 | talby | 2008-05-26 23:04:06 +0200 (Pn, 26 maj 2008) | 3 lines
  
  The perl5 minherit runtime test will work better if the classes are 
  actually built under SWIGPERL.
........
  r10503 | wsfulton | 2008-05-28 11:44:37 +0200 (Śr, 28 maj 2008) | 1 line
  
  Fix variable wrappers when using -proxy. Patch from Jan Jezabek
........
  r10504 | bhy | 2008-05-28 19:27:48 +0200 (Śr, 28 maj 2008) | 2 lines
  
  Fixed SF #1971977:  typo in pycontainer.swg (related to -extranative option)
........
  r10506 | wsfulton | 2008-05-29 02:45:28 +0200 (Cz, 29 maj 2008) | 1 line
  
  Fix variable wrappers when using -noproxy
........
  r10508 | bhy | 2008-05-30 15:53:33 +0200 (Pt, 30 maj 2008) | 1 line
  
  Fixed SF #1976978, apply the macros for primitive types to std::wstring
........
  r10511 | olly | 2008-05-30 18:11:27 +0200 (Pt, 30 maj 2008) | 4 lines
  
  Fix typo in handling of /*@SWIG[...]*/ comments in the scanner.  This just
  meant we were only actually looking for /*@SWI at the start of the comment, so
  was pretty harmless in practice.
........
  r10515 | wsfulton | 2008-06-02 22:10:40 +0200 (Pn, 02 cze 2008) | 1 line
  
  Fix samename testcase for c# and java
........
  r10516 | wsfulton | 2008-06-02 22:15:39 +0200 (Pn, 02 cze 2008) | 1 line
  
  Fix enums when using -noproxy
........
  r10518 | bhy | 2008-06-07 13:20:07 +0200 (So, 07 cze 2008) | 4 lines
  
  Added a test case for keyword renaming.
  Now it works for Python in SWIG's -c++ mode,
  but in C mode it doesn't work! (you can try with make keyword_rename.ctest)
........
  r10519 | bhy | 2008-06-07 15:40:51 +0200 (So, 07 cze 2008) | 1 line
  
  fixed keyword_rename.ctest tese case, caused by a mistake in Swig/naming.c
........
  r10527 | mgossage | 2008-06-17 04:57:15 +0200 (Wt, 17 cze 2008) | 1 line
  
  [lua] bugfix 1938142 (bool& and bool* support)
........
  r10530 | wsfulton | 2008-06-19 22:02:13 +0200 (Cz, 19 cze 2008) | 1 line
  
  Add R keyword support. Rename keywords for successful compilation of Java and C# code. More consistent keyword warnings across the different languages.
........
  r10531 | wsfulton | 2008-06-19 23:15:48 +0200 (Cz, 19 cze 2008) | 1 line
  
  add complete list of R reserved words
........
  r10536 | wsfulton | 2008-06-21 13:35:33 +0200 (So, 21 cze 2008) | 1 line
  
  better terminology for static types
........
  r10537 | wsfulton | 2008-06-21 13:42:48 +0200 (So, 21 cze 2008) | 1 line
  
  remove raise as keyword test- it conflicts with _raise in LIBCMT on windows
........
  r10539 | wsfulton | 2008-06-21 17:21:29 +0200 (So, 21 cze 2008) | 1 line
  
  Lua example warning removal fixes for vc++
........
  r10540 | wsfulton | 2008-06-21 17:23:02 +0200 (So, 21 cze 2008) | 1 line
  
  Remove some vc++ /W4 warnings
........
  r10541 | wsfulton | 2008-06-21 18:04:55 +0200 (So, 21 cze 2008) | 1 line
  
  minor vc++ /W4 warning fixes
........
  r10542 | wsfulton | 2008-06-21 21:07:51 +0200 (So, 21 cze 2008) | 1 line
  
  'byte' is already used in Ruby on windows, so use another keyword
........
  r10543 | wsfulton | 2008-06-21 22:45:32 +0200 (So, 21 cze 2008) | 1 line
  
  Fix crashing in the Ruby reject method in the STL wrappers
........
  r10544 | wsfulton | 2008-06-21 22:48:28 +0200 (So, 21 cze 2008) | 1 line
  
  Fix crashing in the Ruby reject method in the STL wrappers
........
  r10545 | wsfulton | 2008-06-21 22:49:10 +0200 (So, 21 cze 2008) | 1 line
  
  remove unnecessary variable int the char **STRING_ARRAY out typemap
........
  r10546 | wsfulton | 2008-06-21 23:07:49 +0200 (So, 21 cze 2008) | 1 line
  
  Fix Ruby C++ example dependencies in dsp files
........
  r10547 | wsfulton | 2008-06-22 00:25:36 +0200 (N, 22 cze 2008) | 1 line
  
  Fix unused parameter warnings in python when using gcc's -W -Wall options
........
  r10548 | wsfulton | 2008-06-22 00:26:35 +0200 (N, 22 cze 2008) | 1 line
  
  Fix virtual destructor
........
  r10549 | wsfulton | 2008-06-22 01:25:20 +0200 (N, 22 cze 2008) | 1 line
  
  various warning fixes
........
  r10550 | wsfulton | 2008-06-22 02:09:11 +0200 (N, 22 cze 2008) | 1 line
  
  Another fix for the JVM hanging on exit problem when using directors
........
  r10551 | wsfulton | 2008-06-22 02:09:51 +0200 (N, 22 cze 2008) | 1 line
  
  documentation sections update
........
  r10552 | wsfulton | 2008-06-22 02:18:10 +0200 (N, 22 cze 2008) | 1 line
  
  more docs on defining macros for the thread hanging problem
........
  r10558 | wsfulton | 2008-06-22 23:30:20 +0200 (N, 22 cze 2008) | 1 line
  
  fix unused parms in last commit for C code
........
  r10559 | wsfulton | 2008-06-23 00:12:43 +0200 (Pn, 23 cze 2008) | 1 line
  
  Suppress unused methods warning for VC++
........
  r10560 | wsfulton | 2008-06-23 22:26:07 +0200 (Pn, 23 cze 2008) | 1 line
  
  fix partialcheck-test-suite and parallel make for r, chicken, tcl and php
........
  r10561 | wsfulton | 2008-06-23 22:39:41 +0200 (Pn, 23 cze 2008) | 1 line
  
  correct message display when running the partialcheck-test-suite make target
........
  r10562 | wsfulton | 2008-06-23 23:14:53 +0200 (Pn, 23 cze 2008) | 1 line
  
  fix typo
........
  r10563 | olly | 2008-06-23 23:23:54 +0200 (Pn, 23 cze 2008) | 3 lines
  
  Fix bad use of Python API (untested, since I can't even compile this code on
  x86-64!)
........
  r10564 | olly | 2008-06-24 00:58:03 +0200 (Wt, 24 cze 2008) | 3 lines
  
  [PHP] Fix segfault when wrapping a non-class function marked with
  %newobject (testcase char_strings).
........
  r10565 | olly | 2008-06-24 02:27:34 +0200 (Wt, 24 cze 2008) | 3 lines
  
  [PHP] Fix assertion failure when handling %typemap(in,numinputs=0)
  (testcase ignore_parameter).
........
  r10566 | olly | 2008-06-24 02:33:08 +0200 (Wt, 24 cze 2008) | 2 lines
  
  [PHP] Fix typemap_namespace.i to not try to copy a non-existent typemap.
........
  r10567 | olly | 2008-06-24 02:41:07 +0200 (Wt, 24 cze 2008) | 3 lines
  
  Clean up dead and unused code in SwigToPhpType(), and rename to
  GetShadowReturnType().
........
  r10568 | olly | 2008-06-24 02:42:29 +0200 (Wt, 24 cze 2008) | 2 lines
  
  Fix cosmetic typo in string constant.
........
  r10574 | wsfulton | 2008-06-24 22:10:28 +0200 (Wt, 24 cze 2008) | 1 line
  
  zap last entry
........
  r10575 | wsfulton | 2008-06-24 22:11:46 +0200 (Wt, 24 cze 2008) | 1 line
  
  variable name changes to remove php keywords
........
  r10576 | wsfulton | 2008-06-24 22:12:08 +0200 (Wt, 24 cze 2008) | 1 line
  
  variable name hiding fix
........
  r10577 | wsfulton | 2008-06-24 22:12:43 +0200 (Wt, 24 cze 2008) | 1 line
  
  More info about numobjects added
........
  r10578 | wsfulton | 2008-06-24 22:13:41 +0200 (Wt, 24 cze 2008) | 1 line
  
  update for 1.3.36 release
........
  r10579 | wsfulton | 2008-06-24 23:48:46 +0200 (Wt, 24 cze 2008) | 1 line
  
  remove deprecated -c commandline option (runtime library generation)
........
  r10580 | wsfulton | 2008-06-24 23:53:12 +0200 (Wt, 24 cze 2008) | 1 line
  
  correct comment about deprecated option
........
  r10582 | wsfulton | 2008-06-25 01:00:27 +0200 (Śr, 25 cze 2008) | 1 line
  
  use rsync and ssh to upload releases to SourceForge as ftp no longer works
........
  r10584 | wsfulton | 2008-06-25 01:24:48 +0200 (Śr, 25 cze 2008) | 1 line
  
  correction for 1.3.36
........
  r10588 | wsfulton | 2008-06-25 02:16:04 +0200 (Śr, 25 cze 2008) | 1 line
  
  section update
........
  r10589 | wsfulton | 2008-06-25 02:16:40 +0200 (Śr, 25 cze 2008) | 1 line
  
  bump version to 1.3.37
........
  r10594 | wsfulton | 2008-06-26 20:33:06 +0200 (Cz, 26 cze 2008) | 1 line
  
  correct typo in first entry about %fragment
........


git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2008-maciekd@10606 626c5289-ae23-0410-ae9c-e8d60b6d4f22
2008-06-28 23:26:18 +00:00

672 lines
18 KiB
C

/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* templ.c
*
* Expands a template into a specialized version.
* ----------------------------------------------------------------------------- */
char cvsroot_templ_c[] = "$Id$";
#include "swig.h"
#include "cparse.h"
static int template_debug = 0;
String *baselists[3];
void SwigType_template_init() {
baselists[0] = "baselist";
baselists[1] = "protectedbaselist";
baselists[2] = "privatebaselist";
}
static void add_parms(ParmList *p, List *patchlist, List *typelist) {
while (p) {
SwigType *ty = Getattr(p, "type");
SwigType *val = Getattr(p, "value");
Append(typelist, ty);
Append(typelist, val);
Append(patchlist, val);
p = nextSibling(p);
}
}
void Swig_cparse_debug_templates(int x) {
template_debug = x;
}
/* -----------------------------------------------------------------------------
* cparse_template_expand()
*
* Expands a template node into a specialized version. This is done by
* patching typenames and other aspects of the node according to a list of
* template parameters
* ----------------------------------------------------------------------------- */
static int cparse_template_expand(Node *n, String *tname, String *rname, String *templateargs, List *patchlist, List *typelist, List *cpatchlist) {
static int expanded = 0;
int ret;
String *nodeType;
if (!n)
return 0;
nodeType = nodeType(n);
if (Getattr(n, "error"))
return 0;
if (Equal(nodeType, "template")) {
/* Change the node type back to normal */
if (!expanded) {
expanded = 1;
set_nodeType(n, Getattr(n, "templatetype"));
ret = cparse_template_expand(n, tname, rname, templateargs, patchlist, typelist, cpatchlist);
expanded = 0;
return ret;
} else {
/* Called when template appears inside another template */
/* Member templates */
set_nodeType(n, Getattr(n, "templatetype"));
ret = cparse_template_expand(n, tname, rname, templateargs, patchlist, typelist, cpatchlist);
set_nodeType(n, "template");
return ret;
}
} else if (Equal(nodeType, "cdecl")) {
/* A simple C declaration */
SwigType *t, *v, *d;
String *code;
t = Getattr(n, "type");
v = Getattr(n, "value");
d = Getattr(n, "decl");
code = Getattr(n, "code");
Append(typelist, t);
Append(typelist, d);
Append(patchlist, v);
Append(cpatchlist, code);
if (Getattr(n, "conversion_operator")) {
Append(cpatchlist, Getattr(n, "name"));
if (Getattr(n, "sym:name")) {
Append(cpatchlist, Getattr(n, "sym:name"));
}
}
add_parms(Getattr(n, "parms"), cpatchlist, typelist);
add_parms(Getattr(n, "throws"), cpatchlist, typelist);
} else if (Equal(nodeType, "class")) {
/* Patch base classes */
{
int b = 0;
for (b = 0; b < 3; ++b) {
List *bases = Getattr(n, baselists[b]);
if (bases) {
int i;
int ilen = Len(bases);
for (i = 0; i < ilen; i++) {
String *name = Copy(Getitem(bases, i));
Setitem(bases, i, name);
Append(typelist, name);
}
}
}
}
/* Patch children */
{
Node *cn = firstChild(n);
while (cn) {
cparse_template_expand(cn, tname, rname, templateargs, patchlist, typelist, cpatchlist);
cn = nextSibling(cn);
}
}
} else if (Equal(nodeType, "constructor")) {
String *name = Getattr(n, "name");
if (!(Getattr(n, "templatetype"))) {
String *symname;
String *stripped_name = SwigType_templateprefix(name);
if (Strstr(tname, stripped_name)) {
Replaceid(name, stripped_name, tname);
}
Delete(stripped_name);
symname = Getattr(n, "sym:name");
if (symname) {
stripped_name = SwigType_templateprefix(symname);
if (Strstr(tname, stripped_name)) {
Replaceid(symname, stripped_name, tname);
}
Delete(stripped_name);
}
if (strchr(Char(name), '<')) {
Append(patchlist, Getattr(n, "name"));
} else {
Append(name, templateargs);
}
name = Getattr(n, "sym:name");
if (name) {
if (strchr(Char(name), '<')) {
Clear(name);
Append(name, rname);
} else {
String *tmp = Copy(name);
Replace(tmp, tname, rname, DOH_REPLACE_ANY);
Clear(name);
Append(name, tmp);
Delete(tmp);
}
}
/* Setattr(n,"sym:name",name); */
}
Append(cpatchlist, Getattr(n, "code"));
Append(typelist, Getattr(n, "decl"));
add_parms(Getattr(n, "parms"), cpatchlist, typelist);
add_parms(Getattr(n, "throws"), cpatchlist, typelist);
} else if (Equal(nodeType, "destructor")) {
String *name = Getattr(n, "name");
if (name && strchr(Char(name), '<')) {
Append(patchlist, Getattr(n, "name"));
} else {
Append(name, templateargs);
}
name = Getattr(n, "sym:name");
if (name && strchr(Char(name), '<')) {
String *sn = Copy(tname);
Setattr(n, "sym:name", sn);
Delete(sn);
} else {
Replace(name, tname, rname, DOH_REPLACE_ANY);
}
/* Setattr(n,"sym:name",name); */
Append(cpatchlist, Getattr(n, "code"));
} else if (Equal(nodeType, "using")) {
String *uname = Getattr(n, "uname");
if (uname && strchr(Char(uname), '<')) {
Append(patchlist, uname);
}
if (Getattr(n, "namespace")) {
/* Namespace link. This is nasty. Is other namespace defined? */
}
} else {
/* Look for obvious parameters */
Node *cn;
Append(cpatchlist, Getattr(n, "code"));
Append(typelist, Getattr(n, "type"));
Append(typelist, Getattr(n, "decl"));
add_parms(Getattr(n, "parms"), cpatchlist, typelist);
add_parms(Getattr(n, "kwargs"), cpatchlist, typelist);
add_parms(Getattr(n, "pattern"), cpatchlist, typelist);
add_parms(Getattr(n, "throws"), cpatchlist, typelist);
cn = firstChild(n);
while (cn) {
cparse_template_expand(cn, tname, rname, templateargs, patchlist, typelist, cpatchlist);
cn = nextSibling(cn);
}
}
return 0;
}
static
String *partial_arg(String *s, String *p) {
char *c;
char *cp = Char(p);
String *prefix;
String *newarg;
/* Find the prefix on the partial argument */
c = strchr(cp, '$');
if (!c) {
return Copy(s);
}
prefix = NewStringWithSize(cp, c - cp);
newarg = Copy(s);
Replace(newarg, prefix, "", DOH_REPLACE_ANY | DOH_REPLACE_FIRST);
Delete(prefix);
return newarg;
}
/* -----------------------------------------------------------------------------
* Swig_cparse_template_expand()
* ----------------------------------------------------------------------------- */
int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab *tscope) {
List *patchlist, *cpatchlist, *typelist;
String *templateargs;
String *tname;
String *iname;
String *tbase;
patchlist = NewList();
cpatchlist = NewList();
typelist = NewList();
{
String *tmp = NewStringEmpty();
if (tparms) {
SwigType_add_template(tmp, tparms);
}
templateargs = Copy(tmp);
Delete(tmp);
}
tname = Copy(Getattr(n, "name"));
tbase = Swig_scopename_last(tname);
/* Look for partial specialization matching */
if (Getattr(n, "partialargs")) {
Parm *p, *tp;
ParmList *ptargs = SwigType_function_parms(Getattr(n, "partialargs"));
p = ptargs;
tp = tparms;
while (p && tp) {
SwigType *ptype;
SwigType *tptype;
SwigType *partial_type;
ptype = Getattr(p, "type");
tptype = Getattr(tp, "type");
if (ptype && tptype) {
partial_type = partial_arg(tptype, ptype);
/* Printf(stdout,"partial '%s' '%s' ---> '%s'\n", tptype, ptype, partial_type); */
Setattr(tp, "type", partial_type);
Delete(partial_type);
}
p = nextSibling(p);
tp = nextSibling(tp);
}
assert(ParmList_len(ptargs) == ParmList_len(tparms));
Delete(ptargs);
}
/*
Parm *p = tparms;
while (p) {
Printf(stdout, "tparm: '%s' '%s' '%s'\n", Getattr(p, "name"), Getattr(p, "type"), Getattr(p, "value"));
p = nextSibling(p);
}
*/
/* Printf(stdout,"targs = '%s'\n", templateargs);
Printf(stdout,"rname = '%s'\n", rname);
Printf(stdout,"tname = '%s'\n", tname); */
cparse_template_expand(n, tname, rname, templateargs, patchlist, typelist, cpatchlist);
/* Set the name */
{
String *name = Getattr(n, "name");
if (name) {
Append(name, templateargs);
}
iname = name;
}
/* Patch all of the types */
{
Parm *tp = Getattr(n, "templateparms");
Parm *p = tparms;
/* Printf(stdout,"%s\n", ParmList_str_defaultargs(tp)); */
if (tp) {
Symtab *tsdecl = Getattr(n, "sym:symtab");
while (p && tp) {
String *name, *value, *valuestr, *tydef, *tmp, *tmpr;
int sz, i;
String *dvalue = 0;
String *qvalue = 0;
name = Getattr(tp, "name");
value = Getattr(p, "value");
tydef = Getattr(p, "typedef");
if (name) {
if (!value)
value = Getattr(p, "type");
qvalue = Swig_symbol_typedef_reduce(value, tsdecl);
dvalue = Swig_symbol_type_qualify(qvalue, tsdecl);
if (SwigType_istemplate(dvalue)) {
String *ty = Swig_symbol_template_deftype(dvalue, tscope);
Delete(dvalue);
dvalue = ty;
}
assert(dvalue);
valuestr = SwigType_str(dvalue, 0);
/* Need to patch default arguments */
{
Parm *rp = nextSibling(p);
while (rp) {
String *rvalue = Getattr(rp, "value");
if (rvalue) {
Replace(rvalue, name, dvalue, DOH_REPLACE_ID);
}
rp = nextSibling(rp);
}
}
sz = Len(patchlist);
for (i = 0; i < sz; i++) {
String *s = Getitem(patchlist, i);
Replace(s, name, dvalue, DOH_REPLACE_ID);
}
sz = Len(typelist);
for (i = 0; i < sz; i++) {
String *s = Getitem(typelist, i);
/* Replace(s,name,value, DOH_REPLACE_ID); */
/* Printf(stdout,"name = '%s', value = '%s', tbase = '%s', iname='%s' s = '%s' --> ", name, dvalue, tbase, iname, s); */
SwigType_typename_replace(s, name, dvalue);
SwigType_typename_replace(s, tbase, iname);
/* Printf(stdout,"'%s'\n", s); */
}
if (!tydef) {
tydef = dvalue;
}
tmp = NewStringf("#%s", name);
tmpr = NewStringf("\"%s\"", valuestr);
sz = Len(cpatchlist);
for (i = 0; i < sz; i++) {
String *s = Getitem(cpatchlist, i);
Replace(s, tmp, tmpr, DOH_REPLACE_ID);
/* Replace(s,name,tydef, DOH_REPLACE_ID); */
Replace(s, name, valuestr, DOH_REPLACE_ID);
}
Delete(tmp);
Delete(tmpr);
Delete(valuestr);
Delete(dvalue);
Delete(qvalue);
}
p = nextSibling(p);
tp = nextSibling(tp);
if (!p)
p = tp;
}
} else {
/* No template parameters at all. This could be a specialization */
int i, sz;
sz = Len(typelist);
for (i = 0; i < sz; i++) {
String *s = Getitem(typelist, i);
SwigType_typename_replace(s, tbase, iname);
}
}
}
/* Patch bases */
{
List *bases = Getattr(n, "baselist");
if (bases) {
Iterator b;
for (b = First(bases); b.item; b = Next(b)) {
String *qn = Swig_symbol_type_qualify(b.item, tscope);
Clear(b.item);
Append(b.item, qn);
Delete(qn);
}
}
}
Delete(patchlist);
Delete(cpatchlist);
Delete(typelist);
Delete(tbase);
Delete(tname);
Delete(templateargs);
/* set_nodeType(n,"template"); */
return 0;
}
/* -----------------------------------------------------------------------------
* template_locate()
*
* Search for a template that matches name with given parameters.
* ----------------------------------------------------------------------------- */
static Node *template_locate(String *name, Parm *tparms, Symtab *tscope) {
Node *n;
String *tname, *rname = 0;
Node *templ;
List *mpartials = 0;
Parm *p;
Parm *parms;
Parm *targs;
ParmList *expandedparms;
tname = Copy(name);
parms = CopyParmList(tparms);
/* Search for generic template */
templ = Swig_symbol_clookup(name, 0);
/* Add default values from generic template */
if (templ) {
Symtab *tsdecl = Getattr(templ, "sym:symtab");
targs = Getattr(templ, "templateparms");
expandedparms = Swig_symbol_template_defargs(parms, targs, tscope, tsdecl);
} else {
expandedparms = parms;
}
/* reduce the typedef */
p = expandedparms;
while (p) {
SwigType *ty = Getattr(p, "type");
if (ty) {
SwigType *nt = Swig_symbol_type_qualify(ty, tscope);
Setattr(p, "type", nt);
Delete(nt);
}
p = nextSibling(p);
}
SwigType_add_template(tname, expandedparms);
if (template_debug) {
Printf(stdout, "\n%s:%d: template_debug: Searching for %s\n", cparse_file, cparse_line, tname);
}
/* Search for an exact specialization.
Example: template<> class name<int> { ... } */
{
if (template_debug) {
Printf(stdout, " searching: '%s' (exact specialization)\n", tname);
}
n = Swig_symbol_clookup_local(tname, 0);
if (!n) {
SwigType *rname = Swig_symbol_typedef_reduce(tname, tscope);
if (!Equal(rname, tname)) {
if (template_debug) {
Printf(stdout, " searching: '%s' (exact specialization)\n", rname);
}
n = Swig_symbol_clookup_local(rname, 0);
}
Delete(rname);
}
if (n) {
Node *tn;
String *nodeType = nodeType(n);
if (Equal(nodeType, "template"))
goto success;
tn = Getattr(n, "template");
if (tn) {
n = tn;
goto success; /* Previously wrapped by a template return that */
}
Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType(n));
Delete(tname);
Delete(parms);
return 0; /* Found a match, but it's not a template of any kind. */
}
}
/* Search for partial specialization.
Example: template<typename T> class name<T *> { ... } */
/* Generate reduced template name (stripped of extraneous pointers, etc.) */
rname = NewStringf("%s<(", name);
p = parms;
while (p) {
String *t;
t = Getattr(p, "type");
if (!t)
t = Getattr(p, "value");
if (t) {
String *ty = Swig_symbol_typedef_reduce(t, tscope);
String *tb = SwigType_base(ty);
String *td = SwigType_default(ty);
Replaceid(td, "enum SWIGTYPE", tb);
Replaceid(td, "SWIGTYPE", tb);
Append(rname, td);
Delete(tb);
Delete(ty);
Delete(td);
}
p = nextSibling(p);
if (p) {
Append(rname, ",");
}
}
Append(rname, ")>");
mpartials = NewList();
if (templ) {
/* First, we search using an exact type prototype */
Parm *p;
char tmp[32];
int i;
List *partials;
String *ss;
Iterator pi;
partials = Getattr(templ, "partials");
if (partials) {
for (pi = First(partials); pi.item; pi = Next(pi)) {
ss = Copy(pi.item);
p = parms;
i = 1;
while (p) {
String *t, *tn;
sprintf(tmp, "$%d", i);
t = Getattr(p, "type");
if (!t)
t = Getattr(p, "value");
if (t) {
String *ty = Swig_symbol_typedef_reduce(t, tscope);
tn = SwigType_base(ty);
Replaceid(ss, tmp, tn);
Delete(tn);
Delete(ty);
}
i++;
p = nextSibling(p);
}
if (template_debug) {
Printf(stdout, " searching: '%s' (partial specialization - %s)\n", ss, pi.item);
}
if ((Equal(ss, tname)) || (Equal(ss, rname))) {
Append(mpartials, pi.item);
}
Delete(ss);
}
}
}
if (template_debug) {
Printf(stdout, " Matched partials: %s\n", mpartials);
}
if (Len(mpartials)) {
String *s = Getitem(mpartials, 0);
n = Swig_symbol_clookup_local(s, 0);
if (Len(mpartials) > 1) {
if (n) {
Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, cparse_file, cparse_line, "Instantiation of template '%s' is ambiguous,\n", SwigType_namestr(tname));
Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, Getfile(n), Getline(n), " instantiation '%s' is used.\n", SwigType_namestr(Getattr(n, "name")));
}
}
}
if (!n) {
n = templ;
}
if (!n) {
Swig_error(cparse_file, cparse_line, "Template '%s' undefined.\n", name);
} else if (n) {
String *nodeType = nodeType(n);
if (!Equal(nodeType, "template")) {
Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType);
n = 0;
}
}
success:
Delete(tname);
Delete(rname);
Delete(mpartials);
if ((template_debug) && (n)) {
Printf(stdout, "Node: %p\n", n);
Swig_print_node(n);
}
Delete(parms);
return n;
}
/* -----------------------------------------------------------------------------
* Swig_cparse_template_locate()
*
* Search for a template that matches name with given parameters.
* For templated classes finds the specialized template should there be one.
* For templated functions finds the unspecialized template even if a specialized
* template exists.
* ----------------------------------------------------------------------------- */
Node *Swig_cparse_template_locate(String *name, Parm *tparms, Symtab *tscope) {
Node *n = template_locate(name, tparms, tscope); /* this function does what we want for templated classes */
if (n) {
String *nodeType = nodeType(n);
int isclass = 0;
assert(Equal(nodeType, "template"));
isclass = (Equal(Getattr(n, "templatetype"), "class"));
if (!isclass) {
/* If not a templated class we must have a templated function.
The template found is not necessarily the one we want when dealing with templated
functions. We don't want any specialized templated functions as they won't have
the default parameters. Lets look for the unspecialized template. Also make sure
the number of template parameters is correct as it is possible to overload a
templated function with different numbers of template parameters. */
if (template_debug) {
Printf(stdout, " Not a templated class, seeking most appropriate templated function\n");
}
n = Swig_symbol_clookup_local(name, 0);
while (n) {
Parm *tparmsfound = Getattr(n, "templateparms");
if (ParmList_len(tparms) == ParmList_len(tparmsfound)) {
/* successful match */
break;
}
/* repeat until we find a match with correct number of templated parameters */
n = Getattr(n, "sym:nextSibling");
}
if (!n) {
Swig_error(cparse_file, cparse_line, "Template '%s' undefined.\n", name);
}
if ((template_debug) && (n)) {
Printf(stdout, "Templated function found: %p\n", n);
Swig_print_node(n);
}
}
}
return n;
}