From f45411ac238b532fd49f22fe6a383e24d105fa42 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Fri, 7 Apr 2017 15:54:41 -0400
Subject: [PATCH 5/7] FIXME: non-working attempt to do use-before-def in C
 frontend (can't work)

---
 gcc/c-family/c-common.h | 35 +---------------------------
 gcc/c/c-decl.c          |  7 ++++++
 gcc/cp/name-lookup.c    | 31 -------------------------
 gcc/name-hint.h         | 62 +++++++++++++++++++++++++++++++++++++++++++++++++
 gcc/spellcheck-tree.c   | 27 +++++++++++++++++++++
 gcc/spellcheck-tree.h   | 14 +++++++++++
 6 files changed, 111 insertions(+), 65 deletions(-)
 create mode 100644 gcc/name-hint.h

diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 86edd9a..6e12b13 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "alias.h"
 #include "tree.h"
 #include "fold-const.h"
+#include "name-hint.h"
 
 /* In order for the format checking to accept the C frontend
    diagnostic framework extensions, you must include this file before
@@ -1010,40 +1011,6 @@ enum lookup_name_fuzzy_kind {
   FUZZY_LOOKUP_NAME
 };
 
-/* FIXME.  */
-
-class deferred_diagnostic
-{
- public:
-  virtual ~deferred_diagnostic () {}
-  virtual void emit () = 0;
-};
-
-/* FIXME.  */
-
-class name_hint
-{
-public:
-  name_hint (const char *suggestion, deferred_diagnostic *deferred)
-  : m_suggestion (suggestion), m_deferred (deferred)
-  {}
-
-  ~name_hint ()
-  {
-    if (m_deferred)
-      m_deferred->emit ();
-    delete m_deferred;
-  }
-
-  const char *suggestion () const { return m_suggestion; }
-  operator bool () const { return m_suggestion != NULL; }
-
-private:
-  const char *m_suggestion;
-  // FIXME: should this be a unique_ptr; where was that gdb patch?
-  deferred_diagnostic *m_deferred;
-};
-
 extern name_hint lookup_name_fuzzy (tree, enum lookup_name_fuzzy_kind);
 
 extern bool vector_targets_convertible_p (const_tree t1, const_tree t2);
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 24bc573..868901d 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -4085,6 +4085,13 @@ lookup_name_fuzzy (tree name, enum lookup_name_fuzzy_kind kind)
 			  bmm.get_best_distance (),
 			  bmm.get_best_candidate_length ());
     }
+  else if (bmm.get_best_distance () == 0)
+    {
+      cpp_hashnode *macro = bmm.get_best_candidate_meaning_be_damned ();
+      if (macro)
+	return name_hint (NULL,
+			  new macro_use_before_def (input_location, macro));
+    }
 
   /* Try the "start_typename" keywords to detect
      "singed" vs "signed" typos.  */
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index c507336..379b9e2 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -4842,36 +4842,6 @@ consider_binding_level (tree name, best_match <tree, tree> &bm,
     }
 }
 
-/* FIXME.  */
-
-class macro_use_before_def : public deferred_diagnostic
-{
- public:
-  macro_use_before_def (location_t loc, cpp_hashnode *macro)
-  : m_loc (loc), m_macro (macro)
-  {
-    gcc_assert (macro);
-  }
-
-  void emit () OVERRIDE FINAL
-  {
-    source_location def_loc = cpp_macro_definition_location (m_macro);
-    if (def_loc != UNKNOWN_LOCATION)
-      {
-	/* FIXME: do we want to impose an ordering constraint on the
-	   locations?  What if the macro was undeffed?  */
-	inform (m_loc, "the macro %qs had not yet been defined",
-		(const char *)m_macro->ident.str);
-	inform (def_loc, "it was later defined here");
-      }
-  }
-
- private:
-  location_t m_loc;
-  cpp_hashnode *m_macro;
-};
-
-
 /* Search for near-matches for NAME within the current bindings, and within
    macro names, returning the best match as a const char *, or NULL if
    no reasonable match is found.  */
