aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family/known-headers.cc
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2020-05-22 01:10:50 +0200
committerMark Wielaard <mark@klomp.org>2020-06-04 01:22:52 +0200
commit9eea5d2ddf73037e21b59bcd8084ba969ae10174 (patch)
treefc247b15b760343e12c8472d91d08634b9340557 /gcc/c-family/known-headers.cc
parent34e4962aed08b38f37e37242234bfbbd1b897f39 (diff)
downloadgcc-9eea5d2ddf73037e21b59bcd8084ba969ae10174.zip
gcc-9eea5d2ddf73037e21b59bcd8084ba969ae10174.tar.gz
gcc-9eea5d2ddf73037e21b59bcd8084ba969ae10174.tar.bz2
Provide diagnostic hints for missing C inttypes.h string constants.
This adds a flag to c_parser so we know when we were trying to construct a string literal. If there is a parse error and we were constructing a string literal, and the next token is an unknown identifier name, and we know there is a standard header that defines that name as a string literal, then add a missing header hint to the error messsage. The list of macro names are also used when providing a hint for missing identifiers. gcc/c-family/ChangeLog: * known-headers.cc (get_string_macro_hint): New function. (get_stdlib_header_for_name): Use get_string_macro_hint. (get_c_stdlib_header_for_string_macro_name): New function. * known-headers.h (get_c_stdlib_header_for_string_macro_name): New function declaration. gcc/c/ChangeLog: * c-parser.c (struct c_parser): Add seen_string_literal bitfield. (c_parser_consume_token): Reset seen_string_literal. (c_parser_error_richloc): Add name_hint if seen_string_literal and next token is a CPP_NAME and we have a missing header suggestion for the name. (c_parser_string_literal): Set seen_string_literal. gcc/testsuite/ChangeLog: * gcc.dg/spellcheck-inttypes.c: New test. * g++.dg/spellcheck-inttypes.C: Likewise.
Diffstat (limited to 'gcc/c-family/known-headers.cc')
-rw-r--r--gcc/c-family/known-headers.cc53
1 files changed, 52 insertions, 1 deletions
diff --git a/gcc/c-family/known-headers.cc b/gcc/c-family/known-headers.cc
index 1e2bf49..c07cfd1 100644
--- a/gcc/c-family/known-headers.cc
+++ b/gcc/c-family/known-headers.cc
@@ -46,6 +46,49 @@ struct stdlib_hint
const char *header[NUM_STDLIBS];
};
+/* Given non-NULL NAME, return the header name defining it (as literal
+ string) within either the standard library (with '<' and '>'), or
+ NULL.
+
+ Only handle string macros, so that this can be used for
+ get_stdlib_header_for_name and
+ get_c_stdlib_header_for_string_macro_name. */
+
+static const char *
+get_string_macro_hint (const char *name, enum stdlib lib)
+{
+ /* <inttypes.h> and <cinttypes>. */
+ static const char *c99_cxx11_macros[] =
+ { "PRId8", "PRId16", "PRId32", "PRId64",
+ "PRIi8", "PRIi16", "PRIi32", "PRIi64",
+ "PRIo8", "PRIo16", "PRIo32", "PRIo64",
+ "PRIu8", "PRIu16", "PRIu32", "PRIu64",
+ "PRIx8", "PRIx16", "PRIx32", "PRIx64",
+ "PRIX8", "PRIX16", "PRIX32", "PRIX64",
+
+ "PRIdPTR", "PRIiPTR", "PRIoPTR", "PRIuPTR", "PRIxPTR", "PRIXPTR",
+
+ "SCNd8", "SCNd16", "SCNd32", "SCNd64",
+ "SCNi8", "SCNi16", "SCNi32", "SCNi64",
+ "SCNo8", "SCNo16", "SCNo32", "SCNo64",
+ "SCNu8", "SCNu16", "SCNu32", "SCNu64",
+ "SCNx8", "SCNx16", "SCNx32", "SCNx64",
+
+ "SCNdPTR", "SCNiPTR", "SCNoPTR", "SCNuPTR", "SCNxPTR" };
+
+ if ((lib == STDLIB_C && flag_isoc99)
+ || (lib == STDLIB_CPLUSPLUS && cxx_dialect >= cxx11 ))
+ {
+ const size_t num_c99_cxx11_macros
+ = sizeof (c99_cxx11_macros) / sizeof (c99_cxx11_macros[0]);
+ for (size_t i = 0; i < num_c99_cxx11_macros; i++)
+ if (strcmp (name, c99_cxx11_macros[i]) == 0)
+ return lib == STDLIB_C ? "<inttypes.h>" : "<cinttypes>";
+ }
+
+ return NULL;
+}
+
/* Given non-NULL NAME, return the header name defining it within either
the standard library (with '<' and '>'), or NULL.
Only handles a subset of the most common names within the stdlibs. */
@@ -196,7 +239,7 @@ get_stdlib_header_for_name (const char *name, enum stdlib lib)
if (strcmp (name, c99_cxx11_hints[i].name) == 0)
return c99_cxx11_hints[i].header[lib];
- return NULL;
+ return get_string_macro_hint (name, lib);
}
/* Given non-NULL NAME, return the header name defining it within the C
@@ -217,6 +260,14 @@ get_cp_stdlib_header_for_name (const char *name)
return get_stdlib_header_for_name (name, STDLIB_CPLUSPLUS);
}
+/* Given non-NULL NAME, return the header name defining a string macro
+ within the C standard library (with '<' and '>'), or NULL. */
+const char *
+get_c_stdlib_header_for_string_macro_name (const char *name)
+{
+ return get_string_macro_hint (name, STDLIB_C);
+}
+
/* Implementation of class suggest_missing_header. */
/* suggest_missing_header's ctor. */