This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Improve -Wc++-compat to warn about types defined inside structs


In C it is valid to write

struct s1 { struct s2 { int i; } f; };
struct s2 v;

This is invalid in C++, because struct s2 is defined inside struct s1.
The only way to refer to struct s2 is to say s1::s2.

The first patch in this message improves the C frontend to warn about
this type of case.  The only types which can be defined inside a struct
(or union) in C are struct, union, and enum types.  For those types, I
use TYPE_LANG_FLAG_2, now known as C_TYPE_DEFINED_IN_STRUCT, to record
whether the type was defined inside a struct.

The new flag is only set after the struct definition is complete,
because it is valid C++ to refer to the newly defined struct within the
same defining struct, as in

struct s1 { struct s2 { int i; } f1; struct s2 f2; };

If -Wc++-compat, I issue a warning if a type with
C_TYPE_DEFINED_IN_STRUCT set is used.  I also issue a warning if an enum
constant defined in such a type is used.

Since I was looking at the code, I slightly improved the location
information for struct redefinition errors, and in the case of a
non-nested redefinition I changed the compiler to report the location of
the original definition.  This required changing a few test cases to
accept the new note.

This first patch requires approval from the C frontend maintainers.  It
would probably also be a good idea for the Objective C and Objective C++
maintainers to take a look, as I had to modify those frontends as well.

The second patch fixes all the new errors I found doing a bootstrap on
i686-pc-linux-gnu.  I also built the arm, ia64, mips, pa, rs6000, s390,
sh, sparc, and spu backends, but no new warnings were triggered.  This
second patch requires approval from the Fortran frontend maintainers.

Bootstrapped and tested on i686-pc-linux-gnu.

OK for mainline?

Ian


First patch

gcc/ChangeLog:

2009-05-06  Ian Lance Taylor  <iant@google.com>

	* c-decl.c (in_struct, struct_types): New static variables.
	(pushtag): Add loc parameter.  Change all callers.
	(lookup_tag): Add ploc parameter.  Change all callers.
	(parser_xref_tag): Add loc parameter.  Change all callers.  If
	-Wc++-compat, warn about struct/union/enum types defined within a
	struct or union.
	(start_struct): Add enclosing_in_struct, enclosing_struct_types,
	and loc parameters.  Change all callers.  Change error calls to
	error_at, using loc.  For a redefinition, if the location of the
	original definition is known, report it.  Set in_struct and
	struct_types.
	(finish_struct): Add new parameters enclosing_in_struct and
	enclosing_struct_types.  Change all callers.  Set
	C_TYPE_DEFINED_IN_STRUCT for all struct/union/enum types defined
	in the struct.  If in a struct, add this struct to struct_types.
	(start_enum): Add loc parameter.  Change all callers.  Use
	error_at for errors, using loc.  For a redefinition, if the
	location of the original definition is known, report it.  If in a
	struct, add this enum type to struct_types.
	* c-parser.c (c_parser_enum_specifier): Get enum location for
	start_enum.
	(c_parser_struct_or_union_specifier): Get struct location for
	start_struct.  Save in_struct and struct_types status between
	start_struct and finish_struct.
	* c-typeck.c (build_external_ref): If -Wc++-compat, warn about a
	use of an enum constant from an enum type defined in a struct or
	union.
	* c-tree.h (C_TYPE_DEFINED_IN_STRUCT): Define.
	(start_enum, start_struct, finish_struct): Update declarations.
	(parser_xref_tag): Update declaration.

gcc/objc/ChangeLog:

2009-05-06  Ian Lance Taylor  <iant@google.com>

	* objc-act.c (objc_building_struct): New static variable.
	(objc_in_struct, objc_struct_types): New static variables.
	(objc_start_struct, objc_finish_struct): New static functions.
	(generate_struct_by_value_array): Call objc_start_struct instead
	of start_struct, and call objc_finish_struct instead of
	finish_struct.
	(objc_build_struct, build_objc_symtab_template): Likewise.
	(build_module_descriptor): Likewise.
	(build_next_objc_exception_stuff): Likewise.
	(build_protocol_template): Likewise.
	(build_method_prototype_list_template): Likewise.
	(build_method_prototype_template): Likewise.
	(build_category_template, build_selector_template): Likewise.
	(build_class_template, build_super_template): Likewise.
	(build_ivar_template, build_ivar_list_template): Likewise.
	(build_method_list_template): Likewise.
	(build_method_template): Likewise.

gcc/objcp/ChangeLog:

2009-05-06  Ian Lance Taylor  <iant@google.com>

	* objcp-decl.h (start_struct): Add three new, ignored, macro
	parameters.
	(finish_struct): Add two new, ignored, macro parameters.


gcc/testsuite/ChangeLog:

2009-05-06  Ian Lance Taylor  <iant@google.com>

	* gcc.dg/Wcxx-compat-7.c: New testcase.
	* gcc.dg/c99-tag-1.c: Recognize new "originally defined here"
	notes
	* gcc.dg/pr17188-1.c: Likewise.
	* gcc.dg/pr39084.c: Likewise.


Index: c-decl.c
===================================================================
--- c-decl.c	(revision 147115)
+++ c-decl.c	(working copy)
@@ -126,6 +126,15 @@ static GTY(()) struct stmt_tree_s c_stmt
 tree c_break_label;
 tree c_cont_label;
 
+/* True if we are currently parsing the fields of a struct or
+   union.  */
+
+static bool in_struct;
+
+/* A list of types defined in the current struct or union.  */
+
+static tree struct_types;
+
 /* Linked list of TRANSLATION_UNIT_DECLS for the translation units
    included in this invocation.  Note that the current translation
    unit is not included in this list.  */
@@ -1046,13 +1055,12 @@ pop_file_scope (void)
    In that case, the TYPE_SIZE will be zero.  */
 
 static void
