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
This commit is contained in:
Nathan Sidwell 2000-08-17 12:26:39 +00:00 committed by Nathan Sidwell
parent 07745bdb36
commit 4b054b8004
6 changed files with 47 additions and 11 deletions

View 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 ...

View 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}

View 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)

View 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;

View 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;
}
;

View 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;