aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family/name-hint.h
blob: 3d95027228bf7f3d871d48544e388af8daaf5011 (plain)
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
/* Support for offering suggestions for handling unrecognized names.
   Copyright (C) 2016-2024 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

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 std::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 */