Commit f2ae0c45 by Jason Merrill Committed by Jason Merrill

decl.c (maybe_deduce_size_from_array_init): Set do_default for all non-extern arrays.

        * decl.c (maybe_deduce_size_from_array_init): Set do_default for
        all non-extern arrays.

        * decl.c (grokdeclarator): Complain about 'friend T' for implicit
        typenames, too.  Downgrade complaint to pedwarn.
        (xref_tag): Warn about surprising behavior of 'friend struct T'.
        * decl2.c (handle_class_head): Generate a TYPENAME_TYPE for
        'class This::Inherited'.

From-SVN: r36382
parent 634dd0ca
2000-09-12 Jason Merrill <jason@redhat.com>
* decl.c (maybe_deduce_size_from_array_init): Set do_default for
all non-extern arrays.
* decl.c (grokdeclarator): Complain about 'friend T' for implicit
typenames, too. Downgrade complaint to pedwarn.
(xref_tag): Warn about surprising behavior of 'friend struct T'.
* decl2.c (handle_class_head): Generate a TYPENAME_TYPE for
'class This::Inherited'.
2000-09-12 Mark Mitchell <mark@codesourcery.com> 2000-09-12 Mark Mitchell <mark@codesourcery.com>
* decl.c (finish_case_label): Given the LABEL_DECL a * decl.c (finish_case_label): Given the LABEL_DECL a
......
...@@ -7654,12 +7654,9 @@ maybe_deduce_size_from_array_init (decl, init) ...@@ -7654,12 +7654,9 @@ maybe_deduce_size_from_array_init (decl, init)
&& TYPE_DOMAIN (type) == NULL_TREE && TYPE_DOMAIN (type) == NULL_TREE
&& TREE_CODE (decl) != TYPE_DECL) && TREE_CODE (decl) != TYPE_DECL)
{ {
int do_default /* do_default is really a C-ism to deal with tentative definitions.
= (TREE_STATIC (decl) But let's leave it here to ease the eventual merge. */
/* Even if pedantic, an external linkage array int do_default = !DECL_EXTERNAL (decl);
may have incomplete type at first. */
? pedantic && ! DECL_EXTERNAL (decl)
: !DECL_EXTERNAL (decl));
tree initializer = init ? init : DECL_INITIAL (decl); tree initializer = init ? init : DECL_INITIAL (decl);
int failure = complete_array_type (type, initializer, do_default); int failure = complete_array_type (type, initializer, do_default);
...@@ -11381,12 +11378,23 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) ...@@ -11381,12 +11378,23 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
cp_error ("`inline' specified for friend class declaration"); cp_error ("`inline' specified for friend class declaration");
inlinep = 0; inlinep = 0;
} }
if (!current_aggr && TREE_CODE (type) != TYPENAME_TYPE)
/* Until core issue 180 is resolved, allow 'friend typename A::B'.
But don't allow implicit typenames. */
if (!current_aggr && (TREE_CODE (type) != TYPENAME_TYPE
|| IMPLICIT_TYPENAME_P (type)))
{ {
if (TREE_CODE (type) == TEMPLATE_TYPE_PARM) if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
cp_error ("template parameters cannot be friends"); cp_pedwarn ("template parameters cannot be friends");
else if (TREE_CODE (type) == TYPENAME_TYPE)
cp_pedwarn ("\
friend declaration requires class-key, i.e. `friend class %T::%T'",
constructor_name (current_class_type),
TYPE_IDENTIFIER (type));
else else
cp_error ("friend declaration requires `%#T'", type); cp_pedwarn ("\
friend declaration requires class-key, i.e. `friend %#T'",
type);
} }
/* Only try to do this stuff if we didn't already give up. */ /* Only try to do this stuff if we didn't already give up. */
...@@ -12896,6 +12904,22 @@ xref_tag (code_type_node, name, globalize) ...@@ -12896,6 +12904,22 @@ xref_tag (code_type_node, name, globalize)
else else
t = IDENTIFIER_TYPE_VALUE (name); t = IDENTIFIER_TYPE_VALUE (name);
/* Warn about 'friend struct Inherited;' doing the wrong thing. */
if (t && globalize && TREE_CODE (t) == TYPENAME_TYPE)
{
static int explained;
cp_warning ("`%s %T' declares a new type at namespace scope;\n\
to refer to the inherited type, say `%s %T::%T'%s",
tag_name (tag_code), name, tag_name (tag_code),
constructor_name (current_class_type), TYPE_IDENTIFIER (t),
(!explained ? "\n\
(names from dependent base classes are not visible to unqualified name lookup)"
: ""));
explained = 1;
}
if (t && TREE_CODE (t) != code && TREE_CODE (t) != TEMPLATE_TYPE_PARM if (t && TREE_CODE (t) != code && TREE_CODE (t) != TEMPLATE_TYPE_PARM
&& TREE_CODE (t) != BOUND_TEMPLATE_TEMPLATE_PARM) && TREE_CODE (t) != BOUND_TEMPLATE_TEMPLATE_PARM)
t = NULL_TREE; t = NULL_TREE;
......
...@@ -5437,7 +5437,7 @@ tree ...@@ -5437,7 +5437,7 @@ tree
handle_class_head (aggr, scope, id) handle_class_head (aggr, scope, id)
tree aggr, scope, id; tree aggr, scope, id;
{ {
tree decl; tree decl = NULL_TREE;
if (TREE_CODE (id) == TYPE_DECL) if (TREE_CODE (id) == TYPE_DECL)
/* We must bash typedefs back to the main decl of the type. Otherwise /* We must bash typedefs back to the main decl of the type. Otherwise
...@@ -5447,7 +5447,7 @@ handle_class_head (aggr, scope, id) ...@@ -5447,7 +5447,7 @@ handle_class_head (aggr, scope, id)
decl = DECL_TEMPLATE_RESULT (id); decl = DECL_TEMPLATE_RESULT (id);
else else
{ {
tree current = current_scope(); tree current = current_scope ();
if (current == NULL_TREE) if (current == NULL_TREE)
current = current_namespace; current = current_namespace;
...@@ -5455,7 +5455,17 @@ handle_class_head (aggr, scope, id) ...@@ -5455,7 +5455,17 @@ handle_class_head (aggr, scope, id)
scope = global_namespace; scope = global_namespace;
if (scope == NULL_TREE) if (scope == NULL_TREE)
scope = global_namespace; scope = global_namespace;
if (scope == current)
if (TYPE_P (scope))
{
/* According to the suggested resolution of core issue 180,
'typename' is assumed after a class-key. */
decl = make_typename_type (scope, id, 1);
if (decl == error_mark_node)
return error_mark_node;
decl = TYPE_MAIN_DECL (decl);
}
else if (scope == current)
{ {
/* We've been given AGGR SCOPE::ID, when we're already inside SCOPE. /* We've been given AGGR SCOPE::ID, when we're already inside SCOPE.
Be nice about it. */ Be nice about it. */
...@@ -5469,7 +5479,8 @@ handle_class_head (aggr, scope, id) ...@@ -5469,7 +5479,8 @@ handle_class_head (aggr, scope, id)
cp_error ("no file-scope type named `%D'", id); cp_error ("no file-scope type named `%D'", id);
/* Inject it at the current scope. */ /* Inject it at the current scope. */
decl = TYPE_MAIN_DECL (xref_tag (aggr, id, 1)); if (!decl)
decl = TYPE_MAIN_DECL (xref_tag (aggr, id, 1));
} }
/* Enter the SCOPE. If this turns out not to be a definition, the /* Enter the SCOPE. If this turns out not to be a definition, the
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment