]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/c-family/known-headers.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / c-family / known-headers.cc
1 /* Support for suggestions about missing #include directives.
2 Copyright (C) 2017-2021 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
19
20 #include "config.h"
21 #define INCLUDE_UNIQUE_PTR
22 #include "system.h"
23 #include "coretypes.h"
24 #include "c-family/c-common.h"
25 #include "c-family/name-hint.h"
26 #include "c-family/known-headers.h"
27 #include "gcc-rich-location.h"
28
29 /* An enum for distinguishing between the C and C++ stdlibs. */
30
31 enum stdlib
32 {
33 STDLIB_C,
34 STDLIB_CPLUSPLUS,
35
36 NUM_STDLIBS
37 };
38
39 /* A struct for associating names in a standard library with the header
40 that should be included to locate them, for each of the C and C++ stdlibs
41 (or NULL, for names that aren't in a header for a particular stdlib). */
42
43 struct stdlib_hint
44 {
45 const char *name;
46 const char *header[NUM_STDLIBS];
47 };
48
49 /* Given non-NULL NAME, return the header name defining it (as literal
50 string) within either the standard library (with '<' and '>'), or
51 NULL.
52
53 Only handle string macros, so that this can be used for
54 get_stdlib_header_for_name and
55 get_c_stdlib_header_for_string_macro_name. */
56
57 static const char *
58 get_string_macro_hint (const char *name, enum stdlib lib)
59 {
60 /* <inttypes.h> and <cinttypes>. */
61 static const char *c99_cxx11_macros[] =
62 { "PRId8", "PRId16", "PRId32", "PRId64",
63 "PRIi8", "PRIi16", "PRIi32", "PRIi64",
64 "PRIo8", "PRIo16", "PRIo32", "PRIo64",
65 "PRIu8", "PRIu16", "PRIu32", "PRIu64",
66 "PRIx8", "PRIx16", "PRIx32", "PRIx64",
67 "PRIX8", "PRIX16", "PRIX32", "PRIX64",
68
69 "PRIdPTR", "PRIiPTR", "PRIoPTR", "PRIuPTR", "PRIxPTR", "PRIXPTR",
70
71 "SCNd8", "SCNd16", "SCNd32", "SCNd64",
72 "SCNi8", "SCNi16", "SCNi32", "SCNi64",
73 "SCNo8", "SCNo16", "SCNo32", "SCNo64",
74 "SCNu8", "SCNu16", "SCNu32", "SCNu64",
75 "SCNx8", "SCNx16", "SCNx32", "SCNx64",
76
77 "SCNdPTR", "SCNiPTR", "SCNoPTR", "SCNuPTR", "SCNxPTR" };
78
79 if ((lib == STDLIB_C && flag_isoc99)
80 || (lib == STDLIB_CPLUSPLUS && cxx_dialect >= cxx11 ))
81 {
82 const size_t num_c99_cxx11_macros
83 = sizeof (c99_cxx11_macros) / sizeof (c99_cxx11_macros[0]);
84 for (size_t i = 0; i < num_c99_cxx11_macros; i++)
85 if (strcmp (name, c99_cxx11_macros[i]) == 0)
86 return lib == STDLIB_C ? "<inttypes.h>" : "<cinttypes>";
87 }
88
89 return NULL;
90 }
91
92 /* Given non-NULL NAME, return the header name defining it within either
93 the standard library (with '<' and '>'), or NULL.
94 Only handles a subset of the most common names within the stdlibs. */
95
96 static const char *
97 get_stdlib_header_for_name (const char *name, enum stdlib lib)
98 {
99 gcc_assert (name);
100 gcc_assert (lib < NUM_STDLIBS);
101
102 static const stdlib_hint hints[] = {
103 /* <assert.h> and <cassert>. */
104 {"assert", {"<assert.h>", "<cassert>"} },
105
106 /* <errno.h> and <cerrno>. */
107 {"errno", {"<errno.h>", "<cerrno>"} },
108
109 /* <limits.h> and <climits>. */
110 {"CHAR_BIT", {"<limits.h>", "<climits>"} },
111 {"CHAR_MAX", {"<limits.h>", "<climits>"} },
112 {"CHAR_MIN", {"<limits.h>", "<climits>"} },
113 {"INT_MAX", {"<limits.h>", "<climits>"} },
114 {"INT_MIN", {"<limits.h>", "<climits>"} },
115 {"LLONG_MAX", {"<limits.h>", "<climits>"} },
116 {"LLONG_MIN", {"<limits.h>", "<climits>"} },
117 {"LONG_MAX", {"<limits.h>", "<climits>"} },
118 {"LONG_MIN", {"<limits.h>", "<climits>"} },
119 {"MB_LEN_MAX", {"<limits.h>", "<climits>"} },
120 {"SCHAR_MAX", {"<limits.h>", "<climits>"} },
121 {"SCHAR_MIN", {"<limits.h>", "<climits>"} },
122 {"SHRT_MAX", {"<limits.h>", "<climits>"} },
123 {"SHRT_MIN", {"<limits.h>", "<climits>"} },
124 {"UCHAR_MAX", {"<limits.h>", "<climits>"} },
125 {"UINT_MAX", {"<limits.h>", "<climits>"} },
126 {"ULLONG_MAX", {"<limits.h>", "<climits>"} },
127 {"ULONG_MAX", {"<limits.h>", "<climits>"} },
128 {"USHRT_MAX", {"<limits.h>", "<climits>"} },
129
130 /* <float.h> and <cfloat>. */
131 {"DBL_MAX", {"<float.h>", "<cfloat>"} },
132 {"DBL_MIN", {"<float.h>", "<cfloat>"} },
133 {"FLT_MAX", {"<float.h>", "<cfloat>"} },
134 {"FLT_MIN", {"<float.h>", "<cfloat>"} },
135 {"LDBL_MAX", {"<float.h>", "<cfloat>"} },
136 {"LDBL_MIN", {"<float.h>", "<cfloat>"} },
137
138 /* <stdarg.h> and <cstdarg>. */
139 {"va_list", {"<stdarg.h>", "<cstdarg>"} },
140
141 /* <stddef.h> and <cstddef>. */
142 {"NULL", {"<stddef.h>", "<cstddef>"} },
143 {"nullptr_t", {NULL, "<cstddef>"} },
144 {"offsetof", {"<stddef.h>", "<cstddef>"} },
145 {"ptrdiff_t", {"<stddef.h>", "<cstddef>"} },
146 {"size_t", {"<stddef.h>", "<cstddef>"} },
147 {"wchar_t", {"<stddef.h>", NULL /* a keyword in C++ */} },
148
149 /* <stdio.h> and <cstdio>. */
150 {"BUFSIZ", {"<stdio.h>", "<cstdio>"} },
151 {"EOF", {"<stdio.h>", "<cstdio>"} },
152 {"FILE", {"<stdio.h>", "<cstdio>"} },
153 {"FILENAME_MAX", {"<stdio.h>", "<cstdio>"} },
154 {"fopen", {"<stdio.h>", "<cstdio>"} },
155 {"fpos_t", {"<stdio.h>", "<cstdio>"} },
156 {"getchar", {"<stdio.h>", "<cstdio>"} },
157 {"printf", {"<stdio.h>", "<cstdio>"} },
158 {"snprintf", {"<stdio.h>", "<cstdio>"} },
159 {"sprintf", {"<stdio.h>", "<cstdio>"} },
160 {"stderr", {"<stdio.h>", "<cstdio>"} },
161 {"stdin", {"<stdio.h>", "<cstdio>"} },
162 {"stdout", {"<stdio.h>", "<cstdio>"} },
163
164 /* <stdlib.h> and <cstdlib>. */
165 {"free", {"<stdlib.h>", "<cstdlib>"} },
166 {"malloc", {"<stdlib.h>", "<cstdlib>"} },
167 {"realloc", {"<stdlib.h>", "<cstdlib>"} },
168
169 /* <string.h> and <cstring>. */
170 {"memchr", {"<string.h>", "<cstring>"} },
171 {"memcmp", {"<string.h>", "<cstring>"} },
172 {"memcpy", {"<string.h>", "<cstring>"} },
173 {"memmove", {"<string.h>", "<cstring>"} },
174 {"memset", {"<string.h>", "<cstring>"} },
175 {"strcat", {"<string.h>", "<cstring>"} },
176 {"strchr", {"<string.h>", "<cstring>"} },
177 {"strcmp", {"<string.h>", "<cstring>"} },
178 {"strcpy", {"<string.h>", "<cstring>"} },
179 {"strlen", {"<string.h>", "<cstring>"} },
180 {"strncat", {"<string.h>", "<cstring>"} },
181 {"strncmp", {"<string.h>", "<cstring>"} },
182 {"strncpy", {"<string.h>", "<cstring>"} },
183 {"strrchr", {"<string.h>", "<cstring>"} },
184 {"strspn", {"<string.h>", "<cstring>"} },
185 {"strstr", {"<string.h>", "<cstring>"} },
186
187 /* <stdint.h>. */
188 {"PTRDIFF_MAX", {"<stdint.h>", "<cstdint>"} },
189 {"PTRDIFF_MIN", {"<stdint.h>", "<cstdint>"} },
190 {"SIG_ATOMIC_MAX", {"<stdint.h>", "<cstdint>"} },
191 {"SIG_ATOMIC_MIN", {"<stdint.h>", "<cstdint>"} },
192 {"SIZE_MAX", {"<stdint.h>", "<cstdint>"} },
193 {"WINT_MAX", {"<stdint.h>", "<cstdint>"} },
194 {"WINT_MIN", {"<stdint.h>", "<cstdint>"} },
195
196 /* <wchar.h>. */
197 {"WCHAR_MAX", {"<wchar.h>", "<cwchar>"} },
198 {"WCHAR_MIN", {"<wchar.h>", "<cwchar>"} }
199 };
200 const size_t num_hints = sizeof (hints) / sizeof (hints[0]);
201 for (size_t i = 0; i < num_hints; i++)
202 if (strcmp (name, hints[i].name) == 0)
203 return hints[i].header[lib];
204
205 static const stdlib_hint c99_cxx11_hints[] = {
206 /* <stdbool.h>. Defined natively in C++. */
207 {"bool", {"<stdbool.h>", NULL} },
208 {"true", {"<stdbool.h>", NULL} },
209 {"false", {"<stdbool.h>", NULL} },
210
211 /* <stdint.h> and <cstdint>. */
212 {"int8_t", {"<stdint.h>", "<cstdint>"} },
213 {"uint8_t", {"<stdint.h>", "<cstdint>"} },
214 {"int16_t", {"<stdint.h>", "<cstdint>"} },
215 {"uint16_t", {"<stdint.h>", "<cstdint>"} },
216 {"int32_t", {"<stdint.h>", "<cstdint>"} },
217 {"uint32_t", {"<stdint.h>", "<cstdint>"} },
218 {"int64_t", {"<stdint.h>", "<cstdint>"} },
219 {"uint64_t", {"<stdint.h>", "<cstdint>"} },
220 {"intptr_t", {"<stdint.h>", "<cstdint>"} },
221 {"uintptr_t", {"<stdint.h>", "<cstdint>"} },
222 {"INT8_MAX", {"<stdint.h>", "<cstdint>"} },
223 {"INT16_MAX", {"<stdint.h>", "<cstdint>"} },
224 {"INT32_MAX", {"<stdint.h>", "<cstdint>"} },
225 {"INT64_MAX", {"<stdint.h>", "<cstdint>"} },
226 {"UINT8_MAX", {"<stdint.h>", "<cstdint>"} },
227 {"UINT16_MAX", {"<stdint.h>", "<cstdint>"} },
228 {"UINT32_MAX", {"<stdint.h>", "<cstdint>"} },
229 {"UINT64_MAX", {"<stdint.h>", "<cstdint>"} },
230 {"INTPTR_MAX", {"<stdint.h>", "<cstdint>"} },
231 {"UINTPTR_MAX", {"<stdint.h>", "<cstdint>"} }
232 };
233
234 const size_t num_c99_cxx11_hints = sizeof (c99_cxx11_hints)
235 / sizeof (c99_cxx11_hints[0]);
236 if ((lib == STDLIB_C && flag_isoc99)
237 || (lib == STDLIB_CPLUSPLUS && cxx_dialect >= cxx11 ))
238 for (size_t i = 0; i < num_c99_cxx11_hints; i++)
239 if (strcmp (name, c99_cxx11_hints[i].name) == 0)
240 return c99_cxx11_hints[i].header[lib];
241
242 return get_string_macro_hint (name, lib);
243 }
244
245 /* Given non-NULL NAME, return the header name defining it within the C
246 standard library (with '<' and '>'), or NULL. */
247
248 const char *
249 get_c_stdlib_header_for_name (const char *name)
250 {
251 return get_stdlib_header_for_name (name, STDLIB_C);
252 }
253
254 /* Given non-NULL NAME, return the header name defining it within the C++
255 standard library (with '<' and '>'), or NULL. */
256
257 const char *
258 get_cp_stdlib_header_for_name (const char *name)
259 {
260 return get_stdlib_header_for_name (name, STDLIB_CPLUSPLUS);
261 }
262
263 /* Given non-NULL NAME, return the header name defining a string macro
264 within the C standard library (with '<' and '>'), or NULL. */
265 const char *
266 get_c_stdlib_header_for_string_macro_name (const char *name)
267 {
268 return get_string_macro_hint (name, STDLIB_C);
269 }
270
271 /* Given non-NULL NAME, return the header name defining a string macro
272 within the C++ standard library (with '<' and '>'), or NULL. */
273 const char *
274 get_cp_stdlib_header_for_string_macro_name (const char *name)
275 {
276 return get_string_macro_hint (name, STDLIB_CPLUSPLUS);
277 }
278
279 /* Implementation of class suggest_missing_header. */
280
281 /* suggest_missing_header's ctor. */
282
283 suggest_missing_header::suggest_missing_header (location_t loc,
284 const char *name,
285 const char *header_hint)
286 : deferred_diagnostic (loc), m_name_str (name), m_header_hint (header_hint)
287 {
288 gcc_assert (name);
289 gcc_assert (header_hint);
290 }
291
292 /* suggest_missing_header's dtor. */
293
294 suggest_missing_header::~suggest_missing_header ()
295 {
296 if (is_suppressed_p ())
297 return;
298
299 gcc_rich_location richloc (get_location ());
300 maybe_add_include_fixit (&richloc, m_header_hint, true);
301 inform (&richloc,
302 "%qs is defined in header %qs;"
303 " did you forget to %<#include %s%>?",
304 m_name_str, m_header_hint, m_header_hint);
305 }