cp-tree.h (TYPE_LINKAGE_IDENTIFIER): New macro.
* cp-tree.h (TYPE_LINKAGE_IDENTIFIER): New macro. (TYPE_ANONYMOUS_P): New macro. (TAGGED_TYPE_P): New macro. * decl.c (check_tag_decl): Use TYPE_ANONYMOUS_P. (grokfndecl, grokvardecl, grokdeclarator): Likewise. * tree.c (no_linkage_helper): Likewise. * semantics.c (begin_class_definition): Likewise. * pt.c (convert_template_argument): Likewise. * lex.c (check_for_missing_semicolon): Likewise. From-SVN: r41303
This commit is contained in:
parent
d93aa33514
commit
1951a1b6ec
|
@ -1,3 +1,15 @@
|
|||
2001-04-11 Jason Merrill <jason_merrill@redhat.com>
|
||||
|
||||
* cp-tree.h (TYPE_LINKAGE_IDENTIFIER): New macro.
|
||||
(TYPE_ANONYMOUS_P): New macro.
|
||||
(TAGGED_TYPE_P): New macro.
|
||||
* decl.c (check_tag_decl): Use TYPE_ANONYMOUS_P.
|
||||
(grokfndecl, grokvardecl, grokdeclarator): Likewise.
|
||||
* tree.c (no_linkage_helper): Likewise.
|
||||
* semantics.c (begin_class_definition): Likewise.
|
||||
* pt.c (convert_template_argument): Likewise.
|
||||
* lex.c (check_for_missing_semicolon): Likewise.
|
||||
|
||||
2001-04-12 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* class.c (dfs_unshared_virtual_bases): New function.
|
||||
|
|
|
@ -1163,12 +1163,18 @@ enum languages { lang_c, lang_cplusplus, lang_java };
|
|||
|
||||
/* Macros to make error reporting functions' lives easier. */
|
||||
#define TYPE_IDENTIFIER(NODE) (DECL_NAME (TYPE_NAME (NODE)))
|
||||
#define TYPE_LINKAGE_IDENTIFIER(NODE) \
|
||||
(TYPE_IDENTIFIER (TYPE_MAIN_VARIANT (NODE)))
|
||||
#define TYPE_NAME_STRING(NODE) (IDENTIFIER_POINTER (TYPE_IDENTIFIER (NODE)))
|
||||
#define TYPE_NAME_LENGTH(NODE) (IDENTIFIER_LENGTH (TYPE_IDENTIFIER (NODE)))
|
||||
|
||||
#define TYPE_ASSEMBLER_NAME_STRING(NODE) (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TYPE_NAME (NODE))))
|
||||
#define TYPE_ASSEMBLER_NAME_LENGTH(NODE) (IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (TYPE_NAME (NODE))))
|
||||
|
||||
/* Nonzero if NODE has no name for linkage purposes. */
|
||||
#define TYPE_ANONYMOUS_P(NODE) \
|
||||
(TAGGED_TYPE_P (NODE) && ANON_AGGRNAME_P (TYPE_LINKAGE_IDENTIFIER (NODE)))
|
||||
|
||||
/* The _DECL for this _TYPE. */
|
||||
#define TYPE_MAIN_DECL(NODE) (TYPE_STUB_DECL (TYPE_MAIN_VARIANT (NODE)))
|
||||
|
||||
|
@ -1198,8 +1204,9 @@ enum languages { lang_c, lang_cplusplus, lang_java };
|
|||
#define IS_AGGR_TYPE_2(TYPE1,TYPE2) \
|
||||
(TREE_CODE (TYPE1) == TREE_CODE (TYPE2) \
|
||||
&& IS_AGGR_TYPE (TYPE1) && IS_AGGR_TYPE (TYPE2))
|
||||
#define IS_OVERLOAD_TYPE(t) \
|
||||
(IS_AGGR_TYPE (t) || TREE_CODE (t) == ENUMERAL_TYPE)
|
||||
#define TAGGED_TYPE_P(t) \
|
||||
(CLASS_TYPE_P (t) || TREE_CODE (t) == ENUMERAL_TYPE)
|
||||
#define IS_OVERLOAD_TYPE(T) TAGGED_TYPE_P (T)
|
||||
|
||||
/* In a *_TYPE, nonzero means a built-in type. */
|
||||
#define TYPE_BUILT_IN(NODE) TYPE_LANG_FLAG_6(NODE)
|
||||
|
|
|
@ -2873,6 +2873,7 @@ pushtag (name, type, globalize)
|
|||
else
|
||||
d = pushdecl_with_scope (d, b);
|
||||
|
||||
/* FIXME what if it gets a name from typedef? */
|
||||
if (ANON_AGGRNAME_P (name))
|
||||
DECL_IGNORED_P (d) = 1;
|
||||
|
||||
|
@ -6972,12 +6973,9 @@ check_tag_decl (declspecs)
|
|||
if (t == NULL_TREE && ! saw_friend)
|
||||
pedwarn ("declaration does not declare anything");
|
||||
|
||||
/* Check for an anonymous union. We're careful
|
||||
accessing TYPE_IDENTIFIER because some built-in types, like
|
||||
pointer-to-member types, do not have TYPE_NAME. */
|
||||
/* Check for an anonymous union. */
|
||||
else if (t && IS_AGGR_TYPE_CODE (TREE_CODE (t))
|
||||
&& TYPE_NAME (t)
|
||||
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
|
||||
&& TYPE_ANONYMOUS_P (t))
|
||||
{
|
||||
/* 7/3 In a simple-declaration, the optional init-declarator-list
|
||||
can be omitted only when declaring a class (clause 9) or
|
||||
|
@ -8733,17 +8731,11 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
|
|||
int check, friendp, publicp, inlinep, funcdef_flag, template_count;
|
||||
tree in_namespace;
|
||||
{
|
||||
tree cname, decl;
|
||||
tree decl;
|
||||
int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE;
|
||||
int has_default_arg = 0;
|
||||
tree t;
|
||||
|
||||
if (ctype)
|
||||
cname = TREE_CODE (TYPE_NAME (ctype)) == TYPE_DECL
|
||||
? TYPE_IDENTIFIER (ctype) : TYPE_NAME (ctype);
|
||||
else
|
||||
cname = NULL_TREE;
|
||||
|
||||
if (raises)
|
||||
{
|
||||
type = build_exception_variant (type, raises);
|
||||
|
@ -8799,7 +8791,8 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
|
|||
|
||||
/* Members of anonymous types and local classes have no linkage; make
|
||||
them internal. */
|
||||
if (ctype && (ANON_AGGRNAME_P (TYPE_IDENTIFIER (ctype))
|
||||
/* FIXME what if it gets a name from typedef? */
|
||||
if (ctype && (TYPE_ANONYMOUS_P (ctype)
|
||||
|| decl_function_context (TYPE_MAIN_DECL (ctype))))
|
||||
publicp = 0;
|
||||
|
||||
|
@ -8813,13 +8806,19 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
|
|||
t = no_linkage_check (TREE_TYPE (decl));
|
||||
if (t)
|
||||
{
|
||||
if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
|
||||
if (TYPE_ANONYMOUS_P (t))
|
||||
{
|
||||
if (DECL_EXTERN_C_P (decl))
|
||||
/* Allow this; it's pretty common in C. */;
|
||||
else
|
||||
cp_pedwarn ("non-local function `%#D' uses anonymous type",
|
||||
decl);
|
||||
{
|
||||
cp_pedwarn ("non-local function `%#D' uses anonymous type",
|
||||
decl);
|
||||
if (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
|
||||
cp_pedwarn_at ("\
|
||||
`%#D' does not refer to the unqualified type, so it is not used for linkage",
|
||||
TYPE_NAME (t));
|
||||
}
|
||||
}
|
||||
else
|
||||
cp_pedwarn ("non-local function `%#D' uses local type `%T'",
|
||||
|
@ -8931,7 +8930,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
|
|||
if (check < 0)
|
||||
return decl;
|
||||
|
||||
if (flags == NO_SPECIAL && ctype && constructor_name (cname) == declarator)
|
||||
if (flags == NO_SPECIAL && ctype && constructor_name (ctype) == declarator)
|
||||
DECL_CONSTRUCTOR_P (decl) = 1;
|
||||
|
||||
/* Function gets the ugly name, field gets the nice one. This call
|
||||
|
@ -9095,7 +9094,7 @@ grokvardecl (type, declarator, specbits_in, initialized, constp, in_namespace)
|
|||
tree t = no_linkage_check (TREE_TYPE (decl));
|
||||
if (t)
|
||||
{
|
||||
if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
|
||||
if (TYPE_ANONYMOUS_P (t))
|
||||
/* Ignore for now; `enum { foo } e' is pretty common. */;
|
||||
else
|
||||
cp_pedwarn ("non-local variable `%#D' uses local type `%T'",
|
||||
|
@ -11037,7 +11036,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
|||
&& declarator
|
||||
&& TYPE_NAME (type)
|
||||
&& TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
|
||||
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (type))
|
||||
&& TYPE_ANONYMOUS_P (type)
|
||||
&& CP_TYPE_QUALS (type) == TYPE_UNQUALIFIED)
|
||||
{
|
||||
tree oldname = TYPE_NAME (type);
|
||||
|
|
|
@ -1011,7 +1011,7 @@ check_for_missing_semicolon (type)
|
|||
&& yychar != SELFNAME)
|
||||
|| yychar == 0 /* EOF */)
|
||||
{
|
||||
if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type)))
|
||||
if (TYPE_ANONYMOUS_P (type))
|
||||
error ("semicolon missing after %s declaration",
|
||||
TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct");
|
||||
else
|
||||
|
|
|
@ -3389,7 +3389,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
|
|||
tree t = no_linkage_check (val);
|
||||
if (t)
|
||||
{
|
||||
if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
|
||||
if (TYPE_ANONYMOUS_P (t))
|
||||
cp_pedwarn
|
||||
("template-argument `%T' uses anonymous type", val);
|
||||
else
|
||||
|
|
|
@ -1860,16 +1860,12 @@ begin_class_definition (t)
|
|||
/* Reset the interface data, at the earliest possible
|
||||
moment, as it might have been set via a class foo;
|
||||
before. */
|
||||
{
|
||||
tree name = TYPE_IDENTIFIER (t);
|
||||
|
||||
if (! ANON_AGGRNAME_P (name))
|
||||
{
|
||||
CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
|
||||
SET_CLASSTYPE_INTERFACE_UNKNOWN_X
|
||||
(t, interface_unknown);
|
||||
}
|
||||
}
|
||||
if (! TYPE_ANONYMOUS_P (t))
|
||||
{
|
||||
CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
|
||||
SET_CLASSTYPE_INTERFACE_UNKNOWN_X
|
||||
(t, interface_unknown);
|
||||
}
|
||||
reset_specialization();
|
||||
|
||||
/* Make a declaration for this class in its own scope. */
|
||||
|
|
|
@ -1502,7 +1502,7 @@ no_linkage_helper (tp, walk_subtrees, data)
|
|||
if (TYPE_P (t)
|
||||
&& (CLASS_TYPE_P (t) || TREE_CODE (t) == ENUMERAL_TYPE)
|
||||
&& (decl_function_context (TYPE_MAIN_DECL (t))
|
||||
|| ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))))
|
||||
|| TYPE_ANONYMOUS_P (t)))
|
||||
return t;
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
// Test that we properly diagnose an attempt to use an anonymous class
|
||||
// in declaring an external function.
|
||||
|
||||
typedef const struct { int i; } T; // ERROR - referenced below
|
||||
void f (T* t); // ERROR - uses unnamed type
|
Loading…
Reference in New Issue