Re: [PATCH 1/3] c-family: add name_hint/deferred_diagnostic
On 07/03/2017 11:32 AM, David Malcolm wrote: > On Mon, 2017-07-03 at 10:25 -0600, Jeff Law wrote: >> On 05/05/2017 11:51 AM, David Malcolm wrote: >>> In various places we use lookup_name_fuzzy to provide a hint, >>> and can report messages of the form: >>> error: unknown foo named 'bar' >>> or: >>> error: unknown foo named 'bar'; did you mean 'SUGGESTION? >>> >>> This patch provides a way for lookup_name_fuzzy to provide >>> both the suggestion above, and (optionally) additional hints >>> that can be printed e.g. >>> >>> note: did you forget to include ? >>> >>> This patch provides the mechanism and ports existing users >>> of lookup_name_fuzzy to the new return type. >>> There are no uses of such hints in this patch, but followup >>> patches provide various front-end specific uses of this. >>> >>> gcc/c-family/ChangeLog: >>> * c-common.h (class deferred_diagnostic): New class. >>> (class name_hint): New class. >>> (lookup_name_fuzzy): Convert return type from const char * >>> to name_hint. Add location_t param. >>> >>> gcc/c/ChangeLog: >>> * c-decl.c (implicit_decl_warning): Convert "hint" from >>> const char * to name_hint. Pass location to >>> lookup_name_fuzzy. Suppress any deferred diagnostic if the >>> warning was not printed. >>> (undeclared_variable): Likewise for "guessed_id". >>> (lookup_name_fuzzy): Convert return type from const char * >>> to name_hint. Add location_t param. >>> * c-parser.c (c_parser_declaration_or_fndef): Convert "hint" >>> from >>> const char * to name_hint. Pass location to lookup_name_fuzzy. >>> (c_parser_parameter_declaration): Pass location to >>> lookup_name_fuzzy. >>> >>> gcc/cp/ChangeLog: >>> * name-lookup.c (suggest_alternatives_for): Convert >>> "fuzzy_name" from >>> const char * to name_hint, and rename to "hint". Pass location >>> to >>> lookup_name_fuzzy. >>> (lookup_name_fuzzy): Convert return type from const char * >>> to name_hint. Add location_t param. >>> * parser.c (cp_parser_diagnose_invalid_type_name): Convert >>> "suggestion" from const char * to name_hint, and rename to >>> "hint". >>> Pass location to lookup_name_fuzzy. >> >>> --- >>> gcc/c-family/c-common.h | 121 >>> +++- >>> gcc/c/c-decl.c | 35 +++--- >>> gcc/c/c-parser.c| 16 --- >>> gcc/cp/name-lookup.c| 17 +++ >>> gcc/cp/parser.c | 12 ++--- >>> 5 files changed, 163 insertions(+), 38 deletions(-) >>> >>> diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h >>> index 138a0a6..83c1a68 100644 >>> --- a/gcc/c-family/c-common.h >>> +++ b/gcc/c-family/c-common.h >>> @@ -1009,7 +1009,126 @@ enum lookup_name_fuzzy_kind { >>>/* Any name. */ >>>FUZZY_LOOKUP_NAME >>> }; >>> -extern const char *lookup_name_fuzzy (tree, enum >>> lookup_name_fuzzy_kind); >>> + >>> +/* A deferred_diagnostic is a wrapper around optional extra >>> diagnostics >>> + that we may want to bundle into a name_hint. >>> + >>> + The emit method is called when no name_hint instances reference >>> + the deferred_diagnostic. In the simple case this is when the >>> name_hint >>> + goes out of scope, but a reference-counting scheme is used to >>> allow >>> + name_hint instances to be copied. */ >>> + >>> +class deferred_diagnostic >>> +{ >>> + public: >>> + virtual ~deferred_diagnostic () {} >>> + virtual void emit () = 0; >>> + >>> + void incref () { m_refcnt++; } >>> + void decref () >>> + { >>> +if (--m_refcnt == 0) >>> + { >>> + if (!m_suppress) >>> + emit (); >>> + delete this; >>> + } >>> + } >>> + >>> + 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; >>> + } >>> + >>> + protected: >>> + deferred_diagnostic (location_t loc) >>> + : m_refcnt (0), m_loc (loc), m_suppress (false) {} >>> + >>> + private: >>> + int m_refcnt; >>> + location_t m_loc; >>> + bool m_suppress; >>> +}; >> So what stands out here is "delete this" and the need for explicit >> reference counting. Also doesn't that imply that deferred_diagnostic >> objects must be allocated on the heap? Is there another way to get >> the >> behavior you want without resorting to something like this? >> > > Thanks for looking at this. > > Yes: deferred_diagnostic instances are heap-allocated. This is because > it's an abstract base class; each concrete subclass is an > implementation detail within the frontends, for isolating the special > -case logic for each different kind of hint, and thus these concrete > subclasses are hidden within the FE code. > > My initial implementation of the above had the name_hint class directly > "own" the deferred_diagnostic ptr, with a: > delete m_deferred; > within
Re: [PATCH 1/3] c-family: add name_hint/deferred_diagnostic
On Mon, Jul 03, 2017 at 01:32:46PM -0400, David Malcolm wrote: > On Mon, 2017-07-03 at 10:25 -0600, Jeff Law wrote: > > On 05/05/2017 11:51 AM, David Malcolm wrote: > > > In various places we use lookup_name_fuzzy to provide a hint, > > > and can report messages of the form: > > > error: unknown foo named 'bar' > > > or: > > > error: unknown foo named 'bar'; did you mean 'SUGGESTION? > > > > > > This patch provides a way for lookup_name_fuzzy to provide > > > both the suggestion above, and (optionally) additional hints > > > that can be printed e.g. > > > > > > note: did you forget to include ? > > > > > > This patch provides the mechanism and ports existing users > > > of lookup_name_fuzzy to the new return type. > > > There are no uses of such hints in this patch, but followup > > > patches provide various front-end specific uses of this. > > > > > > gcc/c-family/ChangeLog: > > > * c-common.h (class deferred_diagnostic): New class. > > > (class name_hint): New class. > > > (lookup_name_fuzzy): Convert return type from const char * > > > to name_hint. Add location_t param. > > > > > > gcc/c/ChangeLog: > > > * c-decl.c (implicit_decl_warning): Convert "hint" from > > > const char * to name_hint. Pass location to > > > lookup_name_fuzzy. Suppress any deferred diagnostic if the > > > warning was not printed. > > > (undeclared_variable): Likewise for "guessed_id". > > > (lookup_name_fuzzy): Convert return type from const char * > > > to name_hint. Add location_t param. > > > * c-parser.c (c_parser_declaration_or_fndef): Convert "hint" > > > from > > > const char * to name_hint. Pass location to lookup_name_fuzzy. > > > (c_parser_parameter_declaration): Pass location to > > > lookup_name_fuzzy. > > > > > > gcc/cp/ChangeLog: > > > * name-lookup.c (suggest_alternatives_for): Convert > > > "fuzzy_name" from > > > const char * to name_hint, and rename to "hint". Pass location > > > to > > > lookup_name_fuzzy. > > > (lookup_name_fuzzy): Convert return type from const char * > > > to name_hint. Add location_t param. > > > * parser.c (cp_parser_diagnose_invalid_type_name): Convert > > > "suggestion" from const char * to name_hint, and rename to > > > "hint". > > > Pass location to lookup_name_fuzzy. > > > > > --- > > > gcc/c-family/c-common.h | 121 > > > +++- > > > gcc/c/c-decl.c | 35 +++--- > > > gcc/c/c-parser.c| 16 --- > > > gcc/cp/name-lookup.c| 17 +++ > > > gcc/cp/parser.c | 12 ++--- > > > 5 files changed, 163 insertions(+), 38 deletions(-) > > > > > > diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h > > > index 138a0a6..83c1a68 100644 > > > --- a/gcc/c-family/c-common.h > > > +++ b/gcc/c-family/c-common.h > > > @@ -1009,7 +1009,126 @@ enum lookup_name_fuzzy_kind { > > >/* Any name. */ > > >FUZZY_LOOKUP_NAME > > > }; > > > -extern const char *lookup_name_fuzzy (tree, enum > > > lookup_name_fuzzy_kind); > > > + > > > +/* A deferred_diagnostic is a wrapper around optional extra > > > diagnostics > > > + that we may want to bundle into a name_hint. > > > + > > > + The emit method is called when no name_hint instances reference > > > + the deferred_diagnostic. In the simple case this is when the > > > name_hint > > > + goes out of scope, but a reference-counting scheme is used to > > > allow > > > + name_hint instances to be copied. */ > > > + > > > +class deferred_diagnostic > > > +{ > > > + public: > > > + virtual ~deferred_diagnostic () {} > > > + virtual void emit () = 0; > > > + > > > + void incref () { m_refcnt++; } > > > + void decref () > > > + { > > > +if (--m_refcnt == 0) > > > + { > > > + if (!m_suppress) > > > + emit (); > > > + delete this; > > > + } > > > + } > > > + > > > + 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; > > > + } > > > + > > > + protected: > > > + deferred_diagnostic (location_t loc) > > > + : m_refcnt (0), m_loc (loc), m_suppress (false) {} > > > + > > > + private: > > > + int m_refcnt; > > > + location_t m_loc; > > > + bool m_suppress; > > > +}; > > So what stands out here is "delete this" and the need for explicit > > reference counting. Also doesn't that imply that deferred_diagnostic > > objects must be allocated on the heap? Is there another way to get > > the > > behavior you want without resorting to something like this? > > > > Thanks for looking at this. > > Yes: deferred_diagnostic instances are heap-allocated. This is because > it's an abstract base class; each concrete subclass is an > implementation detail within the frontends, for isolating the special > -case logic for each different kind of hint, and thus
Re: [PATCH 1/3] c-family: add name_hint/deferred_diagnostic
On Mon, 2017-07-03 at 10:25 -0600, Jeff Law wrote: > On 05/05/2017 11:51 AM, David Malcolm wrote: > > In various places we use lookup_name_fuzzy to provide a hint, > > and can report messages of the form: > > error: unknown foo named 'bar' > > or: > > error: unknown foo named 'bar'; did you mean 'SUGGESTION? > > > > This patch provides a way for lookup_name_fuzzy to provide > > both the suggestion above, and (optionally) additional hints > > that can be printed e.g. > > > > note: did you forget to include ? > > > > This patch provides the mechanism and ports existing users > > of lookup_name_fuzzy to the new return type. > > There are no uses of such hints in this patch, but followup > > patches provide various front-end specific uses of this. > > > > gcc/c-family/ChangeLog: > > * c-common.h (class deferred_diagnostic): New class. > > (class name_hint): New class. > > (lookup_name_fuzzy): Convert return type from const char * > > to name_hint. Add location_t param. > > > > gcc/c/ChangeLog: > > * c-decl.c (implicit_decl_warning): Convert "hint" from > > const char * to name_hint. Pass location to > > lookup_name_fuzzy. Suppress any deferred diagnostic if the > > warning was not printed. > > (undeclared_variable): Likewise for "guessed_id". > > (lookup_name_fuzzy): Convert return type from const char * > > to name_hint. Add location_t param. > > * c-parser.c (c_parser_declaration_or_fndef): Convert "hint" > > from > > const char * to name_hint. Pass location to lookup_name_fuzzy. > > (c_parser_parameter_declaration): Pass location to > > lookup_name_fuzzy. > > > > gcc/cp/ChangeLog: > > * name-lookup.c (suggest_alternatives_for): Convert > > "fuzzy_name" from > > const char * to name_hint, and rename to "hint". Pass location > > to > > lookup_name_fuzzy. > > (lookup_name_fuzzy): Convert return type from const char * > > to name_hint. Add location_t param. > > * parser.c (cp_parser_diagnose_invalid_type_name): Convert > > "suggestion" from const char * to name_hint, and rename to > > "hint". > > Pass location to lookup_name_fuzzy. > > > --- > > gcc/c-family/c-common.h | 121 > > +++- > > gcc/c/c-decl.c | 35 +++--- > > gcc/c/c-parser.c| 16 --- > > gcc/cp/name-lookup.c| 17 +++ > > gcc/cp/parser.c | 12 ++--- > > 5 files changed, 163 insertions(+), 38 deletions(-) > > > > diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h > > index 138a0a6..83c1a68 100644 > > --- a/gcc/c-family/c-common.h > > +++ b/gcc/c-family/c-common.h > > @@ -1009,7 +1009,126 @@ enum lookup_name_fuzzy_kind { > >/* Any name. */ > >FUZZY_LOOKUP_NAME > > }; > > -extern const char *lookup_name_fuzzy (tree, enum > > lookup_name_fuzzy_kind); > > + > > +/* A deferred_diagnostic is a wrapper around optional extra > > diagnostics > > + that we may want to bundle into a name_hint. > > + > > + The emit method is called when no name_hint instances reference > > + the deferred_diagnostic. In the simple case this is when the > > name_hint > > + goes out of scope, but a reference-counting scheme is used to > > allow > > + name_hint instances to be copied. */ > > + > > +class deferred_diagnostic > > +{ > > + public: > > + virtual ~deferred_diagnostic () {} > > + virtual void emit () = 0; > > + > > + void incref () { m_refcnt++; } > > + void decref () > > + { > > +if (--m_refcnt == 0) > > + { > > + if (!m_suppress) > > + emit (); > > + delete this; > > + } > > + } > > + > > + 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; > > + } > > + > > + protected: > > + deferred_diagnostic (location_t loc) > > + : m_refcnt (0), m_loc (loc), m_suppress (false) {} > > + > > + private: > > + int m_refcnt; > > + location_t m_loc; > > + bool m_suppress; > > +}; > So what stands out here is "delete this" and the need for explicit > reference counting. Also doesn't that imply that deferred_diagnostic > objects must be allocated on the heap? Is there another way to get > the > behavior you want without resorting to something like this? > Thanks for looking at this. Yes: deferred_diagnostic instances are heap-allocated. This is because it's an abstract base class; each concrete subclass is an implementation detail within the frontends, for isolating the special -case logic for each different kind of hint, and thus these concrete subclasses are hidden within the FE code. My initial implementation of the above had the name_hint class directly "own" the deferred_diagnostic ptr, with a: delete m_deferred; within name_hint's dtor. This worked OK, until I encountered places in the C and
Re: [PATCH 1/3] c-family: add name_hint/deferred_diagnostic
On 05/05/2017 11:51 AM, David Malcolm wrote: > In various places we use lookup_name_fuzzy to provide a hint, > and can report messages of the form: > error: unknown foo named 'bar' > or: > error: unknown foo named 'bar'; did you mean 'SUGGESTION? > > This patch provides a way for lookup_name_fuzzy to provide > both the suggestion above, and (optionally) additional hints > that can be printed e.g. > > note: did you forget to include ? > > This patch provides the mechanism and ports existing users > of lookup_name_fuzzy to the new return type. > There are no uses of such hints in this patch, but followup > patches provide various front-end specific uses of this. > > gcc/c-family/ChangeLog: > * c-common.h (class deferred_diagnostic): New class. > (class name_hint): New class. > (lookup_name_fuzzy): Convert return type from const char * > to name_hint. Add location_t param. > > gcc/c/ChangeLog: > * c-decl.c (implicit_decl_warning): Convert "hint" from > const char * to name_hint. Pass location to > lookup_name_fuzzy. Suppress any deferred diagnostic if the > warning was not printed. > (undeclared_variable): Likewise for "guessed_id". > (lookup_name_fuzzy): Convert return type from const char * > to name_hint. Add location_t param. > * c-parser.c (c_parser_declaration_or_fndef): Convert "hint" from > const char * to name_hint. Pass location to lookup_name_fuzzy. > (c_parser_parameter_declaration): Pass location to > lookup_name_fuzzy. > > gcc/cp/ChangeLog: > * name-lookup.c (suggest_alternatives_for): Convert "fuzzy_name" from > const char * to name_hint, and rename to "hint". Pass location to > lookup_name_fuzzy. > (lookup_name_fuzzy): Convert return type from const char * > to name_hint. Add location_t param. > * parser.c (cp_parser_diagnose_invalid_type_name): Convert > "suggestion" from const char * to name_hint, and rename to "hint". > Pass location to lookup_name_fuzzy. > --- > gcc/c-family/c-common.h | 121 > +++- > gcc/c/c-decl.c | 35 +++--- > gcc/c/c-parser.c| 16 --- > gcc/cp/name-lookup.c| 17 +++ > gcc/cp/parser.c | 12 ++--- > 5 files changed, 163 insertions(+), 38 deletions(-) > > diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h > index 138a0a6..83c1a68 100644 > --- a/gcc/c-family/c-common.h > +++ b/gcc/c-family/c-common.h > @@ -1009,7 +1009,126 @@ enum lookup_name_fuzzy_kind { >/* Any name. */ >FUZZY_LOOKUP_NAME > }; > -extern const char *lookup_name_fuzzy (tree, enum lookup_name_fuzzy_kind); > + > +/* A deferred_diagnostic is a wrapper around optional extra diagnostics > + that we may want to bundle into a name_hint. > + > + The emit method is called when no name_hint instances reference > + the deferred_diagnostic. In the simple case this is when the name_hint > + goes out of scope, but a reference-counting scheme is used to allow > + name_hint instances to be copied. */ > + > +class deferred_diagnostic > +{ > + public: > + virtual ~deferred_diagnostic () {} > + virtual void emit () = 0; > + > + void incref () { m_refcnt++; } > + void decref () > + { > +if (--m_refcnt == 0) > + { > + if (!m_suppress) > + emit (); > + delete this; > + } > + } > + > + 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; > + } > + > + protected: > + deferred_diagnostic (location_t loc) > + : m_refcnt (0), m_loc (loc), m_suppress (false) {} > + > + private: > + int m_refcnt; > + location_t m_loc; > + bool m_suppress; > +}; So what stands out here is "delete this" and the need for explicit reference counting. Also doesn't that imply that deferred_diagnostic objects must be allocated on the heap? Is there another way to get the behavior you want without resorting to something like this? Or is your argument that deferred_diagnostic is only used from within class name_hint and thus the concerns around heap vs stack, explicit counting, etc are all buried inside the name_hint class? If so, is there any reasonable way to restrict the use of deferred_disagnostic to within the name_hint class? The rest of the changes seem non-controversial, so I think if we can sort out the issues with those classes then this will be fine to move forward. jeff
[PING] Re: [PATCH 1/3] c-family: add name_hint/deferred_diagnostic
I'd like to ping the following patches: [PATCH 1/3] c-family: add name_hint/deferred_diagnostic https://gcc.gnu.org/ml/gcc-patches/2017-05/msg00439.html [PATCH 2/3] C++: provide macro used-before-defined hint (PR c++/72786). https://gcc.gnu.org/ml/gcc-patches/2017-05/msg00437.html [PATCH 3/3] C: hints for missing stdlib includes for macros and types https://gcc.gnu.org/ml/gcc-patches/2017-05/msg00438.html On Fri, 2017-05-05 at 13:51 -0400, David Malcolm wrote: > In various places we use lookup_name_fuzzy to provide a hint, > and can report messages of the form: > error: unknown foo named 'bar' > or: > error: unknown foo named 'bar'; did you mean 'SUGGESTION? > > This patch provides a way for lookup_name_fuzzy to provide > both the suggestion above, and (optionally) additional hints > that can be printed e.g. > > note: did you forget to include ? > > This patch provides the mechanism and ports existing users > of lookup_name_fuzzy to the new return type. > There are no uses of such hints in this patch, but followup > patches provide various front-end specific uses of this. > > gcc/c-family/ChangeLog: > * c-common.h (class deferred_diagnostic): New class. > (class name_hint): New class. > (lookup_name_fuzzy): Convert return type from const char * > to name_hint. Add location_t param. > > gcc/c/ChangeLog: > * c-decl.c (implicit_decl_warning): Convert "hint" from > const char * to name_hint. Pass location to > lookup_name_fuzzy. Suppress any deferred diagnostic if the > warning was not printed. > (undeclared_variable): Likewise for "guessed_id". > (lookup_name_fuzzy): Convert return type from const char * > to name_hint. Add location_t param. > * c-parser.c (c_parser_declaration_or_fndef): Convert "hint" > from > const char * to name_hint. Pass location to lookup_name_fuzzy. > (c_parser_parameter_declaration): Pass location to > lookup_name_fuzzy. > > gcc/cp/ChangeLog: > * name-lookup.c (suggest_alternatives_for): Convert > "fuzzy_name" from > const char * to name_hint, and rename to "hint". Pass location > to > lookup_name_fuzzy. > (lookup_name_fuzzy): Convert return type from const char * > to name_hint. Add location_t param. > * parser.c (cp_parser_diagnose_invalid_type_name): Convert > "suggestion" from const char * to name_hint, and rename to > "hint". > Pass location to lookup_name_fuzzy. > --- > gcc/c-family/c-common.h | 121 > +++- > gcc/c/c-decl.c | 35 +++--- > gcc/c/c-parser.c| 16 --- > gcc/cp/name-lookup.c| 17 +++ > gcc/cp/parser.c | 12 ++--- > 5 files changed, 163 insertions(+), 38 deletions(-) > > diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h > index 138a0a6..83c1a68 100644 > --- a/gcc/c-family/c-common.h > +++ b/gcc/c-family/c-common.h > @@ -1009,7 +1009,126 @@ enum lookup_name_fuzzy_kind { >/* Any name. */ >FUZZY_LOOKUP_NAME > }; > -extern const char *lookup_name_fuzzy (tree, enum > lookup_name_fuzzy_kind); > + > +/* A deferred_diagnostic is a wrapper around optional extra > diagnostics > + that we may want to bundle into a name_hint. > + > + The emit method is called when no name_hint instances reference > + the deferred_diagnostic. In the simple case this is when the > name_hint > + goes out of scope, but a reference-counting scheme is used to > allow > + name_hint instances to be copied. */ > + > +class deferred_diagnostic > +{ > + public: > + virtual ~deferred_diagnostic () {} > + virtual void emit () = 0; > + > + void incref () { m_refcnt++; } > + void decref () > + { > +if (--m_refcnt == 0) > + { > + if (!m_suppress) > + emit (); > + delete this; > + } > + } > + > + 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; > + } > + > + protected: > + deferred_diagnostic (location_t loc) > + : m_refcnt (0), m_loc (loc), m_suppress (false) {} > + > + private: > + int m_refcnt; > + 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 SU
[PATCH 1/3] c-family: add name_hint/deferred_diagnostic
In various places we use lookup_name_fuzzy to provide a hint, and can report messages of the form: error: unknown foo named 'bar' or: error: unknown foo named 'bar'; did you mean 'SUGGESTION? This patch provides a way for lookup_name_fuzzy to provide both the suggestion above, and (optionally) additional hints that can be printed e.g. note: did you forget to include ? This patch provides the mechanism and ports existing users of lookup_name_fuzzy to the new return type. There are no uses of such hints in this patch, but followup patches provide various front-end specific uses of this. gcc/c-family/ChangeLog: * c-common.h (class deferred_diagnostic): New class. (class name_hint): New class. (lookup_name_fuzzy): Convert return type from const char * to name_hint. Add location_t param. gcc/c/ChangeLog: * c-decl.c (implicit_decl_warning): Convert "hint" from const char * to name_hint. Pass location to lookup_name_fuzzy. Suppress any deferred diagnostic if the warning was not printed. (undeclared_variable): Likewise for "guessed_id". (lookup_name_fuzzy): Convert return type from const char * to name_hint. Add location_t param. * c-parser.c (c_parser_declaration_or_fndef): Convert "hint" from const char * to name_hint. Pass location to lookup_name_fuzzy. (c_parser_parameter_declaration): Pass location to lookup_name_fuzzy. gcc/cp/ChangeLog: * name-lookup.c (suggest_alternatives_for): Convert "fuzzy_name" from const char * to name_hint, and rename to "hint". Pass location to lookup_name_fuzzy. (lookup_name_fuzzy): Convert return type from const char * to name_hint. Add location_t param. * parser.c (cp_parser_diagnose_invalid_type_name): Convert "suggestion" from const char * to name_hint, and rename to "hint". Pass location to lookup_name_fuzzy. --- gcc/c-family/c-common.h | 121 +++- gcc/c/c-decl.c | 35 +++--- gcc/c/c-parser.c| 16 --- gcc/cp/name-lookup.c| 17 +++ gcc/cp/parser.c | 12 ++--- 5 files changed, 163 insertions(+), 38 deletions(-) diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 138a0a6..83c1a68 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -1009,7 +1009,126 @@ enum lookup_name_fuzzy_kind { /* Any name. */ FUZZY_LOOKUP_NAME }; -extern const char *lookup_name_fuzzy (tree, enum lookup_name_fuzzy_kind); + +/* A deferred_diagnostic is a wrapper around optional extra diagnostics + that we may want to bundle into a name_hint. + + The emit method is called when no name_hint instances reference + the deferred_diagnostic. In the simple case this is when the name_hint + goes out of scope, but a reference-counting scheme is used to allow + name_hint instances to be copied. */ + +class deferred_diagnostic +{ + public: + virtual ~deferred_diagnostic () {} + virtual void emit () = 0; + + void incref () { m_refcnt++; } + void decref () + { +if (--m_refcnt == 0) + { + if (!m_suppress) + emit (); + delete this; + } + } + + 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; + } + + protected: + deferred_diagnostic (location_t loc) + : m_refcnt (0), m_loc (loc), m_suppress (false) {} + + private: + int m_refcnt; + 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 when no name_hint instances reference + the deferred_diagnostic. In the simple case this is when the name_hint + goes out of scope, but a reference-counting scheme is used to allow + name_hint instances to be copied. */ + +class name_hint +{ +public: + name_hint () : m_suggestion (NULL), m_deferred (NULL) {} + + name_hint (const char *suggestion, deferred_diagnostic *deferred) + : m_suggestion (suggestion), m_deferred (deferred) + { +if (m_deferred) + m_deferred->incref (); + } + + name_hint (const name_hint ) + : m_suggestion (other.m_suggestion), m_deferred (other.m_deferred) + { +if (m_deferred) + m_deferred->incref (); + } + + name_hint& operator= (const name_hint ) + { +m_suggestion = other.m_suggestion; +if (other.m_deferred) + other.m_deferred->incref (); +if (m_deferred) +