templated function overloading support

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@6394 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2004-10-16 20:41:17 +00:00
commit 77eef87058
4 changed files with 253 additions and 162 deletions

View file

@ -382,11 +382,11 @@ static void add_symbols(Node *n) {
Swig_warning(0,Getfile(n),Getline(n), "%s\n", wrn);
}
c = Swig_symbol_add(symname,n);
if (c != n) {
/* symbol conflict attempting to add in the new symbol */
if (Getattr(n,"sym:weak")) {
Setattr(n,"sym:name",symname);
} else if ((Strcmp(nodeType(n),"template") == 0) && (Strcmp(Getattr(n,"templatetype"),"cdecl") == 0)) {
Setattr(n,"sym:name",symname);
} else {
String *e = NewString("");
String *en = NewString("");
@ -892,7 +892,6 @@ static void default_arguments(Node *n) {
}
if (default_args) {
ParmList* newparms = 0;
/* Create a parameter list for the new function by copying all
but the last (defaulted) parameter */
{
@ -933,14 +932,12 @@ static void default_arguments(Node *n) {
if (throws) Setattr(new_function,"throws",CopyParmList(throws));
}
/* copy template specific attributes */
/* copy specific attributes for global (or in a namespace) template functions - these are not templated class methods */
if (Strcmp(nodeType(function),"template") == 0) {
Node *templatetype = Getattr(function,"templatetype");
Node *symname = Getattr(function,"sym:name");
Node *symtypename = Getattr(function,"sym:typename");
Parm *templateparms = Getattr(function,"templateparms");
if (templatetype) Setattr(new_function,"templatetype",Copy(templatetype));
if (symname) Setattr(new_function,"sym:name",Copy(symname));
if (symtypename) Setattr(new_function,"sym:typename",Copy(symtypename));
if (templateparms) Setattr(new_function,"templateparms",CopyParmList(templateparms));
}
@ -2097,147 +2094,168 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
}
p = nextSibling(p);
}
/* Look for the template */
{
Node *nn = n;
Node *linklistend = 0;
while (nn) {
Node *templnode = 0;
if (Strcmp(nodeType(nn),"template") == 0) {
int nnisclass = (Strcmp(Getattr(nn,"templatetype"),"class") == 0); /* if not a templated class it is a templated function */
Parm *tparms = Getattr(nn,"templateparms");
if (!tparms) {
specialized = 1;
}
if (nnisclass && !specialized && ((ParmList_len($7) > ParmList_len(tparms)))) {
Swig_error(cparse_file, cparse_line, "Too many template parameters. Maximum of %d.\n", ParmList_len(tparms));
} else if (nnisclass && !specialized && ((ParmList_len($7) < ParmList_numrequired(tparms)))) {
Swig_error(cparse_file, cparse_line, "Not enough template parameters specified. %d required.\n", ParmList_numrequired(tparms));
} else if (!nnisclass && ((ParmList_len($7) != ParmList_len(tparms)))) {
/* must be an overloaded templated method - ignore it as it is overloaded with a different number of template parameters */
nn = Getattr(nn,"sym:nextSibling"); /* repeat for overloaded templated functions */
continue;
} else {
int def_supplied = 0;
/* Expand the template */
ParmList *temparms;
if (specialized) temparms = CopyParmList($7);
else temparms = CopyParmList(tparms);
if (n && (Strcmp(nodeType(n),"template") == 0)) {
Parm *tparms = Getattr(n,"templateparms");
if (!tparms) {
specialized = 1;
}
if (!specialized && ((ParmList_len($7) > ParmList_len(tparms)))) {
Swig_error(cparse_file, cparse_line, "Too many template parameters. Maximum of %d.\n", ParmList_len(tparms));
} else if (!specialized && ((ParmList_len($7) < ParmList_numrequired(tparms)))) {
Swig_error(cparse_file, cparse_line, "Not enough template parameters specified. %d required.\n", ParmList_numrequired(tparms));
} else {
int def_supplied = 0;
/* Expand the template */
ParmList *temparms;
if (specialized) temparms = CopyParmList($7);
else temparms = CopyParmList(tparms);
/* Create typedef's and arguments */
p = $7;
tp = temparms;
while (p) {
String *value = Getattr(p,"value");
if (def_supplied) {
Setattr(p,"default","1");
}
if (value) {
Setattr(tp,"value",value);
} else {
SwigType *ty = Getattr(p,"type");
if (ty) {
Setattr(tp,"type",ty);
}
Delattr(tp,"value");
}
p = nextSibling(p);
tp = nextSibling(tp);
if (!p && tp) {
p = tp;
def_supplied = 1;
}
}
/* Create typedef's and arguments */
p = $7;
tp = temparms;
while (p) {
String *value = Getattr(p,"value");
if (def_supplied) {
Setattr(p,"default","1");
}
if (value) {
Setattr(tp,"value",value);
} else {
SwigType *ty = Getattr(p,"type");
if (ty) {
Setattr(tp,"type",ty);
}
Delattr(tp,"value");
}
p = nextSibling(p);
tp = nextSibling(tp);
if (!p && tp) {
p = tp;
def_supplied = 1;
}
}
templnode = copy_node(nn);
/* We need to set the node name based on name used to instantiate */
Setattr(templnode,"name",Copy($5));
if (!specialized) {
Delattr(templnode,"sym:typename");
} else {
Setattr(templnode,"sym:typename","1");
}
if ($3) {
Swig_cparse_template_expand(templnode,$3,temparms);
Setattr(templnode,"sym:name",$3);
} else {
static int cnt = 0;
String *nname = NewStringf("__dummy_%d__", cnt++);
Swig_cparse_template_expand(templnode,nname,temparms);
Setattr(templnode,"sym:name",nname);
if (!Swig_template_extmode()) {
Setattr(templnode,"feature:ignore","1");
} else {
Setattr(templnode,"feature:onlychildren",
"typemap,typemapitem,typemapcopy,typedef,types,fragment");
}
}
Delattr(templnode,"templatetype");
Setattr(templnode,"template",nn);
tnode = templnode;
Setfile(templnode,cparse_file);
Setline(templnode,cparse_line);
Delete(temparms);
add_symbols_copy(templnode);
$$ = copy_node(n);
/* We need to set the node name based on name used to instantiate */
Setattr($$,"name",Copy($5));
if (!specialized) {
Delattr($$,"sym:typename");
} else {
Setattr($$,"sym:typename","1");
}
if ($3) {
Swig_cparse_template_expand($$,$3,temparms);
Setattr($$,"sym:name",$3);
} else {
static int cnt = 0;
String *nname = NewStringf("__dummy_%d__", cnt++);
Swig_cparse_template_expand($$,nname,temparms);
Setattr($$,"sym:name",nname);
if (!Swig_template_extmode()) {
Setattr($$,"feature:ignore","1");
} else {
Setattr($$,"feature:onlychildren",
"typemap,typemapitem,typemapcopy,typedef,types,fragment");
}
}
Delattr($$,"templatetype");
Setattr($$,"template",n);
tnode = $$;
Setfile($$,cparse_file);
Setline($$,cparse_line);
Delete(temparms);
add_symbols_copy($$);
if (Strcmp(nodeType($$),"class") == 0) {
if (Strcmp(nodeType(templnode),"class") == 0) {
/* Identify pure abstract methods */
Setattr($$,"abstract", pure_abstract(firstChild($$)));
/* Set up inheritance in symbol table */
{
Symtab *csyms;
List *baselist = Getattr($$,"baselist");
csyms = Swig_symbol_current();
Swig_symbol_setscope(Getattr($$,"symtab"));
if (baselist) {
List *bases = make_inherit_list(Getattr($$,"name"),baselist);
if (bases) {
Iterator s;
for (s = First(bases); s.item; s = Next(s)) {
Symtab *st = Getattr(s.item,"symtab");
if (st) {
Swig_symbol_inherit(st);
}
}
}
}
Swig_symbol_setscope(csyms);
}
/* Identify pure abstract methods */
Setattr(templnode,"abstract", pure_abstract(firstChild(templnode)));
/* Set up inheritance in symbol table */
{
Symtab *csyms;
List *baselist = Getattr(templnode,"baselist");
csyms = Swig_symbol_current();
Swig_symbol_setscope(Getattr(templnode,"symtab"));
if (baselist) {
List *bases = make_inherit_list(Getattr(templnode,"name"),baselist);
if (bases) {
Iterator s;
for (s = First(bases); s.item; s = Next(s)) {
Symtab *st = Getattr(s.item,"symtab");
if (st) {
Swig_symbol_inherit(st);
}
}
}
}
Swig_symbol_setscope(csyms);
}
/* Merge in addmethods for this class */
/* !!! This may be broken. We may have to add the addmethods at the beginning of
the class */
if (extendhash) {
String *clsname;
Node *am;
if (Namespaceprefix) {
clsname = NewStringf("%s::%s", Namespaceprefix, Getattr($$,"name"));
} else {
clsname = Getattr($$,"name");
}
am = Getattr(extendhash,clsname);
if (am) {
Symtab *st = Swig_symbol_current();
Swig_symbol_setscope(Getattr($$,"symtab"));
/* Printf(stdout,"%s: %s %x %x\n", Getattr($$,"name"), clsname, Swig_symbol_current(), Getattr($$,"symtab")); */
merge_extensions($$,am);
Swig_symbol_setscope(st);
appendChild($$,am);
Delattr(extendhash,clsname);
}
}
/* Add to classes hash */
if (!classes) classes = NewHash();
/* Merge in addmethods for this class */
/* !!! This may be broken. We may have to add the addmethods at the beginning of
the class */
if (extendhash) {
String *clsname;
Node *am;
if (Namespaceprefix) {
clsname = NewStringf("%s::%s", Namespaceprefix, Getattr(templnode,"name"));
} else {
clsname = Getattr(templnode,"name");
}
am = Getattr(extendhash,clsname);
if (am) {
Symtab *st = Swig_symbol_current();
Swig_symbol_setscope(Getattr(templnode,"symtab"));
/* Printf(stdout,"%s: %s %x %x\n", Getattr(templnode,"name"), clsname, Swig_symbol_current(), Getattr(templnode,"symtab")); */
merge_extensions(templnode,am);
Swig_symbol_setscope(st);
appendChild(templnode,am);
Delattr(extendhash,clsname);
}
}
/* Add to classes hash */
if (!classes) classes = NewHash();
{
if (Namespaceprefix) {
String *temp = NewStringf("%s::%s", Namespaceprefix, Getattr($$,"name"));
Setattr(classes,temp,$$);
} else {
Setattr(classes,Swig_symbol_qualifiedscopename($$),$$);
}
}
}
}
if ($$ && nspace) {
appendChild(nspace_inner,$$);
$$ = nspace;
}
{
if (Namespaceprefix) {
String *temp = NewStringf("%s::%s", Namespaceprefix, Getattr(templnode,"name"));
Setattr(classes,temp,templnode);
} else {
Setattr(classes,Swig_symbol_qualifiedscopename(templnode),templnode);
}
}
}
}
if (templnode && nspace) {
appendChild(nspace_inner,templnode);
templnode = nspace;
}
/* all the overloaded templated functions are added into a linked list */
if (!linklistend) {
$$ = templnode;
} else {
set_nextSibling(linklistend,templnode);
}
linklistend = templnode;
}
nn = Getattr(nn,"sym:nextSibling"); /* repeat for overloaded templated functions. If a templated class there will never be a sibling. */
}
}
Swig_symbol_setscope(tscope);
Namespaceprefix = Swig_symbol_qualifiedscopename(0);