aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/mangle.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/mangle.c')
-rw-r--r--gcc/cp/mangle.c75
1 files changed, 41 insertions, 34 deletions
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index c72747c..eabab7f 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -2143,27 +2143,6 @@ write_expression (tree expr)
{
enum tree_code code = TREE_CODE (expr);
- /* Inside decltype we can simplify some expressions, since we're only
- interested in the type. */
- if (skip_evaluation)
- {
- tree type = describable_type (expr);
- if (type == NULL_TREE)
- ;
- else if (TREE_CODE (type) == REFERENCE_TYPE)
- {
- write_string ("sT");
- write_type (TREE_TYPE (type));
- return;
- }
- else
- {
- write_string ("sR");
- write_type (type);
- return;
- }
- }
-
/* Skip NOP_EXPRs. They can occur when (say) a pointer argument
is converted (via qualification conversions) to another
type. */
@@ -2210,10 +2189,12 @@ write_expression (tree expr)
write_template_arg_literal (expr);
else if (code == PARM_DECL)
{
- /* A function parameter used under decltype in a late-specified
- return type. Represented with a type placeholder. */
- write_string ("sT");
- write_type (non_reference (TREE_TYPE (expr)));
+ /* A function parameter used in a late-specified return type. */
+ int index = parm_index (expr);
+ write_string ("fp");
+ if (index > 1)
+ write_unsigned_number (index - 2);
+ write_char ('_');
}
else if (DECL_P (expr))
{
@@ -2231,6 +2212,12 @@ write_expression (tree expr)
write_string ("st");
write_type (TREE_OPERAND (expr, 0));
}
+ else if (TREE_CODE (expr) == ALIGNOF_EXPR
+ && TYPE_P (TREE_OPERAND (expr, 0)))
+ {
+ write_string ("at");
+ write_type (TREE_OPERAND (expr, 0));
+ }
else if (abi_version_at_least (2) && TREE_CODE (expr) == SCOPE_REF)
{
tree scope = TREE_OPERAND (expr, 0);
@@ -2298,9 +2285,16 @@ write_expression (tree expr)
write_template_args (template_args);
}
}
+ else if (TREE_CODE (expr) == INDIRECT_REF
+ && TREE_TYPE (TREE_OPERAND (expr, 0))
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
+ {
+ write_expression (TREE_OPERAND (expr, 0));
+ }
else
{
int i;
+ const char *name;
/* When we bind a variable or function to a non-type template
argument with reference type, we create an ADDR_EXPR to show
@@ -2338,7 +2332,14 @@ write_expression (tree expr)
}
/* If it wasn't any of those, recursively expand the expression. */
- write_string (operator_name_info[(int) code].mangled_name);
+ name = operator_name_info[(int) code].mangled_name;
+ if (name == NULL)
+ {
+ sorry ("mangling %C", code);
+ return;
+ }
+ else
+ write_string (name);
switch (code)
{
@@ -2351,23 +2352,29 @@ write_expression (tree expr)
case CAST_EXPR:
write_type (TREE_TYPE (expr));
- /* There is no way to mangle a zero-operand cast like
- "T()". */
- if (!TREE_OPERAND (expr, 0))
- sorry ("zero-operand casts cannot be mangled due to a defect "
- "in the C++ ABI");
- else if (list_length (TREE_OPERAND (expr, 0)) > 1)
- sorry ("mangling function-style cast with more than one argument");
- else
+ if (list_length (TREE_OPERAND (expr, 0)) == 1)
write_expression (TREE_VALUE (TREE_OPERAND (expr, 0)));
+ else
+ {
+ tree args = TREE_OPERAND (expr, 0);
+ write_char ('_');
+ for (; args; args = TREE_CHAIN (args))
+ write_expression (TREE_VALUE (args));
+ write_char ('E');
+ }
break;
+ /* FIXME these should have a distinct mangling. */
case STATIC_CAST_EXPR:
case CONST_CAST_EXPR:
write_type (TREE_TYPE (expr));
write_expression (TREE_OPERAND (expr, 0));
break;
+ case NEW_EXPR:
+ sorry ("mangling new-expression");
+ break;
+
/* Handle pointers-to-members specially. */
case SCOPE_REF:
write_type (TREE_OPERAND (expr, 0));