diff options
Diffstat (limited to 'gcc/cp/mangle.c')
-rw-r--r-- | gcc/cp/mangle.c | 75 |
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)); |