aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2000-08-17 12:26:39 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2000-08-17 12:26:39 +0000
commit4b054b8004c01fbdc368f1adfbc35681ec63f435 (patch)
treedc83201e24e209489973c8e23767f94b2ee9b3ac
parent07745bdb36b003562aadda9564917e0413c7b403 (diff)
downloadgcc-4b054b8004c01fbdc368f1adfbc35681ec63f435.zip
gcc-4b054b8004c01fbdc368f1adfbc35681ec63f435.tar.gz
gcc-4b054b8004c01fbdc368f1adfbc35681ec63f435.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog17
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/decl.c7
-rw-r--r--gcc/cp/error.c2
-rw-r--r--gcc/cp/parse.y22
-rw-r--r--gcc/cp/pt.c8
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 <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 ...
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 (&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;
}
;
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;