-pushtag (tree name, tree type)
+pushtag (tree name, tree type, location_t loc)
 {
   /* Record the identifier as the type's name if it has none.  */
   if (name && !TYPE_NAME (type))
     TYPE_NAME (type) = name;
-  bind (name, type, current_scope, /*invisible=*/false, /*nested=*/false,
-	UNKNOWN_LOCATION);
+  bind (name, type, current_scope, /*invisible=*/false, /*nested=*/false, loc);
 
   /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE will be the
      tagged type we just added to the current scope.  This fake
@@ -2685,10 +2693,13 @@ define_label (location_t location, tree 
    If THISLEVEL_ONLY is nonzero, searches only the current_scope.
    CODE says which kind of type the caller wants;
    it is RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE.
+   If PLOC is not NULL and this returns non-null, it sets *PLOC to the
+   location where the tag was defined.
    If the wrong kind of type is found, an error is reported.  */
 
 static tree
-lookup_tag (enum tree_code code, tree name, int thislevel_only)
+lookup_tag (enum tree_code code, tree name, int thislevel_only,
+	    location_t *ploc)
 {
   struct c_binding *b = I_TAG_BINDING (name);
   int thislevel = 0;
@@ -2725,6 +2736,10 @@ lookup_tag (enum tree_code code, tree na
       if (thislevel)
 	pending_xref_error ();
     }
+
+  if (ploc != NULL)
+    *ploc = b->locus;
+
   return b->decl;
 }
 
@@ -2997,12 +3012,12 @@ shadow_tag_warned (const struct c_declsp
 	  else
 	    {
 	      pending_invalid_xref = 0;
-	      t = lookup_tag (code, name, 1);
+	      t = lookup_tag (code, name, 1, NULL);
 
 	      if (t == 0)
 		{
 		  t = make_node (code);
-		  pushtag (name, t);
+		  pushtag (name, t, input_location);
 		}
 	    }
 	}
@@ -5512,10 +5527,11 @@ get_parm_info (bool ellipsis)
    Return a c_typespec structure for the type specifier.  */
 
 struct c_typespec
-parser_xref_tag (enum tree_code code, tree name)
+parser_xref_tag (enum tree_code code, tree name, location_t loc)
 {
   struct c_typespec ret;
   tree ref;
+  location_t refloc;
 
   ret.expr = NULL_TREE;
   ret.expr_const_operands = true;
@@ -5523,7 +5539,7 @@ parser_xref_tag (enum tree_code code, tr
   /* If a cross reference is requested, look up the type
      already defined for this tag and return it.  */
 
-  ref = lookup_tag (code, name, 0);
+  ref = lookup_tag (code, name, 0, &refloc);
   /* If this is the right type of tag, return what we found.
      (This reference will be shadowed by shadow_tag later if appropriate.)
      If this is the wrong type of tag, do not return it.  If it was the
@@ -5538,6 +5554,35 @@ parser_xref_tag (enum tree_code code, tr
   ret.kind = (ref ? ctsk_tagref : ctsk_tagfirstref);
   if (ref && TREE_CODE (ref) == code)
     {
+      if (C_TYPE_DEFINED_IN_STRUCT (ref)
+	  && loc != UNKNOWN_LOCATION
+	  && warn_cxx_compat)
+	{
+	  switch (code)
+	    {
+	    case ENUMERAL_TYPE:
+	      warning_at (loc, OPT_Wc___compat,
+			  ("enum type defined in struct or union "
+			   "is not visible in C++"));
+	      inform (refloc, "enum type defined here");
+	      break;
+	    case RECORD_TYPE:
+	      warning_at (loc, OPT_Wc___compat,
+			  ("struct defined in struct or union "
+			   "is not visible in C++"));
+	      inform (refloc, "struct defined here");
+	      break;
+	    case UNION_TYPE:
+	      warning_at (loc, OPT_Wc___compat,
+			  ("union defined in struct or union "
+			   "is not visible in C++"));
+	      inform (refloc, "union defined here");
+	      break;
+	    default:
+	      gcc_unreachable();
+	    }
+	}
+
       ret.spec = ref;
       return ret;
     }
@@ -5561,7 +5606,7 @@ parser_xref_tag (enum tree_code code, tr
       TYPE_MAX_VALUE (ref) = TYPE_MAX_VALUE (unsigned_type_node);
     }
 
-  pushtag (name, ref);
+  pushtag (name, ref, loc);
 
   ret.spec = ref;
   return ret;
@@ -5574,40 +5619,52 @@ parser_xref_tag (enum tree_code code, tr
 tree
 xref_tag (enum tree_code code, tree name)
 {
-  return parser_xref_tag (code, name).spec;
+  return parser_xref_tag (code, name, UNKNOWN_LOCATION).spec;
 }
 
 /* Make sure that the tag NAME is defined *in the current scope*
    at least as a forward reference.
-   CODE says which kind of tag NAME ought to be.  */
+   CODE says which kind of tag NAME ought to be.
+
+   This stores the current value of the file static IN_STRUCT in
+   *ENCLOSING_IN_STRUCT, and sets IN_STRUCT to true.  Similarly, this
+   sets STRUCT_TYPES in *ENCLOSING_STRUCT_TYPES, and sets STRUCT_TYPES
+   to NULL_TREE.  The old values are restored in finish_struct.  */
 
 tree
-start_struct (enum tree_code code, tree name)
+start_struct (enum tree_code code, tree name, bool *enclosing_in_struct,
+	      tree *enclosing_struct_types, location_t loc)
 {
   /* If there is already a tag defined at this scope
      (as a forward reference), just return it.  */
 
-  tree ref = 0;
+  tree ref = NULL_TREE;
+  location_t refloc = UNKNOWN_LOCATION;
 
-  if (name != 0)
-    ref = lookup_tag (code, name, 1);
+  if (name != NULL_TREE)
+    ref = lookup_tag (code, name, 1, &refloc);
   if (ref && TREE_CODE (ref) == code)
     {
       if (TYPE_SIZE (ref))
 	{
 	  if (code == UNION_TYPE)
-	    error ("redefinition of %<union %E%>", name);
+	    error_at (loc, "redefinition of %<union %E%>", name);
 	  else
-	    error ("redefinition of %<struct %E%>", name);
+	    error_at (loc, "redefinition of %<struct %E%>", name);
+	  if (refloc != UNKNOWN_LOCATION)
+	    inform (refloc, "originally defined here");
 	  /* Don't create structures using a name already in use.  */
 	  ref = NULL_TREE;
 	}
       else if (C_TYPE_BEING_DEFINED (ref))
 	{
 	  if (code == UNION_TYPE)
-	    error ("nested redefinition of %<union %E%>", name);
+	    error_at (loc, "nested redefinition of %<union %E%>", name);
 	  else
-	    error ("nested redefinition of %<struct %E%>", name);
+	    error_at (loc, "nested redefinition of %<struct %E%>", name);
+	  /* Don't bother to report "originally defined here" for a
+	     nested redefinition; the original definition should be
+	     obvious.  */
 	  /* Don't create structures that contain themselves.  */
 	  ref = NULL_TREE;
 	}
@@ -5618,11 +5675,17 @@ start_struct (enum tree_code code, tree 
   if (ref == NULL_TREE || TREE_CODE (ref) != code)
     {
       ref = make_node (code);
-      pushtag (name, ref);
+      pushtag (name, ref, loc);
     }
 
   C_TYPE_BEING_DEFINED (ref) = 1;
   TYPE_PACKED (ref) = flag_pack_struct;
+
+  *enclosing_in_struct = in_struct;
+  *enclosing_struct_types = struct_types;
+  in_struct = true;
+  struct_types = NULL_TREE;
+
   return ref;
 }
 
@@ -5760,10 +5823,16 @@ detect_field_duplicates (tree fieldlist)
 
 /* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T.
    FIELDLIST is a chain of FIELD_DECL nodes for the fields.
-   ATTRIBUTES are attributes to be applied to the structure.  */
+   ATTRIBUTES are attributes to be applied to the structure.
+
+   ENCLOSING_IN_STRUCT is the value of IN_STRUCT, and
+   ENCLOSING_STRUCT_TYPES is the value of STRUCT_TYPES, when the
+   struct was started.  This sets the C_TYPE_DEFINED_IN_STRUCT flag
+   for any type defined in the current struct.  */
 
 tree
-finish_struct (tree t, tree fieldlist, tree attributes)
+finish_struct (tree t, tree fieldlist, tree attributes,
+	       bool enclosing_in_struct, tree enclosing_struct_types)
 {
   tree x;
   bool toplevel = file_scope == current_scope;
@@ -6020,6 +6089,22 @@ finish_struct (tree t, tree fieldlist, t
   if (cur_stmt_list && variably_modified_type_p (t, NULL_TREE))
     add_stmt (build_stmt (DECL_EXPR, build_decl (TYPE_DECL, NULL, t)));
 
+  /* Set the C_TYPE_DEFINED_IN_STRUCT flag for each type defined in
+     the current struct.  We do this now at the end of the struct
+     because the flag is used to issue visibility warnings when using
+     -Wc++-compat, and we only want to issue those warnings if the
+     type is referenced outside of the struct declaration.  */
+  for (x = struct_types; x != NULL_TREE; x = TREE_CHAIN (x))
+    C_TYPE_DEFINED_IN_STRUCT (TREE_VALUE (x)) = 1;
+
+  in_struct = enclosing_in_struct;
+  struct_types = enclosing_struct_types;
+
+  /* If this struct is defined inside a struct, add it to
+     STRUCT_TYPES.  */
+  if (in_struct)
+    struct_types = tree_cons (NULL_TREE, t, struct_types);
+
   return t;
 }
 
@@ -6040,32 +6125,35 @@ layout_array_type (tree t)
    may be used to declare the individual values as they are read.  */
 
 tree
-start_enum (struct c_enum_contents *the_enum, tree name)
+start_enum (struct c_enum_contents *the_enum, tree name, location_t loc)
 {
-  tree enumtype = 0;
+  tree enumtype = NULL_TREE;
+  location_t enumloc = UNKNOWN_LOCATION;
 
   /* If this is the real definition for a previous forward reference,
      fill in the contents in the same object that used to be the
      forward reference.  */
 
-  if (name != 0)
-    enumtype = lookup_tag (ENUMERAL_TYPE, name, 1);
+  if (name != NULL_TREE)
+    enumtype = lookup_tag (ENUMERAL_TYPE, name, 1, &enumloc);
 
   if (enumtype == 0 || TREE_CODE (enumtype) != ENUMERAL_TYPE)
     {
       enumtype = make_node (ENUMERAL_TYPE);
-      pushtag (name, enumtype);
+      pushtag (name, enumtype, loc);
     }
 
   if (C_TYPE_BEING_DEFINED (enumtype))
-    error ("nested redefinition of %<enum %E%>", name);
+    error_at (loc, "nested redefinition of %<enum %E%>", name);
 
   C_TYPE_BEING_DEFINED (enumtype) = 1;
 
   if (TYPE_VALUES (enumtype) != 0)
     {
       /* This enum is a named one that has been declared already.  */
-      error ("redeclaration of %<enum %E%>", name);
+      error_at (loc, "redeclaration of %<enum %E%>", name);
+      if (enumloc != UNKNOWN_LOCATION)
+	inform (enumloc, "originally defined here");
 
       /* Completely replace its old definition.
 	 The old enumerators remain defined, however.  */
@@ -6217,6 +6305,11 @@ finish_enum (tree enumtype, tree values,
   /* Finish debugging output for this type.  */
   rest_of_type_compilation (enumtype, toplevel);
 
+  /* If this enum is defined inside a struct, add it to
+     STRUCT_TYPES.  */
+  if (in_struct)
+    struct_types = tree_cons (NULL_TREE, enumtype, struct_types);
+
   return enumtype;
 }
 
Index: c-parser.c
===================================================================
--- c-parser.c	(revision 147115)
+++ c-parser.c	(working copy)
@@ -1617,8 +1617,10 @@ c_parser_enum_specifier (c_parser *parse
   struct c_typespec ret;
   tree attrs;
   tree ident = NULL_TREE;
+  location_t enum_loc;
   location_t ident_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
+  enum_loc = c_parser_peek_token (parser)->location;
   c_parser_consume_token (parser);
   attrs = c_parser_attributes (parser);
   /* Set the location in case we create a decl now.  */
@@ -1627,13 +1629,14 @@ c_parser_enum_specifier (c_parser *parse
     {
       ident = c_parser_peek_token (parser)->value;
       ident_loc = c_parser_peek_token (parser)->location;
+      enum_loc = ident_loc;
       c_parser_consume_token (parser);
     }
   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
     {
       /* Parse an enum definition.  */
       struct c_enum_contents the_enum;
-      tree type = start_enum (&the_enum, ident);
+      tree type = start_enum (&the_enum, ident, enum_loc);
       tree postfix_attrs;
       /* We chain the enumerators in reverse order, then put them in
 	 forward order at the end.  */
@@ -1712,7 +1715,7 @@ c_parser_enum_specifier (c_parser *parse
       ret.expr_const_operands = true;
       return ret;
     }
-  ret = parser_xref_tag (ENUMERAL_TYPE, ident);
+  ret = parser_xref_tag (ENUMERAL_TYPE, ident, ident_loc);
   /* In ISO C, enumerated types can be referred to only if already
      defined.  */
   if (pedantic && !COMPLETE_TYPE_P (ret.spec))
@@ -1769,6 +1772,8 @@ c_parser_struct_or_union_specifier (c_pa
   struct c_typespec ret;
   tree attrs;
   tree ident = NULL_TREE;
+  location_t struct_loc;
+  location_t ident_loc = UNKNOWN_LOCATION;
   enum tree_code code;
   switch (c_parser_peek_token (parser)->keyword)
     {
@@ -1781,6 +1786,7 @@ c_parser_struct_or_union_specifier (c_pa
     default:
       gcc_unreachable ();
     }
+  struct_loc = c_parser_peek_token (parser)->location;
   c_parser_consume_token (parser);
   attrs = c_parser_attributes (parser);
   /* Set the location in case we create a decl now.  */
@@ -1788,13 +1794,18 @@ c_parser_struct_or_union_specifier (c_pa
   if (c_parser_next_token_is (parser, CPP_NAME))
     {
       ident = c_parser_peek_token (parser)->value;
+      ident_loc = c_parser_peek_token (parser)->location;
+      struct_loc = ident_loc;
       c_parser_consume_token (parser);
     }
   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
     {
       /* Parse a struct or union definition.  Start the scope of the
 	 tag before parsing components.  */
-      tree type = start_struct (code, ident);
+      bool in_struct;
+      tree struct_types;
+      tree type = start_struct (code, ident, &in_struct, &struct_types,
+				struct_loc);
       tree postfix_attrs;
       /* We chain the components in reverse order, then put them in
 	 forward order at the end.  Each struct-declaration may
@@ -1884,7 +1895,8 @@ c_parser_struct_or_union_specifier (c_pa
 	}
       postfix_attrs = c_parser_attributes (parser);
       ret.spec = finish_struct (type, nreverse (contents),
-				chainon (attrs, postfix_attrs));
+				chainon (attrs, postfix_attrs),
+				in_struct, struct_types);
       ret.kind = ctsk_tagdef;
       ret.expr = NULL_TREE;
       ret.expr_const_operands = true;
@@ -1899,7 +1911,7 @@ c_parser_struct_or_union_specifier (c_pa
       ret.expr_const_operands = true;
       return ret;
     }
-  ret = parser_xref_tag (code, ident);
+  ret = parser_xref_tag (code, ident, ident_loc);
   return ret;
 }
 
Index: c-typeck.c
===================================================================
--- c-typeck.c	(revision 147115)
+++ c-typeck.c	(working copy)
@@ -2246,6 +2246,18 @@ build_external_ref (tree id, int fun, lo
   if (TREE_CODE (ref) == CONST_DECL)
     {
       used_types_insert (TREE_TYPE (ref));
+
+      if (warn_cxx_compat
+	  && TREE_CODE (TREE_TYPE (ref)) == ENUMERAL_TYPE
+	  && C_TYPE_DEFINED_IN_STRUCT (TREE_TYPE (ref)))
+	{
+	  warning_at (loc,
+		      OPT_Wc___compat,
+		      ("enum constant defined in struct or union "
+		       "is not visible in C++"));
+	  inform (DECL_SOURCE_LOCATION (ref), "enum constant defined here");
+	}
+
       ref = DECL_INITIAL (ref);
       TREE_CONSTANT (ref) = 1;
     }
Index: c-tree.h
===================================================================
--- c-tree.h	(revision 147115)
+++ c-tree.h	(working copy)
@@ -73,6 +73,10 @@ struct GTY(()) lang_type {
 #define C_TYPE_VARIABLE_SIZE(TYPE) TYPE_LANG_FLAG_1 (TYPE)
 #define C_DECL_VARIABLE_SIZE(TYPE) DECL_LANG_FLAG_0 (TYPE)
 
+/* Record whether a type is defined inside a struct or union type.
+   This is used for -Wc++-compat. */
+#define C_TYPE_DEFINED_IN_STRUCT(TYPE) TYPE_LANG_FLAG_2 (TYPE)
+
 /* Record whether a typedef for type `int' was actually `signed int'.  */
 #define C_TYPEDEF_EXPLICITLY_SIGNED(EXP) DECL_LANG_FLAG_1 (EXP)
 
@@ -514,7 +518,7 @@ extern void c_maybe_initialize_eh (void)
 extern void finish_decl (tree, tree, tree, tree);
 extern tree finish_enum (tree, tree, tree);
 extern void finish_function (void);
-extern tree finish_struct (tree, tree, tree);
+extern tree finish_struct (tree, tree, tree, bool, tree);
 extern struct c_arg_info *get_parm_info (bool);
 extern tree grokfield (location_t, struct c_declarator *,
 		       struct c_declspecs *, tree, tree *);
@@ -532,15 +536,15 @@ extern tree c_builtin_function (tree);
 extern tree c_builtin_function_ext_scope (tree);
 extern void shadow_tag (const struct c_declspecs *);
 extern void shadow_tag_warned (const struct c_declspecs *, int);
-extern tree start_enum (struct c_enum_contents *, tree);
+extern tree start_enum (struct c_enum_contents *, tree, location_t);
 extern int  start_function (struct c_declspecs *, struct c_declarator *, tree);
 extern tree start_decl (struct c_declarator *, struct c_declspecs *, bool,
 			tree);
-extern tree start_struct (enum tree_code, tree);
+extern tree start_struct (enum tree_code, tree, bool *, tree *, location_t);
 extern void store_parm_decls (void);
 extern void store_parm_decls_from (struct c_arg_info *);
 extern tree xref_tag (enum tree_code, tree);
-extern struct c_typespec parser_xref_tag (enum tree_code, tree);
+extern struct c_typespec parser_xref_tag (enum tree_code, tree, location_t);
 extern int c_expand_decl (tree);
 extern struct c_parm *build_c_parm (struct c_declspecs *, tree,
 				    struct c_declarator *);
Index: objc/objc-act.c
===================================================================
--- objc/objc-act.c	(revision 147115)
+++ objc/objc-act.c	(working copy)
@@ -415,6 +415,35 @@ FILE *gen_declaration_file;
 
 static int generating_instance_variables = 0;
 
+/* For building an objc struct.  These may not be used when this file
+   is compiled as part of obj-c++.  */
+
+static bool objc_building_struct;
+static bool objc_in_struct ATTRIBUTE_UNUSED;
+static tree objc_struct_types ATTRIBUTE_UNUSED;
+
+/* Start building a struct for objc.  */
+
+static tree
+objc_start_struct (tree name)
+{
+  gcc_assert (!objc_building_struct);
+  objc_building_struct = true;
+  return start_struct (RECORD_TYPE, name, &objc_in_struct, &objc_struct_types,
+		       UNKNOWN_LOCATION);
+}
+
+/* Finish building a struct for objc.  */
+
+static tree
+objc_finish_struct (tree type, tree fieldlist)
+{
+  gcc_assert (objc_building_struct);
+  objc_building_struct = false;
+  return finish_struct (type, fieldlist, NULL_TREE, objc_in_struct,
+			objc_struct_types);
+}
+
 /* Some platforms pass small structures through registers versus
    through an invisible pointer.  Determine at what size structure is
    the transition point between the two possibilities.  */
@@ -434,7 +463,7 @@ generate_struct_by_value_array (void)
       char buffer[5];
 
       /* Create an unnamed struct that has `i' character components */
-      type = start_struct (RECORD_TYPE, NULL_TREE);
+      type = objc_start_struct (NULL_TREE);
 
       strcpy (buffer, "c1");
       field_decl = create_field_decl (char_type_node,
@@ -448,7 +477,7 @@ generate_struct_by_value_array (void)
 					  buffer);
 	  chainon (field_decl_chain, field_decl);
 	}
-      finish_struct (type, field_decl_chain, NULL_TREE);
+      objc_finish_struct (type, field_decl_chain);
 
       aggregate_in_mem[i] = aggregate_value_p (type, 0);
       if (!aggregate_in_mem[i])
@@ -788,7 +817,7 @@ static tree
 objc_build_struct (tree klass, tree fields, tree super_name)
 {
   tree name = CLASS_NAME (klass);
-  tree s = start_struct (RECORD_TYPE, name);
+  tree s = objc_start_struct (name);
   tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
   tree t, objc_info = NULL_TREE;
 
@@ -849,7 +878,7 @@ objc_build_struct (tree klass, tree fiel
   INIT_TYPE_OBJC_INFO (s);
   TYPE_OBJC_INTERFACE (s) = klass;
 
-  s = finish_struct (s, fields, NULL_TREE);
+  s = objc_finish_struct (s, fields);
 
   for (t = TYPE_NEXT_VARIANT (s); t;
        t = TYPE_NEXT_VARIANT (t), objc_info = TREE_CHAIN (objc_info))
@@ -2057,8 +2086,7 @@ build_objc_symtab_template (void)
 {
   tree field_decl, field_decl_chain;
 
-  objc_symtab_template
-    = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
+  objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
 
   /* long sel_ref_cnt; */
   field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
@@ -2092,7 +2120,7 @@ build_objc_symtab_template (void)
       chainon (field_decl_chain, field_decl);
     }
 
-  finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
+  objc_finish_struct (objc_symtab_template, field_decl_chain);
 }
 
 /* Create the initial value for the `defs' field of _objc_symtab.
@@ -2292,8 +2320,7 @@ build_module_descriptor (void)
   push_lang_context (lang_name_c); /* extern "C" */
 #endif
 
-  objc_module_template
-    = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
+  objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE));
 
   /* long version; */
   field_decl = create_field_decl (long_integer_type_node, "version");
@@ -2315,7 +2342,7 @@ build_module_descriptor (void)
 			 "symtab");
   chainon (field_decl_chain, field_decl);
 
-  finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
+  objc_finish_struct (objc_module_template, field_decl_chain);
 
   /* Create an instance of "_objc_module".  */
   UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
@@ -3993,7 +4020,7 @@ build_next_objc_exception_stuff (void)
   tree field_decl, field_decl_chain, index, temp_type;
 
   objc_exception_data_template
-    = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
+    = objc_start_struct (get_identifier (UTAG_EXCDATA));
 
   /* int buf[OBJC_JBLEN]; */
 
@@ -4009,7 +4036,7 @@ build_next_objc_exception_stuff (void)
 				  "pointers");
   chainon (field_decl_chain, field_decl);
 
-  finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
+  objc_finish_struct (objc_exception_data_template, field_decl_chain);
 
   /* int _setjmp(...); */
   /* If the user includes <setjmp.h>, this shall be superseded by
@@ -4156,8 +4183,7 @@ build_protocol_template (void)
 {
   tree field_decl, field_decl_chain;
 
-  objc_protocol_template = start_struct (RECORD_TYPE,
-					 get_identifier (UTAG_PROTOCOL));
+  objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL));
 
   /* struct _objc_class *isa; */
   field_decl = create_field_decl (build_pointer_type
@@ -4187,7 +4213,7 @@ build_protocol_template (void)
 				  "class_methods");
   chainon (field_decl_chain, field_decl);
 
-  finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
+  objc_finish_struct (objc_protocol_template, field_decl_chain);
 }
 
 static tree
@@ -4237,7 +4263,7 @@ build_method_prototype_list_template (tr
 
   /* Generate an unnamed struct definition.  */
 
-  objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
+  objc_ivar_list_record = objc_start_struct (NULL_TREE);
 
   /* int method_count; */
   field_decl = create_field_decl (integer_type_node, "method_count");
@@ -4251,7 +4277,7 @@ build_method_prototype_list_template (tr
 				  "method_list");
   chainon (field_decl_chain, field_decl);
 
-  finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
+  objc_finish_struct (objc_ivar_list_record, field_decl_chain);
 
   return objc_ivar_list_record;
 }
@@ -4262,8 +4288,7 @@ build_method_prototype_template (void)
   tree proto_record;
   tree field_decl, field_decl_chain;
 
-  proto_record
-    = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
+  proto_record = objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE));
 
   /* SEL _cmd; */
   field_decl = create_field_decl (objc_selector_type, "_cmd");
@@ -4273,7 +4298,7 @@ build_method_prototype_template (void)
   field_decl = create_field_decl (string_type_node, "method_types");
   chainon (field_decl_chain, field_decl);
 
-  finish_struct (proto_record, field_decl_chain, NULL_TREE);
+  objc_finish_struct (proto_record, field_decl_chain);
 
   return proto_record;
 }
@@ -4758,8 +4783,7 @@ build_category_template (void)
 {
   tree field_decl, field_decl_chain;
 
-  objc_category_template = start_struct (RECORD_TYPE,
-					 get_identifier (UTAG_CATEGORY));
+  objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY));
 
   /* char *category_name; */
   field_decl = create_field_decl (string_type_node, "category_name");
@@ -4786,7 +4810,7 @@ build_category_template (void)
 				  "protocol_list");
   chainon (field_decl_chain, field_decl);
 
-  finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
+  objc_finish_struct (objc_category_template, field_decl_chain);
 }
 
 /* struct _objc_selector {
@@ -4797,11 +4821,9 @@ build_category_template (void)
 static void
 build_selector_template (void)
 {
-
   tree field_decl, field_decl_chain;
 
-  objc_selector_template
-    = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
+  objc_selector_template = objc_start_struct (get_identifier (UTAG_SELECTOR));
 
   /* SEL sel_id; */
   field_decl = create_field_decl (objc_selector_type, "sel_id");
@@ -4811,7 +4833,7 @@ build_selector_template (void)
   field_decl = create_field_decl (string_type_node, "sel_type");
   chainon (field_decl_chain, field_decl);
 
-  finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
+  objc_finish_struct (objc_selector_template, field_decl_chain);
 }
 
 /* struct _objc_class {
@@ -4847,8 +4869,7 @@ build_class_template (void)
 {
   tree field_decl, field_decl_chain;
 
-  objc_class_template
-    = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
+  objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS));
 
   /* struct _objc_class *isa; */
   field_decl = create_field_decl (build_pointer_type (objc_class_template),
@@ -4941,7 +4962,7 @@ build_class_template (void)
 				  "gc_object_type");
   chainon (field_decl_chain, field_decl);
 
-  finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
+  objc_finish_struct (objc_class_template, field_decl_chain);
 }
 
 /* Generate appropriate forward declarations for an implementation.  */
@@ -5042,7 +5063,7 @@ build_super_template (void)
 {
   tree field_decl, field_decl_chain;
 
-  objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
+  objc_super_template = objc_start_struct (get_identifier (UTAG_SUPER));
 
   /* struct _objc_object *self; */
   field_decl = create_field_decl (objc_object_type, "self");
@@ -5053,7 +5074,7 @@ build_super_template (void)
 				  "super_class");
   chainon (field_decl_chain, field_decl);
 
-  finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
+  objc_finish_struct (objc_super_template, field_decl_chain);
 }
 
 /* struct _objc_ivar {
@@ -5069,7 +5090,7 @@ build_ivar_template (void)
   tree field_decl, field_decl_chain;
 
   objc_ivar_id = get_identifier (UTAG_IVAR);
-  objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
+  objc_ivar_record = objc_start_struct (objc_ivar_id);
 
   /* char *ivar_name; */
   field_decl = create_field_decl (string_type_node, "ivar_name");
@@ -5083,7 +5104,7 @@ build_ivar_template (void)
   field_decl = create_field_decl (integer_type_node, "ivar_offset");
   chainon (field_decl_chain, field_decl);
 
-  finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
+  objc_finish_struct (objc_ivar_record, field_decl_chain);
 
   return objc_ivar_record;
 }
@@ -5099,7 +5120,7 @@ build_ivar_list_template (tree list_type
   tree objc_ivar_list_record;
   tree field_decl, field_decl_chain;
 
-  objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
+  objc_ivar_list_record = objc_start_struct (NULL_TREE);
 
   /* int ivar_count; */
   field_decl = create_field_decl (integer_type_node, "ivar_count");
@@ -5113,7 +5134,7 @@ build_ivar_list_template (tree list_type
 				  "ivar_list");
   chainon (field_decl_chain, field_decl);
 
-  finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
+  objc_finish_struct (objc_ivar_list_record, field_decl_chain);
 
   return objc_ivar_list_record;
 }
@@ -5130,7 +5151,7 @@ build_method_list_template (tree list_ty
   tree objc_ivar_list_record;
   tree field_decl, field_decl_chain;
 
-  objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
+  objc_ivar_list_record = objc_start_struct (NULL_TREE);
 
   /* struct _objc__method_prototype_list *method_next; */
   field_decl = create_field_decl (objc_method_proto_list_ptr,
@@ -5149,7 +5170,7 @@ build_method_list_template (tree list_ty
 				  "method_list");
   chainon (field_decl_chain, field_decl);
 
-  finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
+  objc_finish_struct (objc_ivar_list_record, field_decl_chain);
 
   return objc_ivar_list_record;
 }
@@ -5337,7 +5358,7 @@ build_method_template (void)
   tree _SLT_record;
   tree field_decl, field_decl_chain;
 
-  _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
+  _SLT_record = objc_start_struct (get_identifier (UTAG_METHOD));
 
   /* SEL _cmd; */
   field_decl = create_field_decl (objc_selector_type, "_cmd");
@@ -5352,7 +5373,7 @@ build_method_template (void)
 				  "_imp");
   chainon (field_decl_chain, field_decl);
 
-  finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
+  objc_finish_struct (_SLT_record, field_decl_chain);
 
   return _SLT_record;
 }
