mirror of https://github.com/swig/swig
Add warning for ineffective %template instantiations
on forward template class declarations. A full template class definition is required in order to wrap a template class as a proxy class. Also tidyup handling of classforward code (no observable changes in test-suite).
This commit is contained in:
parent
3556c41b98
commit
8c8e27d246
|
@ -415,6 +415,7 @@ example.i(4) : Syntax error in input(1).
|
||||||
<li>327. Extern template ignored.
|
<li>327. Extern template ignored.
|
||||||
<li>328. Value assigned to <em>name</em> not used due to limited parsing implementation.
|
<li>328. Value assigned to <em>name</em> not used due to limited parsing implementation.
|
||||||
<li>329. Using declaration '<em>name</em>' for inheriting constructors uses base '<em>name</em>' which is not an immediate base of '<em>name</em>'.
|
<li>329. Using declaration '<em>name</em>' for inheriting constructors uses base '<em>name</em>' which is not an immediate base of '<em>name</em>'.
|
||||||
|
<li>330. Template forward class instantiation '<em>templ</em>' with name '<em>name</em>' is ineffective.
|
||||||
<li>340. Lambda expressions and closures are not fully supported yet.
|
<li>340. Lambda expressions and closures are not fully supported yet.
|
||||||
<li>344. Unable to deduce decltype for '<em>expr</em>'.
|
<li>344. Unable to deduce decltype for '<em>expr</em>'.
|
||||||
<li>345. Unable to deduce auto return type for '<em>name</em>' (ignored).
|
<li>345. Unable to deduce auto return type for '<em>name</em>' (ignored).
|
||||||
|
|
|
@ -7,3 +7,8 @@ namespace UUU {
|
||||||
}
|
}
|
||||||
|
|
||||||
%template(xxx) UUU::JJJ<int>;
|
%template(xxx) UUU::JJJ<int>;
|
||||||
|
|
||||||
|
%template(TTT_int) VVV::TTT<int>; // needs to be after template is parsed
|
||||||
|
namespace VVV {
|
||||||
|
template<typename T> struct TTT {};
|
||||||
|
}
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
cpp_invalid_template.i:3: Error: Template 'SSS::AAA' undefined.
|
cpp_invalid_template.i:3: Error: Template 'SSS::AAA' undefined.
|
||||||
cpp_invalid_template.i:9: Error: 'JJJ' is not defined as a template. (classforward)
|
cpp_invalid_template.i:9: Error: 'JJJ' is not defined as a template. (classforward)
|
||||||
|
cpp_invalid_template.i:11: Error: Template 'VVV::TTT' undefined.
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
%module xxx
|
||||||
|
|
||||||
|
|
||||||
|
namespace Space {
|
||||||
|
template <typename T> struct ForwardDeclaredTemplate;
|
||||||
|
%template(ForwardDeclaredTemplate_double) ForwardDeclaredTemplate<double>;
|
||||||
|
|
||||||
|
template <typename T> struct ForwardDeclaredSpecialized;
|
||||||
|
%template(ForwardDeclaredTemplate_int) ForwardDeclaredSpecialized<int>; // no primary defined
|
||||||
|
%template(ForwardDeclaredTemplate_double) ForwardDeclaredSpecialized<double>; // needs to be after the specialized template definition.
|
||||||
|
template <> struct ForwardDeclaredSpecialized<double> {
|
||||||
|
void specialized(const ForwardDeclaredSpecialized& other) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T> struct ForwardDeclaredMisplacedPrimary;
|
||||||
|
%template(ForwardDeclaredTemplate_double) ForwardDeclaredMisplacedPrimary<double>; // needs to be after the primary template definition.
|
||||||
|
template <typename T> struct ForwardDeclaredMisplacedPrimary {
|
||||||
|
void primary(const ForwardDeclaredMisplacedPrimary& other) { }
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
cpp_template_forward.i:6: Warning 330: Template instantiation of forward class declaration 'Space::ForwardDeclaredTemplate< double >' with name 'ForwardDeclaredTemplate_double' is ineffective.
|
||||||
|
cpp_template_forward.i:9: Warning 330: Template instantiation of forward class declaration 'Space::ForwardDeclaredSpecialized< int >' with name 'ForwardDeclaredTemplate_int' is ineffective.
|
||||||
|
cpp_template_forward.i:10: Warning 330: Template instantiation of forward class declaration 'Space::ForwardDeclaredSpecialized< double >' with name 'ForwardDeclaredTemplate_double' is ineffective.
|
||||||
|
cpp_template_forward.i:16: Warning 330: Template instantiation of forward class declaration 'Space::ForwardDeclaredMisplacedPrimary< double >' with name 'ForwardDeclaredTemplate_double' is ineffective.
|
|
@ -3,6 +3,8 @@
|
||||||
%rename(not1) *::operator!() const;
|
%rename(not1) *::operator!() const;
|
||||||
%rename(negate) *::operator-() const;
|
%rename(negate) *::operator-() const;
|
||||||
|
|
||||||
|
%warnfilter(SWIGWARN_PARSE_TEMPLATE_FORWARD) vfncs::OnlySpecialized<double>;
|
||||||
|
|
||||||
%inline %{
|
%inline %{
|
||||||
|
|
||||||
namespace vfncs {
|
namespace vfncs {
|
||||||
|
@ -45,7 +47,7 @@ namespace vfncs {
|
||||||
%template(OnlySpecialized_int) OnlySpecialized<int>;
|
%template(OnlySpecialized_int) OnlySpecialized<int>;
|
||||||
|
|
||||||
// Primary instantiation with only primary template forward declaration
|
// Primary instantiation with only primary template forward declaration
|
||||||
%template(OnlySpecialized_double) OnlySpecialized<double>; // silently ignored - probably should warn
|
%template(OnlySpecialized_double) OnlySpecialized<double>; // ignored with a warning
|
||||||
}
|
}
|
||||||
|
|
||||||
%{
|
%{
|
||||||
|
|
|
@ -2905,7 +2905,7 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
|
||||||
if (GetFlag(nn, "instantiate")) {
|
if (GetFlag(nn, "instantiate")) {
|
||||||
Delattr(nn, "instantiate");
|
Delattr(nn, "instantiate");
|
||||||
{
|
{
|
||||||
int nnisclass = (Strcmp(Getattr(nn, "templatetype"), "class") == 0); /* if not a class template it is a function template */
|
int nnisclass = (Strcmp(Getattr(nn, "templatetype"), "class") == 0); /* class template not a classforward nor function template */
|
||||||
Parm *tparms = Getattr(nn, "templateparms");
|
Parm *tparms = Getattr(nn, "templateparms");
|
||||||
int specialized = !tparms; /* fully specialized (an explicit specialization) */
|
int specialized = !tparms; /* fully specialized (an explicit specialization) */
|
||||||
String *tname = Copy(idcolonnt);
|
String *tname = Copy(idcolonnt);
|
||||||
|
@ -2960,6 +2960,13 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
|
||||||
}
|
}
|
||||||
add_symbols_copy(templnode);
|
add_symbols_copy(templnode);
|
||||||
|
|
||||||
|
if (Equal(nodeType(templnode), "classforward")) {
|
||||||
|
SWIG_WARN_NODE_BEGIN(templnode);
|
||||||
|
/* A full template class definition is required in order to wrap a template class as a proxy class so this %template is ineffective. */
|
||||||
|
Swig_warning(WARN_PARSE_TEMPLATE_FORWARD, cparse_file, cparse_line, "Template forward class instantiation '%s' with name '%s' is ineffective.\n", Swig_name_decl(templnode), Getattr(templnode, "sym:name"));
|
||||||
|
SWIG_WARN_NODE_END(templnode);
|
||||||
|
}
|
||||||
|
|
||||||
if (Strcmp(nodeType(templnode),"class") == 0) {
|
if (Strcmp(nodeType(templnode),"class") == 0) {
|
||||||
|
|
||||||
/* Identify pure abstract methods */
|
/* Identify pure abstract methods */
|
||||||
|
|
|
@ -223,6 +223,8 @@ static void cparse_template_expand(Node *templnode, Node *n, String *tname, Stri
|
||||||
cn = nextSibling(cn);
|
cn = nextSibling(cn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (Equal(nodeType, "classforward")) {
|
||||||
|
/* Nothing to expand */
|
||||||
} else if (Equal(nodeType, "constructor")) {
|
} else if (Equal(nodeType, "constructor")) {
|
||||||
if (!(Getattr(n, "templatetype"))) {
|
if (!(Getattr(n, "templatetype"))) {
|
||||||
String *symname = Getattr(n, "sym:name");
|
String *symname = Getattr(n, "sym:name");
|
||||||
|
@ -1172,12 +1174,10 @@ Node *Swig_cparse_template_locate(String *name, Parm *instantiated_parms, String
|
||||||
|
|
||||||
if (n) {
|
if (n) {
|
||||||
String *nodeType = nodeType(n);
|
String *nodeType = nodeType(n);
|
||||||
int isclass = 0;
|
|
||||||
assert(Equal(nodeType, "template"));
|
assert(Equal(nodeType, "template"));
|
||||||
(void)nodeType;
|
String *templatetype = Getattr(n, "templatetype");
|
||||||
isclass = (Equal(Getattr(n, "templatetype"), "class"));
|
|
||||||
|
|
||||||
if (isclass) {
|
if (Equal(templatetype, "class") || Equal(templatetype, "classforward")) {
|
||||||
Node *primary = Getattr(n, "primarytemplate");
|
Node *primary = Getattr(n, "primarytemplate");
|
||||||
Parm *tparmsfound = Getattr(primary ? primary : n, "templateparms");
|
Parm *tparmsfound = Getattr(primary ? primary : n, "templateparms");
|
||||||
int specialized = !tparmsfound; /* fully specialized (an explicit specialization) */
|
int specialized = !tparmsfound; /* fully specialized (an explicit specialization) */
|
||||||
|
@ -1361,8 +1361,8 @@ static void expand_defaults(ParmList *expanded_templateparms) {
|
||||||
|
|
||||||
ParmList *Swig_cparse_template_parms_expand(ParmList *instantiated_parms, Node *primary, Node *templ) {
|
ParmList *Swig_cparse_template_parms_expand(ParmList *instantiated_parms, Node *primary, Node *templ) {
|
||||||
ParmList *expanded_templateparms = CopyParmList(instantiated_parms);
|
ParmList *expanded_templateparms = CopyParmList(instantiated_parms);
|
||||||
|
|
||||||
String *templatetype = Getattr(primary, "templatetype");
|
String *templatetype = Getattr(primary, "templatetype");
|
||||||
|
|
||||||
if (Equal(templatetype, "class") || Equal(templatetype, "classforward")) {
|
if (Equal(templatetype, "class") || Equal(templatetype, "classforward")) {
|
||||||
/* Class template */
|
/* Class template */
|
||||||
ParmList *templateparms = Getattr(primary, "templateparms");
|
ParmList *templateparms = Getattr(primary, "templateparms");
|
||||||
|
@ -1400,8 +1400,9 @@ ParmList *Swig_cparse_template_parms_expand(ParmList *instantiated_parms, Node *
|
||||||
|
|
||||||
ParmList *Swig_cparse_template_partialargs_expand(ParmList *partially_specialized_parms, Node *primary, ParmList *templateparms) {
|
ParmList *Swig_cparse_template_partialargs_expand(ParmList *partially_specialized_parms, Node *primary, ParmList *templateparms) {
|
||||||
ParmList *expanded_templateparms = CopyParmList(partially_specialized_parms);
|
ParmList *expanded_templateparms = CopyParmList(partially_specialized_parms);
|
||||||
|
String *templatetype = Getattr(primary, "templatetype");
|
||||||
|
|
||||||
if (Equal(Getattr(primary, "templatetype"), "class")) {
|
if (Equal(templatetype, "class") || Equal(templatetype, "classforward")) {
|
||||||
/* Class template */
|
/* Class template */
|
||||||
int variadic = ParmList_variadic_parm(templateparms) ? 1 : 0;
|
int variadic = ParmList_variadic_parm(templateparms) ? 1 : 0;
|
||||||
/* Add default arguments from primary template */
|
/* Add default arguments from primary template */
|
||||||
|
|
|
@ -96,6 +96,7 @@
|
||||||
#define WARN_PARSE_EXTERN_TEMPLATE 327
|
#define WARN_PARSE_EXTERN_TEMPLATE 327
|
||||||
#define WARN_PARSE_ASSIGNED_VALUE 328
|
#define WARN_PARSE_ASSIGNED_VALUE 328
|
||||||
#define WARN_PARSE_USING_CONSTRUCTOR 329
|
#define WARN_PARSE_USING_CONSTRUCTOR 329
|
||||||
|
#define WARN_PARSE_TEMPLATE_FORWARD 330
|
||||||
|
|
||||||
#define WARN_CPP11_LAMBDA 340
|
#define WARN_CPP11_LAMBDA 340
|
||||||
/* Unused since 3.0.11: #define WARN_CPP11_ALIAS_DECLARATION 341 */
|
/* Unused since 3.0.11: #define WARN_CPP11_ALIAS_DECLARATION 341 */
|
||||||
|
|
Loading…
Reference in New Issue