C++ PATCH: PR 11703, 9512, 10923

Mark Mitchell mark@codesourcery.com
Tue Aug 12 22:28:00 GMT 2003


This patch fixes several related regressions on the mainline.

The parser will now (correctly) issue an error about:

+ struct W {} (*p) (); // { dg-error "" }

and other similar constructs.  The logic to detect type definitions in
return types is now purely within the parser, where it belongs.  (As
opposed to being mixed in with pointer-to-member-function creation,
for example...)

Some gunk that was not being used in lang_type_class has been removed.

Tested on i686-pc-linux-gnu, applied on the mainline.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2003-08-12  Mark Mitchell  <mark@codesourcery.com>

	PR c++/11703
	* call.c (type_passed_as): Use TYPE_SIZE, not TYPE_PRECISION to
	determine whether or not to promote types.
	(convert_for_arg_passing): Likewise.
	* decl2.c (cp_build_parm_decl): Do not set DECL_ARG_TYPE in
	templates.
	* pt.c (tsubst_decl): Do not expect it to be set.

	PR c++/9512
	PR c++/10923
	* cp-tree.h (check_elaborated_type_specifier): Declare.
	(handle_class_head): Remove.
	(note_got_semicolon): Likewise.
	(note_list_got_semicolon): Likewise.
	(finish_class_definition): Likewise.
	* decl.c (check_elaborated_type_specifier): Make it public.
	Robustify.
	(handle_class_head): Remove.
	* parser.c (cp_parser_elaborated_type_specifier): Use
	check_elaborated_type_specifier.
	(cp_parser_class_specifier): Do not call finish_class_definition.
	(cp_parser_class_head): Or handle_class_head.  Check for
	over-qualified names.
	* semantics.c (finish_class_definition): Remove.

	* parser.c (cp_parser_check_for_definition_in_return_type): New
	function.
	(cp_parser_simple_declaration): Adjust call to
	cp_parser_init_declarator.
	(cp_parser_decl_specifier_seq): Change type of
	declares_class_or_enum parameter.
	(cp_parser_explicit_instantiation): Adjust accordingly.
	(cp_parser_type_specifier): Change type of
	declares_class_or_enum parameter.
	(cp_parser_init_declarator): Add declares_class_or_enum
	parameter.
	(cp_parser_parameter_declaration): Adjust call to
	cp_parser_decl_specifier_seq.
	(cp_parser_function_definition): Likewise.
	(cp_parser_member_declaration): Likewise.
	(cp_parser_single_declaration): Likewise.
	
	* cp-tree.h (lang_type_class): Remove has_call_overloaded,
	has_array_ref_overloaded, has_arrow_overloaded, and got_semicolon.
	(TYPE_OVERLOADS_CALL_EXPR): Remove.
	(TYPE_OVERLOADS_ARRAY_REF): Likewise.
	(TYPE_OVERLOADS_ARROW): Likewise.
	(CLASSTYPE_GOT_SEMICOLON): Likewise.
	* class.c (check_bases): Do not set them.
	(finish_struct_1): Likewise.
	* decl.c (cp_finish_decl): Do not set CLASSTYPE_GOT_SEMICOLON.
	(build_ptrmemfunc_type): Likewise.
	(grok_op_properties): Do not set TYPE_OVERLOADS_*.
	(start_function): Do not check CLASSTYPE_GOT_SEMICOLON.
	* decl2.c (grokfield): Do not set CLASSTYPE_GOT_SEMICOLON.
	* lex.c (note_got_semicolon): Remove.
	(note_list_got_semicolon): Likewise.
	* parser.c (cp_parser_simple_declaration): Do not call
	note_list_got_semicolon.
	* pt.c (list_eq): Remove.
	(lookup_template_class): Do not set CLASSTYPE_GOT_SEMICOLON.
	(instantiate_class_template): Do not set TYPE_OVERLOADS*.
	(instantiate_class_template): Do not set CLASSTYPE_GOT_SEMICOLON.
	* ptree.c (cxx_print_type): Do not print them.
	* semantics.c (finish_member_class_template): Do not call
	note_list_got_semicolon.

2003-08-12  Mark Mitchell  <mark@codesourcery.com>

	* g++.dg/parse/ret-type2.C: New test.

	PR c++/11703
	* g++.dg/init/new8.C: New test.

	PR c++/10923
	* g++.dg/parse/typedef5.C: New test.

	PR c++/9512
	* g++.dg/parse/qualified2.C: New test.
	* g++.old-deja/g++.other/decl5.C: Mark one more instance of
	invalid code.

Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.419
diff -c -5 -p -r1.419 call.c
*** cp/call.c	10 Aug 2003 14:59:56 -0000	1.419
--- cp/call.c	12 Aug 2003 22:17:56 -0000
*************** type_passed_as (tree type)
*** 4322,4332 ****
    /* Pass classes with copy ctors by invisible reference.  */
    if (TREE_ADDRESSABLE (type))
      type = build_reference_type (type);
    else if (PROMOTE_PROTOTYPES
  	   && INTEGRAL_TYPE_P (type)
! 	   && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
      type = integer_type_node;
  
    return type;
  }
  
--- 4322,4333 ----
    /* Pass classes with copy ctors by invisible reference.  */
    if (TREE_ADDRESSABLE (type))
      type = build_reference_type (type);
    else if (PROMOTE_PROTOTYPES
  	   && INTEGRAL_TYPE_P (type)
! 	   && INT_CST_LT_UNSIGNED (TYPE_SIZE (type),
! 				   TYPE_SIZE (integer_type_node)))
      type = integer_type_node;
  
    return type;
  }
  
*************** convert_for_arg_passing (tree type, tree
*** 4340,4350 ****
    /* Pass classes with copy ctors by invisible reference.  */
    else if (TREE_ADDRESSABLE (type))
      val = build1 (ADDR_EXPR, build_reference_type (type), val);
    else if (PROMOTE_PROTOTYPES
  	   && INTEGRAL_TYPE_P (type)
! 	   && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
      val = perform_integral_promotions (val);
    return val;
  }
  
  /* Subroutine of the various build_*_call functions.  Overload resolution
--- 4341,4352 ----
    /* Pass classes with copy ctors by invisible reference.  */
    else if (TREE_ADDRESSABLE (type))
      val = build1 (ADDR_EXPR, build_reference_type (type), val);
    else if (PROMOTE_PROTOTYPES
  	   && INTEGRAL_TYPE_P (type)
! 	   && INT_CST_LT_UNSIGNED (TYPE_SIZE (type),
! 				   TYPE_SIZE (integer_type_node)))
      val = perform_integral_promotions (val);
    return val;
  }
  
  /* Subroutine of the various build_*_call functions.  Overload resolution
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.562
diff -c -5 -p -r1.562 class.c
*** cp/class.c	2 Aug 2003 18:52:14 -0000	1.562
--- cp/class.c	12 Aug 2003 22:18:00 -0000
*************** check_bases (tree t,
*** 1282,1294 ****
        TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) 
  	|= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (basetype);
        TYPE_HAS_COMPLEX_ASSIGN_REF (t) 
  	|= TYPE_HAS_COMPLEX_ASSIGN_REF (basetype);
        TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_HAS_COMPLEX_INIT_REF (basetype);
-       TYPE_OVERLOADS_CALL_EXPR (t) |= TYPE_OVERLOADS_CALL_EXPR (basetype);
-       TYPE_OVERLOADS_ARRAY_REF (t) |= TYPE_OVERLOADS_ARRAY_REF (basetype);
-       TYPE_OVERLOADS_ARROW (t) |= TYPE_OVERLOADS_ARROW (basetype);
        TYPE_POLYMORPHIC_P (t) |= TYPE_POLYMORPHIC_P (basetype);
        CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) 
  	|= CLASSTYPE_CONTAINS_EMPTY_CLASS_P (basetype);
      }
  }
--- 1282,1291 ----
*************** finish_struct_1 (tree t)
*** 4975,4985 ****
      }
  
    /* If this type was previously laid out as a forward reference,
       make sure we lay it out again.  */
    TYPE_SIZE (t) = NULL_TREE;
