This is a reimplementation of get_target_clone_attr_len, get_attr_str, and separate_attrs using string_slice and auto_vec to make memory management and use simpler.
gcc/c-family/ChangeLog: * c-attribs.cc (handle_target_clones_attribute): Change to use get_clone_versions. gcc/ChangeLog: * tree.cc (get_clone_versions): New function. (get_clone_attr_versions): New function. * tree.h (get_clone_versions): New function. (get_clone_attr_versions): New function. --- gcc/c-family/c-attribs.cc | 2 +- gcc/tree.cc | 40 +++++++++++++++++++++++++++++++++++++++ gcc/tree.h | 3 +++ 3 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc index f3181e7b57c..642d724f6c6 100644 --- a/gcc/c-family/c-attribs.cc +++ b/gcc/c-family/c-attribs.cc @@ -6129,7 +6129,7 @@ handle_target_clones_attribute (tree *node, tree name, tree ARG_UNUSED (args), } } - if (get_target_clone_attr_len (args) == -1) + if (get_clone_attr_versions (args).length () == 1) { warning (OPT_Wattributes, "single %<target_clones%> attribute is ignored"); diff --git a/gcc/tree.cc b/gcc/tree.cc index 0743ed71c78..83dc9f32f96 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -15356,6 +15356,46 @@ get_target_clone_attr_len (tree arglist) return str_len_sum; } +/* Returns an auto_vec of string_slices containing the version strings from + ARGLIST. DEFAULT_COUNT is incremented for each default version found. */ + +auto_vec<string_slice> +get_clone_attr_versions (const tree arglist, int *default_count) +{ + gcc_assert (TREE_CODE (arglist) == TREE_LIST); + auto_vec<string_slice> versions; + + static const char separator_str[] = {TARGET_CLONES_ATTR_SEPARATOR, 0}; + string_slice separators = string_slice (separator_str); + + for (tree arg = arglist; arg; arg = TREE_CHAIN (arg)) + { + string_slice str = string_slice (TREE_STRING_POINTER (TREE_VALUE (arg))); + while (str.is_valid ()) + { + string_slice attr = string_slice::tokenize (&str, separators); + attr = attr.strip (); + if (attr == "default" && default_count) + (*default_count)++; + versions.safe_push (attr); + } + } + return versions; +} + +/* Returns an auto_vec of string_slices containing the version strings from + the target_clone attribute from DECL. DEFAULT_COUNT is incremented for each + default version found. */ +auto_vec<string_slice> +get_clone_versions (const tree decl, int *default_count) +{ + tree attr = lookup_attribute ("target_clones", DECL_ATTRIBUTES (decl)); + if (!attr) + return auto_vec<string_slice> (); + tree arglist = TREE_VALUE (attr); + return get_clone_attr_versions (arglist, default_count); +} + void tree_cc_finalize (void) { diff --git a/gcc/tree.h b/gcc/tree.h index 21f3cd5525c..70541070c40 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-core.h" #include "options.h" +#include "vec.h" /* Convert a target-independent built-in function code to a combined_fn. */ @@ -7035,5 +7036,7 @@ extern unsigned fndecl_dealloc_argno (tree); extern tree get_attr_nonstring_decl (tree, tree * = NULL); extern int get_target_clone_attr_len (tree); +auto_vec<string_slice> get_clone_versions (const tree, int * = NULL); +auto_vec<string_slice> get_clone_attr_versions (const tree, int * = NULL); #endif /* GCC_TREE_H */