1 /* OpenMP directive matching and resolving.
2 Copyright (C) 2005-2020 Free Software Foundation, Inc.
3 Contributed by Jakub Jelinek
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
28 #include "diagnostic.h"
29 #include "gomp-constants.h"
31 /* Match an end of OpenMP directive. End of OpenMP directive is optional
32 whitespace, followed by '\n' or comment '!'. */
35 gfc_match_omp_eos (void)
40 old_loc
= gfc_current_locus
;
41 gfc_gobble_whitespace ();
43 c
= gfc_next_ascii_char ();
48 c
= gfc_next_ascii_char ();
56 gfc_current_locus
= old_loc
;
61 gfc_match_omp_eos_error (void)
63 if (gfc_match_omp_eos() == MATCH_YES
)
66 gfc_error ("Unexpected junk at %C");
71 /* Free an omp_clauses structure. */
74 gfc_free_omp_clauses (gfc_omp_clauses
*c
)
80 gfc_free_expr (c
->if_expr
);
81 gfc_free_expr (c
->final_expr
);
82 gfc_free_expr (c
->num_threads
);
83 gfc_free_expr (c
->chunk_size
);
84 gfc_free_expr (c
->safelen_expr
);
85 gfc_free_expr (c
->simdlen_expr
);
86 gfc_free_expr (c
->num_teams
);
87 gfc_free_expr (c
->device
);
88 gfc_free_expr (c
->thread_limit
);
89 gfc_free_expr (c
->dist_chunk_size
);
90 gfc_free_expr (c
->grainsize
);
91 gfc_free_expr (c
->hint
);
92 gfc_free_expr (c
->num_tasks
);
93 gfc_free_expr (c
->priority
);
94 for (i
= 0; i
< OMP_IF_LAST
; i
++)
95 gfc_free_expr (c
->if_exprs
[i
]);
96 gfc_free_expr (c
->async_expr
);
97 gfc_free_expr (c
->gang_num_expr
);
98 gfc_free_expr (c
->gang_static_expr
);
99 gfc_free_expr (c
->worker_expr
);
100 gfc_free_expr (c
->vector_expr
);
101 gfc_free_expr (c
->num_gangs_expr
);
102 gfc_free_expr (c
->num_workers_expr
);
103 gfc_free_expr (c
->vector_length_expr
);
104 for (i
= 0; i
< OMP_LIST_NUM
; i
++)
105 gfc_free_omp_namelist (c
->lists
[i
]);
106 gfc_free_expr_list (c
->wait_list
);
107 gfc_free_expr_list (c
->tile_list
);
108 free (CONST_CAST (char *, c
->critical_name
));
112 /* Free oacc_declare structures. */
115 gfc_free_oacc_declare_clauses (struct gfc_oacc_declare
*oc
)
117 struct gfc_oacc_declare
*decl
= oc
;
121 struct gfc_oacc_declare
*next
;
124 gfc_free_omp_clauses (decl
->clauses
);
131 /* Free expression list. */
133 gfc_free_expr_list (gfc_expr_list
*list
)
137 for (; list
; list
= n
)
144 /* Free an !$omp declare simd construct list. */
147 gfc_free_omp_declare_simd (gfc_omp_declare_simd
*ods
)
151 gfc_free_omp_clauses (ods
->clauses
);
157 gfc_free_omp_declare_simd_list (gfc_omp_declare_simd
*list
)
161 gfc_omp_declare_simd
*current
= list
;
163 gfc_free_omp_declare_simd (current
);
167 /* Free an !$omp declare reduction. */
170 gfc_free_omp_udr (gfc_omp_udr
*omp_udr
)
174 gfc_free_omp_udr (omp_udr
->next
);
175 gfc_free_namespace (omp_udr
->combiner_ns
);
176 if (omp_udr
->initializer_ns
)
177 gfc_free_namespace (omp_udr
->initializer_ns
);
184 gfc_find_omp_udr (gfc_namespace
*ns
, const char *name
, gfc_typespec
*ts
)
192 gfc_omp_udr
*omp_udr
;
194 st
= gfc_find_symtree (ns
->omp_udr_root
, name
);
197 for (omp_udr
= st
->n
.omp_udr
; omp_udr
; omp_udr
= omp_udr
->next
)
200 else if (gfc_compare_types (&omp_udr
->ts
, ts
))
202 if (ts
->type
== BT_CHARACTER
)
204 if (omp_udr
->ts
.u
.cl
->length
== NULL
)
206 if (ts
->u
.cl
->length
== NULL
)
208 if (gfc_compare_expr (omp_udr
->ts
.u
.cl
->length
,
217 /* Don't escape an interface block. */
218 if (ns
&& !ns
->has_import_set
219 && ns
->proc_name
&& ns
->proc_name
->attr
.if_source
== IFSRC_IFBODY
)
230 /* Match a variable/common block list and construct a namelist from it. */
233 gfc_match_omp_variable_list (const char *str
, gfc_omp_namelist
**list
,
234 bool allow_common
, bool *end_colon
= NULL
,
235 gfc_omp_namelist
***headp
= NULL
,
236 bool allow_sections
= false,
237 bool allow_derived
= false)
239 gfc_omp_namelist
*head
, *tail
, *p
;
240 locus old_loc
, cur_loc
;
241 char n
[GFC_MAX_SYMBOL_LEN
+1];
248 old_loc
= gfc_current_locus
;
256 cur_loc
= gfc_current_locus
;
257 m
= gfc_match_symbol (&sym
, 1);
263 if ((allow_sections
&& gfc_peek_ascii_char () == '(')
264 || (allow_derived
&& gfc_peek_ascii_char () == '%'))
266 gfc_current_locus
= cur_loc
;
267 m
= gfc_match_variable (&expr
, 0);
277 if (gfc_is_coindexed (expr
))
279 gfc_error ("List item shall not be coindexed at %C");
283 gfc_set_sym_referenced (sym
);
284 p
= gfc_get_omp_namelist ();
294 tail
->where
= cur_loc
;
305 m
= gfc_match (" / %n /", n
);
306 if (m
== MATCH_ERROR
)
311 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
314 gfc_error ("COMMON block /%s/ not found at %C", n
);
317 for (sym
= st
->n
.common
->head
; sym
; sym
= sym
->common_next
)
319 gfc_set_sym_referenced (sym
);
320 p
= gfc_get_omp_namelist ();
329 tail
->where
= cur_loc
;
333 if (end_colon
&& gfc_match_char (':') == MATCH_YES
)
338 if (gfc_match_char (')') == MATCH_YES
)
340 if (gfc_match_char (',') != MATCH_YES
)
345 list
= &(*list
)->next
;
353 gfc_error ("Syntax error in OpenMP variable list at %C");
356 gfc_free_omp_namelist (head
);
357 gfc_current_locus
= old_loc
;
361 /* Match a variable/procedure/common block list and construct a namelist
365 gfc_match_omp_to_link (const char *str
, gfc_omp_namelist
**list
)
367 gfc_omp_namelist
*head
, *tail
, *p
;
368 locus old_loc
, cur_loc
;
369 char n
[GFC_MAX_SYMBOL_LEN
+1];
376 old_loc
= gfc_current_locus
;
384 cur_loc
= gfc_current_locus
;
385 m
= gfc_match_symbol (&sym
, 1);
389 p
= gfc_get_omp_namelist ();
398 tail
->where
= cur_loc
;
406 m
= gfc_match (" / %n /", n
);
407 if (m
== MATCH_ERROR
)
412 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
415 gfc_error ("COMMON block /%s/ not found at %C", n
);
418 p
= gfc_get_omp_namelist ();
426 tail
->u
.common
= st
->n
.common
;
427 tail
->where
= cur_loc
;
430 if (gfc_match_char (')') == MATCH_YES
)
432 if (gfc_match_char (',') != MATCH_YES
)
437 list
= &(*list
)->next
;
443 gfc_error ("Syntax error in OpenMP variable list at %C");
446 gfc_free_omp_namelist (head
);
447 gfc_current_locus
= old_loc
;
451 /* Match depend(sink : ...) construct a namelist from it. */
454 gfc_match_omp_depend_sink (gfc_omp_namelist
**list
)
456 gfc_omp_namelist
*head
, *tail
, *p
;
457 locus old_loc
, cur_loc
;
462 old_loc
= gfc_current_locus
;
466 cur_loc
= gfc_current_locus
;
467 switch (gfc_match_symbol (&sym
, 1))
470 gfc_set_sym_referenced (sym
);
471 p
= gfc_get_omp_namelist ();
475 head
->u
.depend_op
= OMP_DEPEND_SINK_FIRST
;
481 tail
->u
.depend_op
= OMP_DEPEND_SINK
;
485 tail
->where
= cur_loc
;
486 if (gfc_match_char ('+') == MATCH_YES
)
488 if (gfc_match_literal_constant (&tail
->expr
, 0) != MATCH_YES
)
491 else if (gfc_match_char ('-') == MATCH_YES
)
493 if (gfc_match_literal_constant (&tail
->expr
, 0) != MATCH_YES
)
495 tail
->expr
= gfc_uminus (tail
->expr
);
504 if (gfc_match_char (')') == MATCH_YES
)
506 if (gfc_match_char (',') != MATCH_YES
)
511 list
= &(*list
)->next
;
517 gfc_error ("Syntax error in OpenMP DEPEND SINK list at %C");
520 gfc_free_omp_namelist (head
);
521 gfc_current_locus
= old_loc
;
526 match_oacc_expr_list (const char *str
, gfc_expr_list
**list
,
529 gfc_expr_list
*head
, *tail
, *p
;
536 old_loc
= gfc_current_locus
;
544 m
= gfc_match_expr (&expr
);
545 if (m
== MATCH_YES
|| allow_asterisk
)
547 p
= gfc_get_expr_list ();
557 else if (gfc_match (" *") != MATCH_YES
)
561 if (m
== MATCH_ERROR
)
566 if (gfc_match_char (')') == MATCH_YES
)
568 if (gfc_match_char (',') != MATCH_YES
)
573 list
= &(*list
)->next
;
579 gfc_error ("Syntax error in OpenACC expression list at %C");
582 gfc_free_expr_list (head
);
583 gfc_current_locus
= old_loc
;
588 match_oacc_clause_gwv (gfc_omp_clauses
*cp
, unsigned gwv
)
590 match ret
= MATCH_YES
;
592 if (gfc_match (" ( ") != MATCH_YES
)
595 if (gwv
== GOMP_DIM_GANG
)
597 /* The gang clause accepts two optional arguments, num and static.
598 The num argument may either be explicit (num: <val>) or
599 implicit without (<val> without num:). */
601 while (ret
== MATCH_YES
)
603 if (gfc_match (" static :") == MATCH_YES
)
608 cp
->gang_static
= true;
609 if (gfc_match_char ('*') == MATCH_YES
)
610 cp
->gang_static_expr
= NULL
;
611 else if (gfc_match (" %e ", &cp
->gang_static_expr
) != MATCH_YES
)
616 if (cp
->gang_num_expr
)
619 /* The 'num' argument is optional. */
620 gfc_match (" num :");
622 if (gfc_match (" %e ", &cp
->gang_num_expr
) != MATCH_YES
)
626 ret
= gfc_match (" , ");
629 else if (gwv
== GOMP_DIM_WORKER
)
631 /* The 'num' argument is optional. */
632 gfc_match (" num :");
634 if (gfc_match (" %e ", &cp
->worker_expr
) != MATCH_YES
)
637 else if (gwv
== GOMP_DIM_VECTOR
)
639 /* The 'length' argument is optional. */
640 gfc_match (" length :");
642 if (gfc_match (" %e ", &cp
->vector_expr
) != MATCH_YES
)
646 gfc_fatal_error ("Unexpected OpenACC parallelism.");
648 return gfc_match (" )");
652 gfc_match_oacc_clause_link (const char *str
, gfc_omp_namelist
**list
)
654 gfc_omp_namelist
*head
= NULL
;
655 gfc_omp_namelist
*tail
, *p
;
657 char n
[GFC_MAX_SYMBOL_LEN
+1];
662 old_loc
= gfc_current_locus
;
668 m
= gfc_match (" (");
672 m
= gfc_match_symbol (&sym
, 0);
676 if (sym
->attr
.in_common
)
678 gfc_error_now ("Variable at %C is an element of a COMMON block");
681 gfc_set_sym_referenced (sym
);
682 p
= gfc_get_omp_namelist ();
692 tail
->where
= gfc_current_locus
;
701 m
= gfc_match (" / %n /", n
);
702 if (m
== MATCH_ERROR
)
704 if (m
== MATCH_NO
|| n
[0] == '\0')
707 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
710 gfc_error ("COMMON block /%s/ not found at %C", n
);
714 for (sym
= st
->n
.common
->head
; sym
; sym
= sym
->common_next
)
716 gfc_set_sym_referenced (sym
);
717 p
= gfc_get_omp_namelist ();
726 tail
->where
= gfc_current_locus
;
730 if (gfc_match_char (')') == MATCH_YES
)
732 if (gfc_match_char (',') != MATCH_YES
)
736 if (gfc_match_omp_eos () != MATCH_YES
)
738 gfc_error ("Unexpected junk after !$ACC DECLARE at %C");
743 list
= &(*list
)->next
;
748 gfc_error ("Syntax error in !$ACC DECLARE list at %C");
751 gfc_current_locus
= old_loc
;
755 /* OpenMP 4.5 clauses. */
759 OMP_CLAUSE_FIRSTPRIVATE
,
760 OMP_CLAUSE_LASTPRIVATE
,
761 OMP_CLAUSE_COPYPRIVATE
,
764 OMP_CLAUSE_REDUCTION
,
766 OMP_CLAUSE_NUM_THREADS
,
773 OMP_CLAUSE_MERGEABLE
,
778 OMP_CLAUSE_NOTINBRANCH
,
779 OMP_CLAUSE_PROC_BIND
,
787 OMP_CLAUSE_NUM_TEAMS
,
788 OMP_CLAUSE_THREAD_LIMIT
,
789 OMP_CLAUSE_DIST_SCHEDULE
,
790 OMP_CLAUSE_DEFAULTMAP
,
791 OMP_CLAUSE_GRAINSIZE
,
793 OMP_CLAUSE_IS_DEVICE_PTR
,
796 OMP_CLAUSE_NUM_TASKS
,
800 OMP_CLAUSE_USE_DEVICE_PTR
,
801 OMP_CLAUSE_USE_DEVICE_ADDR
, /* Actually, OpenMP 5.0. */
803 /* This must come last. */
807 /* OpenACC 2.0+ specific clauses. */
811 OMP_CLAUSE_NUM_GANGS
,
812 OMP_CLAUSE_NUM_WORKERS
,
813 OMP_CLAUSE_VECTOR_LENGTH
,
817 OMP_CLAUSE_NO_CREATE
,
819 OMP_CLAUSE_DEVICEPTR
,
824 OMP_CLAUSE_INDEPENDENT
,
825 OMP_CLAUSE_USE_DEVICE
,
826 OMP_CLAUSE_DEVICE_RESIDENT
,
827 OMP_CLAUSE_HOST_SELF
,
832 OMP_CLAUSE_IF_PRESENT
,
836 /* This must come last. */
842 /* Customized bitset for up to 128-bits.
843 The two enums above provide bit numbers to use, and which of the
844 two enums it is determines which of the two mask fields is used.
845 Supported operations are defining a mask, like:
846 #define XXX_CLAUSES \
847 (omp_mask (OMP_CLAUSE_XXX) | OMP_CLAUSE_YYY | OMP_CLAUSE_ZZZ)
848 oring such bitsets together or removing selected bits:
849 (XXX_CLAUSES | YYY_CLAUSES) & ~(omp_mask (OMP_CLAUSE_VVV))
850 and testing individual bits:
851 if (mask & OMP_CLAUSE_UUU) */
854 const uint64_t mask1
;
855 const uint64_t mask2
;
857 inline omp_mask (omp_mask1
);
858 inline omp_mask (omp_mask2
);
859 inline omp_mask (uint64_t, uint64_t);
860 inline omp_mask
operator| (omp_mask1
) const;
861 inline omp_mask
operator| (omp_mask2
) const;
862 inline omp_mask
operator| (omp_mask
) const;
863 inline omp_mask
operator& (const omp_inv_mask
&) const;
864 inline bool operator& (omp_mask1
) const;
865 inline bool operator& (omp_mask2
) const;
866 inline omp_inv_mask
operator~ () const;
869 struct omp_inv_mask
: public omp_mask
{
870 inline omp_inv_mask (const omp_mask
&);
873 omp_mask::omp_mask () : mask1 (0), mask2 (0)
877 omp_mask::omp_mask (omp_mask1 m
) : mask1 (((uint64_t) 1) << m
), mask2 (0)
881 omp_mask::omp_mask (omp_mask2 m
) : mask1 (0), mask2 (((uint64_t) 1) << m
)
885 omp_mask::omp_mask (uint64_t m1
, uint64_t m2
) : mask1 (m1
), mask2 (m2
)
890 omp_mask::operator| (omp_mask1 m
) const
892 return omp_mask (mask1
| (((uint64_t) 1) << m
), mask2
);
896 omp_mask::operator| (omp_mask2 m
) const
898 return omp_mask (mask1
, mask2
| (((uint64_t) 1) << m
));
902 omp_mask::operator| (omp_mask m
) const
904 return omp_mask (mask1
| m
.mask1
, mask2
| m
.mask2
);
908 omp_mask::operator& (const omp_inv_mask
&m
) const
910 return omp_mask (mask1
& ~m
.mask1
, mask2
& ~m
.mask2
);
914 omp_mask::operator& (omp_mask1 m
) const
916 return (mask1
& (((uint64_t) 1) << m
)) != 0;
920 omp_mask::operator& (omp_mask2 m
) const
922 return (mask2
& (((uint64_t) 1) << m
)) != 0;
926 omp_mask::operator~ () const
928 return omp_inv_mask (*this);
931 omp_inv_mask::omp_inv_mask (const omp_mask
&m
) : omp_mask (m
)
935 /* Helper function for OpenACC and OpenMP clauses involving memory
939 gfc_match_omp_map_clause (gfc_omp_namelist
**list
, gfc_omp_map_op map_op
,
940 bool allow_common
, bool allow_derived
)
942 gfc_omp_namelist
**head
= NULL
;
943 if (gfc_match_omp_variable_list ("", list
, allow_common
, NULL
, &head
, true,
948 for (n
= *head
; n
; n
= n
->next
)
949 n
->u
.map_op
= map_op
;
956 /* Match OpenMP and OpenACC directive clauses. MASK is a bitmask of
957 clauses that are allowed for a particular directive. */
960 gfc_match_omp_clauses (gfc_omp_clauses
**cp
, const omp_mask mask
,
961 bool first
= true, bool needs_space
= true,
962 bool openacc
= false)
964 gfc_omp_clauses
*c
= gfc_get_omp_clauses ();
966 /* Determine whether we're dealing with an OpenACC directive that permits
967 derived type member accesses. This in particular disallows
968 "!$acc declare" from using such accesses, because it's not clear if/how
970 bool allow_derived
= (openacc
971 && ((mask
& OMP_CLAUSE_ATTACH
)
972 || (mask
& OMP_CLAUSE_DETACH
)
973 || (mask
& OMP_CLAUSE_HOST_SELF
)));
975 gcc_checking_assert (OMP_MASK1_LAST
<= 64 && OMP_MASK2_LAST
<= 64);
979 if ((first
|| gfc_match_char (',') != MATCH_YES
)
980 && (needs_space
&& gfc_match_space () != MATCH_YES
))
984 gfc_gobble_whitespace ();
986 gfc_omp_namelist
**head
;
987 old_loc
= gfc_current_locus
;
988 char pc
= gfc_peek_ascii_char ();
994 if ((mask
& OMP_CLAUSE_ALIGNED
)
995 && gfc_match_omp_variable_list ("aligned (",
996 &c
->lists
[OMP_LIST_ALIGNED
],
1000 gfc_expr
*alignment
= NULL
;
1001 gfc_omp_namelist
*n
;
1003 if (end_colon
&& gfc_match (" %e )", &alignment
) != MATCH_YES
)
1005 gfc_free_omp_namelist (*head
);
1006 gfc_current_locus
= old_loc
;
1010 for (n
= *head
; n
; n
= n
->next
)
1011 if (n
->next
&& alignment
)
1012 n
->expr
= gfc_copy_expr (alignment
);
1014 n
->expr
= alignment
;
1017 if ((mask
& OMP_CLAUSE_ASYNC
)
1019 && gfc_match ("async") == MATCH_YES
)
1022 match m
= gfc_match (" ( %e )", &c
->async_expr
);
1023 if (m
== MATCH_ERROR
)
1025 gfc_current_locus
= old_loc
;
1028 else if (m
== MATCH_NO
)
1031 = gfc_get_constant_expr (BT_INTEGER
,
1032 gfc_default_integer_kind
,
1033 &gfc_current_locus
);
1034 mpz_set_si (c
->async_expr
->value
.integer
, GOMP_ASYNC_NOVAL
);
1039 if ((mask
& OMP_CLAUSE_AUTO
)
1041 && gfc_match ("auto") == MATCH_YES
)
1047 if ((mask
& OMP_CLAUSE_ATTACH
)
1048 && gfc_match ("attach ( ") == MATCH_YES
1049 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1050 OMP_MAP_ATTACH
, false,
1055 if ((mask
& OMP_CLAUSE_COLLAPSE
)
1058 gfc_expr
*cexpr
= NULL
;
1059 match m
= gfc_match ("collapse ( %e )", &cexpr
);
1064 if (gfc_extract_int (cexpr
, &collapse
, -1))
1066 else if (collapse
<= 0)
1068 gfc_error_now ("COLLAPSE clause argument not"
1069 " constant positive integer at %C");
1072 c
->collapse
= collapse
;
1073 gfc_free_expr (cexpr
);
1077 if ((mask
& OMP_CLAUSE_COPY
)
1078 && gfc_match ("copy ( ") == MATCH_YES
1079 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1080 OMP_MAP_TOFROM
, true,
1083 if (mask
& OMP_CLAUSE_COPYIN
)
1087 if (gfc_match ("copyin ( ") == MATCH_YES
1088 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1093 else if (gfc_match_omp_variable_list ("copyin (",
1094 &c
->lists
[OMP_LIST_COPYIN
],
1098 if ((mask
& OMP_CLAUSE_COPYOUT
)
1099 && gfc_match ("copyout ( ") == MATCH_YES
1100 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1101 OMP_MAP_FROM
, true, allow_derived
))
1103 if ((mask
& OMP_CLAUSE_COPYPRIVATE
)
1104 && gfc_match_omp_variable_list ("copyprivate (",
1105 &c
->lists
[OMP_LIST_COPYPRIVATE
],
1108 if ((mask
& OMP_CLAUSE_CREATE
)
1109 && gfc_match ("create ( ") == MATCH_YES
1110 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1111 OMP_MAP_ALLOC
, true, allow_derived
))
1115 if ((mask
& OMP_CLAUSE_DEFAULT
)
1116 && c
->default_sharing
== OMP_DEFAULT_UNKNOWN
)
1118 if (gfc_match ("default ( none )") == MATCH_YES
)
1119 c
->default_sharing
= OMP_DEFAULT_NONE
;
1122 if (gfc_match ("default ( present )") == MATCH_YES
)
1123 c
->default_sharing
= OMP_DEFAULT_PRESENT
;
1127 if (gfc_match ("default ( firstprivate )") == MATCH_YES
)
1128 c
->default_sharing
= OMP_DEFAULT_FIRSTPRIVATE
;
1129 else if (gfc_match ("default ( private )") == MATCH_YES
)
1130 c
->default_sharing
= OMP_DEFAULT_PRIVATE
;
1131 else if (gfc_match ("default ( shared )") == MATCH_YES
)
1132 c
->default_sharing
= OMP_DEFAULT_SHARED
;
1134 if (c
->default_sharing
!= OMP_DEFAULT_UNKNOWN
)
1137 if ((mask
& OMP_CLAUSE_DEFAULTMAP
)
1139 && gfc_match ("defaultmap ( tofrom : scalar )") == MATCH_YES
)
1141 c
->defaultmap
= true;
1144 if ((mask
& OMP_CLAUSE_DELETE
)
1145 && gfc_match ("delete ( ") == MATCH_YES
1146 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1147 OMP_MAP_RELEASE
, true,
1150 if ((mask
& OMP_CLAUSE_DEPEND
)
1151 && gfc_match ("depend ( ") == MATCH_YES
)
1153 match m
= MATCH_YES
;
1154 gfc_omp_depend_op depend_op
= OMP_DEPEND_OUT
;
1155 if (gfc_match ("inout") == MATCH_YES
)
1156 depend_op
= OMP_DEPEND_INOUT
;
1157 else if (gfc_match ("in") == MATCH_YES
)
1158 depend_op
= OMP_DEPEND_IN
;
1159 else if (gfc_match ("out") == MATCH_YES
)
1160 depend_op
= OMP_DEPEND_OUT
;
1161 else if (!c
->depend_source
1162 && gfc_match ("source )") == MATCH_YES
)
1164 c
->depend_source
= true;
1167 else if (gfc_match ("sink : ") == MATCH_YES
)
1169 if (gfc_match_omp_depend_sink (&c
->lists
[OMP_LIST_DEPEND
])
1178 && gfc_match_omp_variable_list (" : ",
1179 &c
->lists
[OMP_LIST_DEPEND
],
1183 gfc_omp_namelist
*n
;
1184 for (n
= *head
; n
; n
= n
->next
)
1185 n
->u
.depend_op
= depend_op
;
1189 gfc_current_locus
= old_loc
;
1191 if ((mask
& OMP_CLAUSE_DETACH
)
1192 && gfc_match ("detach ( ") == MATCH_YES
1193 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1194 OMP_MAP_DETACH
, false,
1197 if ((mask
& OMP_CLAUSE_DEVICE
)
1199 && c
->device
== NULL
1200 && gfc_match ("device ( %e )", &c
->device
) == MATCH_YES
)
1202 if ((mask
& OMP_CLAUSE_DEVICE
)
1204 && gfc_match ("device ( ") == MATCH_YES
1205 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1206 OMP_MAP_FORCE_TO
, true,
1209 if ((mask
& OMP_CLAUSE_DEVICEPTR
)
1210 && gfc_match ("deviceptr ( ") == MATCH_YES
1211 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1212 OMP_MAP_FORCE_DEVICEPTR
, false,
1215 if ((mask
& OMP_CLAUSE_DEVICE_RESIDENT
)
1216 && gfc_match_omp_variable_list
1217 ("device_resident (",
1218 &c
->lists
[OMP_LIST_DEVICE_RESIDENT
], true) == MATCH_YES
)
1220 if ((mask
& OMP_CLAUSE_DIST_SCHEDULE
)
1221 && c
->dist_sched_kind
== OMP_SCHED_NONE
1222 && gfc_match ("dist_schedule ( static") == MATCH_YES
)
1225 c
->dist_sched_kind
= OMP_SCHED_STATIC
;
1226 m
= gfc_match (" , %e )", &c
->dist_chunk_size
);
1228 m
= gfc_match_char (')');
1231 c
->dist_sched_kind
= OMP_SCHED_NONE
;
1232 gfc_current_locus
= old_loc
;
1239 if ((mask
& OMP_CLAUSE_FINAL
)
1240 && c
->final_expr
== NULL
1241 && gfc_match ("final ( %e )", &c
->final_expr
) == MATCH_YES
)
1243 if ((mask
& OMP_CLAUSE_FINALIZE
)
1245 && gfc_match ("finalize") == MATCH_YES
)
1251 if ((mask
& OMP_CLAUSE_FIRSTPRIVATE
)
1252 && gfc_match_omp_variable_list ("firstprivate (",
1253 &c
->lists
[OMP_LIST_FIRSTPRIVATE
],
1256 if ((mask
& OMP_CLAUSE_FROM
)
1257 && gfc_match_omp_variable_list ("from (",
1258 &c
->lists
[OMP_LIST_FROM
], false,
1259 NULL
, &head
, true) == MATCH_YES
)
1263 if ((mask
& OMP_CLAUSE_GANG
)
1265 && gfc_match ("gang") == MATCH_YES
)
1268 match m
= match_oacc_clause_gwv (c
, GOMP_DIM_GANG
);
1269 if (m
== MATCH_ERROR
)
1271 gfc_current_locus
= old_loc
;
1274 else if (m
== MATCH_NO
)
1278 if ((mask
& OMP_CLAUSE_GRAINSIZE
)
1279 && c
->grainsize
== NULL
1280 && gfc_match ("grainsize ( %e )", &c
->grainsize
) == MATCH_YES
)
1284 if ((mask
& OMP_CLAUSE_HINT
)
1286 && gfc_match ("hint ( %e )", &c
->hint
) == MATCH_YES
)
1288 if ((mask
& OMP_CLAUSE_HOST_SELF
)
1289 && gfc_match ("host ( ") == MATCH_YES
1290 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1291 OMP_MAP_FORCE_FROM
, true,
1296 if ((mask
& OMP_CLAUSE_IF
)
1297 && c
->if_expr
== NULL
1298 && gfc_match ("if ( ") == MATCH_YES
)
1300 if (gfc_match ("%e )", &c
->if_expr
) == MATCH_YES
)
1304 /* This should match the enum gfc_omp_if_kind order. */
1305 static const char *ifs
[OMP_IF_LAST
] = {
1310 " target data : %e )",
1311 " target update : %e )",
1312 " target enter data : %e )",
1313 " target exit data : %e )" };
1315 for (i
= 0; i
< OMP_IF_LAST
; i
++)
1316 if (c
->if_exprs
[i
] == NULL
1317 && gfc_match (ifs
[i
], &c
->if_exprs
[i
]) == MATCH_YES
)
1319 if (i
< OMP_IF_LAST
)
1322 gfc_current_locus
= old_loc
;
1324 if ((mask
& OMP_CLAUSE_IF_PRESENT
)
1326 && gfc_match ("if_present") == MATCH_YES
)
1328 c
->if_present
= true;
1332 if ((mask
& OMP_CLAUSE_INBRANCH
)
1335 && gfc_match ("inbranch") == MATCH_YES
)
1337 c
->inbranch
= needs_space
= true;
1340 if ((mask
& OMP_CLAUSE_INDEPENDENT
)
1342 && gfc_match ("independent") == MATCH_YES
)
1344 c
->independent
= true;
1348 if ((mask
& OMP_CLAUSE_IS_DEVICE_PTR
)
1349 && gfc_match_omp_variable_list
1351 &c
->lists
[OMP_LIST_IS_DEVICE_PTR
], false) == MATCH_YES
)
1355 if ((mask
& OMP_CLAUSE_LASTPRIVATE
)
1356 && gfc_match_omp_variable_list ("lastprivate (",
1357 &c
->lists
[OMP_LIST_LASTPRIVATE
],
1362 if ((mask
& OMP_CLAUSE_LINEAR
)
1363 && gfc_match ("linear (") == MATCH_YES
)
1365 gfc_omp_linear_op linear_op
= OMP_LINEAR_DEFAULT
;
1366 gfc_expr
*step
= NULL
;
1368 if (gfc_match_omp_variable_list (" ref (",
1369 &c
->lists
[OMP_LIST_LINEAR
],
1372 linear_op
= OMP_LINEAR_REF
;
1373 else if (gfc_match_omp_variable_list (" val (",
1374 &c
->lists
[OMP_LIST_LINEAR
],
1377 linear_op
= OMP_LINEAR_VAL
;
1378 else if (gfc_match_omp_variable_list (" uval (",
1379 &c
->lists
[OMP_LIST_LINEAR
],
1382 linear_op
= OMP_LINEAR_UVAL
;
1383 else if (gfc_match_omp_variable_list ("",
1384 &c
->lists
[OMP_LIST_LINEAR
],
1385 false, &end_colon
, &head
)
1387 linear_op
= OMP_LINEAR_DEFAULT
;
1390 gfc_current_locus
= old_loc
;
1393 if (linear_op
!= OMP_LINEAR_DEFAULT
)
1395 if (gfc_match (" :") == MATCH_YES
)
1397 else if (gfc_match (" )") != MATCH_YES
)
1399 gfc_free_omp_namelist (*head
);
1400 gfc_current_locus
= old_loc
;
1405 if (end_colon
&& gfc_match (" %e )", &step
) != MATCH_YES
)
1407 gfc_free_omp_namelist (*head
);
1408 gfc_current_locus
= old_loc
;
1412 else if (!end_colon
)
1414 step
= gfc_get_constant_expr (BT_INTEGER
,
1415 gfc_default_integer_kind
,
1417 mpz_set_si (step
->value
.integer
, 1);
1419 (*head
)->expr
= step
;
1420 if (linear_op
!= OMP_LINEAR_DEFAULT
)
1421 for (gfc_omp_namelist
*n
= *head
; n
; n
= n
->next
)
1422 n
->u
.linear_op
= linear_op
;
1425 if ((mask
& OMP_CLAUSE_LINK
)
1427 && (gfc_match_oacc_clause_link ("link (",
1428 &c
->lists
[OMP_LIST_LINK
])
1431 else if ((mask
& OMP_CLAUSE_LINK
)
1433 && (gfc_match_omp_to_link ("link (",
1434 &c
->lists
[OMP_LIST_LINK
])
1439 if ((mask
& OMP_CLAUSE_MAP
)
1440 && gfc_match ("map ( ") == MATCH_YES
)
1442 locus old_loc2
= gfc_current_locus
;
1443 bool always
= false;
1444 gfc_omp_map_op map_op
= OMP_MAP_TOFROM
;
1445 if (gfc_match ("always , ") == MATCH_YES
)
1447 if (gfc_match ("alloc : ") == MATCH_YES
)
1448 map_op
= OMP_MAP_ALLOC
;
1449 else if (gfc_match ("tofrom : ") == MATCH_YES
)
1450 map_op
= always
? OMP_MAP_ALWAYS_TOFROM
: OMP_MAP_TOFROM
;
1451 else if (gfc_match ("to : ") == MATCH_YES
)
1452 map_op
= always
? OMP_MAP_ALWAYS_TO
: OMP_MAP_TO
;
1453 else if (gfc_match ("from : ") == MATCH_YES
)
1454 map_op
= always
? OMP_MAP_ALWAYS_FROM
: OMP_MAP_FROM
;
1455 else if (gfc_match ("release : ") == MATCH_YES
)
1456 map_op
= OMP_MAP_RELEASE
;
1457 else if (gfc_match ("delete : ") == MATCH_YES
)
1458 map_op
= OMP_MAP_DELETE
;
1461 gfc_current_locus
= old_loc2
;
1465 if (gfc_match_omp_variable_list ("", &c
->lists
[OMP_LIST_MAP
],
1469 gfc_omp_namelist
*n
;
1470 for (n
= *head
; n
; n
= n
->next
)
1471 n
->u
.map_op
= map_op
;
1475 gfc_current_locus
= old_loc
;
1477 if ((mask
& OMP_CLAUSE_MERGEABLE
) && !c
->mergeable
1478 && gfc_match ("mergeable") == MATCH_YES
)
1480 c
->mergeable
= needs_space
= true;
1485 if ((mask
& OMP_CLAUSE_NO_CREATE
)
1486 && gfc_match ("no_create ( ") == MATCH_YES
1487 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1488 OMP_MAP_IF_PRESENT
, true,
1491 if ((mask
& OMP_CLAUSE_NOGROUP
)
1493 && gfc_match ("nogroup") == MATCH_YES
)
1495 c
->nogroup
= needs_space
= true;
1498 if ((mask
& OMP_CLAUSE_NOTINBRANCH
)
1501 && gfc_match ("notinbranch") == MATCH_YES
)
1503 c
->notinbranch
= needs_space
= true;
1506 if ((mask
& OMP_CLAUSE_NOWAIT
)
1508 && gfc_match ("nowait") == MATCH_YES
)
1510 c
->nowait
= needs_space
= true;
1513 if ((mask
& OMP_CLAUSE_NUM_GANGS
)
1514 && c
->num_gangs_expr
== NULL
1515 && gfc_match ("num_gangs ( %e )",
1516 &c
->num_gangs_expr
) == MATCH_YES
)
1518 if ((mask
& OMP_CLAUSE_NUM_TASKS
)
1519 && c
->num_tasks
== NULL
1520 && gfc_match ("num_tasks ( %e )", &c
->num_tasks
) == MATCH_YES
)
1522 if ((mask
& OMP_CLAUSE_NUM_TEAMS
)
1523 && c
->num_teams
== NULL
1524 && gfc_match ("num_teams ( %e )", &c
->num_teams
) == MATCH_YES
)
1526 if ((mask
& OMP_CLAUSE_NUM_THREADS
)
1527 && c
->num_threads
== NULL
1528 && (gfc_match ("num_threads ( %e )", &c
->num_threads
)
1531 if ((mask
& OMP_CLAUSE_NUM_WORKERS
)
1532 && c
->num_workers_expr
== NULL
1533 && gfc_match ("num_workers ( %e )",
1534 &c
->num_workers_expr
) == MATCH_YES
)
1538 if ((mask
& OMP_CLAUSE_ORDERED
)
1540 && gfc_match ("ordered") == MATCH_YES
)
1542 gfc_expr
*cexpr
= NULL
;
1543 match m
= gfc_match (" ( %e )", &cexpr
);
1549 if (gfc_extract_int (cexpr
, &ordered
, -1))
1551 else if (ordered
<= 0)
1553 gfc_error_now ("ORDERED clause argument not"
1554 " constant positive integer at %C");
1557 c
->orderedc
= ordered
;
1558 gfc_free_expr (cexpr
);
1567 if ((mask
& OMP_CLAUSE_COPY
)
1568 && gfc_match ("pcopy ( ") == MATCH_YES
1569 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1570 OMP_MAP_TOFROM
, true, allow_derived
))
1572 if ((mask
& OMP_CLAUSE_COPYIN
)
1573 && gfc_match ("pcopyin ( ") == MATCH_YES
1574 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1575 OMP_MAP_TO
, true, allow_derived
))
1577 if ((mask
& OMP_CLAUSE_COPYOUT
)
1578 && gfc_match ("pcopyout ( ") == MATCH_YES
1579 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1580 OMP_MAP_FROM
, true, allow_derived
))
1582 if ((mask
& OMP_CLAUSE_CREATE
)
1583 && gfc_match ("pcreate ( ") == MATCH_YES
1584 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1585 OMP_MAP_ALLOC
, true, allow_derived
))
1587 if ((mask
& OMP_CLAUSE_PRESENT
)
1588 && gfc_match ("present ( ") == MATCH_YES
1589 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1590 OMP_MAP_FORCE_PRESENT
, false,
1593 if ((mask
& OMP_CLAUSE_COPY
)
1594 && gfc_match ("present_or_copy ( ") == MATCH_YES
1595 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1596 OMP_MAP_TOFROM
, true,
1599 if ((mask
& OMP_CLAUSE_COPYIN
)
1600 && gfc_match ("present_or_copyin ( ") == MATCH_YES
1601 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1602 OMP_MAP_TO
, true, allow_derived
))
1604 if ((mask
& OMP_CLAUSE_COPYOUT
)
1605 && gfc_match ("present_or_copyout ( ") == MATCH_YES
1606 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1607 OMP_MAP_FROM
, true, allow_derived
))
1609 if ((mask
& OMP_CLAUSE_CREATE
)
1610 && gfc_match ("present_or_create ( ") == MATCH_YES
1611 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1612 OMP_MAP_ALLOC
, true, allow_derived
))
1614 if ((mask
& OMP_CLAUSE_PRIORITY
)
1615 && c
->priority
== NULL
1616 && gfc_match ("priority ( %e )", &c
->priority
) == MATCH_YES
)
1618 if ((mask
& OMP_CLAUSE_PRIVATE
)
1619 && gfc_match_omp_variable_list ("private (",
1620 &c
->lists
[OMP_LIST_PRIVATE
],
1623 if ((mask
& OMP_CLAUSE_PROC_BIND
)
1624 && c
->proc_bind
== OMP_PROC_BIND_UNKNOWN
)
1626 if (gfc_match ("proc_bind ( master )") == MATCH_YES
)
1627 c
->proc_bind
= OMP_PROC_BIND_MASTER
;
1628 else if (gfc_match ("proc_bind ( spread )") == MATCH_YES
)
1629 c
->proc_bind
= OMP_PROC_BIND_SPREAD
;
1630 else if (gfc_match ("proc_bind ( close )") == MATCH_YES
)
1631 c
->proc_bind
= OMP_PROC_BIND_CLOSE
;
1632 if (c
->proc_bind
!= OMP_PROC_BIND_UNKNOWN
)
1637 if ((mask
& OMP_CLAUSE_REDUCTION
)
1638 && gfc_match ("reduction ( ") == MATCH_YES
)
1640 gfc_omp_reduction_op rop
= OMP_REDUCTION_NONE
;
1641 char buffer
[GFC_MAX_SYMBOL_LEN
+ 3];
1642 if (gfc_match_char ('+') == MATCH_YES
)
1643 rop
= OMP_REDUCTION_PLUS
;
1644 else if (gfc_match_char ('*') == MATCH_YES
)
1645 rop
= OMP_REDUCTION_TIMES
;
1646 else if (gfc_match_char ('-') == MATCH_YES
)
1647 rop
= OMP_REDUCTION_MINUS
;
1648 else if (gfc_match (".and.") == MATCH_YES
)
1649 rop
= OMP_REDUCTION_AND
;
1650 else if (gfc_match (".or.") == MATCH_YES
)
1651 rop
= OMP_REDUCTION_OR
;
1652 else if (gfc_match (".eqv.") == MATCH_YES
)
1653 rop
= OMP_REDUCTION_EQV
;
1654 else if (gfc_match (".neqv.") == MATCH_YES
)
1655 rop
= OMP_REDUCTION_NEQV
;
1656 if (rop
!= OMP_REDUCTION_NONE
)
1657 snprintf (buffer
, sizeof buffer
, "operator %s",
1658 gfc_op2string ((gfc_intrinsic_op
) rop
));
1659 else if (gfc_match_defined_op_name (buffer
+ 1, 1) == MATCH_YES
)
1662 strcat (buffer
, ".");
1664 else if (gfc_match_name (buffer
) == MATCH_YES
)
1667 const char *n
= buffer
;
1669 gfc_find_symbol (buffer
, NULL
, 1, &sym
);
1672 if (sym
->attr
.intrinsic
)
1674 else if ((sym
->attr
.flavor
!= FL_UNKNOWN
1675 && sym
->attr
.flavor
!= FL_PROCEDURE
)
1676 || sym
->attr
.external
1677 || sym
->attr
.generic
1681 || sym
->attr
.subroutine
1682 || sym
->attr
.pointer
1684 || sym
->attr
.cray_pointer
1685 || sym
->attr
.cray_pointee
1686 || (sym
->attr
.proc
!= PROC_UNKNOWN
1687 && sym
->attr
.proc
!= PROC_INTRINSIC
)
1688 || sym
->attr
.if_source
!= IFSRC_UNKNOWN
1689 || sym
== sym
->ns
->proc_name
)
1698 rop
= OMP_REDUCTION_NONE
;
1699 else if (strcmp (n
, "max") == 0)
1700 rop
= OMP_REDUCTION_MAX
;
1701 else if (strcmp (n
, "min") == 0)
1702 rop
= OMP_REDUCTION_MIN
;
1703 else if (strcmp (n
, "iand") == 0)
1704 rop
= OMP_REDUCTION_IAND
;
1705 else if (strcmp (n
, "ior") == 0)
1706 rop
= OMP_REDUCTION_IOR
;
1707 else if (strcmp (n
, "ieor") == 0)
1708 rop
= OMP_REDUCTION_IEOR
;
1709 if (rop
!= OMP_REDUCTION_NONE
1711 && ! sym
->attr
.intrinsic
1712 && ! sym
->attr
.use_assoc
1713 && ((sym
->attr
.flavor
== FL_UNKNOWN
1714 && !gfc_add_flavor (&sym
->attr
, FL_PROCEDURE
,
1716 || !gfc_add_intrinsic (&sym
->attr
, NULL
)))
1717 rop
= OMP_REDUCTION_NONE
;
1723 ? gfc_find_omp_udr (gfc_current_ns
, buffer
, NULL
) : NULL
);
1724 gfc_omp_namelist
**head
= NULL
;
1725 if (rop
== OMP_REDUCTION_NONE
&& udr
)
1726 rop
= OMP_REDUCTION_USER
;
1728 if (gfc_match_omp_variable_list (" :",
1729 &c
->lists
[OMP_LIST_REDUCTION
],
1730 false, NULL
, &head
, openacc
,
1731 allow_derived
) == MATCH_YES
)
1733 gfc_omp_namelist
*n
;
1734 if (rop
== OMP_REDUCTION_NONE
)
1738 gfc_error_now ("!$OMP DECLARE REDUCTION %s not found "
1739 "at %L", buffer
, &old_loc
);
1740 gfc_free_omp_namelist (n
);
1743 for (n
= *head
; n
; n
= n
->next
)
1745 n
->u
.reduction_op
= rop
;
1748 n
->udr
= gfc_get_omp_namelist_udr ();
1755 gfc_current_locus
= old_loc
;
1759 if ((mask
& OMP_CLAUSE_SAFELEN
)
1760 && c
->safelen_expr
== NULL
1761 && gfc_match ("safelen ( %e )", &c
->safelen_expr
) == MATCH_YES
)
1763 if ((mask
& OMP_CLAUSE_SCHEDULE
)
1764 && c
->sched_kind
== OMP_SCHED_NONE
1765 && gfc_match ("schedule ( ") == MATCH_YES
)
1768 locus old_loc2
= gfc_current_locus
;
1771 if (gfc_match ("simd") == MATCH_YES
)
1773 c
->sched_simd
= true;
1776 else if (gfc_match ("monotonic") == MATCH_YES
)
1778 c
->sched_monotonic
= true;
1781 else if (gfc_match ("nonmonotonic") == MATCH_YES
)
1783 c
->sched_nonmonotonic
= true;
1789 gfc_current_locus
= old_loc2
;
1793 && gfc_match (" , ") == MATCH_YES
)
1795 else if (gfc_match (" : ") == MATCH_YES
)
1797 gfc_current_locus
= old_loc2
;
1801 if (gfc_match ("static") == MATCH_YES
)
1802 c
->sched_kind
= OMP_SCHED_STATIC
;
1803 else if (gfc_match ("dynamic") == MATCH_YES
)
1804 c
->sched_kind
= OMP_SCHED_DYNAMIC
;
1805 else if (gfc_match ("guided") == MATCH_YES
)
1806 c
->sched_kind
= OMP_SCHED_GUIDED
;
1807 else if (gfc_match ("runtime") == MATCH_YES
)
1808 c
->sched_kind
= OMP_SCHED_RUNTIME
;
1809 else if (gfc_match ("auto") == MATCH_YES
)
1810 c
->sched_kind
= OMP_SCHED_AUTO
;
1811 if (c
->sched_kind
!= OMP_SCHED_NONE
)
1814 if (c
->sched_kind
!= OMP_SCHED_RUNTIME
1815 && c
->sched_kind
!= OMP_SCHED_AUTO
)
1816 m
= gfc_match (" , %e )", &c
->chunk_size
);
1818 m
= gfc_match_char (')');
1820 c
->sched_kind
= OMP_SCHED_NONE
;
1822 if (c
->sched_kind
!= OMP_SCHED_NONE
)
1825 gfc_current_locus
= old_loc
;
1827 if ((mask
& OMP_CLAUSE_HOST_SELF
)
1828 && gfc_match ("self ( ") == MATCH_YES
1829 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1830 OMP_MAP_FORCE_FROM
, true,
1833 if ((mask
& OMP_CLAUSE_SEQ
)
1835 && gfc_match ("seq") == MATCH_YES
)
1841 if ((mask
& OMP_CLAUSE_SHARED
)
1842 && gfc_match_omp_variable_list ("shared (",
1843 &c
->lists
[OMP_LIST_SHARED
],
1846 if ((mask
& OMP_CLAUSE_SIMDLEN
)
1847 && c
->simdlen_expr
== NULL
1848 && gfc_match ("simdlen ( %e )", &c
->simdlen_expr
) == MATCH_YES
)
1850 if ((mask
& OMP_CLAUSE_SIMD
)
1852 && gfc_match ("simd") == MATCH_YES
)
1854 c
->simd
= needs_space
= true;
1859 if ((mask
& OMP_CLAUSE_THREAD_LIMIT
)
1860 && c
->thread_limit
== NULL
1861 && gfc_match ("thread_limit ( %e )",
1862 &c
->thread_limit
) == MATCH_YES
)
1864 if ((mask
& OMP_CLAUSE_THREADS
)
1866 && gfc_match ("threads") == MATCH_YES
)
1868 c
->threads
= needs_space
= true;
1871 if ((mask
& OMP_CLAUSE_TILE
)
1873 && match_oacc_expr_list ("tile (", &c
->tile_list
,
1876 if ((mask
& OMP_CLAUSE_TO
) && (mask
& OMP_CLAUSE_LINK
))
1878 if (gfc_match_omp_to_link ("to (", &c
->lists
[OMP_LIST_TO
])
1882 else if ((mask
& OMP_CLAUSE_TO
)
1883 && gfc_match_omp_variable_list ("to (",
1884 &c
->lists
[OMP_LIST_TO
], false,
1885 NULL
, &head
, true) == MATCH_YES
)
1889 if ((mask
& OMP_CLAUSE_UNIFORM
)
1890 && gfc_match_omp_variable_list ("uniform (",
1891 &c
->lists
[OMP_LIST_UNIFORM
],
1892 false) == MATCH_YES
)
1894 if ((mask
& OMP_CLAUSE_UNTIED
)
1896 && gfc_match ("untied") == MATCH_YES
)
1898 c
->untied
= needs_space
= true;
1901 if ((mask
& OMP_CLAUSE_USE_DEVICE
)
1902 && gfc_match_omp_variable_list ("use_device (",
1903 &c
->lists
[OMP_LIST_USE_DEVICE
],
1906 if ((mask
& OMP_CLAUSE_USE_DEVICE_PTR
)
1907 && gfc_match_omp_variable_list
1908 ("use_device_ptr (",
1909 &c
->lists
[OMP_LIST_USE_DEVICE_PTR
], false) == MATCH_YES
)
1911 if ((mask
& OMP_CLAUSE_USE_DEVICE_ADDR
)
1912 && gfc_match_omp_variable_list
1913 ("use_device_addr (",
1914 &c
->lists
[OMP_LIST_USE_DEVICE_ADDR
], false) == MATCH_YES
)
1918 /* VECTOR_LENGTH must be matched before VECTOR, because the latter
1919 doesn't unconditionally match '('. */
1920 if ((mask
& OMP_CLAUSE_VECTOR_LENGTH
)
1921 && c
->vector_length_expr
== NULL
1922 && (gfc_match ("vector_length ( %e )", &c
->vector_length_expr
)
1925 if ((mask
& OMP_CLAUSE_VECTOR
)
1927 && gfc_match ("vector") == MATCH_YES
)
1930 match m
= match_oacc_clause_gwv (c
, GOMP_DIM_VECTOR
);
1931 if (m
== MATCH_ERROR
)
1933 gfc_current_locus
= old_loc
;
1942 if ((mask
& OMP_CLAUSE_WAIT
)
1943 && gfc_match ("wait") == MATCH_YES
)
1945 match m
= match_oacc_expr_list (" (", &c
->wait_list
, false);
1946 if (m
== MATCH_ERROR
)
1948 gfc_current_locus
= old_loc
;
1951 else if (m
== MATCH_NO
)
1954 = gfc_get_constant_expr (BT_INTEGER
,
1955 gfc_default_integer_kind
,
1956 &gfc_current_locus
);
1957 mpz_set_si (expr
->value
.integer
, GOMP_ASYNC_NOVAL
);
1958 gfc_expr_list
**expr_list
= &c
->wait_list
;
1960 expr_list
= &(*expr_list
)->next
;
1961 *expr_list
= gfc_get_expr_list ();
1962 (*expr_list
)->expr
= expr
;
1967 if ((mask
& OMP_CLAUSE_WORKER
)
1969 && gfc_match ("worker") == MATCH_YES
)
1972 match m
= match_oacc_clause_gwv (c
, GOMP_DIM_WORKER
);
1973 if (m
== MATCH_ERROR
)
1975 gfc_current_locus
= old_loc
;
1978 else if (m
== MATCH_NO
)
1987 if (gfc_match_omp_eos () != MATCH_YES
)
1989 if (!gfc_error_flag_test ())
1990 gfc_error ("Failed to match clause at %C");
1991 gfc_free_omp_clauses (c
);
2000 #define OACC_PARALLEL_CLAUSES \
2001 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS \
2002 | OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_REDUCTION \
2003 | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
2004 | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT \
2005 | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
2006 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
2007 #define OACC_KERNELS_CLAUSES \
2008 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS \
2009 | OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_DEVICEPTR \
2010 | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
2011 | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT \
2012 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
2013 #define OACC_SERIAL_CLAUSES \
2014 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_REDUCTION \
2015 | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
2016 | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT \
2017 | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
2018 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
2019 #define OACC_DATA_CLAUSES \
2020 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_COPY \
2021 | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT | OMP_CLAUSE_CREATE \
2022 | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT | OMP_CLAUSE_ATTACH)
2023 #define OACC_LOOP_CLAUSES \
2024 (omp_mask (OMP_CLAUSE_COLLAPSE) | OMP_CLAUSE_GANG | OMP_CLAUSE_WORKER \
2025 | OMP_CLAUSE_VECTOR | OMP_CLAUSE_SEQ | OMP_CLAUSE_INDEPENDENT \
2026 | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_AUTO \
2028 #define OACC_PARALLEL_LOOP_CLAUSES \
2029 (OACC_LOOP_CLAUSES | OACC_PARALLEL_CLAUSES)
2030 #define OACC_KERNELS_LOOP_CLAUSES \
2031 (OACC_LOOP_CLAUSES | OACC_KERNELS_CLAUSES)
2032 #define OACC_SERIAL_LOOP_CLAUSES \
2033 (OACC_LOOP_CLAUSES | OACC_SERIAL_CLAUSES)
2034 #define OACC_HOST_DATA_CLAUSES \
2035 (omp_mask (OMP_CLAUSE_USE_DEVICE) \
2037 | OMP_CLAUSE_IF_PRESENT)
2038 #define OACC_DECLARE_CLAUSES \
2039 (omp_mask (OMP_CLAUSE_COPY) | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
2040 | OMP_CLAUSE_CREATE | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_DEVICE_RESIDENT \
2041 | OMP_CLAUSE_PRESENT \
2043 #define OACC_UPDATE_CLAUSES \
2044 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_HOST_SELF \
2045 | OMP_CLAUSE_DEVICE | OMP_CLAUSE_WAIT | OMP_CLAUSE_IF_PRESENT)
2046 #define OACC_ENTER_DATA_CLAUSES \
2047 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_WAIT \
2048 | OMP_CLAUSE_COPYIN | OMP_CLAUSE_CREATE | OMP_CLAUSE_ATTACH)
2049 #define OACC_EXIT_DATA_CLAUSES \
2050 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_WAIT \
2051 | OMP_CLAUSE_COPYOUT | OMP_CLAUSE_DELETE | OMP_CLAUSE_FINALIZE \
2052 | OMP_CLAUSE_DETACH)
2053 #define OACC_WAIT_CLAUSES \
2054 omp_mask (OMP_CLAUSE_ASYNC)
2055 #define OACC_ROUTINE_CLAUSES \
2056 (omp_mask (OMP_CLAUSE_GANG) | OMP_CLAUSE_WORKER | OMP_CLAUSE_VECTOR \
2061 match_acc (gfc_exec_op op
, const omp_mask mask
)
2064 if (gfc_match_omp_clauses (&c
, mask
, false, false, true) != MATCH_YES
)
2067 new_st
.ext
.omp_clauses
= c
;
2072 gfc_match_oacc_parallel_loop (void)
2074 return match_acc (EXEC_OACC_PARALLEL_LOOP
, OACC_PARALLEL_LOOP_CLAUSES
);
2079 gfc_match_oacc_parallel (void)
2081 return match_acc (EXEC_OACC_PARALLEL
, OACC_PARALLEL_CLAUSES
);
2086 gfc_match_oacc_kernels_loop (void)
2088 return match_acc (EXEC_OACC_KERNELS_LOOP
, OACC_KERNELS_LOOP_CLAUSES
);
2093 gfc_match_oacc_kernels (void)
2095 return match_acc (EXEC_OACC_KERNELS
, OACC_KERNELS_CLAUSES
);
2100 gfc_match_oacc_serial_loop (void)
2102 return match_acc (EXEC_OACC_SERIAL_LOOP
, OACC_SERIAL_LOOP_CLAUSES
);
2107 gfc_match_oacc_serial (void)
2109 return match_acc (EXEC_OACC_SERIAL
, OACC_SERIAL_CLAUSES
);
2114 gfc_match_oacc_data (void)
2116 return match_acc (EXEC_OACC_DATA
, OACC_DATA_CLAUSES
);
2121 gfc_match_oacc_host_data (void)
2123 return match_acc (EXEC_OACC_HOST_DATA
, OACC_HOST_DATA_CLAUSES
);
2128 gfc_match_oacc_loop (void)
2130 return match_acc (EXEC_OACC_LOOP
, OACC_LOOP_CLAUSES
);
2135 gfc_match_oacc_declare (void)
2138 gfc_omp_namelist
*n
;
2139 gfc_namespace
*ns
= gfc_current_ns
;
2140 gfc_oacc_declare
*new_oc
;
2141 bool module_var
= false;
2142 locus where
= gfc_current_locus
;
2144 if (gfc_match_omp_clauses (&c
, OACC_DECLARE_CLAUSES
, false, false, true)
2148 for (n
= c
->lists
[OMP_LIST_DEVICE_RESIDENT
]; n
!= NULL
; n
= n
->next
)
2149 n
->sym
->attr
.oacc_declare_device_resident
= 1;
2151 for (n
= c
->lists
[OMP_LIST_LINK
]; n
!= NULL
; n
= n
->next
)
2152 n
->sym
->attr
.oacc_declare_link
= 1;
2154 for (n
= c
->lists
[OMP_LIST_MAP
]; n
!= NULL
; n
= n
->next
)
2156 gfc_symbol
*s
= n
->sym
;
2158 if (s
->ns
->proc_name
&& s
->ns
->proc_name
->attr
.proc
== PROC_MODULE
)
2160 if (n
->u
.map_op
!= OMP_MAP_ALLOC
&& n
->u
.map_op
!= OMP_MAP_TO
)
2162 gfc_error ("Invalid clause in module with !$ACC DECLARE at %L",
2170 if (s
->attr
.use_assoc
)
2172 gfc_error ("Variable is USE-associated with !$ACC DECLARE at %L",
2177 if ((s
->attr
.dimension
|| s
->attr
.codimension
)
2178 && s
->attr
.dummy
&& s
->as
->type
!= AS_EXPLICIT
)
2180 gfc_error ("Assumed-size dummy array with !$ACC DECLARE at %L",
2185 switch (n
->u
.map_op
)
2187 case OMP_MAP_FORCE_ALLOC
:
2189 s
->attr
.oacc_declare_create
= 1;
2192 case OMP_MAP_FORCE_TO
:
2194 s
->attr
.oacc_declare_copyin
= 1;
2197 case OMP_MAP_FORCE_DEVICEPTR
:
2198 s
->attr
.oacc_declare_deviceptr
= 1;
2206 new_oc
= gfc_get_oacc_declare ();
2207 new_oc
->next
= ns
->oacc_declare
;
2208 new_oc
->module_var
= module_var
;
2209 new_oc
->clauses
= c
;
2210 new_oc
->loc
= gfc_current_locus
;
2211 ns
->oacc_declare
= new_oc
;
2218 gfc_match_oacc_update (void)
2221 locus here
= gfc_current_locus
;
2223 if (gfc_match_omp_clauses (&c
, OACC_UPDATE_CLAUSES
, false, false, true)
2227 if (!c
->lists
[OMP_LIST_MAP
])
2229 gfc_error ("%<acc update%> must contain at least one "
2230 "%<device%> or %<host%> or %<self%> clause at %L", &here
);
2234 new_st
.op
= EXEC_OACC_UPDATE
;
2235 new_st
.ext
.omp_clauses
= c
;
2241 gfc_match_oacc_enter_data (void)
2243 return match_acc (EXEC_OACC_ENTER_DATA
, OACC_ENTER_DATA_CLAUSES
);
2248 gfc_match_oacc_exit_data (void)
2250 return match_acc (EXEC_OACC_EXIT_DATA
, OACC_EXIT_DATA_CLAUSES
);
2255 gfc_match_oacc_wait (void)
2257 gfc_omp_clauses
*c
= gfc_get_omp_clauses ();
2258 gfc_expr_list
*wait_list
= NULL
, *el
;
2262 m
= match_oacc_expr_list (" (", &wait_list
, true);
2263 if (m
== MATCH_ERROR
)
2265 else if (m
== MATCH_YES
)
2268 if (gfc_match_omp_clauses (&c
, OACC_WAIT_CLAUSES
, space
, space
, true)
2273 for (el
= wait_list
; el
; el
= el
->next
)
2275 if (el
->expr
== NULL
)
2277 gfc_error ("Invalid argument to !$ACC WAIT at %C");
2281 if (!gfc_resolve_expr (el
->expr
)
2282 || el
->expr
->ts
.type
!= BT_INTEGER
|| el
->expr
->rank
!= 0)
2284 gfc_error ("WAIT clause at %L requires a scalar INTEGER expression",
2290 c
->wait_list
= wait_list
;
2291 new_st
.op
= EXEC_OACC_WAIT
;
2292 new_st
.ext
.omp_clauses
= c
;
2298 gfc_match_oacc_cache (void)
2300 gfc_omp_clauses
*c
= gfc_get_omp_clauses ();
2301 /* The OpenACC cache directive explicitly only allows "array elements or
2302 subarrays", which we're currently not checking here. Either check this
2303 after the call of gfc_match_omp_variable_list, or add something like a
2304 only_sections variant next to its allow_sections parameter. */
2305 match m
= gfc_match_omp_variable_list (" (",
2306 &c
->lists
[OMP_LIST_CACHE
], true,
2310 gfc_free_omp_clauses(c
);
2314 if (gfc_current_state() != COMP_DO
2315 && gfc_current_state() != COMP_DO_CONCURRENT
)
2317 gfc_error ("ACC CACHE directive must be inside of loop %C");
2318 gfc_free_omp_clauses(c
);
2322 new_st
.op
= EXEC_OACC_CACHE
;
2323 new_st
.ext
.omp_clauses
= c
;
2327 /* Determine the OpenACC 'routine' directive's level of parallelism. */
2329 static oacc_routine_lop
2330 gfc_oacc_routine_lop (gfc_omp_clauses
*clauses
)
2332 oacc_routine_lop ret
= OACC_ROUTINE_LOP_SEQ
;
2336 unsigned n_lop_clauses
= 0;
2341 ret
= OACC_ROUTINE_LOP_GANG
;
2343 if (clauses
->worker
)
2346 ret
= OACC_ROUTINE_LOP_WORKER
;
2348 if (clauses
->vector
)
2351 ret
= OACC_ROUTINE_LOP_VECTOR
;
2356 ret
= OACC_ROUTINE_LOP_SEQ
;
2359 if (n_lop_clauses
> 1)
2360 ret
= OACC_ROUTINE_LOP_ERROR
;
2367 gfc_match_oacc_routine (void)
2371 gfc_intrinsic_sym
*isym
= NULL
;
2372 gfc_symbol
*sym
= NULL
;
2373 gfc_omp_clauses
*c
= NULL
;
2374 gfc_oacc_routine_name
*n
= NULL
;
2375 oacc_routine_lop lop
= OACC_ROUTINE_LOP_NONE
;
2377 old_loc
= gfc_current_locus
;
2379 m
= gfc_match (" (");
2381 if (gfc_current_ns
->proc_name
2382 && gfc_current_ns
->proc_name
->attr
.if_source
== IFSRC_IFBODY
2385 gfc_error ("Only the !$ACC ROUTINE form without "
2386 "list is allowed in interface block at %C");
2392 char buffer
[GFC_MAX_SYMBOL_LEN
+ 1];
2394 m
= gfc_match_name (buffer
);
2397 gfc_symtree
*st
= NULL
;
2399 /* First look for an intrinsic symbol. */
2400 isym
= gfc_find_function (buffer
);
2402 isym
= gfc_find_subroutine (buffer
);
2403 /* If no intrinsic symbol found, search the current namespace. */
2405 st
= gfc_find_symtree (gfc_current_ns
->sym_root
, buffer
);
2409 /* If the name in a 'routine' directive refers to the containing
2410 subroutine or function, then make sure that we'll later handle
2411 this accordingly. */
2412 if (gfc_current_ns
->proc_name
!= NULL
2413 && strcmp (sym
->name
, gfc_current_ns
->proc_name
->name
) == 0)
2417 if (isym
== NULL
&& st
== NULL
)
2419 gfc_error ("Invalid NAME %qs in !$ACC ROUTINE ( NAME ) at %C",
2421 gfc_current_locus
= old_loc
;
2427 gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C");
2428 gfc_current_locus
= old_loc
;
2432 if (gfc_match_char (')') != MATCH_YES
)
2434 gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C, expecting"
2436 gfc_current_locus
= old_loc
;
2441 if (gfc_match_omp_eos () != MATCH_YES
2442 && (gfc_match_omp_clauses (&c
, OACC_ROUTINE_CLAUSES
, false, false, true)
2446 lop
= gfc_oacc_routine_lop (c
);
2447 if (lop
== OACC_ROUTINE_LOP_ERROR
)
2449 gfc_error ("Multiple loop axes specified for routine at %C");
2455 /* Diagnose any OpenACC 'routine' directive that doesn't match the
2456 (implicit) one with a 'seq' clause. */
2457 if (c
&& (c
->gang
|| c
->worker
|| c
->vector
))
2459 gfc_error ("Intrinsic symbol specified in !$ACC ROUTINE ( NAME )"
2460 " at %C marked with incompatible GANG, WORKER, or VECTOR"
2465 else if (sym
!= NULL
)
2469 /* For a repeated OpenACC 'routine' directive, diagnose if it doesn't
2470 match the first one. */
2471 for (gfc_oacc_routine_name
*n_p
= gfc_current_ns
->oacc_routine_names
;
2474 if (n_p
->sym
== sym
)
2477 if (lop
!= gfc_oacc_routine_lop (n_p
->clauses
))
2479 gfc_error ("!$ACC ROUTINE already applied at %C");
2486 sym
->attr
.oacc_routine_lop
= lop
;
2488 n
= gfc_get_oacc_routine_name ();
2491 n
->next
= gfc_current_ns
->oacc_routine_names
;
2493 gfc_current_ns
->oacc_routine_names
= n
;
2496 else if (gfc_current_ns
->proc_name
)
2498 /* For a repeated OpenACC 'routine' directive, diagnose if it doesn't
2499 match the first one. */
2500 oacc_routine_lop lop_p
= gfc_current_ns
->proc_name
->attr
.oacc_routine_lop
;
2501 if (lop_p
!= OACC_ROUTINE_LOP_NONE
2504 gfc_error ("!$ACC ROUTINE already applied at %C");
2508 if (!gfc_add_omp_declare_target (&gfc_current_ns
->proc_name
->attr
,
2509 gfc_current_ns
->proc_name
->name
,
2512 gfc_current_ns
->proc_name
->attr
.oacc_routine_lop
= lop
;
2515 /* Something has gone wrong, possibly a syntax error. */
2520 else if (gfc_current_ns
->oacc_routine
)
2521 gfc_current_ns
->oacc_routine_clauses
= c
;
2523 new_st
.op
= EXEC_OACC_ROUTINE
;
2524 new_st
.ext
.omp_clauses
= c
;
2528 gfc_current_locus
= old_loc
;
2533 #define OMP_PARALLEL_CLAUSES \
2534 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2535 | OMP_CLAUSE_SHARED | OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION \
2536 | OMP_CLAUSE_IF | OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT \
2537 | OMP_CLAUSE_PROC_BIND)
2538 #define OMP_DECLARE_SIMD_CLAUSES \
2539 (omp_mask (OMP_CLAUSE_SIMDLEN) | OMP_CLAUSE_LINEAR \
2540 | OMP_CLAUSE_UNIFORM | OMP_CLAUSE_ALIGNED | OMP_CLAUSE_INBRANCH \
2541 | OMP_CLAUSE_NOTINBRANCH)
2542 #define OMP_DO_CLAUSES \
2543 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2544 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION \
2545 | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED | OMP_CLAUSE_COLLAPSE \
2546 | OMP_CLAUSE_LINEAR)
2547 #define OMP_SECTIONS_CLAUSES \
2548 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2549 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION)
2550 #define OMP_SIMD_CLAUSES \
2551 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE \
2552 | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN \
2553 | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ALIGNED | OMP_CLAUSE_SIMDLEN)
2554 #define OMP_TASK_CLAUSES \
2555 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2556 | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF | OMP_CLAUSE_DEFAULT \
2557 | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL | OMP_CLAUSE_MERGEABLE \
2558 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_PRIORITY)
2559 #define OMP_TASKLOOP_CLAUSES \
2560 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2561 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF \
2562 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL \
2563 | OMP_CLAUSE_MERGEABLE | OMP_CLAUSE_PRIORITY | OMP_CLAUSE_GRAINSIZE \
2564 | OMP_CLAUSE_NUM_TASKS | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_NOGROUP)
2565 #define OMP_TARGET_CLAUSES \
2566 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
2567 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE \
2568 | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP \
2569 | OMP_CLAUSE_IS_DEVICE_PTR)
2570 #define OMP_TARGET_DATA_CLAUSES \
2571 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
2572 | OMP_CLAUSE_USE_DEVICE_PTR | OMP_CLAUSE_USE_DEVICE_ADDR)
2573 #define OMP_TARGET_ENTER_DATA_CLAUSES \
2574 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
2575 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
2576 #define OMP_TARGET_EXIT_DATA_CLAUSES \
2577 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
2578 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
2579 #define OMP_TARGET_UPDATE_CLAUSES \
2580 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_IF | OMP_CLAUSE_TO \
2581 | OMP_CLAUSE_FROM | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
2582 #define OMP_TEAMS_CLAUSES \
2583 (omp_mask (OMP_CLAUSE_NUM_TEAMS) | OMP_CLAUSE_THREAD_LIMIT \
2584 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
2585 | OMP_CLAUSE_SHARED | OMP_CLAUSE_REDUCTION)
2586 #define OMP_DISTRIBUTE_CLAUSES \
2587 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2588 | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_DIST_SCHEDULE)
2589 #define OMP_SINGLE_CLAUSES \
2590 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE)
2591 #define OMP_ORDERED_CLAUSES \
2592 (omp_mask (OMP_CLAUSE_THREADS) | OMP_CLAUSE_SIMD)
2593 #define OMP_DECLARE_TARGET_CLAUSES \
2594 (omp_mask (OMP_CLAUSE_TO) | OMP_CLAUSE_LINK)
2598 match_omp (gfc_exec_op op
, const omp_mask mask
)
2601 if (gfc_match_omp_clauses (&c
, mask
) != MATCH_YES
)
2604 new_st
.ext
.omp_clauses
= c
;
2610 gfc_match_omp_critical (void)
2612 char n
[GFC_MAX_SYMBOL_LEN
+1];
2613 gfc_omp_clauses
*c
= NULL
;
2615 if (gfc_match (" ( %n )", n
) != MATCH_YES
)
2618 if (gfc_match_omp_eos () != MATCH_YES
)
2620 gfc_error ("Unexpected junk after $OMP CRITICAL statement at %C");
2624 else if (gfc_match_omp_clauses (&c
, omp_mask (OMP_CLAUSE_HINT
)) != MATCH_YES
)
2627 new_st
.op
= EXEC_OMP_CRITICAL
;
2628 new_st
.ext
.omp_clauses
= c
;
2630 c
->critical_name
= xstrdup (n
);
2636 gfc_match_omp_end_critical (void)
2638 char n
[GFC_MAX_SYMBOL_LEN
+1];
2640 if (gfc_match (" ( %n )", n
) != MATCH_YES
)
2642 if (gfc_match_omp_eos () != MATCH_YES
)
2644 gfc_error ("Unexpected junk after $OMP CRITICAL statement at %C");
2648 new_st
.op
= EXEC_OMP_END_CRITICAL
;
2649 new_st
.ext
.omp_name
= n
[0] ? xstrdup (n
) : NULL
;
2655 gfc_match_omp_distribute (void)
2657 return match_omp (EXEC_OMP_DISTRIBUTE
, OMP_DISTRIBUTE_CLAUSES
);
2662 gfc_match_omp_distribute_parallel_do (void)
2664 return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO
,
2665 (OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
2667 & ~(omp_mask (OMP_CLAUSE_ORDERED
))
2668 & ~(omp_mask (OMP_CLAUSE_LINEAR
)));
2673 gfc_match_omp_distribute_parallel_do_simd (void)
2675 return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
,
2676 (OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
2677 | OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
)
2678 & ~(omp_mask (OMP_CLAUSE_ORDERED
)));
2683 gfc_match_omp_distribute_simd (void)
2685 return match_omp (EXEC_OMP_DISTRIBUTE_SIMD
,
2686 OMP_DISTRIBUTE_CLAUSES
| OMP_SIMD_CLAUSES
);
2691 gfc_match_omp_do (void)
2693 return match_omp (EXEC_OMP_DO
, OMP_DO_CLAUSES
);
2698 gfc_match_omp_do_simd (void)
2700 return match_omp (EXEC_OMP_DO_SIMD
, OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
);
2705 gfc_match_omp_flush (void)
2707 gfc_omp_namelist
*list
= NULL
;
2708 gfc_match_omp_variable_list (" (", &list
, true);
2709 if (gfc_match_omp_eos () != MATCH_YES
)
2711 gfc_error ("Unexpected junk after $OMP FLUSH statement at %C");
2712 gfc_free_omp_namelist (list
);
2715 new_st
.op
= EXEC_OMP_FLUSH
;
2716 new_st
.ext
.omp_namelist
= list
;
2722 gfc_match_omp_declare_simd (void)
2724 locus where
= gfc_current_locus
;
2725 gfc_symbol
*proc_name
;
2727 gfc_omp_declare_simd
*ods
;
2728 bool needs_space
= false;
2730 switch (gfc_match (" ( %s ) ", &proc_name
))
2732 case MATCH_YES
: break;
2733 case MATCH_NO
: proc_name
= NULL
; needs_space
= true; break;
2734 case MATCH_ERROR
: return MATCH_ERROR
;
2737 if (gfc_match_omp_clauses (&c
, OMP_DECLARE_SIMD_CLAUSES
, true,
2738 needs_space
) != MATCH_YES
)
2741 if (gfc_current_ns
->is_block_data
)
2743 gfc_free_omp_clauses (c
);
2747 ods
= gfc_get_omp_declare_simd ();
2749 ods
->proc_name
= proc_name
;
2751 ods
->next
= gfc_current_ns
->omp_declare_simd
;
2752 gfc_current_ns
->omp_declare_simd
= ods
;
2758 match_udr_expr (gfc_symtree
*omp_sym1
, gfc_symtree
*omp_sym2
)
2761 locus old_loc
= gfc_current_locus
;
2762 char sname
[GFC_MAX_SYMBOL_LEN
+ 1];
2764 gfc_namespace
*ns
= gfc_current_ns
;
2765 gfc_expr
*lvalue
= NULL
, *rvalue
= NULL
;
2767 gfc_actual_arglist
*arglist
;
2769 m
= gfc_match (" %v =", &lvalue
);
2771 gfc_current_locus
= old_loc
;
2774 m
= gfc_match (" %e )", &rvalue
);
2777 ns
->code
= gfc_get_code (EXEC_ASSIGN
);
2778 ns
->code
->expr1
= lvalue
;
2779 ns
->code
->expr2
= rvalue
;
2780 ns
->code
->loc
= old_loc
;
2784 gfc_current_locus
= old_loc
;
2785 gfc_free_expr (lvalue
);
2788 m
= gfc_match (" %n", sname
);
2792 if (strcmp (sname
, omp_sym1
->name
) == 0
2793 || strcmp (sname
, omp_sym2
->name
) == 0)
2796 gfc_current_ns
= ns
->parent
;
2797 if (gfc_get_ha_sym_tree (sname
, &st
))
2801 if (sym
->attr
.flavor
!= FL_PROCEDURE
2802 && sym
->attr
.flavor
!= FL_UNKNOWN
)
2805 if (!sym
->attr
.generic
2806 && !sym
->attr
.subroutine
2807 && !sym
->attr
.function
)
2809 if (!(sym
->attr
.external
&& !sym
->attr
.referenced
))
2811 /* ...create a symbol in this scope... */
2812 if (sym
->ns
!= gfc_current_ns
2813 && gfc_get_sym_tree (sname
, NULL
, &st
, false) == 1)
2816 if (sym
!= st
->n
.sym
)
2820 /* ...and then to try to make the symbol into a subroutine. */
2821 if (!gfc_add_subroutine (&sym
->attr
, sym
->name
, NULL
))
2825 gfc_set_sym_referenced (sym
);
2826 gfc_gobble_whitespace ();
2827 if (gfc_peek_ascii_char () != '(')
2830 gfc_current_ns
= ns
;
2831 m
= gfc_match_actual_arglist (1, &arglist
);
2835 if (gfc_match_char (')') != MATCH_YES
)
2838 ns
->code
= gfc_get_code (EXEC_CALL
);
2839 ns
->code
->symtree
= st
;
2840 ns
->code
->ext
.actual
= arglist
;
2841 ns
->code
->loc
= old_loc
;
2846 gfc_omp_udr_predef (gfc_omp_reduction_op rop
, const char *name
,
2847 gfc_typespec
*ts
, const char **n
)
2849 if (!gfc_numeric_ts (ts
) && ts
->type
!= BT_LOGICAL
)
2854 case OMP_REDUCTION_PLUS
:
2855 case OMP_REDUCTION_MINUS
:
2856 case OMP_REDUCTION_TIMES
:
2857 return ts
->type
!= BT_LOGICAL
;
2858 case OMP_REDUCTION_AND
:
2859 case OMP_REDUCTION_OR
:
2860 case OMP_REDUCTION_EQV
:
2861 case OMP_REDUCTION_NEQV
:
2862 return ts
->type
== BT_LOGICAL
;
2863 case OMP_REDUCTION_USER
:
2864 if (name
[0] != '.' && (ts
->type
== BT_INTEGER
|| ts
->type
== BT_REAL
))
2868 gfc_find_symbol (name
, NULL
, 1, &sym
);
2871 if (sym
->attr
.intrinsic
)
2873 else if ((sym
->attr
.flavor
!= FL_UNKNOWN
2874 && sym
->attr
.flavor
!= FL_PROCEDURE
)
2875 || sym
->attr
.external
2876 || sym
->attr
.generic
2880 || sym
->attr
.subroutine
2881 || sym
->attr
.pointer
2883 || sym
->attr
.cray_pointer
2884 || sym
->attr
.cray_pointee
2885 || (sym
->attr
.proc
!= PROC_UNKNOWN
2886 && sym
->attr
.proc
!= PROC_INTRINSIC
)
2887 || sym
->attr
.if_source
!= IFSRC_UNKNOWN
2888 || sym
== sym
->ns
->proc_name
)
2896 && (strcmp (*n
, "max") == 0 || strcmp (*n
, "min") == 0))
2899 && ts
->type
== BT_INTEGER
2900 && (strcmp (*n
, "iand") == 0
2901 || strcmp (*n
, "ior") == 0
2902 || strcmp (*n
, "ieor") == 0))
2913 gfc_omp_udr_find (gfc_symtree
*st
, gfc_typespec
*ts
)
2915 gfc_omp_udr
*omp_udr
;
2920 for (omp_udr
= st
->n
.omp_udr
; omp_udr
; omp_udr
= omp_udr
->next
)
2921 if (omp_udr
->ts
.type
== ts
->type
2922 || ((omp_udr
->ts
.type
== BT_DERIVED
|| omp_udr
->ts
.type
== BT_CLASS
)
2923 && (ts
->type
== BT_DERIVED
|| ts
->type
== BT_CLASS
)))
2925 if (omp_udr
->ts
.type
== BT_DERIVED
|| omp_udr
->ts
.type
== BT_CLASS
)
2927 if (strcmp (omp_udr
->ts
.u
.derived
->name
, ts
->u
.derived
->name
) == 0)
2930 else if (omp_udr
->ts
.kind
== ts
->kind
)
2932 if (omp_udr
->ts
.type
== BT_CHARACTER
)
2934 if (omp_udr
->ts
.u
.cl
->length
== NULL
2935 || ts
->u
.cl
->length
== NULL
)
2937 if (omp_udr
->ts
.u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
2939 if (ts
->u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
2941 if (omp_udr
->ts
.u
.cl
->length
->ts
.type
!= BT_INTEGER
)
2943 if (ts
->u
.cl
->length
->ts
.type
!= BT_INTEGER
)
2945 if (gfc_compare_expr (omp_udr
->ts
.u
.cl
->length
,
2946 ts
->u
.cl
->length
, INTRINSIC_EQ
) != 0)
2956 gfc_match_omp_declare_reduction (void)
2959 gfc_intrinsic_op op
;
2960 char name
[GFC_MAX_SYMBOL_LEN
+ 3];
2961 auto_vec
<gfc_typespec
, 5> tss
;
2965 locus where
= gfc_current_locus
;
2966 locus end_loc
= gfc_current_locus
;
2967 bool end_loc_set
= false;
2968 gfc_omp_reduction_op rop
= OMP_REDUCTION_NONE
;
2970 if (gfc_match_char ('(') != MATCH_YES
)
2973 m
= gfc_match (" %o : ", &op
);
2974 if (m
== MATCH_ERROR
)
2978 snprintf (name
, sizeof name
, "operator %s", gfc_op2string (op
));
2979 rop
= (gfc_omp_reduction_op
) op
;
2983 m
= gfc_match_defined_op_name (name
+ 1, 1);
2984 if (m
== MATCH_ERROR
)
2990 if (gfc_match (" : ") != MATCH_YES
)
2995 if (gfc_match (" %n : ", name
) != MATCH_YES
)
2998 rop
= OMP_REDUCTION_USER
;
3001 m
= gfc_match_type_spec (&ts
);
3004 /* Treat len=: the same as len=*. */
3005 if (ts
.type
== BT_CHARACTER
)
3006 ts
.deferred
= false;
3009 while (gfc_match_char (',') == MATCH_YES
)
3011 m
= gfc_match_type_spec (&ts
);
3016 if (gfc_match_char (':') != MATCH_YES
)
3019 st
= gfc_find_symtree (gfc_current_ns
->omp_udr_root
, name
);
3020 for (i
= 0; i
< tss
.length (); i
++)
3022 gfc_symtree
*omp_out
, *omp_in
;
3023 gfc_symtree
*omp_priv
= NULL
, *omp_orig
= NULL
;
3024 gfc_namespace
*combiner_ns
, *initializer_ns
= NULL
;
3025 gfc_omp_udr
*prev_udr
, *omp_udr
;
3026 const char *predef_name
= NULL
;
3028 omp_udr
= gfc_get_omp_udr ();
3029 omp_udr
->name
= gfc_get_string ("%s", name
);
3031 omp_udr
->ts
= tss
[i
];
3032 omp_udr
->where
= where
;
3034 gfc_current_ns
= combiner_ns
= gfc_get_namespace (gfc_current_ns
, 1);
3035 combiner_ns
->proc_name
= combiner_ns
->parent
->proc_name
;
3037 gfc_get_sym_tree ("omp_out", combiner_ns
, &omp_out
, false);
3038 gfc_get_sym_tree ("omp_in", combiner_ns
, &omp_in
, false);
3039 combiner_ns
->omp_udr_ns
= 1;
3040 omp_out
->n
.sym
->ts
= tss
[i
];
3041 omp_in
->n
.sym
->ts
= tss
[i
];
3042 omp_out
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
3043 omp_in
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
3044 omp_out
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
3045 omp_in
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
3046 gfc_commit_symbols ();
3047 omp_udr
->combiner_ns
= combiner_ns
;
3048 omp_udr
->omp_out
= omp_out
->n
.sym
;
3049 omp_udr
->omp_in
= omp_in
->n
.sym
;
3051 locus old_loc
= gfc_current_locus
;
3053 if (!match_udr_expr (omp_out
, omp_in
))
3056 gfc_current_locus
= old_loc
;
3057 gfc_current_ns
= combiner_ns
->parent
;
3058 gfc_undo_symbols ();
3059 gfc_free_omp_udr (omp_udr
);
3063 if (gfc_match (" initializer ( ") == MATCH_YES
)
3065 gfc_current_ns
= combiner_ns
->parent
;
3066 initializer_ns
= gfc_get_namespace (gfc_current_ns
, 1);
3067 gfc_current_ns
= initializer_ns
;
3068 initializer_ns
->proc_name
= initializer_ns
->parent
->proc_name
;
3070 gfc_get_sym_tree ("omp_priv", initializer_ns
, &omp_priv
, false);
3071 gfc_get_sym_tree ("omp_orig", initializer_ns
, &omp_orig
, false);
3072 initializer_ns
->omp_udr_ns
= 1;
3073 omp_priv
->n
.sym
->ts
= tss
[i
];
3074 omp_orig
->n
.sym
->ts
= tss
[i
];
3075 omp_priv
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
3076 omp_orig
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
3077 omp_priv
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
3078 omp_orig
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
3079 gfc_commit_symbols ();
3080 omp_udr
->initializer_ns
= initializer_ns
;
3081 omp_udr
->omp_priv
= omp_priv
->n
.sym
;
3082 omp_udr
->omp_orig
= omp_orig
->n
.sym
;
3084 if (!match_udr_expr (omp_priv
, omp_orig
))
3088 gfc_current_ns
= combiner_ns
->parent
;
3092 end_loc
= gfc_current_locus
;
3094 gfc_current_locus
= old_loc
;
3096 prev_udr
= gfc_omp_udr_find (st
, &tss
[i
]);
3097 if (gfc_omp_udr_predef (rop
, name
, &tss
[i
], &predef_name
)
3098 /* Don't error on !$omp declare reduction (min : integer : ...)
3099 just yet, there could be integer :: min afterwards,
3100 making it valid. When the UDR is resolved, we'll get
3102 && (rop
!= OMP_REDUCTION_USER
|| name
[0] == '.'))
3105 gfc_error_now ("Redefinition of predefined %s "
3106 "!$OMP DECLARE REDUCTION at %L",
3107 predef_name
, &where
);
3109 gfc_error_now ("Redefinition of predefined "
3110 "!$OMP DECLARE REDUCTION at %L", &where
);
3114 gfc_error_now ("Redefinition of !$OMP DECLARE REDUCTION at %L",
3116 gfc_error_now ("Previous !$OMP DECLARE REDUCTION at %L",
3121 omp_udr
->next
= st
->n
.omp_udr
;
3122 st
->n
.omp_udr
= omp_udr
;
3126 st
= gfc_new_symtree (&gfc_current_ns
->omp_udr_root
, name
);
3127 st
->n
.omp_udr
= omp_udr
;
3133 gfc_current_locus
= end_loc
;
3134 if (gfc_match_omp_eos () != MATCH_YES
)
3136 gfc_error ("Unexpected junk after !$OMP DECLARE REDUCTION at %C");
3137 gfc_current_locus
= where
;
3149 gfc_match_omp_declare_target (void)
3153 gfc_omp_clauses
*c
= NULL
;
3155 gfc_omp_namelist
*n
;
3158 old_loc
= gfc_current_locus
;
3160 if (gfc_current_ns
->proc_name
3161 && gfc_match_omp_eos () == MATCH_YES
)
3163 if (!gfc_add_omp_declare_target (&gfc_current_ns
->proc_name
->attr
,
3164 gfc_current_ns
->proc_name
->name
,
3170 if (gfc_current_ns
->proc_name
3171 && gfc_current_ns
->proc_name
->attr
.if_source
== IFSRC_IFBODY
)
3173 gfc_error ("Only the !$OMP DECLARE TARGET form without "
3174 "clauses is allowed in interface block at %C");
3178 m
= gfc_match (" (");
3181 c
= gfc_get_omp_clauses ();
3182 gfc_current_locus
= old_loc
;
3183 m
= gfc_match_omp_to_link (" (", &c
->lists
[OMP_LIST_TO
]);
3186 if (gfc_match_omp_eos () != MATCH_YES
)
3188 gfc_error ("Unexpected junk after !$OMP DECLARE TARGET at %C");
3192 else if (gfc_match_omp_clauses (&c
, OMP_DECLARE_TARGET_CLAUSES
) != MATCH_YES
)
3195 gfc_buffer_error (false);
3197 for (list
= OMP_LIST_TO
; list
!= OMP_LIST_NUM
;
3198 list
= (list
== OMP_LIST_TO
? OMP_LIST_LINK
: OMP_LIST_NUM
))
3199 for (n
= c
->lists
[list
]; n
; n
= n
->next
)
3202 else if (n
->u
.common
->head
)
3203 n
->u
.common
->head
->mark
= 0;
3205 for (list
= OMP_LIST_TO
; list
!= OMP_LIST_NUM
;
3206 list
= (list
== OMP_LIST_TO
? OMP_LIST_LINK
: OMP_LIST_NUM
))
3207 for (n
= c
->lists
[list
]; n
; n
= n
->next
)
3210 if (n
->sym
->attr
.in_common
)
3211 gfc_error_now ("OMP DECLARE TARGET variable at %L is an "
3212 "element of a COMMON block", &n
->where
);
3213 else if (n
->sym
->attr
.omp_declare_target
3214 && n
->sym
->attr
.omp_declare_target_link
3215 && list
!= OMP_LIST_LINK
)
3216 gfc_error_now ("OMP DECLARE TARGET variable at %L previously "
3217 "mentioned in LINK clause and later in TO clause",
3219 else if (n
->sym
->attr
.omp_declare_target
3220 && !n
->sym
->attr
.omp_declare_target_link
3221 && list
== OMP_LIST_LINK
)
3222 gfc_error_now ("OMP DECLARE TARGET variable at %L previously "
3223 "mentioned in TO clause and later in LINK clause",
3225 else if (n
->sym
->mark
)
3226 gfc_error_now ("Variable at %L mentioned multiple times in "
3227 "clauses of the same OMP DECLARE TARGET directive",
3229 else if (gfc_add_omp_declare_target (&n
->sym
->attr
, n
->sym
->name
,
3230 &n
->sym
->declared_at
))
3232 if (list
== OMP_LIST_LINK
)
3233 gfc_add_omp_declare_target_link (&n
->sym
->attr
, n
->sym
->name
,
3234 &n
->sym
->declared_at
);
3238 else if (n
->u
.common
->omp_declare_target
3239 && n
->u
.common
->omp_declare_target_link
3240 && list
!= OMP_LIST_LINK
)
3241 gfc_error_now ("OMP DECLARE TARGET COMMON at %L previously "
3242 "mentioned in LINK clause and later in TO clause",
3244 else if (n
->u
.common
->omp_declare_target
3245 && !n
->u
.common
->omp_declare_target_link
3246 && list
== OMP_LIST_LINK
)
3247 gfc_error_now ("OMP DECLARE TARGET COMMON at %L previously "
3248 "mentioned in TO clause and later in LINK clause",
3250 else if (n
->u
.common
->head
&& n
->u
.common
->head
->mark
)
3251 gfc_error_now ("COMMON at %L mentioned multiple times in "
3252 "clauses of the same OMP DECLARE TARGET directive",
3256 n
->u
.common
->omp_declare_target
= 1;
3257 n
->u
.common
->omp_declare_target_link
= (list
== OMP_LIST_LINK
);
3258 for (s
= n
->u
.common
->head
; s
; s
= s
->common_next
)
3261 if (gfc_add_omp_declare_target (&s
->attr
, s
->name
,
3264 if (list
== OMP_LIST_LINK
)
3265 gfc_add_omp_declare_target_link (&s
->attr
, s
->name
,
3271 gfc_buffer_error (true);
3274 gfc_free_omp_clauses (c
);
3278 gfc_error ("Syntax error in !$OMP DECLARE TARGET list at %C");
3281 gfc_current_locus
= old_loc
;
3283 gfc_free_omp_clauses (c
);
3289 gfc_match_omp_threadprivate (void)
3292 char n
[GFC_MAX_SYMBOL_LEN
+1];
3297 old_loc
= gfc_current_locus
;
3299 m
= gfc_match (" (");
3305 m
= gfc_match_symbol (&sym
, 0);
3309 if (sym
->attr
.in_common
)
3310 gfc_error_now ("Threadprivate variable at %C is an element of "
3312 else if (!gfc_add_threadprivate (&sym
->attr
, sym
->name
, &sym
->declared_at
))
3321 m
= gfc_match (" / %n /", n
);
3322 if (m
== MATCH_ERROR
)
3324 if (m
== MATCH_NO
|| n
[0] == '\0')
3327 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
3330 gfc_error ("COMMON block /%s/ not found at %C", n
);
3333 st
->n
.common
->threadprivate
= 1;
3334 for (sym
= st
->n
.common
->head
; sym
; sym
= sym
->common_next
)
3335 if (!gfc_add_threadprivate (&sym
->attr
, sym
->name
, &sym
->declared_at
))
3339 if (gfc_match_char (')') == MATCH_YES
)
3341 if (gfc_match_char (',') != MATCH_YES
)
3345 if (gfc_match_omp_eos () != MATCH_YES
)
3347 gfc_error ("Unexpected junk after OMP THREADPRIVATE at %C");
3354 gfc_error ("Syntax error in !$OMP THREADPRIVATE list at %C");
3357 gfc_current_locus
= old_loc
;
3363 gfc_match_omp_parallel (void)
3365 return match_omp (EXEC_OMP_PARALLEL
, OMP_PARALLEL_CLAUSES
);
3370 gfc_match_omp_parallel_do (void)
3372 return match_omp (EXEC_OMP_PARALLEL_DO
,
3373 OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
);
3378 gfc_match_omp_parallel_do_simd (void)
3380 return match_omp (EXEC_OMP_PARALLEL_DO_SIMD
,
3381 OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
);
3386 gfc_match_omp_parallel_sections (void)
3388 return match_omp (EXEC_OMP_PARALLEL_SECTIONS
,
3389 OMP_PARALLEL_CLAUSES
| OMP_SECTIONS_CLAUSES
);
3394 gfc_match_omp_parallel_workshare (void)
3396 return match_omp (EXEC_OMP_PARALLEL_WORKSHARE
, OMP_PARALLEL_CLAUSES
);
3401 gfc_match_omp_sections (void)
3403 return match_omp (EXEC_OMP_SECTIONS
, OMP_SECTIONS_CLAUSES
);
3408 gfc_match_omp_simd (void)
3410 return match_omp (EXEC_OMP_SIMD
, OMP_SIMD_CLAUSES
);
3415 gfc_match_omp_single (void)
3417 return match_omp (EXEC_OMP_SINGLE
, OMP_SINGLE_CLAUSES
);
3422 gfc_match_omp_target (void)
3424 return match_omp (EXEC_OMP_TARGET
, OMP_TARGET_CLAUSES
);
3429 gfc_match_omp_target_data (void)
3431 return match_omp (EXEC_OMP_TARGET_DATA
, OMP_TARGET_DATA_CLAUSES
);
3436 gfc_match_omp_target_enter_data (void)
3438 return match_omp (EXEC_OMP_TARGET_ENTER_DATA
, OMP_TARGET_ENTER_DATA_CLAUSES
);
3443 gfc_match_omp_target_exit_data (void)
3445 return match_omp (EXEC_OMP_TARGET_EXIT_DATA
, OMP_TARGET_EXIT_DATA_CLAUSES
);
3450 gfc_match_omp_target_parallel (void)
3452 return match_omp (EXEC_OMP_TARGET_PARALLEL
,
3453 (OMP_TARGET_CLAUSES
| OMP_PARALLEL_CLAUSES
)
3454 & ~(omp_mask (OMP_CLAUSE_COPYIN
)));
3459 gfc_match_omp_target_parallel_do (void)
3461 return match_omp (EXEC_OMP_TARGET_PARALLEL_DO
,
3462 (OMP_TARGET_CLAUSES
| OMP_PARALLEL_CLAUSES
3463 | OMP_DO_CLAUSES
) & ~(omp_mask (OMP_CLAUSE_COPYIN
)));
3468 gfc_match_omp_target_parallel_do_simd (void)
3470 return match_omp (EXEC_OMP_TARGET_PARALLEL_DO_SIMD
,
3471 (OMP_TARGET_CLAUSES
| OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
3472 | OMP_SIMD_CLAUSES
) & ~(omp_mask (OMP_CLAUSE_COPYIN
)));
3477 gfc_match_omp_target_simd (void)
3479 return match_omp (EXEC_OMP_TARGET_SIMD
,
3480 OMP_TARGET_CLAUSES
| OMP_SIMD_CLAUSES
);
3485 gfc_match_omp_target_teams (void)
3487 return match_omp (EXEC_OMP_TARGET_TEAMS
,
3488 OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
);
3493 gfc_match_omp_target_teams_distribute (void)
3495 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
,
3496 OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
3497 | OMP_DISTRIBUTE_CLAUSES
);
3502 gfc_match_omp_target_teams_distribute_parallel_do (void)
3504 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
,
3505 (OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
3506 | OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
3508 & ~(omp_mask (OMP_CLAUSE_ORDERED
))
3509 & ~(omp_mask (OMP_CLAUSE_LINEAR
)));
3514 gfc_match_omp_target_teams_distribute_parallel_do_simd (void)
3516 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
,
3517 (OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
3518 | OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
3519 | OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
)
3520 & ~(omp_mask (OMP_CLAUSE_ORDERED
)));
3525 gfc_match_omp_target_teams_distribute_simd (void)
3527 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
,
3528 OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
3529 | OMP_DISTRIBUTE_CLAUSES
| OMP_SIMD_CLAUSES
);
3534 gfc_match_omp_target_update (void)
3536 return match_omp (EXEC_OMP_TARGET_UPDATE
, OMP_TARGET_UPDATE_CLAUSES
);
3541 gfc_match_omp_task (void)
3543 return match_omp (EXEC_OMP_TASK
, OMP_TASK_CLAUSES
);
3548 gfc_match_omp_taskloop (void)
3550 return match_omp (EXEC_OMP_TASKLOOP
, OMP_TASKLOOP_CLAUSES
);
3555 gfc_match_omp_taskloop_simd (void)
3557 return match_omp (EXEC_OMP_TASKLOOP_SIMD
,
3558 (OMP_TASKLOOP_CLAUSES
| OMP_SIMD_CLAUSES
)
3559 & ~(omp_mask (OMP_CLAUSE_REDUCTION
)));
3564 gfc_match_omp_taskwait (void)
3566 if (gfc_match_omp_eos () != MATCH_YES
)
3568 gfc_error ("Unexpected junk after TASKWAIT clause at %C");
3571 new_st
.op
= EXEC_OMP_TASKWAIT
;
3572 new_st
.ext
.omp_clauses
= NULL
;
3578 gfc_match_omp_taskyield (void)
3580 if (gfc_match_omp_eos () != MATCH_YES
)
3582 gfc_error ("Unexpected junk after TASKYIELD clause at %C");
3585 new_st
.op
= EXEC_OMP_TASKYIELD
;
3586 new_st
.ext
.omp_clauses
= NULL
;
3592 gfc_match_omp_teams (void)
3594 return match_omp (EXEC_OMP_TEAMS
, OMP_TEAMS_CLAUSES
);
3599 gfc_match_omp_teams_distribute (void)
3601 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE
,
3602 OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
);
3607 gfc_match_omp_teams_distribute_parallel_do (void)
3609 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
,
3610 (OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
3611 | OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
)
3612 & ~(omp_mask (OMP_CLAUSE_ORDERED
))
3613 & ~(omp_mask (OMP_CLAUSE_LINEAR
)));
3618 gfc_match_omp_teams_distribute_parallel_do_simd (void)
3620 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
,
3621 (OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
3622 | OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
3623 | OMP_SIMD_CLAUSES
) & ~(omp_mask (OMP_CLAUSE_ORDERED
)));
3628 gfc_match_omp_teams_distribute_simd (void)
3630 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
,
3631 OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
3632 | OMP_SIMD_CLAUSES
);
3637 gfc_match_omp_workshare (void)
3639 if (gfc_match_omp_eos () != MATCH_YES
)
3641 gfc_error ("Unexpected junk after $OMP WORKSHARE statement at %C");
3644 new_st
.op
= EXEC_OMP_WORKSHARE
;
3645 new_st
.ext
.omp_clauses
= gfc_get_omp_clauses ();
3651 gfc_match_omp_master (void)
3653 if (gfc_match_omp_eos () != MATCH_YES
)
3655 gfc_error ("Unexpected junk after $OMP MASTER statement at %C");
3658 new_st
.op
= EXEC_OMP_MASTER
;
3659 new_st
.ext
.omp_clauses
= NULL
;
3665 gfc_match_omp_ordered (void)
3667 return match_omp (EXEC_OMP_ORDERED
, OMP_ORDERED_CLAUSES
);
3672 gfc_match_omp_ordered_depend (void)
3674 return match_omp (EXEC_OMP_ORDERED
, omp_mask (OMP_CLAUSE_DEPEND
));
3679 gfc_match_omp_oacc_atomic (bool omp_p
)
3681 gfc_omp_atomic_op op
= GFC_OMP_ATOMIC_UPDATE
;
3683 if (gfc_match ("% seq_cst") == MATCH_YES
)
3685 locus old_loc
= gfc_current_locus
;
3686 if (seq_cst
&& gfc_match_char (',') == MATCH_YES
)
3689 || gfc_match_space () == MATCH_YES
)
3691 gfc_gobble_whitespace ();
3692 if (gfc_match ("update") == MATCH_YES
)
3693 op
= GFC_OMP_ATOMIC_UPDATE
;
3694 else if (gfc_match ("read") == MATCH_YES
)
3695 op
= GFC_OMP_ATOMIC_READ
;
3696 else if (gfc_match ("write") == MATCH_YES
)
3697 op
= GFC_OMP_ATOMIC_WRITE
;
3698 else if (gfc_match ("capture") == MATCH_YES
)
3699 op
= GFC_OMP_ATOMIC_CAPTURE
;
3703 gfc_current_locus
= old_loc
;
3707 && (gfc_match (", seq_cst") == MATCH_YES
3708 || gfc_match ("% seq_cst") == MATCH_YES
))
3712 if (gfc_match_omp_eos () != MATCH_YES
)
3714 gfc_error ("Unexpected junk after $OMP ATOMIC statement at %C");
3717 new_st
.op
= (omp_p
? EXEC_OMP_ATOMIC
: EXEC_OACC_ATOMIC
);
3719 op
= (gfc_omp_atomic_op
) (op
| GFC_OMP_ATOMIC_SEQ_CST
);
3720 new_st
.ext
.omp_atomic
= op
;
3725 gfc_match_oacc_atomic (void)
3727 return gfc_match_omp_oacc_atomic (false);
3731 gfc_match_omp_atomic (void)
3733 return gfc_match_omp_oacc_atomic (true);
3737 gfc_match_omp_barrier (void)
3739 if (gfc_match_omp_eos () != MATCH_YES
)
3741 gfc_error ("Unexpected junk after $OMP BARRIER statement at %C");
3744 new_st
.op
= EXEC_OMP_BARRIER
;
3745 new_st
.ext
.omp_clauses
= NULL
;
3751 gfc_match_omp_taskgroup (void)
3753 if (gfc_match_omp_eos () != MATCH_YES
)
3755 gfc_error ("Unexpected junk after $OMP TASKGROUP statement at %C");
3758 new_st
.op
= EXEC_OMP_TASKGROUP
;
3763 static enum gfc_omp_cancel_kind
3764 gfc_match_omp_cancel_kind (void)
3766 if (gfc_match_space () != MATCH_YES
)
3767 return OMP_CANCEL_UNKNOWN
;
3768 if (gfc_match ("parallel") == MATCH_YES
)
3769 return OMP_CANCEL_PARALLEL
;
3770 if (gfc_match ("sections") == MATCH_YES
)
3771 return OMP_CANCEL_SECTIONS
;
3772 if (gfc_match ("do") == MATCH_YES
)
3773 return OMP_CANCEL_DO
;
3774 if (gfc_match ("taskgroup") == MATCH_YES
)
3775 return OMP_CANCEL_TASKGROUP
;
3776 return OMP_CANCEL_UNKNOWN
;
3781 gfc_match_omp_cancel (void)
3784 enum gfc_omp_cancel_kind kind
= gfc_match_omp_cancel_kind ();
3785 if (kind
== OMP_CANCEL_UNKNOWN
)
3787 if (gfc_match_omp_clauses (&c
, omp_mask (OMP_CLAUSE_IF
), false) != MATCH_YES
)
3790 new_st
.op
= EXEC_OMP_CANCEL
;
3791 new_st
.ext
.omp_clauses
= c
;
3797 gfc_match_omp_cancellation_point (void)
3800 enum gfc_omp_cancel_kind kind
= gfc_match_omp_cancel_kind ();
3801 if (kind
== OMP_CANCEL_UNKNOWN
)
3803 if (gfc_match_omp_eos () != MATCH_YES
)
3805 gfc_error ("Unexpected junk after $OMP CANCELLATION POINT statement "
3809 c
= gfc_get_omp_clauses ();
3811 new_st
.op
= EXEC_OMP_CANCELLATION_POINT
;
3812 new_st
.ext
.omp_clauses
= c
;
3818 gfc_match_omp_end_nowait (void)
3820 bool nowait
= false;
3821 if (gfc_match ("% nowait") == MATCH_YES
)
3823 if (gfc_match_omp_eos () != MATCH_YES
)
3825 gfc_error ("Unexpected junk after NOWAIT clause at %C");
3828 new_st
.op
= EXEC_OMP_END_NOWAIT
;
3829 new_st
.ext
.omp_bool
= nowait
;
3835 gfc_match_omp_end_single (void)
3838 if (gfc_match ("% nowait") == MATCH_YES
)
3840 new_st
.op
= EXEC_OMP_END_NOWAIT
;
3841 new_st
.ext
.omp_bool
= true;
3844 if (gfc_match_omp_clauses (&c
, omp_mask (OMP_CLAUSE_COPYPRIVATE
))
3847 new_st
.op
= EXEC_OMP_END_SINGLE
;
3848 new_st
.ext
.omp_clauses
= c
;
3854 oacc_is_loop (gfc_code
*code
)
3856 return code
->op
== EXEC_OACC_PARALLEL_LOOP
3857 || code
->op
== EXEC_OACC_KERNELS_LOOP
3858 || code
->op
== EXEC_OACC_SERIAL_LOOP
3859 || code
->op
== EXEC_OACC_LOOP
;
3863 resolve_scalar_int_expr (gfc_expr
*expr
, const char *clause
)
3865 if (!gfc_resolve_expr (expr
)
3866 || expr
->ts
.type
!= BT_INTEGER
3868 gfc_error ("%s clause at %L requires a scalar INTEGER expression",
3869 clause
, &expr
->where
);
3873 resolve_positive_int_expr (gfc_expr
*expr
, const char *clause
)
3875 resolve_scalar_int_expr (expr
, clause
);
3876 if (expr
->expr_type
== EXPR_CONSTANT
3877 && expr
->ts
.type
== BT_INTEGER
3878 && mpz_sgn (expr
->value
.integer
) <= 0)
3879 gfc_warning (0, "INTEGER expression of %s clause at %L must be positive",
3880 clause
, &expr
->where
);
3884 resolve_nonnegative_int_expr (gfc_expr
*expr
, const char *clause
)
3886 resolve_scalar_int_expr (expr
, clause
);
3887 if (expr
->expr_type
== EXPR_CONSTANT
3888 && expr
->ts
.type
== BT_INTEGER
3889 && mpz_sgn (expr
->value
.integer
) < 0)
3890 gfc_warning (0, "INTEGER expression of %s clause at %L must be "
3891 "non-negative", clause
, &expr
->where
);
3894 /* Emits error when symbol is pointer, cray pointer or cray pointee
3895 of derived of polymorphic type. */
3898 check_symbol_not_pointer (gfc_symbol
*sym
, locus loc
, const char *name
)
3900 if (sym
->ts
.type
== BT_DERIVED
&& sym
->attr
.cray_pointer
)
3901 gfc_error ("Cray pointer object %qs of derived type in %s clause at %L",
3902 sym
->name
, name
, &loc
);
3903 if (sym
->ts
.type
== BT_DERIVED
&& sym
->attr
.cray_pointee
)
3904 gfc_error ("Cray pointee object %qs of derived type in %s clause at %L",
3905 sym
->name
, name
, &loc
);
3907 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.pointer
)
3908 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3909 && CLASS_DATA (sym
)->attr
.pointer
))
3910 gfc_error ("POINTER object %qs of polymorphic type in %s clause at %L",
3911 sym
->name
, name
, &loc
);
3912 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.cray_pointer
)
3913 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3914 && CLASS_DATA (sym
)->attr
.cray_pointer
))
3915 gfc_error ("Cray pointer object %qs of polymorphic type in %s clause at %L",
3916 sym
->name
, name
, &loc
);
3917 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.cray_pointee
)
3918 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3919 && CLASS_DATA (sym
)->attr
.cray_pointee
))
3920 gfc_error ("Cray pointee object %qs of polymorphic type in %s clause at %L",
3921 sym
->name
, name
, &loc
);
3924 /* Emits error when symbol represents assumed size/rank array. */
3927 check_array_not_assumed (gfc_symbol
*sym
, locus loc
, const char *name
)
3929 if (sym
->as
&& sym
->as
->type
== AS_ASSUMED_SIZE
)
3930 gfc_error ("Assumed size array %qs in %s clause at %L",
3931 sym
->name
, name
, &loc
);
3932 if (sym
->as
&& sym
->as
->type
== AS_ASSUMED_RANK
)
3933 gfc_error ("Assumed rank array %qs in %s clause at %L",
3934 sym
->name
, name
, &loc
);
3938 resolve_oacc_data_clauses (gfc_symbol
*sym
, locus loc
, const char *name
)
3940 check_array_not_assumed (sym
, loc
, name
);
3944 resolve_oacc_deviceptr_clause (gfc_symbol
*sym
, locus loc
, const char *name
)
3946 if (sym
->attr
.pointer
3947 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3948 && CLASS_DATA (sym
)->attr
.class_pointer
))
3949 gfc_error ("POINTER object %qs in %s clause at %L",
3950 sym
->name
, name
, &loc
);
3951 if (sym
->attr
.cray_pointer
3952 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3953 && CLASS_DATA (sym
)->attr
.cray_pointer
))
3954 gfc_error ("Cray pointer object %qs in %s clause at %L",
3955 sym
->name
, name
, &loc
);
3956 if (sym
->attr
.cray_pointee
3957 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3958 && CLASS_DATA (sym
)->attr
.cray_pointee
))
3959 gfc_error ("Cray pointee object %qs in %s clause at %L",
3960 sym
->name
, name
, &loc
);
3961 if (sym
->attr
.allocatable
3962 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3963 && CLASS_DATA (sym
)->attr
.allocatable
))
3964 gfc_error ("ALLOCATABLE object %qs in %s clause at %L",
3965 sym
->name
, name
, &loc
);
3966 if (sym
->attr
.value
)
3967 gfc_error ("VALUE object %qs in %s clause at %L",
3968 sym
->name
, name
, &loc
);
3969 check_array_not_assumed (sym
, loc
, name
);
3973 struct resolve_omp_udr_callback_data
3975 gfc_symbol
*sym1
, *sym2
;
3980 resolve_omp_udr_callback (gfc_expr
**e
, int *, void *data
)
3982 struct resolve_omp_udr_callback_data
*rcd
3983 = (struct resolve_omp_udr_callback_data
*) data
;
3984 if ((*e
)->expr_type
== EXPR_VARIABLE
3985 && ((*e
)->symtree
->n
.sym
== rcd
->sym1
3986 || (*e
)->symtree
->n
.sym
== rcd
->sym2
))
3988 gfc_ref
*ref
= gfc_get_ref ();
3989 ref
->type
= REF_ARRAY
;
3990 ref
->u
.ar
.where
= (*e
)->where
;
3991 ref
->u
.ar
.as
= (*e
)->symtree
->n
.sym
->as
;
3992 ref
->u
.ar
.type
= AR_FULL
;
3993 ref
->u
.ar
.dimen
= 0;
3994 ref
->next
= (*e
)->ref
;
4002 resolve_omp_udr_callback2 (gfc_expr
**e
, int *, void *)
4004 if ((*e
)->expr_type
== EXPR_FUNCTION
4005 && (*e
)->value
.function
.isym
== NULL
)
4007 gfc_symbol
*sym
= (*e
)->symtree
->n
.sym
;
4008 if (!sym
->attr
.intrinsic
4009 && sym
->attr
.if_source
== IFSRC_UNKNOWN
)
4010 gfc_error ("Implicitly declared function %s used in "
4011 "!$OMP DECLARE REDUCTION at %L", sym
->name
, &(*e
)->where
);
4018 resolve_omp_udr_clause (gfc_omp_namelist
*n
, gfc_namespace
*ns
,
4019 gfc_symbol
*sym1
, gfc_symbol
*sym2
)
4022 gfc_symbol sym1_copy
, sym2_copy
;
4024 if (ns
->code
->op
== EXEC_ASSIGN
)
4026 copy
= gfc_get_code (EXEC_ASSIGN
);
4027 copy
->expr1
= gfc_copy_expr (ns
->code
->expr1
);
4028 copy
->expr2
= gfc_copy_expr (ns
->code
->expr2
);
4032 copy
= gfc_get_code (EXEC_CALL
);
4033 copy
->symtree
= ns
->code
->symtree
;
4034 copy
->ext
.actual
= gfc_copy_actual_arglist (ns
->code
->ext
.actual
);
4036 copy
->loc
= ns
->code
->loc
;
4041 sym1
->name
= sym1_copy
.name
;
4042 sym2
->name
= sym2_copy
.name
;
4043 ns
->proc_name
= ns
->parent
->proc_name
;
4044 if (n
->sym
->attr
.dimension
)
4046 struct resolve_omp_udr_callback_data rcd
;
4049 gfc_code_walker (©
, gfc_dummy_code_callback
,
4050 resolve_omp_udr_callback
, &rcd
);
4052 gfc_resolve_code (copy
, gfc_current_ns
);
4053 if (copy
->op
== EXEC_CALL
&& copy
->resolved_isym
== NULL
)
4055 gfc_symbol
*sym
= copy
->resolved_sym
;
4057 && !sym
->attr
.intrinsic
4058 && sym
->attr
.if_source
== IFSRC_UNKNOWN
)
4059 gfc_error ("Implicitly declared subroutine %s used in "
4060 "!$OMP DECLARE REDUCTION at %L", sym
->name
,
4063 gfc_code_walker (©
, gfc_dummy_code_callback
,
4064 resolve_omp_udr_callback2
, NULL
);
4070 /* OpenMP directive resolving routines. */
4073 resolve_omp_clauses (gfc_code
*code
, gfc_omp_clauses
*omp_clauses
,
4074 gfc_namespace
*ns
, bool openacc
= false)
4076 gfc_omp_namelist
*n
;
4080 bool if_without_mod
= false;
4081 gfc_omp_linear_op linear_op
= OMP_LINEAR_DEFAULT
;
4082 static const char *clause_names
[]
4083 = { "PRIVATE", "FIRSTPRIVATE", "LASTPRIVATE", "COPYPRIVATE", "SHARED",
4084 "COPYIN", "UNIFORM", "ALIGNED", "LINEAR", "DEPEND", "MAP",
4085 "TO", "FROM", "REDUCTION", "DEVICE_RESIDENT", "LINK", "USE_DEVICE",
4086 "CACHE", "IS_DEVICE_PTR", "USE_DEVICE_PTR", "USE_DEVICE_ADDR" };
4088 if (omp_clauses
== NULL
)
4091 if (omp_clauses
->orderedc
&& omp_clauses
->orderedc
< omp_clauses
->collapse
)
4092 gfc_error ("ORDERED clause parameter is less than COLLAPSE at %L",
4095 if (omp_clauses
->if_expr
)
4097 gfc_expr
*expr
= omp_clauses
->if_expr
;
4098 if (!gfc_resolve_expr (expr
)
4099 || expr
->ts
.type
!= BT_LOGICAL
|| expr
->rank
!= 0)
4100 gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
4102 if_without_mod
= true;
4104 for (ifc
= 0; ifc
< OMP_IF_LAST
; ifc
++)
4105 if (omp_clauses
->if_exprs
[ifc
])
4107 gfc_expr
*expr
= omp_clauses
->if_exprs
[ifc
];
4109 if (!gfc_resolve_expr (expr
)
4110 || expr
->ts
.type
!= BT_LOGICAL
|| expr
->rank
!= 0)
4111 gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
4113 else if (if_without_mod
)
4115 gfc_error ("IF clause without modifier at %L used together with "
4116 "IF clauses with modifiers",
4117 &omp_clauses
->if_expr
->where
);
4118 if_without_mod
= false;
4123 case EXEC_OMP_PARALLEL
:
4124 case EXEC_OMP_PARALLEL_DO
:
4125 case EXEC_OMP_PARALLEL_SECTIONS
:
4126 case EXEC_OMP_PARALLEL_WORKSHARE
:
4127 case EXEC_OMP_PARALLEL_DO_SIMD
:
4128 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
4129 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
4130 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
4131 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
4132 ok
= ifc
== OMP_IF_PARALLEL
;
4136 ok
= ifc
== OMP_IF_TASK
;
4139 case EXEC_OMP_TASKLOOP
:
4140 case EXEC_OMP_TASKLOOP_SIMD
:
4141 ok
= ifc
== OMP_IF_TASKLOOP
;
4144 case EXEC_OMP_TARGET
:
4145 case EXEC_OMP_TARGET_TEAMS
:
4146 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
4147 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
4148 case EXEC_OMP_TARGET_SIMD
:
4149 ok
= ifc
== OMP_IF_TARGET
;
4152 case EXEC_OMP_TARGET_DATA
:
4153 ok
= ifc
== OMP_IF_TARGET_DATA
;
4156 case EXEC_OMP_TARGET_UPDATE
:
4157 ok
= ifc
== OMP_IF_TARGET_UPDATE
;
4160 case EXEC_OMP_TARGET_ENTER_DATA
:
4161 ok
= ifc
== OMP_IF_TARGET_ENTER_DATA
;
4164 case EXEC_OMP_TARGET_EXIT_DATA
:
4165 ok
= ifc
== OMP_IF_TARGET_EXIT_DATA
;
4168 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
4169 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
4170 case EXEC_OMP_TARGET_PARALLEL
:
4171 case EXEC_OMP_TARGET_PARALLEL_DO
:
4172 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
4173 ok
= ifc
== OMP_IF_TARGET
|| ifc
== OMP_IF_PARALLEL
;
4182 static const char *ifs
[] = {
4189 "TARGET ENTER DATA",
4192 gfc_error ("IF clause modifier %s at %L not appropriate for "
4193 "the current OpenMP construct", ifs
[ifc
], &expr
->where
);
4197 if (omp_clauses
->final_expr
)
4199 gfc_expr
*expr
= omp_clauses
->final_expr
;
4200 if (!gfc_resolve_expr (expr
)
4201 || expr
->ts
.type
!= BT_LOGICAL
|| expr
->rank
!= 0)
4202 gfc_error ("FINAL clause at %L requires a scalar LOGICAL expression",
4205 if (omp_clauses
->num_threads
)
4206 resolve_positive_int_expr (omp_clauses
->num_threads
, "NUM_THREADS");
4207 if (omp_clauses
->chunk_size
)
4209 gfc_expr
*expr
= omp_clauses
->chunk_size
;
4210 if (!gfc_resolve_expr (expr
)
4211 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
4212 gfc_error ("SCHEDULE clause's chunk_size at %L requires "
4213 "a scalar INTEGER expression", &expr
->where
);
4214 else if (expr
->expr_type
== EXPR_CONSTANT
4215 && expr
->ts
.type
== BT_INTEGER
4216 && mpz_sgn (expr
->value
.integer
) <= 0)
4217 gfc_warning (0, "INTEGER expression of SCHEDULE clause's chunk_size "
4218 "at %L must be positive", &expr
->where
);
4220 if (omp_clauses
->sched_kind
!= OMP_SCHED_NONE
4221 && omp_clauses
->sched_nonmonotonic
)
4223 if (omp_clauses
->sched_kind
!= OMP_SCHED_DYNAMIC
4224 && omp_clauses
->sched_kind
!= OMP_SCHED_GUIDED
)
4227 switch (omp_clauses
->sched_kind
)
4229 case OMP_SCHED_STATIC
: p
= "STATIC"; break;
4230 case OMP_SCHED_RUNTIME
: p
= "RUNTIME"; break;
4231 case OMP_SCHED_AUTO
: p
= "AUTO"; break;
4232 default: gcc_unreachable ();
4234 gfc_error ("NONMONOTONIC modifier specified for %s schedule kind "
4235 "at %L", p
, &code
->loc
);
4237 else if (omp_clauses
->sched_monotonic
)
4238 gfc_error ("Both MONOTONIC and NONMONOTONIC schedule modifiers "
4239 "specified at %L", &code
->loc
);
4240 else if (omp_clauses
->ordered
)
4241 gfc_error ("NONMONOTONIC schedule modifier specified with ORDERED "
4242 "clause at %L", &code
->loc
);
4245 /* Check that no symbol appears on multiple clauses, except that
4246 a symbol can appear on both firstprivate and lastprivate. */
4247 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
4248 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
4251 n
->sym
->comp_mark
= 0;
4252 if (n
->sym
->attr
.flavor
== FL_VARIABLE
4253 || n
->sym
->attr
.proc_pointer
4254 || (!code
&& (!n
->sym
->attr
.dummy
|| n
->sym
->ns
!= ns
)))
4256 if (!code
&& (!n
->sym
->attr
.dummy
|| n
->sym
->ns
!= ns
))
4257 gfc_error ("Variable %qs is not a dummy argument at %L",
4258 n
->sym
->name
, &n
->where
);
4261 if (n
->sym
->attr
.flavor
== FL_PROCEDURE
4262 && n
->sym
->result
== n
->sym
4263 && n
->sym
->attr
.function
)
4265 if (gfc_current_ns
->proc_name
== n
->sym
4266 || (gfc_current_ns
->parent
4267 && gfc_current_ns
->parent
->proc_name
== n
->sym
))
4269 if (gfc_current_ns
->proc_name
->attr
.entry_master
)
4271 gfc_entry_list
*el
= gfc_current_ns
->entries
;
4272 for (; el
; el
= el
->next
)
4273 if (el
->sym
== n
->sym
)
4278 if (gfc_current_ns
->parent
4279 && gfc_current_ns
->parent
->proc_name
->attr
.entry_master
)
4281 gfc_entry_list
*el
= gfc_current_ns
->parent
->entries
;
4282 for (; el
; el
= el
->next
)
4283 if (el
->sym
== n
->sym
)
4289 if (list
== OMP_LIST_MAP
4290 && n
->sym
->attr
.flavor
== FL_PARAMETER
)
4293 gfc_error ("Object %qs is not a variable at %L; parameters"
4294 " cannot be and need not be copied", n
->sym
->name
,
4297 gfc_error ("Object %qs is not a variable at %L; parameters"
4298 " cannot be and need not be mapped", n
->sym
->name
,
4302 gfc_error ("Object %qs is not a variable at %L", n
->sym
->name
,
4306 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
4307 if (list
!= OMP_LIST_FIRSTPRIVATE
4308 && list
!= OMP_LIST_LASTPRIVATE
4309 && list
!= OMP_LIST_ALIGNED
4310 && list
!= OMP_LIST_DEPEND
4311 && (list
!= OMP_LIST_MAP
|| openacc
)
4312 && list
!= OMP_LIST_FROM
4313 && list
!= OMP_LIST_TO
4314 && (list
!= OMP_LIST_REDUCTION
|| !openacc
))
4315 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
4317 bool component_ref_p
= false;
4319 /* Allow multiple components of the same (e.g. derived-type)
4320 variable here. Duplicate components are detected elsewhere. */
4321 if (n
->expr
&& n
->expr
->expr_type
== EXPR_VARIABLE
)
4322 for (gfc_ref
*ref
= n
->expr
->ref
; ref
; ref
= ref
->next
)
4323 if (ref
->type
== REF_COMPONENT
)
4324 component_ref_p
= true;
4325 if ((!component_ref_p
&& n
->sym
->comp_mark
)
4326 || (component_ref_p
&& n
->sym
->mark
))
4327 gfc_error ("Symbol %qs has mixed component and non-component "
4328 "accesses at %L", n
->sym
->name
, &n
->where
);
4329 else if (n
->sym
->mark
)
4330 gfc_error ("Symbol %qs present on multiple clauses at %L",
4331 n
->sym
->name
, &n
->where
);
4334 if (component_ref_p
)
4335 n
->sym
->comp_mark
= 1;
4341 gcc_assert (OMP_LIST_LASTPRIVATE
== OMP_LIST_FIRSTPRIVATE
+ 1);
4342 for (list
= OMP_LIST_FIRSTPRIVATE
; list
<= OMP_LIST_LASTPRIVATE
; list
++)
4343 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
4346 gfc_error ("Symbol %qs present on multiple clauses at %L",
4347 n
->sym
->name
, &n
->where
);
4351 for (n
= omp_clauses
->lists
[OMP_LIST_FIRSTPRIVATE
]; n
; n
= n
->next
)
4354 gfc_error ("Symbol %qs present on multiple clauses at %L",
4355 n
->sym
->name
, &n
->where
);
4359 for (n
= omp_clauses
->lists
[OMP_LIST_LASTPRIVATE
]; n
; n
= n
->next
)
4362 for (n
= omp_clauses
->lists
[OMP_LIST_LASTPRIVATE
]; n
; n
= n
->next
)
4365 gfc_error ("Symbol %qs present on multiple clauses at %L",
4366 n
->sym
->name
, &n
->where
);
4371 for (n
= omp_clauses
->lists
[OMP_LIST_ALIGNED
]; n
; n
= n
->next
)
4374 for (n
= omp_clauses
->lists
[OMP_LIST_ALIGNED
]; n
; n
= n
->next
)
4377 gfc_error ("Symbol %qs present on multiple clauses at %L",
4378 n
->sym
->name
, &n
->where
);
4383 /* OpenACC reductions. */
4386 for (n
= omp_clauses
->lists
[OMP_LIST_REDUCTION
]; n
; n
= n
->next
)
4389 for (n
= omp_clauses
->lists
[OMP_LIST_REDUCTION
]; n
; n
= n
->next
)
4392 gfc_error ("Symbol %qs present on multiple clauses at %L",
4393 n
->sym
->name
, &n
->where
);
4397 /* OpenACC does not support reductions on arrays. */
4399 gfc_error ("Array %qs is not permitted in reduction at %L",
4400 n
->sym
->name
, &n
->where
);
4404 for (n
= omp_clauses
->lists
[OMP_LIST_TO
]; n
; n
= n
->next
)
4406 for (n
= omp_clauses
->lists
[OMP_LIST_FROM
]; n
; n
= n
->next
)
4407 if (n
->expr
== NULL
)
4409 for (n
= omp_clauses
->lists
[OMP_LIST_TO
]; n
; n
= n
->next
)
4411 if (n
->expr
== NULL
&& n
->sym
->mark
)
4412 gfc_error ("Symbol %qs present on both FROM and TO clauses at %L",
4413 n
->sym
->name
, &n
->where
);
4418 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
4419 if ((n
= omp_clauses
->lists
[list
]) != NULL
)
4423 if (list
< OMP_LIST_NUM
)
4424 name
= clause_names
[list
];
4430 case OMP_LIST_COPYIN
:
4431 for (; n
!= NULL
; n
= n
->next
)
4433 if (!n
->sym
->attr
.threadprivate
)
4434 gfc_error ("Non-THREADPRIVATE object %qs in COPYIN clause"
4435 " at %L", n
->sym
->name
, &n
->where
);
4438 case OMP_LIST_COPYPRIVATE
:
4439 for (; n
!= NULL
; n
= n
->next
)
4441 if (n
->sym
->as
&& n
->sym
->as
->type
== AS_ASSUMED_SIZE
)
4442 gfc_error ("Assumed size array %qs in COPYPRIVATE clause "
4443 "at %L", n
->sym
->name
, &n
->where
);
4444 if (n
->sym
->attr
.pointer
&& n
->sym
->attr
.intent
== INTENT_IN
)
4445 gfc_error ("INTENT(IN) POINTER %qs in COPYPRIVATE clause "
4446 "at %L", n
->sym
->name
, &n
->where
);
4449 case OMP_LIST_SHARED
:
4450 for (; n
!= NULL
; n
= n
->next
)
4452 if (n
->sym
->attr
.threadprivate
)
4453 gfc_error ("THREADPRIVATE object %qs in SHARED clause at "
4454 "%L", n
->sym
->name
, &n
->where
);
4455 if (n
->sym
->attr
.cray_pointee
)
4456 gfc_error ("Cray pointee %qs in SHARED clause at %L",
4457 n
->sym
->name
, &n
->where
);
4458 if (n
->sym
->attr
.associate_var
)
4459 gfc_error ("ASSOCIATE name %qs in SHARED clause at %L",
4460 n
->sym
->name
, &n
->where
);
4463 case OMP_LIST_ALIGNED
:
4464 for (; n
!= NULL
; n
= n
->next
)
4466 if (!n
->sym
->attr
.pointer
4467 && !n
->sym
->attr
.allocatable
4468 && !n
->sym
->attr
.cray_pointer
4469 && (n
->sym
->ts
.type
!= BT_DERIVED
4470 || (n
->sym
->ts
.u
.derived
->from_intmod
4471 != INTMOD_ISO_C_BINDING
)
4472 || (n
->sym
->ts
.u
.derived
->intmod_sym_id
4473 != ISOCBINDING_PTR
)))
4474 gfc_error ("%qs in ALIGNED clause must be POINTER, "
4475 "ALLOCATABLE, Cray pointer or C_PTR at %L",
4476 n
->sym
->name
, &n
->where
);
4479 gfc_expr
*expr
= n
->expr
;
4481 if (!gfc_resolve_expr (expr
)
4482 || expr
->ts
.type
!= BT_INTEGER
4484 || gfc_extract_int (expr
, &alignment
)
4486 gfc_error ("%qs in ALIGNED clause at %L requires a scalar "
4487 "positive constant integer alignment "
4488 "expression", n
->sym
->name
, &n
->where
);
4492 case OMP_LIST_DEPEND
:
4496 case OMP_LIST_CACHE
:
4497 for (; n
!= NULL
; n
= n
->next
)
4499 if (list
== OMP_LIST_DEPEND
)
4501 if (n
->u
.depend_op
== OMP_DEPEND_SINK_FIRST
4502 || n
->u
.depend_op
== OMP_DEPEND_SINK
)
4504 if (code
->op
!= EXEC_OMP_ORDERED
)
4505 gfc_error ("SINK dependence type only allowed "
4506 "on ORDERED directive at %L", &n
->where
);
4507 else if (omp_clauses
->depend_source
)
4509 gfc_error ("DEPEND SINK used together with "
4510 "DEPEND SOURCE on the same construct "
4511 "at %L", &n
->where
);
4512 omp_clauses
->depend_source
= false;
4516 if (!gfc_resolve_expr (n
->expr
)
4517 || n
->expr
->ts
.type
!= BT_INTEGER
4518 || n
->expr
->rank
!= 0)
4519 gfc_error ("SINK addend not a constant integer "
4520 "at %L", &n
->where
);
4524 else if (code
->op
== EXEC_OMP_ORDERED
)
4525 gfc_error ("Only SOURCE or SINK dependence types "
4526 "are allowed on ORDERED directive at %L",
4529 gfc_ref
*array_ref
= NULL
;
4530 bool resolved
= false;
4533 array_ref
= n
->expr
->ref
;
4534 resolved
= gfc_resolve_expr (n
->expr
);
4536 /* Look through component refs to find last array
4538 if (openacc
&& resolved
)
4540 /* The "!$acc cache" directive allows rectangular
4541 subarrays to be specified, with some restrictions
4542 on the form of bounds (not implemented).
4543 Only raise an error here if we're really sure the
4544 array isn't contiguous. An expression such as
4545 arr(-n:n,-n:n) could be contiguous even if it looks
4546 like it may not be. */
4547 if (list
!= OMP_LIST_CACHE
4548 && !gfc_is_simply_contiguous (n
->expr
, false, true)
4549 && gfc_is_not_contiguous (n
->expr
))
4550 gfc_error ("Array is not contiguous at %L",
4554 && (array_ref
->type
== REF_COMPONENT
4555 || (array_ref
->type
== REF_ARRAY
4557 && (array_ref
->next
->type
4558 == REF_COMPONENT
))))
4559 array_ref
= array_ref
->next
;
4564 && (!resolved
|| n
->expr
->expr_type
!= EXPR_VARIABLE
)))
4567 || n
->expr
->expr_type
!= EXPR_VARIABLE
4569 || array_ref
->type
!= REF_ARRAY
)
4570 gfc_error ("%qs in %s clause at %L is not a proper "
4571 "array section", n
->sym
->name
, name
,
4576 gfc_array_ref
*ar
= &array_ref
->u
.ar
;
4577 for (i
= 0; i
< ar
->dimen
; i
++)
4580 gfc_error ("Stride should not be specified for "
4581 "array section in %s clause at %L",
4585 else if (ar
->dimen_type
[i
] != DIMEN_ELEMENT
4586 && ar
->dimen_type
[i
] != DIMEN_RANGE
)
4588 gfc_error ("%qs in %s clause at %L is not a "
4589 "proper array section",
4590 n
->sym
->name
, name
, &n
->where
);
4593 else if (list
== OMP_LIST_DEPEND
4595 && ar
->start
[i
]->expr_type
== EXPR_CONSTANT
4597 && ar
->end
[i
]->expr_type
== EXPR_CONSTANT
4598 && mpz_cmp (ar
->start
[i
]->value
.integer
,
4599 ar
->end
[i
]->value
.integer
) > 0)
4601 gfc_error ("%qs in DEPEND clause at %L is a "
4602 "zero size array section",
4603 n
->sym
->name
, &n
->where
);
4610 if (list
== OMP_LIST_MAP
4611 && n
->u
.map_op
== OMP_MAP_FORCE_DEVICEPTR
)
4612 resolve_oacc_deviceptr_clause (n
->sym
, n
->where
, name
);
4614 resolve_oacc_data_clauses (n
->sym
, n
->where
, name
);
4616 else if (list
!= OMP_LIST_DEPEND
4618 && n
->sym
->as
->type
== AS_ASSUMED_SIZE
)
4619 gfc_error ("Assumed size array %qs in %s clause at %L",
4620 n
->sym
->name
, name
, &n
->where
);
4621 if (list
== OMP_LIST_MAP
&& !openacc
)
4624 case EXEC_OMP_TARGET
:
4625 case EXEC_OMP_TARGET_DATA
:
4626 switch (n
->u
.map_op
)
4629 case OMP_MAP_ALWAYS_TO
:
4631 case OMP_MAP_ALWAYS_FROM
:
4632 case OMP_MAP_TOFROM
:
4633 case OMP_MAP_ALWAYS_TOFROM
:
4637 gfc_error ("TARGET%s with map-type other than TO, "
4638 "FROM, TOFROM, or ALLOC on MAP clause "
4640 code
->op
== EXEC_OMP_TARGET
4641 ? "" : " DATA", &n
->where
);
4645 case EXEC_OMP_TARGET_ENTER_DATA
:
4646 switch (n
->u
.map_op
)
4649 case OMP_MAP_ALWAYS_TO
:
4653 gfc_error ("TARGET ENTER DATA with map-type other "
4654 "than TO, or ALLOC on MAP clause at %L",
4659 case EXEC_OMP_TARGET_EXIT_DATA
:
4660 switch (n
->u
.map_op
)
4663 case OMP_MAP_ALWAYS_FROM
:
4664 case OMP_MAP_RELEASE
:
4665 case OMP_MAP_DELETE
:
4668 gfc_error ("TARGET EXIT DATA with map-type other "
4669 "than FROM, RELEASE, or DELETE on MAP "
4670 "clause at %L", &n
->where
);
4679 if (list
!= OMP_LIST_DEPEND
)
4680 for (n
= omp_clauses
->lists
[list
]; n
!= NULL
; n
= n
->next
)
4682 n
->sym
->attr
.referenced
= 1;
4683 if (n
->sym
->attr
.threadprivate
)
4684 gfc_error ("THREADPRIVATE object %qs in %s clause at %L",
4685 n
->sym
->name
, name
, &n
->where
);
4686 if (n
->sym
->attr
.cray_pointee
)
4687 gfc_error ("Cray pointee %qs in %s clause at %L",
4688 n
->sym
->name
, name
, &n
->where
);
4691 case OMP_LIST_IS_DEVICE_PTR
:
4692 if (!n
->sym
->attr
.dummy
)
4693 gfc_error ("Non-dummy object %qs in %s clause at %L",
4694 n
->sym
->name
, name
, &n
->where
);
4695 if (n
->sym
->attr
.allocatable
4696 || (n
->sym
->ts
.type
== BT_CLASS
4697 && CLASS_DATA (n
->sym
)->attr
.allocatable
))
4698 gfc_error ("ALLOCATABLE object %qs in %s clause at %L",
4699 n
->sym
->name
, name
, &n
->where
);
4700 if (n
->sym
->attr
.pointer
4701 || (n
->sym
->ts
.type
== BT_CLASS
4702 && CLASS_DATA (n
->sym
)->attr
.pointer
))
4703 gfc_error ("POINTER object %qs in %s clause at %L",
4704 n
->sym
->name
, name
, &n
->where
);
4705 if (n
->sym
->attr
.value
)
4706 gfc_error ("VALUE object %qs in %s clause at %L",
4707 n
->sym
->name
, name
, &n
->where
);
4709 case OMP_LIST_USE_DEVICE_PTR
:
4710 case OMP_LIST_USE_DEVICE_ADDR
:
4711 /* FIXME: Handle OMP_LIST_USE_DEVICE_PTR. */
4714 for (; n
!= NULL
; n
= n
->next
)
4717 if (n
->sym
->attr
.threadprivate
)
4718 gfc_error ("THREADPRIVATE object %qs in %s clause at %L",
4719 n
->sym
->name
, name
, &n
->where
);
4720 if (n
->sym
->attr
.cray_pointee
)
4721 gfc_error ("Cray pointee %qs in %s clause at %L",
4722 n
->sym
->name
, name
, &n
->where
);
4723 if (n
->sym
->attr
.associate_var
)
4724 gfc_error ("ASSOCIATE name %qs in %s clause at %L",
4725 n
->sym
->name
, name
, &n
->where
);
4726 if (list
!= OMP_LIST_PRIVATE
)
4728 if (n
->sym
->attr
.proc_pointer
&& list
== OMP_LIST_REDUCTION
)
4729 gfc_error ("Procedure pointer %qs in %s clause at %L",
4730 n
->sym
->name
, name
, &n
->where
);
4731 if (n
->sym
->attr
.pointer
&& list
== OMP_LIST_REDUCTION
)
4732 gfc_error ("POINTER object %qs in %s clause at %L",
4733 n
->sym
->name
, name
, &n
->where
);
4734 if (n
->sym
->attr
.cray_pointer
&& list
== OMP_LIST_REDUCTION
)
4735 gfc_error ("Cray pointer %qs in %s clause at %L",
4736 n
->sym
->name
, name
, &n
->where
);
4739 && (oacc_is_loop (code
)
4740 || code
->op
== EXEC_OACC_PARALLEL
4741 || code
->op
== EXEC_OACC_SERIAL
))
4742 check_array_not_assumed (n
->sym
, n
->where
, name
);
4743 else if (n
->sym
->as
&& n
->sym
->as
->type
== AS_ASSUMED_SIZE
)
4744 gfc_error ("Assumed size array %qs in %s clause at %L",
4745 n
->sym
->name
, name
, &n
->where
);
4746 if (n
->sym
->attr
.in_namelist
&& list
!= OMP_LIST_REDUCTION
)
4747 gfc_error ("Variable %qs in %s clause is used in "
4748 "NAMELIST statement at %L",
4749 n
->sym
->name
, name
, &n
->where
);
4750 if (n
->sym
->attr
.pointer
&& n
->sym
->attr
.intent
== INTENT_IN
)
4753 case OMP_LIST_PRIVATE
:
4754 case OMP_LIST_LASTPRIVATE
:
4755 case OMP_LIST_LINEAR
:
4756 /* case OMP_LIST_REDUCTION: */
4757 gfc_error ("INTENT(IN) POINTER %qs in %s clause at %L",
4758 n
->sym
->name
, name
, &n
->where
);
4766 case OMP_LIST_REDUCTION
:
4767 switch (n
->u
.reduction_op
)
4769 case OMP_REDUCTION_PLUS
:
4770 case OMP_REDUCTION_TIMES
:
4771 case OMP_REDUCTION_MINUS
:
4772 if (!gfc_numeric_ts (&n
->sym
->ts
))
4775 case OMP_REDUCTION_AND
:
4776 case OMP_REDUCTION_OR
:
4777 case OMP_REDUCTION_EQV
:
4778 case OMP_REDUCTION_NEQV
:
4779 if (n
->sym
->ts
.type
!= BT_LOGICAL
)
4782 case OMP_REDUCTION_MAX
:
4783 case OMP_REDUCTION_MIN
:
4784 if (n
->sym
->ts
.type
!= BT_INTEGER
4785 && n
->sym
->ts
.type
!= BT_REAL
)
4788 case OMP_REDUCTION_IAND
:
4789 case OMP_REDUCTION_IOR
:
4790 case OMP_REDUCTION_IEOR
:
4791 if (n
->sym
->ts
.type
!= BT_INTEGER
)
4794 case OMP_REDUCTION_USER
:
4804 const char *udr_name
= NULL
;
4807 udr_name
= n
->udr
->udr
->name
;
4809 = gfc_find_omp_udr (NULL
, udr_name
,
4811 if (n
->udr
->udr
== NULL
)
4819 if (udr_name
== NULL
)
4820 switch (n
->u
.reduction_op
)
4822 case OMP_REDUCTION_PLUS
:
4823 case OMP_REDUCTION_TIMES
:
4824 case OMP_REDUCTION_MINUS
:
4825 case OMP_REDUCTION_AND
:
4826 case OMP_REDUCTION_OR
:
4827 case OMP_REDUCTION_EQV
:
4828 case OMP_REDUCTION_NEQV
:
4829 udr_name
= gfc_op2string ((gfc_intrinsic_op
)
4832 case OMP_REDUCTION_MAX
:
4835 case OMP_REDUCTION_MIN
:
4838 case OMP_REDUCTION_IAND
:
4841 case OMP_REDUCTION_IOR
:
4844 case OMP_REDUCTION_IEOR
:
4850 gfc_error ("!$OMP DECLARE REDUCTION %s not found "
4851 "for type %s at %L", udr_name
,
4852 gfc_typename (&n
->sym
->ts
), &n
->where
);
4856 gfc_omp_udr
*udr
= n
->udr
->udr
;
4857 n
->u
.reduction_op
= OMP_REDUCTION_USER
;
4859 = resolve_omp_udr_clause (n
, udr
->combiner_ns
,
4862 if (udr
->initializer_ns
)
4864 = resolve_omp_udr_clause (n
,
4865 udr
->initializer_ns
,
4871 case OMP_LIST_LINEAR
:
4873 && n
->u
.linear_op
!= OMP_LINEAR_DEFAULT
4874 && n
->u
.linear_op
!= linear_op
)
4876 gfc_error ("LINEAR clause modifier used on DO or SIMD"
4877 " construct at %L", &n
->where
);
4878 linear_op
= n
->u
.linear_op
;
4880 else if (omp_clauses
->orderedc
)
4881 gfc_error ("LINEAR clause specified together with "
4882 "ORDERED clause with argument at %L",
4884 else if (n
->u
.linear_op
!= OMP_LINEAR_REF
4885 && n
->sym
->ts
.type
!= BT_INTEGER
)
4886 gfc_error ("LINEAR variable %qs must be INTEGER "
4887 "at %L", n
->sym
->name
, &n
->where
);
4888 else if ((n
->u
.linear_op
== OMP_LINEAR_REF
4889 || n
->u
.linear_op
== OMP_LINEAR_UVAL
)
4890 && n
->sym
->attr
.value
)
4891 gfc_error ("LINEAR dummy argument %qs with VALUE "
4892 "attribute with %s modifier at %L",
4894 n
->u
.linear_op
== OMP_LINEAR_REF
4895 ? "REF" : "UVAL", &n
->where
);
4898 gfc_expr
*expr
= n
->expr
;
4899 if (!gfc_resolve_expr (expr
)
4900 || expr
->ts
.type
!= BT_INTEGER
4902 gfc_error ("%qs in LINEAR clause at %L requires "
4903 "a scalar integer linear-step expression",
4904 n
->sym
->name
, &n
->where
);
4905 else if (!code
&& expr
->expr_type
!= EXPR_CONSTANT
)
4907 if (expr
->expr_type
== EXPR_VARIABLE
4908 && expr
->symtree
->n
.sym
->attr
.dummy
4909 && expr
->symtree
->n
.sym
->ns
== ns
)
4911 gfc_omp_namelist
*n2
;
4912 for (n2
= omp_clauses
->lists
[OMP_LIST_UNIFORM
];
4914 if (n2
->sym
== expr
->symtree
->n
.sym
)
4919 gfc_error ("%qs in LINEAR clause at %L requires "
4920 "a constant integer linear-step "
4921 "expression or dummy argument "
4922 "specified in UNIFORM clause",
4923 n
->sym
->name
, &n
->where
);
4927 /* Workaround for PR middle-end/26316, nothing really needs
4928 to be done here for OMP_LIST_PRIVATE. */
4929 case OMP_LIST_PRIVATE
:
4930 gcc_assert (code
&& code
->op
!= EXEC_NOP
);
4932 case OMP_LIST_USE_DEVICE
:
4933 if (n
->sym
->attr
.allocatable
4934 || (n
->sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (n
->sym
)
4935 && CLASS_DATA (n
->sym
)->attr
.allocatable
))
4936 gfc_error ("ALLOCATABLE object %qs in %s clause at %L",
4937 n
->sym
->name
, name
, &n
->where
);
4938 if (n
->sym
->ts
.type
== BT_CLASS
4939 && CLASS_DATA (n
->sym
)
4940 && CLASS_DATA (n
->sym
)->attr
.class_pointer
)
4941 gfc_error ("POINTER object %qs of polymorphic type in "
4942 "%s clause at %L", n
->sym
->name
, name
,
4944 if (n
->sym
->attr
.cray_pointer
)
4945 gfc_error ("Cray pointer object %qs in %s clause at %L",
4946 n
->sym
->name
, name
, &n
->where
);
4947 else if (n
->sym
->attr
.cray_pointee
)
4948 gfc_error ("Cray pointee object %qs in %s clause at %L",
4949 n
->sym
->name
, name
, &n
->where
);
4950 else if (n
->sym
->attr
.flavor
== FL_VARIABLE
4952 && !n
->sym
->attr
.pointer
)
4953 gfc_error ("%s clause variable %qs at %L is neither "
4954 "a POINTER nor an array", name
,
4955 n
->sym
->name
, &n
->where
);
4957 case OMP_LIST_DEVICE_RESIDENT
:
4958 check_symbol_not_pointer (n
->sym
, n
->where
, name
);
4959 check_array_not_assumed (n
->sym
, n
->where
, name
);
4968 if (omp_clauses
->safelen_expr
)
4969 resolve_positive_int_expr (omp_clauses
->safelen_expr
, "SAFELEN");
4970 if (omp_clauses
->simdlen_expr
)
4971 resolve_positive_int_expr (omp_clauses
->simdlen_expr
, "SIMDLEN");
4972 if (omp_clauses
->num_teams
)
4973 resolve_positive_int_expr (omp_clauses
->num_teams
, "NUM_TEAMS");
4974 if (omp_clauses
->device
)
4975 resolve_nonnegative_int_expr (omp_clauses
->device
, "DEVICE");
4976 if (omp_clauses
->hint
)
4977 resolve_scalar_int_expr (omp_clauses
->hint
, "HINT");
4978 if (omp_clauses
->priority
)
4979 resolve_nonnegative_int_expr (omp_clauses
->priority
, "PRIORITY");
4980 if (omp_clauses
->dist_chunk_size
)
4982 gfc_expr
*expr
= omp_clauses
->dist_chunk_size
;
4983 if (!gfc_resolve_expr (expr
)
4984 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
4985 gfc_error ("DIST_SCHEDULE clause's chunk_size at %L requires "
4986 "a scalar INTEGER expression", &expr
->where
);
4988 if (omp_clauses
->thread_limit
)
4989 resolve_positive_int_expr (omp_clauses
->thread_limit
, "THREAD_LIMIT");
4990 if (omp_clauses
->grainsize
)
4991 resolve_positive_int_expr (omp_clauses
->grainsize
, "GRAINSIZE");
4992 if (omp_clauses
->num_tasks
)
4993 resolve_positive_int_expr (omp_clauses
->num_tasks
, "NUM_TASKS");
4994 if (omp_clauses
->async
)
4995 if (omp_clauses
->async_expr
)
4996 resolve_scalar_int_expr (omp_clauses
->async_expr
, "ASYNC");
4997 if (omp_clauses
->num_gangs_expr
)
4998 resolve_positive_int_expr (omp_clauses
->num_gangs_expr
, "NUM_GANGS");
4999 if (omp_clauses
->num_workers_expr
)
5000 resolve_positive_int_expr (omp_clauses
->num_workers_expr
, "NUM_WORKERS");
5001 if (omp_clauses
->vector_length_expr
)
5002 resolve_positive_int_expr (omp_clauses
->vector_length_expr
,
5004 if (omp_clauses
->gang_num_expr
)
5005 resolve_positive_int_expr (omp_clauses
->gang_num_expr
, "GANG");
5006 if (omp_clauses
->gang_static_expr
)
5007 resolve_positive_int_expr (omp_clauses
->gang_static_expr
, "GANG");
5008 if (omp_clauses
->worker_expr
)
5009 resolve_positive_int_expr (omp_clauses
->worker_expr
, "WORKER");
5010 if (omp_clauses
->vector_expr
)
5011 resolve_positive_int_expr (omp_clauses
->vector_expr
, "VECTOR");
5012 for (el
= omp_clauses
->wait_list
; el
; el
= el
->next
)
5013 resolve_scalar_int_expr (el
->expr
, "WAIT");
5014 if (omp_clauses
->collapse
&& omp_clauses
->tile_list
)
5015 gfc_error ("Incompatible use of TILE and COLLAPSE at %L", &code
->loc
);
5016 if (omp_clauses
->depend_source
&& code
->op
!= EXEC_OMP_ORDERED
)
5017 gfc_error ("SOURCE dependence type only allowed "
5018 "on ORDERED directive at %L", &code
->loc
);
5019 if (!openacc
&& code
&& omp_clauses
->lists
[OMP_LIST_MAP
] == NULL
)
5021 const char *p
= NULL
;
5024 case EXEC_OMP_TARGET_DATA
: p
= "TARGET DATA"; break;
5025 case EXEC_OMP_TARGET_ENTER_DATA
: p
= "TARGET ENTER DATA"; break;
5026 case EXEC_OMP_TARGET_EXIT_DATA
: p
= "TARGET EXIT DATA"; break;
5030 gfc_error ("%s must contain at least one MAP clause at %L",
5036 /* Return true if SYM is ever referenced in EXPR except in the SE node. */
5039 expr_references_sym (gfc_expr
*e
, gfc_symbol
*s
, gfc_expr
*se
)
5041 gfc_actual_arglist
*arg
;
5042 if (e
== NULL
|| e
== se
)
5044 switch (e
->expr_type
)
5049 case EXPR_STRUCTURE
:
5051 if (e
->symtree
!= NULL
5052 && e
->symtree
->n
.sym
== s
)
5055 case EXPR_SUBSTRING
:
5057 && (expr_references_sym (e
->ref
->u
.ss
.start
, s
, se
)
5058 || expr_references_sym (e
->ref
->u
.ss
.end
, s
, se
)))
5062 if (expr_references_sym (e
->value
.op
.op2
, s
, se
))
5064 return expr_references_sym (e
->value
.op
.op1
, s
, se
);
5066 for (arg
= e
->value
.function
.actual
; arg
; arg
= arg
->next
)
5067 if (expr_references_sym (arg
->expr
, s
, se
))
5076 /* If EXPR is a conversion function that widens the type
5077 if WIDENING is true or narrows the type if WIDENING is false,
5078 return the inner expression, otherwise return NULL. */
5081 is_conversion (gfc_expr
*expr
, bool widening
)
5083 gfc_typespec
*ts1
, *ts2
;
5085 if (expr
->expr_type
!= EXPR_FUNCTION
5086 || expr
->value
.function
.isym
== NULL
5087 || expr
->value
.function
.esym
!= NULL
5088 || expr
->value
.function
.isym
->id
!= GFC_ISYM_CONVERSION
)
5094 ts2
= &expr
->value
.function
.actual
->expr
->ts
;
5098 ts1
= &expr
->value
.function
.actual
->expr
->ts
;
5102 if (ts1
->type
> ts2
->type
5103 || (ts1
->type
== ts2
->type
&& ts1
->kind
> ts2
->kind
))
5104 return expr
->value
.function
.actual
->expr
;
5111 resolve_omp_atomic (gfc_code
*code
)
5113 gfc_code
*atomic_code
= code
;
5115 gfc_expr
*expr2
, *expr2_tmp
;
5116 gfc_omp_atomic_op aop
5117 = (gfc_omp_atomic_op
) (atomic_code
->ext
.omp_atomic
& GFC_OMP_ATOMIC_MASK
);
5119 code
= code
->block
->next
;
5120 /* resolve_blocks asserts this is initially EXEC_ASSIGN.
5121 If it changed to EXEC_NOP, assume an error has been emitted already. */
5122 if (code
->op
== EXEC_NOP
)
5124 if (code
->op
!= EXEC_ASSIGN
)
5127 gfc_error ("unexpected !$OMP ATOMIC expression at %L", &code
->loc
);
5130 if (aop
!= GFC_OMP_ATOMIC_CAPTURE
)
5132 if (code
->next
!= NULL
)
5137 if (code
->next
== NULL
)
5139 if (code
->next
->op
== EXEC_NOP
)
5141 if (code
->next
->op
!= EXEC_ASSIGN
|| code
->next
->next
)
5148 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
5149 || code
->expr1
->symtree
== NULL
5150 || code
->expr1
->rank
!= 0
5151 || (code
->expr1
->ts
.type
!= BT_INTEGER
5152 && code
->expr1
->ts
.type
!= BT_REAL
5153 && code
->expr1
->ts
.type
!= BT_COMPLEX
5154 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
5156 gfc_error ("!$OMP ATOMIC statement must set a scalar variable of "
5157 "intrinsic type at %L", &code
->loc
);
5161 var
= code
->expr1
->symtree
->n
.sym
;
5162 expr2
= is_conversion (code
->expr2
, false);
5165 if (aop
== GFC_OMP_ATOMIC_READ
|| aop
== GFC_OMP_ATOMIC_WRITE
)
5166 expr2
= is_conversion (code
->expr2
, true);
5168 expr2
= code
->expr2
;
5173 case GFC_OMP_ATOMIC_READ
:
5174 if (expr2
->expr_type
!= EXPR_VARIABLE
5175 || expr2
->symtree
== NULL
5177 || (expr2
->ts
.type
!= BT_INTEGER
5178 && expr2
->ts
.type
!= BT_REAL
5179 && expr2
->ts
.type
!= BT_COMPLEX
5180 && expr2
->ts
.type
!= BT_LOGICAL
))
5181 gfc_error ("!$OMP ATOMIC READ statement must read from a scalar "
5182 "variable of intrinsic type at %L", &expr2
->where
);
5184 case GFC_OMP_ATOMIC_WRITE
:
5185 if (expr2
->rank
!= 0 || expr_references_sym (code
->expr2
, var
, NULL
))
5186 gfc_error ("expr in !$OMP ATOMIC WRITE assignment var = expr "
5187 "must be scalar and cannot reference var at %L",
5190 case GFC_OMP_ATOMIC_CAPTURE
:
5192 if (expr2
== code
->expr2
)
5194 expr2_tmp
= is_conversion (code
->expr2
, true);
5195 if (expr2_tmp
== NULL
)
5198 if (expr2_tmp
->expr_type
== EXPR_VARIABLE
)
5200 if (expr2_tmp
->symtree
== NULL
5201 || expr2_tmp
->rank
!= 0
5202 || (expr2_tmp
->ts
.type
!= BT_INTEGER
5203 && expr2_tmp
->ts
.type
!= BT_REAL
5204 && expr2_tmp
->ts
.type
!= BT_COMPLEX
5205 && expr2_tmp
->ts
.type
!= BT_LOGICAL
)
5206 || expr2_tmp
->symtree
->n
.sym
== var
)
5208 gfc_error ("!$OMP ATOMIC CAPTURE capture statement must read from "
5209 "a scalar variable of intrinsic type at %L",
5213 var
= expr2_tmp
->symtree
->n
.sym
;
5215 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
5216 || code
->expr1
->symtree
== NULL
5217 || code
->expr1
->rank
!= 0
5218 || (code
->expr1
->ts
.type
!= BT_INTEGER
5219 && code
->expr1
->ts
.type
!= BT_REAL
5220 && code
->expr1
->ts
.type
!= BT_COMPLEX
5221 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
5223 gfc_error ("!$OMP ATOMIC CAPTURE update statement must set "
5224 "a scalar variable of intrinsic type at %L",
5225 &code
->expr1
->where
);
5228 if (code
->expr1
->symtree
->n
.sym
!= var
)
5230 gfc_error ("!$OMP ATOMIC CAPTURE capture statement reads from "
5231 "different variable than update statement writes "
5232 "into at %L", &code
->expr1
->where
);
5235 expr2
= is_conversion (code
->expr2
, false);
5237 expr2
= code
->expr2
;
5244 if (gfc_expr_attr (code
->expr1
).allocatable
)
5246 gfc_error ("!$OMP ATOMIC with ALLOCATABLE variable at %L",
5251 if (aop
== GFC_OMP_ATOMIC_CAPTURE
5252 && code
->next
== NULL
5253 && code
->expr2
->rank
== 0
5254 && !expr_references_sym (code
->expr2
, var
, NULL
))
5255 atomic_code
->ext
.omp_atomic
5256 = (gfc_omp_atomic_op
) (atomic_code
->ext
.omp_atomic
5257 | GFC_OMP_ATOMIC_SWAP
);
5258 else if (expr2
->expr_type
== EXPR_OP
)
5260 gfc_expr
*v
= NULL
, *e
, *c
;
5261 gfc_intrinsic_op op
= expr2
->value
.op
.op
;
5262 gfc_intrinsic_op alt_op
= INTRINSIC_NONE
;
5266 case INTRINSIC_PLUS
:
5267 alt_op
= INTRINSIC_MINUS
;
5269 case INTRINSIC_TIMES
:
5270 alt_op
= INTRINSIC_DIVIDE
;
5272 case INTRINSIC_MINUS
:
5273 alt_op
= INTRINSIC_PLUS
;
5275 case INTRINSIC_DIVIDE
:
5276 alt_op
= INTRINSIC_TIMES
;
5282 alt_op
= INTRINSIC_NEQV
;
5284 case INTRINSIC_NEQV
:
5285 alt_op
= INTRINSIC_EQV
;
5288 gfc_error ("!$OMP ATOMIC assignment operator must be binary "
5289 "+, *, -, /, .AND., .OR., .EQV. or .NEQV. at %L",
5294 /* Check for var = var op expr resp. var = expr op var where
5295 expr doesn't reference var and var op expr is mathematically
5296 equivalent to var op (expr) resp. expr op var equivalent to
5297 (expr) op var. We rely here on the fact that the matcher
5298 for x op1 y op2 z where op1 and op2 have equal precedence
5299 returns (x op1 y) op2 z. */
5300 e
= expr2
->value
.op
.op2
;
5301 if (e
->expr_type
== EXPR_VARIABLE
5302 && e
->symtree
!= NULL
5303 && e
->symtree
->n
.sym
== var
)
5305 else if ((c
= is_conversion (e
, true)) != NULL
5306 && c
->expr_type
== EXPR_VARIABLE
5307 && c
->symtree
!= NULL
5308 && c
->symtree
->n
.sym
== var
)
5312 gfc_expr
**p
= NULL
, **q
;
5313 for (q
= &expr2
->value
.op
.op1
; (e
= *q
) != NULL
; )
5314 if (e
->expr_type
== EXPR_VARIABLE
5315 && e
->symtree
!= NULL
5316 && e
->symtree
->n
.sym
== var
)
5321 else if ((c
= is_conversion (e
, true)) != NULL
)
5322 q
= &e
->value
.function
.actual
->expr
;
5323 else if (e
->expr_type
!= EXPR_OP
5324 || (e
->value
.op
.op
!= op
5325 && e
->value
.op
.op
!= alt_op
)
5331 q
= &e
->value
.op
.op1
;
5336 gfc_error ("!$OMP ATOMIC assignment must be var = var op expr "
5337 "or var = expr op var at %L", &expr2
->where
);
5344 switch (e
->value
.op
.op
)
5346 case INTRINSIC_MINUS
:
5347 case INTRINSIC_DIVIDE
:
5349 case INTRINSIC_NEQV
:
5350 gfc_error ("!$OMP ATOMIC var = var op expr not "
5351 "mathematically equivalent to var = var op "
5352 "(expr) at %L", &expr2
->where
);
5358 /* Canonicalize into var = var op (expr). */
5359 *p
= e
->value
.op
.op2
;
5360 e
->value
.op
.op2
= expr2
;
5362 if (code
->expr2
== expr2
)
5363 code
->expr2
= expr2
= e
;
5365 code
->expr2
->value
.function
.actual
->expr
= expr2
= e
;
5367 if (!gfc_compare_types (&expr2
->value
.op
.op1
->ts
, &expr2
->ts
))
5369 for (p
= &expr2
->value
.op
.op1
; *p
!= v
;
5370 p
= &(*p
)->value
.function
.actual
->expr
)
5373 gfc_free_expr (expr2
->value
.op
.op1
);
5374 expr2
->value
.op
.op1
= v
;
5375 gfc_convert_type (v
, &expr2
->ts
, 2);
5380 if (e
->rank
!= 0 || expr_references_sym (code
->expr2
, var
, v
))
5382 gfc_error ("expr in !$OMP ATOMIC assignment var = var op expr "
5383 "must be scalar and cannot reference var at %L",
5388 else if (expr2
->expr_type
== EXPR_FUNCTION
5389 && expr2
->value
.function
.isym
!= NULL
5390 && expr2
->value
.function
.esym
== NULL
5391 && expr2
->value
.function
.actual
!= NULL
5392 && expr2
->value
.function
.actual
->next
!= NULL
)
5394 gfc_actual_arglist
*arg
, *var_arg
;
5396 switch (expr2
->value
.function
.isym
->id
)
5404 if (expr2
->value
.function
.actual
->next
->next
!= NULL
)
5406 gfc_error ("!$OMP ATOMIC assignment intrinsic IAND, IOR "
5407 "or IEOR must have two arguments at %L",
5413 gfc_error ("!$OMP ATOMIC assignment intrinsic must be "
5414 "MIN, MAX, IAND, IOR or IEOR at %L",
5420 for (arg
= expr2
->value
.function
.actual
; arg
; arg
= arg
->next
)
5422 if ((arg
== expr2
->value
.function
.actual
5423 || (var_arg
== NULL
&& arg
->next
== NULL
))
5424 && arg
->expr
->expr_type
== EXPR_VARIABLE
5425 && arg
->expr
->symtree
!= NULL
5426 && arg
->expr
->symtree
->n
.sym
== var
)
5428 else if (expr_references_sym (arg
->expr
, var
, NULL
))
5430 gfc_error ("!$OMP ATOMIC intrinsic arguments except one must "
5431 "not reference %qs at %L",
5432 var
->name
, &arg
->expr
->where
);
5435 if (arg
->expr
->rank
!= 0)
5437 gfc_error ("!$OMP ATOMIC intrinsic arguments must be scalar "
5438 "at %L", &arg
->expr
->where
);
5443 if (var_arg
== NULL
)
5445 gfc_error ("First or last !$OMP ATOMIC intrinsic argument must "
5446 "be %qs at %L", var
->name
, &expr2
->where
);
5450 if (var_arg
!= expr2
->value
.function
.actual
)
5452 /* Canonicalize, so that var comes first. */
5453 gcc_assert (var_arg
->next
== NULL
);
5454 for (arg
= expr2
->value
.function
.actual
;
5455 arg
->next
!= var_arg
; arg
= arg
->next
)
5457 var_arg
->next
= expr2
->value
.function
.actual
;
5458 expr2
->value
.function
.actual
= var_arg
;
5463 gfc_error ("!$OMP ATOMIC assignment must have an operator or "
5464 "intrinsic on right hand side at %L", &expr2
->where
);
5466 if (aop
== GFC_OMP_ATOMIC_CAPTURE
&& code
->next
)
5469 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
5470 || code
->expr1
->symtree
== NULL
5471 || code
->expr1
->rank
!= 0
5472 || (code
->expr1
->ts
.type
!= BT_INTEGER
5473 && code
->expr1
->ts
.type
!= BT_REAL
5474 && code
->expr1
->ts
.type
!= BT_COMPLEX
5475 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
5477 gfc_error ("!$OMP ATOMIC CAPTURE capture statement must set "
5478 "a scalar variable of intrinsic type at %L",
5479 &code
->expr1
->where
);
5483 expr2
= is_conversion (code
->expr2
, false);
5486 expr2
= is_conversion (code
->expr2
, true);
5488 expr2
= code
->expr2
;
5491 if (expr2
->expr_type
!= EXPR_VARIABLE
5492 || expr2
->symtree
== NULL
5494 || (expr2
->ts
.type
!= BT_INTEGER
5495 && expr2
->ts
.type
!= BT_REAL
5496 && expr2
->ts
.type
!= BT_COMPLEX
5497 && expr2
->ts
.type
!= BT_LOGICAL
))
5499 gfc_error ("!$OMP ATOMIC CAPTURE capture statement must read "
5500 "from a scalar variable of intrinsic type at %L",
5504 if (expr2
->symtree
->n
.sym
!= var
)
5506 gfc_error ("!$OMP ATOMIC CAPTURE capture statement reads from "
5507 "different variable than update statement writes "
5508 "into at %L", &expr2
->where
);
5515 static struct fortran_omp_context
5518 hash_set
<gfc_symbol
*> *sharing_clauses
;
5519 hash_set
<gfc_symbol
*> *private_iterators
;
5520 struct fortran_omp_context
*previous
;
5523 static gfc_code
*omp_current_do_code
;
5524 static int omp_current_do_collapse
;
5527 gfc_resolve_omp_do_blocks (gfc_code
*code
, gfc_namespace
*ns
)
5529 if (code
->block
->next
&& code
->block
->next
->op
== EXEC_DO
)
5534 omp_current_do_code
= code
->block
->next
;
5535 if (code
->ext
.omp_clauses
->orderedc
)
5536 omp_current_do_collapse
= code
->ext
.omp_clauses
->orderedc
;
5538 omp_current_do_collapse
= code
->ext
.omp_clauses
->collapse
;
5539 for (i
= 1, c
= omp_current_do_code
; i
< omp_current_do_collapse
; i
++)
5542 if (c
->op
!= EXEC_DO
|| c
->next
== NULL
)
5545 if (c
->op
!= EXEC_DO
)
5548 if (i
< omp_current_do_collapse
|| omp_current_do_collapse
<= 0)
5549 omp_current_do_collapse
= 1;
5551 gfc_resolve_blocks (code
->block
, ns
);
5552 omp_current_do_collapse
= 0;
5553 omp_current_do_code
= NULL
;
5558 gfc_resolve_omp_parallel_blocks (gfc_code
*code
, gfc_namespace
*ns
)
5560 struct fortran_omp_context ctx
;
5561 gfc_omp_clauses
*omp_clauses
= code
->ext
.omp_clauses
;
5562 gfc_omp_namelist
*n
;
5566 ctx
.sharing_clauses
= new hash_set
<gfc_symbol
*>;
5567 ctx
.private_iterators
= new hash_set
<gfc_symbol
*>;
5568 ctx
.previous
= omp_current_ctx
;
5569 ctx
.is_openmp
= true;
5570 omp_current_ctx
= &ctx
;
5572 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
5575 case OMP_LIST_SHARED
:
5576 case OMP_LIST_PRIVATE
:
5577 case OMP_LIST_FIRSTPRIVATE
:
5578 case OMP_LIST_LASTPRIVATE
:
5579 case OMP_LIST_REDUCTION
:
5580 case OMP_LIST_LINEAR
:
5581 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
5582 ctx
.sharing_clauses
->add (n
->sym
);
5590 case EXEC_OMP_PARALLEL_DO
:
5591 case EXEC_OMP_PARALLEL_DO_SIMD
:
5592 case EXEC_OMP_TARGET_PARALLEL_DO
:
5593 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
5594 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
5595 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
5596 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
5597 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
5598 case EXEC_OMP_TASKLOOP
:
5599 case EXEC_OMP_TASKLOOP_SIMD
:
5600 case EXEC_OMP_TEAMS_DISTRIBUTE
:
5601 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
5602 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
5603 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
5604 gfc_resolve_omp_do_blocks (code
, ns
);
5607 gfc_resolve_blocks (code
->block
, ns
);
5610 omp_current_ctx
= ctx
.previous
;
5611 delete ctx
.sharing_clauses
;
5612 delete ctx
.private_iterators
;
5616 /* Save and clear openmp.c private state. */
5619 gfc_omp_save_and_clear_state (struct gfc_omp_saved_state
*state
)
5621 state
->ptrs
[0] = omp_current_ctx
;
5622 state
->ptrs
[1] = omp_current_do_code
;
5623 state
->ints
[0] = omp_current_do_collapse
;
5624 omp_current_ctx
= NULL
;
5625 omp_current_do_code
= NULL
;
5626 omp_current_do_collapse
= 0;
5630 /* Restore openmp.c private state from the saved state. */
5633 gfc_omp_restore_state (struct gfc_omp_saved_state
*state
)
5635 omp_current_ctx
= (struct fortran_omp_context
*) state
->ptrs
[0];
5636 omp_current_do_code
= (gfc_code
*) state
->ptrs
[1];
5637 omp_current_do_collapse
= state
->ints
[0];
5641 /* Note a DO iterator variable. This is special in !$omp parallel
5642 construct, where they are predetermined private. */
5645 gfc_resolve_do_iterator (gfc_code
*code
, gfc_symbol
*sym
, bool add_clause
)
5647 if (omp_current_ctx
== NULL
)
5650 int i
= omp_current_do_collapse
;
5651 gfc_code
*c
= omp_current_do_code
;
5653 if (sym
->attr
.threadprivate
)
5656 /* !$omp do and !$omp parallel do iteration variable is predetermined
5657 private just in the !$omp do resp. !$omp parallel do construct,
5658 with no implications for the outer parallel constructs. */
5668 /* An openacc context may represent a data clause. Abort if so. */
5669 if (!omp_current_ctx
->is_openmp
&& !oacc_is_loop (omp_current_ctx
->code
))
5672 if (omp_current_ctx
->sharing_clauses
->contains (sym
))
5675 if (! omp_current_ctx
->private_iterators
->add (sym
) && add_clause
)
5677 gfc_omp_clauses
*omp_clauses
= omp_current_ctx
->code
->ext
.omp_clauses
;
5678 gfc_omp_namelist
*p
;
5680 p
= gfc_get_omp_namelist ();
5682 p
->next
= omp_clauses
->lists
[OMP_LIST_PRIVATE
];
5683 omp_clauses
->lists
[OMP_LIST_PRIVATE
] = p
;
5688 handle_local_var (gfc_symbol
*sym
)
5690 if (sym
->attr
.flavor
!= FL_VARIABLE
5692 || (sym
->ts
.type
!= BT_INTEGER
&& sym
->ts
.type
!= BT_REAL
))
5694 gfc_resolve_do_iterator (sym
->ns
->code
, sym
, false);
5698 gfc_resolve_omp_local_vars (gfc_namespace
*ns
)
5700 if (omp_current_ctx
)
5701 gfc_traverse_ns (ns
, handle_local_var
);
5705 resolve_omp_do (gfc_code
*code
)
5707 gfc_code
*do_code
, *c
;
5708 int list
, i
, collapse
;
5709 gfc_omp_namelist
*n
;
5712 bool is_simd
= false;
5716 case EXEC_OMP_DISTRIBUTE
: name
= "!$OMP DISTRIBUTE"; break;
5717 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
5718 name
= "!$OMP DISTRIBUTE PARALLEL DO";
5720 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
5721 name
= "!$OMP DISTRIBUTE PARALLEL DO SIMD";
5724 case EXEC_OMP_DISTRIBUTE_SIMD
:
5725 name
= "!$OMP DISTRIBUTE SIMD";
5728 case EXEC_OMP_DO
: name
= "!$OMP DO"; break;
5729 case EXEC_OMP_DO_SIMD
: name
= "!$OMP DO SIMD"; is_simd
= true; break;
5730 case EXEC_OMP_PARALLEL_DO
: name
= "!$OMP PARALLEL DO"; break;
5731 case EXEC_OMP_PARALLEL_DO_SIMD
:
5732 name
= "!$OMP PARALLEL DO SIMD";
5735 case EXEC_OMP_SIMD
: name
= "!$OMP SIMD"; is_simd
= true; break;
5736 case EXEC_OMP_TARGET_PARALLEL_DO
: name
= "!$OMP TARGET PARALLEL DO"; break;
5737 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
5738 name
= "!$OMP TARGET PARALLEL DO SIMD";
5741 case EXEC_OMP_TARGET_SIMD
:
5742 name
= "!$OMP TARGET SIMD";
5745 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
5746 name
= "!$OMP TARGET TEAMS DISTRIBUTE";
5748 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
5749 name
= "!$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO";
5751 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
5752 name
= "!$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD";
5755 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
5756 name
= "!$OMP TARGET TEAMS DISTRIBUTE SIMD";
5759 case EXEC_OMP_TASKLOOP
: name
= "!$OMP TASKLOOP"; break;
5760 case EXEC_OMP_TASKLOOP_SIMD
:
5761 name
= "!$OMP TASKLOOP SIMD";
5764 case EXEC_OMP_TEAMS_DISTRIBUTE
: name
= "!$OMP TEAMS DISTRIBUTE"; break;
5765 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
5766 name
= "!$OMP TEAMS DISTRIBUTE PARALLEL DO";
5768 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
5769 name
= "!$OMP TEAMS DISTRIBUTE PARALLEL DO SIMD";
5772 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
5773 name
= "!$OMP TEAMS DISTRIBUTE SIMD";
5776 default: gcc_unreachable ();
5779 if (code
->ext
.omp_clauses
)
5780 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
);
5782 do_code
= code
->block
->next
;
5783 if (code
->ext
.omp_clauses
->orderedc
)
5784 collapse
= code
->ext
.omp_clauses
->orderedc
;
5787 collapse
= code
->ext
.omp_clauses
->collapse
;
5791 for (i
= 1; i
<= collapse
; i
++)
5793 if (do_code
->op
== EXEC_DO_WHILE
)
5795 gfc_error ("%s cannot be a DO WHILE or DO without loop control "
5796 "at %L", name
, &do_code
->loc
);
5799 if (do_code
->op
== EXEC_DO_CONCURRENT
)
5801 gfc_error ("%s cannot be a DO CONCURRENT loop at %L", name
,
5805 gcc_assert (do_code
->op
== EXEC_DO
);
5806 if (do_code
->ext
.iterator
->var
->ts
.type
!= BT_INTEGER
)
5807 gfc_error ("%s iteration variable must be of type integer at %L",
5808 name
, &do_code
->loc
);
5809 dovar
= do_code
->ext
.iterator
->var
->symtree
->n
.sym
;
5810 if (dovar
->attr
.threadprivate
)
5811 gfc_error ("%s iteration variable must not be THREADPRIVATE "
5812 "at %L", name
, &do_code
->loc
);
5813 if (code
->ext
.omp_clauses
)
5814 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
5816 ? (list
!= OMP_LIST_PRIVATE
&& list
!= OMP_LIST_LASTPRIVATE
)
5817 : code
->ext
.omp_clauses
->collapse
> 1
5818 ? (list
!= OMP_LIST_LASTPRIVATE
)
5819 : (list
!= OMP_LIST_LINEAR
))
5820 for (n
= code
->ext
.omp_clauses
->lists
[list
]; n
; n
= n
->next
)
5821 if (dovar
== n
->sym
)
5824 gfc_error ("%s iteration variable present on clause "
5825 "other than PRIVATE or LASTPRIVATE at %L",
5826 name
, &do_code
->loc
);
5827 else if (code
->ext
.omp_clauses
->collapse
> 1)
5828 gfc_error ("%s iteration variable present on clause "
5829 "other than LASTPRIVATE at %L",
5830 name
, &do_code
->loc
);
5832 gfc_error ("%s iteration variable present on clause "
5833 "other than LINEAR at %L",
5834 name
, &do_code
->loc
);
5839 gfc_code
*do_code2
= code
->block
->next
;
5842 for (j
= 1; j
< i
; j
++)
5844 gfc_symbol
*ivar
= do_code2
->ext
.iterator
->var
->symtree
->n
.sym
;
5846 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->start
)
5847 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->end
)
5848 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->step
))
5850 gfc_error ("%s collapsed loops don't form rectangular "
5851 "iteration space at %L", name
, &do_code
->loc
);
5854 do_code2
= do_code2
->block
->next
;
5859 for (c
= do_code
->next
; c
; c
= c
->next
)
5860 if (c
->op
!= EXEC_NOP
&& c
->op
!= EXEC_CONTINUE
)
5862 gfc_error ("collapsed %s loops not perfectly nested at %L",
5868 do_code
= do_code
->block
;
5869 if (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
)
5871 gfc_error ("not enough DO loops for collapsed %s at %L",
5875 do_code
= do_code
->next
;
5877 || (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
))
5879 gfc_error ("not enough DO loops for collapsed %s at %L",
5887 oacc_is_parallel (gfc_code
*code
)
5889 return code
->op
== EXEC_OACC_PARALLEL
|| code
->op
== EXEC_OACC_PARALLEL_LOOP
;
5892 static gfc_statement
5893 omp_code_to_statement (gfc_code
*code
)
5897 case EXEC_OMP_PARALLEL
:
5898 return ST_OMP_PARALLEL
;
5899 case EXEC_OMP_PARALLEL_SECTIONS
:
5900 return ST_OMP_PARALLEL_SECTIONS
;
5901 case EXEC_OMP_SECTIONS
:
5902 return ST_OMP_SECTIONS
;
5903 case EXEC_OMP_ORDERED
:
5904 return ST_OMP_ORDERED
;
5905 case EXEC_OMP_CRITICAL
:
5906 return ST_OMP_CRITICAL
;
5907 case EXEC_OMP_MASTER
:
5908 return ST_OMP_MASTER
;
5909 case EXEC_OMP_SINGLE
:
5910 return ST_OMP_SINGLE
;
5913 case EXEC_OMP_WORKSHARE
:
5914 return ST_OMP_WORKSHARE
;
5915 case EXEC_OMP_PARALLEL_WORKSHARE
:
5916 return ST_OMP_PARALLEL_WORKSHARE
;
5919 case EXEC_OMP_ATOMIC
:
5920 return ST_OMP_ATOMIC
;
5921 case EXEC_OMP_BARRIER
:
5922 return ST_OMP_BARRIER
;
5923 case EXEC_OMP_CANCEL
:
5924 return ST_OMP_CANCEL
;
5925 case EXEC_OMP_CANCELLATION_POINT
:
5926 return ST_OMP_CANCELLATION_POINT
;
5927 case EXEC_OMP_FLUSH
:
5928 return ST_OMP_FLUSH
;
5929 case EXEC_OMP_DISTRIBUTE
:
5930 return ST_OMP_DISTRIBUTE
;
5931 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
5932 return ST_OMP_DISTRIBUTE_PARALLEL_DO
;
5933 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
5934 return ST_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
;
5935 case EXEC_OMP_DISTRIBUTE_SIMD
:
5936 return ST_OMP_DISTRIBUTE_SIMD
;
5937 case EXEC_OMP_DO_SIMD
:
5938 return ST_OMP_DO_SIMD
;
5941 case EXEC_OMP_TARGET
:
5942 return ST_OMP_TARGET
;
5943 case EXEC_OMP_TARGET_DATA
:
5944 return ST_OMP_TARGET_DATA
;
5945 case EXEC_OMP_TARGET_ENTER_DATA
:
5946 return ST_OMP_TARGET_ENTER_DATA
;
5947 case EXEC_OMP_TARGET_EXIT_DATA
:
5948 return ST_OMP_TARGET_EXIT_DATA
;
5949 case EXEC_OMP_TARGET_PARALLEL
:
5950 return ST_OMP_TARGET_PARALLEL
;
5951 case EXEC_OMP_TARGET_PARALLEL_DO
:
5952 return ST_OMP_TARGET_PARALLEL_DO
;
5953 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
5954 return ST_OMP_TARGET_PARALLEL_DO_SIMD
;
5955 case EXEC_OMP_TARGET_SIMD
:
5956 return ST_OMP_TARGET_SIMD
;
5957 case EXEC_OMP_TARGET_TEAMS
:
5958 return ST_OMP_TARGET_TEAMS
;
5959 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
5960 return ST_OMP_TARGET_TEAMS_DISTRIBUTE
;
5961 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
5962 return ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
;
5963 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
5964 return ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
;
5965 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
5966 return ST_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
;
5967 case EXEC_OMP_TARGET_UPDATE
:
5968 return ST_OMP_TARGET_UPDATE
;
5969 case EXEC_OMP_TASKGROUP
:
5970 return ST_OMP_TASKGROUP
;
5971 case EXEC_OMP_TASKLOOP
:
5972 return ST_OMP_TASKLOOP
;
5973 case EXEC_OMP_TASKLOOP_SIMD
:
5974 return ST_OMP_TASKLOOP_SIMD
;
5975 case EXEC_OMP_TASKWAIT
:
5976 return ST_OMP_TASKWAIT
;
5977 case EXEC_OMP_TASKYIELD
:
5978 return ST_OMP_TASKYIELD
;
5979 case EXEC_OMP_TEAMS
:
5980 return ST_OMP_TEAMS
;
5981 case EXEC_OMP_TEAMS_DISTRIBUTE
:
5982 return ST_OMP_TEAMS_DISTRIBUTE
;
5983 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
5984 return ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
;
5985 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
5986 return ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
;
5987 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
5988 return ST_OMP_TEAMS_DISTRIBUTE_SIMD
;
5989 case EXEC_OMP_PARALLEL_DO
:
5990 return ST_OMP_PARALLEL_DO
;
5991 case EXEC_OMP_PARALLEL_DO_SIMD
:
5992 return ST_OMP_PARALLEL_DO_SIMD
;
5999 static gfc_statement
6000 oacc_code_to_statement (gfc_code
*code
)
6004 case EXEC_OACC_PARALLEL
:
6005 return ST_OACC_PARALLEL
;
6006 case EXEC_OACC_KERNELS
:
6007 return ST_OACC_KERNELS
;
6008 case EXEC_OACC_SERIAL
:
6009 return ST_OACC_SERIAL
;
6010 case EXEC_OACC_DATA
:
6011 return ST_OACC_DATA
;
6012 case EXEC_OACC_HOST_DATA
:
6013 return ST_OACC_HOST_DATA
;
6014 case EXEC_OACC_PARALLEL_LOOP
:
6015 return ST_OACC_PARALLEL_LOOP
;
6016 case EXEC_OACC_KERNELS_LOOP
:
6017 return ST_OACC_KERNELS_LOOP
;
6018 case EXEC_OACC_SERIAL_LOOP
:
6019 return ST_OACC_SERIAL_LOOP
;
6020 case EXEC_OACC_LOOP
:
6021 return ST_OACC_LOOP
;
6022 case EXEC_OACC_ATOMIC
:
6023 return ST_OACC_ATOMIC
;
6024 case EXEC_OACC_ROUTINE
:
6025 return ST_OACC_ROUTINE
;
6026 case EXEC_OACC_UPDATE
:
6027 return ST_OACC_UPDATE
;
6028 case EXEC_OACC_WAIT
:
6029 return ST_OACC_WAIT
;
6030 case EXEC_OACC_CACHE
:
6031 return ST_OACC_CACHE
;
6032 case EXEC_OACC_ENTER_DATA
:
6033 return ST_OACC_ENTER_DATA
;
6034 case EXEC_OACC_EXIT_DATA
:
6035 return ST_OACC_EXIT_DATA
;
6036 case EXEC_OACC_DECLARE
:
6037 return ST_OACC_DECLARE
;
6044 resolve_oacc_directive_inside_omp_region (gfc_code
*code
)
6046 if (omp_current_ctx
!= NULL
&& omp_current_ctx
->is_openmp
)
6048 gfc_statement st
= omp_code_to_statement (omp_current_ctx
->code
);
6049 gfc_statement oacc_st
= oacc_code_to_statement (code
);
6050 gfc_error ("The %s directive cannot be specified within "
6051 "a %s region at %L", gfc_ascii_statement (oacc_st
),
6052 gfc_ascii_statement (st
), &code
->loc
);
6057 resolve_omp_directive_inside_oacc_region (gfc_code
*code
)
6059 if (omp_current_ctx
!= NULL
&& !omp_current_ctx
->is_openmp
)
6061 gfc_statement st
= oacc_code_to_statement (omp_current_ctx
->code
);
6062 gfc_statement omp_st
= omp_code_to_statement (code
);
6063 gfc_error ("The %s directive cannot be specified within "
6064 "a %s region at %L", gfc_ascii_statement (omp_st
),
6065 gfc_ascii_statement (st
), &code
->loc
);
6071 resolve_oacc_nested_loops (gfc_code
*code
, gfc_code
* do_code
, int collapse
,
6078 for (i
= 1; i
<= collapse
; i
++)
6080 if (do_code
->op
== EXEC_DO_WHILE
)
6082 gfc_error ("!$ACC LOOP cannot be a DO WHILE or DO without loop control "
6083 "at %L", &do_code
->loc
);
6086 if (do_code
->op
== EXEC_DO_CONCURRENT
)
6088 gfc_error ("!$ACC LOOP cannot be a DO CONCURRENT loop at %L",
6092 gcc_assert (do_code
->op
== EXEC_DO
);
6093 if (do_code
->ext
.iterator
->var
->ts
.type
!= BT_INTEGER
)
6094 gfc_error ("!$ACC LOOP iteration variable must be of type integer at %L",
6096 dovar
= do_code
->ext
.iterator
->var
->symtree
->n
.sym
;
6099 gfc_code
*do_code2
= code
->block
->next
;
6102 for (j
= 1; j
< i
; j
++)
6104 gfc_symbol
*ivar
= do_code2
->ext
.iterator
->var
->symtree
->n
.sym
;
6106 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->start
)
6107 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->end
)
6108 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->step
))
6110 gfc_error ("!$ACC LOOP %s loops don't form rectangular "
6111 "iteration space at %L", clause
, &do_code
->loc
);
6114 do_code2
= do_code2
->block
->next
;
6119 for (c
= do_code
->next
; c
; c
= c
->next
)
6120 if (c
->op
!= EXEC_NOP
&& c
->op
!= EXEC_CONTINUE
)
6122 gfc_error ("%s !$ACC LOOP loops not perfectly nested at %L",
6128 do_code
= do_code
->block
;
6129 if (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
6130 && do_code
->op
!= EXEC_DO_CONCURRENT
)
6132 gfc_error ("not enough DO loops for %s !$ACC LOOP at %L",
6133 clause
, &code
->loc
);
6136 do_code
= do_code
->next
;
6138 || (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
6139 && do_code
->op
!= EXEC_DO_CONCURRENT
))
6141 gfc_error ("not enough DO loops for %s !$ACC LOOP at %L",
6142 clause
, &code
->loc
);
6150 resolve_oacc_params_in_parallel (gfc_code
*code
, const char *clause
,
6153 fortran_omp_context
*c
;
6155 if (oacc_is_parallel (code
))
6156 gfc_error ("!$ACC LOOP %s in PARALLEL region doesn't allow "
6157 "%s arguments at %L", clause
, arg
, &code
->loc
);
6158 for (c
= omp_current_ctx
; c
; c
= c
->previous
)
6160 if (oacc_is_loop (c
->code
))
6162 if (oacc_is_parallel (c
->code
))
6163 gfc_error ("!$ACC LOOP %s in PARALLEL region doesn't allow "
6164 "%s arguments at %L", clause
, arg
, &code
->loc
);
6170 resolve_oacc_loop_blocks (gfc_code
*code
)
6172 if (!oacc_is_loop (code
))
6175 if (code
->ext
.omp_clauses
->tile_list
&& code
->ext
.omp_clauses
->gang
6176 && code
->ext
.omp_clauses
->worker
&& code
->ext
.omp_clauses
->vector
)
6177 gfc_error ("Tiled loop cannot be parallelized across gangs, workers and "
6178 "vectors at the same time at %L", &code
->loc
);
6180 if (code
->ext
.omp_clauses
->gang
6181 && code
->ext
.omp_clauses
->gang_num_expr
)
6182 resolve_oacc_params_in_parallel (code
, "GANG", "num");
6184 if (code
->ext
.omp_clauses
->worker
6185 && code
->ext
.omp_clauses
->worker_expr
)
6186 resolve_oacc_params_in_parallel (code
, "WORKER", "num");
6188 if (code
->ext
.omp_clauses
->vector
6189 && code
->ext
.omp_clauses
->vector_expr
)
6190 resolve_oacc_params_in_parallel (code
, "VECTOR", "length");
6192 if (code
->ext
.omp_clauses
->tile_list
)
6195 for (el
= code
->ext
.omp_clauses
->tile_list
; el
; el
= el
->next
)
6197 if (el
->expr
== NULL
)
6199 /* NULL expressions are used to represent '*' arguments.
6200 Convert those to a 0 expressions. */
6201 el
->expr
= gfc_get_constant_expr (BT_INTEGER
,
6202 gfc_default_integer_kind
,
6204 mpz_set_si (el
->expr
->value
.integer
, 0);
6208 resolve_positive_int_expr (el
->expr
, "TILE");
6209 if (el
->expr
->expr_type
!= EXPR_CONSTANT
)
6210 gfc_error ("TILE requires constant expression at %L",
6219 gfc_resolve_oacc_blocks (gfc_code
*code
, gfc_namespace
*ns
)
6221 fortran_omp_context ctx
;
6222 gfc_omp_clauses
*omp_clauses
= code
->ext
.omp_clauses
;
6223 gfc_omp_namelist
*n
;
6226 resolve_oacc_loop_blocks (code
);
6229 ctx
.sharing_clauses
= new hash_set
<gfc_symbol
*>;
6230 ctx
.private_iterators
= new hash_set
<gfc_symbol
*>;
6231 ctx
.previous
= omp_current_ctx
;
6232 ctx
.is_openmp
= false;
6233 omp_current_ctx
= &ctx
;
6235 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
6238 case OMP_LIST_PRIVATE
:
6239 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
6240 ctx
.sharing_clauses
->add (n
->sym
);
6246 gfc_resolve_blocks (code
->block
, ns
);
6248 omp_current_ctx
= ctx
.previous
;
6249 delete ctx
.sharing_clauses
;
6250 delete ctx
.private_iterators
;
6255 resolve_oacc_loop (gfc_code
*code
)
6260 if (code
->ext
.omp_clauses
)
6261 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
, true);
6263 do_code
= code
->block
->next
;
6264 collapse
= code
->ext
.omp_clauses
->collapse
;
6266 /* Both collapsed and tiled loops are lowered the same way, but are not
6267 compatible. In gfc_trans_omp_do, the tile is prioritized. */
6268 if (code
->ext
.omp_clauses
->tile_list
)
6272 for (el
= code
->ext
.omp_clauses
->tile_list
; el
; el
= el
->next
)
6274 resolve_oacc_nested_loops (code
, code
->block
->next
, num
, "tiled");
6280 resolve_oacc_nested_loops (code
, do_code
, collapse
, "collapsed");
6284 gfc_resolve_oacc_declare (gfc_namespace
*ns
)
6287 gfc_omp_namelist
*n
;
6288 gfc_oacc_declare
*oc
;
6290 if (ns
->oacc_declare
== NULL
)
6293 for (oc
= ns
->oacc_declare
; oc
; oc
= oc
->next
)
6295 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
6296 for (n
= oc
->clauses
->lists
[list
]; n
; n
= n
->next
)
6299 if (n
->sym
->attr
.flavor
!= FL_VARIABLE
6300 && (n
->sym
->attr
.flavor
!= FL_PROCEDURE
6301 || n
->sym
->result
!= n
->sym
))
6303 gfc_error ("Object %qs is not a variable at %L",
6304 n
->sym
->name
, &oc
->loc
);
6308 if (n
->expr
&& n
->expr
->ref
->type
== REF_ARRAY
)
6310 gfc_error ("Array sections: %qs not allowed in"
6311 " !$ACC DECLARE at %L", n
->sym
->name
, &oc
->loc
);
6316 for (n
= oc
->clauses
->lists
[OMP_LIST_DEVICE_RESIDENT
]; n
; n
= n
->next
)
6317 check_array_not_assumed (n
->sym
, oc
->loc
, "DEVICE_RESIDENT");
6320 for (oc
= ns
->oacc_declare
; oc
; oc
= oc
->next
)
6322 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
6323 for (n
= oc
->clauses
->lists
[list
]; n
; n
= n
->next
)
6327 gfc_error ("Symbol %qs present on multiple clauses at %L",
6328 n
->sym
->name
, &oc
->loc
);
6336 for (oc
= ns
->oacc_declare
; oc
; oc
= oc
->next
)
6338 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
6339 for (n
= oc
->clauses
->lists
[list
]; n
; n
= n
->next
)
6346 gfc_resolve_oacc_routines (gfc_namespace
*ns
)
6348 for (gfc_oacc_routine_name
*orn
= ns
->oacc_routine_names
;
6352 gfc_symbol
*sym
= orn
->sym
;
6353 if (!sym
->attr
.external
6354 && !sym
->attr
.function
6355 && !sym
->attr
.subroutine
)
6357 gfc_error ("NAME %qs does not refer to a subroutine or function"
6358 " in !$ACC ROUTINE ( NAME ) at %L", sym
->name
, &orn
->loc
);
6361 if (!gfc_add_omp_declare_target (&sym
->attr
, sym
->name
, &orn
->loc
))
6363 gfc_error ("NAME %qs invalid"
6364 " in !$ACC ROUTINE ( NAME ) at %L", sym
->name
, &orn
->loc
);
6372 gfc_resolve_oacc_directive (gfc_code
*code
, gfc_namespace
*ns ATTRIBUTE_UNUSED
)
6374 resolve_oacc_directive_inside_omp_region (code
);
6378 case EXEC_OACC_PARALLEL
:
6379 case EXEC_OACC_KERNELS
:
6380 case EXEC_OACC_SERIAL
:
6381 case EXEC_OACC_DATA
:
6382 case EXEC_OACC_HOST_DATA
:
6383 case EXEC_OACC_UPDATE
:
6384 case EXEC_OACC_ENTER_DATA
:
6385 case EXEC_OACC_EXIT_DATA
:
6386 case EXEC_OACC_WAIT
:
6387 case EXEC_OACC_CACHE
:
6388 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
, true);
6390 case EXEC_OACC_PARALLEL_LOOP
:
6391 case EXEC_OACC_KERNELS_LOOP
:
6392 case EXEC_OACC_SERIAL_LOOP
:
6393 case EXEC_OACC_LOOP
:
6394 resolve_oacc_loop (code
);
6396 case EXEC_OACC_ATOMIC
:
6397 resolve_omp_atomic (code
);
6405 /* Resolve OpenMP directive clauses and check various requirements
6406 of each directive. */
6409 gfc_resolve_omp_directive (gfc_code
*code
, gfc_namespace
*ns ATTRIBUTE_UNUSED
)
6411 resolve_omp_directive_inside_oacc_region (code
);
6413 if (code
->op
!= EXEC_OMP_ATOMIC
)
6414 gfc_maybe_initialize_eh ();
6418 case EXEC_OMP_DISTRIBUTE
:
6419 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
6420 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
6421 case EXEC_OMP_DISTRIBUTE_SIMD
:
6423 case EXEC_OMP_DO_SIMD
:
6424 case EXEC_OMP_PARALLEL_DO
:
6425 case EXEC_OMP_PARALLEL_DO_SIMD
:
6427 case EXEC_OMP_TARGET_PARALLEL_DO
:
6428 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
6429 case EXEC_OMP_TARGET_SIMD
:
6430 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
6431 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
6432 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
6433 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
6434 case EXEC_OMP_TASKLOOP
:
6435 case EXEC_OMP_TASKLOOP_SIMD
:
6436 case EXEC_OMP_TEAMS_DISTRIBUTE
:
6437 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
6438 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
6439 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
6440 resolve_omp_do (code
);
6442 case EXEC_OMP_CANCEL
:
6443 case EXEC_OMP_PARALLEL_WORKSHARE
:
6444 case EXEC_OMP_PARALLEL
:
6445 case EXEC_OMP_PARALLEL_SECTIONS
:
6446 case EXEC_OMP_SECTIONS
:
6447 case EXEC_OMP_SINGLE
:
6448 case EXEC_OMP_TARGET
:
6449 case EXEC_OMP_TARGET_DATA
:
6450 case EXEC_OMP_TARGET_ENTER_DATA
:
6451 case EXEC_OMP_TARGET_EXIT_DATA
:
6452 case EXEC_OMP_TARGET_PARALLEL
:
6453 case EXEC_OMP_TARGET_TEAMS
:
6455 case EXEC_OMP_TEAMS
:
6456 case EXEC_OMP_WORKSHARE
:
6457 if (code
->ext
.omp_clauses
)
6458 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
);
6460 case EXEC_OMP_TARGET_UPDATE
:
6461 if (code
->ext
.omp_clauses
)
6462 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
);
6463 if (code
->ext
.omp_clauses
== NULL
6464 || (code
->ext
.omp_clauses
->lists
[OMP_LIST_TO
] == NULL
6465 && code
->ext
.omp_clauses
->lists
[OMP_LIST_FROM
] == NULL
))
6466 gfc_error ("OMP TARGET UPDATE at %L requires at least one TO or "
6467 "FROM clause", &code
->loc
);
6469 case EXEC_OMP_ATOMIC
:
6470 resolve_omp_atomic (code
);
6477 /* Resolve !$omp declare simd constructs in NS. */
6480 gfc_resolve_omp_declare_simd (gfc_namespace
*ns
)
6482 gfc_omp_declare_simd
*ods
;
6484 for (ods
= ns
->omp_declare_simd
; ods
; ods
= ods
->next
)
6486 if (ods
->proc_name
!= NULL
6487 && ods
->proc_name
!= ns
->proc_name
)
6488 gfc_error ("!$OMP DECLARE SIMD should refer to containing procedure "
6489 "%qs at %L", ns
->proc_name
->name
, &ods
->where
);
6491 resolve_omp_clauses (NULL
, ods
->clauses
, ns
);
6495 struct omp_udr_callback_data
6497 gfc_omp_udr
*omp_udr
;
6498 bool is_initializer
;
6502 omp_udr_callback (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
6505 struct omp_udr_callback_data
*cd
= (struct omp_udr_callback_data
*) data
;
6506 if ((*e
)->expr_type
== EXPR_VARIABLE
)
6508 if (cd
->is_initializer
)
6510 if ((*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_priv
6511 && (*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_orig
)
6512 gfc_error ("Variable other than OMP_PRIV or OMP_ORIG used in "
6513 "INITIALIZER clause of !$OMP DECLARE REDUCTION at %L",
6518 if ((*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_out
6519 && (*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_in
)
6520 gfc_error ("Variable other than OMP_OUT or OMP_IN used in "
6521 "combiner of !$OMP DECLARE REDUCTION at %L",
6528 /* Resolve !$omp declare reduction constructs. */
6531 gfc_resolve_omp_udr (gfc_omp_udr
*omp_udr
)
6533 gfc_actual_arglist
*a
;
6534 const char *predef_name
= NULL
;
6536 switch (omp_udr
->rop
)
6538 case OMP_REDUCTION_PLUS
:
6539 case OMP_REDUCTION_TIMES
:
6540 case OMP_REDUCTION_MINUS
:
6541 case OMP_REDUCTION_AND
:
6542 case OMP_REDUCTION_OR
:
6543 case OMP_REDUCTION_EQV
:
6544 case OMP_REDUCTION_NEQV
:
6545 case OMP_REDUCTION_MAX
:
6546 case OMP_REDUCTION_USER
:
6549 gfc_error ("Invalid operator for !$OMP DECLARE REDUCTION %s at %L",
6550 omp_udr
->name
, &omp_udr
->where
);
6554 if (gfc_omp_udr_predef (omp_udr
->rop
, omp_udr
->name
,
6555 &omp_udr
->ts
, &predef_name
))
6558 gfc_error_now ("Redefinition of predefined %s "
6559 "!$OMP DECLARE REDUCTION at %L",
6560 predef_name
, &omp_udr
->where
);
6562 gfc_error_now ("Redefinition of predefined "
6563 "!$OMP DECLARE REDUCTION at %L", &omp_udr
->where
);
6567 if (omp_udr
->ts
.type
== BT_CHARACTER
6568 && omp_udr
->ts
.u
.cl
->length
6569 && omp_udr
->ts
.u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
6571 gfc_error ("CHARACTER length in !$OMP DECLARE REDUCTION %s not "
6572 "constant at %L", omp_udr
->name
, &omp_udr
->where
);
6576 struct omp_udr_callback_data cd
;
6577 cd
.omp_udr
= omp_udr
;
6578 cd
.is_initializer
= false;
6579 gfc_code_walker (&omp_udr
->combiner_ns
->code
, gfc_dummy_code_callback
,
6580 omp_udr_callback
, &cd
);
6581 if (omp_udr
->combiner_ns
->code
->op
== EXEC_CALL
)
6583 for (a
= omp_udr
->combiner_ns
->code
->ext
.actual
; a
; a
= a
->next
)
6584 if (a
->expr
== NULL
)
6587 gfc_error ("Subroutine call with alternate returns in combiner "
6588 "of !$OMP DECLARE REDUCTION at %L",
6589 &omp_udr
->combiner_ns
->code
->loc
);
6591 if (omp_udr
->initializer_ns
)
6593 cd
.is_initializer
= true;
6594 gfc_code_walker (&omp_udr
->initializer_ns
->code
, gfc_dummy_code_callback
,
6595 omp_udr_callback
, &cd
);
6596 if (omp_udr
->initializer_ns
->code
->op
== EXEC_CALL
)
6598 for (a
= omp_udr
->initializer_ns
->code
->ext
.actual
; a
; a
= a
->next
)
6599 if (a
->expr
== NULL
)
6602 gfc_error ("Subroutine call with alternate returns in "
6603 "INITIALIZER clause of !$OMP DECLARE REDUCTION "
6604 "at %L", &omp_udr
->initializer_ns
->code
->loc
);
6605 for (a
= omp_udr
->initializer_ns
->code
->ext
.actual
; a
; a
= a
->next
)
6607 && a
->expr
->expr_type
== EXPR_VARIABLE
6608 && a
->expr
->symtree
->n
.sym
== omp_udr
->omp_priv
6609 && a
->expr
->ref
== NULL
)
6612 gfc_error ("One of actual subroutine arguments in INITIALIZER "
6613 "clause of !$OMP DECLARE REDUCTION must be OMP_PRIV "
6614 "at %L", &omp_udr
->initializer_ns
->code
->loc
);
6617 else if (omp_udr
->ts
.type
== BT_DERIVED
6618 && !gfc_has_default_initializer (omp_udr
->ts
.u
.derived
))
6620 gfc_error ("Missing INITIALIZER clause for !$OMP DECLARE REDUCTION "
6621 "of derived type without default initializer at %L",
6628 gfc_resolve_omp_udrs (gfc_symtree
*st
)
6630 gfc_omp_udr
*omp_udr
;
6634 gfc_resolve_omp_udrs (st
->left
);
6635 gfc_resolve_omp_udrs (st
->right
);
6636 for (omp_udr
= st
->n
.omp_udr
; omp_udr
; omp_udr
= omp_udr
->next
)
6637 gfc_resolve_omp_udr (omp_udr
);