Template instantion fixes when template parameter is used twice in type

For example T in:
Y<T>::YYY<T>::value_type
This commit is contained in:
William S Fulton 2019-02-17 17:10:46 +00:00
parent de861bea64
commit 629c881de5
4 changed files with 97 additions and 7 deletions

View File

@ -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 \

View File

@ -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>;

View File

@ -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();
}
}

View File

@ -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);
}