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