Index: objcp/objcp-decl.h
===================================================================
--- objcp/objcp-decl.h	(revision 147115)
+++ objcp/objcp-decl.h	(working copy)
@@ -1,6 +1,6 @@
 /* Process the ObjC-specific declarations and variables for 
    the Objective-C++ compiler.
-   Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc.
    Contributed by Ziemowit Laski  <zlaski@apple.com>
 
 This file is part of GCC.
@@ -37,9 +37,9 @@ extern tree objcp_end_compound_stmt (tre
    invoke the original C++ functions if needed).  */
 #ifdef OBJCP_REMAP_FUNCTIONS
 
-#define start_struct(code, name) \
+#define start_struct(code, name, in_struct, struct_types, loc) \
 	objcp_start_struct (code, name)
-#define finish_struct(t, fieldlist, attributes) \
+#define finish_struct(t, fieldlist, attributes, in_struct, struct_types) \
 	objcp_finish_struct (t, fieldlist, attributes)
 #define finish_function() \
 	objcp_finish_function ()
Index: testsuite/gcc.dg/Wcxx-compat-7.c
===================================================================
--- testsuite/gcc.dg/Wcxx-compat-7.c	(revision 0)
+++ testsuite/gcc.dg/Wcxx-compat-7.c	(revision 0)
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-Wc++-compat" } */
+
+struct s1
+{
+  enum e1	/* { dg-message "note: enum type defined here" } */
+  {
+    A,		/* { dg-message "note: enum constant defined here" } */
+    B
+  } f1;
+  struct s2	/* { dg-message "note: struct defined here" } */
+  {
+    struct s3	/* { dg-message "note: struct defined here" } */
+    {
+      enum e1 f3;
+      struct s1 *p1;
+      struct s2 *p2;
+      struct s3 *p3;
+    } f2;
+    union u1	/* { dg-message "note: union defined here" } */
+    {
+      int f4;
+    } f5;
+    struct s3 f6;
+  } f7;
+  struct s2 f8;
+  enum e1 f9;
+};
+
+struct s1 v1;
+enum e1 v2;	/* { dg-warning "not visible in C\[+\]\[+\]" } */
+struct s2 v3;	/* { dg-warning "not visible in C\[+\]\[+\]" } */
+struct s3 v4;	/* { dg-warning "not visible in C\[+\]\[+\]" } */
+union u1 v5;	/* { dg-warning "not visible in C\[+\]\[+\]" } */
+int i = A;	/* { dg-warning "not visible in C\[+\]\[+\]" } */
Index: testsuite/gcc.dg/pr39084.c
===================================================================
--- testsuite/gcc.dg/pr39084.c	(revision 147115)
+++ testsuite/gcc.dg/pr39084.c	(working copy)
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options "-O2" } */
 
