Hello,
Le 09/11/2022 à 20:02, Bernhard Reutner-Fischer via Fortran a écrit :
Hi!
Add support for attribute target_clones:
!GCC$ ATTRIBUTES target_clones("arch1", "arch3","default") :: mysubroutine
Bootstrapped and regtested on x86_64-unknown-linux with
--target_board=unix'{-m32,-m64}'.
OK for trunk?
gcc/fortran/ChangeLog:
* decl.cc: Include fold-const.h for size_int.
(gfc_match_gcc_attribute_args): New internal helper function.
(gfc_match_gcc_attributes): Handle target_clones.
* f95-lang.cc (struct attribute_spec): Add target and
target_clones entries.
* gfortran.h (ext_attr_id_t): Add EXT_ATTR_TARGET_CLONES.
(struct symbol_attribute): Add field ext_attr_args.
* trans-decl.cc (add_attributes_to_decl): Also add ext_attr_args
to the decl's attributes.
* gfortran.texi: Document attribute target_clones.
gcc/testsuite/ChangeLog:
* gfortran.dg/attr_target_clones-1.F90: New test.
Cc: gfortran ML <fort...@gcc.gnu.org>
---
gcc/fortran/decl.cc | 104 ++++++++++++++++++
gcc/fortran/f95-lang.cc | 4 +
gcc/fortran/gfortran.h | 2 +
gcc/fortran/gfortran.texi | 31 ++++++
gcc/fortran/trans-decl.cc | 3 +
.../gfortran.dg/attr_target_clones-1.F90 | 30 +++++
6 files changed, 174 insertions(+)
create mode 100644 gcc/testsuite/gfortran.dg/attr_target_clones-1.F90
diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc
index 0f9b2ced4c2..3a619dbdd34 100644
--- a/gcc/fortran/decl.cc
+++ b/gcc/fortran/decl.cc
(...)
@@ -11709,6 +11710,96 @@ gfc_match_final_decl (void)
return MATCH_YES;
}
+/* Internal helper to parse attribute argument list.
+ If REQUIRE_STRING is true, then require a string.
+ If ALLOW_MULTIPLE is true, allow more than one arg.
+ If multiple arguments are passed, require braces around them.
+ Returns a tree_list of arguments or NULL_TREE. */
+static tree
+gfc_match_gcc_attribute_args (bool require_string, bool allow_multiple)
+{
+ tree attr_args = NULL_TREE, attr_arg;
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ unsigned pos = 0;
+ gfc_char_t c;
+
+ /* When we get here, we already parsed
+ !GCC$ ATTRIBUTES ATTRIBUTE_NAME
+ Now parse the arguments. These could be one of
+ "single_string_literal"
+ ( "str_literal_1" , "str_literal_2" )
+ */
+
+ gfc_gobble_whitespace ();
+
+ if (allow_multiple && gfc_match_char ('(') != MATCH_YES)
+ {
+ gfc_error ("expected '(' at %C");
+ return NULL_TREE;
+ }
+
+ if (require_string)
+ {
+ do {
+ if (pos)
+ {
+ if (!allow_multiple)
+ {
+ gfc_error ("surplus argument at %C");
+ return NULL_TREE;
+ }
+ gfc_next_ascii_char (); /* Consume the comma. */
+ }
+ pos = 0;
+ gfc_gobble_whitespace ();
+ unsigned char num_quotes = 0;
+ do {
+ c = gfc_next_char_literal (NONSTRING);
+ if (c == '"')
+ {
+ num_quotes++;
+ continue; /* Skip the quote */
+ }
+ name[pos++] = c;
+ if (pos >= GFC_MAX_SYMBOL_LEN)
+ {
+ gfc_error ("attribute argument truncated at %C");
+ return NULL_TREE;
+ }
+ } while (num_quotes % 2 && gfc_match_eos () != MATCH_YES);
The do-while loops are wrongly indented.
It should be:
do
{
...
}
while (...)
+ if (pos < 1)
+ {
+ gfc_error ("expected argument at %C");
+ return NULL_TREE;
+ }
+ if (num_quotes != 2)
+ {
+ gfc_error ("invalid string literal at %C");
+ return NULL_TREE;
+ }
+ name[pos] = '\0'; /* Redundant wrt build_string. */
+ tree str = build_string (pos, name);
+ /* Compare with c-family/c-common.cc: fix_string_type. */
+ tree i_type = build_index_type (size_int (pos));
+ tree a_type = build_array_type (char_type_node, i_type);
+ TREE_TYPE (str) = a_type;
+ TREE_READONLY (str) = 1;
+ TREE_STATIC (str) = 1;
+ attr_arg = build_tree_list (NULL_TREE, str);
+ attr_args = chainon (attr_args, attr_arg);
Same comment as for the flatten attribute:
please no tree stuff out of the trans-*.cc files.
This includes gfortran.h, so the attribute arguments need to be carried
around using the front-end structures (gfc_actual_arglist for example).
+
+ gfc_gobble_whitespace ();
+ } while (gfc_peek_ascii_char () == ',');
+ }
+
+ if (allow_multiple && gfc_match_char (')') != MATCH_YES)
+ {
+ gfc_error ("expected ')' at %C");
+ return NULL_TREE;
+ }
+
+ return attr_args;
+}
I'm not sure this function need to do all the parsing manually.
I would rather use gfc_match_actual_arglist, or maybe implement the
function as a wrapper around it.
What is allowed here? Are non-literal constants allowed, for example
parameter variables? Is line continuation supported ?
Nothing (bad) to say about the rest, but there is enough to change with
the above comments.
Mikael