From 4b054b8004c01fbdc368f1adfbc35681ec63f435 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Thu, 17 Aug 2000 12:26:39 +0000 Subject: [PATCH] cp-tree.h (CPTR_AGGR_TAG): New global tree node. * 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. From-SVN: r35755 --- gcc/cp/ChangeLog | 17 +++++++++++++++++ gcc/cp/cp-tree.h | 2 ++ gcc/cp/decl.c | 7 +++++++ gcc/cp/error.c | 2 +- gcc/cp/parse.y | 22 ++++++++++++++-------- gcc/cp/pt.c | 8 ++++++-- 6 files changed, 47 insertions(+), 11 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4432554..d92ba16 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,20 @@ +2000-08-17 Nathan Sidwell + + * 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 * cvt.c (warn_ref_binding): New static function, broken out of ... diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index e4b4feb..f5a38ba 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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} diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index e84264d..e415628 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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) diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 74a798b..fb8ff38 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -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; diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index 2aba608..49785f2 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -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 (¤t_declspecs, 1); ggc_add_tree_root (&prefix_attributes, 1); - ggc_add_tree_root (¤t_aggr, 1); ggc_add_tree_root (¤t_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 == ';'; - $$ = finish_class_definition ($1.t, $6, semi, - $1.new_type_flag); + t = finish_class_definition ($1.t, $6, semi, + $1.new_type_flag); + $$ = 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; } ; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 3d0a1b3..302d962 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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; -- 2.7.4