On 02/13/2018 04:05 PM, David Malcolm wrote:
On Tue, 2018-02-13 at 15:37 -0700, Martin Sebor wrote:
On 02/13/2018 01:59 PM, Manuel López-Ibáñez wrote:


On 13 Feb 2018 5:58 pm, "Martin Sebor" <mse...@gmail.com
<mailto:mse...@gmail.com>> wrote:


    I wanted to make the _n() functions like warning_n() more
    robust by letting them accept a tree argument (as well as
    offset_int and wide_int) in addition to HOST_WIDE_INT but
    I can't do it if they can't work with these types.


There must be a tree-diagnostics.c where you can add those
functions and
then call the general diagnostic functions. Same for RTL.

I don't see how to do that.

Here's a sketch of what I tried to do:

   struct IntegerConverter
   {
     union {
       tree t;
       unsigned HOST_WIDE_INT hwi;
       // buffer for offset_int, wide_int, etc.
     } value;

     IntegerConverter (tree t)
     {
       value.t = t;
     }

     IntegerConverter (unsigned HOST_WIDE_INT x)
     {
       value.x = x;
     }

     ...
   };

   void error_n (int, const IntegerConverter &, const char*, ...);
   ...

With that, the call

   error_n (loc, t, "%E thing", "%E things", t);

works when t is a tree, and the call to the same function

   error_n (loc, i, "%wu thing", "%wu things", i);

also works when i is a HOST_WIDE_INT.  I chose this approach
to avoid introducing additional overloads of the error_n()
functions.

Why can't you simply introduce a tree-diagnostic.h and tree-
diagnostic.c and put overloads there?

In diagnostic.c the various _n all use diagnostic_n_impl, which
ultimately calls out to
  ngettext (singular_gmsgid, plural_gmsgid, n)
so there would presumably be an analogous "diagnostic_n_hwi_impl" (or
somesuch) function there to do the same thing.

The analogous function would, in fact, do the exact same
thing.


That would keep the tree stuff separated from the rest of the
diagnostics subsystem.

Or am I missing something?

(Sorry if I'm being overly verbose below.  I'm just trying
to make things clear.)

I wasn't introducing overloads.  I was replacing each of
the existing error_n() and related functions with one that
takes an IntegerConverter argument instead of the int n
argument.  The IntegerConverter constructor is overloaded
on all the types I want to be able to call error_n() with
(tree, offset_int, wide_int, and perhaps also the various
flavors of poly_int).  That has the effect if overloading
each of the functions on each of the types
the IntegerConverter class constructor is overloaded on.

Introducing new overloads of error_n() et al. and keeping
the ones in diagnostic-core.h would lead to ambiguities.
E.g., the call to

  error_n (loc, i, "%wu thing", "%wu things", i);

would be ambiguous if i were signed long (converting it
to unsigned long is no better than converting it to int).

I could change the existing error_n() to take HOST_WIDE_INT
instead of int as an argument and also add the overload(s)
as you suggest.  But the last time this issue came up Jakub
had a strong preference for not adding overloads of these
functions.  It also didn't occur to me to duplicate all
these functions.  Does that seem like a good approach to
you? (I mean, to have two parallel sets of functions that
do the same thing and only differ in the type of one of
their arguments.  If duplicating the signatures is
thought to be the right solution to achieve modularity
then I would think that ultimately one should call
the other.)

Martin


Hope this is constructive
Dave

Note that pretty-printer.c works in the same way.

It works that way for arguments passed through the ellipsis.
I was trying to use tree (indirectly) in the signature of
the _n() functions and for that I need "tree.h" etc. in
diagnostic-core.h and be able to call functions from
the header in diagnostic-core.c.  I suppose I could make
the calls indirectly somehow but I can't avoid including
GCC headers in diagnostic-core.h.

Martin


Reply via email to