Hi,
I've been adding an fn spec function attribute to some openacc builtin
functions:
...
diff --git a/gcc/builtin-attrs.def b/gcc/builtin-attrs.def
index 9c05a94..4e34192 100644
--- a/gcc/builtin-attrs.def
+++ b/gcc/builtin-attrs.def
@@ -64,6 +64,7 @@ DEF_ATTR_FOR_INT (6)
DEF_ATTR_TREE_LIST (ATTR_LIST_##ENUM, ATTR_NULL, \
ATTR_##ENUM, ATTR_NULL)
DEF_ATTR_FOR_STRING (STR1, "1")
+DEF_ATTR_FOR_STRING (DOT_DOT_DOT_r_r_r, "...rrr")
#undef DEF_ATTR_FOR_STRING
/* Construct a tree for a list of two integers. */
@@ -127,6 +128,8 @@ DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_LIST, ATTR_PURE,\
ATTR_NULL, ATTR_NOTHROW_LIST)
DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_LEAF_LIST, ATTR_PURE, \
ATTR_NULL, ATTR_NOTHROW_LEAF_LIST)
+DEF_ATTR_TREE_LIST (ATTR_FNSPEC_DOT_DOT_DOT_NOCLOB_NOCLOB_NOCLOB_NOTHROW_LIST,\
+ ATTR_FNSPEC, ATTR_LIST_DOT_DOT_DOT_r_r_r, ATTR_NOTHROW_LIST)
DEF_ATTR_TREE_LIST (ATTR_NORETURN_NOTHROW_LIST, ATTR_NORETURN, \
ATTR_NULL, ATTR_NOTHROW_LIST)
DEF_ATTR_TREE_LIST (ATTR_NORETURN_NOTHROW_LEAF_LIST, ATTR_NORETURN,\
...
That worked well for c. When compiling the fortran compiler, I ran into this
error:
...
In file included from gcc/fortran/f95-lang.c:1194:0:
gcc/fortran/../oacc-builtins.def: In function 'void
gfc_init_builtin_functions()':
gcc/fortran/../oacc-builtins.def:32:1: error:
'ATTR_FNSPEC_DOT_DOT_DOT_NOCLOB_NOCLOB_NOCLOB_NOTHROW_LIST' was not declared in
this scope
make[2]: *** [fortran/f95-lang.o] Error 1
...
In fortran, attributes are modelled as integers:
...
/* So far we need just these 7 attribute types. */
#define ATTR_NULL 0
#define ATTR_LEAF_LIST (ECF_LEAF)
#define ATTR_NOTHROW_LEAF_LIST (ECF_NOTHROW | ECF_LEAF)
#define ATTR_NOTHROW_LEAF_MALLOC_LIST (ECF_NOTHROW | ECF_LEAF | ECF_MALLOC)
#define ATTR_CONST_NOTHROW_LEAF_LIST (ECF_NOTHROW | ECF_LEAF | ECF_CONST)
#define ATTR_PURE_NOTHROW_LEAF_LIST (ECF_NOTHROW | ECF_LEAF | ECF_PURE)
#define ATTR_NOTHROW_LIST (ECF_NOTHROW)
#define ATTR_CONST_NOTHROW_LIST (ECF_NOTHROW | ECF_CONST)
...
And the attribute ints are passed to gfc_define_builtin:
...
static void
gfc_define_builtin (const char *name, tree type, enum built_in_function code,
const char *library_name, int attr)
{
tree decl;
decl = add_builtin_function (name, type, code, BUILT_IN_NORMAL,
library_name, NULL_TREE);
set_call_expr_flags (decl, attr);
set_builtin_decl (code, decl, true);
}
...
which passes it to set_call_expr_flags:
...
void
set_call_expr_flags (tree decl, int flags)
{
if (flags & ECF_NOTHROW)
TREE_NOTHROW (decl) = 1;
if (flags & ECF_CONST)
TREE_READONLY (decl) = 1;
if (flags & ECF_PURE)
DECL_PURE_P (decl) = 1;
if (flags & ECF_LOOPING_CONST_OR_PURE)
DECL_LOOPING_CONST_OR_PURE_P (decl) = 1;
if (flags & ECF_NOVOPS)
DECL_IS_NOVOPS (decl) = 1;
if (flags & ECF_NORETURN)
TREE_THIS_VOLATILE (decl) = 1;
if (flags & ECF_MALLOC)
DECL_IS_MALLOC (decl) = 1;
if (flags & ECF_RETURNS_TWICE)
DECL_IS_RETURNS_TWICE (decl) = 1;
if (flags & ECF_LEAF)
DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("leaf"),
NULL, DECL_ATTRIBUTES (decl));
if ((flags & ECF_TM_PURE) && flag_tm)
apply_tm_attr (decl, get_identifier ("transaction_pure"));
/* Looping const or pure is implied by noreturn.
There is currently no way to declare looping const or looping pure alone.
*/
gcc_assert (!(flags & ECF_LOOPING_CONST_OR_PURE)
|| ((flags & ECF_NORETURN) && (flags & (ECF_CONST | ECF_PURE))));
}
...
Note that in case of ECF_LEAF, we set an actual attribute.
So, Is this the moment to define ECF_FNSPEC_DOT_DOT_DOT_r_r_r in tree-core.h,
and handle it in set_call_expr_flags, or should we add more generic attribute
handling in f95-lang.c?
Thanks,
- Tom