-struct color { int i; };
+struct color { int i; }; /* { dg-message "note: originally defined here" } */
 static const struct color col;
 struct color * f(void)
 {
Index: testsuite/gcc.dg/c99-tag-1.c
===================================================================
--- testsuite/gcc.dg/c99-tag-1.c	(revision 147115)
+++ testsuite/gcc.dg/c99-tag-1.c	(working copy)
@@ -24,7 +24,7 @@ foo (void)
   /* A specific type shall have its content defined at most once.  But we
      may redeclare the tag in different scopes.  */
   {
-    struct s0 { int i; };
+    struct s0 { int i; }; /* { dg-message "note: originally defined here" } */
     {
       struct s0 { long l; };
     }
@@ -33,7 +33,7 @@ foo (void)
     }
     struct s0 { int i; }; /* { dg-bogus "warning" "warning in place of error" } */
     /* { dg-error "rede" "struct redef" { target *-*-* } 34 } */
-    union u0 { int i; };
+    union u0 { int i; }; /* { dg-message "note: originally defined here" } */
     {
       union u0 { long l; };
     }
@@ -42,7 +42,7 @@ foo (void)
     }
     union u0 { int i; }; /* { dg-bogus "warning" "warning in place of error" } */
     /* { dg-error "rede" "union redef" { target *-*-* } 43 } */
