]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/cp/mangle.c
Merge basic-improvements-branch to trunk
[thirdparty/gcc.git] / gcc / cp / mangle.c
index 523db85ab388996441d567a295281cac31395951..cf106d518cd8db0a0cb2c0577562c2b90cdd1dcb 100644 (file)
@@ -49,6 +49,8 @@
 
 #include "config.h"
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 #include "tree.h"
 #include "cp-tree.h"
 #include "real.h"
@@ -154,6 +156,7 @@ static void add_substitution PARAMS ((tree));
 static inline int is_std_substitution PARAMS ((tree, substitution_identifier_index_t));
 static inline int is_std_substitution_char PARAMS ((tree, substitution_identifier_index_t));
 static int find_substitution PARAMS ((tree));
+static void mangle_call_offset PARAMS ((tree, tree));
 
 /* Functions for emitting mangled representations of things.  */
 
@@ -2532,45 +2535,79 @@ mangle_ctor_vtbl_for_type (type, binfo)
   return get_identifier (result);
 }
 
-/* Return an identifier for the mangled name of a thunk to FN_DECL.
-   OFFSET is the initial adjustment to this used to find the vptr.  If
-   VCALL_OFFSET is non-NULL, this is a virtual thunk, and it is the
-   vtbl offset in bytes.  
+/* Mangle a this pointer or result pointer adjustment.
+   
+   <call-offset> ::= h <fixed offset number> _
+                ::= v <fixed offset number> _ <virtual offset number> _ */
+   
+static void
+mangle_call_offset (fixed_offset, virtual_offset)
+     tree fixed_offset;
+     tree virtual_offset;
+{
+  if (virtual_offset)
+    write_char (virtual_offset ? 'v' : 'h');
+  else
+    write_char ('h');
+
+  /* For either flavor, write the fixed offset.  */
+  write_integer_cst (fixed_offset);
+  write_char ('_');
+
+  /* For a virtual thunk, add the virtual offset.  */
+  if (virtual_offset)
+    {
+      write_integer_cst (virtual_offset);
+      write_char ('_');
+    }
+}
+
+/* Return an identifier for the mangled name of a this-adjusting or
+   covariant thunk to FN_DECL.  FIXED_OFFSET is the initial adjustment
+   to this used to find the vptr.  If VIRTUAL_OFFSET is non-NULL, this
+   is a virtual thunk, and it is the vtbl offset in
+   bytes. THIS_ADJUSTING is non-zero for a this adjusting thunk and
+   zero for a covariant thunk. Note, that FN_DECL might be a covariant
+   thunk itself. A covariant thunk name always includes the adjustment
+   for the this pointer, even if there is none.
 
-    <special-name> ::= Th <offset number> _ <base encoding>
-                   ::= Tv <offset number> _ <vcall offset number> _
-                                                           <base encoding>
+   <special-name> ::= T <call-offset> <base encoding>
+                  ::= Tc <this_adjust call-offset> <result_adjust call-offset>
+                                       <base encoding>
 */
 
 tree
-mangle_thunk (fn_decl, offset, vcall_offset)
+mangle_thunk (fn_decl, this_adjusting, fixed_offset, virtual_offset)
      tree fn_decl;
-     tree offset;
-     tree vcall_offset;
+     int this_adjusting;
+     tree fixed_offset;
+     tree virtual_offset;
 {
   const char *result;
   
   start_mangling (fn_decl);
 
   write_string ("_Z");
-  /* The <special-name> for virtual thunks is Tv, for non-virtual
-     thunks Th.  */
   write_char ('T');
-  if (vcall_offset != 0)
-    write_char ('v');
+  
+  if (this_adjusting && !DECL_RESULT_THUNK_P (fn_decl))
+    /* Plain this adjusting thunk.  */
+    mangle_call_offset (fixed_offset, virtual_offset);
+  else if (!this_adjusting)
+    {
+      /* Covariant thunk with no this adjustment */
+      write_char ('c');
+      mangle_call_offset (integer_zero_node, NULL_TREE);
+      mangle_call_offset (fixed_offset, virtual_offset);
+    }
   else
-    write_char ('h');
-
-  /* For either flavor, write the offset to this.  */
-  write_integer_cst (offset);
-  write_char ('_');
-
-  /* For a virtual thunk, add the vcall offset.  */
-  if (vcall_offset)
     {
-      /* Virtual thunk.  Write the vcall offset and base type name.  */
-      write_integer_cst (vcall_offset);
-      write_char ('_');
+      /* This adjusting thunk to covariant thunk.  */
+      write_char ('c');
+      mangle_call_offset (fixed_offset, virtual_offset);
+      mangle_call_offset (ssize_int (THUNK_FIXED_OFFSET (fn_decl)),
+                         THUNK_VIRTUAL_OFFSET (fn_decl));
+      fn_decl = TREE_OPERAND (DECL_INITIAL (fn_decl), 0);
     }
 
   /* Scoped name.  */