OSDN Git Service

* cp-tree.h (CPTR_AGGR_TAG): New global tree node.
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 17 Aug 2000 12:26:39 +0000 (12:26 +0000)
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 17 Aug 2000 12:26:39 +0000 (12:26 +0000)
(current_aggr): Define.
* decl.c (grokdeclarator): Make sure a friend class is an
elaborated type specifier.
* parse.y (current_aggr): Remove static definition.
(cp_parse_init): Adjust.
(structsp): Clear and restore current_aggr.
(component_decl_list): Clear current_aggr.

* error.c (dump_type, case TYPENAME_TYPE): Don't emit the
aggregate tag on the typename's context.

* pt.c (tsubst_friend_class): Return NULL, if parms becomes NULL.
(instantiate_class_template): Ignore NULL friend types.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@35755 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/error.c
gcc/cp/parse.y
gcc/cp/pt.c

index 4432554..d92ba16 100644 (file)
@@ -1,3 +1,20 @@
+2000-08-17  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * cp-tree.h (CPTR_AGGR_TAG): New global tree node.
+       (current_aggr): Define.
+       * decl.c (grokdeclarator): Make sure a friend class is an
+       elaborated type specifier.
+       * parse.y (current_aggr): Remove static definition.
+       (cp_parse_init): Adjust.
+       (structsp): Clear and restore current_aggr.
+       (component_decl_list): Clear current_aggr.
+       
+       * error.c (dump_type, case TYPENAME_TYPE): Don't emit the
+       aggregate tag on the typename's context.
+       
+       * pt.c (tsubst_friend_class): Return NULL, if parms becomes NULL.
+       (instantiate_class_template): Ignore NULL friend types.
+
 2000-08-14  Nathan Sidwell  <nathan@codesourcery.com>
 
        * cvt.c (warn_ref_binding): New static function, broken out of ...
index e4b4feb..f5a38ba 100644 (file)
@@ -592,6 +592,7 @@ enum cp_tree_index
     CPTI_TINFO_VAR_ID,
     CPTI_ABORT_FNDECL,
     CPTI_GLOBAL_DELETE_FNDECL,
+    CPTI_AGGR_TAG,
 
     CPTI_ACCESS_DEFAULT,
     CPTI_ACCESS_PUBLIC,
@@ -686,6 +687,7 @@ extern tree cp_global_trees[CPTI_MAX];
 #define tinfo_var_id                    cp_global_trees[CPTI_TINFO_VAR_ID]
 #define abort_fndecl                   cp_global_trees[CPTI_ABORT_FNDECL]
 #define global_delete_fndecl           cp_global_trees[CPTI_GLOBAL_DELETE_FNDECL]
+#define current_aggr                   cp_global_trees[CPTI_AGGR_TAG]
 
 /* Define the sets of attributes that member functions and baseclasses
    can have.  These are sensible combinations of {public,private,protected}
index e84264d..e415628 100644 (file)
@@ -11220,6 +11220,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
              cp_error ("`inline' specified for friend class declaration");
              inlinep = 0;
            }
+         if (!current_aggr && TREE_CODE (type) != TYPENAME_TYPE)
+           {
+             if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
+               cp_error ("template parameters cannot be friends");
+             else
+               cp_error ("friend declaration requires `%#T'", type);
+           }
 
          /* Only try to do this stuff if we didn't already give up.  */
          if (type != integer_type_node)
index 74a798b..fb8ff38 100644 (file)
@@ -457,7 +457,7 @@ dump_type (t, flags)
     }
     case TYPENAME_TYPE:
       OB_PUTS ("typename ");
-      dump_type (TYPE_CONTEXT (t), flags);
+      dump_type (TYPE_CONTEXT (t), flags & ~TS_AGGR_TAGS);
       OB_PUTS ("::");
       dump_decl (TYPENAME_TYPE_FULLNAME (t), flags);
       break;
index 2aba608..49785f2 100644 (file)
@@ -77,10 +77,6 @@ static tree current_declspecs;
    a declspec list have been updated.  */
 static tree prefix_attributes;
 
-/* When defining an aggregate, this is the kind of the most recent one
-   being defined.  (For example, this might be class_type_node.)  */
-static tree current_aggr;
-
 /* When defining an enumeration, this is the type of the enumeration.  */
 static tree current_enum_type;
 
@@ -213,7 +209,6 @@ cp_parse_init ()
 {
   ggc_add_tree_root (&current_declspecs, 1);
   ggc_add_tree_root (&prefix_attributes, 1);
-  ggc_add_tree_root (&current_aggr, 1);
   ggc_add_tree_root (&current_enum_type, 1);
 }
 %}
@@ -2242,17 +2237,26 @@ structsp:
                    cp_pedwarn ("using `typename' outside of template"); }
        /* C++ extensions, merged with C to avoid shift/reduce conflicts */
        | class_head '{'
-                { $1.t = begin_class_definition ($1.t); }
+                { $1.t = begin_class_definition ($1.t); 
+                  current_aggr = NULL_TREE; }
           opt.component_decl_list '}' maybe_attribute
                { 
                  int semi;
+                 tree t;
 
                  if (yychar == YYEMPTY)
                    yychar = YYLEX;
                  semi = yychar == ';';
 
-                 $<ttype>$ = finish_class_definition ($1.t, $6, semi,
-                                                      $1.new_type_flag); 
+                 t = finish_class_definition ($1.t, $6, semi,
+                                              $1.new_type_flag); 
+                 $<ttype>$ = t;
+
+                 /* restore current_aggr */
+                 current_aggr = TREE_CODE (t) != RECORD_TYPE
+                                ? union_type_node
+                                : CLASSTYPE_DECLARED_CLASS (t)
+                                ? class_type_node : record_type_node;
                }
          pending_defargs
                 {
@@ -2514,10 +2518,12 @@ component_decl_list:
          component_decl
                { 
                  finish_member_declaration ($1);
+                 current_aggr = NULL_TREE;
                }
        | component_decl_list component_decl
                { 
                  finish_member_declaration ($2);
+                 current_aggr = NULL_TREE;
                }
        ;
 
index 3d0a1b3..302d962 100644 (file)
@@ -4677,7 +4677,8 @@ tsubst_friend_function (decl, args)
 /* FRIEND_TMPL is a friend TEMPLATE_DECL.  ARGS is the vector of
    template arguments, as for tsubst.
 
-   Returns an appropriate tsbust'd friend type.  */
+   Returns an appropriate tsbust'd friend type or error_mark_node on
+   failure.  */
 
 static tree
 tsubst_friend_class (friend_tmpl, args)
@@ -4718,6 +4719,8 @@ tsubst_friend_class (friend_tmpl, args)
       tree parms 
        = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_tmpl),
                                 args, /*complain=*/1);
+      if (!parms)
+        return error_mark_node;
       redeclare_class_template (TREE_TYPE (tmpl), parms);
       friend_type = TREE_TYPE (tmpl);
     }
@@ -5144,7 +5147,8 @@ instantiate_class_template (type)
           information.  */
        ++processing_template_decl;
 
-      make_friend_class (type, new_friend_type);
+      if (new_friend_type != error_mark_node)
+        make_friend_class (type, new_friend_type);
 
       if (TREE_CODE (friend_type) == TEMPLATE_DECL)
        --processing_template_decl;