[libcp1] handle anon aggregates linkage-named by typedefs
authorAlexandre Oliva <aoliva@redhat.com>
Sat, 15 Apr 2017 03:28:31 +0000 (03:28 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Sat, 15 Apr 2017 03:28:31 +0000 (03:28 +0000)
Arrange for the first typedef to an anonymous type in the same context
to be used as the linkage name for the type.

for  gcc/cp/ChangeLog

* decl.c (name_unnamed_type): Split out of...
(grokdeclarator): ... this.
* decl.h (name_unnamed_type): Declare.

for  libcc1/ChangeLog

* libcp1plugin.cc (plugin_build_decl): Call name_unnamed_type.

From-SVN: r246938

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/decl.h
libcc1/ChangeLog
libcc1/libcp1plugin.cc

index 9997825e8057db33325cf09199a5d65181ec5c47..0aa6351c06b57fd3586910a4786db5fb694a239f 100644 (file)
@@ -1,3 +1,9 @@
+2017-04-15  Alexandre Oliva <aoliva@redhat.com>
+
+       * decl.c (name_unnamed_type): Split out of...
+       (grokdeclarator): ... this.
+       * decl.h (name_unnamed_type): Declare.
+
 2017-04-12  Richard Biener  <rguenther@suse.de>
        Bernd Edlinger  <bernd.edlinger@hotmail.de>
 
index 438a4ec1c510b7e94b52a1eb022c3a79c69382e1..8e9a466afa0630d0e455c97bcab1ab5d51655e95 100644 (file)
@@ -9852,6 +9852,49 @@ mark_inline_variable (tree decl)
     }
 }
 
+
+/* Assign a typedef-given name to a class or enumeration type declared
+   as anonymous at first.  This was split out of grokdeclarator
+   because it is also used in libcc1.  */
+
+void
+name_unnamed_type (tree type, tree decl)
+{
+  gcc_assert (TYPE_UNNAMED_P (type));
+
+  /* Replace the anonymous name with the real name everywhere.  */
+  for (tree t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+    {
+      if (anon_aggrname_p (TYPE_IDENTIFIER (t)))
+       /* We do not rename the debug info representing the
+          unnamed tagged type because the standard says in
+          [dcl.typedef] that the naming applies only for
+          linkage purposes.  */
+       /*debug_hooks->set_name (t, decl);*/
+       TYPE_NAME (t) = decl;
+    }
+
+  if (TYPE_LANG_SPECIFIC (type))
+    TYPE_WAS_UNNAMED (type) = 1;
+
+  /* If this is a typedef within a template class, the nested
+     type is a (non-primary) template.  The name for the
+     template needs updating as well.  */
+  if (TYPE_LANG_SPECIFIC (type) && CLASSTYPE_TEMPLATE_INFO (type))
+    DECL_NAME (CLASSTYPE_TI_TEMPLATE (type))
+      = TYPE_IDENTIFIER (type);
+
+  /* Adjust linkage now that we aren't unnamed anymore.  */
+  reset_type_linkage (type);
+
+  /* FIXME remangle member functions; member functions of a
+     type with external linkage have external linkage.  */
+
+  /* Check that our job is done, and that it would fail if we
+     attempted to do it again.  */
+  gcc_assert (!TYPE_UNNAMED_P (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.
@@ -11576,37 +11619,7 @@ grokdeclarator (const cp_declarator *declarator,
          && declspecs->type_definition_p
          && attributes_naming_typedef_ok (*attrlist)
          && cp_type_quals (type) == TYPE_UNQUALIFIED)
-       {
-         tree t;
-
-         /* Replace the anonymous name with the real name everywhere.  */
-         for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
-           {
-             if (anon_aggrname_p (TYPE_IDENTIFIER (t)))
-               /* We do not rename the debug info representing the
-                  unnamed tagged type because the standard says in
-                  [dcl.typedef] that the naming applies only for
-                  linkage purposes.  */
-               /*debug_hooks->set_name (t, decl);*/
-               TYPE_NAME (t) = decl;
-           }
-
-         if (TYPE_LANG_SPECIFIC (type))
-           TYPE_WAS_UNNAMED (type) = 1;
-
-         /* If this is a typedef within a template class, the nested
-            type is a (non-primary) template.  The name for the
-            template needs updating as well.  */
-         if (TYPE_LANG_SPECIFIC (type) && CLASSTYPE_TEMPLATE_INFO (type))
-           DECL_NAME (CLASSTYPE_TI_TEMPLATE (type))
-             = TYPE_IDENTIFIER (type);
-
-         /* Adjust linkage now that we aren't unnamed anymore.  */
-         reset_type_linkage (type);
-
-         /* FIXME remangle member functions; member functions of a
-            type with external linkage have external linkage.  */
-       }
+       name_unnamed_type (type, decl);
 
       if (signed_p
          || (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl)))
index 3e1d91f70921ada4e7b9d80adeb8a29e6c269c6c..d84d90c82d2369d016dc0bd7ae4d9cbb29308dc0 100644 (file)
@@ -35,6 +35,7 @@ enum decl_context
 extern tree grokdeclarator (const cp_declarator *,
                            cp_decl_specifier_seq *,
                            enum decl_context, int, tree*);
+extern void name_unnamed_type (tree, tree);
 
 /* States indicating how grokdeclarator() should handle declspecs marked
    with __attribute__((deprecated)).  An object declared as
index 5db05c58ba720d54d4896d4d3bf7a0553e70844a..a6b9985e4ab56a30571ed0696c8a9b71672cd3ad 100644 (file)
@@ -1,3 +1,7 @@
+2017-04-15  Alexandre Oliva <aoliva@redhat.com>
+
+       * libcp1plugin.cc (plugin_build_decl): Call name_unnamed_type.
+
 2017-01-30  Alexandre Oliva <aoliva@redhat.com>
 
        Introduce C++ support.
index 545f28b98617ebd84c666312e525b2d7b3afdfe6..2464aa2f39d4fc8c6e406c19770f7cb0eb48e62e 100644 (file)
@@ -1494,6 +1494,15 @@ plugin_build_decl (cc1_plugin::connection *self,
 
   set_access_flags (decl, acc_flags);
 
+  /* If this is the typedef that names an otherwise anonymous type,
+     propagate the typedef name to the type.  In normal compilation,
+     this is done in grokdeclarator.  */
+  if (sym_kind == GCC_CP_SYMBOL_TYPEDEF
+      && !template_decl_p
+      && DECL_CONTEXT (decl) == TYPE_CONTEXT (sym_type)
+      && TYPE_UNNAMED_P (sym_type))
+    name_unnamed_type (sym_type, decl);
+
   if (sym_kind != GCC_CP_SYMBOL_TYPEDEF
       && sym_kind != GCC_CP_SYMBOL_CLASS
       && sym_kind != GCC_CP_SYMBOL_UNION