#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "cp-tree.h"
#include "real.h"
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. */
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. */