Template instantion fixes when template parameter is used twice in type
For example T in:
Y<T>::YYY<T>::value_type
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index 6794c2e..595ba4a 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -560,6 +560,7 @@
# C++11 test cases.
CPP11_TEST_CASES += \
+ cpp11_alias_nested_template_scoping \
cpp11_alignment \
cpp11_alternate_function_syntax \
cpp11_constexpr \
@@ -575,7 +576,6 @@
cpp11_initializer_list \
cpp11_initializer_list_extend \
cpp11_lambda_functions \
- cpp11_std_array \
cpp11_noexcept \
cpp11_null_pointer_constant \
cpp11_raw_string_literals \
@@ -588,6 +588,7 @@
cpp11_rvalue_reference3 \
cpp11_sizeof_object \
cpp11_static_assert \
+ cpp11_std_array \
cpp11_strongly_typed_enumerations \
cpp11_thread_local \
cpp11_template_double_brackets \
diff --git a/Examples/test-suite/cpp11_alias_nested_template_scoping.i b/Examples/test-suite/cpp11_alias_nested_template_scoping.i
new file mode 100644
index 0000000..0cf5ea3
--- /dev/null
+++ b/Examples/test-suite/cpp11_alias_nested_template_scoping.i
@@ -0,0 +1,45 @@
+%module cpp11_alias_nested_template_scoping
+
+// Test to check a template parameter type is expanded when the template parameter
+// is used twice in a type name. Expansion was
+// Y< short >::YYY< T >::value_type >
+// instead of
+// Y< short >::YYY< short >::value_type >
+
+#if !defined(SWIGCSHARP) && !defined(SWIGJAVA)
+%feature("flatnested") ZZZ;
+#endif
+
+%inline %{
+template<typename T> struct Y {
+ typedef T value_type;
+ typedef Y YY;
+ template<typename T2> using YYY = Y<T2>;
+ template<typename T2> struct ZZZ {
+ typedef T2 another_type;
+ };
+ value_type create1() const { return T(); }
+ Y::value_type create2() const { return T(); }
+ Y<T>::value_type create3() const { return T(); }
+ YY::value_type create4() const { return T(); }
+ Y<T>::YY::value_type create5() const { return T(); }
+ Y<T>::YYY<T>::value_type create6() const { return T(); }
+ typename Y<T>::template ZZZ<T>::another_type create7() const { return T(); }
+
+ // With global scope prefix
+ ::Y<T>::value_type create13() const { return T(); }
+
+ ::Y<T>::YY::value_type create15() const { return T(); }
+ ::Y<T>::YYY<T>::value_type create16() const { return T(); }
+ typename ::Y<T>::template ZZZ<T>::another_type create17() const { return T(); }
+};
+%}
+
+%extend Y {
+%template() YYY<short>;
+%template() ZZZ<short>;
+};
+// Use above workaround instead of below (which currently gives syntax error)
+// %template() Y<short>::YYY<short>;
+
+%template(Yshort) Y<short>;
diff --git a/Examples/test-suite/java/cpp11_alias_nested_template_scoping_runme.java b/Examples/test-suite/java/cpp11_alias_nested_template_scoping_runme.java
new file mode 100644
index 0000000..7afa83a
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_alias_nested_template_scoping_runme.java
@@ -0,0 +1,32 @@
+
+import cpp11_alias_nested_template_scoping.*;
+
+public class cpp11_alias_nested_template_scoping_runme {
+
+ static {
+ try {
+ System.loadLibrary("cpp11_alias_nested_template_scoping");
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+ System.exit(1);
+ }
+ }
+
+ public static void main(String argv[]) {
+ Yshort ys = new Yshort();
+ short val = 0;
+ val = ys.create1();
+ val = ys.create2();
+ val = ys.create3();
+ val = ys.create4();
+ val = ys.create5();
+ val = ys.create6();
+ val = ys.create7();
+
+ val = ys.create13();
+
+ val = ys.create15();
+ val = ys.create16();
+ val = ys.create17();
+ }
+}
diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c
index 364329d..66518f5 100644
--- a/Source/Swig/stype.c
+++ b/Source/Swig/stype.c
@@ -1310,6 +1310,7 @@
Putc(',', nt);
}
tsuffix = SwigType_templatesuffix(e);
+ SwigType_typename_replace(tsuffix, pat, rep);
Printf(nt, ")>%s", tsuffix);
Delete(tsuffix);
Clear(e);
@@ -1318,13 +1319,24 @@
Delete(tparms);
}
} else if (Swig_scopename_check(e)) {
- String *first, *rest;
- first = Swig_scopename_first(e);
- rest = Swig_scopename_suffix(e);
- SwigType_typename_replace(rest, pat, rep);
- SwigType_typename_replace(first, pat, rep);
+ String *first = 0;
+ String *rest = 0;
+ Swig_scopename_split(e, &first, &rest);
+
+ /* Swig_scopename_split doesn't handle :: prefix very well ... could do with a rework */
+ if (Strncmp(rest, "::", 2) == 0) {
+ String *tmp = NewString(Char(rest) + 2);
+ Clear(rest);
+ Printv(rest, tmp, NIL);
+ Delete(tmp);
+ assert(!first);
+ }
+
Clear(e);
- Printv(e, first, "::", rest, NIL);
+ if (first)
+ SwigType_typename_replace(first, pat, rep);
+ SwigType_typename_replace(rest, pat, rep);
+ Printv(e, first ? first : "", "::", rest, NIL);
Delete(first);
Delete(rest);
}