Extern template tweaks

Document extern template functions support.
Extern templates result in new warning to differentiate
from template explicit instantiation definition warning.
This commit is contained in:
William S Fulton 2022-01-25 00:28:08 +00:00
commit 017900d57e
8 changed files with 89 additions and 16 deletions

View file

@ -7,6 +7,22 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
2022-01-25: wsfulton
New warning 327 for extern templates, eg:
extern template class std::vector<int>;
extern template void Func<int>();
results in warning
example.i:3: Warning 327: Extern template ignored.
example.i:4: Warning 327: Extern template ignored.
Extern template classes previously resulted in warning 320.
2022-01-24: romintomasetti
#2131 #2157 C++11 extern function template parsing error fix.
2022-01-21: wsfulton
#2120 #2138 Replace legacy PCRE dependency with PCRE2.
This requires changes for building SWIG from source. See updated

View file

@ -144,14 +144,39 @@ When either of these is used from a target language, a runtime call is made to o
<H3><a name="CPlusPlus11_extern_template">7.2.3 Extern template</a></H3>
<p>SWIG correctly parses the keywords <tt>extern template</tt>.
<p>SWIG correctly parses <tt>extern template</tt> explicit instantiation declarations.
However, this template instantiation suppression in a translation unit has no relevance outside of the C++ compiler and so is not used by SWIG.
SWIG only uses <tt>%template</tt> for instantiating and wrapping templates.</p>
SWIG only uses <tt>%template</tt> for instantiating and wrapping templates.
Consider the class template below:
</p>
<div class="code"><pre>
template class std::vector&lt;int&gt;; // C++03 explicit instantiation in C++
extern template class std::vector&lt;int&gt;; // C++11 explicit instantiation suppression in C++
%template(VectorInt) std::vector&lt;int&gt;; // SWIG instantiation
// Class template
template class std::vector&lt;int&gt;; // C++03 template explicit instantiation definition in C++
extern template class std::vector&lt;int&gt;; // C++11 template explicit instantiation declaration (extern template)
%template(VectorInt) std::vector&lt;int&gt;; // SWIG template instantiation
</pre></div>
<p>
The above result in warnings:
</p>
<div class="shell">
<pre>
example.i:2: Warning 320: Explicit template instantiation ignored.
example.i:3: Warning 327: Extern template ignored.
</pre>
</div>
<p>
Similarly for the function template below:
</p>
<div class="code"><pre>
// Function template
template void Func&lt;int&gt;(); // C++03 template explicit instantiation definition in C++
extern template void Func&lt;int&gt;(); // C++11 template explicit instantiation declaration (extern template)
%template(FuncInt) Func&lt;int&gt;; // SWIG template instantiation
</pre></div>
<H3><a name="CPlusPlus11_initializer_lists">7.2.4 Initializer lists</a></H3>

View file

@ -428,6 +428,7 @@ example.i(4) : Syntax error in input(1).
<li>324. Named nested template instantiations not supported. Processing as if no name was given to %template().
<li>325. Nested <em>kind</em> not currently supported (<em>name</em> ignored).
<li>326. Deprecated %extend name used - the <em>kind</em> name '<em>name</em>' should be used instead of the typedef name '<em>name</em>'.
<li>327. Extern template ignored.
<li>350. operator new ignored.
<li>351. operator delete ignored.
<li>352. operator+ ignored.

View file

@ -4,8 +4,9 @@
*/
%module cpp11_template_explicit
/* Explicitely silence SWIG warning related to explicit templates */
/* Suppress SWIG warnings related to explicit template instantiation and extern templates */
#pragma SWIG nowarn=SWIGWARN_PARSE_EXPLICIT_TEMPLATE
#pragma SWIG nowarn=SWIGWARN_PARSE_EXTERN_TEMPLATE
%inline %{

View file

@ -0,0 +1,24 @@
%module xxx
%inline %{
namespace std {
template<typename T> class vector {};
}
template<typename T> void Func() {}
%}
%inline %{
// Class template
template class std::vector<int>; // C++03 template explicit instantiation definition in C++
extern template class std::vector<int>; // C++11 template explicit instantiation declaration (extern template)
%}
%template(VectorInt) std::vector<int>; // SWIG template instantiation
%inline %{
// Function template
template void Func<int>(); // C++03 template explicit instantiation definition in C++
extern template void Func<int>(); // C++11 template explicit instantiation declaration (extern template)
%}
%template(FuncInt) Func<int>; // SWIG template instantiation

View file

@ -0,0 +1,4 @@
cpp_template_explicit_instantiation.i:12: Warning 320: Explicit template instantiation ignored.
cpp_template_explicit_instantiation.i:13: Warning 327: Extern template ignored.
cpp_template_explicit_instantiation.i:19: Warning 320: Explicit template instantiation ignored.
cpp_template_explicit_instantiation.i:20: Warning 327: Extern template ignored.

View file

@ -4355,29 +4355,30 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN {
parsing_template_declaration = 0;
}
/* Explicit template instantiation */
/* Class template explicit instantiation definition */
| TEMPLATE cpptype idcolon {
Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit template instantiation ignored.\n");
$$ = 0;
}
/* Explicit function template instantiation */
/* Function template explicit instantiation definition */
| TEMPLATE cpp_alternate_rettype idcolon LPAREN parms RPAREN {
Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit function template instantiation ignored.\n");
Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit template instantiation ignored.\n");
$$ = 0;
}
}
/* Explicit class template instantiation without the translation unit */
/* Class template explicit instantiation declaration (extern template) */
| EXTERN TEMPLATE cpptype idcolon {
Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit (extern) class template instantiation ignored.\n");
Swig_warning(WARN_PARSE_EXTERN_TEMPLATE, cparse_file, cparse_line, "Extern template ignored.\n");
$$ = 0;
}
/* Explicit function template instantiation without the translation unit */
/* Function template explicit instantiation declaration (extern template) */
| EXTERN TEMPLATE cpp_alternate_rettype idcolon LPAREN parms RPAREN {
Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit (extern) function template instantiation ignored.\n");
Swig_warning(WARN_PARSE_EXTERN_TEMPLATE, cparse_file, cparse_line, "Extern template ignored.\n");
$$ = 0;
}
;
}
;
cpp_template_possible: c_decl {
$$ = $1;

View file

@ -93,6 +93,7 @@
#define WARN_PARSE_NESTED_TEMPLATE 324
#define WARN_PARSE_NAMED_NESTED_CLASS 325
#define WARN_PARSE_EXTEND_NAME 326
#define WARN_PARSE_EXTERN_TEMPLATE 327
#define WARN_CPP11_LAMBDA 340
#define WARN_CPP11_ALIAS_DECLARATION 341 /* redundant now */