-    enum e0 { E0A };
+    enum e0 { E0A }; /* { dg-message "note: originally defined here" } */
     {
       enum e0 { E0B };
     }
Index: testsuite/gcc.dg/pr17188-1.c
===================================================================
--- testsuite/gcc.dg/pr17188-1.c	(revision 147115)
+++ testsuite/gcc.dg/pr17188-1.c	(working copy)
@@ -5,20 +5,20 @@
 /* { dg-do compile } */
 /* { dg-options "" } */
 
-struct s0 { };
+struct s0 { }; /* { dg-message "note: originally defined here" } */
 struct s0;
 struct s0 { }; /* { dg-error "redefinition of 'struct s0'" } */
 
-struct s1 { };
+struct s1 { }; /* { dg-message "note: originally defined here" } */
 struct s1 { }; /* { dg-error "redefinition of 'struct s1'" } */
 
-struct s2 { int a : 1; };
+struct s2 { int a : 1; }; /* { dg-message "note: originally defined here" } */
 struct s2 { int a : 1; }; /* { dg-error "redefinition of 'struct s2'" } */
 
-struct s3 { };
+struct s3 { }; /* { dg-message "note: originally defined here" } */
 struct s3 { int a : 1; }; /* { dg-error "redefinition of 'struct s3'" } */
 
