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:
parent
07745bdb36
commit
4b054b8004
|
@ -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 ...
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 == ';';
|
||||
|
||||
$<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;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue