aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/decl.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2019-05-28 08:47:33 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2019-05-28 08:47:33 +0000
commit5ca5ef68709f317927a055a610bfcec6e4ec0172 (patch)
treedec6a653b7329a451f0344e9c05b5d25a6bffdb1 /gcc/ada/gcc-interface/decl.c
parent79069232df7ae1f59c68bbe90804a30c2dbec5d3 (diff)
downloadgcc-5ca5ef68709f317927a055a610bfcec6e4ec0172.zip
gcc-5ca5ef68709f317927a055a610bfcec6e4ec0172.tar.gz
gcc-5ca5ef68709f317927a055a610bfcec6e4ec0172.tar.bz2
implementation_defined_pragmas.rst (Machine_Attribute): Document additional optional parameters.
* doc/gnat_rm/implementation_defined_pragmas.rst (Machine_Attribute): Document additional optional parameters. * sem_prag.adb (Analyze_Pragma) <Pragma_Machine_Attribute>: Accept more than one optional parameter. * gcc-interface/decl.c (prepend_one_attribute_pragma): Alphabetize the list of supported pragmas. Simplify the handling of parameters and add support for more than one optional parameter. * gcc-interface/utils.c (attr_cold_hot_exclusions): New constant. (gnat_internal_attribute_table): Add entry for no_icf, noipa, flatten, used, cold, hot, target and target_clones. (begin_subprog_body): Do not create the RTL for the subprogram here. (handle_noicf_attribute): New static function. (handle_noipa_attribute): Likewise. (handle_flatten_attribute): Likewise. (handle_used_attribute): Likewise. (handle_cold_attribute): Likewise. (handle_hot_attribute): Likewise. (handle_target_attribute): Likewise. (handle_target_clones_attribute): Likewise. From-SVN: r271693
Diffstat (limited to 'gcc/ada/gcc-interface/decl.c')
-rw-r--r--gcc/ada/gcc-interface/decl.c85
1 files changed, 39 insertions, 46 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index da8fbe6..4dfd76b 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -6458,25 +6458,18 @@ prepend_one_attribute (struct attrib **attr_list,
static void
prepend_one_attribute_pragma (struct attrib **attr_list, Node_Id gnat_pragma)
{
- const Node_Id gnat_arg = Pragma_Argument_Associations (gnat_pragma);
- tree gnu_arg0 = NULL_TREE, gnu_arg1 = NULL_TREE;
+ const Node_Id gnat_arg = First (Pragma_Argument_Associations (gnat_pragma));
+ Node_Id gnat_next_arg = Next (gnat_arg);
+ tree gnu_arg1 = NULL_TREE, gnu_arg_list = NULL_TREE;
enum attrib_type etype;
/* Map the pragma at hand. Skip if this isn't one we know how to handle. */
switch (Get_Pragma_Id (Chars (Pragma_Identifier (gnat_pragma))))
{
- case Pragma_Machine_Attribute:
- etype = ATTR_MACHINE_ATTRIBUTE;
- break;
-
case Pragma_Linker_Alias:
etype = ATTR_LINK_ALIAS;
break;
- case Pragma_Linker_Section:
- etype = ATTR_LINK_SECTION;
- break;
-
case Pragma_Linker_Constructor:
etype = ATTR_LINK_CONSTRUCTOR;
break;
@@ -6485,58 +6478,58 @@ prepend_one_attribute_pragma (struct attrib **attr_list, Node_Id gnat_pragma)
etype = ATTR_LINK_DESTRUCTOR;
break;
- case Pragma_Weak_External:
- etype = ATTR_WEAK_EXTERNAL;
+ case Pragma_Linker_Section:
+ etype = ATTR_LINK_SECTION;
+ break;
+
+ case Pragma_Machine_Attribute:
+ etype = ATTR_MACHINE_ATTRIBUTE;
break;
case Pragma_Thread_Local_Storage:
etype = ATTR_THREAD_LOCAL_STORAGE;
break;
+ case Pragma_Weak_External:
+ etype = ATTR_WEAK_EXTERNAL;
+ break;
+
default:
return;
}
/* See what arguments we have and turn them into GCC trees for attribute
- handlers. These expect identifier for strings. We handle at most two
- arguments and static expressions only. */
- if (Present (gnat_arg) && Present (First (gnat_arg)))
+ handlers. The first one is always expected to be a string meant to be
+ turned into an identifier. The next ones are all static expressions,
+ among which strings meant to be turned into an identifier, except for
+ a couple of specific attributes that require raw strings. */
+ if (Present (gnat_next_arg))
{
- Node_Id gnat_arg0 = Next (First (gnat_arg));
- Node_Id gnat_arg1 = Empty;
-
- if (Present (gnat_arg0)
- && Is_OK_Static_Expression (Expression (gnat_arg0)))
- {
- gnu_arg0 = gnat_to_gnu (Expression (gnat_arg0));
-
- if (TREE_CODE (gnu_arg0) == STRING_CST)
- {
- gnu_arg0 = get_identifier (TREE_STRING_POINTER (gnu_arg0));
- if (IDENTIFIER_LENGTH (gnu_arg0) == 0)
- return;
- }
-
- gnat_arg1 = Next (gnat_arg0);
- }
-
- if (Present (gnat_arg1)
- && Is_OK_Static_Expression (Expression (gnat_arg1)))
+ gnu_arg1 = gnat_to_gnu (Expression (gnat_next_arg));
+ gcc_assert (TREE_CODE (gnu_arg1) == STRING_CST);
+
+ const char *const p = TREE_STRING_POINTER (gnu_arg1);
+ const bool string_args
+ = strcmp (p, "target") == 0 || strcmp (p, "target_clones") == 0;
+ gnu_arg1 = get_identifier (p);
+ if (IDENTIFIER_LENGTH (gnu_arg1) == 0)
+ return;
+ gnat_next_arg = Next (gnat_next_arg);
+
+ while (Present (gnat_next_arg))
{
- gnu_arg1 = gnat_to_gnu (Expression (gnat_arg1));
-
- if (TREE_CODE (gnu_arg1) == STRING_CST)
- gnu_arg1 = get_identifier (TREE_STRING_POINTER (gnu_arg1));
+ tree gnu_arg = gnat_to_gnu (Expression (gnat_next_arg));
+ if (TREE_CODE (gnu_arg) == STRING_CST && !string_args)
+ gnu_arg = get_identifier (TREE_STRING_POINTER (gnu_arg));
+ gnu_arg_list
+ = chainon (gnu_arg_list, build_tree_list (NULL_TREE, gnu_arg));
+ gnat_next_arg = Next (gnat_next_arg);
}
}
- /* Prepend to the list. Make a list of the argument we might have, as GCC
- expects it. */
- prepend_one_attribute (attr_list, etype, gnu_arg0,
- gnu_arg1
- ? build_tree_list (NULL_TREE, gnu_arg1) : NULL_TREE,
- Present (Next (First (gnat_arg)))
- ? Expression (Next (First (gnat_arg))) : gnat_pragma);
+ prepend_one_attribute (attr_list, etype, gnu_arg1, gnu_arg_list,
+ Present (Next (gnat_arg))
+ ? Expression (Next (gnat_arg)) : gnat_pragma);
}
/* Prepend to ATTR_LIST the list of attributes for GNAT_ENTITY, if any. */