+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.
/* 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)))
#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)
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;
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
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);
/* 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;
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'",
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
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'",
&& 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);
&& 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
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
/* 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. */
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;
}
--- /dev/null
+// 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