Closes #1300 Changes to support the first example below (partial specialization of template parameter types like Vect<int>). Previous implementation and design could only handle one template parameter name per template specialization argument, such as Vect<TS> for the first template specialization argument (for first example below) template<class TS, typename TTS> class Foo<Vect<TS>, int> { ... }; and not template<class TS, typename TTS> class Foo<Vect<TS, TTS>, int> { ... }; New approach is to not modify 'templateparms' in the template node, (except to fill in default args from primary template) Previous implementation also assumed a template parameter could not be used more than once in the specialized arguments, such as template<typename T> struct Hey<T, T> { void specialA() {} }; Examples ======== 1) For primary: template<class T, typename TT> class Foo { ... }; and specialization: template<class TS, typename TTS> class Foo<Vect<TS>, TTS> { ... }; Fix specialization template from (wrong) | templateparms - 'Vect< TS >,typename TTS' to (correct/new way) | templateparms - 'class TS,typename TTS' 2) For primary: template<typename P1 = int, typename P2 = double> struct Partialler { void primary(P1, P2) {}; }; and specialization: template<typename S1, typename S2> struct Partialler<S2, S1*> { void special(S1*, S2, bool) {}; }; Specialized template changes from (wrong) | templateparms - 'typename S2=int,typename S1=double' to (correct/new way, default args are removed) | templateparms - 'typename S1,typename S2' and subsequent change to partialargs from | partialargs - "Partialler<($1,p.$2)>" to | partialargs - "Partialler<($2,p.$1)>" so that the $n number is now more logically the nth template parameter in templateparms 3) For primary: template<typename X, typename Y> struct Hey { void primary() {} }; and specialization: template<typename T> struct Hey<T, T> { void specialA() {} }; old (wrong/old way) | templateparms - 'typename T,typename T' new (correct/new way) | templateparms - 'typename T' These are unchanged and are okay: | partialargs - "Hey<($1,$1)>" 4) For primary: enum Hello { hi, hello }; template <Hello, class A> struct C {}; and specialization: template <class A> struct C<hello,A> { ... }; old (wrong/old way) | templateparms - 'hello,class A' new (correct/new way) | templateparms - 'class A' and subsequent changes to partialargs from | partialargs - "C<(hi,$2)>" to | partialargs - "C<(hi,$1)>" Test-suite ========== Identical output as before in Python but in Java, an unimportant change in cpp11_variadic_function_templates.i results in one variadic parameter name being different. New testcase template_partial_specialization_more.i with more testcases added including above examples that are not already in the test-suite.
86 lines
3.1 KiB
C
86 lines
3.1 KiB
C
/* -----------------------------------------------------------------------------
|
|
* This file is part of SWIG, which is licensed as a whole under version 3
|
|
* (or any later version) of the GNU General Public License. Some additional
|
|
* terms also apply to certain portions of SWIG. The full details of the SWIG
|
|
* license and copyrights can be found in the LICENSE and COPYRIGHT files
|
|
* included with the SWIG source code as distributed by the SWIG developers
|
|
* and at https://www.swig.org/legal.html.
|
|
*
|
|
* cparse.h
|
|
*
|
|
* SWIG parser module.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
#ifndef SWIG_CPARSE_H
|
|
#define SWIG_CPARSE_H
|
|
|
|
#include "swig.h"
|
|
#include "swigwarn.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* cscanner.c */
|
|
extern String *cparse_file;
|
|
extern int cparse_line;
|
|
extern int cparse_cplusplus;
|
|
extern int cparse_cplusplusout;
|
|
extern int cparse_start_line;
|
|
extern String *cparse_unknown_directive;
|
|
extern int scan_doxygen_comments;
|
|
|
|
extern void Swig_cparse_cplusplus(int);
|
|
extern void Swig_cparse_cplusplusout(int);
|
|
extern void scanner_file(File *);
|
|
extern void scanner_next_token(int);
|
|
extern void skip_balanced(int startchar, int endchar);
|
|
extern String *get_raw_text_balanced(int startchar, int endchar);
|
|
extern void skip_decl(void);
|
|
extern void scanner_check_typedef(void);
|
|
extern void scanner_ignore_typedef(void);
|
|
extern void scanner_last_id(int);
|
|
extern void scanner_clear_rename(void);
|
|
extern void scanner_set_location(String *file, int line);
|
|
extern void scanner_set_main_input_file(String *file);
|
|
extern String *scanner_get_main_input_file(void);
|
|
extern void Swig_cparse_follow_locators(int);
|
|
extern void start_inline(char *, int);
|
|
extern String *scanner_ccode;
|
|
extern int yylex(void);
|
|
|
|
/* parser.y */
|
|
extern SwigType *Swig_cparse_type(String *);
|
|
extern Node *Swig_cparse(File *);
|
|
extern Hash *Swig_cparse_features(void);
|
|
extern void SWIG_cparse_set_compact_default_args(int defargs);
|
|
extern int SWIG_cparse_template_reduce(int treduce);
|
|
|
|
/* util.c */
|
|
extern void Swig_cparse_replace_descriptor(String *s);
|
|
extern SwigType *Swig_cparse_smartptr(Node *n);
|
|
extern void cparse_normalize_void(Node *);
|
|
extern Parm *Swig_cparse_parm(String *s);
|
|
extern ParmList *Swig_cparse_parms(String *s, Node *file_line_node);
|
|
extern Node *Swig_cparse_new_node(const_String_or_char_ptr tag);
|
|
|
|
/* 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, String *symname, Symtab *tscope);
|
|
extern void Swig_cparse_debug_templates(int);
|
|
extern ParmList *Swig_cparse_template_parms_expand(ParmList *instantiated_parameters, Node *primary, Node *templ);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
#define SWIG_WARN_NODE_BEGIN(Node) \
|
|
{ \
|
|
String *wrnfilter = Node ? Getattr(Node,"feature:warnfilter") : 0; \
|
|
if (wrnfilter) Swig_warnfilter(wrnfilter,1)
|
|
#define SWIG_WARN_NODE_END(Node) \
|
|
if (wrnfilter) Swig_warnfilter(wrnfilter,0); \
|
|
}
|
|
|
|
#define COMPOUND_EXPR_VAL(dtype) \
|
|
((dtype).type == T_CHAR || (dtype).type == T_WCHAR ? (dtype).rawval : (dtype).val)
|
|
#endif
|