Alfie Richards <[email protected]> writes:
> 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 | 5 +++++
> 3 files changed, 46 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 05f679edc09..346522d01c0 100644
> --- a/gcc/tree.cc
> +++ b/gcc/tree.cc
> @@ -15299,6 +15299,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)));
> + for (string_slice attr = string_slice::strtok (&str, separators);
> + attr.is_valid (); attr = string_slice::strtok (&str, separators))
> + {
> + attr = attr.strip ();
> + if (attr == string_slice ("default") && default_count)
Do we need the explicit constructor here? It would be nice if
attr == "default" worked.
> + (*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..aea1cf078a0 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,9 @@ 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);
Formatting nit, but: it's more usual to put declarations on a single line,
if they'd fit.
Otherwise it looks good, given that patch 13 removes the old functions.
Thanks,
Richard
>
> #endif /* GCC_TREE_H */