/* Support for offering suggestions for handling unrecognized names. Copyright (C) 2016-2020 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 . */ #ifndef GCC_NAME_HINT_H #define GCC_NAME_HINT_H /* This header uses gnu::unique_ptr, but unique-ptr.h can't be directly included due to issues with macros. Hence it must be included from system.h by defining INCLUDE_UNIQUE_PTR in any source file using it. */ #ifndef GNU_UNIQUE_PTR_H # error "You must define INCLUDE_UNIQUE_PTR 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. */ gnu::unique_ptr 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; gnu::unique_ptr m_deferred; }; extern name_hint lookup_name_fuzzy (tree, enum lookup_name_fuzzy_kind, location_t); #endif /* ! GCC_NAME_HINT_H */