This is similar to clone_function_name and its siblings but takes an identifier tree node rather than a function declaration.
This is to be used in conjunction with the identifier node stored in cgraph_function_version_info::assembler_name to mangle FMV functions in later patches. gcc/ChangeLog: * cgraph.h (clone_identifier): New function. * cgraphclones.cc (clone_identifier): New function. (clone_function_name): Refactored to use clone_identifier. (is_valid_asm_symbol): New helper function. --- gcc/cgraph.h | 2 ++ gcc/cgraphclones.cc | 58 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/gcc/cgraph.h b/gcc/cgraph.h index deca564a8e3..189fa74497b 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -2644,6 +2644,8 @@ tree clone_function_name (const char *name, const char *suffix, tree clone_function_name (tree decl, const char *suffix, unsigned long number); tree clone_function_name (tree decl, const char *suffix); +tree clone_identifier (tree decl, const char *suffix, + bool filter_suffix = false); void tree_function_versioning (tree, tree, vec<ipa_replace_map *, va_gc> *, ipa_param_adjustments *, diff --git a/gcc/cgraphclones.cc b/gcc/cgraphclones.cc index c160e8b6985..e23ced16860 100644 --- a/gcc/cgraphclones.cc +++ b/gcc/cgraphclones.cc @@ -570,6 +570,32 @@ clone_function_name (tree decl, const char *suffix) /* For consistency this needs to behave the same way as ASM_FORMAT_PRIVATE_NAME does, but without the final number suffix. */ + return clone_identifier (identifier, suffix); +} + +/* Return true if symbol is valid in assembler name. */ + +static bool +is_valid_asm_symbol (char c) +{ + if ('a' <= c && c <= 'z') + return true; + if ('A' <= c && c <= 'Z') + return true; + if ('0' <= c && c <= '9') + return true; + if (c == '_') + return true; + return false; +} + +/* Return a new clone of ID ending with the string SUFFIX. + If FILTER_SUFFIX is true, any illegal asm characters in the SUFFIX are + replaced with _. */ + +tree +clone_identifier (tree id, const char *suffix, bool filter_suffix) +{ char *separator = XALLOCAVEC (char, 2); separator[0] = symbol_table::symbol_suffix_separator (); separator[1] = 0; @@ -578,14 +604,32 @@ clone_function_name (tree decl, const char *suffix) #else const char *prefix = ""; #endif - char *result = ACONCAT ((prefix, - IDENTIFIER_POINTER (identifier), - separator, - suffix, - (char*)0)); - return get_identifier (result); -} + if (!suffix) + suffix = ""; + if (!filter_suffix) + { + char *result = ACONCAT ( + (prefix, IDENTIFIER_POINTER (id), separator, suffix, (char *) 0)); + return get_identifier (result); + } + else + { + /* Replace any illegal chars with _. */ + int suffix_len = strlen (suffix); + char *converted_suffix = XALLOCAVEC (char, suffix_len + 1); + for (int i = 0; i < suffix_len; i++) + if (!is_valid_asm_symbol (suffix[i])) + converted_suffix[i] = '_'; + else + converted_suffix[i] = suffix[i]; + converted_suffix[suffix_len] = '\0'; + + char *result = ACONCAT ((prefix, IDENTIFIER_POINTER (id), separator, + converted_suffix, (char *) 0)); + return get_identifier (result); + } +} /* Create callgraph node clone with new declaration. The actual body will be copied later at compilation stage. The name of the new clone will be -- 2.34.1 -- Alfie Richards