[libcp1] handle anon aggregates linkage-named by typedefs

Alexandre Oliva aoliva@redhat.com
Tue Apr 11 21:13:00 GMT 2017


On Apr 10, 2017, Jeff Law <law@redhat.com> wrote:

> On 03/21/2017 05:32 PM, Alexandre Oliva wrote:
>> * libcp1plugin.cc (plugin_build_decl): Propagate typedef name to
>> anonymous aggregate target type.
> Can you put some kind of pointer in the code you copied from cp/decl.c
> so that there's some chance anyone changing that code would at least
> go look at the libcpplugin.cc copy and try to DTRT.

Well, if we're actually touching the g++ code, I'd much rather refactor
it a bit and export this chunk of code for libcc1 to use without
copying.  How's this instead?  (testing)


[libcp1] handle anon aggregates linkage-named by typedefs

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.
---
 gcc/cp/decl.c          |   75 ++++++++++++++++++++++++++++--------------------
 gcc/cp/decl.h          |    1 +
 libcc1/libcp1plugin.cc |    9 ++++++
 3 files changed, 54 insertions(+), 31 deletions(-)

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 516b93c..b29945c 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -9831,6 +9831,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.
@@ -11555,37 +11598,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)))
diff --git a/gcc/cp/decl.h b/gcc/cp/decl.h
index 3e1d91f..d84d90c 100644
--- a/gcc/cp/decl.h
+++ b/gcc/cp/decl.h
@@ -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
diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc
index 545f28b9..2464aa2 100644
--- a/libcc1/libcp1plugin.cc
+++ b/libcc1/libcp1plugin.cc
@@ -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


-- 
Alexandre Oliva, freedom fighter    http://FSFLA.org/~lxoliva/
You must be the change you wish to see in the world. -- Gandhi
Be Free! -- http://FSFLA.org/   FSF Latin America board member
Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer



More information about the Gcc-patches mailing list