+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>
* decl.c (finish_case_label): Given the LABEL_DECL a
&& TYPE_DOMAIN (type) == NULL_TREE
&& TREE_CODE (decl) != TYPE_DECL)
{
- int do_default
- = (TREE_STATIC (decl)
- /* Even if pedantic, an external linkage array
- may have incomplete type at first. */
- ? pedantic && ! DECL_EXTERNAL (decl)
- : !DECL_EXTERNAL (decl));
+ /* do_default is really a C-ism to deal with tentative definitions.
+ But let's leave it here to ease the eventual merge. */
+ int do_default = !DECL_EXTERNAL (decl);
tree initializer = init ? init : DECL_INITIAL (decl);
int failure = complete_array_type (type, initializer, do_default);
cp_error ("`inline' specified for friend class declaration");
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)
- 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
- 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. */
else
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
&& TREE_CODE (t) != BOUND_TEMPLATE_TEMPLATE_PARM)
t = NULL_TREE;
handle_class_head (aggr, scope, id)
tree aggr, scope, id;
{
- tree decl;
+ tree decl = NULL_TREE;
if (TREE_CODE (id) == TYPE_DECL)
/* We must bash typedefs back to the main decl of the type. Otherwise
decl = DECL_TEMPLATE_RESULT (id);
else
{
- tree current = current_scope();
+ tree current = current_scope ();
if (current == NULL_TREE)
current = current_namespace;
scope = global_namespace;
if (scope == NULL_TREE)
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.
Be nice about it. */
cp_error ("no file-scope type named `%D'", id);
/* 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