public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* C++ PATCH to implement mangling of unnamed types with linkage
@ 2009-10-03  0:49 Jason Merrill
  2011-01-23 22:49 ` H.J. Lu
  0 siblings, 1 reply; 2+ messages in thread
From: Jason Merrill @ 2009-10-03  0:49 UTC (permalink / raw)
  To: gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 418 bytes --]

DR 757 allows types without linkage to be used in decls with linkage so 
long as those decls are defined in the current translation unit.  And in 
fact some of those types really do have linkage: notably, class-scope 
unnamed types and function-local types in functions with vague linkage. 
  The C++ ABI now specifies a mangling for these, which this patch 
implements.

Tested x86_64-pc-linux-gnu, applied to trunk.

[-- Attachment #2: unnamed.patch --]
[-- Type: text/x-patch, Size: 6378 bytes --]

commit 063753f624a4a7243ceae32570f2203471dc3a82
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Oct 2 18:07:12 2009 -0400

    	* mangle.c (write_unnamed_type_name): Implement.
    	(local_class_index): Split out from...
    	(discriminator_for_local_entity): ...here.
    	(nested_anon_class_index): New.
    	* cp-tree.h (TYPE_FUNCTION_SCOPE_P): New.

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index fc00176..8a18575 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -2249,6 +2249,9 @@ struct GTY(()) lang_decl {
   (DECL_CONTEXT (NODE) \
    && TREE_CODE (DECL_CONTEXT (NODE)) == FUNCTION_DECL)
 
+#define TYPE_FUNCTION_SCOPE_P(NODE) \
+  (TYPE_CONTEXT (NODE) && TREE_CODE (TYPE_CONTEXT (NODE)) == FUNCTION_DECL)
+
 /* 1 iff VAR_DECL node NODE is a type-info decl.  This flag is set for
    both the primary typeinfo object and the associated NTBS name.  */
 #define DECL_TINFO_P(NODE) TREE_LANG_FLAG_4 (VAR_DECL_CHECK (NODE))
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 1e08465..d96a929 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -217,6 +217,7 @@ static void write_discriminator (const int);
 static void write_local_name (tree, const tree, const tree);
 static void dump_substitution_candidates (void);
 static tree mangle_decl_string (const tree);
+static int local_class_index (tree);
 
 /* Control functions.  */
 
@@ -1204,8 +1205,7 @@ write_unqualified_name (const tree decl)
       tree type = TREE_TYPE (decl);
 
       if (TREE_CODE (decl) == TYPE_DECL
-          && TYPE_ANONYMOUS_P (type)
-          && !ANON_UNION_TYPE_P (type))
+          && TYPE_ANONYMOUS_P (type))
         write_unnamed_type_name (type);
       else if (TREE_CODE (decl) == TYPE_DECL
                && LAMBDA_TYPE_P (type))
@@ -1252,14 +1252,48 @@ write_compact_number (int num)
   write_char ('_');
 }
 
+/* Return how many unnamed types precede TYPE in its enclosing class.  */
+
+static int
+nested_anon_class_index (tree type)
+{
+  int index = 0;
+  tree member = TYPE_FIELDS (TYPE_CONTEXT (type));
+  for (; member; member = TREE_CHAIN (member))
+    if (DECL_IMPLICIT_TYPEDEF_P (member))
+      {
+	tree memtype = TREE_TYPE (member);
+	if (memtype == type)
+	  return index;
+	else if (TYPE_ANONYMOUS_P (memtype))
+	  ++index;
+      }
+
+  gcc_unreachable ();
+}
+
+/* <unnamed-type-name> ::= Ut [ <nonnegative number> ] _ */
+
 static void
 write_unnamed_type_name (const tree type __attribute__ ((__unused__)))
 {
+  int discriminator;
   MANGLE_TRACE_TREE ("unnamed-type-name", type);
 
+  if (TYPE_FUNCTION_SCOPE_P (type))
+    discriminator = local_class_index (type);
+  else if (TYPE_CLASS_SCOPE_P (type))
+    discriminator = nested_anon_class_index (type);
+  else
+    {
+      gcc_assert (no_linkage_check (type, /*relaxed_p=*/true));
+      /* Just use the old mangling at namespace scope.  */
+      write_source_name (TYPE_IDENTIFIER (type));
+      return;
+    }
+
   write_string ("Ut");
-  /* TODO: Implement discriminators for unnamed-types.  */
-  write_char ('_');
+  write_compact_number (discriminator);
 }
 
 /* <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
@@ -1539,6 +1573,29 @@ write_special_name_destructor (const tree dtor)
     }
 }
 
+/* Scan the vector of local classes and return how many others with the
+   same name (or same no name) and context precede ENTITY.  */
+
+static int
+local_class_index (tree entity)
+{
+  int ix, discriminator = 0;
+  tree name = (TYPE_ANONYMOUS_P (entity) ? NULL_TREE
+	       : TYPE_IDENTIFIER (entity));
+  tree ctx = TYPE_CONTEXT (entity);
+  for (ix = 0; ; ix++)
+    {
+      tree type = VEC_index (tree, local_classes, ix);
+      if (type == entity)
+	return discriminator;
+      if (TYPE_CONTEXT (type) == ctx
+	  && (name ? TYPE_IDENTIFIER (type) == name
+	      : TYPE_ANONYMOUS_P (type)))
+	++discriminator;
+    }
+  gcc_unreachable ();
+}
+
 /* Return the discriminator for ENTITY appearing inside
    FUNCTION.  The discriminator is the lexical ordinal of VAR among
    entities with the same name in the same FUNCTION.  */
@@ -1546,15 +1603,17 @@ write_special_name_destructor (const tree dtor)
 static int
 discriminator_for_local_entity (tree entity)
 {
-  /* Assume this is the only local entity with this name.  */
-  int discriminator = 0;
-
-  if (DECL_DISCRIMINATOR_P (entity) && DECL_LANG_SPECIFIC (entity))
-    discriminator = DECL_DISCRIMINATOR (entity);
+  if (DECL_DISCRIMINATOR_P (entity))
+    {
+      if (DECL_LANG_SPECIFIC (entity))
+	return DECL_DISCRIMINATOR (entity);
+      else
+	/* The first entity with a particular name doesn't get
+	   DECL_LANG_SPECIFIC/DECL_DISCRIMINATOR.  */
+	return 0;
+    }
   else if (TREE_CODE (entity) == TYPE_DECL)
     {
-      int ix;
-
       /* Scan the list of local classes.  */
       entity = TREE_TYPE (entity);
 
@@ -1562,18 +1621,10 @@ discriminator_for_local_entity (tree entity)
       if (LAMBDA_TYPE_P (entity) || TYPE_ANONYMOUS_P (entity))
 	return 0;
 
-      for (ix = 0; ; ix++)
-	{
-	  tree type = VEC_index (tree, local_classes, ix);
-	  if (type == entity)
-	    break;
-	  if (TYPE_IDENTIFIER (type) == TYPE_IDENTIFIER (entity)
-	      && TYPE_CONTEXT (type) == TYPE_CONTEXT (entity))
-	    ++discriminator;
-	}
+      return local_class_index (entity);
     }
-
-  return discriminator;
+  else
+    gcc_unreachable ();
 }
 
 /* Return the discriminator for STRING, a string literal used inside
diff --git a/gcc/testsuite/g++.dg/abi/mangle32.C b/gcc/testsuite/g++.dg/abi/mangle32.C
new file mode 100644
index 0000000..de02887
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle32.C
@@ -0,0 +1,41 @@
+// Testcase for mangling of unnamed types.
+
+// namespace-scope unnamed types have no linkage, so we only test that they
+// are distinct.
+typedef struct { } *A;
+typedef struct { } *B;
+
+void f(A) { }
+void f(B) { }
+
+struct C
+{
+  typedef struct { }* D;
+  typedef enum { }* E;
+};
+
+// { dg-final { scan-assembler "_Z2g1PN1CUt_E" } }
+void g1(C::D) { }
+// { dg-final { scan-assembler "_Z2g2PN1CUt0_E" } }
+void g2(C::E) { }
+
+template <class T>
+void h1(T t) { }
+
+template <class T>
+void h2(T t) { }
+
+inline void j()
+{
+  typedef enum { }* F;
+// { dg-final { scan-assembler "_Z2h1IPZ1jvEUt_EvT_" } }
+  h1(F());
+  typedef struct { }* G;
+// { dg-final { scan-assembler "_Z2h2IPZ1jvEUt0_EvT_" } }
+  h2(G());
+}
+
+int main()
+{
+  j();
+}

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: C++ PATCH to implement mangling of unnamed types with linkage
  2009-10-03  0:49 C++ PATCH to implement mangling of unnamed types with linkage Jason Merrill
@ 2011-01-23 22:49 ` H.J. Lu
  0 siblings, 0 replies; 2+ messages in thread
From: H.J. Lu @ 2011-01-23 22:49 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches List

On Fri, Oct 2, 2009 at 5:49 PM, Jason Merrill <jason@redhat.com> wrote:
> DR 757 allows types without linkage to be used in decls with linkage so long
> as those decls are defined in the current translation unit.  And in fact
> some of those types really do have linkage: notably, class-scope unnamed
> types and function-local types in functions with vague linkage.  The C++ ABI
> now specifies a mangling for these, which this patch implements.
>
> Tested x86_64-pc-linux-gnu, applied to trunk.
>

This caused:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47049

-- 
H.J.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2011-01-23 16:42 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-10-03  0:49 C++ PATCH to implement mangling of unnamed types with linkage Jason Merrill
2011-01-23 22:49 ` H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).