@@ -4914,7 +4884,6 @@ lookup_name_fuzzy (tree name, enum lookup_name_fuzzy_kind kind)
 	return name_hint (NULL,
 			  new macro_use_before_def (input_location, macro));
     }
-  // TODO: same again for C frontend
 
   /* Try the "starts_decl_specifier_p" keywords to detect
      "singed" vs "signed" typos.  */
diff --git a/gcc/name-hint.h b/gcc/name-hint.h
new file mode 100644
index 0000000..5470812
--- /dev/null
+++ b/gcc/name-hint.h
@@ -0,0 +1,62 @@
+/* FIXME
+   Copyright (C) 2017 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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_NAME_HINT_H
+#define GCC_NAME_HINT_H
+
+/* FIXME.  */
+
+class deferred_diagnostic
+{
+ public:
+  virtual ~deferred_diagnostic () {}
+  virtual void emit () = 0;
+};
+
+/* FIXME.  */
+
+class name_hint
+{
+public:
+  name_hint (const char *suggestion, deferred_diagnostic *deferred)
+  : m_suggestion (suggestion), m_deferred (deferred)
+  {}
+
+  ~name_hint ()
+  {
+    if (m_deferred)
+      m_deferred->emit ();
+    delete m_deferred;
+  }
+
+  const char *suggestion () const { return m_suggestion; }
+  operator bool () const { return m_suggestion != NULL; }
+
+private:
+  const char *m_suggestion;
+  // FIXME: should this be a unique_ptr; where was that gdb patch?
+  deferred_diagnostic *m_deferred;
+};
+
+#endif /* name-hint.h */
diff --git a/gcc/spellcheck-tree.c b/gcc/spellcheck-tree.c
index 56740b9..1a2314e 100644
--- a/gcc/spellcheck-tree.c
+++ b/gcc/spellcheck-tree.c
@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "spellcheck-tree.h"
 #include "selftest.h"
 #include "stringpool.h"
+#include "diagnostic-core.h"
 
 /* Calculate Levenshtein distance between two identifiers.  */
 
@@ -96,6 +97,32 @@ best_macro_match::best_macro_match (tree goal,
   cpp_forall_identifiers (reader, find_closest_macro_cpp_cb, this);
 }
 
+/* FIXME.  */
+
+/* Implementation of class macro_use_before_def.  */
+
+macro_use_before_def::macro_use_before_def (location_t loc, cpp_hashnode *macro)
+: m_loc (loc), m_macro (macro)
+{
+  gcc_assert (macro);
+}
+
+/* FIXME.  */
+
+void
+macro_use_before_def::emit ()
+{
+  source_location def_loc = cpp_macro_definition_location (m_macro);
+  if (def_loc != UNKNOWN_LOCATION)
+    {
+      /* FIXME: do we want to impose an ordering constraint on the
+	 locations?  What if the macro was undeffed?  */
+      inform (m_loc, "the macro %qs had not yet been defined",
+	      (const char *)m_macro->ident.str);
+      inform (def_loc, "it was later defined here");
+    }
+}
+
 #if CHECKING_P
 
 namespace selftest {
diff --git a/gcc/spellcheck-tree.h b/gcc/spellcheck-tree.h
index eecfd1a..b6a693a 100644
--- a/gcc/spellcheck-tree.h
+++ b/gcc/spellcheck-tree.h
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3.  If not see
 #define GCC_SPELLCHECK_TREE_H
 
 #include "spellcheck.h"
+#include "name-hint.h"
 
 /* spellcheck-tree.c  */
 
@@ -74,4 +75,17 @@ class best_macro_match : public best_match<tree, cpp_hashnode *>
 		    cpp_reader *reader);
 };
 
+/* FIXME.  */
+
+class macro_use_before_def : public deferred_diagnostic
+{
+ public:
+  macro_use_before_def (location_t loc, cpp_hashnode *macro);
+  void emit () OVERRIDE FINAL;
+
+ private:
+  location_t m_loc;
+  cpp_hashnode *m_macro;
+};
+
 #endif  /* GCC_SPELLCHECK_TREE_H  */
-- 
1.8.5.3

