diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 6794c2e8b..595ba4ae6 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -560,6 +560,7 @@ CPP_TEST_CASES += \ # 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_TEST_CASES += \ 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_TEST_CASES += \ 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 000000000..0cf5ea35a --- /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 struct Y { + typedef T value_type; + typedef Y YY; + template using YYY = Y; + template struct ZZZ { + typedef T2 another_type; + }; + value_type create1() const { return T(); } + Y::value_type create2() const { return T(); } + Y::value_type create3() const { return T(); } + YY::value_type create4() const { return T(); } + Y::YY::value_type create5() const { return T(); } + Y::YYY::value_type create6() const { return T(); } + typename Y::template ZZZ::another_type create7() const { return T(); } + + // With global scope prefix + ::Y::value_type create13() const { return T(); } + + ::Y::YY::value_type create15() const { return T(); } + ::Y::YYY::value_type create16() const { return T(); } + typename ::Y::template ZZZ::another_type create17() const { return T(); } +}; +%} + +%extend Y { +%template() YYY; +%template() ZZZ; +}; +// Use above workaround instead of below (which currently gives syntax error) +// %template() Y::YYY; + +%template(Yshort) Y; 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 000000000..7afa83a0f --- /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 364329d08..66518f50c 100644 --- a/Source/Swig/stype.c +++ b/Source/Swig/stype.c @@ -1310,6 +1310,7 @@ void SwigType_typename_replace(SwigType *t, String *pat, String *rep) { Putc(',', nt); } tsuffix = SwigType_templatesuffix(e); + SwigType_typename_replace(tsuffix, pat, rep); Printf(nt, ")>%s", tsuffix); Delete(tsuffix); Clear(e); @@ -1318,13 +1319,24 @@ void SwigType_typename_replace(SwigType *t, String *pat, String *rep) { 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); }