diff options
author | Jakub Jelinek <jakub@redhat.com> | 2023-11-04 09:09:08 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2023-11-04 09:09:08 +0100 |
commit | 40b9af020fc2842b4e22ae06742088815400631e (patch) | |
tree | be3a513ca58aad599180e0752e46cb4412cc7217 /gcc/c/c-decl.cc | |
parent | 8d22ac6a18cf542cd541c06b2a7df8fdd293946d (diff) | |
download | gcc-40b9af020fc2842b4e22ae06742088815400631e.zip gcc-40b9af020fc2842b4e22ae06742088815400631e.tar.gz gcc-40b9af020fc2842b4e22ae06742088815400631e.tar.bz2 |
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 <jakub@redhat.com>
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_omp_begin_assumes_data, va_gc> *.
* 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<c_omp_begin_assumes_data, va_gc> *.
(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.
Diffstat (limited to 'gcc/c/c-decl.cc')
-rw-r--r-- | gcc/c/c-decl.cc | 82 |
1 files changed, 78 insertions, 4 deletions
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<c_omp_declare_target_attr, va_gc> *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<c_omp_begin_assumes_data, va_gc> *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<c_token, va_gc> *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 ("%<omp::%s%> 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, |