-struct s4 { int a : 1; };
+struct s4 { int a : 1; }; /* { dg-message "note: originally defined here" } */
 struct s4 { }; /* { dg-error "redefinition of 'struct s4'" } */
 
 struct s5 { int a : 1; };



==================================================

Second patch:

gcc/ChangeLog:

2009-05-06  Ian Lance Taylor  <iant@google.com>

	* basic-block.h (enum profile_status): Break out of struct
	control_flow_graph.
	* cgraph.h (struct inline_summary): Break out of struct
	cgraph_local_info.
	* cgraphunit.c (enum cgraph_order_sort_kind): New enum, broken out
	of struct cgraph_order_sort.
	* combine.c (enum undo_kind): New enum, broken out of struct
	undo.
	* cse.c (struct branch_path): Break out of struct
	cse_basic_block_data.
	* except.h (enum eh_region_type): Break out of struct eh_region.
	* gcc.c (enum add_del): Break out of struct modify_target.
	* genrecog.c (enum decision_type): Break out of struct
	decision_test.
	* ggc-page.c (struct ggc_pch_ondisk): Break out of struct
	ggc_pch_data.
	* matrix-reorg.c (struct free_info): Break out of struct
	matrix_info.
	* regmove.c (enum match_use): New enum, broken out of struct
	match.
	* sched-int.h (enum post_call_group): New enum, broken out of
	struct deps.
	(struct deps_reg): Break out of struct deps.
	* target.h (struct asm_int_op): Break out of struct gcc_target.
	* tree-eh.c (struct goto_queue_node): Break out of struct
	leh_tf_state.
	* tree-inline.h (enum copy_body_cge_which): Break out of
	copy_body_data.
	* tree-pass.h (enum opt_pass_type): Break out of struct opt_pass.

gcc/fortran/ChangeLog:

2009-05-06  Ian Lance Taylor  <iant@google.com>

	* gfortran.h (enum gfc_omp_sched_kind): New enum, broken out of
	gfc_omp_clauses.
	(enum gfc_omp_default_sharing): Likewise.
	* module.c (enum gfc_rsym_state): New enum, broken out of
	pointer_info.
	(enum gfc_wsym_state): Likewise.
	* parse.c (enum state_order): New enum, broken out of st_state.


Index: genrecog.c
===================================================================
--- genrecog.c	(revision 147115)
+++ genrecog.c	(working copy)
@@ -71,6 +71,17 @@ struct decision_head
   struct decision *last;
 };
 
+/* These types are roughly in the order in which we'd like to test them.  */
+enum decision_type
+{
+  DT_num_insns,
+  DT_mode, DT_code, DT_veclen,
+  DT_elt_zero_int, DT_elt_one_int, DT_elt_zero_wide, DT_elt_zero_wide_safe,
+  DT_const_int,
+  DT_veclen_ge, DT_dup, DT_pred, DT_c_test,
+  DT_accept_op, DT_accept_insn
+};
+
 /* A single test.  The two accept types aren't tests per-se, but
    their equality (or lack thereof) does affect tree merging so
    it is convenient to keep them here.  */
@@ -80,16 +91,7 @@ struct decision_test
   /* A linked list through the tests attached to a node.  */
   struct decision_test *next;
 
