From 33a4b6fee655c2a20f85daf74444d7aa23a08571 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Fri, 26 Aug 2016 17:10:12 -0400
Subject: [PATCH 33/44] FIXME: WIP on better error msg for missing 'namespace'
 in 'using namespace'

---
 gcc/cp/parser.c                            | 38 ++++++++++++++++++++----------
 gcc/testsuite/g++.dg/bad-using-directive.C |  3 +++
 2 files changed, 29 insertions(+), 12 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/bad-using-directive.C

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 4a5adef..fe9e3dd 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -2041,7 +2041,7 @@ static cp_expr cp_parser_unqualified_id
 static tree cp_parser_nested_name_specifier_opt
   (cp_parser *, bool, bool, bool, bool);
 static tree cp_parser_nested_name_specifier
-  (cp_parser *, bool, bool, bool, bool);
+  (cp_parser *, bool, bool, bool, bool, const char *);
 static tree cp_parser_qualifying_entity
   (cp_parser *, bool, bool, bool, bool, bool);
 static cp_expr cp_parser_postfix_expression
@@ -6206,10 +6206,11 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
 
 static tree
 cp_parser_nested_name_specifier (cp_parser *parser,
-				 bool typename_keyword_p,
-				 bool check_dependency_p,
-				 bool type_p,
-				 bool is_declaration)
+                                 bool typename_keyword_p,
+                                 bool check_dependency_p,
+                                 bool type_p,
+                                 bool is_declaration,
+                                 const char *errmsg)
 {
   tree scope;
 
@@ -6222,7 +6223,14 @@ cp_parser_nested_name_specifier (cp_parser *parser,
   /* If it was not present, issue an error message.  */
   if (!scope)
     {
-      cp_parser_error (parser, "expected nested-name-specifier");
+      cp_parser_error (parser, errmsg); // "expected nested-name-specifier");
+      // FIXME: horrible hack, convert this to an enum param
+      if (0 == strcmp (errmsg, "using declaration requires a qualified name"))
+        {
+          rich_location richloc (line_table, input_location);
+          richloc.add_fixit_insert (input_location, "namespace ");
+          inform_at_rich_loc (&richloc, "did you forget %<namespace%>?");
+        }
       parser->scope = NULL_TREE;
     }
 
@@ -16821,7 +16829,10 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
 					   /*typename_keyword_p=*/true,
 					   /*check_dependency_p=*/true,
 					   /*type_p=*/true,
-					    is_declaration))
+					    is_declaration,
+                                            "elaborated-type-specifier"
+                                            " requires a"
+                                            " nested-name-specifier"))
 	return error_mark_node;
     }
   else
@@ -17906,10 +17917,12 @@ cp_parser_using_declaration (cp_parser* parser,
      nested-name-specifier present.  */
   if (typename_p || !global_scope_p)
     {
-      qscope = cp_parser_nested_name_specifier (parser, typename_p,
-						/*check_dependency_p=*/true,
-						/*type_p=*/false,
-						/*is_declaration=*/true);
+      qscope = cp_parser_nested_name_specifier
+        (parser, typename_p,
+         /*check_dependency_p=*/true,
+         /*type_p=*/false,
+         /*is_declaration=*/true,
+         "using declaration requires a qualified name");
       if (!qscope && !cp_parser_uncommitted_to_tentative_parse_p (parser))
 	{
 	  cp_parser_skip_to_end_of_block_or_statement (parser);
@@ -19630,7 +19643,8 @@ cp_parser_ptr_operator (cp_parser* parser,
 				       /*typename_keyword_p=*/false,
 				       /*check_dependency_p=*/true,
 				       /*type_p=*/false,
-				       /*is_declaration=*/false);
+				       /*is_declaration=*/false,
+                                       "FIXME");
       /* If we found it, and the next token is a `*', then we are
 	 indeed looking at a pointer-to-member operator.  */
       if (!cp_parser_error_occurred (parser)
diff --git a/gcc/testsuite/g++.dg/bad-using-directive.C b/gcc/testsuite/g++.dg/bad-using-directive.C
new file mode 100644
index 0000000..f273a85
--- /dev/null
+++ b/gcc/testsuite/g++.dg/bad-using-directive.C
@@ -0,0 +1,3 @@
+/* Verify behavior when a user omits the "namespace" from
+   "using namespace std;".  */
+using std;
-- 
1.8.5.3

