This is the mail archive of the
mailing list for the GCC project.
Re: [PING] Re: [PATCH] c/c++: Add fix-it hints for suggested missing #includes
- From: David Malcolm <dmalcolm at redhat dot com>
- To: Jeff Law <law at redhat dot com>, gcc-patches at gcc dot gnu dot org
- Date: Fri, 30 Jun 2017 16:14:06 -0400
- Subject: Re: [PING] Re: [PATCH] c/c++: Add fix-it hints for suggested missing #includes
- Authentication-results: sourceware.org; auth=none
- Authentication-results: ext-mx05.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com
- Authentication-results: ext-mx05.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=dmalcolm at redhat dot com
- Dkim-filter: OpenDKIM Filter v2.11.0 mx1.redhat.com DFD5530AF4E
- Dmarc-filter: OpenDMARC Filter v1.3.2 mx1.redhat.com DFD5530AF4E
- References: <email@example.com> <firstname.lastname@example.org> <email@example.com>
On Fri, 2017-06-30 at 09:40 -0600, Jeff Law wrote:
> On 05/26/2017 01:54 PM, David Malcolm wrote:
> > Ping:
> > https://gcc.gnu.org/ml/gcc-patches/2017-05/msg00321.html
> > On Thu, 2017-05-04 at 12:36 -0400, David Malcolm wrote:
> > > As of r247522, fix-it-hints can suggest the insertion of new
> > > lines.
> > >
> > > This patch uses this to implement a new "maybe_add_include_fixit"
> > > function in c-common.c and uses it in the two places where the C
> > > and
> > > C++
> > > frontend can suggest missing #include directives. 
> > >
> > > The idea is that the user can then click on the fix-it in an IDE
> > > and have it add the #include for them (or use -fdiagnostics
> > > -generate
> > > -patch).
> > >
> > > Examples can be seen in the test cases.
> > >
> > > The function attempts to put the #include in a reasonable place:
> > > immediately after the last #include within the file, or at the
> > > top of the file. It is idempotent, so -fdiagnostics-generate
> > > -patch
> > > does the right thing if several such diagnostics are emitted.
> > >
> > > Successfully bootstrapped®rtested on x86_64-pc-linux-gnu.
> > >
> > > OK for trunk?
> > >
> > >  I'm working on a followup which tweaks another diagnostic so
> > > that
> > > it
> > > can suggest that a #include was missing, so I'll use it there as
> > > well.
> > >
> > > gcc/c-family/ChangeLog:
> > > * c-common.c (try_to_locate_new_include_insertion_point): New
> > > function.
> > > (per_file_includes_t): New typedef.
> > > (added_includes_t): New typedef.
> > > (added_includes): New variable.
> > > (maybe_add_include_fixit): New function.
> > > * c-common.h (maybe_add_include_fixit): New decl.
> > >
> > > gcc/c/ChangeLog:
> > > * c-decl.c (implicitly_declare): When suggesting a missing
> > > #include, provide a fix-it hint.
> > >
> > > gcc/cp/ChangeLog:
> > > * name-lookup.c (get_std_name_hint): Add '<' and '>' around
> > > the header names.
> > > (maybe_suggest_missing_header): Update for addition of '<' and
> > > '>'
> > > to above. Provide a fix-it hint.
> > >
> > > gcc/testsuite/ChangeLog:
> > > * g++.dg/lookup/missing-std-include-2.C: New text case.
> > > * gcc.dg/missing-header-fixit-1.c: New test case.
> Generally OK. But a few comments on how you find the location for
> to suggest the new #include.
Thanks for looking at it.
> It looks like you're walking the whole table every time?!?
Note that try_to_locate_new_include_insertion_point is guarded by the
idempotency logic within maybe_add_include_fixit: it will be called at
most once per suggested #include.
I don't know if "walking" is the word I would have used: it's iterating
over the whole array of structs, doing a few pointer compares of fields
within it. The elements in the array are line *maps*, not lines
themselves, so it's likely to be of the order of a few thousand entries
for a source file with plenty of nested #includes.
> you at least bound things between start of file
By "start of file", do you mean "start of the main source file", or the
start of the file containing the diagnostic? AIUI, getting at this
information requires a walk forwards through the line maps, which is
exactly what the patch is doing.
> and the point where an
> error was issued? ie, if you used an undefined type on line XX, a
> #include after line XX makes no sense to resolve the error.
Hmmm. I agree that the fix-it hint would makes little sense for this
case. I did some testing of this case, and it uncovered some bugs with
the patch, so I'm going to post an updated patch, with some test
coverage for it (and addressing the bugs).
But I'd prefer to focus on correctness rather than on performance here;
because of the idempotency guard it's only called once per header file
that we "know" about (and can thus suggest in a fix-it hint).
> I'm not sure how often this will get called when someone does
> stupid and needs the #include. But ISTM you're looking for two
> For the "last" case you start at the statement which generated the
> and walk backwards stopping when you find the last map.
It's not clear to me what you're proposing. If we expand the
statement's location to get a physical location, that will be within an
ordinary line_map, within the file in question. The start of that
linemap might related to returning from a #include, but it might also
relate to changes in line length (due to cpplib trying to make best use
of the 32-bit encoding space) e.g. in the middle of a function, or in
the middle of a comment.
We could maybe use this ordinary map as an upper boundary for the
search (though I'd want to check that the logic in the search still
makes sense for this case).
> For the "first" case, you start at the beginning and walk forward to
> find the map, then quit.
Again, I'm not quite sure what you mean here.
> Are those not appropriate here?
As noted above, these feel to me like premature optimizations; I don't
see this as a performance hog, so I'd prefer to focus on getting the
implementation correct (and simple) first.
I'm working on an updated patch fixing the bugs mentioned above; does
the above address your concerns about v1 of the patch for now?
As a further followup, consider the case of a diagnostic about a
missing #include emitted within a header: if we're adding the #include
to the header (which is what the patch does), then maybe we should put
the suggested #include inside #ifndef guards if they're present, rather
than at the top of the header. I think I've now figured out how to
express that in DejaGnu :) Does that sound worth pursuing in this
patch, or in a followup?