-  /* These types are roughly in the order in which we'd like to test them.  */
-  enum decision_type
-    {
-      DT_num_insns,
-      DT_mode, DT_code, DT_veclen,
-      DT_elt_zero_int, DT_elt_one_int, DT_elt_zero_wide, DT_elt_zero_wide_safe,
-      DT_const_int,
-      DT_veclen_ge, DT_dup, DT_pred, DT_c_test,
-      DT_accept_op, DT_accept_insn
-    } type;
+  enum decision_type type;
 
   union
   {
Index: cgraph.h
===================================================================
--- cgraph.h	(revision 147115)
+++ cgraph.h	(working copy)
@@ -1,5 +1,5 @@
 /* Callgraph handling code.
-   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
    Contributed by Jan Hubicka
 
@@ -48,17 +48,22 @@ enum availability
 
 extern const char * const cgraph_availability_names[];
 
+/* Function inlining information.  */
+
+struct GTY(()) inline_summary
+{
+  /* Estimated stack frame consumption by the function.  */
+  HOST_WIDE_INT estimated_self_stack_size;
+
+  /* Size of the function before inlining.  */
+  int self_insns;
+};
+
 /* Information about the function collected locally.
    Available after function is analyzed.  */
 
 struct GTY(()) cgraph_local_info {
-  struct inline_summary {
-    /* Estimated stack frame consumption by the function.  */
-    HOST_WIDE_INT estimated_self_stack_size;
-
-    /* Size of the function before inlining.  */
-    int self_insns;
-  } inline_summary;
+  struct inline_summary inline_summary;
 
   /* Set when function function is visible in current compilation unit only
      and its address is never taken.  */
Index: tree-pass.h
===================================================================
--- tree-pass.h	(revision 147115)
+++ tree-pass.h	(working copy)
@@ -94,17 +94,22 @@ extern const char *dump_file_name;
 /* Return the dump_file_info for the given phase.  */
 extern struct dump_file_info *get_dump_file_info (int);
 
+/* Optimization pass type.  */
+enum opt_pass_type
+{
+  GIMPLE_PASS,
+  RTL_PASS,
+  SIMPLE_IPA_PASS,
+  IPA_PASS
+};
+
 /* Describe one pass; this is the common part shared across different pass
    types.  */
 struct opt_pass
 {
   /* Optimization pass type.  */
-  enum opt_pass_type {
-    GIMPLE_PASS,
-    RTL_PASS,
-    SIMPLE_IPA_PASS,
-    IPA_PASS
-  } type;
+  enum opt_pass_type type;
+
   /* Terse name of the pass used as a fragment of the dump file
      name.  If the name starts with a star, no dump happens. */
   const char *name;
Index: target.h
===================================================================
--- target.h	(revision 147115)
+++ target.h	(working copy)
@@ -91,6 +91,18 @@ struct _dep;
 /* This is defined in ddg.h .  */
 struct ddg;
 
+/* Assembler instructions for creating various kinds of integer object.  */
+
+struct asm_int_op
+{
+  const char *hi;
+  const char *si;
+  const char *di;
+  const char *ti;
+};
+
+/* The target structure.  This holds all the backend hooks.  */
+
 struct gcc_target
 {
   /* Functions that output assembler for the target.  */
@@ -101,13 +113,7 @@ struct gcc_target
 
     /* Assembler instructions for creating various kinds of integer object.  */
     const char *byte_op;
-    struct asm_int_op
-    {
-      const char *hi;
-      const char *si;
-      const char *di;
-      const char *ti;
-    } aligned_op, unaligned_op;
+    struct asm_int_op aligned_op, unaligned_op;
 
     /* Try to output the assembler code for an integer object whose
        value is given by X.  SIZE is the size of the object in bytes and
Index: gcc.c
===================================================================
--- gcc.c	(revision 147115)
+++ gcc.c	(working copy)
@@ -268,10 +268,12 @@ static const char *cross_compile = "0";
    switch.  The only case we support now is simply appending or deleting a
    string to or from the end of the first part of the configuration name.  */
 
+enum add_del {ADD, DELETE};
+
 static const struct modify_target
 {
   const char *const sw;
-  const enum add_del {ADD, DELETE} add_del;
+  const enum add_del add_del;
   const char *const str;
 }
 modify_target[] = MODIFY_TARGET_NAME;
Index: cgraphunit.c
===================================================================
--- cgraphunit.c	(revision 147115)
+++ cgraphunit.c	(working copy)
@@ -1118,9 +1118,17 @@ cgraph_expand_all_functions (void)
 
 /* This is used to sort the node types by the cgraph order number.  */
 
+enum cgraph_order_sort_kind
+{
+  ORDER_UNDEFINED = 0,
+  ORDER_FUNCTION,
+  ORDER_VAR,
+  ORDER_ASM
+};
+
 struct cgraph_order_sort
 {
-  enum { ORDER_UNDEFINED = 0, ORDER_FUNCTION, ORDER_VAR, ORDER_ASM } kind;
+  enum cgraph_order_sort_kind kind;
   union
   {
     struct cgraph_node *f;
Index: cse.c
===================================================================
--- cse.c	(revision 147115)
+++ cse.c	(working copy)
@@ -517,6 +517,14 @@ static struct table_elt *free_element_ch
 static int constant_pool_entries_cost;
 static int constant_pool_entries_regcost;
 
+/* Trace a patch through the CFG.  */
+
+struct branch_path
+{
+  /* The basic block for this path entry.  */
+  basic_block bb;
+};
+
 /* This data describes a block that will be processed by
    cse_extended_basic_block.  */
 
@@ -527,11 +535,7 @@ struct cse_basic_block_data
   /* Size of current branch path, if any.  */
   int path_size;
   /* Current path, indicating which basic_blocks will be processed.  */
-  struct branch_path
-    {
-      /* The basic block for this path entry.  */
-      basic_block bb;
-    } *path;
+  struct branch_path *path;
 };
 
 
@@ -7058,4 +7062,3 @@ struct rtl_opt_pass pass_cse_after_globa
   TODO_verify_flow                      /* todo_flags_finish */
  }
 };
-
Index: matrix-reorg.c
===================================================================
--- matrix-reorg.c	(revision 147115)
+++ matrix-reorg.c	(working copy)
@@ -243,6 +243,14 @@ typedef struct access_site_info *access_
 DEF_VEC_P (access_site_info_p);
 DEF_VEC_ALLOC_P (access_site_info_p, heap);
 
+/* Calls to free when flattening a matrix.  */
+
+struct free_info
+{
+  gimple stmt;
+  tree func;
+};
+
 /* Information about matrix to flatten.  */
 struct matrix_info
 {
@@ -275,11 +283,7 @@ struct matrix_info
   tree allocation_function_decl;
 
   /* The calls to free for each level of indirection.  */
-  struct free_info
-  {
-    gimple stmt;
-    tree func;
-  } *free_stmts;
+  struct free_info *free_stmts;
 
   /* An array which holds for each dimension its size. where
      dimension 0 is the outer most (one that contains all the others).
Index: tree-eh.c
===================================================================
--- tree-eh.c	(revision 147115)
+++ tree-eh.c	(working copy)
@@ -344,6 +344,26 @@ outside_finally_tree (treemple start, gi
    The eh region creation is straight-forward, but frobbing all the gotos
    and such into shape isn't.  */
 
+/* The GOTO_QUEUE is is an array of GIMPLE_GOTO and GIMPLE_RETURN
+   statements that are seen to escape this GIMPLE_TRY_FINALLY node.
+   The idea is to record a gimple statement for everything except for
+   the conditionals, which get their labels recorded. Since labels are
+   of type 'tree', we need this node to store both gimple and tree
+   objects.  REPL_STMT is the sequence used to replace the goto/return
+   statement.  CONT_STMT is used to store the statement that allows
+   the return/goto to jump to the original destination. */
+
+struct goto_queue_node
+{
+  treemple stmt;
+  gimple_seq repl_stmt;
+  gimple cont_stmt;
+  int index;
+  /* This is used when index >= 0 to indicate that stmt is a label (as
+     opposed to a goto stmt).  */
+  int is_label;
+};
+
 /* State of the world while lowering.  */
 
 struct leh_state
@@ -378,23 +398,8 @@ struct leh_tf_state
   /* The exception region created for it.  */
   struct eh_region *region;
 
-  /* The GOTO_QUEUE is is an array of GIMPLE_GOTO and GIMPLE_RETURN statements
-     that are seen to escape this GIMPLE_TRY_FINALLY node.
-     The idea is to record a gimple statement for everything except for 
-     the conditionals, which get their labels recorded. Since labels are of
-     type 'tree', we need this node to store both gimple and tree objects.
-     REPL_STMT is the sequence used to replace the goto/return statement.
-     CONT_STMT is used to store the statement that allows the return/goto to
-     jump to the original destination. */
-  struct goto_queue_node {
-    treemple stmt;
-    gimple_seq repl_stmt;
-    gimple cont_stmt;
-    int index;
-    /* this is used when index >= 0 to indicate that stmt is a label(as
-       opposed to a goto stmt) */
-    int is_label;
-  } *goto_queue;
+  /* The goto queue.  */
+  struct goto_queue_node *goto_queue;
   size_t goto_queue_size;
   size_t goto_queue_active;
 
Index: fortran/gfortran.h
===================================================================
--- fortran/gfortran.h	(revision 147115)
+++ fortran/gfortran.h	(working copy)
@@ -927,29 +927,34 @@ enum
 
 /* Because a symbol can belong to multiple namelists, they must be
    linked externally to the symbol itself.  */
+
+enum gfc_omp_sched_kind
+{
+  OMP_SCHED_NONE,
+  OMP_SCHED_STATIC,
+  OMP_SCHED_DYNAMIC,
+  OMP_SCHED_GUIDED,
+  OMP_SCHED_RUNTIME,
+  OMP_SCHED_AUTO
+};
+
+enum gfc_omp_default_sharing
+{
+  OMP_DEFAULT_UNKNOWN,
+  OMP_DEFAULT_NONE,
+  OMP_DEFAULT_PRIVATE,
+  OMP_DEFAULT_SHARED,
+  OMP_DEFAULT_FIRSTPRIVATE
+};
+
 typedef struct gfc_omp_clauses
 {
   struct gfc_expr *if_expr;
   struct gfc_expr *num_threads;
   gfc_namelist *lists[OMP_LIST_NUM];
-  enum
-    {
-      OMP_SCHED_NONE,
-      OMP_SCHED_STATIC,
-      OMP_SCHED_DYNAMIC,
-      OMP_SCHED_GUIDED,
-      OMP_SCHED_RUNTIME,
-      OMP_SCHED_AUTO
-    } sched_kind;
+  enum gfc_omp_sched_kind sched_kind;
   struct gfc_expr *chunk_size;
-  enum
-    {
-      OMP_DEFAULT_UNKNOWN,
-      OMP_DEFAULT_NONE,
-      OMP_DEFAULT_PRIVATE,
-      OMP_DEFAULT_SHARED,
-      OMP_DEFAULT_FIRSTPRIVATE
-    } default_sharing;
+  enum gfc_omp_default_sharing default_sharing;
   int collapse;
   bool nowait, ordered, untied;
 }
Index: fortran/module.c
===================================================================
--- fortran/module.c	(revision 147115)
+++ fortran/module.c	(working copy)
@@ -119,6 +119,20 @@ fixup_t;
 
 /* Structure for holding extra info needed for pointers being read.  */
 
+enum gfc_rsym_state
+{
+  UNUSED,
+  NEEDED,
+  USED
+};
+
+enum gfc_wsym_state
+{
+  UNREFERENCED = 0,
+  NEEDS_WRITE,
+  WRITTEN
+};
+
 typedef struct pointer_info
 {
   BBT_HEADER (pointer_info);
@@ -138,9 +152,7 @@ typedef struct pointer_info
     {
       gfc_symbol *sym;
       char true_name[GFC_MAX_SYMBOL_LEN + 1], module[GFC_MAX_SYMBOL_LEN + 1];
-      enum
-      { UNUSED, NEEDED, USED }
-      state;
+      enum gfc_rsym_state state;
       int ns, referenced, renamed;
       module_locus where;
       fixup_t *stfixup;
@@ -152,9 +164,7 @@ typedef struct pointer_info
     struct
     {
       gfc_symbol *sym;
-      enum
-      { UNREFERENCED = 0, NEEDS_WRITE, WRITTEN }
-      state;
+      enum gfc_wsym_state state;
     }
     wsym;
   }
Index: fortran/parse.c
===================================================================
--- fortran/parse.c	(revision 147115)
+++ fortran/parse.c	(working copy)
@@ -1580,13 +1580,20 @@ unexpected_statement (gfc_statement st)
 
 */
 
+enum state_order
+{
+  ORDER_START,
+  ORDER_USE,
+  ORDER_IMPORT,
+  ORDER_IMPLICIT_NONE,
+  ORDER_IMPLICIT,
+  ORDER_SPEC,
+  ORDER_EXEC
+};
+
 typedef struct
 {
-  enum
-  { ORDER_START, ORDER_USE, ORDER_IMPORT, ORDER_IMPLICIT_NONE,
-    ORDER_IMPLICIT, ORDER_SPEC, ORDER_EXEC
-  }
-  state;
+  enum state_order state;
   gfc_statement last_statement;
   locus where;
 }
Index: regmove.c
===================================================================
--- regmove.c	(revision 147115)
+++ regmove.c	(working copy)
@@ -50,9 +50,16 @@ static void optimize_reg_copy_2 (rtx, rt
 static void optimize_reg_copy_3 (rtx, rtx, rtx);
 static void copy_src_to_dest (rtx, rtx, rtx);
 
+enum match_use
+{
+  READ,
+  WRITE,
+  READWRITE
+};
+
 struct match {
   int with[MAX_RECOG_OPERANDS];
-  enum { READ, WRITE, READWRITE } use[MAX_RECOG_OPERANDS];
+  enum match_use use[MAX_RECOG_OPERANDS];
   int commutative[MAX_RECOG_OPERANDS];
   int early_clobber[MAX_RECOG_OPERANDS];
 };
Index: except.h
===================================================================
--- except.h	(revision 147115)
+++ except.h	(working copy)
@@ -1,6 +1,6 @@
 /* Exception Handling interface routines.
    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2007, 2008  Free Software Foundation, Inc.
+   2007, 2008, 2009  Free Software Foundation, Inc.
    Contributed by Mike Stump <mrs@cygnus.com>.
 
 This file is part of GCC.
@@ -24,6 +24,18 @@ along with GCC; see the file COPYING3.  
 
 struct function;
 
+/* The type of an exception region.  */
+enum eh_region_type
+{
+  ERT_UNKNOWN = 0,
+  ERT_CLEANUP,
+  ERT_TRY,
+  ERT_CATCH,
+  ERT_ALLOWED_EXCEPTIONS,
+  ERT_MUST_NOT_THROW,
+  ERT_THROW
+};
+
 /* Describes one exception region.  */
 struct GTY(()) eh_region
 {
@@ -45,16 +57,7 @@ struct GTY(()) eh_region
   bitmap aka;
 
   /* Each region does exactly one thing.  */
-  enum eh_region_type
-  {
-    ERT_UNKNOWN = 0,
-    ERT_CLEANUP,
-    ERT_TRY,
-    ERT_CATCH,
-    ERT_ALLOWED_EXCEPTIONS,
-    ERT_MUST_NOT_THROW,
-    ERT_THROW
-  } type;
+  enum eh_region_type type;
 
   /* Holds the action to perform based on the preceding type.  */
   union eh_region_u {
Index: ggc-page.c
===================================================================
--- ggc-page.c	(revision 147115)
+++ ggc-page.c	(working copy)
@@ -1,5 +1,5 @@
 /* "Bag-of-pages" garbage collector for the GNU compiler.
-   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
+   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -2063,12 +2063,14 @@ ggc_print_statistics (void)
 #endif
 }
 
+struct ggc_pch_ondisk
+{
+  unsigned totals[NUM_ORDERS];
+};
+
 struct ggc_pch_data
 {
-  struct ggc_pch_ondisk
-  {
-    unsigned totals[NUM_ORDERS];
-  } d;
+  struct ggc_pch_ondisk d;
   size_t base[NUM_ORDERS];
   size_t written[NUM_ORDERS];
 };
Index: tree-inline.h
===================================================================
--- tree-inline.h	(revision 147115)
+++ tree-inline.h	(working copy)
@@ -1,5 +1,6 @@
 /* Tree inlining hooks and declarations.
-   Copyright 2001, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+   Copyright 2001, 2003, 2004, 2005, 2007, 2008, 2009
+   Free Software Foundation, Inc.
    Contributed by Alexandre Oliva  <aoliva@redhat.com>
 
 This file is part of GCC.
@@ -25,6 +26,17 @@ along with GCC; see the file COPYING3.  
 #include "pointer-set.h"
 
 
+/* Indicate the desired behavior wrt call graph edges.  We can either
+   duplicate the edge (inlining, cloning), move the edge (versioning,
+   parallelization), or move the edges of the clones (saving).  */
+
+enum copy_body_cge_which
+{
+  CB_CGE_DUPLICATE,
+  CB_CGE_MOVE,
+  CB_CGE_MOVE_CLONES
+};
+
 /* Data required for function body duplication.  */
 
 typedef struct copy_body_data
@@ -76,14 +88,8 @@ typedef struct copy_body_data
      than enumerating the different cases, we categorize the behavior
      in the various situations.  */
 
-  /* Indicate the desired behavior wrt call graph edges.  We can either
-     duplicate the edge (inlining, cloning), move the edge (versioning,
-     parallelization), or move the edges of the clones (saving).  */
-  enum copy_body_cge_which {
-    CB_CGE_DUPLICATE,
-    CB_CGE_MOVE,
-    CB_CGE_MOVE_CLONES
-  } transform_call_graph_edges;
+  /* What to do with call graph edges.  */
+  enum copy_body_cge_which transform_call_graph_edges;
 
   /* True if a new CFG should be created.  False for inlining, true for
      everything else.  */
Index: sched-int.h
===================================================================
--- sched-int.h	(revision 147115)
+++ sched-int.h	(working copy)
@@ -1,7 +1,8 @@
 /* Instruction scheduling pass.  This file contains definitions used
    internally in the scheduler.
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+   2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -425,6 +426,24 @@ enum reg_pending_barrier_mode
   TRUE_BARRIER
 };
 
+/* Whether a register movement is associated with a call.  */
+enum post_call_group
+{
+  not_post_call,
+  post_call,
+  post_call_initial
+};
+
+/* Insns which affect pseudo-registers.  */
+struct deps_reg
+{
+  rtx uses;
+  rtx sets;
+  rtx clobbers;
+  int uses_length;
+  int clobbers_length;
+};
+
 /* Describe state of dependencies used during sched_analyze phase.  */
 struct deps
 {
@@ -488,7 +507,7 @@ struct deps
 
   /* Used to keep post-call pseudo/hard reg movements together with
      the call.  */
-  enum { not_post_call, post_call, post_call_initial } in_post_call_group_p;
+  enum post_call_group in_post_call_group_p;
 
   /* The maximum register number for the following arrays.  Before reload
      this is max_reg_num; after reload it is FIRST_PSEUDO_REGISTER.  */
@@ -498,14 +517,7 @@ struct deps
      N within the current basic block; or zero, if there is no
      such insn.  Needed for new registers which may be introduced
      by splitting insns.  */
-  struct deps_reg
-    {
-      rtx uses;
-      rtx sets;
-      rtx clobbers;
-      int uses_length;
-      int clobbers_length;
-    } *reg_last;
+  struct deps_reg *reg_last;
 
   /* Element N is set for each register that has any nonzero element
      in reg_last[N].{uses,sets,clobbers}.  */
Index: combine.c
===================================================================
--- combine.c	(revision 147115)
+++ combine.c	(working copy)
@@ -342,10 +342,12 @@ static int nonzero_sign_valid;
 /* Record one modification to rtl structure
    to be undone by storing old_contents into *where.  */
 
+enum undo_kind { UNDO_RTX, UNDO_INT, UNDO_MODE };
+
 struct undo
 {
   struct undo *next;
-  enum { UNDO_RTX, UNDO_INT, UNDO_MODE } kind;
+  enum undo_kind kind;
   union { rtx r; int i; enum machine_mode m; } old_contents;
   union { rtx *r; int *i; } where;
 };
Index: basic-block.h
===================================================================
--- basic-block.h	(revision 147115)
+++ basic-block.h	(working copy)
@@ -1,6 +1,6 @@
 /* Define control and data flow tables, and regsets.
    Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+   2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -356,6 +356,14 @@ enum dom_state
   DOM_OK		/* Everything is ok.  */
 };
 
+/* What sort of profiling information we have.  */
+enum profile_status
+{
+  PROFILE_ABSENT,
+  PROFILE_GUESSED,
+  PROFILE_READ
+};
+
 /* A structure to group all the per-function control flow graph data.
    The x_* prefixing is necessary because otherwise references to the
    fields of this struct are interpreted as the defines for backward
@@ -382,11 +390,7 @@ struct GTY(()) control_flow_graph {
      only used for the gimple CFG.  */
   VEC(basic_block,gc) *x_label_to_block_map;
 
-  enum profile_status {
-    PROFILE_ABSENT,
-    PROFILE_GUESSED,
-    PROFILE_READ
-  } x_profile_status;
+  enum profile_status x_profile_status;
 
   /* Whether the dominators and the postdominators are available.  */
   enum dom_state x_dom_computed[2];

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]