1 | /* Support for offering suggestions for handling unrecognized names. |
2 | Copyright (C) 2016-2023 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 | #ifndef GCC_NAME_HINT_H |
21 | #define GCC_NAME_HINT_H |
22 | |
23 | /* This header uses std::unique_ptr, but <memory> can't be directly |
24 | included due to issues with macros. Hence it must be included from |
25 | system.h by defining INCLUDE_MEMORY in any source file using it. */ |
26 | |
27 | #ifndef INCLUDE_MEMORY |
28 | # error "You must define INCLUDE_MEMORY before including system.h to use name-hint.h" |
29 | #endif |
30 | |
31 | enum lookup_name_fuzzy_kind { |
32 | /* Names of types. */ |
33 | FUZZY_LOOKUP_TYPENAME, |
34 | |
35 | /* Names of function decls. */ |
36 | FUZZY_LOOKUP_FUNCTION_NAME, |
37 | |
38 | /* Any name. */ |
39 | FUZZY_LOOKUP_NAME |
40 | }; |
41 | |
42 | /* A deferred_diagnostic is a wrapper around optional extra diagnostics |
43 | that we may want to bundle into a name_hint. |
44 | |
45 | The diagnostic is emitted by the subclass destructor, which should |
46 | check that is_suppressed_p () is not true. */ |
47 | |
48 | class deferred_diagnostic |
49 | { |
50 | public: |
51 | virtual ~deferred_diagnostic () {} |
52 | |
53 | location_t get_location () const { return m_loc; } |
54 | |
55 | /* Call this if the corresponding warning was not emitted, |
56 | in which case we should also not emit the deferred_diagnostic. */ |
57 | void suppress () |
58 | { |
59 | m_suppress = true; |
60 | } |
61 | |
62 | bool is_suppressed_p () const { return m_suppress; } |
63 | |
64 | protected: |
65 | deferred_diagnostic (location_t loc) |
66 | : m_loc (loc), m_suppress (false) {} |
67 | |
68 | private: |
69 | location_t m_loc; |
70 | bool m_suppress; |
71 | }; |
72 | |
73 | /* A name_hint is an optional string suggestion, along with an |
74 | optional deferred_diagnostic. |
75 | For example: |
76 | |
77 | error: unknown foo named 'bar' |
78 | |
79 | if the SUGGESTION is "baz", then one might print: |
80 | |
81 | error: unknown foo named 'bar'; did you mean 'baz'? |
82 | |
83 | and the deferred_diagnostic allows for additional (optional) |
84 | diagnostics e.g.: |
85 | |
86 | note: did you check behind the couch? |
87 | |
88 | The deferred_diagnostic is emitted by its destructor, when the |
89 | name_hint goes out of scope. */ |
90 | |
91 | class name_hint |
92 | { |
93 | public: |
94 | name_hint () : m_suggestion (NULL), m_deferred () {} |
95 | |
96 | name_hint (const char *suggestion, deferred_diagnostic *deferred) |
97 | : m_suggestion (suggestion), m_deferred (deferred) |
98 | { |
99 | } |
100 | |
101 | const char *suggestion () const { return m_suggestion; } |
102 | |
103 | /* Does this name_hint have a suggestion or a deferred diagnostic? */ |
104 | operator bool () const { return (m_suggestion != NULL |
105 | || m_deferred != NULL); } |
106 | |
107 | /* Take ownership of this name_hint's deferred_diagnostic, for use |
108 | in chaining up deferred diagnostics. */ |
109 | std::unique_ptr<deferred_diagnostic> take_deferred () { return std::move (m_deferred); } |
110 | |
111 | /* Call this on a name_hint if the corresponding warning was not emitted, |
112 | in which case we should also not emit the deferred_diagnostic. */ |
113 | |
114 | void suppress () |
115 | { |
116 | if (m_deferred) |
117 | m_deferred->suppress (); |
118 | } |
119 | |
120 | private: |
121 | const char *m_suggestion; |
122 | std::unique_ptr<deferred_diagnostic> m_deferred; |
123 | }; |
124 | |
125 | extern name_hint lookup_name_fuzzy (tree, enum lookup_name_fuzzy_kind, |
126 | location_t); |
127 | |
128 | #endif /* ! GCC_NAME_HINT_H */ |
129 | |