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 <SOME_HEADER.h>?
> 
> 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

Reply via email to