-   CLASSTYPE_GOT_SEMICOLON (t) = 0;
    CLASSTYPE_PRIMARY_BINFO (t) = NULL_TREE;
  
    fixup_inline_methods (t);
    
    /* Make assumptions about the class; we'll reset the flags if
--- 4972,4981 ----
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.900
diff -c -5 -p -r1.900 cp-tree.h
*** cp/cp-tree.h	11 Aug 2003 02:49:42 -0000	1.900
--- cp/cp-tree.h	12 Aug 2003 22:18:02 -0000
*************** struct lang_type_class GTY(())
*** 1069,1118 ****
    unsigned has_assign_ref : 1;
    unsigned has_new : 1;
    unsigned has_array_new : 1;
  
    unsigned gets_delete : 2;
-   unsigned has_call_overloaded : 1;
-   unsigned has_array_ref_overloaded : 1;
-   unsigned has_arrow_overloaded : 1;
    unsigned interface_only : 1;
    unsigned interface_unknown : 1;
    unsigned contains_empty_class_p : 1;
  
    unsigned marks: 6;
    unsigned vec_new_uses_cookie : 1;
    unsigned declared_class : 1;
  
    unsigned being_defined : 1;
    unsigned redefined : 1;
    unsigned debug_requested : 1;
    unsigned use_template : 2;
!   unsigned got_semicolon : 1;
    unsigned ptrmemfunc_flag : 1;
    unsigned was_anonymous : 1;
  
    unsigned has_real_assign_ref : 1;
    unsigned has_const_init_ref : 1;
    unsigned has_complex_init_ref : 1;
    unsigned has_complex_assign_ref : 1;
    unsigned has_abstract_assign_ref : 1;
    unsigned non_aggregate : 1;
    unsigned java_interface : 1;
-   unsigned anon_aggr : 1;
- 
-   unsigned non_zero_init : 1;
-   unsigned empty_p : 1;
-   unsigned fields_readonly : 1;
  
    /* When adding a flag here, consider whether or not it ought to
       apply to a template instance if it applies to the template.  If
       so, make sure to copy it in instantiate_class_template!  */
  
    /* There are some bits left to fill out a 32-bit word.  Keep track
       of this by updating the size of this bitfield whenever you add or
       remove a flag.  */
!   unsigned dummy : 5;
  
    tree primary_base;
    tree vfields;
    tree vcall_indices;
    tree vtables;
--- 1069,1113 ----
    unsigned has_assign_ref : 1;
    unsigned has_new : 1;
    unsigned has_array_new : 1;
  
    unsigned gets_delete : 2;
    unsigned interface_only : 1;
    unsigned interface_unknown : 1;
    unsigned contains_empty_class_p : 1;
+   unsigned anon_aggr : 1;
+   unsigned non_zero_init : 1;
+   unsigned empty_p : 1;
  
    unsigned marks: 6;
    unsigned vec_new_uses_cookie : 1;
    unsigned declared_class : 1;
  
    unsigned being_defined : 1;
    unsigned redefined : 1;
    unsigned debug_requested : 1;
    unsigned use_template : 2;
!   unsigned fields_readonly : 1;
    unsigned ptrmemfunc_flag : 1;
    unsigned was_anonymous : 1;
  
    unsigned has_real_assign_ref : 1;
    unsigned has_const_init_ref : 1;
    unsigned has_complex_init_ref : 1;
    unsigned has_complex_assign_ref : 1;
    unsigned has_abstract_assign_ref : 1;
    unsigned non_aggregate : 1;
    unsigned java_interface : 1;
  
    /* When adding a flag here, consider whether or not it ought to
       apply to a template instance if it applies to the template.  If
       so, make sure to copy it in instantiate_class_template!  */
  
    /* There are some bits left to fill out a 32-bit word.  Keep track
       of this by updating the size of this bitfield whenever you add or
       remove a flag.  */
!   unsigned dummy : 9;
  
    tree primary_base;
    tree vfields;
    tree vcall_indices;
    tree vtables;
*************** struct lang_type GTY(())
*** 1219,1240 ****
  #define TYPE_BEING_DEFINED(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->being_defined)
  /* Nonzero means that this type has been redefined.  In this case, if
     convenient, don't reprocess any methods that appear in its redefinition.  */
  #define TYPE_REDEFINED(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->redefined)
  
- /* Nonzero means that this _CLASSTYPE node overloads operator().  */
- #define TYPE_OVERLOADS_CALL_EXPR(NODE) \
-   (LANG_TYPE_CLASS_CHECK (NODE)->has_call_overloaded)
- 
- /* Nonzero means that this _CLASSTYPE node overloads operator[].  */
- #define TYPE_OVERLOADS_ARRAY_REF(NODE) \
-   (LANG_TYPE_CLASS_CHECK (NODE)->has_array_ref_overloaded)
- 
- /* Nonzero means that this _CLASSTYPE node overloads operator->.  */
- #define TYPE_OVERLOADS_ARROW(NODE) \
-   (LANG_TYPE_CLASS_CHECK (NODE)->has_arrow_overloaded)
- 
  /* Nonzero means that this _CLASSTYPE (or one of its ancestors) uses
     multiple inheritance.  If this is 0 for the root of a type
     hierarchy, then we can use more efficient search techniques.  */
  #define TYPE_USES_MULTIPLE_INHERITANCE(NODE) \
    (LANG_TYPE_CLASS_CHECK (NODE)->h.uses_multiple_inheritance)
--- 1214,1223 ----
*************** struct lang_type GTY(())
*** 1380,1392 ****
  /* A cons list of virtual functions which cannot be inherited by
     derived classes.  When deriving from this type, the derived
     class must provide its own definition for each of these functions.  */
  #define CLASSTYPE_PURE_VIRTUALS(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->pure_virtuals)
  
- /* Nonzero means that this aggr type has been `closed' by a semicolon.  */
- #define CLASSTYPE_GOT_SEMICOLON(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->got_semicolon)
- 
  /* Nonzero means that this type has an X() constructor.  */
  #define TYPE_HAS_DEFAULT_CONSTRUCTOR(NODE) \
    (LANG_TYPE_CLASS_CHECK (NODE)->h.has_default_ctor)
  
  /* Nonzero means that this type contains a mutable member */
--- 1363,1372 ----
*************** extern int local_variable_p             
*** 3761,3770 ****
--- 3741,3751 ----
  extern int nonstatic_local_decl_p               (tree);
  extern tree declare_global_var                  (tree, tree);
  extern void register_dtor_fn                    (tree);
  extern tmpl_spec_kind current_tmpl_spec_kind    (int);
  extern tree cp_fname_init			(const char *);
+ extern tree check_elaborated_type_specifier     (enum tag_types, tree, bool);
  extern bool have_extern_spec;
  
  /* in decl2.c */
  extern bool check_java_method (tree);
  extern int grok_method_quals (tree, tree, tree);
