1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
/* Support for offering suggestions for handling unrecognized names.
Copyright (C) 2016-2022 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_NAME_HINT_H
#define GCC_NAME_HINT_H
/* This header uses std::unique_ptr, but <memory> can't be directly
included due to issues with macros. Hence it must be included from
system.h by defining INCLUDE_MEMORY in any source file using it. */
#ifndef INCLUDE_MEMORY
# error "You must define INCLUDE_MEMORY before including system.h to use name-hint.h"
#endif
enum lookup_name_fuzzy_kind {
/* Names of types. */
FUZZY_LOOKUP_TYPENAME,
/* Names of function decls. */
FUZZY_LOOKUP_FUNCTION_NAME,
/* Any name. */
FUZZY_LOOKUP_NAME
};
/* A deferred_diagnostic is a wrapper around optional extra diagnostics
that we may want to bundle into a name_hint.
The diagnostic is emitted by the subclass destructor, which should
check that is_suppressed_p () is not true. */
class deferred_diagnostic
{
public:
virtual ~deferred_diagnostic () {}
location_t get_location () const { return m_loc; }
/* Call this if the corresponding warning was not emitted,
in which case we should also not emit the deferred_diagnostic. */
void suppress ()
{
m_suppress = true;
}
bool is_suppressed_p () const { return m_suppress; }
protected:
deferred_diagnostic (location_t loc)
: m_loc (loc), m_suppress (false) {}
private:
location_t m_loc;
bool m_suppress;
};
/* A name_hint is an optional string suggestion, along with an
optional deferred_diagnostic.
For example:
error: unknown foo named 'bar'
if the SUGGESTION is "baz", then one might print:
error: unknown foo named 'bar'; did you mean 'baz'?
and the deferred_diagnostic allows for additional (optional)
diagnostics e.g.:
note: did you check behind the couch?
The deferred_diagnostic is emitted by its destructor, when the
name_hint goes out of scope. */
class name_hint
{
public:
name_hint () : m_suggestion (NULL), m_deferred () {}
name_hint (const char *suggestion, deferred_diagnostic *deferred)
: m_suggestion (suggestion), m_deferred (deferred)
{
}
const char *suggestion () const { return m_suggestion; }
/* Does this name_hint have a suggestion or a deferred diagnostic? */
operator bool () const { return (m_suggestion != NULL
|| m_deferred != NULL); }
/* Take ownership of this name_hint's deferred_diagnostic, for use
in chaining up deferred diagnostics. */
std::unique_ptr<deferred_diagnostic> take_deferred () { return move (m_deferred); }
/* Call this on a name_hint if the corresponding warning was not emitted,
in which case we should also not emit the deferred_diagnostic. */
void suppress ()
{
if (m_deferred)
m_deferred->suppress ();
}
private:
const char *m_suggestion;
std::unique_ptr<deferred_diagnostic> m_deferred;
};
extern name_hint lookup_name_fuzzy (tree, enum lookup_name_fuzzy_kind,
location_t);
#endif /* ! GCC_NAME_HINT_H */
|