Refactor %template parameters handling

Move code from %template parsing in parser.y into new function
Swig_cparse_template_parms_expand
This commit is contained in:
William S Fulton 2022-12-09 19:23:57 +00:00
commit 9e8a0daf9e
3 changed files with 82 additions and 62 deletions

View file

@ -68,6 +68,7 @@ extern "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, String *symname, Symtab *tscope);
extern void Swig_cparse_debug_templates(int);
extern ParmList *Swig_cparse_template_parms_expand(ParmList *instantiated_parameters, ParmList *temparms_input, Parm *targs, Node *nn);
#ifdef __cplusplus
}

View file

@ -2812,11 +2812,11 @@ types_directive : TYPES LPAREN parms RPAREN stringbracesemi {
------------------------------------------------------------ */
template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN valparms GREATERTHAN SEMI {
Parm *p, *tp;
Parm *p;
Node *n;
Node *outer_class = currentOuterClass;
Symtab *tscope = 0;
int specialized = 0;
int specialized = 0; /* fully specialized (an explicit specialization) */
int variadic = 0;
String *symname = $3 ? NewString($3) : 0;
@ -2892,65 +2892,12 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
continue;
} else {
String *tname = Copy($5);
int def_supplied = 0;
/* Expand the template */
Node *templ = Swig_symbol_clookup($5,0);
Parm *targs = templ ? Getattr(templ,"templateparms") : 0;
Node *primary_template = Swig_symbol_clookup(tname, 0);
ParmList *targs = primary_template ? Getattr(primary_template, "templateparms") : 0;
ParmList *temparms_input = specialized ? $7 : tparms;
ParmList *temparms;
if (specialized) temparms = CopyParmList($7);
else temparms = CopyParmList(tparms);
/* Create typedef's and arguments */
p = $7;
tp = temparms;
if (!p && ParmList_len(p) != ParmList_len(temparms)) {
/* we have no template parameters supplied in %template for a template that has default args*/
p = tp;
def_supplied = 1;
}
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");
}
/* fix default arg values */
if (targs) {
Parm *pi = temparms;
Parm *ti = targs;
String *tv = Getattr(tp,"value");
if (!tv) tv = Getattr(tp,"type");
while(pi != tp && ti && pi) {
String *name = Getattr(ti,"name");
String *value = Getattr(pi,"value");
if (!value) value = Getattr(pi,"type");
Replaceid(tv, name, value);
pi = nextSibling(pi);
ti = nextSibling(ti);
}
}
p = nextSibling(p);
tp = nextSibling(tp);
if (!p && tp) {
p = tp;
def_supplied = 1;
} else if (p && !tp) { /* Variadic template - tp < p */
SWIG_WARN_NODE_BEGIN(nn);
Swig_warning(WARN_CPP11_VARIADIC_TEMPLATE,cparse_file, cparse_line,"Only the first variadic template argument is currently supported.\n");
SWIG_WARN_NODE_END(nn);
break;
}
}
ParmList *temparms = Swig_cparse_template_parms_expand($7, temparms_input, targs, nn);
templnode = copy_node(nn);
update_nested_classes(templnode); /* update classes nested within template */

View file

@ -322,8 +322,7 @@ static void cparse_postprocess_expanded_template(Node *n) {
* partial_arg()
* ----------------------------------------------------------------------------- */
static
String *partial_arg(String *s, String *p) {
static String *partial_arg(String *s, String *p) {
char *c;
char *cp = Char(p);
String *prefix;
@ -1005,3 +1004,76 @@ Node *Swig_cparse_template_locate(String *name, Parm *tparms, String *symname, S
return n;
}
/* -----------------------------------------------------------------------------
* Swig_cparse_template_parms_expand()
*
* instantiated_parameters: template parameters passed to %template
* temparms_inputs: template parameters to use as starting point
* targs: primary template parameters, default args copied from here
* nn: template node (just used for warning)
*
* Expand the instantiated_parameters and return a parameter list with default
* arguments filled in where necessary.
* ----------------------------------------------------------------------------- */
ParmList *Swig_cparse_template_parms_expand(ParmList *instantiated_parameters, ParmList *temparms_input, Parm *targs, Node *nn) {
Parm *p;
Parm *tp;
int def_supplied = 0;
ParmList *temparms = CopyParmList(temparms_input);
p = instantiated_parameters;
tp = temparms;
if (!p && ParmList_len(p) != ParmList_len(temparms)) {
/* we have no template parameters supplied in %template for a template that has default args*/
p = tp;
def_supplied = 1;
}
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");
}
/* fix default arg values */
if (targs) {
Parm *pi = temparms;
Parm *ti = targs;
String *tv = Getattr(tp, "value");
if (!tv) tv = Getattr(tp, "type");
while(pi != tp && ti && pi) {
String *name = Getattr(ti, "name");
String *value = Getattr(pi, "value");
if (!value) value = Getattr(pi, "type");
Replaceid(tv, name, value);
pi = nextSibling(pi);
ti = nextSibling(ti);
}
}
p = nextSibling(p);
tp = nextSibling(tp);
if (!p && tp) {
p = tp;
def_supplied = 1;
} else if (p && !tp) { /* Variadic template - tp < p */
SWIG_WARN_NODE_BEGIN(nn);
Swig_warning(WARN_CPP11_VARIADIC_TEMPLATE, cparse_file, cparse_line, "Only the first variadic template argument is currently supported.\n");
SWIG_WARN_NODE_END(nn);
break;
}
}
return temparms;
}