From 40b9af020fc2842b4e22ae06742088815400631e Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 4 Nov 2023 09:09:08 +0100 Subject: openmp: Add support for omp::directive and omp::sequence attributes in C2X The following patch adds support for attribute syntax which we have in C++11 and above since GCC 12 also for C, where OpenMP standard is going to add it in OpenMP 6.0. 2023-11-04 Jakub Jelinek gcc/c/ * c-tree.def: New file. * c-tree.h (struct c_tree_token_vec): Forward declare. (c_tree_size): Declare. * c-lang.h (struct c_omp_declare_target_attr): Add attr_syntax member. (struct c_omp_begin_assumes_data): New type. (current_omp_begin_assumes): Change type from int to vec *. * c-lang.cc: Include c-family/c-pragma.h and c-parser.h. * c-parser.h (struct c_tree_token_vec_struct): New type. (C_TOKEN_VEC_TOKENS): New macro. * c-parser.cc (struct c_parser): Add omp_attrs_forbidden_p and in_omp_attribute_pragma members. (c_parser_skip_until_found): Handle CPP_PRAGMA_EOL when parser->in_omp_attribute_pragma. (c_parser_skip_to_pragma_eol): Likewise. (c_parser_translation_unit): Adjust for current_omp_begin_assumes being a vector rather than counter. (c_parser_declaration_or_fndef): Handle omp::directive and omp::sequence attributes on attribute declaration and declare simd or declare variant directives in those on function declarations. (c_parser_check_balanced_raw_token_sequence): Forward declare. (c_parser_omp_directive_args, c_parser_omp_sequence_args): New functions. (c_parser_std_attribute): Handle omp::directive and omp::sequence attributes. (struct c_omp_attribute_data): New type. (c_parser_handle_statement_omp_attributes, c_parser_handle_directive_omp_attributes): New functions. (c_parser_compound_statement_nostart): Handle omp::directive and omp::sequence attributes on statements. Formatting fix. (c_parser_all_labels): Handle omp::directive and omp::sequence attributes on statements. (c_parser_statement): Clear parser->omp_attrs_forbidden_p. (c_parser_omp_variable_list): Handle parser->tokens != &parser->tokens_buf[0] by saving/restoring it. (c_parser_omp_structured_block): Set parser->omp_attrs_forbidden_p. (c_parser_omp_section_scan): New function. (c_parser_omp_structured_block_sequence, c_parser_omp_sections_scope): Use it. (c_parser_omp_parallel): Set parser->omp_attrs_forbidden_p. (c_parser_omp_task): Likewise. (c_parser_omp_declare_simd): Handle function declaration after std attributes. (c_finish_omp_declare_simd): Don't assert all kinds are the same. (c_parser_omp_declare_target): Also push attr_syntax flag. (c_parser_omp_begin): Likewise. Adjust for current_omp_begin_assumes type change. (c_parser_omp_end): Adjust for current_omp_begin_assumes type change. Diagnose mixing of attribute vs. pragma syntax on end assumes or end declare target. (c_parser_omp_declare_reduction): Handle parser->tokens != &parser->tokens_buf[0] by saving/restoring it. * c-decl.cc: Include c-parser.h. (current_omp_begin_assumes): Change type from int to vec *. (struct c_tree_token_vec): New type. Add static assertions for sizeof and offsetof. (union lang_tree_node): Add c_token_vec member and adjust GTY desc for it. (c_tree_size): New function. (c_decl_attributes): Diagnose invalid omp::directive attribute uses. * c-objc-common.h (LANG_HOOKS_TREE_SIZE): Redefine. gcc/cp/ * parser.h (struct cp_parser): Adjust comment on omp_attrs_forbidden_p member. * parser.cc (cp_parser_omp_section_scan): Allow __directive__ spelling. gcc/objc/ * objc-act.h (objc_common_tree_size): Remove. * objc-act.cc (objc_common_tree_size): Remove. * objc-lang.cc (LANG_HOOKS_TREE_SIZE): Remove. gcc/testsuite/ * gcc.dg/gomp/attrs-1.c: New test. * gcc.dg/gomp/attrs-2.c: New test. * gcc.dg/gomp/attrs-3.c: New test. * gcc.dg/gomp/attrs-4.c: New test. * gcc.dg/gomp/attrs-5.c: New test. * gcc.dg/gomp/attrs-6.c: New test. * gcc.dg/gomp/attrs-7.c: New test. * gcc.dg/gomp/attrs-8.c: New test. * gcc.dg/gomp/attrs-9.c: New test. * gcc.dg/gomp/attrs-10.c: New test. * gcc.dg/gomp/attrs-11.c: New test. * gcc.dg/gomp/attrs-12.c: New test. * gcc.dg/gomp/attrs-13.c: New test. * gcc.dg/gomp/attrs-14.c: New test. * gcc.dg/gomp/attrs-15.c: New test. * gcc.dg/gomp/attrs-16.c: New test. * gcc.dg/gomp/attrs-17.c: New test. * gcc.dg/gomp/attrs-18.c: New test. * g++.dg/gomp/attrs-2.C: Enable for c++11 rather than just c++17. Avoid using omp : syntax for c++11, c++14 and c. --- gcc/c/c-decl.cc | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 4 deletions(-) (limited to 'gcc/c/c-decl.cc') diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 7a145be..33fb64d 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -61,6 +61,7 @@ along with GCC; see the file COPYING3. If not see #include "context.h" /* For 'g'. */ #include "omp-general.h" #include "omp-offload.h" /* For offload_vars. */ +#include "c-parser.h" #include "tree-pretty-print.h" @@ -157,9 +158,10 @@ static bool undef_nested_function; the attribute lists. */ vec *current_omp_declare_target_attribute; -/* If non-zero, we are inside of - #pragma omp begin assumes ... #pragma omp end assumes region. */ -int current_omp_begin_assumes; +/* Vector of + #pragma omp begin assumes ... #pragma omp end assumes regions + we are in. */ +vec *current_omp_begin_assumes; /* Each c_binding structure describes one binding of an identifier to a decl. All the decls in a scope - irrespective of namespace - are @@ -323,17 +325,46 @@ i_label_binding (tree node) #define I_LABEL_DECL(node) \ (I_LABEL_BINDING(node) ? I_LABEL_BINDING(node)->decl : 0) +/* Used by C_TOKEN_VEC tree. */ +struct GTY (()) c_tree_token_vec { + struct tree_base base; + vec *tokens; +}; + +STATIC_ASSERT (sizeof (c_tree_token_vec) == sizeof (c_tree_token_vec_struct)); +STATIC_ASSERT (offsetof (c_tree_token_vec, tokens) + == offsetof (c_tree_token_vec_struct, tokens)); + /* The resulting tree type. */ -union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"), +union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE + 2 * (TREE_CODE (&%h.generic) == C_TOKEN_VEC)"), chain_next ("(union lang_tree_node *) c_tree_chain_next (&%h.generic)"))) lang_tree_node { union tree_node GTY ((tag ("0"), desc ("tree_node_structure (&%h)"))) generic; struct lang_identifier GTY ((tag ("1"))) identifier; + struct c_tree_token_vec GTY ((tag ("2"))) c_token_vec; }; +/* Langhook for tree_size. */ +size_t +c_tree_size (enum tree_code code) +{ + gcc_checking_assert (code >= NUM_TREE_CODES); + switch (code) + { + case C_TOKEN_VEC: return sizeof (c_tree_token_vec); + default: + switch (TREE_CODE_CLASS (code)) + { + case tcc_declaration: return sizeof (tree_decl_non_common); + case tcc_type: return sizeof (tree_type_non_common); + default: gcc_unreachable (); + } + } +} + /* Track bindings and other things that matter for goto warnings. For efficiency, we do not gather all the decls at the point of definition. Instead, we point into the bindings structure. As @@ -5335,6 +5366,49 @@ c_decl_attributes (tree *node, tree attributes, int flags) } } + if (flag_openmp || flag_openmp_simd) + { + bool diagnosed = false; + for (tree *pa = &attributes; *pa; ) + { + if (is_attribute_namespace_p ("omp", *pa)) + { + tree name = get_attribute_name (*pa); + if (is_attribute_p ("directive", name) + || is_attribute_p ("sequence", name) + || is_attribute_p ("decl", name)) + { + const char *p = NULL; + if (TREE_VALUE (*pa) == NULL_TREE) + p = IDENTIFIER_POINTER (name); + for (tree a = TREE_VALUE (*pa); a; a = TREE_CHAIN (a)) + { + tree d = TREE_VALUE (a); + gcc_assert (TREE_CODE (d) == C_TOKEN_VEC); +/* if (TREE_PUBLIC (d) + && (VAR_P (*decl) + || TREE_CODE (*decl) == FUNCTION_DECL) + && c_maybe_parse_omp_decl (*decl, d)) + continue; */ + p = TREE_PUBLIC (d) ? "decl" : "directive"; + } + if (p && !diagnosed) + { + error ("% not allowed to be specified in " + "this context", p); + diagnosed = true; + } + if (p) + { + *pa = TREE_CHAIN (*pa); + continue; + } + } + } + pa = &TREE_CHAIN (*pa); + } + } + /* Look up the current declaration with all the attributes merged so far so that attributes on the current declaration that's about to be pushed that conflict with the former can be detected, -- cgit v1.1