C/C++: more stdlib header hints (PR c/81404)
authorDavid Malcolm <dmalcolm@redhat.com>
Tue, 21 Nov 2017 00:50:39 +0000 (00:50 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Tue, 21 Nov 2017 00:50:39 +0000 (00:50 +0000)
commit26edace69b6b909eebddcf18c8844bb4c94d9a35
treec414ee9be1fe6e6f9cd8b371e22e609482196e19
parentb1212255558f0a4a398c7314f92effe4dbdcfec2
C/C++: more stdlib header hints (PR c/81404)

This patch extends the C frontend's "knowledge" of the C stdlib within
get_c_name_hint to cover some more macros and functions, covering
a case reported in PR c/81404 ("INT_MAX"), so that rather than printing:

  t.c:5:12: error: 'INT_MAX' undeclared here (not in a function); did you mean '__INT_MAX__'?
   int test = INT_MAX;
              ^~~~~~~
              __INT_MAX__

we instead print:

  t.c:5:12: error: 'INT_MAX' undeclared here (not in a function)
   int test = INT_MAX;
              ^~~~~~~
  t.c:5:12: note: 'INT_MAX' is defined in header '<limits.h>'; did you forget to '#include <limits.h>'?
  t.c:1:1:
  +#include <limits.h>

  t.c:5:12:
    int test = INT_MAX;
               ^~~~~~~

It also adds generalizes some of the code for this (and for the "std::"
namespace hints in the C++ frontend), moving it to a new
c-family/known-headers.cc and .h, and introducing a class known_headers.
This currently just works by scanning a hardcoded array of known
name/header associations, but perhaps in the future could be turned
into some kind of symbol database so that the compiler could record API
uses and use that to offer suggestions e.g.

foo.cc: error: 'myapi::foo' was not declared in this scope
foo.cc: note: 'myapi::foo" was declared in header 'myapi/private.h'
(included via 'myapi/public.h') when compiling 'bar.cc'; did you forget to
'#include "myapi/public.h"'?

or somesuch.

In any case, moving this to a class gives an easier way to locate the
hardcoded knowledge about the stdlib.

The patch also adds similar code to the C++ frontend covering
unqualified names in the standard library, so that rather than just
e.g.:

  t.cc:19:13: error: 'NULL' was not declared in this scope
   void *ptr = NULL;
               ^~~~

we can emit:

  t.cc:19:13: error: 'NULL' was not declared in this scope
   void *ptr = NULL;
               ^~~~
  t.cc:19:13: note: 'NULL' is defined in header '<cstddef>'; did you forget
  to '#include <cstddef>'?
  t.cc:1:1:
  +#include <cstddef>

  t.cc:19:13:
   void *ptr = NULL;
               ^~~~

(Also XFAIL for PR c++/80567 added for the C++ testcase; this is a
separate pre-existing bug exposed by the testcase for PR 81404).

gcc/ChangeLog:
PR c/81404
* Makefile.in (C_COMMON_OBJS): Add c-family/known-headers.o.

gcc/c-family/ChangeLog:
PR c/81404
* known-headers.cc: New file, based on material from c/c-decl.c.
(suggest_missing_header): Copied as-is.
(get_stdlib_header_for_name): New, based on get_c_name_hint but
heavily edited to add C++ support.  Add some knowledge about
<limits.h>, <stdint.h>, and <wchar.h>.
* known-headers.h: Likewise.

gcc/c/ChangeLog:
PR c/81404
* c-decl.c: Include "c-family/known-headers.h".
(get_c_name_hint): Rename to get_stdlib_header_for_name and move
to known-headers.cc.
(class suggest_missing_header): Move to known-header.h.
(lookup_name_fuzzy): Call get_c_stdlib_header_for_name rather
than get_c_name_hint.

gcc/cp/ChangeLog:
PR c/81404
* name-lookup.c: Include "c-family/known-headers.h"
(lookup_name_fuzzy): Call get_cp_stdlib_header_for_name and
potentially return a new suggest_missing_header hint.

gcc/testsuite/ChangeLog:
PR c/81404
* g++.dg/spellcheck-stdlib.C: New.
* gcc.dg/spellcheck-stdlib.c (test_INT_MAX): New.

From-SVN: r254980
12 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/c-family/ChangeLog
gcc/c-family/known-headers.cc [new file with mode: 0644]
gcc/c-family/known-headers.h [new file with mode: 0644]
gcc/c/ChangeLog
gcc/c/c-decl.c
gcc/cp/ChangeLog
gcc/cp/name-lookup.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/spellcheck-stdlib.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/spellcheck-stdlib.c