Import GCC-8 to a new vendor branch
[dragonfly.git] / contrib / gcc-8.0 / gcc / c-family / known-headers.cc
1 /* Support for suggestions about missing #include directives.
2    Copyright (C) 2017-2018 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 within either
50    the standard library (with '<' and '>'), or NULL.
51    Only handles a subset of the most common names within the stdlibs.  */
52
53 static const char *
54 get_stdlib_header_for_name (const char *name, enum stdlib lib)
55 {
56   gcc_assert (name);
57   gcc_assert (lib < NUM_STDLIBS);
58
59   static const stdlib_hint hints[] = {
60     /* <assert.h> and <cassert>.  */
61     {"assert", {"<assert.h>",  "<cassert>"} },
62
63     /* <errno.h> and <cerrno>.  */
64     {"errno", {"<errno.h>", "<cerrno>"} },
65
66     /* <limits.h> and <climits>.  */
67     {"CHAR_BIT", {"<limits.h>", "<climits>"} },
68     {"CHAR_MAX", {"<limits.h>", "<climits>"} },
69     {"CHAR_MIN", {"<limits.h>", "<climits>"} },
70     {"INT_MAX", {"<limits.h>", "<climits>"} },
71     {"INT_MIN", {"<limits.h>", "<climits>"} },
72     {"LLONG_MAX", {"<limits.h>", "<climits>"} },
73     {"LLONG_MIN", {"<limits.h>", "<climits>"} },
74     {"LONG_MAX", {"<limits.h>", "<climits>"} },
75     {"LONG_MIN", {"<limits.h>", "<climits>"} },
76     {"MB_LEN_MAX", {"<limits.h>", "<climits>"} },
77     {"SCHAR_MAX", {"<limits.h>", "<climits>"} },
78     {"SCHAR_MIN", {"<limits.h>", "<climits>"} },
79     {"SHRT_MAX", {"<limits.h>", "<climits>"} },
80     {"SHRT_MIN", {"<limits.h>", "<climits>"} },
81     {"UCHAR_MAX", {"<limits.h>", "<climits>"} },
82     {"UINT_MAX", {"<limits.h>", "<climits>"} },
83     {"ULLONG_MAX", {"<limits.h>", "<climits>"} },
84     {"ULONG_MAX", {"<limits.h>", "<climits>"} },
85     {"USHRT_MAX", {"<limits.h>", "<climits>"} },
86
87     /* <stdarg.h> and <cstdarg>.  */
88     {"va_list", {"<stdarg.h>", "<cstdarg>"} },
89
90     /* <stddef.h> and <cstddef>.  */
91     {"NULL", {"<stddef.h>", "<cstddef>"} },
92     {"nullptr_t", {NULL, "<cstddef>"} },
93     {"offsetof", {"<stddef.h>", "<cstddef>"} },
94     {"ptrdiff_t", {"<stddef.h>", "<cstddef>"} },
95     {"size_t", {"<stddef.h>", "<cstddef>"} },
96     {"wchar_t", {"<stddef.h>", NULL /* a keyword in C++ */} },
97
98     /* <stdio.h> and <cstdio>.  */
99     {"BUFSIZ", {"<stdio.h>", "<cstdio>"} },
100     {"EOF", {"<stdio.h>", "<cstdio>"} },
101     {"FILE", {"<stdio.h>", "<cstdio>"} },
102     {"FILENAME_MAX", {"<stdio.h>", "<cstdio>"} },
103     {"fopen", {"<stdio.h>", "<cstdio>"} },
104     {"fpos_t", {"<stdio.h>", "<cstdio>"} },
105     {"getchar", {"<stdio.h>", "<cstdio>"} },
106     {"printf", {"<stdio.h>", "<cstdio>"} },
107     {"snprintf", {"<stdio.h>", "<cstdio>"} },
108     {"sprintf", {"<stdio.h>", "<cstdio>"} },
109     {"stderr", {"<stdio.h>", "<cstdio>"} },
110     {"stdin", {"<stdio.h>", "<cstdio>"} },
111     {"stdout", {"<stdio.h>", "<cstdio>"} },
112
113     /* <stdlib.h> and <cstdlib>.  */
114     {"free", {"<stdlib.h>", "<cstdlib>"} },
115     {"malloc", {"<stdlib.h>", "<cstdlib>"} },
116     {"realloc", {"<stdlib.h>", "<cstdlib>"} },
117
118     /* <string.h> and <cstring>.  */
119     {"memchr", {"<string.h>", "<cstring>"} },
120     {"memcmp", {"<string.h>", "<cstring>"} },
121     {"memcpy", {"<string.h>", "<cstring>"} },
122     {"memmove", {"<string.h>", "<cstring>"} },
123     {"memset", {"<string.h>", "<cstring>"} },
124     {"strcat", {"<string.h>", "<cstring>"} },
125     {"strchr", {"<string.h>", "<cstring>"} },
126     {"strcmp", {"<string.h>", "<cstring>"} },
127     {"strcpy", {"<string.h>", "<cstring>"} },
128     {"strlen", {"<string.h>", "<cstring>"} },
129     {"strncat", {"<string.h>", "<cstring>"} },
130     {"strncmp", {"<string.h>", "<cstring>"} },
131     {"strncpy", {"<string.h>", "<cstring>"} },
132     {"strrchr", {"<string.h>", "<cstring>"} },
133     {"strspn", {"<string.h>", "<cstring>"} },
134     {"strstr", {"<string.h>", "<cstring>"} },
135
136     /* <stdint.h>.  */
137     {"PTRDIFF_MAX", {"<stdint.h>", "<cstdint>"} },
138     {"PTRDIFF_MIN", {"<stdint.h>", "<cstdint>"} },
139     {"SIG_ATOMIC_MAX", {"<stdint.h>", "<cstdint>"} },
140     {"SIG_ATOMIC_MIN", {"<stdint.h>", "<cstdint>"} },
141     {"SIZE_MAX", {"<stdint.h>", "<cstdint>"} },
142     {"WINT_MAX", {"<stdint.h>", "<cstdint>"} },
143     {"WINT_MIN", {"<stdint.h>", "<cstdint>"} },
144
145     /* <wchar.h>.  */
146     {"WCHAR_MAX", {"<wchar.h>", "<cwchar>"} },
147     {"WCHAR_MIN", {"<wchar.h>", "<cwchar>"} }
148   };
149   const size_t num_hints = sizeof (hints) / sizeof (hints[0]);
150   for (size_t i = 0; i < num_hints; i++)
151     if (strcmp (name, hints[i].name) == 0)
152       return hints[i].header[lib];
153   return NULL;
154 }
155
156 /* Given non-NULL NAME, return the header name defining it within the C
157    standard library (with '<' and '>'), or NULL.  */
158
159 const char *
160 get_c_stdlib_header_for_name (const char *name)
161 {
162   return get_stdlib_header_for_name (name, STDLIB_C);
163 }
164
165 /* Given non-NULL NAME, return the header name defining it within the C++
166    standard library (with '<' and '>'), or NULL.  */
167
168 const char *
169 get_cp_stdlib_header_for_name (const char *name)
170 {
171   return get_stdlib_header_for_name (name, STDLIB_CPLUSPLUS);
172 }
173
174 /* Implementation of class suggest_missing_header.  */
175
176 /* suggest_missing_header's ctor.  */
177
178 suggest_missing_header::suggest_missing_header (location_t loc,
179                                                 const char *name,
180                                                 const char *header_hint)
181 : deferred_diagnostic (loc), m_name_str (name), m_header_hint (header_hint)
182 {
183   gcc_assert (name);
184   gcc_assert (header_hint);
185 }
186
187 /* suggest_missing_header's dtor.  */
188
189 suggest_missing_header::~suggest_missing_header ()
190 {
191   if (is_suppressed_p ())
192     return;
193
194   gcc_rich_location richloc (get_location ());
195   maybe_add_include_fixit (&richloc, m_header_hint);
196   inform (&richloc,
197           "%qs is defined in header %qs;"
198           " did you forget to %<#include %s%>?",
199           m_name_str, m_header_hint, m_header_hint);
200 }