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

Reply via email to