jni: Fix templates for clang-r377782 update.
In the next clang update, non-type template parameter of function type T
is adjusted to be type "pointer to T". It follows section 17.1.8 in
c++17 standard. But it reports error when compiling code like below:
template <typename T, T fn>
class helper;
template <typename T, typename... Args, T fn(Args...)>
class helper<T(Args...), fn> {};
error: class template partial specialization is not more specialized than
the primary template [-Winvalid-partial-specialization]
The reason is the non-type template parameter fn of
helper<T(Args...), fn> is decayed to T (*)(Args...), making the partial
specialization not match primary template <typename T, T fn>.
To fix this, use <typename T, T* fn> in the primary template. And use
function pointer type explicitly in the partial template specialization
to make code clear.
Bug: 148287303
Test: run jni_compiler_tests.
Change-Id: I99731b08032574b6fc4c1d45bba19e240e9354b4
diff --git a/compiler/jni/jni_compiler_test.cc b/compiler/jni/jni_compiler_test.cc
index 0d0f8a0..0e8602e 100644
--- a/compiler/jni/jni_compiler_test.cc
+++ b/compiler/jni/jni_compiler_test.cc
@@ -147,21 +147,6 @@
(jni_type_traits<Arg>::is_ref ? 1 : 0) + count_refs_helper<Args ...>::value;
};
-template <typename T, T fn>
-struct count_refs_fn_helper;
-
-template <typename R, typename ... Args, R fn(Args...)>
-struct count_refs_fn_helper<R(Args...), fn> : public count_refs_helper<Args...> {};
-
-// Given a function type 'T' figure out how many of the parameter types are a reference.
-// -- The implicit jclass and thisObject also count as 1 reference.
-//
-// Fields:
-// * value - the result counting # of refs
-// * value_type - the type of value (size_t)
-template <typename T, T fn>
-struct count_refs : public count_refs_fn_helper<T, fn> {};
-
// Base case: No parameters = 0 refs.
size_t count_nonnull_refs_helper() {
return 0;
@@ -200,10 +185,10 @@
return count_nonnull_refs_helper(args...);
}
-template <typename T, T fn>
+template <typename T, T* fn>
struct remove_extra_parameters_helper;
-template <typename R, typename Arg1, typename Arg2, typename ... Args, R fn(Arg1, Arg2, Args...)>
+template <typename R, typename Arg1, typename Arg2, typename ... Args, R (*fn)(Arg1, Arg2, Args...)>
struct remove_extra_parameters_helper<R(Arg1, Arg2, Args...), fn> {
// Note: Do not use Args&& here to maintain C-style parameter types.
static R apply(Args... args) {
@@ -216,7 +201,7 @@
// Given a function 'fn' create a function 'apply' which will omit the JNIEnv/jklass parameters
//
// i.e. if fn(JNIEnv*,jklass,a,b,c,d,e...) then apply(a,b,c,d,e,...)
-template <typename T, T fn>
+template <typename T, T* fn>
struct jni_remove_extra_parameters : public remove_extra_parameters_helper<T, fn> {};
class JniCompilerTest : public CommonCompilerTest {
@@ -575,11 +560,11 @@
#define EXPECT_NUM_STACK_REFERENCES(val1, val2) expectNumStackReferences(val1, val2)
-template <typename T, T fn>
+template <typename T, T* fn>
struct make_jni_test_decorator;
// Decorator for "static" JNI callbacks.
-template <typename R, typename ... Args, R fn(JNIEnv*, jclass, Args...)>
+template <typename R, typename ... Args, R (*fn)(JNIEnv*, jclass, Args...)>
struct make_jni_test_decorator<R(JNIEnv*, jclass kls, Args...), fn> {
static R apply(JNIEnv* env, jclass kls, Args ... args) {
EXPECT_THREAD_STATE_FOR_CURRENT_JNI();
@@ -594,7 +579,7 @@
};
// Decorator for instance JNI callbacks.
-template <typename R, typename ... Args, R fn(JNIEnv*, jobject, Args...)>
+template <typename R, typename ... Args, R (*fn)(JNIEnv*, jobject, Args...)>
struct make_jni_test_decorator<R(JNIEnv*, jobject, Args...), fn> {
static R apply(JNIEnv* env, jobject thisObj, Args ... args) {
EXPECT_THREAD_STATE_FOR_CURRENT_JNI();