commit 28beb0d493a46f126f23d15216d4ae9279223514
Author: Jason Merrill <jason@redhat.com>
Date: Fri Jan 4 10:50:46 2013 -0500
PR c++/55877
* decl.c (reset_type_linkage, bt_reset_linkage): New.
(grokdeclarator): Use reset_type_linkage.
* name-lookup.c (binding_table_foreach): Handle null table.
* tree.c (decl_anon_ns_mem_p): Check TYPE_MAIN_DECL, not TYPE_NAME.
@@ -8513,6 +8513,23 @@ check_var_type (tree identifier, tree type)
return type;
}
+/* Functions for adjusting the visibility of a tagged type and its nested
+ types when it gets a name for linkage purposes from a typedef. */
+
+static void bt_reset_linkage (binding_entry, void *);
+static void
+reset_type_linkage (tree type)
+{
+ set_linkage_according_to_type (type, TYPE_MAIN_DECL (type));
+ if (CLASS_TYPE_P (type))
+ binding_table_foreach (CLASSTYPE_NESTED_UTDS (type), bt_reset_linkage, NULL);
+}
+static void
+bt_reset_linkage (binding_entry b, void */*data*/)
+{
+ reset_type_linkage (b->type);
+}
+
/* Given declspecs and a declarator (abstract or otherwise), determine
the name and type of the object declared and construct a DECL node
for it.
@@ -10053,8 +10070,7 @@ grokdeclarator (const cp_declarator *declarator,
= TYPE_IDENTIFIER (type);
/* Adjust linkage now that we aren't anonymous anymore. */
- set_linkage_according_to_type (type, TYPE_MAIN_DECL (type));
- determine_visibility (TYPE_MAIN_DECL (type));
+ reset_type_linkage (type);
/* FIXME remangle member functions; member functions of a
type with external linkage have external linkage. */
@@ -251,9 +251,13 @@ binding_table_find (binding_table table, tree name)
void
binding_table_foreach (binding_table table, bt_foreach_proc proc, void *data)
{
- const size_t chain_count = table->chain_count;
+ size_t chain_count;
size_t i;
+ if (!table)
+ return;
+
+ chain_count = table->chain_count;
for (i = 0; i < chain_count; ++i)
{
binding_entry entry = table->chain[i];
@@ -2404,7 +2404,7 @@ decl_anon_ns_mem_p (const_tree decl)
/* Classes and namespaces inside anonymous namespaces have
TREE_PUBLIC == 0, so we can shortcut the search. */
else if (TYPE_P (decl))
- return (TREE_PUBLIC (TYPE_NAME (decl)) == 0);
+ return (TREE_PUBLIC (TYPE_MAIN_DECL (decl)) == 0);
else if (TREE_CODE (decl) == NAMESPACE_DECL)
return (TREE_PUBLIC (decl) == 0);
else
new file mode 100644
@@ -0,0 +1,13 @@
+// PR c++/55877
+// { dg-final { scan-assembler-not "\\.local" } }
+
+typedef struct {
+ typedef enum { X, Y } A;
+ typedef struct { } B;
+ struct C { };
+} D;
+
+D d;
+D::A a;
+D::B b;
+D::C c;