diff --git a/CHANGES.current b/CHANGES.current
index a9ba1ebaf..59257dc09 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -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;
+ extern template void Func();
+
+ 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
diff --git a/Doc/Manual/CPlusPlus11.html b/Doc/Manual/CPlusPlus11.html
index e5d7fbc2d..86a35bfaa 100644
--- a/Doc/Manual/CPlusPlus11.html
+++ b/Doc/Manual/CPlusPlus11.html
@@ -144,14 +144,39 @@ When either of these is used from a target language, a runtime call is made to o
-SWIG correctly parses the keywords extern template.
+
SWIG correctly parses extern template 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 %template for instantiating and wrapping templates.
+SWIG only uses %template for instantiating and wrapping templates.
+Consider the class template below:
+
-template class std::vector<int>; // C++03 explicit instantiation in C++
-extern template class std::vector<int>; // C++11 explicit instantiation suppression in C++
-%template(VectorInt) std::vector<int>; // SWIG instantiation
+// 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
+
+
+
+The above result in warnings:
+
+
+
+
+example.i:2: Warning 320: Explicit template instantiation ignored.
+example.i:3: Warning 327: Extern template ignored.
+
+
+
+
+Similarly for the function template below:
+
+
+
+// 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
diff --git a/Doc/Manual/Warnings.html b/Doc/Manual/Warnings.html
index 02197f1cb..5d4d3773b 100644
--- a/Doc/Manual/Warnings.html
+++ b/Doc/Manual/Warnings.html
@@ -428,6 +428,7 @@ example.i(4) : Syntax error in input(1).
324. Named nested template instantiations not supported. Processing as if no name was given to %template().
325. Nested kind not currently supported (name ignored).
326. Deprecated %extend name used - the kind name 'name' should be used instead of the typedef name 'name'.
+327. Extern template ignored.
350. operator new ignored.
351. operator delete ignored.
352. operator+ ignored.
diff --git a/Examples/test-suite/cpp11_template_explicit.i b/Examples/test-suite/cpp11_template_explicit.i
index 0a76b93d8..630342862 100644
--- a/Examples/test-suite/cpp11_template_explicit.i
+++ b/Examples/test-suite/cpp11_template_explicit.i
@@ -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 %{
diff --git a/Examples/test-suite/errors/cpp_template_explicit_instantiation.i b/Examples/test-suite/errors/cpp_template_explicit_instantiation.i
new file mode 100644
index 000000000..97513724b
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_template_explicit_instantiation.i
@@ -0,0 +1,24 @@
+%module xxx
+
+%inline %{
+namespace std {
+ template class vector {};
+}
+template void Func() {}
+%}
+
+%inline %{
+// Class template
+template class std::vector; // C++03 template explicit instantiation definition in C++
+extern template class std::vector; // C++11 template explicit instantiation declaration (extern template)
+%}
+%template(VectorInt) std::vector; // SWIG template instantiation
+
+%inline %{
+// Function template
+template void Func(); // C++03 template explicit instantiation definition in C++
+extern template void Func(); // C++11 template explicit instantiation declaration (extern template)
+%}
+%template(FuncInt) Func; // SWIG template instantiation
+
+
diff --git a/Examples/test-suite/errors/cpp_template_explicit_instantiation.stderr b/Examples/test-suite/errors/cpp_template_explicit_instantiation.stderr
new file mode 100644
index 000000000..052d3de27
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_template_explicit_instantiation.stderr
@@ -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.
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index a21d029e0..0796362bc 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -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;
diff --git a/Source/Include/swigwarn.h b/Source/Include/swigwarn.h
index 955a8773a..a57afbe36 100644
--- a/Source/Include/swigwarn.h
+++ b/Source/Include/swigwarn.h
@@ -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 */