Duplicate class template instantiations via %template changes
Named duplicate class template instantiations now issue a warning and are ignored. Duplicate empty class template instantiations are quietly ignored. The test cases are fixed for this new behaviour. This commit is a pre-requisite for the near future so that the Python builtin wrappers can correctly use the SwigType_namestr function without generating duplicate symbol names.
This commit is contained in:
parent
777fd2c280
commit
4729cf2b1f
16 changed files with 283 additions and 55 deletions
|
|
@ -66,7 +66,7 @@ extern "C" {
|
|||
|
||||
/* templ.c */
|
||||
extern int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab *tscope);
|
||||
extern Node *Swig_cparse_template_locate(String *name, ParmList *tparms, Symtab *tscope);
|
||||
extern Node *Swig_cparse_template_locate(String *name, ParmList *tparms, String *symname, Symtab *tscope);
|
||||
extern void Swig_cparse_debug_templates(int);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -2822,6 +2822,7 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
|
|||
Symtab *tscope = 0;
|
||||
int specialized = 0;
|
||||
int variadic = 0;
|
||||
String *symname = $3 ? NewString($3) : 0;
|
||||
|
||||
$$ = 0;
|
||||
|
||||
|
|
@ -2841,7 +2842,7 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
|
|||
|
||||
This is closer to the C++ (typedef) behavior.
|
||||
*/
|
||||
n = Swig_cparse_template_locate($5,$7,tscope);
|
||||
n = Swig_cparse_template_locate($5, $7, symname, tscope);
|
||||
|
||||
/* Patch the argument types to respect namespaces */
|
||||
p = $7;
|
||||
|
|
@ -2966,7 +2967,7 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
|
|||
Setattr(templnode,"sym:typename","1");
|
||||
}
|
||||
/* for now, nested %template is allowed only in the same scope as the template declaration */
|
||||
if ($3 && !(nnisclass && ((outer_class && (outer_class != Getattr(nn, "nested:outer")))
|
||||
if (symname && !(nnisclass && ((outer_class && (outer_class != Getattr(nn, "nested:outer")))
|
||||
||(extendmode && current_class && (current_class != Getattr(nn, "nested:outer")))))) {
|
||||
/*
|
||||
Comment this out for 1.3.28. We need to
|
||||
|
|
@ -2974,11 +2975,10 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
|
|||
move %ignore from using %rename to use
|
||||
%feature(ignore).
|
||||
|
||||
String *symname = Swig_name_make(templnode,0,$3,0,0);
|
||||
String *symname = Swig_name_make(templnode, 0, symname, 0, 0);
|
||||
*/
|
||||
String *symname = NewString($3);
|
||||
Swig_cparse_template_expand(templnode,symname,temparms,tscope);
|
||||
Setattr(templnode,"sym:name",symname);
|
||||
Swig_cparse_template_expand(templnode, symname, temparms, tscope);
|
||||
Setattr(templnode, "sym:name", symname);
|
||||
} else {
|
||||
static int cnt = 0;
|
||||
String *nname = NewStringf("__dummy_%d__", cnt++);
|
||||
|
|
@ -2987,7 +2987,7 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
|
|||
SetFlag(templnode,"hidden");
|
||||
Delete(nname);
|
||||
Setattr(templnode,"feature:onlychildren", "typemap,typemapitem,typemapcopy,typedef,types,fragment,apply");
|
||||
if ($3) {
|
||||
if (symname) {
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
|
@ -3106,6 +3106,7 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
|
|||
Swig_symbol_setscope(tscope);
|
||||
Delete(Namespaceprefix);
|
||||
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
|
||||
Delete(symname);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
|||
|
|
@ -605,7 +605,7 @@ static EMatch does_parm_match(SwigType *type, SwigType *partial_parm_type, const
|
|||
* Search for a template that matches name with given parameters.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
static Node *template_locate(String *name, Parm *tparms, Symtab *tscope) {
|
||||
static Node *template_locate(String *name, Parm *tparms, String *symname, Symtab *tscope) {
|
||||
Node *n = 0;
|
||||
String *tname = 0;
|
||||
Node *templ;
|
||||
|
|
@ -626,7 +626,10 @@ static Node *template_locate(String *name, Parm *tparms, Symtab *tscope) {
|
|||
tname = Copy(name);
|
||||
SwigType_add_template(tname, tparms);
|
||||
Printf(stdout, "\n");
|
||||
Swig_diagnostic(cparse_file, cparse_line, "template_debug: Searching for match to: '%s'\n", tname);
|
||||
if (symname)
|
||||
Swig_diagnostic(cparse_file, cparse_line, "Template debug: Searching for match to: '%s' for instantiation of template named '%s'\n", tname, symname);
|
||||
else
|
||||
Swig_diagnostic(cparse_file, cparse_line, "Template debug: Searching for match to: '%s' for instantiation of empty template\n", tname);
|
||||
Delete(tname);
|
||||
tname = 0;
|
||||
}
|
||||
|
|
@ -682,11 +685,39 @@ static Node *template_locate(String *name, Parm *tparms, Symtab *tscope) {
|
|||
}
|
||||
tn = Getattr(n, "template");
|
||||
if (tn) {
|
||||
if (template_debug) {
|
||||
Printf(stdout, " previous instantiation found: '%s'\n", Getattr(n, "name"));
|
||||
/* Previously wrapped by a template instantiation */
|
||||
Node *previous_named_instantiation = GetFlag(n, "hidden") ? Getattr(n, "csym:nextSibling") : n; /* "hidden" is set when "sym:name" is a __dummy_ name */
|
||||
if (!symname) {
|
||||
/* Quietly ignore empty template instantiations if there is a previous (empty or non-empty) template instantiation */
|
||||
if (template_debug) {
|
||||
if (previous_named_instantiation)
|
||||
Printf(stdout, " previous instantiation with name '%s' found: '%s' - duplicate empty template instantiation ignored\n", Getattr(previous_named_instantiation, "sym:name"), Getattr(n, "name"));
|
||||
else
|
||||
Printf(stdout, " previous empty template instantiation found: '%s' - duplicate empty template instantiation ignored\n", Getattr(n, "name"));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* Accept a second instantiation only if previous template instantiation is empty */
|
||||
if (previous_named_instantiation) {
|
||||
String *previous_name = Getattr(previous_named_instantiation, "name");
|
||||
String *previous_symname = Getattr(previous_named_instantiation, "sym:name");
|
||||
String *unprocessed_tname = Copy(name);
|
||||
SwigType_add_template(unprocessed_tname, tparms);
|
||||
|
||||
if (template_debug)
|
||||
Printf(stdout, " previous instantiation with name '%s' found: '%s' - duplicate instantiation ignored\n", previous_symname, Getattr(n, "name"));
|
||||
SWIG_WARN_NODE_BEGIN(n);
|
||||
Swig_warning(WARN_TYPE_REDEFINED, cparse_file, cparse_line, "Duplicate template instantiation of '%s' with name '%s' ignored,\n", SwigType_namestr(unprocessed_tname), symname);
|
||||
Swig_warning(WARN_TYPE_REDEFINED, Getfile(n), Getline(n), "previous instantiation of '%s' with name '%s'.\n", SwigType_namestr(previous_name), previous_symname);
|
||||
SWIG_WARN_NODE_END(n);
|
||||
|
||||
Delete(unprocessed_tname);
|
||||
return 0;
|
||||
}
|
||||
if (template_debug)
|
||||
Printf(stdout, " previous empty template instantiation found: '%s' - using as duplicate instantiation overrides empty template instantiation\n", Getattr(n, "name"));
|
||||
n = tn;
|
||||
goto success; /* Previously wrapped by a template instantiation */
|
||||
goto success;
|
||||
}
|
||||
Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType(n));
|
||||
Delete(tname);
|
||||
|
|
@ -929,8 +960,8 @@ success:
|
|||
* 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 */
|
||||
Node *Swig_cparse_template_locate(String *name, Parm *tparms, String *symname, Symtab *tscope) {
|
||||
Node *n = template_locate(name, tparms, symname, tscope); /* this function does what we want for templated classes */
|
||||
|
||||
if (n) {
|
||||
String *nodeType = nodeType(n);
|
||||
|
|
|
|||
|
|
@ -446,6 +446,7 @@ class TypePass:private Dispatcher {
|
|||
SwigType_typedef_class(fname);
|
||||
scopename = Copy(fname);
|
||||
} else {
|
||||
// Does this code ever get executed ??
|
||||
Swig_warning(WARN_TYPE_REDEFINED, Getfile(n), Getline(n), "Template '%s' was already wrapped,\n", SwigType_namestr(name));
|
||||
Swig_warning(WARN_TYPE_REDEFINED, Getfile(cn), Getline(cn), "previous wrap of '%s'.\n", SwigType_namestr(Getattr(cn, "name")));
|
||||
scopename = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue