Eric Botcazou <ebotca...@adacore.com> writes: >> Index: gcc/tree.c >> =================================================================== >> --- gcc/tree.c 2019-01-04 11:39:24.810266962 +0000 >> +++ gcc/tree.c 2019-01-04 11:40:33.141683783 +0000 >> @@ -11229,6 +11229,60 @@ initializer_zerop (const_tree init, bool >> } >> } >> >> +/* Return true if EXPR is an initializer expression that consists only >> + of INTEGER_CSTs for which IP0 or IP1 holds and REAL_CSTs for which >> + RP0 or RP1 holds. The choice between IP0 and IP1, and between >> + RP0 and RP1, can vary from one element to the next. */ >> + >> +template<bool (*IP0) (const_tree), bool (*IP1) (const_tree), >> + bool (*RP0) (const_tree), bool (*RP1) (const_tree)> >> +bool >> +initializer_each_a_or_bp (const_tree expr) >> +{ >> +#define RECURSE(X) initializer_each_a_or_bp<IP0, IP1, RP0, RP1> (X) >> + >> + STRIP_ANY_LOCATION_WRAPPER (expr); >> + >> + switch (TREE_CODE (expr)) >> + { >> + case INTEGER_CST: >> + return IP0 (expr) || IP1 (expr); >> + >> + case REAL_CST: >> + return RP0 (expr) || RP1 (expr); >> + >> + case VECTOR_CST: >> + { >> + unsigned HOST_WIDE_INT nelts = vector_cst_encoded_nelts (expr); >> + if (VECTOR_CST_STEPPED_P (expr) >> + && !TYPE_VECTOR_SUBPARTS (TREE_TYPE (expr)).is_constant (&nelts)) >> + return false; >> + >> + for (unsigned int i = 0; i < nelts; ++i) >> + if (!RECURSE (VECTOR_CST_ENCODED_ELT (expr, i))) >> + return false; >> + >> + return true; >> + } >> + >> + default: >> + return false; >> + } >> + >> +#undef RECURSE > > Can we avoid the gratuitous use of template here? We were told that C++ > would > be used only when it makes things more straightforward and it's the contrary > in this case, to wit the need for the ugly RECURSE macro in the middle.
I did it that way so that it would be easy to add things like zero_or_minus_onep without cut-&-pasting the whole structure. The way to do that in C would be to use a macro for the full function, but that's even uglier due to the extra backslashes. I can change it to: for (unsigned int i = 0; i < nelts; ++i) { tree elt = VECTOR_CST_ENCODED_ELT (expr, i); if (!initializer_each_a_or_bp<IP0, IP1, RP0, RP1> (elt)) return false; } if we want to avoid macros. I was actually worried that this wouldn't be C++ enough, due to not using a function template to combine each pair of functions. :-) Richard