*************** extern void do_toplevel_using_decl (tree
*** 3806,3816 ****
  extern void do_local_using_decl (tree);
  extern tree do_class_using_decl (tree);
  extern void do_using_directive (tree);
  extern void check_default_args (tree);
  extern void mark_used (tree);
- extern tree handle_class_head (enum tag_types, tree, tree, tree);
  extern tree lookup_arg_dependent (tree, tree, tree);
  extern void finish_static_data_member_decl (tree, tree, tree, int);
  extern tree cp_build_parm_decl (tree, tree);
  extern tree build_artificial_parm (tree, tree);
  extern tree get_guard (tree);
--- 3787,3796 ----
*************** extern void set_quals_and_spec			(tree, 
*** 3894,3905 ****
  extern void print_parse_statistics		(void);
  extern void do_pending_inlines			(void);
  extern void yyungetc				(int, int);
  extern void snarf_method			(tree);
  
- extern void note_got_semicolon			(tree);
- extern void note_list_got_semicolon		(tree);
  extern void see_typename			(void);
  extern tree unqualified_name_lookup_error       (tree);
  extern tree unqualified_fn_lookup_error         (tree);
  extern tree build_lang_decl			(enum tree_code, tree, tree);
  extern void retrofit_lang_decl			(tree);
--- 3874,3883 ----
*************** extern int begin_function_definition    
*** 4137,4147 ****
  extern void finish_translation_unit             (void);
  extern tree finish_template_type_parm           (tree, tree);
  extern tree finish_template_template_parm       (tree, tree);
  extern tree finish_parmlist                     (tree, int);
  extern tree begin_class_definition              (tree);
- extern tree finish_class_definition             (tree, tree, int, int);
  extern void finish_default_args                 (void);
  extern tree finish_member_class_template        (tree);
  extern void finish_template_decl                (tree);
  extern tree finish_template_type                (tree, tree, int);
  extern tree finish_base_specifier               (tree, tree, bool);
--- 4115,4124 ----
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1111
diff -c -5 -p -r1.1111 decl.c
*** cp/decl.c	7 Aug 2003 00:07:15 -0000	1.1111
--- cp/decl.c	12 Aug 2003 22:18:08 -0000
*************** cp_finish_decl (tree decl, tree init, tr
*** 8064,8074 ****
  	  && IS_AGGR_TYPE (type) && DECL_NAME (decl))
  	{
  	  if (TREE_TYPE (DECL_NAME (decl)) && TREE_TYPE (decl) != type)
  	    warning ("shadowing previous type declaration of `%#D'", decl);
  	  set_identifier_type_value (DECL_NAME (decl), type);
- 	  CLASSTYPE_GOT_SEMICOLON (type) = 1;
  	}
  
        /* If we have installed this as the canonical typedef for this
  	 type, and that type has not been defined yet, delay emitting
  	 the debug information for it, as we will emit it later.  */
--- 8064,8073 ----
*************** build_ptrmemfunc_type (tree type)
*** 9243,9255 ****
  
    /* Cache this pointer-to-member type so that we can find it again
       later.  */
    TYPE_SET_PTRMEMFUNC_TYPE (type, t);
  
-   /* Seems to be wanted.  */
-   CLASSTYPE_GOT_SEMICOLON (t) = 1;
- 
    return t;
  }
  
  /* Create and return a pointer to data member type.  */
  
--- 9242,9251 ----
*************** grok_op_properties (tree decl, int frien
*** 12239,12261 ****
  
    if (! friendp)
      {
        switch (operator_code)
  	{
- 	case CALL_EXPR:
- 	  TYPE_OVERLOADS_CALL_EXPR (current_class_type) = 1;
- 	  break;
- 
- 	case ARRAY_REF:
- 	  TYPE_OVERLOADS_ARRAY_REF (current_class_type) = 1;
- 	  break;
- 
- 	case COMPONENT_REF:
- 	case MEMBER_REF:
- 	  TYPE_OVERLOADS_ARROW (current_class_type) = 1;
- 	  break;
- 
  	case NEW_EXPR:
  	  TYPE_HAS_NEW_OPERATOR (current_class_type) = 1;
  	  break;
  
  	case DELETE_EXPR:
--- 12235,12244 ----
*************** tag_name (enum tag_types code)
*** 12539,12549 ****
     indicated by TAG_CODE) has found TYPE.  If the
     elaborated-type-specifier is invalid, issue a diagnostic and return
     error_mark_node; otherwise, return TYPE itself.  
     If ALLOW_TEMPLATE_P is true, TYPE may be a class template.  */
  
! static tree
  check_elaborated_type_specifier (enum tag_types tag_code,
  				 tree type,
  				 bool allow_template_p)
  {
    tree t = follow_tag_typedef (type);
--- 12522,12532 ----
     indicated by TAG_CODE) has found TYPE.  If the
     elaborated-type-specifier is invalid, issue a diagnostic and return
     error_mark_node; otherwise, return TYPE itself.  
     If ALLOW_TEMPLATE_P is true, TYPE may be a class template.  */
  
! tree
  check_elaborated_type_specifier (enum tag_types tag_code,
  				 tree type,
  				 bool allow_template_p)
  {
    tree t = follow_tag_typedef (type);
*************** check_elaborated_type_specifier (enum ta
*** 12551,12562 ****
    /* [dcl.type.elab] If the identifier resolves to a typedef-name or a
       template type-parameter, the elaborated-type-specifier is
       ill-formed.  */
    if (!t)
      {
!       error ("using typedef-name `%D' after `%s'",
! 	     TYPE_NAME (type), tag_name (tag_code));
        t = error_mark_node;
      }
    else if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
      {
        error ("using template type parameter `%T' after `%s'",
--- 12534,12545 ----
    /* [dcl.type.elab] If the identifier resolves to a typedef-name or a
       template type-parameter, the elaborated-type-specifier is
       ill-formed.  */
    if (!t)
      {
!       error ("using typedef-name `%T' after `%s'",
! 	     type, tag_name (tag_code));
        t = error_mark_node;
      }
    else if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
      {
        error ("using template type parameter `%T' after `%s'",
*************** start_function (tree declspecs, tree dec
*** 13410,13433 ****
  	maybe_apply_pragma_weak (decl1);
  
        fntype = TREE_TYPE (decl1);
  
        restype = TREE_TYPE (fntype);
-       if (CLASS_TYPE_P (restype) && !CLASSTYPE_GOT_SEMICOLON (restype))
- 	{
- 	  error ("semicolon missing after declaration of `%#T'", restype);
- 	  shadow_tag (build_tree_list (NULL_TREE, restype));
- 	  CLASSTYPE_GOT_SEMICOLON (restype) = 1;
- 	  if (TREE_CODE (fntype) == FUNCTION_TYPE)
- 	    fntype = build_function_type (integer_type_node,
- 					  TYPE_ARG_TYPES (fntype));
- 	  else
- 	    fntype = build_cplus_method_type (build_type_variant (TYPE_METHOD_BASETYPE (fntype), TREE_READONLY (decl1), TREE_SIDE_EFFECTS (decl1)),
- 					      integer_type_node,
- 					      TYPE_ARG_TYPES (fntype));
- 	  TREE_TYPE (decl1) = fntype;
- 	}
  
        if (TREE_CODE (fntype) == METHOD_TYPE)
  	ctype = TYPE_METHOD_BASETYPE (fntype);
        else if (DECL_MAIN_P (decl1))
  	{
--- 13393,13402 ----
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.658
diff -c -5 -p -r1.658 decl2.c
*** cp/decl2.c	10 Aug 2003 15:10:34 -0000	1.658
--- cp/decl2.c	12 Aug 2003 22:18:10 -0000
*************** grok_x_components (tree specs)
*** 221,231 ****
  
  tree
  cp_build_parm_decl (tree name, tree type)
  {
    tree parm = build_decl (PARM_DECL, name, type);
!   DECL_ARG_TYPE (parm) = type_passed_as (type);
    return parm;
  }
  
  /* Returns a PARM_DECL for a parameter of the indicated TYPE, with the
     indicated NAME.  */
--- 221,234 ----
  
  tree
  cp_build_parm_decl (tree name, tree type)
  {
    tree parm = build_decl (PARM_DECL, name, type);
!   /* DECL_ARG_TYPE is only used by the back end and the back end never
!      sees templates.  */
!   if (!processing_template_decl)
!     DECL_ARG_TYPE (parm) = type_passed_as (type);
    return parm;
  }
  
  /* Returns a PARM_DECL for a parameter of the indicated TYPE, with the
     indicated NAME.  */
*************** grokfield (tree declarator, tree declspe
*** 916,928 ****
    if (TREE_CODE (value) == TYPE_DECL)
      {
        DECL_NONLOCAL (value) = 1;
        DECL_CONTEXT (value) = current_class_type;
  
-       if (CLASS_TYPE_P (TREE_TYPE (value)))
-         CLASSTYPE_GOT_SEMICOLON (TREE_TYPE (value)) = 1;
-       
        if (processing_template_decl)
  	value = push_template_decl (value);
  
        return value;
      }
--- 919,928 ----
*************** mark_used (tree decl)
*** 4211,4308 ****
  		  information.  */
  	       || cp_function_chain->can_throw);
  
        instantiate_decl (decl, defer);
      }
- }
- 
- /* Called when a class-head is encountered.  TAG_KIND is the class-key
-    for the class.  SCOPE, if non-NULL, is the type or namespace
-    indicated in the nested-name-specifier for the declaration of the
-    class.  ID is the name of the class, if any; it may be a TYPE_DECL,
-    or an IDENTIFIER_NODE.  ATTRIBUTES are attributes that apply to the
-    class.
- 
-    Return a TYPE_DECL for the class being defined.  */
- 
- tree
- handle_class_head (enum tag_types tag_kind, tree scope, tree id,
-                    tree attributes)
- {
-   tree decl = NULL_TREE;
-   tree current = current_scope ();
-   bool xrefd_p = false;
-   bool new_type_p;
-   tree context;
- 
-   if (current == NULL_TREE)
-     current = current_namespace;
- 
-   if (scope)
-     {
-       if (TREE_CODE (id) == TYPE_DECL)
- 	/* We must bash typedefs back to the main decl of the
-        	   type. Otherwise we become confused about scopes.  */
- 	decl = TYPE_MAIN_DECL (TREE_TYPE (id));
-       else if (DECL_CLASS_TEMPLATE_P (id))
- 	decl = DECL_TEMPLATE_RESULT (id);
-       else
- 	{
- 	  if (TYPE_P (scope))
- 	    {
- 	      /* According to the suggested resolution of core issue
- 	     	 180, 'typename' is assumed after a class-key.  */
- 	      decl = make_typename_type (scope, id, tf_error);
- 	      if (decl != error_mark_node)
- 		decl = TYPE_MAIN_DECL (decl);
- 	      else
- 		decl = NULL_TREE;
- 	    }
- 	  else if (scope == current)
- 	    {
- 	      /* We've been given AGGR SCOPE::ID, when we're already
-              	 inside SCOPE.  Be nice about it.  */
- 	      if (pedantic)
- 		pedwarn ("extra qualification `%T::' on member `%D' ignored",
- 			 scope, id);
- 	    }
- 	  else
- 	    error ("`%T' does not have a class or union named `%D'",
- 		   scope, id);
- 	}
-     }
-   
-   if (!decl)
-     {
-       decl = xref_tag (tag_kind, id, attributes, false, false);
-       if (decl == error_mark_node)
- 	return error_mark_node;
-       decl = TYPE_MAIN_DECL (decl);
-       xrefd_p = true;
-     }
- 
-   if (!TYPE_BINFO (TREE_TYPE (decl)))
-     {
-       error ("`%T' is not a class or union type", decl);
-       return error_mark_node;
-     }
-   
-   /* For a definition, we want to enter the containing scope before
-      looking up any base classes etc. Only do so, if this is different
-      to the current scope.  */
-   context = CP_DECL_CONTEXT (decl);
-   
-   new_type_p = (current != context
- 		&& TREE_CODE (context) != TEMPLATE_TYPE_PARM
- 		&& TREE_CODE (context) != BOUND_TEMPLATE_TEMPLATE_PARM);
-   if (new_type_p)
-     push_scope (context);
-   
-   if (!xrefd_p 
-       && PROCESSING_REAL_TEMPLATE_DECL_P ()
-       && !CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl)))
-     decl = push_template_decl (decl);
- 
-   return decl;
  }
  
  #include "gt-cp-decl2.h"
--- 4211,4218 ----
Index: cp/lex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/lex.c,v
retrieving revision 1.314
diff -c -5 -p -r1.314 lex.c
*** cp/lex.c	22 Jul 2003 17:51:05 -0000	1.314
--- cp/lex.c	12 Aug 2003 22:18:11 -0000
*************** interface_strcmp (const char* s)
*** 504,535 ****
  
    /* No matches.  */
    return 1;
  }
  
- void
- note_got_semicolon (tree type)
- {
-   if (!TYPE_P (type))
-     abort ();
-   if (CLASS_TYPE_P (type))
-     CLASSTYPE_GOT_SEMICOLON (type) = 1;
- }
- 
- void
- note_list_got_semicolon (tree declspecs)
- {
-   tree link;
- 
-   for (link = declspecs; link; link = TREE_CHAIN (link))
-     {
-       tree type = TREE_VALUE (link);
-       if (type && TYPE_P (type))
- 	note_got_semicolon (type);
-     }
-   clear_anon_tags ();
- }
  
  
  /* Parse a #pragma whose sole argument is a string constant.
     If OPT is true, the argument is optional.  */
  static tree
--- 504,513 ----
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.99
diff -c -5 -p -r1.99 parser.c
*** cp/parser.c	10 Aug 2003 15:10:34 -0000	1.99
--- cp/parser.c	12 Aug 2003 22:18:16 -0000
*************** static void cp_parser_declaration
*** 1403,1419 ****
  static void cp_parser_block_declaration
    (cp_parser *, bool);
  static void cp_parser_simple_declaration
    (cp_parser *, bool);
  static tree cp_parser_decl_specifier_seq 
!   (cp_parser *, cp_parser_flags, tree *, bool *);
  static tree cp_parser_storage_class_specifier_opt
    (cp_parser *);
  static tree cp_parser_function_specifier_opt
    (cp_parser *);
  static tree cp_parser_type_specifier
!   (cp_parser *, cp_parser_flags, bool, bool, bool *, bool *);
  static tree cp_parser_simple_type_specifier
    (cp_parser *, cp_parser_flags);
  static tree cp_parser_type_name
    (cp_parser *);
  static tree cp_parser_elaborated_type_specifier
--- 1403,1419 ----
  static void cp_parser_block_declaration
    (cp_parser *, bool);
  static void cp_parser_simple_declaration
    (cp_parser *, bool);
  static tree cp_parser_decl_specifier_seq 
!   (cp_parser *, cp_parser_flags, tree *, int *);
  static tree cp_parser_storage_class_specifier_opt
    (cp_parser *);
  static tree cp_parser_function_specifier_opt
    (cp_parser *);
  static tree cp_parser_type_specifier
!   (cp_parser *, cp_parser_flags, bool, bool, int *, bool *);
  static tree cp_parser_simple_type_specifier
    (cp_parser *, cp_parser_flags);
  static tree cp_parser_type_name
    (cp_parser *);
  static tree cp_parser_elaborated_type_specifier
*************** static void cp_parser_linkage_specificat
*** 1444,1454 ****
    (cp_parser *);
  
  /* Declarators [gram.dcl.decl] */
  
  static tree cp_parser_init_declarator
!   (cp_parser *, tree, tree, bool, bool, bool *);
  static tree cp_parser_declarator
    (cp_parser *, cp_parser_declarator_kind, int *);
  static tree cp_parser_direct_declarator
    (cp_parser *, cp_parser_declarator_kind, int *);
  static enum tree_code cp_parser_ptr_operator
--- 1444,1454 ----
    (cp_parser *);
  
  /* Declarators [gram.dcl.decl] */
  
  static tree cp_parser_init_declarator
!   (cp_parser *, tree, tree, bool, bool, int, bool *);
  static tree cp_parser_declarator
    (cp_parser *, cp_parser_declarator_kind, int *);
  static tree cp_parser_direct_declarator
    (cp_parser *, cp_parser_declarator_kind, int *);
  static enum tree_code cp_parser_ptr_operator
*************** static void cp_parser_error
*** 1672,1681 ****
--- 1672,1683 ----
    (cp_parser *, const char *);
  static bool cp_parser_simulate_error
    (cp_parser *);
  static void cp_parser_check_type_definition
    (cp_parser *);
+ static void cp_parser_check_for_definition_in_return_type
+   (tree, int);
  static tree cp_parser_non_constant_expression
    (const char *);
  static bool cp_parser_diagnose_invalid_type_name
    (cp_parser *);
  static int cp_parser_skip_to_closing_parenthesis
*************** cp_parser_check_type_definition (cp_pars
*** 1761,1770 ****
--- 1763,1794 ----
      /* Use `%s' to print the string in case there are any escape
         characters in the message.  */
      error ("%s", parser->type_definition_forbidden_message);
  }
  
+ /* This function is called when a declaration is parsed.  If
+    DECLARATOR is a function declarator and DECLARES_CLASS_OR_ENUM
+    indicates that a type was defined in the decl-specifiers for DECL,
+    then an error is issued.  */
+ 
+ static void
+ cp_parser_check_for_definition_in_return_type (tree declarator, 
+ 					       int declares_class_or_enum)
+ {
+   /* [dcl.fct] forbids type definitions in return types.
+      Unfortunately, it's not easy to know whether or not we are
+      processing a return type until after the fact.  */
+   while (declarator
+ 	 && (TREE_CODE (declarator) == INDIRECT_REF
+ 	     || TREE_CODE (declarator) == ADDR_EXPR))
+     declarator = TREE_OPERAND (declarator, 0);
+   if (declarator
+       && TREE_CODE (declarator) == CALL_EXPR 
+       && declares_class_or_enum & 2)
+     error ("new types may not be defined in a return type");
+ }
+ 
  /* Issue an eror message about the fact that THING appeared in a
     constant-expression.  Returns ERROR_MARK_NODE.  */
  
  static tree
  cp_parser_non_constant_expression (const char *thing)
*************** static void
*** 6039,6049 ****
  cp_parser_simple_declaration (cp_parser* parser, 
                                bool function_definition_allowed_p)
  {
    tree decl_specifiers;
    tree attributes;
!   bool declares_class_or_enum;
    bool saw_declarator;
  
    /* Defer access checks until we know what is being declared; the
       checks for names appearing in the decl-specifier-seq should be
       done as if we were in the scope of the thing being declared.  */
--- 6063,6073 ----
  cp_parser_simple_declaration (cp_parser* parser, 
                                bool function_definition_allowed_p)
  {
    tree decl_specifiers;
    tree attributes;
!   int declares_class_or_enum;
    bool saw_declarator;
  
    /* Defer access checks until we know what is being declared; the
       checks for names appearing in the decl-specifier-seq should be
       done as if we were in the scope of the thing being declared.  */
*************** cp_parser_simple_declaration (cp_parser*
*** 6098,6114 ****
    while (cp_lexer_next_token_is_not (parser->lexer, 
  				     CPP_SEMICOLON))
      {
        cp_token *token;
        bool function_definition_p;
  
        saw_declarator = true;
        /* Parse the init-declarator.  */
!       cp_parser_init_declarator (parser, decl_specifiers, attributes,
! 				 function_definition_allowed_p,
! 				 /*member_p=*/false,
! 				 &function_definition_p);
        /* If an error occurred while parsing tentatively, exit quickly.
  	 (That usually happens when in the body of a function; each
  	 statement is treated as a declaration-statement until proven
  	 otherwise.)  */
        if (cp_parser_error_occurred (parser))
--- 6122,6140 ----
    while (cp_lexer_next_token_is_not (parser->lexer, 
  				     CPP_SEMICOLON))
      {
        cp_token *token;
        bool function_definition_p;
+       tree decl;
  
        saw_declarator = true;
        /* Parse the init-declarator.  */
!       decl = cp_parser_init_declarator (parser, decl_specifiers, attributes,
! 					function_definition_allowed_p,
! 					/*member_p=*/false,
! 					declares_class_or_enum,
! 					&function_definition_p);
        /* If an error occurred while parsing tentatively, exit quickly.
  	 (That usually happens when in the body of a function; each
  	 statement is treated as a declaration-statement until proven
  	 otherwise.)  */
        if (cp_parser_error_occurred (parser))
*************** cp_parser_simple_declaration (cp_parser*
*** 6168,6181 ****
      }
  
    /* Consume the `;'.  */
    cp_parser_require (parser, CPP_SEMICOLON, "`;'");
  
-   /* Mark all the classes that appeared in the decl-specifier-seq as
-      having received a `;'.  */
-   note_list_got_semicolon (decl_specifiers);
- 
   done:
    pop_deferring_access_checks ();
  }
  
  /* Parse a decl-specifier-seq.
--- 6194,6203 ----
*************** cp_parser_simple_declaration (cp_parser*
*** 6206,6229 ****
  
     If FRIEND_IS_NOT_CLASS_P is non-NULL, and the `friend' specifier
     appears, and the entity that will be a friend is not going to be a
     class, then *FRIEND_IS_NOT_CLASS_P will be set to TRUE.  Note that
     even if *FRIEND_IS_NOT_CLASS_P is FALSE, the entity to which
!    friendship is granted might not be a class.  */
  
  static tree
  cp_parser_decl_specifier_seq (cp_parser* parser, 
                                cp_parser_flags flags, 
                                tree* attributes,
! 			      bool* declares_class_or_enum)
  {
    tree decl_specs = NULL_TREE;
    bool friend_p = false;
    bool constructor_possible_p = !parser->in_declarator_p;
    
    /* Assume no class or enumeration type is declared.  */
!   *declares_class_or_enum = false;
  
    /* Assume there are no attributes.  */
    *attributes = NULL_TREE;
  
    /* Keep reading specifiers until there are no more to read.  */
--- 6228,6260 ----
  
     If FRIEND_IS_NOT_CLASS_P is non-NULL, and the `friend' specifier
     appears, and the entity that will be a friend is not going to be a
     class, then *FRIEND_IS_NOT_CLASS_P will be set to TRUE.  Note that
     even if *FRIEND_IS_NOT_CLASS_P is FALSE, the entity to which
!    friendship is granted might not be a class.  
! 
!    *DECLARES_CLASS_OR_ENUM is set to the bitwise or of the following
!    *flags:
! 
!      1: one of the decl-specifiers is an elaborated-type-specifier
!      2: one of the decl-specifiers is an enum-specifier or a
!         class-specifier
! 
!    */
  
  static tree
  cp_parser_decl_specifier_seq (cp_parser* parser, 
                                cp_parser_flags flags, 
                                tree* attributes,
! 			      int* declares_class_or_enum)
  {
    tree decl_specs = NULL_TREE;
    bool friend_p = false;
    bool constructor_possible_p = !parser->in_declarator_p;
    
    /* Assume no class or enumeration type is declared.  */
!   *declares_class_or_enum = 0;
  
    /* Assume there are no attributes.  */
    *attributes = NULL_TREE;
  
    /* Keep reading specifiers until there are no more to read.  */
*************** cp_parser_decl_specifier_seq (cp_parser*
*** 6315,6325 ****
  
        /* If we don't have a DECL_SPEC yet, then we must be looking at
  	 a type-specifier.  */
        if (!decl_spec && !constructor_p)
  	{
! 	  bool decl_spec_declares_class_or_enum;
  	  bool is_cv_qualifier;
  
  	  decl_spec
  	    = cp_parser_type_specifier (parser, flags,
  					friend_p,
--- 6346,6356 ----
  
        /* If we don't have a DECL_SPEC yet, then we must be looking at
  	 a type-specifier.  */
        if (!decl_spec && !constructor_p)
  	{
! 	  int decl_spec_declares_class_or_enum;
  	  bool is_cv_qualifier;
  
  	  decl_spec
  	    = cp_parser_type_specifier (parser, flags,
  					friend_p,
*************** cp_parser_template_argument (cp_parser* 
*** 7911,7921 ****
         decl-specifier-seq [opt] declarator [opt] ;  */
  
  static void
  cp_parser_explicit_instantiation (cp_parser* parser)
  {
!   bool declares_class_or_enum;
    tree decl_specifiers;
    tree attributes;
    tree extension_specifier = NULL_TREE;
  
    /* Look for an (optional) storage-class-specifier or
--- 7942,7952 ----
         decl-specifier-seq [opt] declarator [opt] ;  */
  
  static void
  cp_parser_explicit_instantiation (cp_parser* parser)
  {
!   int declares_class_or_enum;
    tree decl_specifiers;
    tree attributes;
    tree extension_specifier = NULL_TREE;
  
    /* Look for an (optional) storage-class-specifier or
*************** cp_parser_explicit_instantiation (cp_par
*** 7963,7972 ****
--- 7994,8005 ----
  
        /* Parse the declarator.  */
        declarator 
  	= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
  				/*ctor_dtor_or_conv_p=*/NULL);
+       cp_parser_check_for_definition_in_return_type (declarator, 
+ 						     declares_class_or_enum);
        decl = grokdeclarator (declarator, decl_specifiers, 
  			     NORMAL, 0, NULL);
        /* Turn access control back on for names used during
  	 template instantiation.  */
        pop_deferring_access_checks ();
*************** cp_parser_explicit_specialization (cp_pa
*** 8053,8075 ****
     `friend'.  If IS_DECLARATION is TRUE, then this type-specifier is
     appearing in a decl-specifier-seq.
  
     If DECLARES_CLASS_OR_ENUM is non-NULL, and the type-specifier is a
     class-specifier, enum-specifier, or elaborated-type-specifier, then
!    *DECLARES_CLASS_OR_ENUM is set to TRUE.  Otherwise, it is set to
!    FALSE.
  
     If IS_CV_QUALIFIER is non-NULL, and the type-specifier is a
     cv-qualifier, then IS_CV_QUALIFIER is set to TRUE.  Otherwise, it
     is set to FALSE.  */
  
  static tree
  cp_parser_type_specifier (cp_parser* parser, 
  			  cp_parser_flags flags, 
  			  bool is_friend,
  			  bool is_declaration,
! 			  bool* declares_class_or_enum,
  			  bool* is_cv_qualifier)
  {
    tree type_spec = NULL_TREE;
    cp_token *token;
    enum rid keyword;
--- 8086,8109 ----
     `friend'.  If IS_DECLARATION is TRUE, then this type-specifier is
     appearing in a decl-specifier-seq.
  
     If DECLARES_CLASS_OR_ENUM is non-NULL, and the type-specifier is a
     class-specifier, enum-specifier, or elaborated-type-specifier, then
!    *DECLARES_CLASS_OR_ENUM is set to a non-zero value.  The value is 1
!    if a type is declared; 2 if it is defined.  Otherwise, it is set to
!    zero.
  
     If IS_CV_QUALIFIER is non-NULL, and the type-specifier is a
     cv-qualifier, then IS_CV_QUALIFIER is set to TRUE.  Otherwise, it
     is set to FALSE.  */
  
  static tree
  cp_parser_type_specifier (cp_parser* parser, 
  			  cp_parser_flags flags, 
  			  bool is_friend,
  			  bool is_declaration,
! 			  int* declares_class_or_enum,
  			  bool* is_cv_qualifier)
  {
    tree type_spec = NULL_TREE;
    cp_token *token;
    enum rid keyword;
*************** cp_parser_type_specifier (cp_parser* par
*** 8105,8115 ****
  
        /* If that worked, we're done.  */
        if (cp_parser_parse_definitely (parser))
  	{
  	  if (declares_class_or_enum)
! 	    *declares_class_or_enum = true;
  	  return type_spec;
  	}
  
        /* Fall through.  */
  
--- 8139,8149 ----
  
        /* If that worked, we're done.  */
        if (cp_parser_parse_definitely (parser))
  	{
  	  if (declares_class_or_enum)
! 	    *declares_class_or_enum = 2;
  	  return type_spec;
  	}
  
        /* Fall through.  */
  
*************** cp_parser_type_specifier (cp_parser* par
*** 8119,8129 ****
  						       is_friend,
  						       is_declaration);
        /* We're declaring a class or enum -- unless we're using
  	 `typename'.  */
        if (declares_class_or_enum && keyword != RID_TYPENAME)
! 	*declares_class_or_enum = true;
        return type_spec;
  
      case RID_CONST:
      case RID_VOLATILE:
      case RID_RESTRICT:
--- 8153,8163 ----
  						       is_friend,
  						       is_declaration);
        /* We're declaring a class or enum -- unless we're using
  	 `typename'.  */
        if (declares_class_or_enum && keyword != RID_TYPENAME)
! 	*declares_class_or_enum = 1;
        return type_spec;
  
      case RID_CONST:
      case RID_VOLATILE:
      case RID_RESTRICT:
*************** cp_parser_elaborated_type_specifier (cp_
*** 8510,8526 ****
  	  if (TREE_CODE (decl) != TYPE_DECL)
  	    {
  	      error ("expected type-name");
  	      return error_mark_node;
  	    }
! 	  else if (TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE
! 		   && tag_type != enum_type)
! 	    error ("`%T' referred to as `%s'", TREE_TYPE (decl),
! 		   tag_type == record_type ? "struct" : "class");
! 	  else if (TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE
! 		   && tag_type == enum_type)
! 	    error ("`%T' referred to as enum", TREE_TYPE (decl));
  
  	  type = TREE_TYPE (decl);
  	}
        else 
  	{
--- 8544,8560 ----
  	  if (TREE_CODE (decl) != TYPE_DECL)
  	    {
  	      error ("expected type-name");
  	      return error_mark_node;
  	    }
! 
! 	  if (TREE_CODE (TREE_TYPE (decl)) != TYPENAME_TYPE)
! 	    check_elaborated_type_specifier 
! 	      (tag_type, 
! 	       TREE_TYPE (decl),
! 	       (parser->num_template_parameter_lists
! 		|| DECL_SELF_REFERENCE_P (decl)));
  
  	  type = TREE_TYPE (decl);
  	}
        else 
  	{
*************** static tree
*** 9159,9168 ****
--- 9193,9203 ----
  cp_parser_init_declarator (cp_parser* parser, 
  			   tree decl_specifiers, 
  			   tree prefix_attributes,
  			   bool function_definition_allowed_p,
  			   bool member_p,
+ 			   int declares_class_or_enum,
  			   bool* function_definition_p)
  {
    cp_token *token;
    tree declarator;
    tree attributes;
*************** cp_parser_init_declarator (cp_parser* pa
*** 9196,9205 ****
--- 9231,9243 ----
    /* If the DECLARATOR was erroneous, there's no need to go
       further.  */
    if (declarator == error_mark_node)
      return error_mark_node;
  
+   cp_parser_check_for_definition_in_return_type (declarator,
+ 						 declares_class_or_enum);
+ 
    /* Figure out what scope the entity declared by the DECLARATOR is
       located in.  `grokdeclarator' sometimes changes the scope, so
       we compute it now.  */
    scope = get_scope_of_declarator (declarator);
  
*************** cp_parser_parameter_declaration_list (cp
*** 10324,10334 ****
  
  static tree
  cp_parser_parameter_declaration (cp_parser *parser, 
  				 bool template_parm_p)
  {
!   bool declares_class_or_enum;
    bool greater_than_is_operator_p;
    tree decl_specifiers;
    tree attributes;
    tree declarator;
    tree default_argument;
--- 10362,10372 ----
  
  static tree
  cp_parser_parameter_declaration (cp_parser *parser, 
  				 bool template_parm_p)
  {
!   int declares_class_or_enum;
    bool greater_than_is_operator_p;
    tree decl_specifiers;
    tree attributes;
    tree declarator;
    tree default_argument;
*************** cp_parser_function_definition (cp_parser
*** 10559,10569 ****
    tree decl_specifiers;
    tree attributes;
    tree declarator;
    tree fn;
    cp_token *token;
!   bool declares_class_or_enum;
    bool member_p;
    /* The saved value of the PEDANTIC flag.  */
    int saved_pedantic;
  
    /* Any pending qualification must be cleared by our caller.  It is
--- 10597,10607 ----
    tree decl_specifiers;
    tree attributes;
    tree declarator;
    tree fn;
    cp_token *token;
!   int declares_class_or_enum;
    bool member_p;
    /* The saved value of the PEDANTIC flag.  */
    int saved_pedantic;
  
    /* Any pending qualification must be cleared by our caller.  It is
*************** cp_parser_function_definition (cp_parser
*** 10633,10642 ****
--- 10671,10683 ----
  
        pop_deferring_access_checks ();
        return error_mark_node;
      }
  
+   cp_parser_check_for_definition_in_return_type (declarator,
+ 						 declares_class_or_enum);
+ 
    /* If we are in a class scope, then we must handle
       function-definitions specially.  In particular, we save away the
       tokens that make up the function body, and parse them again
       later, in order to handle code like:
  
*************** cp_parser_class_specifier (cp_parser* pa
*** 11124,11138 ****
    token = cp_lexer_peek_token (parser->lexer);
    has_trailing_semicolon = (token->type == CPP_SEMICOLON);
    /* Look for attributes to apply to this class.  */
    if (cp_parser_allow_gnu_extensions_p (parser))
      attributes = cp_parser_attributes_opt (parser);
!   /* Finish the class definition.  */
!   type = finish_class_definition (type, 
! 				  attributes,
! 				  has_trailing_semicolon,
! 				  nested_name_specifier_p);
    /* If this class is not itself within the scope of another class,
       then we need to parse the bodies of all of the queued function
       definitions.  Note that the queued functions defined in a class
       are not always processed immediately following the
       class-specifier for that class.  Consider:
--- 11165,11184 ----
    token = cp_lexer_peek_token (parser->lexer);
    has_trailing_semicolon = (token->type == CPP_SEMICOLON);
    /* Look for attributes to apply to this class.  */
    if (cp_parser_allow_gnu_extensions_p (parser))
      attributes = cp_parser_attributes_opt (parser);
!   /* If we got any attributes in class_head, xref_tag will stick them in
!      TREE_TYPE of the type.  Grab them now.  */
!   if (type != error_mark_node)
!     {
!       attributes = chainon (TYPE_ATTRIBUTES (type), attributes);
!       TYPE_ATTRIBUTES (type) = NULL_TREE;
!       type = finish_struct (type, attributes);
!     }
!   if (nested_name_specifier_p)
!     pop_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (type)));
    /* If this class is not itself within the scope of another class,
       then we need to parse the bodies of all of the queued function
       definitions.  Note that the queued functions defined in a class
       are not always processed immediately following the
       class-specifier for that class.  Consider:
*************** cp_parser_class_head (cp_parser* parser,
*** 11442,11466 ****
  	{
  	  error ("declaration of `%D' in `%D' which does not "
  		 "enclose `%D'", type, scope, nested_name_specifier);
  	  return NULL_TREE;
  	}
  
        maybe_process_partial_specialization (TREE_TYPE (type));
        class_type = current_class_type;
!       type = TREE_TYPE (handle_class_head (class_key, 
! 					   nested_name_specifier,
! 					   type,
! 					   attributes));
!       if (type != error_mark_node)
! 	{
! 	  if (!class_type && TYPE_CONTEXT (type))
! 	    *nested_name_specifier_p = true;
! 	  else if (class_type && !same_type_p (TYPE_CONTEXT (type),
! 					       class_type))
! 	    *nested_name_specifier_p = true;
! 	}
      }
    /* Indicate whether this class was declared as a `class' or as a
       `struct'.  */
    if (TREE_CODE (type) == RECORD_TYPE)
      CLASSTYPE_DECLARED_CLASS (type) = (class_key == class_type);
--- 11488,11522 ----
  	{
  	  error ("declaration of `%D' in `%D' which does not "
  		 "enclose `%D'", type, scope, nested_name_specifier);
  	  return NULL_TREE;
  	}
+       /* [dcl.meaning]
+ 
+          A declarator-id shall not be qualified exception of the
+ 	 definition of a ... nested class outside of its class
+ 	 ... [or] a the definition or explicit instantiation of a
+ 	 class member of a namespace outside of its namespace.  */
+       if (scope == CP_DECL_CONTEXT (type))
+ 	{
+ 	  pedwarn ("extra qualification ignored");
+ 	  nested_name_specifier = NULL_TREE;
+ 	}
  
        maybe_process_partial_specialization (TREE_TYPE (type));
        class_type = current_class_type;
!       /* Enter the scope indicated by the nested-name-specifier.  */
!       if (nested_name_specifier)
! 	push_scope (nested_name_specifier);
!       /* Get the canonical version of this type.  */
!       type = TYPE_MAIN_DECL (TREE_TYPE (type));
!       if (PROCESSING_REAL_TEMPLATE_DECL_P ()
! 	  && !CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (type)))
! 	type = push_template_decl (type);
!       type = TREE_TYPE (type);
!       if (nested_name_specifier)
! 	*nested_name_specifier_p = true;
      }
    /* Indicate whether this class was declared as a `class' or as a
       `struct'.  */
    if (TREE_CODE (type) == RECORD_TYPE)
      CLASSTYPE_DECLARED_CLASS (type) = (class_key == class_type);
*************** static void
*** 11597,11607 ****
  cp_parser_member_declaration (cp_parser* parser)
  {
    tree decl_specifiers;
    tree prefix_attributes;
    tree decl;
!   bool declares_class_or_enum;
    bool friend_p;
    cp_token *token;
    int saved_pedantic;
  
    /* Check for the `__extension__' keyword.  */
--- 11653,11663 ----
  cp_parser_member_declaration (cp_parser* parser)
  {
    tree decl_specifiers;
    tree prefix_attributes;
    tree decl;
!   int declares_class_or_enum;
    bool friend_p;
    cp_token *token;
    int saved_pedantic;
  
    /* Check for the `__extension__' keyword.  */
*************** cp_parser_member_declaration (cp_parser*
*** 11810,11819 ****
--- 11866,11878 ----
  		  /* Skip to the end of the statement.  */
  		  cp_parser_skip_to_end_of_statement (parser);
  		  break;
  		}
  
+ 	      cp_parser_check_for_definition_in_return_type 
+ 		(declarator, declares_class_or_enum);
+ 
  	      /* Look for an asm-specification.  */
  	      asm_specification = cp_parser_asm_specification_opt (parser);
  	      /* Look for attributes that apply to the declaration.  */
  	      attributes = cp_parser_attributes_opt (parser);
  	      /* Remember which attributes are prefix attributes and
*************** cp_parser_template_declaration_after_exp
*** 13541,13551 ****
  static tree
  cp_parser_single_declaration (cp_parser* parser, 
  			      bool member_p,
  			      bool* friend_p)
  {
!   bool declares_class_or_enum;
    tree decl = NULL_TREE;
    tree decl_specifiers;
    tree attributes;
  
    /* Parse the dependent declaration.  We don't know yet
--- 13600,13610 ----
  static tree
  cp_parser_single_declaration (cp_parser* parser, 
  			      bool member_p,
  			      bool* friend_p)
  {
!   int declares_class_or_enum;
    tree decl = NULL_TREE;
    tree decl_specifiers;
    tree attributes;
  
    /* Parse the dependent declaration.  We don't know yet
*************** cp_parser_single_declaration (cp_parser*
*** 13590,13599 ****
--- 13649,13659 ----
      decl = cp_parser_init_declarator (parser, 
  				      decl_specifiers,
  				      attributes,
  				      /*function_definition_allowed_p=*/false,
  				      member_p,
+ 				      declares_class_or_enum,
  				      /*function_definition_p=*/NULL);
  
    pop_deferring_access_checks ();
  
    /* Clear any current qualification; whatever comes next is the start
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.754
diff -c -5 -p -r1.754 pt.c
*** cp/pt.c	10 Aug 2003 15:10:34 -0000	1.754
--- cp/pt.c	12 Aug 2003 22:18:21 -0000
*************** static int unify (tree, tree, tree, tree
*** 98,108 ****
  static void add_pending_template (tree);
  static void reopen_tinst_level (tree);
  static tree classtype_mangled_name (tree);
  static char* mangle_class_name_for_template (const char *, tree, tree);
  static tree tsubst_initializer_list (tree, tree);
- static int list_eq (tree, tree);
  static tree get_class_bindings (tree, tree, tree);
  static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t, int);
  static void tsubst_enum	(tree, tree, tree);
  static tree add_to_template_args (tree, tree);
  static tree add_outermost_template_args (tree, tree);
--- 98,107 ----
*************** lookup_template_class (tree d1, 
*** 4225,4235 ****
        else
  	{
  	  t = make_aggr_type (TREE_CODE (template_type));
  	  CLASSTYPE_DECLARED_CLASS (t) 
  	    = CLASSTYPE_DECLARED_CLASS (template_type);
- 	  CLASSTYPE_GOT_SEMICOLON (t) = 1;
  	  SET_CLASSTYPE_IMPLICIT_INSTANTIATION (t);
  	  TYPE_FOR_JAVA (t) = TYPE_FOR_JAVA (template_type);
  
  	  /* A local class.  Make sure the decl gets registered properly.  */
  	  if (context == current_function_decl)
--- 4224,4233 ----
*************** instantiate_class_template (tree type)
*** 5139,5151 ****
        SET_CLASSTYPE_INTERFACE_UNKNOWN (type);
      }
  
    TYPE_HAS_CONSTRUCTOR (type) = TYPE_HAS_CONSTRUCTOR (pattern);
    TYPE_HAS_DESTRUCTOR (type) = TYPE_HAS_DESTRUCTOR (pattern);
-   TYPE_OVERLOADS_CALL_EXPR (type) = TYPE_OVERLOADS_CALL_EXPR (pattern);
-   TYPE_OVERLOADS_ARRAY_REF (type) = TYPE_OVERLOADS_ARRAY_REF (pattern);
-   TYPE_OVERLOADS_ARROW (type) = TYPE_OVERLOADS_ARROW (pattern);
    TYPE_HAS_NEW_OPERATOR (type) = TYPE_HAS_NEW_OPERATOR (pattern);
    TYPE_HAS_ARRAY_NEW_OPERATOR (type) = TYPE_HAS_ARRAY_NEW_OPERATOR (pattern);
    TYPE_GETS_DELETE (type) = TYPE_GETS_DELETE (pattern);
    TYPE_HAS_ASSIGN_REF (type) = TYPE_HAS_ASSIGN_REF (pattern);
    TYPE_HAS_CONST_ASSIGN_REF (type) = TYPE_HAS_CONST_ASSIGN_REF (pattern);
--- 5137,5146 ----
*************** instantiate_class_template (tree type)
*** 5383,5393 ****
    typedecl = TYPE_MAIN_DECL (type);
    input_location = DECL_SOURCE_LOCATION (typedecl);
    
    unreverse_member_declarations (type);
    finish_struct_1 (type);
-   CLASSTYPE_GOT_SEMICOLON (type) = 1;
  
    /* Clear this now so repo_template_used is happy.  */
    TYPE_BEING_DEFINED (type) = 0;
    repo_template_used (type);
  
--- 5378,5387 ----
*************** instantiate_class_template (tree type)
*** 5412,5436 ****
      keyed_classes = tree_cons (NULL_TREE, type, keyed_classes);
  
    return type;
  }
  
- static int
- list_eq (tree t1, tree t2)
- {
-   if (t1 == NULL_TREE)
-     return t2 == NULL_TREE;
-   if (t2 == NULL_TREE)
-     return 0;
-   /* Don't care if one declares its arg const and the other doesn't -- the
-      main variant of the arg type is all that matters.  */
-   if (TYPE_MAIN_VARIANT (TREE_VALUE (t1))
-       != TYPE_MAIN_VARIANT (TREE_VALUE (t2)))
-     return 0;
-   return list_eq (TREE_CHAIN (t1), TREE_CHAIN (t2));
- }
- 
  static tree
  tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl)
  {
    tree r;
    
--- 5406,5415 ----
*************** tsubst_decl (tree t, tree args, tree typ
*** 6018,6032 ****
  	  SET_DECL_TEMPLATE_PARM_P (r);
  
  	TREE_TYPE (r) = type;
  	c_apply_type_quals_to_decl (cp_type_quals (type), r);
  
! 	if (TREE_CODE (DECL_INITIAL (r)) != TEMPLATE_PARM_INDEX)
! 	  DECL_INITIAL (r) = TREE_TYPE (r);
! 	else
! 	  DECL_INITIAL (r) = tsubst (DECL_INITIAL (r), args,
! 				     complain, in_decl);
  
  	DECL_CONTEXT (r) = NULL_TREE;
  
  	if (!DECL_TEMPLATE_PARM_P (r))
  	  DECL_ARG_TYPE (r) = type_passed_as (type);
--- 5997,6014 ----
  	  SET_DECL_TEMPLATE_PARM_P (r);
  
  	TREE_TYPE (r) = type;
  	c_apply_type_quals_to_decl (cp_type_quals (type), r);
  
! 	if (DECL_INITIAL (r))
! 	  {
! 	    if (TREE_CODE (DECL_INITIAL (r)) != TEMPLATE_PARM_INDEX)
! 	      DECL_INITIAL (r) = TREE_TYPE (r);
! 	    else
! 	      DECL_INITIAL (r) = tsubst (DECL_INITIAL (r), args,
! 					 complain, in_decl);
! 	  }
  
  	DECL_CONTEXT (r) = NULL_TREE;
  
  	if (!DECL_TEMPLATE_PARM_P (r))
  	  DECL_ARG_TYPE (r) = type_passed_as (type);
Index: cp/ptree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/ptree.c,v
retrieving revision 1.36
diff -c -5 -p -r1.36 ptree.c
*** cp/ptree.c	8 Jul 2003 00:35:52 -0000	1.36
--- cp/ptree.c	12 Aug 2003 22:18:21 -0000
*************** cxx_print_type (FILE *file, tree node, i
*** 121,136 ****
      fputs (" delete", file);
    if (TYPE_GETS_DELETE (node) & 2)
      fputs (" delete[]", file);
    if (TYPE_HAS_ASSIGN_REF (node))
      fputs (" this=(X&)", file);
-   if (TYPE_OVERLOADS_CALL_EXPR (node))
-     fputs (" op()", file);
-   if (TYPE_OVERLOADS_ARRAY_REF (node))
-     fputs (" op[]", file);
-   if (TYPE_OVERLOADS_ARROW (node))
-     fputs (" op->", file);
    if (TYPE_USES_MULTIPLE_INHERITANCE (node))
      fputs (" uses-multiple-inheritance", file);
  
    if (TREE_CODE (node) == RECORD_TYPE)
      {
--- 121,130 ----
Index: cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.344
diff -c -5 -p -r1.344 semantics.c
*** cp/semantics.c	2 Aug 2003 18:52:15 -0000	1.344
--- cp/semantics.c	12 Aug 2003 22:18:22 -0000
*************** finish_member_declaration (tree decl)
*** 2131,2175 ****
        maybe_add_class_template_decl_list (current_class_type, decl, 
  					  /*friend_p=*/0);
      }
  }
  
- /* Finish a class definition T with the indicate ATTRIBUTES.  If SEMI,
-    the definition is immediately followed by a semicolon.  Returns the
-    type.  */
- 
- tree
- finish_class_definition (tree t, tree attributes, int semi, int pop_scope_p)
- {
-   if (t == error_mark_node)
-     return error_mark_node;
- 
-   /* finish_struct nukes this anyway; if finish_exception does too,
-      then it can go.  */
-   if (semi)
-     note_got_semicolon (t);
- 
-   /* If we got any attributes in class_head, xref_tag will stick them in
-      TREE_TYPE of the type.  Grab them now.  */
-   attributes = chainon (TYPE_ATTRIBUTES (t), attributes);
-   TYPE_ATTRIBUTES (t) = NULL_TREE;
- 
-   if (TREE_CODE (t) == ENUMERAL_TYPE)
-     ;
-   else
-     {
-       t = finish_struct (t, attributes);
-       if (semi) 
- 	note_got_semicolon (t);
-     }
- 
-   if (pop_scope_p)
-     pop_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (t)));
- 
-   return t;
- }
- 
  /* Finish processing the declaration of a member class template
     TYPES whose template parameters are given by PARMS.  */
  
  tree
  finish_member_class_template (tree types)
--- 2131,2140 ----
*************** finish_member_class_template (tree types
*** 2181,2191 ****
       maybe_process_partial_specialization, so we do that here.  */
    for (t = types; t != NULL_TREE; t = TREE_CHAIN (t))
      if (IS_AGGR_TYPE_CODE (TREE_CODE (TREE_VALUE (t))))
        maybe_process_partial_specialization (TREE_VALUE (t));
  
-   note_list_got_semicolon (types);
    grok_x_components (types);
    if (TYPE_CONTEXT (TREE_VALUE (types)) != current_class_type)
      /* The component was in fact a friend declaration.  We avoid
         finish_member_template_decl performing certain checks by
         unsetting TYPES.  */
--- 2146,2155 ----
Index: testsuite/g++.dg/init/new8.C
===================================================================
RCS file: testsuite/g++.dg/init/new8.C
diff -N testsuite/g++.dg/init/new8.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/init/new8.C	12 Aug 2003 22:18:29 -0000
***************
*** 0 ****
--- 1,17 ----
+ typedef unsigned int size_t;
+ 
+ enum Refcount_Type {
+   NO_REFCOUNT
+ };
+ 
+ struct d0_Unknown_Object
+ {
+   void* operator new (size_t, size_t,  Refcount_Type type);
+   void operator delete (void*, size_t, Refcount_Type);
+   d0_Unknown_Object ();
+ };
+ 
+ void make ()
+ {
+   new (10, NO_REFCOUNT) d0_Unknown_Object;
+ }
Index: testsuite/g++.dg/parse/qualified2.C
===================================================================
RCS file: testsuite/g++.dg/parse/qualified2.C
diff -N testsuite/g++.dg/parse/qualified2.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/parse/qualified2.C	12 Aug 2003 22:18:29 -0000
***************
*** 0 ****
--- 1,4 ----
+ namespace Glib {
+   template <typename> class Value {};
+   template <>         class Glib::Value<int> {}; // { dg-error "" }
+ }
Index: testsuite/g++.dg/parse/typedef5.C
===================================================================
RCS file: testsuite/g++.dg/parse/typedef5.C
diff -N testsuite/g++.dg/parse/typedef5.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/parse/typedef5.C	12 Aug 2003 22:18:29 -0000
***************
*** 0 ****
--- 1,6 ----
+ namespace A
+ {
+   typedef int T;
+ }
+ 
+ class A::T x; // { dg-error "" }
Index: testsuite/g++.old-deja/g++.other/decl5.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.old-deja/g++.other/decl5.C,v
retrieving revision 1.7
diff -c -5 -p -r1.7 decl5.C
*** testsuite/g++.old-deja/g++.other/decl5.C	1 May 2003 02:02:49 -0000	1.7
--- testsuite/g++.old-deja/g++.other/decl5.C	12 Aug 2003 22:18:30 -0000
***************
*** 9,19 ****
  
  struct A {
    int A::fn();        // { dg-warning "" } extra qualification
    int A::m;           // { dg-warning "" } extra qualification
    struct e;
!   struct A::e {int i;};
    struct A::expand {  // { dg-warning "" } extra qualification
    int m;
    };
    struct Z;
    expand me;
--- 9,19 ----
  
  struct A {
    int A::fn();        // { dg-warning "" } extra qualification
    int A::m;           // { dg-warning "" } extra qualification
    struct e;
!   struct A::e {int i;}; // { dg-warning "" } extra qualification
    struct A::expand {  // { dg-warning "" } extra qualification
    int m;
    };
    struct Z;
    expand me;
Index: testsuite/g++.dg/parse/ret-type2.C
===================================================================
RCS file: testsuite/g++.dg/parse/ret-type2.C
diff -N testsuite/g++.dg/parse/ret-type2.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/parse/ret-type2.C	12 Aug 2003 22:18:56 -0000
***************
*** 0 ****
--- 1,5 ----
+ struct S {} f(); // { dg-error "" }
+ struct T {} *g(); // { dg-error "" }
+ struct U {} h() {} // { dg-error "" }
+ struct V {} *i() {} // { dg-error "" }
+ struct W {} (*p) (); // { dg-error "" }



More information about the Gcc-patches mailing list