summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorWilliam S Fulton <wsf@fultondesigns.co.uk>2022-12-02 19:16:02 +0000
committerWilliam S Fulton <wsf@fultondesigns.co.uk>2022-12-02 19:16:02 +0000
commit05b93b1f06fe5299e5bda2c2b1e0d70c7599af61 (patch)
tree713dbb9e92db2908e0aac3fcc4b236212b20dd3a /Source
parentc85e7f1625f8b421c92b8c1a8279d134ba050ecc (diff)
downloadswig-05b93b1f06fe5299e5bda2c2b1e0d70c7599af61.tar.gz
Improved template template parameters support.
Previously, specifying more than one simple template template parameter resulted in a parse error. Now multiple template template parameters are working including instantiation with %template. Example: template <template<template<class> class, class> class Op, template<class> class X, class Y> class C { ... }; Closes #624 Closes #1021
Diffstat (limited to 'Source')
-rw-r--r--Source/CParse/parser.y99
1 files changed, 47 insertions, 52 deletions
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index 526d65ff6..c0f1394d8 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -1681,7 +1681,7 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
%type <dtype> initializer cpp_const exception_specification cv_ref_qualifier qualifiers_exception_specification;
%type <id> storage_class extern_string;
%type <pl> parms ptail rawparms varargs_parms ;
-%type <pl> templateparameters templateparameterstail;
+%type <pl> templateparameterstail;
%type <p> parm_no_dox parm valparm rawvalparms valparms valptail ;
%type <p> typemap_parm tm_list tm_tail ;
%type <p> templateparameter ;
@@ -4446,43 +4446,7 @@ cpp_template_possible: c_decl {
}
;
-template_parms : templateparameters {
- /* Rip out the parameter names */
- Parm *p = $1;
- $$ = $1;
-
- while (p) {
- String *name = Getattr(p,"name");
- if (!name) {
- /* Hmmm. Maybe it's a 'class T' parameter */
- char *type = Char(Getattr(p,"type"));
- /* Template template parameter */
- if (strncmp(type,"template<class> ",16) == 0) {
- type += 16;
- }
- if ((strncmp(type,"class ",6) == 0) || (strncmp(type,"typename ", 9) == 0)) {
- char *t = strchr(type,' ');
- Setattr(p,"name", t+1);
- } else
- /* Variadic template args */
- if ((strncmp(type,"class... ",9) == 0) || (strncmp(type,"typename... ", 12) == 0)) {
- char *t = strchr(type,' ');
- Setattr(p,"name", t+1);
- Setattr(p,"variadic", "1");
- } else {
- /*
- Swig_error(cparse_file, cparse_line, "Missing template parameter name\n");
- $$.rparms = 0;
- $$.parms = 0;
- break; */
- }
- }
- p = nextSibling(p);
- }
- }
- ;
-
-templateparameters : templateparameter templateparameterstail {
+template_parms : templateparameter templateparameterstail {
set_nextSibling($1,$2);
$$ = $1;
}
@@ -4491,10 +4455,52 @@ templateparameters : templateparameter templateparameterstail {
templateparameter : templcpptype def_args {
$$ = NewParmWithoutFileLineInfo(NewString($1), 0);
+ previousNode = currentNode;
+ currentNode = $$;
+ Setfile($$, cparse_file);
+ Setline($$, cparse_line);
Setattr($$, "value", $2.rawval ? $2.rawval : $2.val);
- }
- | parm {
- $$ = $1;
+ }
+ | TEMPLATE LESSTHAN template_parms GREATERTHAN cpptype idcolon def_args {
+ $$ = NewParmWithoutFileLineInfo(NewStringf("template< %s > %s %s", ParmList_str_defaultargs($3), $5, $6), $6);
+ previousNode = currentNode;
+ currentNode = $$;
+ Setfile($$, cparse_file);
+ Setline($$, cparse_line);
+ if ($7.val) {
+ Setattr($$, "value", $7.val);
+ }
+ }
+ | TEMPLATE LESSTHAN template_parms GREATERTHAN cpptype def_args {
+ $$ = NewParmWithoutFileLineInfo(NewStringf("template< %s > %s", ParmList_str_defaultargs($3), $5), 0);
+ previousNode = currentNode;
+ currentNode = $$;
+ Setfile($$, cparse_file);
+ Setline($$, cparse_line);
+ if ($6.val) {
+ Setattr($$, "value", $6.val);
+ }
+ }
+ | parm {
+ Parm *p = $1;
+ $$ = $1;
+
+ /* TODO: also slice off the name from the "type" */
+ /* Rip out the parameter names */
+ String *name = Getattr(p, "name");
+ if (!name) {
+ String *type = Getattr(p, "type");
+ if ((Strncmp(type, "class ", 6) == 0) || (Strncmp(type, "typename ", 9) == 0)) {
+ /* A 'class T' parameter */
+ const char *t = Strchr(type, ' ');
+ Setattr(p, "name", t + 1);
+ } else if ((Strncmp(type, "class... ", 9) == 0) || (Strncmp(type, "typename... ", 12) == 0)) {
+ /* Variadic template args */
+ const char *t = Strchr(type, ' ');
+ Setattr(p, "name", t + 1);
+ Setattr(p, "variadic", "1");
+ }
+ }
}
;
@@ -5195,17 +5201,6 @@ parm_no_dox : rawtype parameter_declarator {
Setattr($$,"value",$2.defarg);
}
}
-
- | TEMPLATE LESSTHAN cpptype GREATERTHAN cpptype idcolon def_args {
- $$ = NewParmWithoutFileLineInfo(NewStringf("template<class> %s %s", $5,$6), 0);
- previousNode = currentNode;
- currentNode = $$;
- Setfile($$,cparse_file);
- Setline($$,cparse_line);
- if ($7.val) {
- Setattr($$,"value",$7.val);
- }
- }
| ELLIPSIS {
SwigType *t = NewString("v(...)");
$$ = NewParmWithoutFileLineInfo(t, 0);