1 /* Support for suggestions about missing #include directives.
2 Copyright (C) 2017 Free Software Foundation, Inc.
4 This file is part of GCC.
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
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
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/>. */
21 #define INCLUDE_UNIQUE_PTR
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"
29 /* An enum for distinguishing between the C and C++ stdlibs. */
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). */
46 const char *header
[NUM_STDLIBS
];
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. */
54 get_stdlib_header_for_name (const char *name
, enum stdlib lib
)
57 gcc_assert (lib
< NUM_STDLIBS
);
59 static const stdlib_hint hints
[] = {
60 /* <errno.h> and <cerrno>. */
61 {"errno", {"<errno.h>", "<cerrno>"} },
63 /* <limits.h> and <climits>. */
64 {"CHAR_BIT", {"<limits.h>", "<climits>"} },
65 {"CHAR_MAX", {"<limits.h>", "<climits>"} },
66 {"CHAR_MIN", {"<limits.h>", "<climits>"} },
67 {"INT_MAX", {"<limits.h>", "<climits>"} },
68 {"INT_MIN", {"<limits.h>", "<climits>"} },
69 {"LLONG_MAX", {"<limits.h>", "<climits>"} },
70 {"LLONG_MIN", {"<limits.h>", "<climits>"} },
71 {"LONG_MAX", {"<limits.h>", "<climits>"} },
72 {"LONG_MIN", {"<limits.h>", "<climits>"} },
73 {"MB_LEN_MAX", {"<limits.h>", "<climits>"} },
74 {"SCHAR_MAX", {"<limits.h>", "<climits>"} },
75 {"SCHAR_MIN", {"<limits.h>", "<climits>"} },
76 {"SHRT_MAX", {"<limits.h>", "<climits>"} },
77 {"SHRT_MIN", {"<limits.h>", "<climits>"} },
78 {"UCHAR_MAX", {"<limits.h>", "<climits>"} },
79 {"UINT_MAX", {"<limits.h>", "<climits>"} },
80 {"ULLONG_MAX", {"<limits.h>", "<climits>"} },
81 {"ULONG_MAX", {"<limits.h>", "<climits>"} },
82 {"USHRT_MAX", {"<limits.h>", "<climits>"} },
84 /* <stdarg.h> and <cstdarg>. */
85 {"va_list", {"<stdarg.h>", "<cstdarg>"} },
87 /* <stddef.h> and <cstddef>. */
88 {"NULL", {"<stddef.h>", "<cstddef>"} },
89 {"nullptr_t", {NULL
, "<cstddef>"} },
90 {"offsetof", {"<stddef.h>", "<cstddef>"} },
91 {"ptrdiff_t", {"<stddef.h>", "<cstddef>"} },
92 {"size_t", {"<stddef.h>", "<cstddef>"} },
93 {"wchar_t", {"<stddef.h>", NULL
/* a keyword in C++ */} },
96 {"BUFSIZ", {"<stdio.h>", "<cstdio>"} },
97 {"EOF", {"<stdio.h>", "<cstdio>"} },
98 {"FILE", {"<stdio.h>", "<cstdio>"} },
99 {"FILENAME_MAX", {"<stdio.h>", "<cstdio>"} },
100 {"fpos_t", {"<stdio.h>", "<cstdio>"} },
101 {"stderr", {"<stdio.h>", "<cstdio>"} },
102 {"stdin", {"<stdio.h>", "<cstdio>"} },
103 {"stdout", {"<stdio.h>", "<cstdio>"} },
106 {"PTRDIFF_MAX", {"<stdint.h>", "<cstdint>"} },
107 {"PTRDIFF_MIN", {"<stdint.h>", "<cstdint>"} },
108 {"SIG_ATOMIC_MAX", {"<stdint.h>", "<cstdint>"} },
109 {"SIG_ATOMIC_MIN", {"<stdint.h>", "<cstdint>"} },
110 {"SIZE_MAX", {"<stdint.h>", "<cstdint>"} },
111 {"WINT_MAX", {"<stdint.h>", "<cstdint>"} },
112 {"WINT_MIN", {"<stdint.h>", "<cstdint>"} },
115 {"WCHAR_MAX", {"<wchar.h>", "<cwchar>"} },
116 {"WCHAR_MIN", {"<wchar.h>", "<cwchar>"} }
118 const size_t num_hints
= sizeof (hints
) / sizeof (hints
[0]);
119 for (size_t i
= 0; i
< num_hints
; i
++)
120 if (0 == strcmp (name
, hints
[i
].name
))
121 return hints
[i
].header
[lib
];
125 /* Given non-NULL NAME, return the header name defining it within the C
126 standard library (with '<' and '>'), or NULL. */
129 get_c_stdlib_header_for_name (const char *name
)
131 return get_stdlib_header_for_name (name
, STDLIB_C
);
134 /* Given non-NULL NAME, return the header name defining it within the C++
135 standard library (with '<' and '>'), or NULL. */
138 get_cp_stdlib_header_for_name (const char *name
)
140 return get_stdlib_header_for_name (name
, STDLIB_CPLUSPLUS
);
143 /* Implementation of class suggest_missing_header. */
145 /* suggest_missing_header's ctor. */
147 suggest_missing_header::suggest_missing_header (location_t loc
,
149 const char *header_hint
)
150 : deferred_diagnostic (loc
), m_name_str (name
), m_header_hint (header_hint
)
153 gcc_assert (header_hint
);
156 /* suggest_missing_header's dtor. */
158 suggest_missing_header::~suggest_missing_header ()
160 if (is_suppressed_p ())
163 gcc_rich_location
richloc (get_location ());
164 maybe_add_include_fixit (&richloc
, m_header_hint
);
166 "%qs is defined in header %qs;"
167 " did you forget to %<#include %s%>?",
168 m_name_str
, m_header_hint
, m_header_hint
);