[RFC 0/1] fortran: TARGET_CLONES attribute argument parsing syntax

2025-07-13 Thread ZAMBAR
From: ZAMBAR 

Hi all,

I would like to seek feedback on the implementation approach for the 
TARGET_CLONES attribute in gfortran, specifically regarding the syntax 
for parsing multiple target specifications.

Currently, I have implemented TARGET_CLONES support for Fortran using 
a C-style comma-separated argument list within parentheses, following 
the same pattern as the C/C++ front ends. The syntax looks like:

!GCC$ ATTRIBUTES TARGET_CLONES("default", "avx", "avx512f") :: function_name

This allows both double and single quoted strings:
!GCC$ ATTRIBUTES TARGET_CLONES('default', 'avx', 'avx512f') :: function_name

The key design question I'd like feedback on is whether this C-style 
comma-separated syntax is appropriate for Fortran, or if we should 
consider alternative approaches that might be more idiomatic to Fortran.

The current implementation:
- Parses comma-separated quoted string arguments
- Stores the target specifications in the symbol structure
- Integrates with the existing multiple target infrastructure
- Follows the same semantics as C/C++ TARGET_CLONES

I have a working patch (attached) that implements C-like syntax, but before 
proceeding further, I wanted to get community input on whether this syntax 
feels appropriate for Fortran users, or if there are better alternatives 
that would be more consistent with Fortran conventions.

Thanks for your time and feedback.

Best regards,
ZAMBAR

ZAMBAR (1):
  feat: gfortran target_clones mversion

 gcc/fortran/decl.cc | 116 
 gcc/fortran/f95-lang.cc |  34 
 gcc/fortran/gfortran.h  |   5 ++
 gcc/fortran/symbol.cc   |   8 +++
 gcc/multiple_target.cc  |   9 +++-
 5 files changed, 170 insertions(+), 2 deletions(-)

-- 
2.34.1



[RFC 1/1] fortran: Add TARGET_CLONES attribute support

2025-07-13 Thread ZAMBAR
From: ZAMBAR 

This patch implements the TARGET_CLONES attribute for Fortran functions,
using C-style comma-separated syntax for target specifications.

The implementation adds:
- Parsing support for TARGET_CLONES("target1", "target2", ...)
- Integration with existing multiple target infrastructure
- Proper memory management for target arguments
- Error handling for malformed syntax

Example usage:
!GCC$ ATTRIBUTES TARGET_CLONES("default", "avx", "avx512f") :: function_name

---
 gcc/fortran/decl.cc | 116 
 gcc/fortran/f95-lang.cc |  34 
 gcc/fortran/gfortran.h  |   5 ++
 gcc/fortran/symbol.cc   |   8 +++
 gcc/multiple_target.cc  |   9 +++-
 5 files changed, 170 insertions(+), 2 deletions(-)

diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc
index 69acd2da981..ed7c82dd8a3 100644
--- a/gcc/fortran/decl.cc
+++ b/gcc/fortran/decl.cc
@@ -11879,6 +11879,7 @@ const ext_attr_t ext_attr_list[] = {
   { "noinline", EXT_ATTR_NOINLINE, NULL   },
   { "noreturn", EXT_ATTR_NORETURN, NULL   },
   { "weak",EXT_ATTR_WEAK, NULL},
+  { "target_clones", EXT_ATTR_TARGET_CLONES, NULL   },
   { NULL,   EXT_ATTR_LAST, NULL}
 };
 
@@ -11896,6 +11897,13 @@ const ext_attr_t ext_attr_list[] = {
 
As there is absolutely no risk of confusion, we should never return
MATCH_NO.  */
+
+/* Structure to temporarily hold target_clones arguments during parsing */
+typedef struct {
+  char **args;
+  int count;
+} target_clones_args_t;
+
 match
 gfc_match_gcc_attributes (void)
 {
@@ -11904,6 +11912,7 @@ gfc_match_gcc_attributes (void)
   unsigned id;
   gfc_symbol *sym;
   match m;
+  target_clones_args_t target_clones_data = { NULL, 0 };
 
   gfc_clear_attr (&attr);
   for(;;)
@@ -11926,6 +11935,85 @@ gfc_match_gcc_attributes (void)
   if (!gfc_add_ext_attribute (&attr, (ext_attr_id_t)id, 
&gfc_current_locus))
return MATCH_ERROR;
 
+  /* Handle target_clones attribute with arguments */
+  if (id == EXT_ATTR_TARGET_CLONES)
+   {
+ /* Expect opening parenthesis for target_clones */
+ if (gfc_match_char ('(') != MATCH_YES)
+   {
+ gfc_error ("Expected '(' after TARGET_CLONES attribute at %C");
+ return MATCH_ERROR;
+   }
+ 
+ /* Parse comma-separated list of target specifications */
+ for (;;)
+   {
+ gfc_expr *expr = NULL;
+ 
+ /* Match quoted string argument */
+ if (gfc_match_literal_constant (&expr, 0) == MATCH_YES)
+   {
+ /* Verify it's a character constant */
+ if (expr->expr_type == EXPR_CONSTANT && expr->ts.type == 
BT_CHARACTER)
+   {
+ target_clones_data.count++;
+ target_clones_data.args = (char **) xrealloc 
(target_clones_data.args, 
+
target_clones_data.count * sizeof (char *));
+ 
+ /* Convert gfc_char_t* to char* */
+ int len = expr->value.character.length;
+ char *arg_str = (char *) xmalloc (len + 1);
+ for (int i = 0; i < len; i++)
+   arg_str[i] = (char) expr->value.character.string[i];
+ arg_str[len] = '\0';
+ 
+ target_clones_data.args[target_clones_data.count - 1] = 
arg_str;
+ gfc_free_expr (expr);
+ 
+ /* Check for comma (more arguments) or closing 
parenthesis */
+ gfc_gobble_whitespace ();
+ if (gfc_match_char (',') == MATCH_YES)
+   {
+ gfc_gobble_whitespace ();
+ continue;
+   }
+ else if (gfc_match_char (')') == MATCH_YES)
+   break;
+ else
+   {
+ gfc_error ("Expected ',' or ')' in TARGET_CLONES 
argument list at %C");
+ goto target_clones_error;
+   }
+   }
+ else
+   {
+ gfc_free_expr (expr);
+ gfc_error ("TARGET_CLONES arguments must be character 
constants at %C");
+ goto target_clones_error;
+   }
+   }
+ else
+   {
+ gfc_error ("Expected quoted string argument in TARGET_CLONES 
at %C");
+