From 360d1b991041860bcf2a1e6f342fb3b19553f827 Mon Sep 17 00:00:00 2001
From: Mark Mitchell <mmitchel@gcc.gnu.org>
Date: Sat, 6 Dec 2003 06:53:02 +0000
Subject: [PATCH] re PR c++/13305 (Parser error with 'class
 __attribute__((dllimport)) Foo;'  type specifier)

	PR c++/13305
	* parser.c (cp_parser_elaborated_type_specifier): Accept
	attributes.

	PR c++/13305
	* g++.dg/ext/attrib9.C: New test.

From-SVN: r74361
---
 gcc/cp/ChangeLog                   |  7 +++++++
 gcc/cp/parser.c                    | 15 ++++++++++++++-
 gcc/testsuite/ChangeLog            |  5 +++++
 gcc/testsuite/g++.dg/ext/attrib9.C |  5 +++++
 4 files changed, 31 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/attrib9.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 39dd385d2a6a..adfdb7e79cbb 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2003-12-05  Danny Smith <dannysmith@gcc.gnu.org>
+	    Mark Mitchell  <mark@codesourcery.com>
+
+	PR c++/13305
+	* parser.c (cp_parser_elaborated_type_specifier): Accept
+	attributes.
+	
 2003-12-05  Mark Mitchell  <mark@codesourcery.com>
 
 	PR c++/13314
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 97d32834d6a1..3f8fe7059bab 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -8647,6 +8647,14 @@ cp_parser_type_name (cp_parser* parser)
      typename :: [opt] nested-name-specifier template [opt] 
        template-id 
 
+   GNU extension:
+
+   elaborated-type-specifier:
+     class-key attributes :: [opt] nested-name-specifier [opt] identifier
+     class-key attributes :: [opt] nested-name-specifier [opt] 
+               template [opt] template-id
+     enum attributes :: [opt] nested-name-specifier [opt] identifier
+
    If IS_FRIEND is TRUE, then this elaborated-type-specifier is being
    declared `friend'.  If IS_DECLARATION is TRUE, then this
    elaborated-type-specifier appears in a decl-specifiers-seq, i.e.,
@@ -8662,6 +8670,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
   enum tag_types tag_type;
   tree identifier;
   tree type = NULL_TREE;
+  tree attributes = NULL_TREE;
 
   /* See if we're looking at the `enum' keyword.  */
   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ENUM))
@@ -8670,6 +8679,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
       cp_lexer_consume_token (parser->lexer);
       /* Remember that it's an enumeration type.  */
       tag_type = enum_type;
+      /* Parse the attributes.  */
+      attributes = cp_parser_attributes_opt (parser);
     }
   /* Or, it might be `typename'.  */
   else if (cp_lexer_next_token_is_keyword (parser->lexer,
@@ -8689,6 +8700,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
       tag_type = cp_parser_class_key (parser);
       if (tag_type == none_type)
 	return error_mark_node;
+      /* Parse the attributes.  */
+      attributes = cp_parser_attributes_opt (parser);
     }
 
   /* Look for the `::' operator.  */
@@ -8858,7 +8871,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
 	     declaration context.  */
 
 	  type = xref_tag (tag_type, identifier, 
-			   /*attributes=*/NULL_TREE,
+			   attributes,
 			   (is_friend 
 			    || !is_declaration
 			    || cp_lexer_next_token_is_not (parser->lexer, 
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index aba0ad31fdb0..f6fd9ff402cb 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2003-12-05  Mark Mitchell  <mark@codesourcery.com>
+
+	PR c++/13305
+	* g++.dg/ext/attrib9.C: New test.
+
 2003-12-05  Mark Mitchell  <mark@codesourcery.com>
 
 	PR c++/13314
diff --git a/gcc/testsuite/g++.dg/ext/attrib9.C b/gcc/testsuite/g++.dg/ext/attrib9.C
new file mode 100644
index 000000000000..ee6fdb1d375c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/attrib9.C
@@ -0,0 +1,5 @@
+class __attribute__((unused)) C;
+struct __attribute__((unused)) S;
+union __attribute__((unused)) U;
+enum e {};
+enum __attribute__((unused)) e;