Bug Summary

File:build/gcc/fortran/openmp.cc
Warning:line 2443, column 8
Value stored to 'm' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-suse-linux -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name openmp.cc -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/gcc -resource-dir /usr/lib64/clang/15.0.7 -D IN_GCC_FRONTEND -D IN_GCC -D HAVE_CONFIG_H -I . -I fortran -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/fortran -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../include -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libcpp/include -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libcody -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libdecnumber -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libdecnumber/bid -I ../libdecnumber -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libbacktrace -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/13/../../../../include/c++/13 -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/13/../../../../include/c++/13/x86_64-suse-linux -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/13/../../../../include/c++/13/backward -internal-isystem /usr/lib64/clang/15.0.7/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/13/../../../../x86_64-suse-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-narrowing -Wwrite-strings -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fdeprecated-macro -fdebug-compilation-dir=/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/gcc -ferror-limit 19 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=plist-html -analyzer-config silence-checkers=core.NullDereference -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /buildworker/marxinbox-gcc-clang-static-analyzer/objdir/clang-static-analyzer/2023-03-27-141847-20772-1/report-1FEa74.plist -x c++ /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/fortran/openmp.cc
1/* OpenMP directive matching and resolving.
2 Copyright (C) 2005-2023 Free Software Foundation, Inc.
3 Contributed by Jakub Jelinek
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "gfortran.h"
25#include "arith.h"
26#include "match.h"
27#include "parse.h"
28#include "constructor.h"
29#include "diagnostic.h"
30#include "gomp-constants.h"
31#include "target-memory.h" /* For gfc_encode_character. */
32#include "bitmap.h"
33
34
35static gfc_statement omp_code_to_statement (gfc_code *);
36
37enum gfc_omp_directive_kind {
38 GFC_OMP_DIR_DECLARATIVE,
39 GFC_OMP_DIR_EXECUTABLE,
40 GFC_OMP_DIR_INFORMATIONAL,
41 GFC_OMP_DIR_META,
42 GFC_OMP_DIR_SUBSIDIARY,
43 GFC_OMP_DIR_UTILITY
44};
45
46struct gfc_omp_directive {
47 const char *name;
48 enum gfc_omp_directive_kind kind;
49 gfc_statement st;
50};
51
52/* Alphabetically sorted OpenMP clauses, except that longer strings are before
53 substrings; excludes combined/composite directives. See note for "ordered"
54 and "nothing". */
55
56static const struct gfc_omp_directive gfc_omp_directives[] = {
57 /* {"allocate", GFC_OMP_DIR_DECLARATIVE, ST_OMP_ALLOCATE}, */
58 /* {"allocators", GFC_OMP_DIR_EXECUTABLE, ST_OMP_ALLOCATORS}, */
59 {"assumes", GFC_OMP_DIR_INFORMATIONAL, ST_OMP_ASSUMES},
60 {"assume", GFC_OMP_DIR_INFORMATIONAL, ST_OMP_ASSUME},
61 {"atomic", GFC_OMP_DIR_EXECUTABLE, ST_OMP_ATOMIC},
62 {"barrier", GFC_OMP_DIR_EXECUTABLE, ST_OMP_BARRIER},
63 {"cancellation point", GFC_OMP_DIR_EXECUTABLE, ST_OMP_CANCELLATION_POINT},
64 {"cancel", GFC_OMP_DIR_EXECUTABLE, ST_OMP_CANCEL},
65 {"critical", GFC_OMP_DIR_EXECUTABLE, ST_OMP_CRITICAL},
66 /* {"declare mapper", GFC_OMP_DIR_DECLARATIVE, ST_OMP_DECLARE_MAPPER}, */
67 {"declare reduction", GFC_OMP_DIR_DECLARATIVE, ST_OMP_DECLARE_REDUCTION},
68 {"declare simd", GFC_OMP_DIR_DECLARATIVE, ST_OMP_DECLARE_SIMD},
69 {"declare target", GFC_OMP_DIR_DECLARATIVE, ST_OMP_DECLARE_TARGET},
70 {"declare variant", GFC_OMP_DIR_DECLARATIVE, ST_OMP_DECLARE_VARIANT},
71 {"depobj", GFC_OMP_DIR_EXECUTABLE, ST_OMP_DEPOBJ},
72 /* {"dispatch", GFC_OMP_DIR_EXECUTABLE, ST_OMP_DISPATCH}, */
73 {"distribute", GFC_OMP_DIR_EXECUTABLE, ST_OMP_DISTRIBUTE},
74 {"do", GFC_OMP_DIR_EXECUTABLE, ST_OMP_DO},
75 /* "error" becomes GFC_OMP_DIR_EXECUTABLE with at(execution) */
76 {"error", GFC_OMP_DIR_UTILITY, ST_OMP_ERROR},
77 {"flush", GFC_OMP_DIR_EXECUTABLE, ST_OMP_FLUSH},
78 /* {"interop", GFC_OMP_DIR_EXECUTABLE, ST_OMP_INTEROP}, */
79 {"loop", GFC_OMP_DIR_EXECUTABLE, ST_OMP_LOOP},
80 {"masked", GFC_OMP_DIR_EXECUTABLE, ST_OMP_MASKED},
81 /* {"metadirective", GFC_OMP_DIR_META, ST_OMP_METADIRECTIVE}, */
82 /* Note: gfc_match_omp_nothing returns ST_NONE. */
83 {"nothing", GFC_OMP_DIR_UTILITY, ST_OMP_NOTHING},
84 /* Special case; for now map to the first one.
85 ordered-blockassoc = ST_OMP_ORDERED
86 ordered-standalone = ST_OMP_ORDERED_DEPEND + depend/doacross. */
87 {"ordered", GFC_OMP_DIR_EXECUTABLE, ST_OMP_ORDERED},
88 {"parallel", GFC_OMP_DIR_EXECUTABLE, ST_OMP_PARALLEL},
89 {"requires", GFC_OMP_DIR_INFORMATIONAL, ST_OMP_REQUIRES},
90 {"scan", GFC_OMP_DIR_SUBSIDIARY, ST_OMP_SCAN},
91 {"scope", GFC_OMP_DIR_EXECUTABLE, ST_OMP_SCOPE},
92 {"sections", GFC_OMP_DIR_EXECUTABLE, ST_OMP_SECTIONS},
93 {"section", GFC_OMP_DIR_SUBSIDIARY, ST_OMP_SECTION},
94 {"simd", GFC_OMP_DIR_EXECUTABLE, ST_OMP_SIMD},
95 {"single", GFC_OMP_DIR_EXECUTABLE, ST_OMP_SINGLE},
96 {"target data", GFC_OMP_DIR_EXECUTABLE, ST_OMP_TARGET_DATA},
97 {"target enter data", GFC_OMP_DIR_EXECUTABLE, ST_OMP_TARGET_ENTER_DATA},
98 {"target exit data", GFC_OMP_DIR_EXECUTABLE, ST_OMP_TARGET_EXIT_DATA},
99 {"target update", GFC_OMP_DIR_EXECUTABLE, ST_OMP_TARGET_UPDATE},
100 {"target", GFC_OMP_DIR_EXECUTABLE, ST_OMP_TARGET},
101 {"taskloop", GFC_OMP_DIR_EXECUTABLE, ST_OMP_TASKLOOP},
102 {"taskwait", GFC_OMP_DIR_EXECUTABLE, ST_OMP_TASKWAIT},
103 {"taskyield", GFC_OMP_DIR_EXECUTABLE, ST_OMP_TASKYIELD},
104 {"task", GFC_OMP_DIR_EXECUTABLE, ST_OMP_TASK},
105 {"teams", GFC_OMP_DIR_EXECUTABLE, ST_OMP_TEAMS},
106 {"threadprivate", GFC_OMP_DIR_DECLARATIVE, ST_OMP_THREADPRIVATE},
107 /* {"tile", GFC_OMP_DIR_EXECUTABLE, ST_OMP_TILE}, */
108 /* {"unroll", GFC_OMP_DIR_EXECUTABLE, ST_OMP_UNROLL}, */
109 {"workshare", GFC_OMP_DIR_EXECUTABLE, ST_OMP_WORKSHARE},
110};
111
112
113/* Match an end of OpenMP directive. End of OpenMP directive is optional
114 whitespace, followed by '\n' or comment '!'. */
115
116static match
117gfc_match_omp_eos (void)
118{
119 locus old_loc;
120 char c;
121
122 old_loc = gfc_current_locus;
123 gfc_gobble_whitespace ();
124
125 c = gfc_next_ascii_char ();
126 switch (c)
127 {
128 case '!':
129 do
130 c = gfc_next_ascii_char ();
131 while (c != '\n');
132 /* Fall through */
133
134 case '\n':
135 return MATCH_YES;
136 }
137
138 gfc_current_locus = old_loc;
139 return MATCH_NO;
140}
141
142match
143gfc_match_omp_eos_error (void)
144{
145 if (gfc_match_omp_eos() == MATCH_YES)
146 return MATCH_YES;
147
148 gfc_error ("Unexpected junk at %C");
149 return MATCH_ERROR;
150}
151
152
153/* Free an omp_clauses structure. */
154
155void
156gfc_free_omp_clauses (gfc_omp_clauses *c)
157{
158 int i;
159 if (c == NULL__null)
160 return;
161
162 gfc_free_expr (c->if_expr);
163 gfc_free_expr (c->final_expr);
164 gfc_free_expr (c->num_threads);
165 gfc_free_expr (c->chunk_size);
166 gfc_free_expr (c->safelen_expr);
167 gfc_free_expr (c->simdlen_expr);
168 gfc_free_expr (c->num_teams_lower);
169 gfc_free_expr (c->num_teams_upper);
170 gfc_free_expr (c->device);
171 gfc_free_expr (c->thread_limit);
172 gfc_free_expr (c->dist_chunk_size);
173 gfc_free_expr (c->grainsize);
174 gfc_free_expr (c->hint);
175 gfc_free_expr (c->num_tasks);
176 gfc_free_expr (c->priority);
177 gfc_free_expr (c->detach);
178 for (i = 0; i < OMP_IF_LAST; i++)
179 gfc_free_expr (c->if_exprs[i]);
180 gfc_free_expr (c->async_expr);
181 gfc_free_expr (c->gang_num_expr);
182 gfc_free_expr (c->gang_static_expr);
183 gfc_free_expr (c->worker_expr);
184 gfc_free_expr (c->vector_expr);
185 gfc_free_expr (c->num_gangs_expr);
186 gfc_free_expr (c->num_workers_expr);
187 gfc_free_expr (c->vector_length_expr);
188 for (i = 0; i < OMP_LIST_NUM; i++)
189 gfc_free_omp_namelist (c->lists[i],
190 i == OMP_LIST_AFFINITY || i == OMP_LIST_DEPEND,
191 i == OMP_LIST_ALLOCATE);
192 gfc_free_expr_list (c->wait_list);
193 gfc_free_expr_list (c->tile_list);
194 free (CONST_CAST (char *, c->critical_name)(const_cast<char *> ((c->critical_name))));
195 if (c->assume)
196 {
197 free (c->assume->absent);
198 free (c->assume->contains);
199 gfc_free_expr_list (c->assume->holds);
200 free (c->assume);
201 }
202 free (c);
203}
204
205/* Free oacc_declare structures. */
206
207void
208gfc_free_oacc_declare_clauses (struct gfc_oacc_declare *oc)
209{
210 struct gfc_oacc_declare *decl = oc;
211
212 do
213 {
214 struct gfc_oacc_declare *next;
215
216 next = decl->next;
217 gfc_free_omp_clauses (decl->clauses);
218 free (decl);
219 decl = next;
220 }
221 while (decl);
222}
223
224/* Free expression list. */
225void
226gfc_free_expr_list (gfc_expr_list *list)
227{
228 gfc_expr_list *n;
229
230 for (; list; list = n)
231 {
232 n = list->next;
233 free (list);
234 }
235}
236
237/* Free an !$omp declare simd construct list. */
238
239void
240gfc_free_omp_declare_simd (gfc_omp_declare_simd *ods)
241{
242 if (ods)
243 {
244 gfc_free_omp_clauses (ods->clauses);
245 free (ods);
246 }
247}
248
249void
250gfc_free_omp_declare_simd_list (gfc_omp_declare_simd *list)
251{
252 while (list)
253 {
254 gfc_omp_declare_simd *current = list;
255 list = list->next;
256 gfc_free_omp_declare_simd (current);
257 }
258}
259
260static void
261gfc_free_omp_trait_property_list (gfc_omp_trait_property *list)
262{
263 while (list)
264 {
265 gfc_omp_trait_property *current = list;
266 list = list->next;
267 switch (current->property_kind)
268 {
269 case CTX_PROPERTY_ID:
270 free (current->name);
271 break;
272 case CTX_PROPERTY_NAME_LIST:
273 if (current->is_name)
274 free (current->name);
275 break;
276 case CTX_PROPERTY_SIMD:
277 gfc_free_omp_clauses (current->clauses);
278 break;
279 default:
280 break;
281 }
282 free (current);
283 }
284}
285
286static void
287gfc_free_omp_selector_list (gfc_omp_selector *list)
288{
289 while (list)
290 {
291 gfc_omp_selector *current = list;
292 list = list->next;
293 gfc_free_omp_trait_property_list (current->properties);
294 free (current);
295 }
296}
297
298static void
299gfc_free_omp_set_selector_list (gfc_omp_set_selector *list)
300{
301 while (list)
302 {
303 gfc_omp_set_selector *current = list;
304 list = list->next;
305 gfc_free_omp_selector_list (current->trait_selectors);
306 free (current);
307 }
308}
309
310/* Free an !$omp declare variant construct list. */
311
312void
313gfc_free_omp_declare_variant_list (gfc_omp_declare_variant *list)
314{
315 while (list)
316 {
317 gfc_omp_declare_variant *current = list;
318 list = list->next;
319 gfc_free_omp_set_selector_list (current->set_selectors);
320 free (current);
321 }
322}
323
324/* Free an !$omp declare reduction. */
325
326void
327gfc_free_omp_udr (gfc_omp_udr *omp_udr)
328{
329 if (omp_udr)
330 {
331 gfc_free_omp_udr (omp_udr->next);
332 gfc_free_namespace (omp_udr->combiner_ns);
333 if (omp_udr->initializer_ns)
334 gfc_free_namespace (omp_udr->initializer_ns);
335 free (omp_udr);
336 }
337}
338
339
340static gfc_omp_udr *
341gfc_find_omp_udr (gfc_namespace *ns, const char *name, gfc_typespec *ts)
342{
343 gfc_symtree *st;
344
345 if (ns == NULL__null)
346 ns = gfc_current_ns;
347 do
348 {
349 gfc_omp_udr *omp_udr;
350
351 st = gfc_find_symtree (ns->omp_udr_root, name);
352 if (st != NULL__null)
353 {
354 for (omp_udr = st->n.omp_udr; omp_udr; omp_udr = omp_udr->next)
355 if (ts == NULL__null)
356 return omp_udr;
357 else if (gfc_compare_types (&omp_udr->ts, ts))
358 {
359 if (ts->type == BT_CHARACTER)
360 {
361 if (omp_udr->ts.u.cl->length == NULL__null)
362 return omp_udr;
363 if (ts->u.cl->length == NULL__null)
364 continue;
365 if (gfc_compare_expr (omp_udr->ts.u.cl->length,
366 ts->u.cl->length,
367 INTRINSIC_EQ) != 0)
368 continue;
369 }
370 return omp_udr;
371 }
372 }
373
374 /* Don't escape an interface block. */
375 if (ns && !ns->has_import_set
376 && ns->proc_name && ns->proc_name->attr.if_source == IFSRC_IFBODY)
377 break;
378
379 ns = ns->parent;
380 }
381 while (ns != NULL__null);
382
383 return NULL__null;
384}
385
386
387/* Match a variable/common block list and construct a namelist from it;
388 if has_all_memory != NULL, *has_all_memory is set and omp_all_memory
389 yields a list->sym NULL entry. */
390
391static match
392gfc_match_omp_variable_list (const char *str, gfc_omp_namelist **list,
393 bool allow_common, bool *end_colon = NULL__null,
394 gfc_omp_namelist ***headp = NULL__null,
395 bool allow_sections = false,
396 bool allow_derived = false,
397 bool *has_all_memory = NULL__null)
398{
399 gfc_omp_namelist *head, *tail, *p;
400 locus old_loc, cur_loc;
401 char n[GFC_MAX_SYMBOL_LEN63+1];
402 gfc_symbol *sym;
403 match m;
404 gfc_symtree *st;
405
406 head = tail = NULL__null;
407
408 old_loc = gfc_current_locus;
409 if (has_all_memory)
410 *has_all_memory = false;
411 m = gfc_match (str);
412 if (m != MATCH_YES)
413 return m;
414
415 for (;;)
416 {
417 cur_loc = gfc_current_locus;
418
419 m = gfc_match_name (n);
420 if (m == MATCH_YES && strcmp (n, "omp_all_memory") == 0)
421 {
422 if (!has_all_memory)
423 {
424 gfc_error ("%<omp_all_memory%> at %C not permitted in this "
425 "clause");
426 goto cleanup;
427 }
428 *has_all_memory = true;
429 p = gfc_get_omp_namelist ()((gfc_omp_namelist *) xcalloc (1, sizeof (gfc_omp_namelist)));
430 if (head == NULL__null)
431 head = tail = p;
432 else
433 {
434 tail->next = p;
435 tail = tail->next;
436 }
437 tail->where = cur_loc;
438 goto next_item;
439 }
440 if (m == MATCH_YES)
441 {
442 gfc_symtree *st;
443 if ((m = gfc_get_ha_sym_tree (n, &st) ? MATCH_ERROR : MATCH_YES)
444 == MATCH_YES)
445 sym = st->n.sym;
446 }
447 switch (m)
448 {
449 case MATCH_YES:
450 gfc_expr *expr;
451 expr = NULL__null;
452 gfc_gobble_whitespace ();
453 if ((allow_sections && gfc_peek_ascii_char () == '(')
454 || (allow_derived && gfc_peek_ascii_char () == '%'))
455 {
456 gfc_current_locus = cur_loc;
457 m = gfc_match_variable (&expr, 0);
458 switch (m)
459 {
460 case MATCH_ERROR:
461 goto cleanup;
462 case MATCH_NO:
463 goto syntax;
464 default:
465 break;
466 }
467 if (gfc_is_coindexed (expr))
468 {
469 gfc_error ("List item shall not be coindexed at %C");
470 goto cleanup;
471 }
472 }
473 gfc_set_sym_referenced (sym);
474 p = gfc_get_omp_namelist ()((gfc_omp_namelist *) xcalloc (1, sizeof (gfc_omp_namelist)));
475 if (head == NULL__null)
476 head = tail = p;
477 else
478 {
479 tail->next = p;
480 tail = tail->next;
481 }
482 tail->sym = sym;
483 tail->expr = expr;
484 tail->where = cur_loc;
485 goto next_item;
486 case MATCH_NO:
487 break;
488 case MATCH_ERROR:
489 goto cleanup;
490 }
491
492 if (!allow_common)
493 goto syntax;
494
495 m = gfc_match (" / %n /", n);
496 if (m == MATCH_ERROR)
497 goto cleanup;
498 if (m == MATCH_NO)
499 goto syntax;
500
501 st = gfc_find_symtree (gfc_current_ns->common_root, n);
502 if (st == NULL__null)
503 {
504 gfc_error ("COMMON block /%s/ not found at %C", n);
505 goto cleanup;
506 }
507 for (sym = st->n.common->head; sym; sym = sym->common_next)
508 {
509 gfc_set_sym_referenced (sym);
510 p = gfc_get_omp_namelist ()((gfc_omp_namelist *) xcalloc (1, sizeof (gfc_omp_namelist)));
511 if (head == NULL__null)
512 head = tail = p;
513 else
514 {
515 tail->next = p;
516 tail = tail->next;
517 }
518 tail->sym = sym;
519 tail->where = cur_loc;
520 }
521
522 next_item:
523 if (end_colon && gfc_match_char (':') == MATCH_YES)
524 {
525 *end_colon = true;
526 break;
527 }
528 if (gfc_match_char (')') == MATCH_YES)
529 break;
530 if (gfc_match_char (',') != MATCH_YES)
531 goto syntax;
532 }
533
534 while (*list)
535 list = &(*list)->next;
536
537 *list = head;
538 if (headp)
539 *headp = list;
540 return MATCH_YES;
541
542syntax:
543 gfc_error ("Syntax error in OpenMP variable list at %C");
544
545cleanup:
546 gfc_free_omp_namelist (head, false, false);
547 gfc_current_locus = old_loc;
548 return MATCH_ERROR;
549}
550
551/* Match a variable/procedure/common block list and construct a namelist
552 from it. */
553
554static match
555gfc_match_omp_to_link (const char *str, gfc_omp_namelist **list)
556{
557 gfc_omp_namelist *head, *tail, *p;
558 locus old_loc, cur_loc;
559 char n[GFC_MAX_SYMBOL_LEN63+1];
560 gfc_symbol *sym;
561 match m;
562 gfc_symtree *st;
563
564 head = tail = NULL__null;
565
566 old_loc = gfc_current_locus;
567
568 m = gfc_match (str);
569 if (m != MATCH_YES)
570 return m;
571
572 for (;;)
573 {
574 cur_loc = gfc_current_locus;
575 m = gfc_match_symbol (&sym, 1);
576 switch (m)
577 {
578 case MATCH_YES:
579 p = gfc_get_omp_namelist ()((gfc_omp_namelist *) xcalloc (1, sizeof (gfc_omp_namelist)));
580 if (head == NULL__null)
581 head = tail = p;
582 else
583 {
584 tail->next = p;
585 tail = tail->next;
586 }
587 tail->sym = sym;
588 tail->where = cur_loc;
589 goto next_item;
590 case MATCH_NO:
591 break;
592 case MATCH_ERROR:
593 goto cleanup;
594 }
595
596 m = gfc_match (" / %n /", n);
597 if (m == MATCH_ERROR)
598 goto cleanup;
599 if (m == MATCH_NO)
600 goto syntax;
601
602 st = gfc_find_symtree (gfc_current_ns->common_root, n);
603 if (st == NULL__null)
604 {
605 gfc_error ("COMMON block /%s/ not found at %C", n);
606 goto cleanup;
607 }
608 p = gfc_get_omp_namelist ()((gfc_omp_namelist *) xcalloc (1, sizeof (gfc_omp_namelist)));
609 if (head == NULL__null)
610 head = tail = p;
611 else
612 {
613 tail->next = p;
614 tail = tail->next;
615 }
616 tail->u.common = st->n.common;
617 tail->where = cur_loc;
618
619 next_item:
620 if (gfc_match_char (')') == MATCH_YES)
621 break;
622 if (gfc_match_char (',') != MATCH_YES)
623 goto syntax;
624 }
625
626 while (*list)
627 list = &(*list)->next;
628
629 *list = head;
630 return MATCH_YES;
631
632syntax:
633 gfc_error ("Syntax error in OpenMP variable list at %C");
634
635cleanup:
636 gfc_free_omp_namelist (head, false, false);
637 gfc_current_locus = old_loc;
638 return MATCH_ERROR;
639}
640
641/* Match detach(event-handle). */
642
643static match
644gfc_match_omp_detach (gfc_expr **expr)
645{
646 locus old_loc = gfc_current_locus;
647
648 if (gfc_match ("detach ( ") != MATCH_YES)
649 goto syntax_error;
650
651 if (gfc_match_variable (expr, 0) != MATCH_YES)
652 goto syntax_error;
653
654 if (gfc_match_char (')') != MATCH_YES)
655 goto syntax_error;
656
657 return MATCH_YES;
658
659syntax_error:
660 gfc_error ("Syntax error in OpenMP detach clause at %C");
661 gfc_current_locus = old_loc;
662 return MATCH_ERROR;
663
664}
665
666/* Match doacross(sink : ...) construct a namelist from it;
667 if depend is true, match legacy 'depend(sink : ...)'. */
668
669static match
670gfc_match_omp_doacross_sink (gfc_omp_namelist **list, bool depend)
671{
672 char n[GFC_MAX_SYMBOL_LEN63+1];
673 gfc_omp_namelist *head, *tail, *p;
674 locus old_loc, cur_loc;
675 gfc_symbol *sym;
676
677 head = tail = NULL__null;
678
679 old_loc = gfc_current_locus;
680
681 for (;;)
682 {
683 cur_loc = gfc_current_locus;
684
685 if (gfc_match_name (n) != MATCH_YES)
686 goto syntax;
687 if (UNLIKELY (strcmp (n, "omp_all_memory") == 0)(__builtin_expect ((strcmp (n, "omp_all_memory") == 0), 0)))
688 {
689 gfc_error ("%<omp_all_memory%> used with dependence-type "
690 "other than OUT or INOUT at %C");
691 goto cleanup;
692 }
693 sym = NULL__null;
694 if (!(strcmp (n, "omp_cur_iteration") == 0))
695 {
696 gfc_symtree *st;
697 if (gfc_get_ha_sym_tree (n, &st))
698 goto syntax;
699 sym = st->n.sym;
700 gfc_set_sym_referenced (sym);
701 }
702 p = gfc_get_omp_namelist ()((gfc_omp_namelist *) xcalloc (1, sizeof (gfc_omp_namelist)));
703 if (head == NULL__null)
704 {
705 head = tail = p;
706 head->u.depend_doacross_op = (depend ? OMP_DEPEND_SINK_FIRST
707 : OMP_DOACROSS_SINK_FIRST);
708 }
709 else
710 {
711 tail->next = p;
712 tail = tail->next;
713 tail->u.depend_doacross_op = OMP_DOACROSS_SINK;
714 }
715 tail->sym = sym;
716 tail->expr = NULL__null;
717 tail->where = cur_loc;
718 if (gfc_match_char ('+') == MATCH_YES)
719 {
720 if (gfc_match_literal_constant (&tail->expr, 0) != MATCH_YES)
721 goto syntax;
722 }
723 else if (gfc_match_char ('-') == MATCH_YES)
724 {
725 if (gfc_match_literal_constant (&tail->expr, 0) != MATCH_YES)
726 goto syntax;
727 tail->expr = gfc_uminus (tail->expr);
728 }
729 if (gfc_match_char (')') == MATCH_YES)
730 break;
731 if (gfc_match_char (',') != MATCH_YES)
732 goto syntax;
733 }
734
735 while (*list)
736 list = &(*list)->next;
737
738 *list = head;
739 return MATCH_YES;
740
741syntax:
742 gfc_error ("Syntax error in OpenMP SINK dependence-type list at %C");
743
744cleanup:
745 gfc_free_omp_namelist (head, false, false);
746 gfc_current_locus = old_loc;
747 return MATCH_ERROR;
748}
749
750static match
751match_oacc_expr_list (const char *str, gfc_expr_list **list,
752 bool allow_asterisk)
753{
754 gfc_expr_list *head, *tail, *p;
755 locus old_loc;
756 gfc_expr *expr;
757 match m;
758
759 head = tail = NULL__null;
760
761 old_loc = gfc_current_locus;
762
763 m = gfc_match (str);
764 if (m != MATCH_YES)
765 return m;
766
767 for (;;)
768 {
769 m = gfc_match_expr (&expr);
770 if (m == MATCH_YES || allow_asterisk)
771 {
772 p = gfc_get_expr_list ()((gfc_expr_list *) xcalloc (1, sizeof (gfc_expr_list)));
773 if (head == NULL__null)
774 head = tail = p;
775 else
776 {
777 tail->next = p;
778 tail = tail->next;
779 }
780 if (m == MATCH_YES)
781 tail->expr = expr;
782 else if (gfc_match (" *") != MATCH_YES)
783 goto syntax;
784 goto next_item;
785 }
786 if (m == MATCH_ERROR)
787 goto cleanup;
788 goto syntax;
789
790 next_item:
791 if (gfc_match_char (')') == MATCH_YES)
792 break;
793 if (gfc_match_char (',') != MATCH_YES)
794 goto syntax;
795 }
796
797 while (*list)
798 list = &(*list)->next;
799
800 *list = head;
801 return MATCH_YES;
802
803syntax:
804 gfc_error ("Syntax error in OpenACC expression list at %C");
805
806cleanup:
807 gfc_free_expr_list (head);
808 gfc_current_locus = old_loc;
809 return MATCH_ERROR;
810}
811
812static match
813match_oacc_clause_gwv (gfc_omp_clauses *cp, unsigned gwv)
814{
815 match ret = MATCH_YES;
816
817 if (gfc_match (" ( ") != MATCH_YES)
818 return MATCH_NO;
819
820 if (gwv == GOMP_DIM_GANG0)
821 {
822 /* The gang clause accepts two optional arguments, num and static.
823 The num argument may either be explicit (num: <val>) or
824 implicit without (<val> without num:). */
825
826 while (ret == MATCH_YES)
827 {
828 if (gfc_match (" static :") == MATCH_YES)
829 {
830 if (cp->gang_static)
831 return MATCH_ERROR;
832 else
833 cp->gang_static = true;
834 if (gfc_match_char ('*') == MATCH_YES)
835 cp->gang_static_expr = NULL__null;
836 else if (gfc_match (" %e ", &cp->gang_static_expr) != MATCH_YES)
837 return MATCH_ERROR;
838 }
839 else
840 {
841 if (cp->gang_num_expr)
842 return MATCH_ERROR;
843
844 /* The 'num' argument is optional. */
845 gfc_match (" num :");
846
847 if (gfc_match (" %e ", &cp->gang_num_expr) != MATCH_YES)
848 return MATCH_ERROR;
849 }
850
851 ret = gfc_match (" , ");
852 }
853 }
854 else if (gwv == GOMP_DIM_WORKER1)
855 {
856 /* The 'num' argument is optional. */
857 gfc_match (" num :");
858
859 if (gfc_match (" %e ", &cp->worker_expr) != MATCH_YES)
860 return MATCH_ERROR;
861 }
862 else if (gwv == GOMP_DIM_VECTOR2)
863 {
864 /* The 'length' argument is optional. */
865 gfc_match (" length :");
866
867 if (gfc_match (" %e ", &cp->vector_expr) != MATCH_YES)
868 return MATCH_ERROR;
869 }
870 else
871 gfc_fatal_error ("Unexpected OpenACC parallelism.");
872
873 return gfc_match (" )");
874}
875
876static match
877gfc_match_oacc_clause_link (const char *str, gfc_omp_namelist **list)
878{
879 gfc_omp_namelist *head = NULL__null;
880 gfc_omp_namelist *tail, *p;
881 locus old_loc;
882 char n[GFC_MAX_SYMBOL_LEN63+1];
883 gfc_symbol *sym;
884 match m;
885 gfc_symtree *st;
886
887 old_loc = gfc_current_locus;
888
889 m = gfc_match (str);
890 if (m != MATCH_YES)
891 return m;
892
893 m = gfc_match (" (");
894
895 for (;;)
896 {
897 m = gfc_match_symbol (&sym, 0);
898 switch (m)
899 {
900 case MATCH_YES:
901 if (sym->attr.in_common)
902 {
903 gfc_error_now ("Variable at %C is an element of a COMMON block");
904 goto cleanup;
905 }
906 gfc_set_sym_referenced (sym);
907 p = gfc_get_omp_namelist ()((gfc_omp_namelist *) xcalloc (1, sizeof (gfc_omp_namelist)));
908 if (head == NULL__null)
909 head = tail = p;
910 else
911 {
912 tail->next = p;
913 tail = tail->next;
914 }
915 tail->sym = sym;
916 tail->expr = NULL__null;
917 tail->where = gfc_current_locus;
918 goto next_item;
919 case MATCH_NO:
920 break;
921
922 case MATCH_ERROR:
923 goto cleanup;
924 }
925
926 m = gfc_match (" / %n /", n);
927 if (m == MATCH_ERROR)
928 goto cleanup;
929 if (m == MATCH_NO || n[0] == '\0')
930 goto syntax;
931
932 st = gfc_find_symtree (gfc_current_ns->common_root, n);
933 if (st == NULL__null)
934 {
935 gfc_error ("COMMON block /%s/ not found at %C", n);
936 goto cleanup;
937 }
938
939 for (sym = st->n.common->head; sym; sym = sym->common_next)
940 {
941 gfc_set_sym_referenced (sym);
942 p = gfc_get_omp_namelist ()((gfc_omp_namelist *) xcalloc (1, sizeof (gfc_omp_namelist)));
943 if (head == NULL__null)
944 head = tail = p;
945 else
946 {
947 tail->next = p;
948 tail = tail->next;
949 }
950 tail->sym = sym;
951 tail->where = gfc_current_locus;
952 }
953
954 next_item:
955 if (gfc_match_char (')') == MATCH_YES)
956 break;
957 if (gfc_match_char (',') != MATCH_YES)
958 goto syntax;
959 }
960
961 if (gfc_match_omp_eos () != MATCH_YES)
962 {
963 gfc_error ("Unexpected junk after !$ACC DECLARE at %C");
964 goto cleanup;
965 }
966
967 while (*list)
968 list = &(*list)->next;
969 *list = head;
970 return MATCH_YES;
971
972syntax:
973 gfc_error ("Syntax error in !$ACC DECLARE list at %C");
974
975cleanup:
976 gfc_current_locus = old_loc;
977 return MATCH_ERROR;
978}
979
980/* OpenMP clauses. */
981enum omp_mask1
982{
983 OMP_CLAUSE_PRIVATE,
984 OMP_CLAUSE_FIRSTPRIVATE,
985 OMP_CLAUSE_LASTPRIVATE,
986 OMP_CLAUSE_COPYPRIVATE,
987 OMP_CLAUSE_SHARED,
988 OMP_CLAUSE_COPYIN,
989 OMP_CLAUSE_REDUCTION,
990 OMP_CLAUSE_IN_REDUCTION,
991 OMP_CLAUSE_TASK_REDUCTION,
992 OMP_CLAUSE_IF,
993 OMP_CLAUSE_NUM_THREADS,
994 OMP_CLAUSE_SCHEDULE,
995 OMP_CLAUSE_DEFAULT,
996 OMP_CLAUSE_ORDER,
997 OMP_CLAUSE_ORDERED,
998 OMP_CLAUSE_COLLAPSE,
999 OMP_CLAUSE_UNTIED,
1000 OMP_CLAUSE_FINAL,
1001 OMP_CLAUSE_MERGEABLE,
1002 OMP_CLAUSE_ALIGNED,
1003 OMP_CLAUSE_DEPEND,
1004 OMP_CLAUSE_INBRANCH,
1005 OMP_CLAUSE_LINEAR,
1006 OMP_CLAUSE_NOTINBRANCH,
1007 OMP_CLAUSE_PROC_BIND,
1008 OMP_CLAUSE_SAFELEN,
1009 OMP_CLAUSE_SIMDLEN,
1010 OMP_CLAUSE_UNIFORM,
1011 OMP_CLAUSE_DEVICE,
1012 OMP_CLAUSE_MAP,
1013 OMP_CLAUSE_TO,
1014 OMP_CLAUSE_FROM,
1015 OMP_CLAUSE_NUM_TEAMS,
1016 OMP_CLAUSE_THREAD_LIMIT,
1017 OMP_CLAUSE_DIST_SCHEDULE,
1018 OMP_CLAUSE_DEFAULTMAP,
1019 OMP_CLAUSE_GRAINSIZE,
1020 OMP_CLAUSE_HINT,
1021 OMP_CLAUSE_IS_DEVICE_PTR,
1022 OMP_CLAUSE_LINK,
1023 OMP_CLAUSE_NOGROUP,
1024 OMP_CLAUSE_NOTEMPORAL,
1025 OMP_CLAUSE_NUM_TASKS,
1026 OMP_CLAUSE_PRIORITY,
1027 OMP_CLAUSE_SIMD,
1028 OMP_CLAUSE_THREADS,
1029 OMP_CLAUSE_USE_DEVICE_PTR,
1030 OMP_CLAUSE_USE_DEVICE_ADDR, /* OpenMP 5.0. */
1031 OMP_CLAUSE_DEVICE_TYPE, /* OpenMP 5.0. */
1032 OMP_CLAUSE_ATOMIC, /* OpenMP 5.0. */
1033 OMP_CLAUSE_CAPTURE, /* OpenMP 5.0. */
1034 OMP_CLAUSE_MEMORDER, /* OpenMP 5.0. */
1035 OMP_CLAUSE_DETACH, /* OpenMP 5.0. */
1036 OMP_CLAUSE_AFFINITY, /* OpenMP 5.0. */
1037 OMP_CLAUSE_ALLOCATE, /* OpenMP 5.0. */
1038 OMP_CLAUSE_BIND, /* OpenMP 5.0. */
1039 OMP_CLAUSE_FILTER, /* OpenMP 5.1. */
1040 OMP_CLAUSE_AT, /* OpenMP 5.1. */
1041 OMP_CLAUSE_MESSAGE, /* OpenMP 5.1. */
1042 OMP_CLAUSE_SEVERITY, /* OpenMP 5.1. */
1043 OMP_CLAUSE_COMPARE, /* OpenMP 5.1. */
1044 OMP_CLAUSE_FAIL, /* OpenMP 5.1. */
1045 OMP_CLAUSE_WEAK, /* OpenMP 5.1. */
1046 OMP_CLAUSE_NOWAIT,
1047 /* This must come last. */
1048 OMP_MASK1_LAST
1049};
1050
1051/* More OpenMP clauses and OpenACC 2.0+ specific clauses. */
1052enum omp_mask2
1053{
1054 OMP_CLAUSE_ASYNC,
1055 OMP_CLAUSE_NUM_GANGS,
1056 OMP_CLAUSE_NUM_WORKERS,
1057 OMP_CLAUSE_VECTOR_LENGTH,
1058 OMP_CLAUSE_COPY,
1059 OMP_CLAUSE_COPYOUT,
1060 OMP_CLAUSE_CREATE,
1061 OMP_CLAUSE_NO_CREATE,
1062 OMP_CLAUSE_PRESENT,
1063 OMP_CLAUSE_DEVICEPTR,
1064 OMP_CLAUSE_GANG,
1065 OMP_CLAUSE_WORKER,
1066 OMP_CLAUSE_VECTOR,
1067 OMP_CLAUSE_SEQ,
1068 OMP_CLAUSE_INDEPENDENT,
1069 OMP_CLAUSE_USE_DEVICE,
1070 OMP_CLAUSE_DEVICE_RESIDENT,
1071 OMP_CLAUSE_HOST_SELF,
1072 OMP_CLAUSE_WAIT,
1073 OMP_CLAUSE_DELETE,
1074 OMP_CLAUSE_AUTO,
1075 OMP_CLAUSE_TILE,
1076 OMP_CLAUSE_IF_PRESENT,
1077 OMP_CLAUSE_FINALIZE,
1078 OMP_CLAUSE_ATTACH,
1079 OMP_CLAUSE_NOHOST,
1080 OMP_CLAUSE_HAS_DEVICE_ADDR, /* OpenMP 5.1 */
1081 OMP_CLAUSE_ENTER, /* OpenMP 5.2 */
1082 OMP_CLAUSE_DOACROSS, /* OpenMP 5.2 */
1083 OMP_CLAUSE_ASSUMPTIONS, /* OpenMP 5.1. */
1084 /* This must come last. */
1085 OMP_MASK2_LAST
1086};
1087
1088struct omp_inv_mask;
1089
1090/* Customized bitset for up to 128-bits.
1091 The two enums above provide bit numbers to use, and which of the
1092 two enums it is determines which of the two mask fields is used.
1093 Supported operations are defining a mask, like:
1094 #define XXX_CLAUSES \
1095 (omp_mask (OMP_CLAUSE_XXX) | OMP_CLAUSE_YYY | OMP_CLAUSE_ZZZ)
1096 oring such bitsets together or removing selected bits:
1097 (XXX_CLAUSES | YYY_CLAUSES) & ~(omp_mask (OMP_CLAUSE_VVV))
1098 and testing individual bits:
1099 if (mask & OMP_CLAUSE_UUU) */
1100
1101struct omp_mask {
1102 const uint64_t mask1;
1103 const uint64_t mask2;
1104 inline omp_mask ();
1105 inline omp_mask (omp_mask1);
1106 inline omp_mask (omp_mask2);
1107 inline omp_mask (uint64_t, uint64_t);
1108 inline omp_mask operator| (omp_mask1) const;
1109 inline omp_mask operator| (omp_mask2) const;
1110 inline omp_mask operator| (omp_mask) const;
1111 inline omp_mask operator& (const omp_inv_mask &) const;
1112 inline bool operator& (omp_mask1) const;
1113 inline bool operator& (omp_mask2) const;
1114 inline omp_inv_mask operator~ () const;
1115};
1116
1117struct omp_inv_mask : public omp_mask {
1118 inline omp_inv_mask (const omp_mask &);
1119};
1120
1121omp_mask::omp_mask () : mask1 (0), mask2 (0)
1122{
1123}
1124
1125omp_mask::omp_mask (omp_mask1 m) : mask1 (((uint64_t) 1) << m), mask2 (0)
1126{
1127}
1128
1129omp_mask::omp_mask (omp_mask2 m) : mask1 (0), mask2 (((uint64_t) 1) << m)
1130{
1131}
1132
1133omp_mask::omp_mask (uint64_t m1, uint64_t m2) : mask1 (m1), mask2 (m2)
1134{
1135}
1136
1137omp_mask
1138omp_mask::operator| (omp_mask1 m) const
1139{
1140 return omp_mask (mask1 | (((uint64_t) 1) << m), mask2);
1141}
1142
1143omp_mask
1144omp_mask::operator| (omp_mask2 m) const
1145{
1146 return omp_mask (mask1, mask2 | (((uint64_t) 1) << m));
1147}
1148
1149omp_mask
1150omp_mask::operator| (omp_mask m) const
1151{
1152 return omp_mask (mask1 | m.mask1, mask2 | m.mask2);
1153}
1154
1155omp_mask
1156omp_mask::operator& (const omp_inv_mask &m) const
1157{
1158 return omp_mask (mask1 & ~m.mask1, mask2 & ~m.mask2);
1159}
1160
1161bool
1162omp_mask::operator& (omp_mask1 m) const
1163{
1164 return (mask1 & (((uint64_t) 1) << m)) != 0;
1165}
1166
1167bool
1168omp_mask::operator& (omp_mask2 m) const
1169{
1170 return (mask2 & (((uint64_t) 1) << m)) != 0;
1171}
1172
1173omp_inv_mask
1174omp_mask::operator~ () const
1175{
1176 return omp_inv_mask (*this);
1177}
1178
1179omp_inv_mask::omp_inv_mask (const omp_mask &m) : omp_mask (m)
1180{
1181}
1182
1183/* Helper function for OpenACC and OpenMP clauses involving memory
1184 mapping. */
1185
1186static bool
1187gfc_match_omp_map_clause (gfc_omp_namelist **list, gfc_omp_map_op map_op,
1188 bool allow_common, bool allow_derived)
1189{
1190 gfc_omp_namelist **head = NULL__null;
1191 if (gfc_match_omp_variable_list ("", list, allow_common, NULL__null, &head, true,
1192 allow_derived)
1193 == MATCH_YES)
1194 {
1195 gfc_omp_namelist *n;
1196 for (n = *head; n; n = n->next)
1197 n->u.map_op = map_op;
1198 return true;
1199 }
1200
1201 return false;
1202}
1203
1204static match
1205gfc_match_iterator (gfc_namespace **ns, bool permit_var)
1206{
1207 locus old_loc = gfc_current_locus;
1208
1209 if (gfc_match ("iterator ( ") != MATCH_YES)
1210 return MATCH_NO;
1211
1212 gfc_typespec ts;
1213 gfc_symbol *last = NULL__null;
1214 gfc_expr *begin, *end, *step;
1215 *ns = gfc_build_block_ns (gfc_current_ns);
1216 char name[GFC_MAX_SYMBOL_LEN63 + 1];
1217 while (true)
1218 {
1219 locus prev_loc = gfc_current_locus;
1220 if (gfc_match_type_spec (&ts) == MATCH_YES
1221 && gfc_match (" :: ") == MATCH_YES)
1222 {
1223 if (ts.type != BT_INTEGER)
1224 {
1225 gfc_error ("Expected INTEGER type at %L", &prev_loc);
1226 return MATCH_ERROR;
1227 }
1228 permit_var = false;
1229 }
1230 else
1231 {
1232 ts.type = BT_INTEGER;
1233 ts.kind = gfc_default_integer_kind;
1234 gfc_current_locus = prev_loc;
1235 }
1236 prev_loc = gfc_current_locus;
1237 if (gfc_match_name (name) != MATCH_YES)
1238 {
1239 gfc_error ("Expected identifier at %C");
1240 goto failed;
1241 }
1242 if (gfc_find_symtree ((*ns)->sym_root, name))
1243 {
1244 gfc_error ("Same identifier %qs specified again at %C", name);
1245 goto failed;
1246 }
1247
1248 gfc_symbol *sym = gfc_new_symbol (name, *ns);
1249 if (last)
1250 last->tlink = sym;
1251 else
1252 (*ns)->omp_affinity_iterators = sym;
1253 last = sym;
1254 sym->declared_at = prev_loc;
1255 sym->ts = ts;
1256 sym->attr.flavor = FL_VARIABLE;
1257 sym->attr.artificial = 1;
1258 sym->attr.referenced = 1;
1259 sym->refs++;
1260 gfc_symtree *st = gfc_new_symtree (&(*ns)->sym_root, name);
1261 st->n.sym = sym;
1262
1263 prev_loc = gfc_current_locus;
1264 if (gfc_match (" = ") != MATCH_YES)
1265 goto failed;
1266 permit_var = false;
1267 begin = end = step = NULL__null;
1268 if (gfc_match ("%e : ", &begin) != MATCH_YES
1269 || gfc_match ("%e ", &end) != MATCH_YES)
1270 {
1271 gfc_error ("Expected range-specification at %C");
1272 gfc_free_expr (begin);
1273 gfc_free_expr (end);
1274 return MATCH_ERROR;
1275 }
1276 if (':' == gfc_peek_ascii_char ())
1277 {
1278 if (gfc_match (": %e ", &step) != MATCH_YES)
1279 {
1280 gfc_free_expr (begin);
1281 gfc_free_expr (end);
1282 gfc_free_expr (step);
1283 goto failed;
1284 }
1285 }
1286
1287 gfc_expr *e = gfc_get_expr ();
1288 e->where = prev_loc;
1289 e->expr_type = EXPR_ARRAY;
1290 e->ts = ts;
1291 e->rank = 1;
1292 e->shape = gfc_get_shape (1)(((mpz_t *) xcalloc (((1)), sizeof (mpz_t))));
1293 mpz_init_set_ui__gmpz_init_set_ui (e->shape[0], step ? 3 : 2);
1294 gfc_constructor_append_expr (&e->value.constructor, begin, &begin->where);
1295 gfc_constructor_append_expr (&e->value.constructor, end, &end->where);
1296 if (step)
1297 gfc_constructor_append_expr (&e->value.constructor, step, &step->where);
1298 sym->value = e;
1299
1300 if (gfc_match (") ") == MATCH_YES)
1301 break;
1302 if (gfc_match (", ") != MATCH_YES)
1303 goto failed;
1304 }
1305 return MATCH_YES;
1306
1307failed:
1308 gfc_namespace *prev_ns = NULL__null;
1309 for (gfc_namespace *it = gfc_current_ns->contained; it; it = it->sibling)
1310 {
1311 if (it == *ns)
1312 {
1313 if (prev_ns)
1314 prev_ns->sibling = it->sibling;
1315 else
1316 gfc_current_ns->contained = it->sibling;
1317 gfc_free_namespace (it);
1318 break;
1319 }
1320 prev_ns = it;
1321 }
1322 *ns = NULL__null;
1323 if (!permit_var)
1324 return MATCH_ERROR;
1325 gfc_current_locus = old_loc;
1326 return MATCH_NO;
1327}
1328
1329/* reduction ( reduction-modifier, reduction-operator : variable-list )
1330 in_reduction ( reduction-operator : variable-list )
1331 task_reduction ( reduction-operator : variable-list ) */
1332
1333static match
1334gfc_match_omp_clause_reduction (char pc, gfc_omp_clauses *c, bool openacc,
1335 bool allow_derived, bool openmp_target = false)
1336{
1337 if (pc == 'r' && gfc_match ("reduction ( ") != MATCH_YES)
1338 return MATCH_NO;
1339 else if (pc == 'i' && gfc_match ("in_reduction ( ") != MATCH_YES)
1340 return MATCH_NO;
1341 else if (pc == 't' && gfc_match ("task_reduction ( ") != MATCH_YES)
1342 return MATCH_NO;
1343
1344 locus old_loc = gfc_current_locus;
1345 int list_idx = 0;
1346
1347 if (pc == 'r' && !openacc)
1348 {
1349 if (gfc_match ("inscan") == MATCH_YES)
1350 list_idx = OMP_LIST_REDUCTION_INSCAN;
1351 else if (gfc_match ("task") == MATCH_YES)
1352 list_idx = OMP_LIST_REDUCTION_TASK;
1353 else if (gfc_match ("default") == MATCH_YES)
1354 list_idx = OMP_LIST_REDUCTION;
1355 if (list_idx != 0 && gfc_match (", ") != MATCH_YES)
1356 {
1357 gfc_error ("Comma expected at %C");
1358 gfc_current_locus = old_loc;
1359 return MATCH_NO;
1360 }
1361 if (list_idx == 0)
1362 list_idx = OMP_LIST_REDUCTION;
1363 }
1364 else if (pc == 'i')
1365 list_idx = OMP_LIST_IN_REDUCTION;
1366 else if (pc == 't')
1367 list_idx = OMP_LIST_TASK_REDUCTION;
1368 else
1369 list_idx = OMP_LIST_REDUCTION;
1370
1371 gfc_omp_reduction_op rop = OMP_REDUCTION_NONE;
1372 char buffer[GFC_MAX_SYMBOL_LEN63 + 3];
1373 if (gfc_match_char ('+') == MATCH_YES)
1374 rop = OMP_REDUCTION_PLUS;
1375 else if (gfc_match_char ('*') == MATCH_YES)
1376 rop = OMP_REDUCTION_TIMES;
1377 else if (gfc_match_char ('-') == MATCH_YES)
1378 rop = OMP_REDUCTION_MINUS;
1379 else if (gfc_match (".and.") == MATCH_YES)
1380 rop = OMP_REDUCTION_AND;
1381 else if (gfc_match (".or.") == MATCH_YES)
1382 rop = OMP_REDUCTION_OR;
1383 else if (gfc_match (".eqv.") == MATCH_YES)
1384 rop = OMP_REDUCTION_EQV;
1385 else if (gfc_match (".neqv.") == MATCH_YES)
1386 rop = OMP_REDUCTION_NEQV;
1387 if (rop != OMP_REDUCTION_NONE)
1388 snprintf (buffer, sizeof buffer, "operator %s",
1389 gfc_op2string ((gfc_intrinsic_op) rop));
1390 else if (gfc_match_defined_op_name (buffer + 1, 1) == MATCH_YES)
1391 {
1392 buffer[0] = '.';
1393 strcat (buffer, ".");
1394 }
1395 else if (gfc_match_name (buffer) == MATCH_YES)
1396 {
1397 gfc_symbol *sym;
1398 const char *n = buffer;
1399
1400 gfc_find_symbol (buffer, NULL__null, 1, &sym);
1401 if (sym != NULL__null)
1402 {
1403 if (sym->attr.intrinsic)
1404 n = sym->name;
1405 else if ((sym->attr.flavor != FL_UNKNOWN
1406 && sym->attr.flavor != FL_PROCEDURE)
1407 || sym->attr.external
1408 || sym->attr.generic
1409 || sym->attr.entry
1410 || sym->attr.result
1411 || sym->attr.dummy
1412 || sym->attr.subroutine
1413 || sym->attr.pointer
1414 || sym->attr.target
1415 || sym->attr.cray_pointer
1416 || sym->attr.cray_pointee
1417 || (sym->attr.proc != PROC_UNKNOWN
1418 && sym->attr.proc != PROC_INTRINSIC)
1419 || sym->attr.if_source != IFSRC_UNKNOWN
1420 || sym == sym->ns->proc_name)
1421 {
1422 sym = NULL__null;
1423 n = NULL__null;
1424 }
1425 else
1426 n = sym->name;
1427 }
1428 if (n == NULL__null)
1429 rop = OMP_REDUCTION_NONE;
1430 else if (strcmp (n, "max") == 0)
1431 rop = OMP_REDUCTION_MAX;
1432 else if (strcmp (n, "min") == 0)
1433 rop = OMP_REDUCTION_MIN;
1434 else if (strcmp (n, "iand") == 0)
1435 rop = OMP_REDUCTION_IAND;
1436 else if (strcmp (n, "ior") == 0)
1437 rop = OMP_REDUCTION_IOR;
1438 else if (strcmp (n, "ieor") == 0)
1439 rop = OMP_REDUCTION_IEOR;
1440 if (rop != OMP_REDUCTION_NONE
1441 && sym != NULL__null
1442 && ! sym->attr.intrinsic
1443 && ! sym->attr.use_assoc
1444 && ((sym->attr.flavor == FL_UNKNOWN
1445 && !gfc_add_flavor (&sym->attr, FL_PROCEDURE,
1446 sym->name, NULL__null))
1447 || !gfc_add_intrinsic (&sym->attr, NULL__null)))
1448 rop = OMP_REDUCTION_NONE;
1449 }
1450 else
1451 buffer[0] = '\0';
1452 gfc_omp_udr *udr = (buffer[0] ? gfc_find_omp_udr (gfc_current_ns, buffer, NULL__null)
1453 : NULL__null);
1454 gfc_omp_namelist **head = NULL__null;
1455 if (rop == OMP_REDUCTION_NONE && udr)
1456 rop = OMP_REDUCTION_USER;
1457
1458 if (gfc_match_omp_variable_list (" :", &c->lists[list_idx], false, NULL__null,
1459 &head, openacc, allow_derived) != MATCH_YES)
1460 {
1461 gfc_current_locus = old_loc;
1462 return MATCH_NO;
1463 }
1464 gfc_omp_namelist *n;
1465 if (rop == OMP_REDUCTION_NONE)
1466 {
1467 n = *head;
1468 *head = NULL__null;
1469 gfc_error_now ("!$OMP DECLARE REDUCTION %s not found at %L",
1470 buffer, &old_loc);
1471 gfc_free_omp_namelist (n, false, false);
1472 }
1473 else
1474 for (n = *head; n; n = n->next)
1475 {
1476 n->u.reduction_op = rop;
1477 if (udr)
1478 {
1479 n->u2.udr = gfc_get_omp_namelist_udr ()((gfc_omp_namelist_udr *) xcalloc (1, sizeof (gfc_omp_namelist_udr
)))
;
1480 n->u2.udr->udr = udr;
1481 }
1482 if (openmp_target && list_idx == OMP_LIST_IN_REDUCTION)
1483 {
1484 gfc_omp_namelist *p = gfc_get_omp_namelist ()((gfc_omp_namelist *) xcalloc (1, sizeof (gfc_omp_namelist))), **tl;
1485 p->sym = n->sym;
1486 p->where = p->where;
1487 p->u.map_op = OMP_MAP_ALWAYS_TOFROM;
1488
1489 tl = &c->lists[OMP_LIST_MAP];
1490 while (*tl)
1491 tl = &((*tl)->next);
1492 *tl = p;
1493 p->next = NULL__null;
1494 }
1495 }
1496 return MATCH_YES;
1497}
1498
1499static match
1500gfc_omp_absent_contains_clause (gfc_omp_assumptions **assume, bool is_absent)
1501{
1502 if (*assume == NULL__null)
1503 *assume = gfc_get_omp_assumptions ()((gfc_omp_assumptions *) xcalloc (1, sizeof (gfc_omp_assumptions
)))
;
1504 do
1505 {
1506 gfc_statement st = ST_NONE;
1507 gfc_gobble_whitespace ();
1508 locus old_loc = gfc_current_locus;
1509 char c = gfc_peek_ascii_char ();
1510 enum gfc_omp_directive_kind kind
1511 = GFC_OMP_DIR_DECLARATIVE; /* Silence warning. */
1512 for (size_t i = 0; i < ARRAY_SIZE (gfc_omp_directives)(sizeof (gfc_omp_directives) / sizeof ((gfc_omp_directives)[0
]))
; i++)
1513 {
1514 if (gfc_omp_directives[i].name[0] > c)
1515 break;
1516 if (gfc_omp_directives[i].name[0] != c)
1517 continue;
1518 if (gfc_match (gfc_omp_directives[i].name) == MATCH_YES)
1519 {
1520 st = gfc_omp_directives[i].st;
1521 kind = gfc_omp_directives[i].kind;
1522 }
1523 }
1524 gfc_gobble_whitespace ();
1525 c = gfc_peek_ascii_char ();
1526 if (st == ST_NONE || (c != ',' && c != ')'))
1527 {
1528 if (st == ST_NONE)
1529 gfc_error ("Unknown directive at %L", &old_loc);
1530 else
1531 gfc_error ("Invalid combined or composit directive at %L",
1532 &old_loc);
1533 return MATCH_ERROR;
1534 }
1535 if (kind == GFC_OMP_DIR_DECLARATIVE
1536 || kind == GFC_OMP_DIR_INFORMATIONAL
1537 || kind == GFC_OMP_DIR_META)
1538 {
1539 gfc_error ("Invalid %qs directive at %L in %s clause: declarative, "
1540 "informational and meta directives not permitted",
1541 gfc_ascii_statement (st, true), &old_loc,
1542 is_absent ? "ABSENT" : "CONTAINS");
1543 return MATCH_ERROR;
1544 }
1545 if (is_absent)
1546 {
1547 /* Use exponential allocation; equivalent to pow2p(x). */
1548 int i = (*assume)->n_absent;
1549 int size = ((i == 0) ? 4
1550 : pow2p_hwi (i) == 1 ? i*2 : 0);
1551 if (size != 0)
1552 (*assume)->absent = XRESIZEVEC (gfc_statement,((gfc_statement *) xrealloc ((void *) ((*assume)->absent),
sizeof (gfc_statement) * (size)))
1553 (*assume)->absent, size)((gfc_statement *) xrealloc ((void *) ((*assume)->absent),
sizeof (gfc_statement) * (size)))
;
1554 (*assume)->absent[(*assume)->n_absent++] = st;
1555 }
1556 else
1557 {
1558 int i = (*assume)->n_contains;
1559 int size = ((i == 0) ? 4
1560 : pow2p_hwi (i) == 1 ? i*2 : 0);
1561 if (size != 0)
1562 (*assume)->contains = XRESIZEVEC (gfc_statement,((gfc_statement *) xrealloc ((void *) ((*assume)->contains
), sizeof (gfc_statement) * (size)))
1563 (*assume)->contains, size)((gfc_statement *) xrealloc ((void *) ((*assume)->contains
), sizeof (gfc_statement) * (size)))
;
1564 (*assume)->contains[(*assume)->n_contains++] = st;
1565 }
1566 gfc_gobble_whitespace ();
1567 if (gfc_match(",") == MATCH_YES)
1568 continue;
1569 if (gfc_match(")") == MATCH_YES)
1570 break;
1571 gfc_error ("Expected %<,%> or %<)%> at %C");
1572 return MATCH_ERROR;
1573 }
1574 while (true);
1575
1576 return MATCH_YES;
1577}
1578
1579/* Check 'check' argument for duplicated statements in absent and/or contains
1580 clauses. If 'merge', merge them from check to 'merge'. */
1581
1582static match
1583omp_verify_merge_absent_contains (gfc_statement st, gfc_omp_assumptions *check,
1584 gfc_omp_assumptions *merge, locus *loc)
1585{
1586 if (check == NULL__null)
1587 return MATCH_YES;
1588 bitmap_head absent_head, contains_head;
1589 bitmap_obstack_initialize (NULL__null);
1590 bitmap_initialize (&absent_head, &bitmap_default_obstack);
1591 bitmap_initialize (&contains_head, &bitmap_default_obstack);
1592
1593 match m = MATCH_YES;
1594 for (int i = 0; i < check->n_absent; i++)
1595 if (!bitmap_set_bit (&absent_head, check->absent[i]))
1596 {
1597 gfc_error ("%qs directive mentioned multiple times in %s clause in %s "
1598 "directive at %L",
1599 gfc_ascii_statement (check->absent[i], true),
1600 "ABSENT", gfc_ascii_statement (st), loc);
1601 m = MATCH_ERROR;
1602 }
1603 for (int i = 0; i < check->n_contains; i++)
1604 {
1605 if (!bitmap_set_bit (&contains_head, check->contains[i]))
1606 {
1607 gfc_error ("%qs directive mentioned multiple times in %s clause in %s "
1608 "directive at %L",
1609 gfc_ascii_statement (check->contains[i], true),
1610 "CONTAINS", gfc_ascii_statement (st), loc);
1611 m = MATCH_ERROR;
1612 }
1613 if (bitmap_bit_p (&absent_head, check->contains[i]))
1614 {
1615 gfc_error ("%qs directive mentioned both times in ABSENT and CONTAINS "
1616 "clauses in %s directive at %L",
1617 gfc_ascii_statement (check->absent[i], true),
1618 gfc_ascii_statement (st), loc);
1619 m = MATCH_ERROR;
1620 }
1621 }
1622
1623 if (m == MATCH_ERROR)
1624 return MATCH_ERROR;
1625 if (merge == NULL__null)
1626 return MATCH_YES;
1627 if (merge->absent == NULL__null && check->absent)
1628 {
1629 merge->n_absent = check->n_absent;
1630 merge->absent = check->absent;
1631 check->absent = NULL__null;
1632 }
1633 else if (merge->absent && check->absent)
1634 {
1635 check->absent = XRESIZEVEC (gfc_statement, check->absent,((gfc_statement *) xrealloc ((void *) (check->absent), sizeof
(gfc_statement) * (merge->n_absent + check->n_absent))
)
1636 merge->n_absent + check->n_absent)((gfc_statement *) xrealloc ((void *) (check->absent), sizeof
(gfc_statement) * (merge->n_absent + check->n_absent))
)
;
1637 for (int i = 0; i < merge->n_absent; i++)
1638 if (!bitmap_bit_p (&absent_head, merge->absent[i]))
1639 check->absent[check->n_absent++] = merge->absent[i];
1640 free (merge->absent);
1641 merge->absent = check->absent;
1642 merge->n_absent = check->n_absent;
1643 check->absent = NULL__null;
1644 }
1645 if (merge->contains == NULL__null && check->contains)
1646 {
1647 merge->n_contains = check->n_contains;
1648 merge->contains = check->contains;
1649 check->contains = NULL__null;
1650 }
1651 else if (merge->contains && check->contains)
1652 {
1653 check->contains = XRESIZEVEC (gfc_statement, check->contains,((gfc_statement *) xrealloc ((void *) (check->contains), sizeof
(gfc_statement) * (merge->n_contains + check->n_contains
)))
1654 merge->n_contains + check->n_contains)((gfc_statement *) xrealloc ((void *) (check->contains), sizeof
(gfc_statement) * (merge->n_contains + check->n_contains
)))
;
1655 for (int i = 0; i < merge->n_contains; i++)
1656 if (!bitmap_bit_p (&contains_head, merge->contains[i]))
1657 check->contains[check->n_contains++] = merge->contains[i];
1658 free (merge->contains);
1659 merge->contains = check->contains;
1660 merge->n_contains = check->n_contains;
1661 check->contains = NULL__null;
1662 }
1663 return MATCH_YES;
1664}
1665
1666
1667/* Match with duplicate check. Matches 'name'. If expr != NULL, it
1668 then matches '(expr)', otherwise, if open_parens is true,
1669 it matches a ' ( ' after 'name'.
1670 dupl_message requires '%qs %L' - and is used by
1671 gfc_match_dupl_memorder and gfc_match_dupl_atomic. */
1672
1673static match
1674gfc_match_dupl_check (bool not_dupl, const char *name, bool open_parens = false,
1675 gfc_expr **expr = NULL__null, const char *dupl_msg = NULL__null)
1676{
1677 match m;
1678 locus old_loc = gfc_current_locus;
1679 if ((m = gfc_match (name)) != MATCH_YES)
1680 return m;
1681 if (!not_dupl)
1682 {
1683 if (dupl_msg)
1684 gfc_error (dupl_msg, name, &old_loc);
1685 else
1686 gfc_error ("Duplicated %qs clause at %L", name, &old_loc);
1687 return MATCH_ERROR;
1688 }
1689 if (open_parens || expr)
1690 {
1691 if (gfc_match (" ( ") != MATCH_YES)
1692 {
1693 gfc_error ("Expected %<(%> after %qs at %C", name);
1694 return MATCH_ERROR;
1695 }
1696 if (expr)
1697 {
1698 if (gfc_match ("%e )", expr) != MATCH_YES)
1699 {
1700 gfc_error ("Invalid expression after %<%s(%> at %C", name);
1701 return MATCH_ERROR;
1702 }
1703 }
1704 }
1705 return MATCH_YES;
1706}
1707
1708static match
1709gfc_match_dupl_memorder (bool not_dupl, const char *name)
1710{
1711 return gfc_match_dupl_check (not_dupl, name, false, NULL__null,
1712 "Duplicated memory-order clause: unexpected %s "
1713 "clause at %L");
1714}
1715
1716static match
1717gfc_match_dupl_atomic (bool not_dupl, const char *name)
1718{
1719 return gfc_match_dupl_check (not_dupl, name, false, NULL__null,
1720 "Duplicated atomic clause: unexpected %s "
1721 "clause at %L");
1722}
1723
1724/* Match OpenMP and OpenACC directive clauses. MASK is a bitmask of
1725 clauses that are allowed for a particular directive. */
1726
1727static match
1728gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
1729 bool first = true, bool needs_space = true,
1730 bool openacc = false, bool context_selector = false,
1731 bool openmp_target = false)
1732{
1733 bool error = false;
1734 gfc_omp_clauses *c = gfc_get_omp_clauses ()((gfc_omp_clauses *) xcalloc (1, sizeof (gfc_omp_clauses)));
1735 locus old_loc;
1736 /* Determine whether we're dealing with an OpenACC directive that permits
1737 derived type member accesses. This in particular disallows
1738 "!$acc declare" from using such accesses, because it's not clear if/how
1739 that should work. */
1740 bool allow_derived = (openacc
1741 && ((mask & OMP_CLAUSE_ATTACH)
1742 || (mask & OMP_CLAUSE_DETACH)
1743 || (mask & OMP_CLAUSE_HOST_SELF)));
1744
1745 gcc_checking_assert (OMP_MASK1_LAST <= 64 && OMP_MASK2_LAST <= 64)((void)(!(OMP_MASK1_LAST <= 64 && OMP_MASK2_LAST <=
64) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/fortran/openmp.cc"
, 1745, __FUNCTION__), 0 : 0))
;
1746 *cp = NULL__null;
1747 while (1)
1748 {
1749 match m = MATCH_NO;
1750 if ((first || (m = gfc_match_char (',')) != MATCH_YES)
1751 && (needs_space && gfc_match_space () != MATCH_YES))
1752 break;
1753 needs_space = false;
1754 first = false;
1755 gfc_gobble_whitespace ();
1756 bool end_colon;
1757 gfc_omp_namelist **head;
1758 old_loc = gfc_current_locus;
1759 char pc = gfc_peek_ascii_char ();
1760 if (pc == '\n' && m == MATCH_YES)
1761 {
1762 gfc_error ("Clause expected at %C after trailing comma");
1763 goto error;
1764 }
1765 switch (pc)
1766 {
1767 case 'a':
1768 end_colon = false;
1769 head = NULL__null;
1770 if ((mask & OMP_CLAUSE_ASSUMPTIONS)
1771 && gfc_match ("absent ( ") == MATCH_YES)
1772 {
1773 if (gfc_omp_absent_contains_clause (&c->assume, true)
1774 != MATCH_YES)
1775 goto error;
1776 continue;
1777 }
1778 if ((mask & OMP_CLAUSE_ALIGNED)
1779 && gfc_match_omp_variable_list ("aligned (",
1780 &c->lists[OMP_LIST_ALIGNED],
1781 false, &end_colon,
1782 &head) == MATCH_YES)
1783 {
1784 gfc_expr *alignment = NULL__null;
1785 gfc_omp_namelist *n;
1786
1787 if (end_colon && gfc_match (" %e )", &alignment) != MATCH_YES)
1788 {
1789 gfc_free_omp_namelist (*head, false, false);
1790 gfc_current_locus = old_loc;
1791 *head = NULL__null;
1792 break;
1793 }
1794 for (n = *head; n; n = n->next)
1795 if (n->next && alignment)
1796 n->expr = gfc_copy_expr (alignment);
1797 else
1798 n->expr = alignment;
1799 continue;
1800 }
1801 if ((mask & OMP_CLAUSE_MEMORDER)
1802 && (m = gfc_match_dupl_memorder ((c->memorder
1803 == OMP_MEMORDER_UNSET),
1804 "acq_rel")) != MATCH_NO)
1805 {
1806 if (m == MATCH_ERROR)
1807 goto error;
1808 c->memorder = OMP_MEMORDER_ACQ_REL;
1809 needs_space = true;
1810 continue;
1811 }
1812 if ((mask & OMP_CLAUSE_MEMORDER)
1813 && (m = gfc_match_dupl_memorder ((c->memorder
1814 == OMP_MEMORDER_UNSET),
1815 "acquire")) != MATCH_NO)
1816 {
1817 if (m == MATCH_ERROR)
1818 goto error;
1819 c->memorder = OMP_MEMORDER_ACQUIRE;
1820 needs_space = true;
1821 continue;
1822 }
1823 if ((mask & OMP_CLAUSE_AFFINITY)
1824 && gfc_match ("affinity ( ") == MATCH_YES)
1825 {
1826 gfc_namespace *ns_iter = NULL__null, *ns_curr = gfc_current_ns;
1827 m = gfc_match_iterator (&ns_iter, true);
1828 if (m == MATCH_ERROR)
1829 break;
1830 if (m == MATCH_YES && gfc_match (" : ") != MATCH_YES)
1831 {
1832 gfc_error ("Expected %<:%> at %C");
1833 break;
1834 }
1835 if (ns_iter)
1836 gfc_current_ns = ns_iter;
1837 head = NULL__null;
1838 m = gfc_match_omp_variable_list ("", &c->lists[OMP_LIST_AFFINITY],
1839 false, NULL__null, &head, true);
1840 gfc_current_ns = ns_curr;
1841 if (m == MATCH_ERROR)
1842 break;
1843 if (ns_iter)
1844 {
1845 for (gfc_omp_namelist *n = *head; n; n = n->next)
1846 {
1847 n->u2.ns = ns_iter;
1848 ns_iter->refs++;
1849 }
1850 }
1851 continue;
1852 }
1853 if ((mask & OMP_CLAUSE_ALLOCATE)
1854 && gfc_match ("allocate ( ") == MATCH_YES)
1855 {
1856 gfc_expr *allocator = NULL__null;
1857 gfc_expr *align = NULL__null;
1858 old_loc = gfc_current_locus;
1859 if ((m = gfc_match ("allocator ( %e )", &allocator)) == MATCH_YES)
1860 gfc_match (" , align ( %e )", &align);
1861 else if ((m = gfc_match ("align ( %e )", &align)) == MATCH_YES)
1862 gfc_match (" , allocator ( %e )", &allocator);
1863
1864 if (m == MATCH_YES)
1865 {
1866 if (gfc_match (" : ") != MATCH_YES)
1867 {
1868 gfc_error ("Expected %<:%> at %C");
1869 goto error;
1870 }
1871 }
1872 else
1873 {
1874 m = gfc_match_expr (&allocator);
1875 if (m == MATCH_YES && gfc_match (" : ") != MATCH_YES)
1876 {
1877 /* If no ":" then there is no allocator, we backtrack
1878 and read the variable list. */
1879 gfc_free_expr (allocator);
1880 allocator = NULL__null;
1881 gfc_current_locus = old_loc;
1882 }
1883 }
1884 gfc_omp_namelist **head = NULL__null;
1885 m = gfc_match_omp_variable_list ("", &c->lists[OMP_LIST_ALLOCATE],
1886 true, NULL__null, &head);
1887
1888 if (m != MATCH_YES)
1889 {
1890 gfc_free_expr (allocator);
1891 gfc_free_expr (align);
1892 gfc_error ("Expected variable list at %C");
1893 goto error;
1894 }
1895
1896 for (gfc_omp_namelist *n = *head; n; n = n->next)
1897 {
1898 n->expr = (allocator) ? gfc_copy_expr (allocator) : NULL__null;
1899 n->u.align = (align) ? gfc_copy_expr (align) : NULL__null;
1900 }
1901 gfc_free_expr (allocator);
1902 gfc_free_expr (align);
1903 continue;
1904 }
1905 if ((mask & OMP_CLAUSE_AT)
1906 && (m = gfc_match_dupl_check (c->at == OMP_AT_UNSET, "at", true))
1907 != MATCH_NO)
1908 {
1909 if (m == MATCH_ERROR)
1910 goto error;
1911 if (gfc_match ("compilation )") == MATCH_YES)
1912 c->at = OMP_AT_COMPILATION;
1913 else if (gfc_match ("execution )") == MATCH_YES)
1914 c->at = OMP_AT_EXECUTION;
1915 else
1916 {
1917 gfc_error ("Expected COMPILATION or EXECUTION in AT clause "
1918 "at %C");
1919 goto error;
1920 }
1921 continue;
1922 }
1923 if ((mask & OMP_CLAUSE_ASYNC)
1924 && (m = gfc_match_dupl_check (!c->async, "async")) != MATCH_NO)
1925 {
1926 if (m == MATCH_ERROR)
1927 goto error;
1928 c->async = true;
1929 m = gfc_match (" ( %e )", &c->async_expr);
1930 if (m == MATCH_ERROR)
1931 {
1932 gfc_current_locus = old_loc;
1933 break;
1934 }
1935 else if (m == MATCH_NO)
1936 {
1937 c->async_expr
1938 = gfc_get_constant_expr (BT_INTEGER,
1939 gfc_default_integer_kind,
1940 &gfc_current_locus);
1941 mpz_set_si__gmpz_set_si (c->async_expr->value.integer, GOMP_ASYNC_NOVAL-1);
1942 needs_space = true;
1943 }
1944 continue;
1945 }
1946 if ((mask & OMP_CLAUSE_AUTO)
1947 && (m = gfc_match_dupl_check (!c->par_auto, "auto"))
1948 != MATCH_NO)
1949 {
1950 if (m == MATCH_ERROR)
1951 goto error;
1952 c->par_auto = true;
1953 needs_space = true;
1954 continue;
1955 }
1956 if ((mask & OMP_CLAUSE_ATTACH)
1957 && gfc_match ("attach ( ") == MATCH_YES
1958 && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
1959 OMP_MAP_ATTACH, false,
1960 allow_derived))
1961 continue;
1962 break;
1963 case 'b':
1964 if ((mask & OMP_CLAUSE_BIND)
1965 && (m = gfc_match_dupl_check (c->bind == OMP_BIND_UNSET, "bind",
1966 true)) != MATCH_NO)
1967 {
1968 if (m == MATCH_ERROR)
1969 goto error;
1970 if (gfc_match ("teams )") == MATCH_YES)
1971 c->bind = OMP_BIND_TEAMS;
1972 else if (gfc_match ("parallel )") == MATCH_YES)
1973 c->bind = OMP_BIND_PARALLEL;
1974 else if (gfc_match ("thread )") == MATCH_YES)
1975 c->bind = OMP_BIND_THREAD;
1976 else
1977 {
1978 gfc_error ("Expected TEAMS, PARALLEL or THREAD as binding in "
1979 "BIND at %C");
1980 break;
1981 }
1982 continue;
1983 }
1984 break;
1985 case 'c':
1986 if ((mask & OMP_CLAUSE_CAPTURE)
1987 && (m = gfc_match_dupl_check (!c->capture, "capture"))
1988 != MATCH_NO)
1989 {
1990 if (m == MATCH_ERROR)
1991 goto error;
1992 c->capture = true;
1993 needs_space = true;
1994 continue;
1995 }
1996 if (mask & OMP_CLAUSE_COLLAPSE)
1997 {
1998 gfc_expr *cexpr = NULL__null;
1999 if ((m = gfc_match_dupl_check (!c->collapse, "collapse", true,
2000 &cexpr)) != MATCH_NO)
2001 {
2002 int collapse;
2003 if (m == MATCH_ERROR)
2004 goto error;
2005 if (gfc_extract_int (cexpr, &collapse, -1))
2006 collapse = 1;
2007 else if (collapse <= 0)
2008 {
2009 gfc_error_now ("COLLAPSE clause argument not constant "
2010 "positive integer at %C");
2011 collapse = 1;
2012 }
2013 gfc_free_expr (cexpr);
2014 c->collapse = collapse;
2015 continue;
2016 }
2017 }
2018 if ((mask & OMP_CLAUSE_COMPARE)
2019 && (m = gfc_match_dupl_check (!c->compare, "compare"))
2020 != MATCH_NO)
2021 {
2022 if (m == MATCH_ERROR)
2023 goto error;
2024 c->compare = true;
2025 needs_space = true;
2026 continue;
2027 }
2028 if ((mask & OMP_CLAUSE_ASSUMPTIONS)
2029 && gfc_match ("contains ( ") == MATCH_YES)
2030 {
2031 if (gfc_omp_absent_contains_clause (&c->assume, false)
2032 != MATCH_YES)
2033 goto error;
2034 continue;
2035 }
2036 if ((mask & OMP_CLAUSE_COPY)
2037 && gfc_match ("copy ( ") == MATCH_YES
2038 && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
2039 OMP_MAP_TOFROM, true,
2040 allow_derived))
2041 continue;
2042 if (mask & OMP_CLAUSE_COPYIN)
2043 {
2044 if (openacc)
2045 {
2046 if (gfc_match ("copyin ( ") == MATCH_YES
2047 && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
2048 OMP_MAP_TO, true,
2049 allow_derived))
2050 continue;
2051 }
2052 else if (gfc_match_omp_variable_list ("copyin (",
2053 &c->lists[OMP_LIST_COPYIN],
2054 true) == MATCH_YES)
2055 continue;
2056 }
2057 if ((mask & OMP_CLAUSE_COPYOUT)
2058 && gfc_match ("copyout ( ") == MATCH_YES
2059 && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
2060 OMP_MAP_FROM, true, allow_derived))
2061 continue;
2062 if ((mask & OMP_CLAUSE_COPYPRIVATE)
2063 && gfc_match_omp_variable_list ("copyprivate (",
2064 &c->lists[OMP_LIST_COPYPRIVATE],
2065 true) == MATCH_YES)
2066 continue;
2067 if ((mask & OMP_CLAUSE_CREATE)
2068 && gfc_match ("create ( ") == MATCH_YES
2069 && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
2070 OMP_MAP_ALLOC, true, allow_derived))
2071 continue;
2072 break;
2073 case 'd':
2074 if ((mask & OMP_CLAUSE_DEFAULTMAP)
2075 && gfc_match ("defaultmap ( ") == MATCH_YES)
2076 {
2077 enum gfc_omp_defaultmap behavior;
2078 gfc_omp_defaultmap_category category
2079 = OMP_DEFAULTMAP_CAT_UNCATEGORIZED;
2080 if (gfc_match ("alloc ") == MATCH_YES)
2081 behavior = OMP_DEFAULTMAP_ALLOC;
2082 else if (gfc_match ("tofrom ") == MATCH_YES)
2083 behavior = OMP_DEFAULTMAP_TOFROM;
2084 else if (gfc_match ("to ") == MATCH_YES)
2085 behavior = OMP_DEFAULTMAP_TO;
2086 else if (gfc_match ("from ") == MATCH_YES)
2087 behavior = OMP_DEFAULTMAP_FROM;
2088 else if (gfc_match ("firstprivate ") == MATCH_YES)
2089 behavior = OMP_DEFAULTMAP_FIRSTPRIVATE;
2090 else if (gfc_match ("none ") == MATCH_YES)
2091 behavior = OMP_DEFAULTMAP_NONE;
2092 else if (gfc_match ("default ") == MATCH_YES)
2093 behavior = OMP_DEFAULTMAP_DEFAULT;
2094 else
2095 {
2096 gfc_error ("Expected ALLOC, TO, FROM, TOFROM, FIRSTPRIVATE, "
2097 "NONE or DEFAULT at %C");
2098 break;
2099 }
2100 if (')' == gfc_peek_ascii_char ())
2101 ;
2102 else if (gfc_match (": ") != MATCH_YES)
2103 break;
2104 else
2105 {
2106 if (gfc_match ("scalar ") == MATCH_YES)
2107 category = OMP_DEFAULTMAP_CAT_SCALAR;
2108 else if (gfc_match ("aggregate ") == MATCH_YES)
2109 category = OMP_DEFAULTMAP_CAT_AGGREGATE;
2110 else if (gfc_match ("allocatable ") == MATCH_YES)
2111 category = OMP_DEFAULTMAP_CAT_ALLOCATABLE;
2112 else if (gfc_match ("pointer ") == MATCH_YES)
2113 category = OMP_DEFAULTMAP_CAT_POINTER;
2114 else
2115 {
2116 gfc_error ("Expected SCALAR, AGGREGATE, ALLOCATABLE or "
2117 "POINTER at %C");
2118 break;
2119 }
2120 }
2121 for (int i = 0; i < OMP_DEFAULTMAP_CAT_NUM; ++i)
2122 {
2123 if (i != category
2124 && category != OMP_DEFAULTMAP_CAT_UNCATEGORIZED)
2125 continue;
2126 if (c->defaultmap[i] != OMP_DEFAULTMAP_UNSET)
2127 {
2128 const char *pcategory = NULL__null;
2129 switch (i)
2130 {
2131 case OMP_DEFAULTMAP_CAT_UNCATEGORIZED: break;
2132 case OMP_DEFAULTMAP_CAT_SCALAR: pcategory = "SCALAR"; break;
2133 case OMP_DEFAULTMAP_CAT_AGGREGATE:
2134 pcategory = "AGGREGATE";
2135 break;
2136 case OMP_DEFAULTMAP_CAT_ALLOCATABLE:
2137 pcategory = "ALLOCATABLE";
2138 break;
2139 case OMP_DEFAULTMAP_CAT_POINTER:
2140 pcategory = "POINTER";
2141 break;
2142 default: gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/fortran/openmp.cc"
, 2142, __FUNCTION__))
;
2143 }
2144 if (i == OMP_DEFAULTMAP_CAT_UNCATEGORIZED)
2145 gfc_error ("DEFAULTMAP at %C but prior DEFAULTMAP with "
2146 "unspecified category");
2147 else
2148 gfc_error ("DEFAULTMAP at %C but prior DEFAULTMAP for "
2149 "category %s", pcategory);
2150 goto error;
2151 }
2152 }
2153 c->defaultmap[category] = behavior;
2154 if (gfc_match (")") != MATCH_YES)
2155 break;
2156 continue;
2157 }
2158 if ((mask & OMP_CLAUSE_DEFAULT)
2159 && (m = gfc_match_dupl_check (c->default_sharing
2160 == OMP_DEFAULT_UNKNOWN, "default",
2161 true)) != MATCH_NO)
2162 {
2163 if (m == MATCH_ERROR)
2164 goto error;
2165 if (gfc_match ("none") == MATCH_YES)
2166 c->default_sharing = OMP_DEFAULT_NONE;
2167 else if (openacc)
2168 {
2169 if (gfc_match ("present") == MATCH_YES)
2170 c->default_sharing = OMP_DEFAULT_PRESENT;
2171 }
2172 else
2173 {
2174 if (gfc_match ("firstprivate") == MATCH_YES)
2175 c->default_sharing = OMP_DEFAULT_FIRSTPRIVATE;
2176 else if (gfc_match ("private") == MATCH_YES)
2177 c->default_sharing = OMP_DEFAULT_PRIVATE;
2178 else if (gfc_match ("shared") == MATCH_YES)
2179 c->default_sharing = OMP_DEFAULT_SHARED;
2180 }
2181 if (c->default_sharing == OMP_DEFAULT_UNKNOWN)
2182 {
2183 if (openacc)
2184 gfc_error ("Expected NONE or PRESENT in DEFAULT clause "
2185 "at %C");
2186 else
2187 gfc_error ("Expected NONE, FIRSTPRIVATE, PRIVATE or SHARED "
2188 "in DEFAULT clause at %C");
2189 goto error;
2190 }
2191 if (gfc_match (" )") != MATCH_YES)
2192 goto error;
2193 continue;
2194 }
2195 if ((mask & OMP_CLAUSE_DELETE)
2196 && gfc_match ("delete ( ") == MATCH_YES
2197 && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
2198 OMP_MAP_RELEASE, true,
2199 allow_derived))
2200 continue;
2201 /* DOACROSS: match 'doacross' and 'depend' with sink/source.
2202 DEPEND: match 'depend' but not sink/source. */
2203 m = MATCH_NO;
2204 if (((mask & OMP_CLAUSE_DOACROSS)
2205 && gfc_match ("doacross ( ") == MATCH_YES)
2206 || (((mask & OMP_CLAUSE_DEPEND) || (mask & OMP_CLAUSE_DOACROSS))
2207 && (m = gfc_match ("depend ( ")) == MATCH_YES))
2208 {
2209 bool has_omp_all_memory;
2210 bool is_depend = m == MATCH_YES;
2211 gfc_namespace *ns_iter = NULL__null, *ns_curr = gfc_current_ns;
2212 match m_it = MATCH_NO;
2213 if (is_depend)
2214 m_it = gfc_match_iterator (&ns_iter, false);
2215 if (m_it == MATCH_ERROR)
2216 break;
2217 if (m_it == MATCH_YES && gfc_match (" , ") != MATCH_YES)
2218 break;
2219 m = MATCH_YES;
2220 gfc_omp_depend_doacross_op depend_op = OMP_DEPEND_OUT;
2221 if (gfc_match ("inoutset") == MATCH_YES)
2222 depend_op = OMP_DEPEND_INOUTSET;
2223 else if (gfc_match ("inout") == MATCH_YES)
2224 depend_op = OMP_DEPEND_INOUT;
2225 else if (gfc_match ("in") == MATCH_YES)
2226 depend_op = OMP_DEPEND_IN;
2227 else if (gfc_match ("out") == MATCH_YES)
2228 depend_op = OMP_DEPEND_OUT;
2229 else if (gfc_match ("mutexinoutset") == MATCH_YES)
2230 depend_op = OMP_DEPEND_MUTEXINOUTSET;
2231 else if (gfc_match ("depobj") == MATCH_YES)
2232 depend_op = OMP_DEPEND_DEPOBJ;
2233 else if (gfc_match ("source") == MATCH_YES)
2234 {
2235 if (m_it == MATCH_YES)
2236 {
2237 gfc_error ("ITERATOR may not be combined with SOURCE "
2238 "at %C");
2239 goto error;
2240 }
2241 if (!(mask & OMP_CLAUSE_DOACROSS))
2242 {
2243 gfc_error ("SOURCE at %C not permitted as dependence-type"
2244 " for this directive");
2245 goto error;
2246 }
2247 if (c->doacross_source)
2248 {
2249 gfc_error ("Duplicated clause with SOURCE dependence-type"
2250 " at %C");
2251 goto error;
2252 }
2253 gfc_gobble_whitespace ();
2254 m = gfc_match (": ");
2255 if (m != MATCH_YES && !is_depend)
2256 {
2257 gfc_error ("Expected %<:%> at %C");
2258 goto error;
2259 }
2260 if (gfc_match (")") != MATCH_YES
2261 && !(m == MATCH_YES
2262 && gfc_match ("omp_cur_iteration )") == MATCH_YES))
2263 {
2264 gfc_error ("Expected %<)%> or %<omp_cur_iteration)%> "
2265 "at %C");
2266 goto error;
2267 }
2268 c->doacross_source = true;
2269 c->depend_source = is_depend;
2270 continue;
2271 }
2272 else if (gfc_match ("sink ") == MATCH_YES)
2273 {
2274 if (!(mask & OMP_CLAUSE_DOACROSS))
2275 {
2276 gfc_error ("SINK at %C not permitted as dependence-type "
2277 "for this directive");
2278 goto error;
2279 }
2280 if (gfc_match (": ") != MATCH_YES)
2281 {
2282 gfc_error ("Expected %<:%> at %C");
2283 goto error;
2284 }
2285 if (m_it == MATCH_YES)
2286 {
2287 gfc_error ("ITERATOR may not be combined with SINK "
2288 "at %C");
2289 goto error;
2290 }
2291 m = gfc_match_omp_doacross_sink (&c->lists[OMP_LIST_DEPEND],
2292 is_depend);
2293 if (m == MATCH_YES)
2294 continue;
2295 goto error;
2296 }
2297 else
2298 m = MATCH_NO;
2299 if (!(mask & OMP_CLAUSE_DEPEND))
2300 {
2301 gfc_error ("Expected dependence-type SINK or SOURCE at %C");
2302 goto error;
2303 }
2304 head = NULL__null;
2305 if (ns_iter)
2306 gfc_current_ns = ns_iter;
2307 if (m == MATCH_YES)
2308 m = gfc_match_omp_variable_list (" : ",
2309 &c->lists[OMP_LIST_DEPEND],
2310 false, NULL__null, &head, true,
2311 false, &has_omp_all_memory);
2312 if (m != MATCH_YES)
2313 goto error;
2314 gfc_current_ns = ns_curr;
2315 if (has_omp_all_memory && depend_op != OMP_DEPEND_INOUT
2316 && depend_op != OMP_DEPEND_OUT)
2317 {
2318 gfc_error ("%<omp_all_memory%> used with DEPEND kind "
2319 "other than OUT or INOUT at %C");
2320 goto error;
2321 }
2322 gfc_omp_namelist *n;
2323 for (n = *head; n; n = n->next)
2324 {
2325 n->u.depend_doacross_op = depend_op;
2326 n->u2.ns = ns_iter;
2327 if (ns_iter)
2328 ns_iter->refs++;
2329 }
2330 continue;
2331 }
2332 if ((mask & OMP_CLAUSE_DETACH)
2333 && !openacc
2334 && !c->detach
2335 && gfc_match_omp_detach (&c->detach) == MATCH_YES)
2336 continue;
2337 if ((mask & OMP_CLAUSE_DETACH)
2338 && openacc
2339 && gfc_match ("detach ( ") == MATCH_YES
2340 && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
2341 OMP_MAP_DETACH, false,
2342 allow_derived))
2343 continue;
2344 if ((mask & OMP_CLAUSE_DEVICE)
2345 && !openacc
2346 && ((m = gfc_match_dupl_check (!c->device, "device", true))
2347 != MATCH_NO))
2348 {
2349 if (m == MATCH_ERROR)
2350 goto error;
2351 c->ancestor = false;
2352 if (gfc_match ("device_num : ") == MATCH_YES)
2353 {
2354 if (gfc_match ("%e )", &c->device) != MATCH_YES)
2355 {
2356 gfc_error ("Expected integer expression at %C");
2357 break;
2358 }
2359 }
2360 else if (gfc_match ("ancestor : ") == MATCH_YES)
2361 {
2362 bool has_requires = false;
2363 c->ancestor = true;
2364 for (gfc_namespace *ns = gfc_current_ns; ns; ns = ns->parent)
2365 if (ns->omp_requires & OMP_REQ_REVERSE_OFFLOAD)
2366 {
2367 has_requires = true;
2368 break;
2369 }
2370 if (!has_requires)
2371 {
2372 gfc_error ("%<ancestor%> device modifier not "
2373 "preceded by %<requires%> directive "
2374 "with %<reverse_offload%> clause at %C");
2375 break;
2376 }
2377 locus old_loc2 = gfc_current_locus;
2378 if (gfc_match ("%e )", &c->device) == MATCH_YES)
2379 {
2380 int device = 0;
2381 if (!gfc_extract_int (c->device, &device) && device != 1)
2382 {
2383 gfc_current_locus = old_loc2;
2384 gfc_error ("the %<device%> clause expression must "
2385 "evaluate to %<1%> at %C");
2386 break;
2387 }
2388 }
2389 else
2390 {
2391 gfc_error ("Expected integer expression at %C");
2392 break;
2393 }
2394 }
2395 else if (gfc_match ("%e )", &c->device) != MATCH_YES)
2396 {
2397 gfc_error ("Expected integer expression or a single device-"
2398 "modifier %<device_num%> or %<ancestor%> at %C");
2399 break;
2400 }
2401 continue;
2402 }
2403 if ((mask & OMP_CLAUSE_DEVICE)
2404 && openacc
2405 && gfc_match ("device ( ") == MATCH_YES
2406 && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
2407 OMP_MAP_FORCE_TO, true,
2408 allow_derived))
2409 continue;
2410 if ((mask & OMP_CLAUSE_DEVICEPTR)
2411 && gfc_match ("deviceptr ( ") == MATCH_YES
2412 && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
2413 OMP_MAP_FORCE_DEVICEPTR, false,
2414 allow_derived))
2415 continue;
2416 if ((mask & OMP_CLAUSE_DEVICE_TYPE)
2417 && gfc_match ("device_type ( ") == MATCH_YES)
2418 {
2419 if (gfc_match ("host") == MATCH_YES)
2420 c->device_type = OMP_DEVICE_TYPE_HOST;
2421 else if (gfc_match ("nohost") == MATCH_YES)
2422 c->device_type = OMP_DEVICE_TYPE_NOHOST;
2423 else if (gfc_match ("any") == MATCH_YES)
2424 c->device_type = OMP_DEVICE_TYPE_ANY;
2425 else
2426 {
2427 gfc_error ("Expected HOST, NOHOST or ANY at %C");
2428 break;
2429 }
2430 if (gfc_match (" )") != MATCH_YES)
2431 break;
2432 continue;
2433 }
2434 if ((mask & OMP_CLAUSE_DEVICE_RESIDENT)
2435 && gfc_match_omp_variable_list
2436 ("device_resident (",
2437 &c->lists[OMP_LIST_DEVICE_RESIDENT], true) == MATCH_YES)
2438 continue;
2439 if ((mask & OMP_CLAUSE_DIST_SCHEDULE)
2440 && c->dist_sched_kind == OMP_SCHED_NONE
2441 && gfc_match ("dist_schedule ( static") == MATCH_YES)
2442 {
2443 m = MATCH_NO;
Value stored to 'm' is never read
2444 c->dist_sched_kind = OMP_SCHED_STATIC;
2445 m = gfc_match (" , %e )", &c->dist_chunk_size);
2446 if (m != MATCH_YES)
2447 m = gfc_match_char (')');
2448 if (m != MATCH_YES)
2449 {
2450 c->dist_sched_kind = OMP_SCHED_NONE;
2451 gfc_current_locus = old_loc;
2452 }
2453 else
2454 continue;
2455 }
2456 break;
2457 case 'e':
2458 if ((mask & OMP_CLAUSE_ENTER))
2459 {
2460 m = gfc_match_omp_to_link ("enter (", &c->lists[OMP_LIST_ENTER]);
2461 if (m == MATCH_ERROR)
2462 goto error;
2463 if (m == MATCH_YES)
2464 continue;
2465 }
2466 break;
2467 case 'f':
2468 if ((mask & OMP_CLAUSE_FAIL)
2469 && (m = gfc_match_dupl_check (c->fail == OMP_MEMORDER_UNSET,
2470 "fail", true)) != MATCH_NO)
2471 {
2472 if (m == MATCH_ERROR)
2473 goto error;
2474 if (gfc_match ("seq_cst") == MATCH_YES)
2475 c->fail = OMP_MEMORDER_SEQ_CST;
2476 else if (gfc_match ("acquire") == MATCH_YES)
2477 c->fail = OMP_MEMORDER_ACQUIRE;
2478 else if (gfc_match ("relaxed") == MATCH_YES)
2479 c->fail = OMP_MEMORDER_RELAXED;
2480 else
2481 {
2482 gfc_error ("Expected SEQ_CST, ACQUIRE or RELAXED at %C");
2483 break;
2484 }
2485 if (gfc_match (" )") != MATCH_YES)
2486 goto error;
2487 continue;
2488 }
2489 if ((mask & OMP_CLAUSE_FILTER)
2490 && (m = gfc_match_dupl_check (!c->filter, "filter", true,
2491 &c->filter)) != MATCH_NO)
2492 {
2493 if (m == MATCH_ERROR)
2494 goto error;
2495 continue;
2496 }
2497 if ((mask & OMP_CLAUSE_FINAL)
2498 && (m = gfc_match_dupl_check (!c->final_expr, "final", true,
2499 &c->final_expr)) != MATCH_NO)
2500 {
2501 if (m == MATCH_ERROR)
2502 goto error;
2503 continue;
2504 }
2505 if ((mask & OMP_CLAUSE_FINALIZE)
2506 && (m = gfc_match_dupl_check (!c->finalize, "finalize"))
2507 != MATCH_NO)
2508 {
2509 if (m == MATCH_ERROR)
2510 goto error;
2511 c->finalize = true;
2512 needs_space = true;
2513 continue;
2514 }
2515 if ((mask & OMP_CLAUSE_FIRSTPRIVATE)
2516 && gfc_match_omp_variable_list ("firstprivate (",
2517 &c->lists[OMP_LIST_FIRSTPRIVATE],
2518 true) == MATCH_YES)
2519 continue;
2520 if ((mask & OMP_CLAUSE_FROM)
2521 && (gfc_match_omp_variable_list ("from (",
2522 &c->lists[OMP_LIST_FROM], false,
2523 NULL__null, &head, true, true)
2524 == MATCH_YES))
2525 continue;
2526 break;
2527 case 'g':
2528 if ((mask & OMP_CLAUSE_GANG)
2529 && (m = gfc_match_dupl_check (!c->gang, "gang")) != MATCH_NO)
2530 {
2531 if (m == MATCH_ERROR)
2532 goto error;
2533 c->gang = true;
2534 m = match_oacc_clause_gwv (c, GOMP_DIM_GANG0);
2535 if (m == MATCH_ERROR)
2536 {
2537 gfc_current_locus = old_loc;
2538 break;
2539 }
2540 else if (m == MATCH_NO)
2541 needs_space = true;
2542 continue;
2543 }
2544 if ((mask & OMP_CLAUSE_GRAINSIZE)
2545 && (m = gfc_match_dupl_check (!c->grainsize, "grainsize", true))
2546 != MATCH_NO)
2547 {
2548 if (m == MATCH_ERROR)
2549 goto error;
2550 if (gfc_match ("strict : ") == MATCH_YES)
2551 c->grainsize_strict = true;
2552 if (gfc_match (" %e )", &c->grainsize) != MATCH_YES)
2553 goto error;
2554 continue;
2555 }
2556 break;
2557 case 'h':
2558 if ((mask & OMP_CLAUSE_HAS_DEVICE_ADDR)
2559 && gfc_match_omp_variable_list
2560 ("has_device_addr (", &c->lists[OMP_LIST_HAS_DEVICE_ADDR],
2561 false, NULL__null, NULL__null, true) == MATCH_YES)
2562 continue;
2563 if ((mask & OMP_CLAUSE_HINT)
2564 && (m = gfc_match_dupl_check (!c->hint, "hint", true, &c->hint))
2565 != MATCH_NO)
2566 {
2567 if (m == MATCH_ERROR)
2568 goto error;
2569 continue;
2570 }
2571 if ((mask & OMP_CLAUSE_ASSUMPTIONS)
2572 && gfc_match ("holds ( ") == MATCH_YES)
2573 {
2574 gfc_expr *e;
2575 if (gfc_match ("%e )", &e) != MATCH_YES)
2576 goto error;
2577 if (c->assume == NULL__null)
2578 c->assume = gfc_get_omp_assumptions ()((gfc_omp_assumptions *) xcalloc (1, sizeof (gfc_omp_assumptions
)))
;
2579 gfc_expr_list *el = XCNEW (gfc_expr_list)((gfc_expr_list *) xcalloc (1, sizeof (gfc_expr_list)));
2580 el->expr = e;
2581 el->next = c->assume->holds;
2582 c->assume->holds = el;
2583 continue;
2584 }
2585 if ((mask & OMP_CLAUSE_HOST_SELF)
2586 && gfc_match ("host ( ") == MATCH_YES
2587 && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
2588 OMP_MAP_FORCE_FROM, true,
2589 allow_derived))
2590 continue;
2591 break;
2592 case 'i':
2593 if ((mask & OMP_CLAUSE_IF_PRESENT)
2594 && (m = gfc_match_dupl_check (!c->if_present, "if_present"))
2595 != MATCH_NO)
2596 {
2597 if (m == MATCH_ERROR)
2598 goto error;
2599 c->if_present = true;
2600 needs_space = true;
2601 continue;
2602 }
2603 if ((mask & OMP_CLAUSE_IF)
2604 && (m = gfc_match_dupl_check (!c->if_expr, "if", true))
2605 != MATCH_NO)
2606 {
2607 if (m == MATCH_ERROR)
2608 goto error;
2609 if (!openacc)
2610 {
2611 /* This should match the enum gfc_omp_if_kind order. */
2612 static const char *ifs[OMP_IF_LAST] = {
2613 "cancel : %e )",
2614 "parallel : %e )",
2615 "simd : %e )",
2616 "task : %e )",
2617 "taskloop : %e )",
2618 "target : %e )",
2619 "target data : %e )",
2620 "target update : %e )",
2621 "target enter data : %e )",
2622 "target exit data : %e )" };
2623 int i;
2624 for (i = 0; i < OMP_IF_LAST; i++)
2625 if (c->if_exprs[i] == NULL__null
2626 && gfc_match (ifs[i], &c->if_exprs[i]) == MATCH_YES)
2627 break;
2628 if (i < OMP_IF_LAST)
2629 continue;
2630 }
2631 if (gfc_match (" %e )", &c->if_expr) == MATCH_YES)
2632 continue;
2633 goto error;
2634 }
2635 if ((mask & OMP_CLAUSE_IN_REDUCTION)
2636 && gfc_match_omp_clause_reduction (pc, c, openacc, allow_derived,
2637 openmp_target) == MATCH_YES)
2638 continue;
2639 if ((mask & OMP_CLAUSE_INBRANCH)
2640 && (m = gfc_match_dupl_check (!c->inbranch && !c->notinbranch,
2641 "inbranch")) != MATCH_NO)
2642 {
2643 if (m == MATCH_ERROR)
2644 goto error;
2645 c->inbranch = needs_space = true;
2646 continue;
2647 }
2648 if ((mask & OMP_CLAUSE_INDEPENDENT)
2649 && (m = gfc_match_dupl_check (!c->independent, "independent"))
2650 != MATCH_NO)
2651 {
2652 if (m == MATCH_ERROR)
2653 goto error;
2654 c->independent = true;
2655 needs_space = true;
2656 continue;
2657 }
2658 if ((mask & OMP_CLAUSE_IS_DEVICE_PTR)
2659 && gfc_match_omp_variable_list
2660 ("is_device_ptr (",
2661 &c->lists[OMP_LIST_IS_DEVICE_PTR], false) == MATCH_YES)
2662 continue;
2663 break;
2664 case 'l':
2665 if ((mask & OMP_CLAUSE_LASTPRIVATE)
2666 && gfc_match ("lastprivate ( ") == MATCH_YES)
2667 {
2668 bool conditional = gfc_match ("conditional : ") == MATCH_YES;
2669 head = NULL__null;
2670 if (gfc_match_omp_variable_list ("",
2671 &c->lists[OMP_LIST_LASTPRIVATE],
2672 false, NULL__null, &head) == MATCH_YES)
2673 {
2674 gfc_omp_namelist *n;
2675 for (n = *head; n; n = n->next)
2676 n->u.lastprivate_conditional = conditional;
2677 continue;
2678 }
2679 gfc_current_locus = old_loc;
2680 break;
2681 }
2682 end_colon = false;
2683 head = NULL__null;
2684 if ((mask & OMP_CLAUSE_LINEAR)
2685 && gfc_match ("linear (") == MATCH_YES)
2686 {
2687 bool old_linear_modifier = false;
2688 gfc_omp_linear_op linear_op = OMP_LINEAR_DEFAULT;
2689 gfc_expr *step = NULL__null;
2690
2691 if (gfc_match_omp_variable_list (" ref (",
2692 &c->lists[OMP_LIST_LINEAR],
2693 false, NULL__null, &head)
2694 == MATCH_YES)
2695 {
2696 linear_op = OMP_LINEAR_REF;
2697 old_linear_modifier = true;
2698 }
2699 else if (gfc_match_omp_variable_list (" val (",
2700 &c->lists[OMP_LIST_LINEAR],
2701 false, NULL__null, &head)
2702 == MATCH_YES)
2703 {
2704 linear_op = OMP_LINEAR_VAL;
2705 old_linear_modifier = true;
2706 }
2707 else if (gfc_match_omp_variable_list (" uval (",
2708 &c->lists[OMP_LIST_LINEAR],
2709 false, NULL__null, &head)
2710 == MATCH_YES)
2711 {
2712 linear_op = OMP_LINEAR_UVAL;
2713 old_linear_modifier = true;
2714 }
2715 else if (gfc_match_omp_variable_list ("",
2716 &c->lists[OMP_LIST_LINEAR],
2717 false, &end_colon, &head)
2718 == MATCH_YES)
2719 linear_op = OMP_LINEAR_DEFAULT;
2720 else
2721 {
2722 gfc_current_locus = old_loc;
2723 break;
2724 }
2725 if (linear_op != OMP_LINEAR_DEFAULT)
2726 {
2727 if (gfc_match (" :") == MATCH_YES)
2728 end_colon = true;
2729 else if (gfc_match (" )") != MATCH_YES)
2730 {
2731 gfc_free_omp_namelist (*head, false, false);
2732 gfc_current_locus = old_loc;
2733 *head = NULL__null;
2734 break;
2735 }
2736 }
2737 gfc_gobble_whitespace ();
2738 if (old_linear_modifier && end_colon)
2739 {
2740 if (gfc_match (" %e )", &step) != MATCH_YES)
2741 {
2742 gfc_free_omp_namelist (*head, false, false);
2743 gfc_current_locus = old_loc;
2744 *head = NULL__null;
2745 goto error;
2746 }
2747 }
2748 else if (end_colon)
2749 {
2750 bool has_error = false;
2751 bool has_modifiers = false;
2752 bool has_step = false;
2753 bool duplicate_step = false;
2754 bool duplicate_mod = false;
2755 while (true)
2756 {
2757 old_loc = gfc_current_locus;
2758 bool close_paren = gfc_match ("val )") == MATCH_YES;
2759 if (close_paren || gfc_match ("val , ") == MATCH_YES)
2760 {
2761 if (linear_op != OMP_LINEAR_DEFAULT)
2762 {
2763 duplicate_mod = true;
2764 break;
2765 }
2766 linear_op = OMP_LINEAR_VAL;
2767 has_modifiers = true;
2768 if (close_paren)
2769 break;
2770 continue;
2771 }
2772 close_paren = gfc_match ("uval )") == MATCH_YES;
2773 if (close_paren || gfc_match ("uval , ") == MATCH_YES)
2774 {
2775 if (linear_op != OMP_LINEAR_DEFAULT)
2776 {
2777 duplicate_mod = true;
2778 break;
2779 }
2780 linear_op = OMP_LINEAR_UVAL;
2781 has_modifiers = true;
2782 if (close_paren)
2783 break;
2784 continue;
2785 }
2786 close_paren = gfc_match ("ref )") == MATCH_YES;
2787 if (close_paren || gfc_match ("ref , ") == MATCH_YES)
2788 {
2789 if (linear_op != OMP_LINEAR_DEFAULT)
2790 {
2791 duplicate_mod = true;
2792 break;
2793 }
2794 linear_op = OMP_LINEAR_REF;
2795 has_modifiers = true;
2796 if (close_paren)
2797 break;
2798 continue;
2799 }
2800 close_paren = (gfc_match ("step ( %e ) )", &step)
2801 == MATCH_YES);
2802 if (close_paren
2803 || gfc_match ("step ( %e ) , ", &step) == MATCH_YES)
2804 {
2805 if (has_step)
2806 {
2807 duplicate_step = true;
2808 break;
2809 }
2810 has_modifiers = has_step = true;
2811 if (close_paren)
2812 break;
2813 continue;
2814 }
2815 if (!has_modifiers
2816 && gfc_match ("%e )", &step) == MATCH_YES)
2817 {
2818 if ((step->expr_type == EXPR_FUNCTION
2819 || step->expr_type == EXPR_VARIABLE)
2820 && strcmp (step->symtree->name, "step") == 0)
2821 {
2822 gfc_current_locus = old_loc;
2823 gfc_match ("step (");
2824 has_error = true;
2825 }
2826 break;
2827 }
2828 has_error = true;
2829 break;
2830 }
2831 if (duplicate_mod || duplicate_step)
2832 {
2833 gfc_error ("Multiple %qs modifiers specified at %C",
2834 duplicate_mod ? "linear" : "step");
2835 has_error = true;
2836 }
2837 if (has_error)
2838 {
2839 gfc_free_omp_namelist (*head, false, false);
2840 *head = NULL__null;
2841 goto error;
2842 }
2843 }
2844 if (step == NULL__null)
2845 {
2846 step = gfc_get_constant_expr (BT_INTEGER,
2847 gfc_default_integer_kind,
2848 &old_loc);
2849 mpz_set_si__gmpz_set_si (step->value.integer, 1);
2850 }
2851 (*head)->expr = step;
2852 if (linear_op != OMP_LINEAR_DEFAULT || old_linear_modifier)
2853 for (gfc_omp_namelist *n = *head; n; n = n->next)
2854 {
2855 n->u.linear.op = linear_op;
2856 n->u.linear.old_modifier = old_linear_modifier;
2857 }
2858 continue;
2859 }
2860 if ((mask & OMP_CLAUSE_LINK)
2861 && openacc
2862 && (gfc_match_oacc_clause_link ("link (",
2863 &c->lists[OMP_LIST_LINK])
2864 == MATCH_YES))
2865 continue;
2866 else if ((mask & OMP_CLAUSE_LINK)
2867 && !openacc
2868 && (gfc_match_omp_to_link ("link (",
2869 &c->lists[OMP_LIST_LINK])
2870 == MATCH_YES))
2871 continue;
2872 break;
2873 case 'm':
2874 if ((mask & OMP_CLAUSE_MAP)
2875 && gfc_match ("map ( ") == MATCH_YES)
2876 {
2877 locus old_loc2 = gfc_current_locus;
2878 int always_modifier = 0;
2879 int close_modifier = 0;
2880 locus second_always_locus = old_loc2;
2881 locus second_close_locus = old_loc2;
2882
2883 for (;;)
2884 {
2885 locus current_locus = gfc_current_locus;
2886 if (gfc_match ("always ") == MATCH_YES)
2887 {
2888 if (always_modifier++ == 1)
2889 second_always_locus = current_locus;
2890 }
2891 else if (gfc_match ("close ") == MATCH_YES)
2892 {
2893 if (close_modifier++ == 1)
2894 second_close_locus = current_locus;
2895 }
2896 else
2897 break;
2898 gfc_match (", ");
2899 }
2900
2901 gfc_omp_map_op map_op = OMP_MAP_TOFROM;
2902 if (gfc_match ("alloc : ") == MATCH_YES)
2903 map_op = OMP_MAP_ALLOC;
2904 else if (gfc_match ("tofrom : ") == MATCH_YES)
2905 map_op = always_modifier ? OMP_MAP_ALWAYS_TOFROM : OMP_MAP_TOFROM;
2906 else if (gfc_match ("to : ") == MATCH_YES)
2907 map_op = always_modifier ? OMP_MAP_ALWAYS_TO : OMP_MAP_TO;
2908 else if (gfc_match ("from : ") == MATCH_YES)
2909 map_op = always_modifier ? OMP_MAP_ALWAYS_FROM : OMP_MAP_FROM;
2910 else if (gfc_match ("release : ") == MATCH_YES)
2911 map_op = OMP_MAP_RELEASE;
2912 else if (gfc_match ("delete : ") == MATCH_YES)
2913 map_op = OMP_MAP_DELETE;
2914 else
2915 {
2916 gfc_current_locus = old_loc2;
2917 always_modifier = 0;
2918 close_modifier = 0;
2919 }
2920
2921 if (always_modifier > 1)
2922 {
2923 gfc_error ("too many %<always%> modifiers at %L",
2924 &second_always_locus);
2925 break;
2926 }
2927 if (close_modifier > 1)
2928 {
2929 gfc_error ("too many %<close%> modifiers at %L",
2930 &second_close_locus);
2931 break;
2932 }
2933
2934 head = NULL__null;
2935 if (gfc_match_omp_variable_list ("", &c->lists[OMP_LIST_MAP],
2936 false, NULL__null, &head,
2937 true, true) == MATCH_YES)
2938 {
2939 gfc_omp_namelist *n;
2940 for (n = *head; n; n = n->next)
2941 n->u.map_op = map_op;
2942 continue;
2943 }
2944 gfc_current_locus = old_loc;
2945 break;
2946 }
2947 if ((mask & OMP_CLAUSE_MERGEABLE)
2948 && (m = gfc_match_dupl_check (!c->mergeable, "mergeable"))
2949 != MATCH_NO)
2950 {
2951 if (m == MATCH_ERROR)
2952 goto error;
2953 c->mergeable = needs_space = true;
2954 continue;
2955 }
2956 if ((mask & OMP_CLAUSE_MESSAGE)
2957 && (m = gfc_match_dupl_check (!c->message, "message", true,
2958 &c->message)) != MATCH_NO)
2959 {
2960 if (m == MATCH_ERROR)
2961 goto error;
2962 continue;
2963 }
2964 break;
2965 case 'n':
2966 if ((mask & OMP_CLAUSE_NO_CREATE)
2967 && gfc_match ("no_create ( ") == MATCH_YES
2968 && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
2969 OMP_MAP_IF_PRESENT, true,
2970 allow_derived))
2971 continue;
2972 if ((mask & OMP_CLAUSE_ASSUMPTIONS)
2973 && (m = gfc_match_dupl_check (!c->assume
2974 || !c->assume->no_openmp_routines,
2975 "no_openmp_routines")) == MATCH_YES)
2976 {
2977 if (m == MATCH_ERROR)
2978 goto error;
2979 if (c->assume == NULL__null)
2980 c->assume = gfc_get_omp_assumptions ()((gfc_omp_assumptions *) xcalloc (1, sizeof (gfc_omp_assumptions
)))
;
2981 c->assume->no_openmp_routines = needs_space = true;
2982 continue;
2983 }
2984 if ((mask & OMP_CLAUSE_ASSUMPTIONS)
2985 && (m = gfc_match_dupl_check (!c->assume || !c->assume->no_openmp,
2986 "no_openmp")) == MATCH_YES)
2987 {
2988 if (m == MATCH_ERROR)
2989 goto error;
2990 if (c->assume == NULL__null)
2991 c->assume = gfc_get_omp_assumptions ()((gfc_omp_assumptions *) xcalloc (1, sizeof (gfc_omp_assumptions
)))
;
2992 c->assume->no_openmp = needs_space = true;
2993 continue;
2994 }
2995 if ((mask & OMP_CLAUSE_ASSUMPTIONS)
2996 && (m = gfc_match_dupl_check (!c->assume
2997 || !c->assume->no_parallelism,
2998 "no_parallelism")) == MATCH_YES)
2999 {
3000 if (m == MATCH_ERROR)
3001 goto error;
3002 if (c->assume == NULL__null)
3003 c->assume = gfc_get_omp_assumptions ()((gfc_omp_assumptions *) xcalloc (1, sizeof (gfc_omp_assumptions
)))
;
3004 c->assume->no_parallelism = needs_space = true;
3005 continue;
3006 }
3007 if ((mask & OMP_CLAUSE_NOGROUP)
3008 && (m = gfc_match_dupl_check (!c->nogroup, "nogroup"))
3009 != MATCH_NO)
3010 {
3011 if (m == MATCH_ERROR)
3012 goto error;
3013 c->nogroup = needs_space = true;
3014 continue;
3015 }
3016 if ((mask & OMP_CLAUSE_NOHOST)
3017 && (m = gfc_match_dupl_check (!c->nohost, "nohost")) != MATCH_NO)
3018 {
3019 if (m == MATCH_ERROR)
3020 goto error;
3021 c->nohost = needs_space = true;
3022 continue;
3023 }
3024 if ((mask & OMP_CLAUSE_NOTEMPORAL)
3025 && gfc_match_omp_variable_list ("nontemporal (",
3026 &c->lists[OMP_LIST_NONTEMPORAL],
3027 true) == MATCH_YES)
3028 continue;
3029 if ((mask & OMP_CLAUSE_NOTINBRANCH)
3030 && (m = gfc_match_dupl_check (!c->notinbranch && !c->inbranch,
3031 "notinbranch")) != MATCH_NO)
3032 {
3033 if (m == MATCH_ERROR)
3034 goto error;
3035 c->notinbranch = needs_space = true;
3036 continue;
3037 }
3038 if ((mask & OMP_CLAUSE_NOWAIT)
3039 && (m = gfc_match_dupl_check (!c->nowait, "nowait")) != MATCH_NO)
3040 {
3041 if (m == MATCH_ERROR)
3042 goto error;
3043 c->nowait = needs_space = true;
3044 continue;
3045 }
3046 if ((mask & OMP_CLAUSE_NUM_GANGS)
3047 && (m = gfc_match_dupl_check (!c->num_gangs_expr, "num_gangs",
3048 true)) != MATCH_NO)
3049 {
3050 if (m == MATCH_ERROR)
3051 goto error;
3052 if (gfc_match (" %e )", &c->num_gangs_expr) != MATCH_YES)
3053 goto error;
3054 continue;
3055 }
3056 if ((mask & OMP_CLAUSE_NUM_TASKS)
3057 && (m = gfc_match_dupl_check (!c->num_tasks, "num_tasks", true))
3058 != MATCH_NO)
3059 {
3060 if (m == MATCH_ERROR)
3061 goto error;
3062 if (gfc_match ("strict : ") == MATCH_YES)
3063 c->num_tasks_strict = true;
3064 if (gfc_match (" %e )", &c->num_tasks) != MATCH_YES)
3065 goto error;
3066 continue;
3067 }
3068 if ((mask & OMP_CLAUSE_NUM_TEAMS)
3069 && (m = gfc_match_dupl_check (!c->num_teams_upper, "num_teams",
3070 true)) != MATCH_NO)
3071 {
3072 if (m == MATCH_ERROR)
3073 goto error;
3074 if (gfc_match ("%e ", &c->num_teams_upper) != MATCH_YES)
3075 goto error;
3076 if (gfc_peek_ascii_char () == ':')
3077 {
3078 c->num_teams_lower = c->num_teams_upper;
3079 c->num_teams_upper = NULL__null;
3080 if (gfc_match (": %e ", &c->num_teams_upper) != MATCH_YES)
3081 goto error;
3082 }
3083 if (gfc_match (") ") != MATCH_YES)
3084 goto error;
3085 continue;
3086 }
3087 if ((mask & OMP_CLAUSE_NUM_THREADS)
3088 && (m = gfc_match_dupl_check (!c->num_threads, "num_threads", true,
3089 &c->num_threads)) != MATCH_NO)
3090 {
3091 if (m == MATCH_ERROR)
3092 goto error;
3093 continue;
3094 }
3095 if ((mask & OMP_CLAUSE_NUM_WORKERS)
3096 && (m = gfc_match_dupl_check (!c->num_workers_expr, "num_workers",
3097 true, &c->num_workers_expr))
3098 != MATCH_NO)
3099 {
3100 if (m == MATCH_ERROR)
3101 goto error;
3102 continue;
3103 }
3104 break;
3105 case 'o':
3106 if ((mask & OMP_CLAUSE_ORDER)
3107 && (m = gfc_match_dupl_check (!c->order_concurrent, "order ("))
3108 != MATCH_NO)
3109 {
3110 if (m == MATCH_ERROR)
3111 goto error;
3112 if (gfc_match (" reproducible : concurrent )") == MATCH_YES)
3113 c->order_reproducible = true;
3114 else if (gfc_match (" concurrent )") == MATCH_YES)
3115 ;
3116 else if (gfc_match (" unconstrained : concurrent )") == MATCH_YES)
3117 c->order_unconstrained = true;
3118 else
3119 {
3120 gfc_error ("Expected ORDER(CONCURRENT) at %C "
3121 "with optional %<reproducible%> or "
3122 "%<unconstrained%> modifier");
3123 goto error;
3124 }
3125 c->order_concurrent = true;
3126 continue;
3127 }
3128 if ((mask & OMP_CLAUSE_ORDERED)
3129 && (m = gfc_match_dupl_check (!c->ordered, "ordered"))
3130 != MATCH_NO)
3131 {
3132 if (m == MATCH_ERROR)
3133 goto error;
3134 gfc_expr *cexpr = NULL__null;
3135 m = gfc_match (" ( %e )", &cexpr);
3136
3137 c->ordered = true;
3138 if (m == MATCH_YES)
3139 {
3140 int ordered = 0;
3141 if (gfc_extract_int (cexpr, &ordered, -1))
3142 ordered = 0;
3143 else if (ordered <= 0)
3144 {
3145 gfc_error_now ("ORDERED clause argument not"
3146 " constant positive integer at %C");
3147 ordered = 0;
3148 }
3149 c->orderedc = ordered;
3150 gfc_free_expr (cexpr);
3151 continue;
3152 }
3153
3154 needs_space = true;
3155 continue;
3156 }
3157 break;
3158 case 'p':
3159 if ((mask & OMP_CLAUSE_COPY)
3160 && gfc_match ("pcopy ( ") == MATCH_YES
3161 && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
3162 OMP_MAP_TOFROM, true, allow_derived))
3163 continue;
3164 if ((mask & OMP_CLAUSE_COPYIN)
3165 && gfc_match ("pcopyin ( ") == MATCH_YES
3166 && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
3167 OMP_MAP_TO, true, allow_derived))
3168 continue;
3169 if ((mask & OMP_CLAUSE_COPYOUT)
3170 && gfc_match ("pcopyout ( ") == MATCH_YES
3171 && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
3172 OMP_MAP_FROM, true, allow_derived))
3173 continue;
3174 if ((mask & OMP_CLAUSE_CREATE)
3175 && gfc_match ("pcreate ( ") == MATCH_YES
3176 && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
3177 OMP_MAP_ALLOC, true, allow_derived))
3178 continue;
3179 if ((mask & OMP_CLAUSE_PRESENT)
3180 && gfc_match ("present ( ") == MATCH_YES
3181 && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
3182 OMP_MAP_FORCE_PRESENT, false,
3183 allow_derived))
3184 continue;
3185 if ((mask & OMP_CLAUSE_COPY)
3186 && gfc_match ("present_or_copy ( ") == MATCH_YES
3187 && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
3188 OMP_MAP_TOFROM, true,
3189 allow_derived))
3190 continue;
3191 if ((mask & OMP_CLAUSE_COPYIN)
3192 && gfc_match ("present_or_copyin ( ") == MATCH_YES
3193 && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
3194 OMP_MAP_TO, true, allow_derived))
3195 continue;
3196 if ((mask & OMP_CLAUSE_COPYOUT)
3197 && gfc_match ("present_or_copyout ( ") == MATCH_YES
3198 && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
3199 OMP_MAP_FROM, true, allow_derived))
3200 continue;
3201 if ((mask & OMP_CLAUSE_CREATE)
3202 && gfc_match ("present_or_create ( ") == MATCH_YES
3203 && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
3204 OMP_MAP_ALLOC, true, allow_derived))
3205 continue;
3206 if ((mask & OMP_CLAUSE_PRIORITY)
3207 && (m = gfc_match_dupl_check (!c->priority, "priority", true,
3208 &c->priority)) != MATCH_NO)
3209 {
3210 if (m == MATCH_ERROR)
3211 goto error;
3212 continue;
3213 }
3214 if ((mask & OMP_CLAUSE_PRIVATE)
3215 && gfc_match_omp_variable_list ("private (",
3216 &c->lists[OMP_LIST_PRIVATE],
3217 true) == MATCH_YES)
3218 continue;
3219 if ((mask & OMP_CLAUSE_PROC_BIND)
3220 && (m = gfc_match_dupl_check ((c->proc_bind
3221 == OMP_PROC_BIND_UNKNOWN),
3222 "proc_bind", true)) != MATCH_NO)
3223 {
3224 if (m == MATCH_ERROR)
3225 goto error;
3226 if (gfc_match ("primary )") == MATCH_YES)
3227 c->proc_bind = OMP_PROC_BIND_PRIMARY;
3228 else if (gfc_match ("master )") == MATCH_YES)
3229 c->proc_bind = OMP_PROC_BIND_MASTER;
3230 else if (gfc_match ("spread )") == MATCH_YES)
3231 c->proc_bind = OMP_PROC_BIND_SPREAD;
3232 else if (gfc_match ("close )") == MATCH_YES)
3233 c->proc_bind = OMP_PROC_BIND_CLOSE;
3234 else
3235 goto error;
3236 continue;
3237 }
3238 break;
3239 case 'r':
3240 if ((mask & OMP_CLAUSE_ATOMIC)
3241 && (m = gfc_match_dupl_atomic ((c->atomic_op
3242 == GFC_OMP_ATOMIC_UNSET),
3243 "read")) != MATCH_NO)
3244 {
3245 if (m == MATCH_ERROR)
3246 goto error;
3247 c->atomic_op = GFC_OMP_ATOMIC_READ;
3248 needs_space = true;
3249 continue;
3250 }
3251 if ((mask & OMP_CLAUSE_REDUCTION)
3252 && gfc_match_omp_clause_reduction (pc, c, openacc,
3253 allow_derived) == MATCH_YES)
3254 continue;
3255 if ((mask & OMP_CLAUSE_MEMORDER)
3256 && (m = gfc_match_dupl_memorder ((c->memorder
3257 == OMP_MEMORDER_UNSET),
3258 "relaxed")) != MATCH_NO)
3259 {
3260 if (m == MATCH_ERROR)
3261 goto error;
3262 c->memorder = OMP_MEMORDER_RELAXED;
3263 needs_space = true;
3264 continue;
3265 }
3266 if ((mask & OMP_CLAUSE_MEMORDER)
3267 && (m = gfc_match_dupl_memorder ((c->memorder
3268 == OMP_MEMORDER_UNSET),
3269 "release")) != MATCH_NO)
3270 {
3271 if (m == MATCH_ERROR)
3272 goto error;
3273 c->memorder = OMP_MEMORDER_RELEASE;
3274 needs_space = true;
3275 continue;
3276 }
3277 break;
3278 case 's':
3279 if ((mask & OMP_CLAUSE_SAFELEN)
3280 && (m = gfc_match_dupl_check (!c->safelen_expr, "safelen",
3281 true, &c->safelen_expr))
3282 != MATCH_NO)
3283 {
3284 if (m == MATCH_ERROR)
3285 goto error;
3286 continue;
3287 }
3288 if ((mask & OMP_CLAUSE_SCHEDULE)
3289 && (m = gfc_match_dupl_check (c->sched_kind == OMP_SCHED_NONE,
3290 "schedule", true)) != MATCH_NO)
3291 {
3292 if (m == MATCH_ERROR)
3293 goto error;
3294 int nmodifiers = 0;
3295 locus old_loc2 = gfc_current_locus;
3296 do
3297 {
3298 if (gfc_match ("simd") == MATCH_YES)
3299 {
3300 c->sched_simd = true;
3301 nmodifiers++;
3302 }
3303 else if (gfc_match ("monotonic") == MATCH_YES)
3304 {
3305 c->sched_monotonic = true;
3306 nmodifiers++;
3307 }
3308 else if (gfc_match ("nonmonotonic") == MATCH_YES)
3309 {
3310 c->sched_nonmonotonic = true;
3311 nmodifiers++;
3312 }
3313 else
3314 {
3315 if (nmodifiers)
3316 gfc_current_locus = old_loc2;
3317 break;
3318 }
3319 if (nmodifiers == 1
3320 && gfc_match (" , ") == MATCH_YES)
3321 continue;
3322 else if (gfc_match (" : ") == MATCH_YES)
3323 break;
3324 gfc_current_locus = old_loc2;
3325 break;
3326 }
3327 while (1);
3328 if (gfc_match ("static") == MATCH_YES)
3329 c->sched_kind = OMP_SCHED_STATIC;
3330 else if (gfc_match ("dynamic") == MATCH_YES)
3331 c->sched_kind = OMP_SCHED_DYNAMIC;
3332 else if (gfc_match ("guided") == MATCH_YES)
3333 c->sched_kind = OMP_SCHED_GUIDED;
3334 else if (gfc_match ("runtime") == MATCH_YES)
3335 c->sched_kind = OMP_SCHED_RUNTIME;
3336 else if (gfc_match ("auto") == MATCH_YES)
3337 c->sched_kind = OMP_SCHED_AUTO;
3338 if (c->sched_kind != OMP_SCHED_NONE)
3339 {
3340 m = MATCH_NO;
3341 if (c->sched_kind != OMP_SCHED_RUNTIME
3342 && c->sched_kind != OMP_SCHED_AUTO)
3343 m = gfc_match (" , %e )", &c->chunk_size);
3344 if (m != MATCH_YES)
3345 m = gfc_match_char (')');
3346 if (m != MATCH_YES)
3347 c->sched_kind = OMP_SCHED_NONE;
3348 }
3349 if (c->sched_kind != OMP_SCHED_NONE)
3350 continue;
3351 else
3352 gfc_current_locus = old_loc;
3353 }
3354 if ((mask & OMP_CLAUSE_HOST_SELF)
3355 && gfc_match ("self ( ") == MATCH_YES
3356 && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
3357 OMP_MAP_FORCE_FROM, true,
3358 allow_derived))
3359 continue;
3360 if ((mask & OMP_CLAUSE_SEQ)
3361 && (m = gfc_match_dupl_check (!c->seq, "seq")) != MATCH_NO)
3362 {
3363 if (m == MATCH_ERROR)
3364 goto error;
3365 c->seq = true;
3366 needs_space = true;
3367 continue;
3368 }
3369 if ((mask & OMP_CLAUSE_MEMORDER)
3370 && (m = gfc_match_dupl_memorder ((c->memorder
3371 == OMP_MEMORDER_UNSET),
3372 "seq_cst")) != MATCH_NO)
3373 {
3374 if (m == MATCH_ERROR)
3375 goto error;
3376 c->memorder = OMP_MEMORDER_SEQ_CST;
3377 needs_space = true;
3378 continue;
3379 }
3380 if ((mask & OMP_CLAUSE_SHARED)
3381 && gfc_match_omp_variable_list ("shared (",
3382 &c->lists[OMP_LIST_SHARED],
3383 true) == MATCH_YES)
3384 continue;
3385 if ((mask & OMP_CLAUSE_SIMDLEN)
3386 && (m = gfc_match_dupl_check (!c->simdlen_expr, "simdlen", true,
3387 &c->simdlen_expr)) != MATCH_NO)
3388 {
3389 if (m == MATCH_ERROR)
3390 goto error;
3391 continue;
3392 }
3393 if ((mask & OMP_CLAUSE_SIMD)
3394 && (m = gfc_match_dupl_check (!c->simd, "simd")) != MATCH_NO)
3395 {
3396 if (m == MATCH_ERROR)
3397 goto error;
3398 c->simd = needs_space = true;
3399 continue;
3400 }
3401 if ((mask & OMP_CLAUSE_SEVERITY)
3402 && (m = gfc_match_dupl_check (!c->severity, "severity", true))
3403 != MATCH_NO)
3404 {
3405 if (m == MATCH_ERROR)
3406 goto error;
3407 if (gfc_match ("fatal )") == MATCH_YES)
3408 c->severity = OMP_SEVERITY_FATAL;
3409 else if (gfc_match ("warning )") == MATCH_YES)
3410 c->severity = OMP_SEVERITY_WARNING;
3411 else
3412 {
3413 gfc_error ("Expected FATAL or WARNING in SEVERITY clause "
3414 "at %C");
3415 goto error;
3416 }
3417 continue;
3418 }
3419 break;
3420 case 't':
3421 if ((mask & OMP_CLAUSE_TASK_REDUCTION)
3422 && gfc_match_omp_clause_reduction (pc, c, openacc,
3423 allow_derived) == MATCH_YES)
3424 continue;
3425 if ((mask & OMP_CLAUSE_THREAD_LIMIT)
3426 && (m = gfc_match_dupl_check (!c->thread_limit, "thread_limit",
3427 true, &c->thread_limit))
3428 != MATCH_NO)
3429 {
3430 if (m == MATCH_ERROR)
3431 goto error;
3432 continue;
3433 }
3434 if ((mask & OMP_CLAUSE_THREADS)
3435 && (m = gfc_match_dupl_check (!c->threads, "threads"))
3436 != MATCH_NO)
3437 {
3438 if (m == MATCH_ERROR)
3439 goto error;
3440 c->threads = needs_space = true;
3441 continue;
3442 }
3443 if ((mask & OMP_CLAUSE_TILE)
3444 && !c->tile_list
3445 && match_oacc_expr_list ("tile (", &c->tile_list,
3446 true) == MATCH_YES)
3447 continue;
3448 if ((mask & OMP_CLAUSE_TO) && (mask & OMP_CLAUSE_LINK))
3449 {
3450 /* Declare target: 'to' is an alias for 'enter';
3451 'to' is deprecated since 5.2. */
3452 m = gfc_match_omp_to_link ("to (", &c->lists[OMP_LIST_TO]);
3453 if (m == MATCH_ERROR)
3454 goto error;
3455 if (m == MATCH_YES)
3456 continue;
3457 }
3458 else if ((mask & OMP_CLAUSE_TO)
3459 && (gfc_match_omp_variable_list ("to (",
3460 &c->lists[OMP_LIST_TO], false,
3461 NULL__null, &head, true, true)
3462 == MATCH_YES))
3463 continue;
3464 break;
3465 case 'u':
3466 if ((mask & OMP_CLAUSE_UNIFORM)
3467 && gfc_match_omp_variable_list ("uniform (",
3468 &c->lists[OMP_LIST_UNIFORM],
3469 false) == MATCH_YES)
3470 continue;
3471 if ((mask & OMP_CLAUSE_UNTIED)
3472 && (m = gfc_match_dupl_check (!c->untied, "untied")) != MATCH_NO)
3473 {
3474 if (m == MATCH_ERROR)
3475 goto error;
3476 c->untied = needs_space = true;
3477 continue;
3478 }
3479 if ((mask & OMP_CLAUSE_ATOMIC)
3480 && (m = gfc_match_dupl_atomic ((c->atomic_op
3481 == GFC_OMP_ATOMIC_UNSET),
3482 "update")) != MATCH_NO)
3483 {
3484 if (m == MATCH_ERROR)
3485 goto error;
3486 c->atomic_op = GFC_OMP_ATOMIC_UPDATE;
3487 needs_space = true;
3488 continue;
3489 }
3490 if ((mask & OMP_CLAUSE_USE_DEVICE)
3491 && gfc_match_omp_variable_list ("use_device (",
3492 &c->lists[OMP_LIST_USE_DEVICE],
3493 true) == MATCH_YES)
3494 continue;
3495 if ((mask & OMP_CLAUSE_USE_DEVICE_PTR)
3496 && gfc_match_omp_variable_list
3497 ("use_device_ptr (",
3498 &c->lists[OMP_LIST_USE_DEVICE_PTR], false) == MATCH_YES)
3499 continue;
3500 if ((mask & OMP_CLAUSE_USE_DEVICE_ADDR)
3501 && gfc_match_omp_variable_list
3502 ("use_device_addr (", &c->lists[OMP_LIST_USE_DEVICE_ADDR],
3503 false, NULL__null, NULL__null, true) == MATCH_YES)
3504 continue;
3505 break;
3506 case 'v':
3507 /* VECTOR_LENGTH must be matched before VECTOR, because the latter
3508 doesn't unconditionally match '('. */
3509 if ((mask & OMP_CLAUSE_VECTOR_LENGTH)
3510 && (m = gfc_match_dupl_check (!c->vector_length_expr,
3511 "vector_length", true,
3512 &c->vector_length_expr))
3513 != MATCH_NO)
3514 {
3515 if (m == MATCH_ERROR)
3516 goto error;
3517 continue;
3518 }
3519 if ((mask & OMP_CLAUSE_VECTOR)
3520 && (m = gfc_match_dupl_check (!c->vector, "vector")) != MATCH_NO)
3521 {
3522 if (m == MATCH_ERROR)
3523 goto error;
3524 c->vector = true;
3525 m = match_oacc_clause_gwv (c, GOMP_DIM_VECTOR2);
3526 if (m == MATCH_ERROR)
3527 goto error;
3528 if (m == MATCH_NO)
3529 needs_space = true;
3530 continue;
3531 }
3532 break;
3533 case 'w':
3534 if ((mask & OMP_CLAUSE_WAIT)
3535 && gfc_match ("wait") == MATCH_YES)
3536 {
3537 m = match_oacc_expr_list (" (", &c->wait_list, false);
3538 if (m == MATCH_ERROR)
3539 goto error;
3540 else if (m == MATCH_NO)
3541 {
3542 gfc_expr *expr
3543 = gfc_get_constant_expr (BT_INTEGER,
3544 gfc_default_integer_kind,
3545 &gfc_current_locus);
3546 mpz_set_si__gmpz_set_si (expr->value.integer, GOMP_ASYNC_NOVAL-1);
3547 gfc_expr_list **expr_list = &c->wait_list;
3548 while (*expr_list)
3549 expr_list = &(*expr_list)->next;
3550 *expr_list = gfc_get_expr_list ()((gfc_expr_list *) xcalloc (1, sizeof (gfc_expr_list)));
3551 (*expr_list)->expr = expr;
3552 needs_space = true;
3553 }
3554 continue;
3555 }
3556 if ((mask & OMP_CLAUSE_WEAK)
3557 && (m = gfc_match_dupl_check (!c->weak, "weak"))
3558 != MATCH_NO)
3559 {
3560 if (m == MATCH_ERROR)
3561 goto error;
3562 c->weak = true;
3563 needs_space = true;
3564 continue;
3565 }
3566 if ((mask & OMP_CLAUSE_WORKER)
3567 && (m = gfc_match_dupl_check (!c->worker, "worker")) != MATCH_NO)
3568 {
3569 if (m == MATCH_ERROR)
3570 goto error;
3571 c->worker = true;
3572 m = match_oacc_clause_gwv (c, GOMP_DIM_WORKER1);
3573 if (m == MATCH_ERROR)
3574 goto error;
3575 else if (m == MATCH_NO)
3576 needs_space = true;
3577 continue;
3578 }
3579 if ((mask & OMP_CLAUSE_ATOMIC)
3580 && (m = gfc_match_dupl_atomic ((c->atomic_op
3581 == GFC_OMP_ATOMIC_UNSET),
3582 "write")) != MATCH_NO)
3583 {
3584 if (m == MATCH_ERROR)
3585 goto error;
3586 c->atomic_op = GFC_OMP_ATOMIC_WRITE;
3587 needs_space = true;
3588 continue;
3589 }
3590 break;
3591 }
3592 break;
3593 }
3594
3595end:
3596 if (error
3597 || (context_selector && gfc_peek_ascii_char () != ')')
3598 || (!context_selector && gfc_match_omp_eos () != MATCH_YES))
3599 {
3600 if (!gfc_error_flag_test ())
3601 gfc_error ("Failed to match clause at %C");
3602 gfc_free_omp_clauses (c);
3603 return MATCH_ERROR;
3604 }
3605
3606 *cp = c;
3607 return MATCH_YES;
3608
3609error:
3610 error = true;
3611 goto end;
3612}
3613
3614
3615#define OACC_PARALLEL_CLAUSES(omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS
| OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_REDUCTION
| OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT |
OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT
| OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE
| OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
\
3616 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS \
3617 | OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_REDUCTION \
3618 | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
3619 | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT \
3620 | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
3621 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
3622#define OACC_KERNELS_CLAUSES(omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS
| OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_DEVICEPTR
| OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT |
OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT
| OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
\
3623 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS \
3624 | OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_DEVICEPTR \
3625 | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
3626 | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT \
3627 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
3628#define OACC_SERIAL_CLAUSES(omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_REDUCTION
| OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT |
OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT
| OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE
| OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
\
3629 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_REDUCTION \
3630 | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
3631 | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT \
3632 | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
3633 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
3634#define OACC_DATA_CLAUSES(omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_COPY
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT | OMP_CLAUSE_CREATE
| OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT | OMP_CLAUSE_ATTACH
)
\
3635 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_COPY \
3636 | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT | OMP_CLAUSE_CREATE \
3637 | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT | OMP_CLAUSE_ATTACH)
3638#define OACC_LOOP_CLAUSES(omp_mask (OMP_CLAUSE_COLLAPSE) | OMP_CLAUSE_GANG | OMP_CLAUSE_WORKER
| OMP_CLAUSE_VECTOR | OMP_CLAUSE_SEQ | OMP_CLAUSE_INDEPENDENT
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_AUTO
| OMP_CLAUSE_TILE)
\
3639 (omp_mask (OMP_CLAUSE_COLLAPSE) | OMP_CLAUSE_GANG | OMP_CLAUSE_WORKER \
3640 | OMP_CLAUSE_VECTOR | OMP_CLAUSE_SEQ | OMP_CLAUSE_INDEPENDENT \
3641 | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_AUTO \
3642 | OMP_CLAUSE_TILE)
3643#define OACC_PARALLEL_LOOP_CLAUSES((omp_mask (OMP_CLAUSE_COLLAPSE) | OMP_CLAUSE_GANG | OMP_CLAUSE_WORKER
| OMP_CLAUSE_VECTOR | OMP_CLAUSE_SEQ | OMP_CLAUSE_INDEPENDENT
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_AUTO
| OMP_CLAUSE_TILE) | (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC
| OMP_CLAUSE_NUM_GANGS | OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN
| OMP_CLAUSE_COPYOUT | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE
| OMP_CLAUSE_PRESENT | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_PRIVATE
| OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT
| OMP_CLAUSE_ATTACH))
\
3644 (OACC_LOOP_CLAUSES(omp_mask (OMP_CLAUSE_COLLAPSE) | OMP_CLAUSE_GANG | OMP_CLAUSE_WORKER
| OMP_CLAUSE_VECTOR | OMP_CLAUSE_SEQ | OMP_CLAUSE_INDEPENDENT
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_AUTO
| OMP_CLAUSE_TILE)
| OACC_PARALLEL_CLAUSES(omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS
| OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_REDUCTION
| OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT |
OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT
| OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE
| OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
)
3645#define OACC_KERNELS_LOOP_CLAUSES((omp_mask (OMP_CLAUSE_COLLAPSE) | OMP_CLAUSE_GANG | OMP_CLAUSE_WORKER
| OMP_CLAUSE_VECTOR | OMP_CLAUSE_SEQ | OMP_CLAUSE_INDEPENDENT
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_AUTO
| OMP_CLAUSE_TILE) | (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC
| OMP_CLAUSE_NUM_GANGS | OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH
| OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN
| OMP_CLAUSE_COPYOUT | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE
| OMP_CLAUSE_PRESENT | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT |
OMP_CLAUSE_ATTACH))
\
3646 (OACC_LOOP_CLAUSES(omp_mask (OMP_CLAUSE_COLLAPSE) | OMP_CLAUSE_GANG | OMP_CLAUSE_WORKER
| OMP_CLAUSE_VECTOR | OMP_CLAUSE_SEQ | OMP_CLAUSE_INDEPENDENT
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_AUTO
| OMP_CLAUSE_TILE)
| OACC_KERNELS_CLAUSES(omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS
| OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_DEVICEPTR
| OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT |
OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT
| OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
)
3647#define OACC_SERIAL_LOOP_CLAUSES((omp_mask (OMP_CLAUSE_COLLAPSE) | OMP_CLAUSE_GANG | OMP_CLAUSE_WORKER
| OMP_CLAUSE_VECTOR | OMP_CLAUSE_SEQ | OMP_CLAUSE_INDEPENDENT
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_AUTO
| OMP_CLAUSE_TILE) | (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN
| OMP_CLAUSE_COPYOUT | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE
| OMP_CLAUSE_PRESENT | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_PRIVATE
| OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT
| OMP_CLAUSE_ATTACH))
\
3648 (OACC_LOOP_CLAUSES(omp_mask (OMP_CLAUSE_COLLAPSE) | OMP_CLAUSE_GANG | OMP_CLAUSE_WORKER
| OMP_CLAUSE_VECTOR | OMP_CLAUSE_SEQ | OMP_CLAUSE_INDEPENDENT
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_AUTO
| OMP_CLAUSE_TILE)
| OACC_SERIAL_CLAUSES(omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_REDUCTION
| OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT |
OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT
| OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE
| OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
)
3649#define OACC_HOST_DATA_CLAUSES(omp_mask (OMP_CLAUSE_USE_DEVICE) | OMP_CLAUSE_IF | OMP_CLAUSE_IF_PRESENT
)
\
3650 (omp_mask (OMP_CLAUSE_USE_DEVICE) \
3651 | OMP_CLAUSE_IF \
3652 | OMP_CLAUSE_IF_PRESENT)
3653#define OACC_DECLARE_CLAUSES(omp_mask (OMP_CLAUSE_COPY) | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT
| OMP_CLAUSE_CREATE | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_DEVICE_RESIDENT
| OMP_CLAUSE_PRESENT | OMP_CLAUSE_LINK)
\
3654 (omp_mask (OMP_CLAUSE_COPY) | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
3655 | OMP_CLAUSE_CREATE | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_DEVICE_RESIDENT \
3656 | OMP_CLAUSE_PRESENT \
3657 | OMP_CLAUSE_LINK)
3658#define OACC_UPDATE_CLAUSES(omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_HOST_SELF
| OMP_CLAUSE_DEVICE | OMP_CLAUSE_WAIT | OMP_CLAUSE_IF_PRESENT
)
\
3659 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_HOST_SELF \
3660 | OMP_CLAUSE_DEVICE | OMP_CLAUSE_WAIT | OMP_CLAUSE_IF_PRESENT)
3661#define OACC_ENTER_DATA_CLAUSES(omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_WAIT
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_CREATE | OMP_CLAUSE_ATTACH)
\
3662 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_WAIT \
3663 | OMP_CLAUSE_COPYIN | OMP_CLAUSE_CREATE | OMP_CLAUSE_ATTACH)
3664#define OACC_EXIT_DATA_CLAUSES(omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_WAIT
| OMP_CLAUSE_COPYOUT | OMP_CLAUSE_DELETE | OMP_CLAUSE_FINALIZE
| OMP_CLAUSE_DETACH)
\
3665 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_WAIT \
3666 | OMP_CLAUSE_COPYOUT | OMP_CLAUSE_DELETE | OMP_CLAUSE_FINALIZE \
3667 | OMP_CLAUSE_DETACH)
3668#define OACC_WAIT_CLAUSESomp_mask (OMP_CLAUSE_ASYNC) \
3669 omp_mask (OMP_CLAUSE_ASYNC)
3670#define OACC_ROUTINE_CLAUSES(omp_mask (OMP_CLAUSE_GANG) | OMP_CLAUSE_WORKER | OMP_CLAUSE_VECTOR
| OMP_CLAUSE_SEQ | OMP_CLAUSE_NOHOST)
\
3671 (omp_mask (OMP_CLAUSE_GANG) | OMP_CLAUSE_WORKER | OMP_CLAUSE_VECTOR \
3672 | OMP_CLAUSE_SEQ \
3673 | OMP_CLAUSE_NOHOST)
3674
3675
3676static match
3677match_acc (gfc_exec_op op, const omp_mask mask)
3678{
3679 gfc_omp_clauses *c;
3680 if (gfc_match_omp_clauses (&c, mask, false, false, true) != MATCH_YES)
3681 return MATCH_ERROR;
3682 new_st.op = op;
3683 new_st.ext.omp_clauses = c;
3684 return MATCH_YES;
3685}
3686
3687match
3688gfc_match_oacc_parallel_loop (void)
3689{
3690 return match_acc (EXEC_OACC_PARALLEL_LOOP, OACC_PARALLEL_LOOP_CLAUSES((omp_mask (OMP_CLAUSE_COLLAPSE) | OMP_CLAUSE_GANG | OMP_CLAUSE_WORKER
| OMP_CLAUSE_VECTOR | OMP_CLAUSE_SEQ | OMP_CLAUSE_INDEPENDENT
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_AUTO
| OMP_CLAUSE_TILE) | (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC
| OMP_CLAUSE_NUM_GANGS | OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN
| OMP_CLAUSE_COPYOUT | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE
| OMP_CLAUSE_PRESENT | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_PRIVATE
| OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT
| OMP_CLAUSE_ATTACH))
);
3691}
3692
3693
3694match
3695gfc_match_oacc_parallel (void)
3696{
3697 return match_acc (EXEC_OACC_PARALLEL, OACC_PARALLEL_CLAUSES(omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS
| OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_REDUCTION
| OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT |
OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT
| OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE
| OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
);
3698}
3699
3700
3701match
3702gfc_match_oacc_kernels_loop (void)
3703{
3704 return match_acc (EXEC_OACC_KERNELS_LOOP, OACC_KERNELS_LOOP_CLAUSES((omp_mask (OMP_CLAUSE_COLLAPSE) | OMP_CLAUSE_GANG | OMP_CLAUSE_WORKER
| OMP_CLAUSE_VECTOR | OMP_CLAUSE_SEQ | OMP_CLAUSE_INDEPENDENT
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_AUTO
| OMP_CLAUSE_TILE) | (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC
| OMP_CLAUSE_NUM_GANGS | OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH
| OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN
| OMP_CLAUSE_COPYOUT | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE
| OMP_CLAUSE_PRESENT | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT |
OMP_CLAUSE_ATTACH))
);
3705}
3706
3707
3708match
3709gfc_match_oacc_kernels (void)
3710{
3711 return match_acc (EXEC_OACC_KERNELS, OACC_KERNELS_CLAUSES(omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS
| OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_DEVICEPTR
| OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT |
OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT
| OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
);
3712}
3713
3714
3715match
3716gfc_match_oacc_serial_loop (void)
3717{
3718 return match_acc (EXEC_OACC_SERIAL_LOOP, OACC_SERIAL_LOOP_CLAUSES((omp_mask (OMP_CLAUSE_COLLAPSE) | OMP_CLAUSE_GANG | OMP_CLAUSE_WORKER
| OMP_CLAUSE_VECTOR | OMP_CLAUSE_SEQ | OMP_CLAUSE_INDEPENDENT
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_AUTO
| OMP_CLAUSE_TILE) | (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN
| OMP_CLAUSE_COPYOUT | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE
| OMP_CLAUSE_PRESENT | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_PRIVATE
| OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT
| OMP_CLAUSE_ATTACH))
);
3719}
3720
3721
3722match
3723gfc_match_oacc_serial (void)
3724{
3725 return match_acc (EXEC_OACC_SERIAL, OACC_SERIAL_CLAUSES(omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_REDUCTION
| OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT |
OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT
| OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE
| OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
);
3726}
3727
3728
3729match
3730gfc_match_oacc_data (void)
3731{
3732 return match_acc (EXEC_OACC_DATA, OACC_DATA_CLAUSES(omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_COPY
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT | OMP_CLAUSE_CREATE
| OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT | OMP_CLAUSE_ATTACH
)
);
3733}
3734
3735
3736match
3737gfc_match_oacc_host_data (void)
3738{
3739 return match_acc (EXEC_OACC_HOST_DATA, OACC_HOST_DATA_CLAUSES(omp_mask (OMP_CLAUSE_USE_DEVICE) | OMP_CLAUSE_IF | OMP_CLAUSE_IF_PRESENT
)
);
3740}
3741
3742
3743match
3744gfc_match_oacc_loop (void)
3745{
3746 return match_acc (EXEC_OACC_LOOP, OACC_LOOP_CLAUSES(omp_mask (OMP_CLAUSE_COLLAPSE) | OMP_CLAUSE_GANG | OMP_CLAUSE_WORKER
| OMP_CLAUSE_VECTOR | OMP_CLAUSE_SEQ | OMP_CLAUSE_INDEPENDENT
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_AUTO
| OMP_CLAUSE_TILE)
);
3747}
3748
3749
3750match
3751gfc_match_oacc_declare (void)
3752{
3753 gfc_omp_clauses *c;
3754 gfc_omp_namelist *n;
3755 gfc_namespace *ns = gfc_current_ns;
3756 gfc_oacc_declare *new_oc;
3757 bool module_var = false;
3758 locus where = gfc_current_locus;
3759
3760 if (gfc_match_omp_clauses (&c, OACC_DECLARE_CLAUSES(omp_mask (OMP_CLAUSE_COPY) | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT
| OMP_CLAUSE_CREATE | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_DEVICE_RESIDENT
| OMP_CLAUSE_PRESENT | OMP_CLAUSE_LINK)
, false, false, true)
3761 != MATCH_YES)
3762 return MATCH_ERROR;
3763
3764 for (n = c->lists[OMP_LIST_DEVICE_RESIDENT]; n != NULL__null; n = n->next)
3765 n->sym->attr.oacc_declare_device_resident = 1;
3766
3767 for (n = c->lists[OMP_LIST_LINK]; n != NULL__null; n = n->next)
3768 n->sym->attr.oacc_declare_link = 1;
3769
3770 for (n = c->lists[OMP_LIST_MAP]; n != NULL__null; n = n->next)
3771 {
3772 gfc_symbol *s = n->sym;
3773
3774 if (gfc_current_ns->proc_name
3775 && gfc_current_ns->proc_name->attr.flavor == FL_MODULE)
3776 {
3777 if (n->u.map_op != OMP_MAP_ALLOC && n->u.map_op != OMP_MAP_TO)
3778 {
3779 gfc_error ("Invalid clause in module with !$ACC DECLARE at %L",
3780 &where);
3781 return MATCH_ERROR;
3782 }
3783
3784 module_var = true;
3785 }
3786
3787 if (s->attr.use_assoc)
3788 {
3789 gfc_error ("Variable is USE-associated with !$ACC DECLARE at %L",
3790 &where);
3791 return MATCH_ERROR;
3792 }
3793
3794 if ((s->result == s && s->ns->contained != gfc_current_ns)
3795 || ((s->attr.flavor == FL_UNKNOWN || s->attr.flavor == FL_VARIABLE)
3796 && s->ns != gfc_current_ns))
3797 {
3798 gfc_error ("Variable %qs shall be declared in the same scoping unit "
3799 "as !$ACC DECLARE at %L", s->name, &where);
3800 return MATCH_ERROR;
3801 }
3802
3803 if ((s->attr.dimension || s->attr.codimension)
3804 && s->attr.dummy && s->as->type != AS_EXPLICIT)
3805 {
3806 gfc_error ("Assumed-size dummy array with !$ACC DECLARE at %L",
3807 &where);
3808 return MATCH_ERROR;
3809 }
3810
3811 switch (n->u.map_op)
3812 {
3813 case OMP_MAP_FORCE_ALLOC:
3814 case OMP_MAP_ALLOC:
3815 s->attr.oacc_declare_create = 1;
3816 break;
3817
3818 case OMP_MAP_FORCE_TO:
3819 case OMP_MAP_TO:
3820 s->attr.oacc_declare_copyin = 1;
3821 break;
3822
3823 case OMP_MAP_FORCE_DEVICEPTR:
3824 s->attr.oacc_declare_deviceptr = 1;
3825 break;
3826
3827 default:
3828 break;
3829 }
3830 }
3831
3832 new_oc = gfc_get_oacc_declare ()((gfc_oacc_declare *) xcalloc (1, sizeof (gfc_oacc_declare)));
3833 new_oc->next = ns->oacc_declare;
3834 new_oc->module_var = module_var;
3835 new_oc->clauses = c;
3836 new_oc->loc = gfc_current_locus;
3837 ns->oacc_declare = new_oc;
3838
3839 return MATCH_YES;
3840}
3841
3842
3843match
3844gfc_match_oacc_update (void)
3845{
3846 gfc_omp_clauses *c;
3847 locus here = gfc_current_locus;
3848
3849 if (gfc_match_omp_clauses (&c, OACC_UPDATE_CLAUSES(omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_HOST_SELF
| OMP_CLAUSE_DEVICE | OMP_CLAUSE_WAIT | OMP_CLAUSE_IF_PRESENT
)
, false, false, true)
3850 != MATCH_YES)
3851 return MATCH_ERROR;
3852
3853 if (!c->lists[OMP_LIST_MAP])
3854 {
3855 gfc_error ("%<acc update%> must contain at least one "
3856 "%<device%> or %<host%> or %<self%> clause at %L", &here);
3857 return MATCH_ERROR;
3858 }
3859
3860 new_st.op = EXEC_OACC_UPDATE;
3861 new_st.ext.omp_clauses = c;
3862 return MATCH_YES;
3863}
3864
3865
3866match
3867gfc_match_oacc_enter_data (void)
3868{
3869 return match_acc (EXEC_OACC_ENTER_DATA, OACC_ENTER_DATA_CLAUSES(omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_WAIT
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_CREATE | OMP_CLAUSE_ATTACH)
);
3870}
3871
3872
3873match
3874gfc_match_oacc_exit_data (void)
3875{
3876 return match_acc (EXEC_OACC_EXIT_DATA, OACC_EXIT_DATA_CLAUSES(omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_WAIT
| OMP_CLAUSE_COPYOUT | OMP_CLAUSE_DELETE | OMP_CLAUSE_FINALIZE
| OMP_CLAUSE_DETACH)
);
3877}
3878
3879
3880match
3881gfc_match_oacc_wait (void)
3882{
3883 gfc_omp_clauses *c = gfc_get_omp_clauses ()((gfc_omp_clauses *) xcalloc (1, sizeof (gfc_omp_clauses)));
3884 gfc_expr_list *wait_list = NULL__null, *el;
3885 bool space = true;
3886 match m;
3887
3888 m = match_oacc_expr_list (" (", &wait_list, true);
3889 if (m == MATCH_ERROR)
3890 return m;
3891 else if (m == MATCH_YES)
3892 space = false;
3893
3894 if (gfc_match_omp_clauses (&c, OACC_WAIT_CLAUSESomp_mask (OMP_CLAUSE_ASYNC), space, space, true)
3895 == MATCH_ERROR)
3896 return MATCH_ERROR;
3897
3898 if (wait_list)
3899 for (el = wait_list; el; el = el->next)
3900 {
3901 if (el->expr == NULL__null)
3902 {
3903 gfc_error ("Invalid argument to !$ACC WAIT at %C");
3904 return MATCH_ERROR;
3905 }
3906
3907 if (!gfc_resolve_expr (el->expr)
3908 || el->expr->ts.type != BT_INTEGER || el->expr->rank != 0)
3909 {
3910 gfc_error ("WAIT clause at %L requires a scalar INTEGER expression",
3911 &el->expr->where);
3912
3913 return MATCH_ERROR;
3914 }
3915 }
3916 c->wait_list = wait_list;
3917 new_st.op = EXEC_OACC_WAIT;
3918 new_st.ext.omp_clauses = c;
3919 return MATCH_YES;
3920}
3921
3922
3923match
3924gfc_match_oacc_cache (void)
3925{
3926 gfc_omp_clauses *c = gfc_get_omp_clauses ()((gfc_omp_clauses *) xcalloc (1, sizeof (gfc_omp_clauses)));
3927 /* The OpenACC cache directive explicitly only allows "array elements or
3928 subarrays", which we're currently not checking here. Either check this
3929 after the call of gfc_match_omp_variable_list, or add something like a
3930 only_sections variant next to its allow_sections parameter. */
3931 match m = gfc_match_omp_variable_list (" (",
3932 &c->lists[OMP_LIST_CACHE], true,
3933 NULL__null, NULL__null, true);
3934 if (m != MATCH_YES)
3935 {
3936 gfc_free_omp_clauses(c);
3937 return m;
3938 }
3939
3940 if (gfc_current_state()(gfc_state_stack->state) != COMP_DO
3941 && gfc_current_state()(gfc_state_stack->state) != COMP_DO_CONCURRENT)
3942 {
3943 gfc_error ("ACC CACHE directive must be inside of loop %C");
3944 gfc_free_omp_clauses(c);
3945 return MATCH_ERROR;
3946 }
3947
3948 new_st.op = EXEC_OACC_CACHE;
3949 new_st.ext.omp_clauses = c;
3950 return MATCH_YES;
3951}
3952
3953/* Determine the OpenACC 'routine' directive's level of parallelism. */
3954
3955static oacc_routine_lop
3956gfc_oacc_routine_lop (gfc_omp_clauses *clauses)
3957{
3958 oacc_routine_lop ret = OACC_ROUTINE_LOP_SEQ;
3959
3960 if (clauses)
3961 {
3962 unsigned n_lop_clauses = 0;
3963
3964 if (clauses->gang)
3965 {
3966 ++n_lop_clauses;
3967 ret = OACC_ROUTINE_LOP_GANG;
3968 }
3969 if (clauses->worker)
3970 {
3971 ++n_lop_clauses;
3972 ret = OACC_ROUTINE_LOP_WORKER;
3973 }
3974 if (clauses->vector)
3975 {
3976 ++n_lop_clauses;
3977 ret = OACC_ROUTINE_LOP_VECTOR;
3978 }
3979 if (clauses->seq)
3980 {
3981 ++n_lop_clauses;
3982 ret = OACC_ROUTINE_LOP_SEQ;
3983 }
3984
3985 if (n_lop_clauses > 1)
3986 ret = OACC_ROUTINE_LOP_ERROR;
3987 }
3988
3989 return ret;
3990}
3991
3992match
3993gfc_match_oacc_routine (void)
3994{
3995 locus old_loc;
3996 match m;
3997 gfc_intrinsic_sym *isym = NULL__null;
3998 gfc_symbol *sym = NULL__null;
3999 gfc_omp_clauses *c = NULL__null;
4000 gfc_oacc_routine_name *n = NULL__null;
4001 oacc_routine_lop lop = OACC_ROUTINE_LOP_NONE;
4002 bool nohost;
4003
4004 old_loc = gfc_current_locus;
4005
4006 m = gfc_match (" (");
4007
4008 if (gfc_current_ns->proc_name
4009 && gfc_current_ns->proc_name->attr.if_source == IFSRC_IFBODY
4010 && m == MATCH_YES)
4011 {
4012 gfc_error ("Only the !$ACC ROUTINE form without "
4013 "list is allowed in interface block at %C");
4014 goto cleanup;
4015 }
4016
4017 if (m == MATCH_YES)
4018 {
4019 char buffer[GFC_MAX_SYMBOL_LEN63 + 1];
4020
4021 m = gfc_match_name (buffer);
4022 if (m == MATCH_YES)
4023 {
4024 gfc_symtree *st = NULL__null;
4025
4026 /* First look for an intrinsic symbol. */
4027 isym = gfc_find_function (buffer);
4028 if (!isym)
4029 isym = gfc_find_subroutine (buffer);
4030 /* If no intrinsic symbol found, search the current namespace. */
4031 if (!isym)
4032 st = gfc_find_symtree (gfc_current_ns->sym_root, buffer);
4033 if (st)
4034 {
4035 sym = st->n.sym;
4036 /* If the name in a 'routine' directive refers to the containing
4037 subroutine or function, then make sure that we'll later handle
4038 this accordingly. */
4039 if (gfc_current_ns->proc_name != NULL__null
4040 && strcmp (sym->name, gfc_current_ns->proc_name->name) == 0)
4041 sym = NULL__null;
4042 }
4043
4044 if (isym == NULL__null && st == NULL__null)
4045 {
4046 gfc_error ("Invalid NAME %qs in !$ACC ROUTINE ( NAME ) at %C",
4047 buffer);
4048 gfc_current_locus = old_loc;
4049 return MATCH_ERROR;
4050 }
4051 }
4052 else
4053 {
4054 gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C");
4055 gfc_current_locus = old_loc;
4056 return MATCH_ERROR;
4057 }
4058
4059 if (gfc_match_char (')') != MATCH_YES)
4060 {
4061 gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C, expecting"
4062 " %<)%> after NAME");
4063 gfc_current_locus = old_loc;
4064 return MATCH_ERROR;
4065 }
4066 }
4067
4068 if (gfc_match_omp_eos () != MATCH_YES
4069 && (gfc_match_omp_clauses (&c, OACC_ROUTINE_CLAUSES(omp_mask (OMP_CLAUSE_GANG) | OMP_CLAUSE_WORKER | OMP_CLAUSE_VECTOR
| OMP_CLAUSE_SEQ | OMP_CLAUSE_NOHOST)
, false, false, true)
4070 != MATCH_YES))
4071 return MATCH_ERROR;
4072
4073 lop = gfc_oacc_routine_lop (c);
4074 if (lop == OACC_ROUTINE_LOP_ERROR)
4075 {
4076 gfc_error ("Multiple loop axes specified for routine at %C");
4077 goto cleanup;
4078 }
4079 nohost = c ? c->nohost : false;
4080
4081 if (isym != NULL__null)
4082 {
4083 /* Diagnose any OpenACC 'routine' directive that doesn't match the
4084 (implicit) one with a 'seq' clause. */
4085 if (c && (c->gang || c->worker || c->vector))
4086 {
4087 gfc_error ("Intrinsic symbol specified in !$ACC ROUTINE ( NAME )"
4088 " at %C marked with incompatible GANG, WORKER, or VECTOR"
4089 " clause");
4090 goto cleanup;
4091 }
4092 /* ..., and no 'nohost' clause. */
4093 if (nohost)
4094 {
4095 gfc_error ("Intrinsic symbol specified in !$ACC ROUTINE ( NAME )"
4096 " at %C marked with incompatible NOHOST clause");
4097 goto cleanup;
4098 }
4099 }
4100 else if (sym != NULL__null)
4101 {
4102 bool add = true;
4103
4104 /* For a repeated OpenACC 'routine' directive, diagnose if it doesn't
4105 match the first one. */
4106 for (gfc_oacc_routine_name *n_p = gfc_current_ns->oacc_routine_names;
4107 n_p;
4108 n_p = n_p->next)
4109 if (n_p->sym == sym)
4110 {
4111 add = false;
4112 bool nohost_p = n_p->clauses ? n_p->clauses->nohost : false;
4113 if (lop != gfc_oacc_routine_lop (n_p->clauses)
4114 || nohost != nohost_p)
4115 {
4116 gfc_error ("!$ACC ROUTINE already applied at %C");
4117 goto cleanup;
4118 }
4119 }
4120
4121 if (add)
4122 {
4123 sym->attr.oacc_routine_lop = lop;
4124 sym->attr.oacc_routine_nohost = nohost;
4125
4126 n = gfc_get_oacc_routine_name ()((gfc_oacc_routine_name *) xcalloc (1, sizeof (gfc_oacc_routine_name
)))
;
4127 n->sym = sym;
4128 n->clauses = c;
4129 n->next = gfc_current_ns->oacc_routine_names;
4130 n->loc = old_loc;
4131 gfc_current_ns->oacc_routine_names = n;
4132 }
4133 }
4134 else if (gfc_current_ns->proc_name)
4135 {
4136 /* For a repeated OpenACC 'routine' directive, diagnose if it doesn't
4137 match the first one. */
4138 oacc_routine_lop lop_p = gfc_current_ns->proc_name->attr.oacc_routine_lop;
4139 bool nohost_p = gfc_current_ns->proc_name->attr.oacc_routine_nohost;
4140 if (lop_p != OACC_ROUTINE_LOP_NONE
4141 && (lop != lop_p
4142 || nohost != nohost_p))
4143 {
4144 gfc_error ("!$ACC ROUTINE already applied at %C");
4145 goto cleanup;
4146 }
4147
4148 if (!gfc_add_omp_declare_target (&gfc_current_ns->proc_name->attr,
4149 gfc_current_ns->proc_name->name,
4150 &old_loc))
4151 goto cleanup;
4152 gfc_current_ns->proc_name->attr.oacc_routine_lop = lop;
4153 gfc_current_ns->proc_name->attr.oacc_routine_nohost = nohost;
4154 }
4155 else
4156 /* Something has gone wrong, possibly a syntax error. */
4157 goto cleanup;
4158
4159 if (gfc_pure (NULL__null) && c && (c->gang || c->worker || c->vector))
4160 {
4161 gfc_error ("!$ACC ROUTINE with GANG, WORKER, or VECTOR clause is not "
4162 "permitted in PURE procedure at %C");
4163 goto cleanup;
4164 }
4165
4166
4167 if (n)
4168 n->clauses = c;
4169 else if (gfc_current_ns->oacc_routine)
4170 gfc_current_ns->oacc_routine_clauses = c;
4171
4172 new_st.op = EXEC_OACC_ROUTINE;
4173 new_st.ext.omp_clauses = c;
4174 return MATCH_YES;
4175
4176cleanup:
4177 gfc_current_locus = old_loc;
4178 return MATCH_ERROR;
4179}
4180
4181
4182#define OMP_PARALLEL_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF |
OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PROC_BIND
| OMP_CLAUSE_ALLOCATE)
\
4183 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
4184 | OMP_CLAUSE_SHARED | OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION \
4185 | OMP_CLAUSE_IF | OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT \
4186 | OMP_CLAUSE_PROC_BIND | OMP_CLAUSE_ALLOCATE)
4187#define OMP_DECLARE_SIMD_CLAUSES(omp_mask (OMP_CLAUSE_SIMDLEN) | OMP_CLAUSE_LINEAR | OMP_CLAUSE_UNIFORM
| OMP_CLAUSE_ALIGNED | OMP_CLAUSE_INBRANCH | OMP_CLAUSE_NOTINBRANCH
)
\
4188 (omp_mask (OMP_CLAUSE_SIMDLEN) | OMP_CLAUSE_LINEAR \
4189 | OMP_CLAUSE_UNIFORM | OMP_CLAUSE_ALIGNED | OMP_CLAUSE_INBRANCH \
4190 | OMP_CLAUSE_NOTINBRANCH)
4191#define OMP_DO_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ORDER
| OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT)
\
4192 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
4193 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION \
4194 | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED | OMP_CLAUSE_COLLAPSE \
4195 | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ORDER | OMP_CLAUSE_ALLOCATE \
4196 | OMP_CLAUSE_NOWAIT)
4197#define OMP_LOOP_CLAUSES(omp_mask (OMP_CLAUSE_BIND) | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_ORDER
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION
)
\
4198 (omp_mask (OMP_CLAUSE_BIND) | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_ORDER \
4199 | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION)
4200
4201#define OMP_SCOPE_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) |OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_REDUCTION
| OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT)
\
4202 (omp_mask (OMP_CLAUSE_PRIVATE) |OMP_CLAUSE_FIRSTPRIVATE \
4203 | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT)
4204#define OMP_SECTIONS_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT
)
\
4205 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
4206 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION \
4207 | OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT)
4208#define OMP_SIMD_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN | OMP_CLAUSE_LINEAR
| OMP_CLAUSE_ALIGNED | OMP_CLAUSE_SIMDLEN | OMP_CLAUSE_IF | OMP_CLAUSE_ORDER
| OMP_CLAUSE_NOTEMPORAL)
\
4209 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE \
4210 | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN \
4211 | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ALIGNED | OMP_CLAUSE_SIMDLEN \
4212 | OMP_CLAUSE_IF | OMP_CLAUSE_ORDER | OMP_CLAUSE_NOTEMPORAL)
4213#define OMP_TASK_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_IF | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL
| OMP_CLAUSE_MERGEABLE | OMP_CLAUSE_DEPEND | OMP_CLAUSE_PRIORITY
| OMP_CLAUSE_IN_REDUCTION | OMP_CLAUSE_DETACH | OMP_CLAUSE_AFFINITY
| OMP_CLAUSE_ALLOCATE)
\
4214 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
4215 | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF | OMP_CLAUSE_DEFAULT \
4216 | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL | OMP_CLAUSE_MERGEABLE \
4217 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_PRIORITY | OMP_CLAUSE_IN_REDUCTION \
4218 | OMP_CLAUSE_DETACH | OMP_CLAUSE_AFFINITY | OMP_CLAUSE_ALLOCATE)
4219#define OMP_TASKLOOP_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_SHARED | OMP_CLAUSE_IF | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_UNTIED
| OMP_CLAUSE_FINAL | OMP_CLAUSE_MERGEABLE | OMP_CLAUSE_PRIORITY
| OMP_CLAUSE_GRAINSIZE | OMP_CLAUSE_NUM_TASKS | OMP_CLAUSE_COLLAPSE
| OMP_CLAUSE_NOGROUP | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IN_REDUCTION
| OMP_CLAUSE_ALLOCATE)
\
4220 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
4221 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF \
4222 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL \
4223 | OMP_CLAUSE_MERGEABLE | OMP_CLAUSE_PRIORITY | OMP_CLAUSE_GRAINSIZE \
4224 | OMP_CLAUSE_NUM_TASKS | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_NOGROUP \
4225 | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IN_REDUCTION | OMP_CLAUSE_ALLOCATE)
4226#define OMP_TASKGROUP_CLAUSES(omp_mask (OMP_CLAUSE_TASK_REDUCTION) | OMP_CLAUSE_ALLOCATE) \
4227 (omp_mask (OMP_CLAUSE_TASK_REDUCTION) | OMP_CLAUSE_ALLOCATE)
4228#define OMP_TARGET_CLAUSES(omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF
| OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE
| OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP | OMP_CLAUSE_IS_DEVICE_PTR
| OMP_CLAUSE_IN_REDUCTION | OMP_CLAUSE_THREAD_LIMIT | OMP_CLAUSE_ALLOCATE
| OMP_CLAUSE_HAS_DEVICE_ADDR)
\
4229 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
4230 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE \
4231 | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP \
4232 | OMP_CLAUSE_IS_DEVICE_PTR | OMP_CLAUSE_IN_REDUCTION \
4233 | OMP_CLAUSE_THREAD_LIMIT | OMP_CLAUSE_ALLOCATE \
4234 | OMP_CLAUSE_HAS_DEVICE_ADDR)
4235#define OMP_TARGET_DATA_CLAUSES(omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF
| OMP_CLAUSE_USE_DEVICE_PTR | OMP_CLAUSE_USE_DEVICE_ADDR)
\
4236 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
4237 | OMP_CLAUSE_USE_DEVICE_PTR | OMP_CLAUSE_USE_DEVICE_ADDR)
4238#define OMP_TARGET_ENTER_DATA_CLAUSES(omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF
| OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
\
4239 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
4240 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
4241#define OMP_TARGET_EXIT_DATA_CLAUSES(omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF
| OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
\
4242 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
4243 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
4244#define OMP_TARGET_UPDATE_CLAUSES(omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_IF | OMP_CLAUSE_TO
| OMP_CLAUSE_FROM | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
\
4245 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_IF | OMP_CLAUSE_TO \
4246 | OMP_CLAUSE_FROM | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
4247#define OMP_TEAMS_CLAUSES(omp_mask (OMP_CLAUSE_NUM_TEAMS) | OMP_CLAUSE_THREAD_LIMIT | OMP_CLAUSE_DEFAULT
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE)
\
4248 (omp_mask (OMP_CLAUSE_NUM_TEAMS) | OMP_CLAUSE_THREAD_LIMIT \
4249 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
4250 | OMP_CLAUSE_SHARED | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE)
4251#define OMP_DISTRIBUTE_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_DIST_SCHEDULE | OMP_CLAUSE_ORDER
| OMP_CLAUSE_ALLOCATE)
\
4252 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
4253 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_DIST_SCHEDULE \
4254 | OMP_CLAUSE_ORDER | OMP_CLAUSE_ALLOCATE)
4255#define OMP_SINGLE_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_ALLOCATE
| OMP_CLAUSE_NOWAIT | OMP_CLAUSE_COPYPRIVATE)
\
4256 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
4257 | OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_COPYPRIVATE)
4258#define OMP_ORDERED_CLAUSES(omp_mask (OMP_CLAUSE_THREADS) | OMP_CLAUSE_SIMD) \
4259 (omp_mask (OMP_CLAUSE_THREADS) | OMP_CLAUSE_SIMD)
4260#define OMP_DECLARE_TARGET_CLAUSES(omp_mask (OMP_CLAUSE_ENTER) | OMP_CLAUSE_LINK | OMP_CLAUSE_DEVICE_TYPE
| OMP_CLAUSE_TO)
\
4261 (omp_mask (OMP_CLAUSE_ENTER) | OMP_CLAUSE_LINK | OMP_CLAUSE_DEVICE_TYPE \
4262 | OMP_CLAUSE_TO)
4263#define OMP_ATOMIC_CLAUSES(omp_mask (OMP_CLAUSE_ATOMIC) | OMP_CLAUSE_CAPTURE | OMP_CLAUSE_HINT
| OMP_CLAUSE_MEMORDER | OMP_CLAUSE_COMPARE | OMP_CLAUSE_FAIL
| OMP_CLAUSE_WEAK)
\
4264 (omp_mask (OMP_CLAUSE_ATOMIC) | OMP_CLAUSE_CAPTURE | OMP_CLAUSE_HINT \
4265 | OMP_CLAUSE_MEMORDER | OMP_CLAUSE_COMPARE | OMP_CLAUSE_FAIL \
4266 | OMP_CLAUSE_WEAK)
4267#define OMP_MASKED_CLAUSES(omp_mask (OMP_CLAUSE_FILTER)) \
4268 (omp_mask (OMP_CLAUSE_FILTER))
4269#define OMP_ERROR_CLAUSES(omp_mask (OMP_CLAUSE_AT) | OMP_CLAUSE_MESSAGE | OMP_CLAUSE_SEVERITY
)
\
4270 (omp_mask (OMP_CLAUSE_AT) | OMP_CLAUSE_MESSAGE | OMP_CLAUSE_SEVERITY)
4271#define OMP_WORKSHARE_CLAUSESomp_mask (OMP_CLAUSE_NOWAIT) \
4272 omp_mask (OMP_CLAUSE_NOWAIT)
4273
4274
4275static match
4276match_omp (gfc_exec_op op, const omp_mask mask)
4277{
4278 gfc_omp_clauses *c;
4279 if (gfc_match_omp_clauses (&c, mask, true, true, false, false,
4280 op == EXEC_OMP_TARGET) != MATCH_YES)
4281 return MATCH_ERROR;
4282 new_st.op = op;
4283 new_st.ext.omp_clauses = c;
4284 return MATCH_YES;
4285}
4286
4287
4288match
4289gfc_match_omp_assume (void)
4290{
4291 gfc_omp_clauses *c;
4292 locus loc = gfc_current_locus;
4293 if ((gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_ASSUMPTIONS))
4294 != MATCH_YES)
4295 || (omp_verify_merge_absent_contains (ST_OMP_ASSUME, c->assume, NULL__null,
4296 &loc) != MATCH_YES))
4297 return MATCH_ERROR;
4298 new_st.op = EXEC_OMP_ASSUME;
4299 new_st.ext.omp_clauses = c;
4300 return MATCH_YES;
4301}
4302
4303
4304match
4305gfc_match_omp_assumes (void)
4306{
4307 gfc_omp_clauses *c;
4308 locus loc = gfc_current_locus;
4309 if (!gfc_current_ns->proc_name
4310 || (gfc_current_ns->proc_name->attr.flavor != FL_MODULE
4311 && !gfc_current_ns->proc_name->attr.subroutine
4312 && !gfc_current_ns->proc_name->attr.function))
4313 {
4314 gfc_error ("!$OMP ASSUMES at %C must be in the specification part of a "
4315 "subprogram or module");
4316 return MATCH_ERROR;
4317 }
4318 if ((gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_ASSUMPTIONS))
4319 != MATCH_YES)
4320 || (omp_verify_merge_absent_contains (ST_OMP_ASSUMES, c->assume,
4321 gfc_current_ns->omp_assumes, &loc)
4322 != MATCH_YES))
4323 return MATCH_ERROR;
4324 if (gfc_current_ns->omp_assumes == NULL__null)
4325 {
4326 gfc_current_ns->omp_assumes = c->assume;
4327 c->assume = NULL__null;
4328 }
4329 else if (gfc_current_ns->omp_assumes && c->assume)
4330 {
4331 gfc_current_ns->omp_assumes->no_openmp |= c->assume->no_openmp;
4332 gfc_current_ns->omp_assumes->no_openmp_routines
4333 |= c->assume->no_openmp_routines;
4334 gfc_current_ns->omp_assumes->no_parallelism |= c->assume->no_parallelism;
4335 if (gfc_current_ns->omp_assumes->holds && c->assume->holds)
4336 {
4337 gfc_expr_list *el = gfc_current_ns->omp_assumes->holds;
4338 for ( ; el->next ; el = el->next)
4339 ;
4340 el->next = c->assume->holds;
4341 }
4342 else if (c->assume->holds)
4343 gfc_current_ns->omp_assumes->holds = c->assume->holds;
4344 c->assume->holds = NULL__null;
4345 }
4346 gfc_free_omp_clauses (c);
4347 return MATCH_YES;
4348}
4349
4350
4351match
4352gfc_match_omp_critical (void)
4353{
4354 char n[GFC_MAX_SYMBOL_LEN63+1];
4355 gfc_omp_clauses *c = NULL__null;
4356
4357 if (gfc_match (" ( %n )", n) != MATCH_YES)
4358 n[0] = '\0';
4359
4360 if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_HINT),
4361 /* first = */ n[0] == '\0') != MATCH_YES)
4362 return MATCH_ERROR;
4363
4364 new_st.op = EXEC_OMP_CRITICAL;
4365 new_st.ext.omp_clauses = c;
4366 if (n[0])
4367 c->critical_name = xstrdup (n);
4368 return MATCH_YES;
4369}
4370
4371
4372match
4373gfc_match_omp_end_critical (void)
4374{
4375 char n[GFC_MAX_SYMBOL_LEN63+1];
4376
4377 if (gfc_match (" ( %n )", n) != MATCH_YES)
4378 n[0] = '\0';
4379 if (gfc_match_omp_eos () != MATCH_YES)
4380 {
4381 gfc_error ("Unexpected junk after $OMP CRITICAL statement at %C");
4382 return MATCH_ERROR;
4383 }
4384
4385 new_st.op = EXEC_OMP_END_CRITICAL;
4386 new_st.ext.omp_name = n[0] ? xstrdup (n) : NULL__null;
4387 return MATCH_YES;
4388}
4389
4390/* depobj(depobj) depend(dep-type:loc)|destroy|update(dep-type)
4391 dep-type = in/out/inout/mutexinoutset/depobj/source/sink
4392 depend: !source, !sink
4393 update: !source, !sink, !depobj
4394 locator = exactly one list item .*/
4395match
4396gfc_match_omp_depobj (void)
4397{
4398 gfc_omp_clauses *c = NULL__null;
4399 gfc_expr *depobj;
4400
4401 if (gfc_match (" ( %v ) ", &depobj) != MATCH_YES)
4402 {
4403 gfc_error ("Expected %<( depobj )%> at %C");
4404 return MATCH_ERROR;
4405 }
4406 if (gfc_match ("update ( ") == MATCH_YES)
4407 {
4408 c = gfc_get_omp_clauses ()((gfc_omp_clauses *) xcalloc (1, sizeof (gfc_omp_clauses)));
4409 if (gfc_match ("inoutset )") == MATCH_YES)
4410 c->depobj_update = OMP_DEPEND_INOUTSET;
4411 else if (gfc_match ("inout )") == MATCH_YES)
4412 c->depobj_update = OMP_DEPEND_INOUT;
4413 else if (gfc_match ("in )") == MATCH_YES)
4414 c->depobj_update = OMP_DEPEND_IN;
4415 else if (gfc_match ("out )") == MATCH_YES)
4416 c->depobj_update = OMP_DEPEND_OUT;
4417 else if (gfc_match ("mutexinoutset )") == MATCH_YES)
4418 c->depobj_update = OMP_DEPEND_MUTEXINOUTSET;
4419 else
4420 {
4421 gfc_error ("Expected IN, OUT, INOUT, INOUTSET or MUTEXINOUTSET "
4422 "followed by %<)%> at %C");
4423 goto error;
4424 }
4425 }
4426 else if (gfc_match ("destroy") == MATCH_YES)
4427 {
4428 c = gfc_get_omp_clauses ()((gfc_omp_clauses *) xcalloc (1, sizeof (gfc_omp_clauses)));
4429 c->destroy = true;
4430 }
4431 else if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_DEPEND), true, false)
4432 != MATCH_YES)
4433 goto error;
4434
4435 if (c->depobj_update == OMP_DEPEND_UNSET && !c->destroy)
4436 {
4437 if (!c->doacross_source && !c->lists[OMP_LIST_DEPEND])
4438 {
4439 gfc_error ("Expected DEPEND, UPDATE, or DESTROY clause at %C");
4440 goto error;
4441 }
4442 if (c->lists[OMP_LIST_DEPEND]->u.depend_doacross_op == OMP_DEPEND_DEPOBJ)
4443 {
4444 gfc_error ("DEPEND clause at %L of OMP DEPOBJ construct shall not "
4445 "have dependence-type DEPOBJ",
4446 c->lists[OMP_LIST_DEPEND]
4447 ? &c->lists[OMP_LIST_DEPEND]->where : &gfc_current_locus);
4448 goto error;
4449 }
4450 if (c->lists[OMP_LIST_DEPEND]->next)
4451 {
4452 gfc_error ("DEPEND clause at %L of OMP DEPOBJ construct shall have "
4453 "only a single locator",
4454 &c->lists[OMP_LIST_DEPEND]->next->where);
4455 goto error;
4456 }
4457 }
4458
4459 c->depobj = depobj;
4460 new_st.op = EXEC_OMP_DEPOBJ;
4461 new_st.ext.omp_clauses = c;
4462 return MATCH_YES;
4463
4464error:
4465 gfc_free_expr (depobj);
4466 gfc_free_omp_clauses (c);
4467 return MATCH_ERROR;
4468}
4469
4470match
4471gfc_match_omp_distribute (void)
4472{
4473 return match_omp (EXEC_OMP_DISTRIBUTE, OMP_DISTRIBUTE_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_DIST_SCHEDULE | OMP_CLAUSE_ORDER
| OMP_CLAUSE_ALLOCATE)
);
4474}
4475
4476
4477match
4478gfc_match_omp_distribute_parallel_do (void)
4479{
4480 return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO,
4481 (OMP_DISTRIBUTE_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_DIST_SCHEDULE | OMP_CLAUSE_ORDER
| OMP_CLAUSE_ALLOCATE)
| OMP_PARALLEL_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF |
OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PROC_BIND
| OMP_CLAUSE_ALLOCATE)
4482 | OMP_DO_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ORDER
| OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT)
)
4483 & ~(omp_mask (OMP_CLAUSE_ORDERED)
4484 | OMP_CLAUSE_LINEAR | OMP_CLAUSE_NOWAIT));
4485}
4486
4487
4488match
4489gfc_match_omp_distribute_parallel_do_simd (void)
4490{
4491 return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD,
4492 (OMP_DISTRIBUTE_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_DIST_SCHEDULE | OMP_CLAUSE_ORDER
| OMP_CLAUSE_ALLOCATE)
| OMP_PARALLEL_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF |
OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PROC_BIND
| OMP_CLAUSE_ALLOCATE)
4493 | OMP_DO_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ORDER
| OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT)
| OMP_SIMD_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN | OMP_CLAUSE_LINEAR
| OMP_CLAUSE_ALIGNED | OMP_CLAUSE_SIMDLEN | OMP_CLAUSE_IF | OMP_CLAUSE_ORDER
| OMP_CLAUSE_NOTEMPORAL)
)
4494 & ~(omp_mask (OMP_CLAUSE_ORDERED) | OMP_CLAUSE_NOWAIT));
4495}
4496
4497
4498match
4499gfc_match_omp_distribute_simd (void)
4500{
4501 return match_omp (EXEC_OMP_DISTRIBUTE_SIMD,
4502 OMP_DISTRIBUTE_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_DIST_SCHEDULE | OMP_CLAUSE_ORDER
| OMP_CLAUSE_ALLOCATE)
| OMP_SIMD_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN | OMP_CLAUSE_LINEAR
| OMP_CLAUSE_ALIGNED | OMP_CLAUSE_SIMDLEN | OMP_CLAUSE_IF | OMP_CLAUSE_ORDER
| OMP_CLAUSE_NOTEMPORAL)
);
4503}
4504
4505
4506match
4507gfc_match_omp_do (void)
4508{
4509 return match_omp (EXEC_OMP_DO, OMP_DO_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ORDER
| OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT)
);
4510}
4511
4512
4513match
4514gfc_match_omp_do_simd (void)
4515{
4516 return match_omp (EXEC_OMP_DO_SIMD, OMP_DO_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ORDER
| OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT)
| OMP_SIMD_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN | OMP_CLAUSE_LINEAR
| OMP_CLAUSE_ALIGNED | OMP_CLAUSE_SIMDLEN | OMP_CLAUSE_IF | OMP_CLAUSE_ORDER
| OMP_CLAUSE_NOTEMPORAL)
);
4517}
4518
4519
4520match
4521gfc_match_omp_loop (void)
4522{
4523 return match_omp (EXEC_OMP_LOOP, OMP_LOOP_CLAUSES(omp_mask (OMP_CLAUSE_BIND) | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_ORDER
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION
)
);
4524}
4525
4526
4527match
4528gfc_match_omp_teams_loop (void)
4529{
4530 return match_omp (EXEC_OMP_TEAMS_LOOP, OMP_TEAMS_CLAUSES(omp_mask (OMP_CLAUSE_NUM_TEAMS) | OMP_CLAUSE_THREAD_LIMIT | OMP_CLAUSE_DEFAULT
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE)
| OMP_LOOP_CLAUSES(omp_mask (OMP_CLAUSE_BIND) | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_ORDER
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION
)
);
4531}
4532
4533
4534match
4535gfc_match_omp_target_teams_loop (void)
4536{
4537 return match_omp (EXEC_OMP_TARGET_TEAMS_LOOP,
4538 OMP_TARGET_CLAUSES(omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF
| OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE
| OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP | OMP_CLAUSE_IS_DEVICE_PTR
| OMP_CLAUSE_IN_REDUCTION | OMP_CLAUSE_THREAD_LIMIT | OMP_CLAUSE_ALLOCATE
| OMP_CLAUSE_HAS_DEVICE_ADDR)
| OMP_TEAMS_CLAUSES(omp_mask (OMP_CLAUSE_NUM_TEAMS) | OMP_CLAUSE_THREAD_LIMIT | OMP_CLAUSE_DEFAULT
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE)
| OMP_LOOP_CLAUSES(omp_mask (OMP_CLAUSE_BIND) | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_ORDER
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION
)
);
4539}
4540
4541
4542match
4543gfc_match_omp_parallel_loop (void)
4544{
4545 return match_omp (EXEC_OMP_PARALLEL_LOOP,
4546 OMP_PARALLEL_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF |
OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PROC_BIND
| OMP_CLAUSE_ALLOCATE)
| OMP_LOOP_CLAUSES(omp_mask (OMP_CLAUSE_BIND) | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_ORDER
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION
)
);
4547}
4548
4549
4550match
4551gfc_match_omp_target_parallel_loop (void)
4552{
4553 return match_omp (EXEC_OMP_TARGET_PARALLEL_LOOP,
4554 (OMP_TARGET_CLAUSES(omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF
| OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE
| OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP | OMP_CLAUSE_IS_DEVICE_PTR
| OMP_CLAUSE_IN_REDUCTION | OMP_CLAUSE_THREAD_LIMIT | OMP_CLAUSE_ALLOCATE
| OMP_CLAUSE_HAS_DEVICE_ADDR)
| OMP_PARALLEL_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF |
OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PROC_BIND
| OMP_CLAUSE_ALLOCATE)
4555 | OMP_LOOP_CLAUSES(omp_mask (OMP_CLAUSE_BIND) | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_ORDER
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION
)
));
4556}
4557
4558
4559match
4560gfc_match_omp_error (void)
4561{
4562 locus loc = gfc_current_locus;
4563 match m = match_omp (EXEC_OMP_ERROR, OMP_ERROR_CLAUSES(omp_mask (OMP_CLAUSE_AT) | OMP_CLAUSE_MESSAGE | OMP_CLAUSE_SEVERITY
)
);
4564 if (m != MATCH_YES)
4565 return m;
4566
4567 gfc_omp_clauses *c = new_st.ext.omp_clauses;
4568 if (c->severity == OMP_SEVERITY_UNSET)
4569 c->severity = OMP_SEVERITY_FATAL;
4570 if (new_st.ext.omp_clauses->at == OMP_AT_EXECUTION)
4571 return MATCH_YES;
4572 if (c->message
4573 && (!gfc_resolve_expr (c->message)
4574 || c->message->ts.type != BT_CHARACTER
4575 || c->message->ts.kind != gfc_default_character_kind
4576 || c->message->rank != 0))
4577 {
4578 gfc_error ("MESSAGE clause at %L requires a scalar default-kind "
4579 "CHARACTER expression",
4580 &new_st.ext.omp_clauses->message->where);
4581 return MATCH_ERROR;
4582 }
4583 if (c->message && !gfc_is_constant_expr (c->message))
4584 {
4585 gfc_error ("Constant character expression required in MESSAGE clause "
4586 "at %L", &new_st.ext.omp_clauses->message->where);
4587 return MATCH_ERROR;
4588 }
4589 if (c->message)
4590 {
4591 const char *msg = G_("$OMP ERROR encountered at %L: %s")"$OMP ERROR encountered at %L: %s";
4592 gcc_assert (c->message->expr_type == EXPR_CONSTANT)((void)(!(c->message->expr_type == EXPR_CONSTANT) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/fortran/openmp.cc"
, 4592, __FUNCTION__), 0 : 0))
;
4593 gfc_charlen_t slen = c->message->value.character.length;
4594 int i = gfc_validate_kind (BT_CHARACTER, gfc_default_character_kind,
4595 false);
4596 size_t size = slen * gfc_character_kinds[i].bit_size / 8;
4597 unsigned char *s = XCNEWVAR (unsigned char, size + 1)((unsigned char *) xcalloc (1, (size + 1)));
4598 gfc_encode_character (gfc_default_character_kind, slen,
4599 c->message->value.character.string,
4600 (unsigned char *) s, size);
4601 s[size] = '\0';
4602 if (c->severity == OMP_SEVERITY_WARNING)
4603 gfc_warning_now (0, msg, &loc, s);
4604 else
4605 gfc_error_now (msg, &loc, s);
4606 free (s);
4607 }
4608 else
4609 {
4610 const char *msg = G_("$OMP ERROR encountered at %L")"$OMP ERROR encountered at %L";
4611 if (c->severity == OMP_SEVERITY_WARNING)
4612 gfc_warning_now (0, msg, &loc);
4613 else
4614 gfc_error_now (msg, &loc);
4615 }
4616 return MATCH_YES;
4617}
4618
4619match
4620gfc_match_omp_flush (void)
4621{
4622 gfc_omp_namelist *list = NULL__null;
4623 gfc_omp_clauses *c = NULL__null;
4624 gfc_gobble_whitespace ();
4625 enum gfc_omp_memorder mo = OMP_MEMORDER_UNSET;
4626 if (gfc_match_omp_eos () == MATCH_NO && gfc_peek_ascii_char () != '(')
4627 {
4628 if (gfc_match ("seq_cst") == MATCH_YES)
4629 mo = OMP_MEMORDER_SEQ_CST;
4630 else if (gfc_match ("acq_rel") == MATCH_YES)
4631 mo = OMP_MEMORDER_ACQ_REL;
4632 else if (gfc_match ("release") == MATCH_YES)
4633 mo = OMP_MEMORDER_RELEASE;
4634 else if (gfc_match ("acquire") == MATCH_YES)
4635 mo = OMP_MEMORDER_ACQUIRE;
4636 else
4637 {
4638 gfc_error ("Expected SEQ_CST, AQC_REL, RELEASE, or ACQUIRE at %C");
4639 return MATCH_ERROR;
4640 }
4641 c = gfc_get_omp_clauses ()((gfc_omp_clauses *) xcalloc (1, sizeof (gfc_omp_clauses)));
4642 c->memorder = mo;
4643 }
4644 gfc_match_omp_variable_list (" (", &list, true);
4645 if (list && mo != OMP_MEMORDER_UNSET)
4646 {
4647 gfc_error ("List specified together with memory order clause in FLUSH "
4648 "directive at %C");
4649 gfc_free_omp_namelist (list, false, false);
4650 gfc_free_omp_clauses (c);
4651 return MATCH_ERROR;
4652 }
4653 if (gfc_match_omp_eos () != MATCH_YES)
4654 {
4655 gfc_error ("Unexpected junk after $OMP FLUSH statement at %C");
4656 gfc_free_omp_namelist (list, false, false);
4657 gfc_free_omp_clauses (c);
4658 return MATCH_ERROR;
4659 }
4660 new_st.op = EXEC_OMP_FLUSH;
4661 new_st.ext.omp_namelist = list;
4662 new_st.ext.omp_clauses = c;
4663 return MATCH_YES;
4664}
4665
4666
4667match
4668gfc_match_omp_declare_simd (void)
4669{
4670 locus where = gfc_current_locus;
4671 gfc_symbol *proc_name;
4672 gfc_omp_clauses *c;
4673 gfc_omp_declare_simd *ods;
4674 bool needs_space = false;
4675
4676 switch (gfc_match (" ( "))
4677 {
4678 case MATCH_YES:
4679 if (gfc_match_symbol (&proc_name, /* host assoc = */ true) != MATCH_YES
4680 || gfc_match (" ) ") != MATCH_YES)
4681 return MATCH_ERROR;
4682 break;
4683 case MATCH_NO: proc_name = NULL__null; needs_space = true; break;
4684 case MATCH_ERROR: return MATCH_ERROR;
4685 }
4686
4687 if (gfc_match_omp_clauses (&c, OMP_DECLARE_SIMD_CLAUSES(omp_mask (OMP_CLAUSE_SIMDLEN) | OMP_CLAUSE_LINEAR | OMP_CLAUSE_UNIFORM
| OMP_CLAUSE_ALIGNED | OMP_CLAUSE_INBRANCH | OMP_CLAUSE_NOTINBRANCH
)
, true,
4688 needs_space) != MATCH_YES)
4689 return MATCH_ERROR;
4690
4691 if (gfc_current_ns->is_block_data)
4692 {
4693 gfc_free_omp_clauses (c);
4694 return MATCH_YES;
4695 }
4696
4697 ods = gfc_get_omp_declare_simd ()((gfc_omp_declare_simd *) xcalloc (1, sizeof (gfc_omp_declare_simd
)))
;
4698 ods->where = where;
4699 ods->proc_name = proc_name;
4700 ods->clauses = c;
4701 ods->next = gfc_current_ns->omp_declare_simd;
4702 gfc_current_ns->omp_declare_simd = ods;
4703 return MATCH_YES;
4704}
4705
4706
4707static bool
4708match_udr_expr (gfc_symtree *omp_sym1, gfc_symtree *omp_sym2)
4709{
4710 match m;
4711 locus old_loc = gfc_current_locus;
4712 char sname[GFC_MAX_SYMBOL_LEN63 + 1];
4713 gfc_symbol *sym;
4714 gfc_namespace *ns = gfc_current_ns;
4715 gfc_expr *lvalue = NULL__null, *rvalue = NULL__null;
4716 gfc_symtree *st;
4717 gfc_actual_arglist *arglist;
4718
4719 m = gfc_match (" %v =", &lvalue);
4720 if (m != MATCH_YES)
4721 gfc_current_locus = old_loc;
4722 else
4723 {
4724 m = gfc_match (" %e )", &rvalue);
4725 if (m == MATCH_YES)
4726 {
4727 ns->code = gfc_get_code (EXEC_ASSIGN);
4728 ns->code->expr1 = lvalue;
4729 ns->code->expr2 = rvalue;
4730 ns->code->loc = old_loc;
4731 return true;
4732 }
4733
4734 gfc_current_locus = old_loc;
4735 gfc_free_expr (lvalue);
4736 }
4737
4738 m = gfc_match (" %n", sname);
4739 if (m != MATCH_YES)
4740 return false;
4741
4742 if (strcmp (sname, omp_sym1->name) == 0
4743 || strcmp (sname, omp_sym2->name) == 0)
4744 return false;
4745
4746 gfc_current_ns = ns->parent;
4747 if (gfc_get_ha_sym_tree (sname, &st))
4748 return false;
4749
4750 sym = st->n.sym;
4751 if (sym->attr.flavor != FL_PROCEDURE
4752 && sym->attr.flavor != FL_UNKNOWN)
4753 return false;
4754
4755 if (!sym->attr.generic
4756 && !sym->attr.subroutine
4757 && !sym->attr.function)
4758 {
4759 if (!(sym->attr.external && !sym->attr.referenced))
4760 {
4761 /* ...create a symbol in this scope... */
4762 if (sym->ns != gfc_current_ns
4763 && gfc_get_sym_tree (sname, NULL__null, &st, false) == 1)
4764 return false;
4765
4766 if (sym != st->n.sym)
4767 sym = st->n.sym;
4768 }
4769
4770 /* ...and then to try to make the symbol into a subroutine. */
4771 if (!gfc_add_subroutine (&sym->attr, sym->name, NULL__null))
4772 return false;
4773 }
4774
4775 gfc_set_sym_referenced (sym);
4776 gfc_gobble_whitespace ();
4777 if (gfc_peek_ascii_char () != '(')
4778 return false;
4779
4780 gfc_current_ns = ns;
4781 m = gfc_match_actual_arglist (1, &arglist);
4782 if (m != MATCH_YES)
4783 return false;
4784
4785 if (gfc_match_char (')') != MATCH_YES)
4786 return false;
4787
4788 ns->code = gfc_get_code (EXEC_CALL);
4789 ns->code->symtree = st;
4790 ns->code->ext.actual = arglist;
4791 ns->code->loc = old_loc;
4792 return true;
4793}
4794
4795static bool
4796gfc_omp_udr_predef (gfc_omp_reduction_op rop, const char *name,
4797 gfc_typespec *ts, const char **n)
4798{
4799 if (!gfc_numeric_ts (ts) && ts->type != BT_LOGICAL)
4800 return false;
4801
4802 switch (rop)
4803 {
4804 case OMP_REDUCTION_PLUS:
4805 case OMP_REDUCTION_MINUS:
4806 case OMP_REDUCTION_TIMES:
4807 return ts->type != BT_LOGICAL;
4808 case OMP_REDUCTION_AND:
4809 case OMP_REDUCTION_OR:
4810 case OMP_REDUCTION_EQV:
4811 case OMP_REDUCTION_NEQV:
4812 return ts->type == BT_LOGICAL;
4813 case OMP_REDUCTION_USER:
4814 if (name[0] != '.' && (ts->type == BT_INTEGER || ts->type == BT_REAL))
4815 {
4816 gfc_symbol *sym;
4817
4818 gfc_find_symbol (name, NULL__null, 1, &sym);
4819 if (sym != NULL__null)
4820 {
4821 if (sym->attr.intrinsic)
4822 *n = sym->name;
4823 else if ((sym->attr.flavor != FL_UNKNOWN
4824 && sym->attr.flavor != FL_PROCEDURE)
4825 || sym->attr.external
4826 || sym->attr.generic
4827 || sym->attr.entry
4828 || sym->attr.result
4829 || sym->attr.dummy
4830 || sym->attr.subroutine
4831 || sym->attr.pointer
4832 || sym->attr.target
4833 || sym->attr.cray_pointer
4834 || sym->attr.cray_pointee
4835 || (sym->attr.proc != PROC_UNKNOWN
4836 && sym->attr.proc != PROC_INTRINSIC)
4837 || sym->attr.if_source != IFSRC_UNKNOWN
4838 || sym == sym->ns->proc_name)
4839 *n = NULL__null;
4840 else
4841 *n = sym->name;
4842 }
4843 else
4844 *n = name;
4845 if (*n
4846 && (strcmp (*n, "max") == 0 || strcmp (*n, "min") == 0))
4847 return true;
4848 else if (*n
4849 && ts->type == BT_INTEGER
4850 && (strcmp (*n, "iand") == 0
4851 || strcmp (*n, "ior") == 0
4852 || strcmp (*n, "ieor") == 0))
4853 return true;
4854 }
4855 break;
4856 default:
4857 break;
4858 }
4859 return false;
4860}
4861
4862gfc_omp_udr *
4863gfc_omp_udr_find (gfc_symtree *st, gfc_typespec *ts)
4864{
4865 gfc_omp_udr *omp_udr;
4866
4867 if (st == NULL__null)
4868 return NULL__null;
4869
4870 for (omp_udr = st->n.omp_udr; omp_udr; omp_udr = omp_udr->next)
4871 if (omp_udr->ts.type == ts->type
4872 || ((omp_udr->ts.type == BT_DERIVED || omp_udr->ts.type == BT_CLASS)
4873 && (ts->type == BT_DERIVED || ts->type == BT_CLASS)))
4874 {
4875 if (omp_udr->ts.type == BT_DERIVED || omp_udr->ts.type == BT_CLASS)
4876 {
4877 if (strcmp (omp_udr->ts.u.derived->name, ts->u.derived->name) == 0)
4878 return omp_udr;
4879 }
4880 else if (omp_udr->ts.kind == ts->kind)
4881 {
4882 if (omp_udr->ts.type == BT_CHARACTER)
4883 {
4884 if (omp_udr->ts.u.cl->length == NULL__null
4885 || ts->u.cl->length == NULL__null)
4886 return omp_udr;
4887 if (omp_udr->ts.u.cl->length->expr_type != EXPR_CONSTANT)
4888 return omp_udr;
4889 if (ts->u.cl->length->expr_type != EXPR_CONSTANT)
4890 return omp_udr;
4891 if (omp_udr->ts.u.cl->length->ts.type != BT_INTEGER)
4892 return omp_udr;
4893 if (ts->u.cl->length->ts.type != BT_INTEGER)
4894 return omp_udr;
4895 if (gfc_compare_expr (omp_udr->ts.u.cl->length,
4896 ts->u.cl->length, INTRINSIC_EQ) != 0)
4897 continue;
4898 }
4899 return omp_udr;
4900 }
4901 }
4902 return NULL__null;
4903}
4904
4905match
4906gfc_match_omp_declare_reduction (void)
4907{
4908 match m;
4909 gfc_intrinsic_op op;
4910 char name[GFC_MAX_SYMBOL_LEN63 + 3];
4911 auto_vec<gfc_typespec, 5> tss;
4912 gfc_typespec ts;
4913 unsigned int i;
4914 gfc_symtree *st;
4915 locus where = gfc_current_locus;
4916 locus end_loc = gfc_current_locus;
4917 bool end_loc_set = false;
4918 gfc_omp_reduction_op rop = OMP_REDUCTION_NONE;
4919
4920 if (gfc_match_char ('(') != MATCH_YES)
4921 return MATCH_ERROR;
4922
4923 m = gfc_match (" %o : ", &op);
4924 if (m == MATCH_ERROR)
4925 return MATCH_ERROR;
4926 if (m == MATCH_YES)
4927 {
4928 snprintf (name, sizeof name, "operator %s", gfc_op2string (op));
4929 rop = (gfc_omp_reduction_op) op;
4930 }
4931 else
4932 {
4933 m = gfc_match_defined_op_name (name + 1, 1);
4934 if (m == MATCH_ERROR)
4935 return MATCH_ERROR;
4936 if (m == MATCH_YES)
4937 {
4938 name[0] = '.';
4939 strcat (name, ".");
4940 if (gfc_match (" : ") != MATCH_YES)
4941 return MATCH_ERROR;
4942 }
4943 else
4944 {
4945 if (gfc_match (" %n : ", name) != MATCH_YES)
4946 return MATCH_ERROR;
4947 }
4948 rop = OMP_REDUCTION_USER;
4949 }
4950
4951 m = gfc_match_type_spec (&ts);
4952 if (m != MATCH_YES)
4953 return MATCH_ERROR;
4954 /* Treat len=: the same as len=*. */
4955 if (ts.type == BT_CHARACTER)
4956 ts.deferred = false;
4957 tss.safe_push (ts);
4958
4959 while (gfc_match_char (',') == MATCH_YES)
4960 {
4961 m = gfc_match_type_spec (&ts);
4962 if (m != MATCH_YES)
4963 return MATCH_ERROR;
4964 tss.safe_push (ts);
4965 }
4966 if (gfc_match_char (':') != MATCH_YES)
4967 return MATCH_ERROR;
4968
4969 st = gfc_find_symtree (gfc_current_ns->omp_udr_root, name);
4970 for (i = 0; i < tss.length (); i++)
4971 {
4972 gfc_symtree *omp_out, *omp_in;
4973 gfc_symtree *omp_priv = NULL__null, *omp_orig = NULL__null;
4974 gfc_namespace *combiner_ns, *initializer_ns = NULL__null;
4975 gfc_omp_udr *prev_udr, *omp_udr;
4976 const char *predef_name = NULL__null;
4977
4978 omp_udr = gfc_get_omp_udr ()((gfc_omp_udr *) xcalloc (1, sizeof (gfc_omp_udr)));
4979 omp_udr->name = gfc_get_string ("%s", name);
4980 omp_udr->rop = rop;
4981 omp_udr->ts = tss[i];
4982 omp_udr->where = where;
4983
4984 gfc_current_ns = combiner_ns = gfc_get_namespace (gfc_current_ns, 1);
4985 combiner_ns->proc_name = combiner_ns->parent->proc_name;
4986
4987 gfc_get_sym_tree ("omp_out", combiner_ns, &omp_out, false);
4988 gfc_get_sym_tree ("omp_in", combiner_ns, &omp_in, false);
4989 combiner_ns->omp_udr_ns = 1;
4990 omp_out->n.sym->ts = tss[i];
4991 omp_in->n.sym->ts = tss[i];
4992 omp_out->n.sym->attr.omp_udr_artificial_var = 1;
4993 omp_in->n.sym->attr.omp_udr_artificial_var = 1;
4994 omp_out->n.sym->attr.flavor = FL_VARIABLE;
4995 omp_in->n.sym->attr.flavor = FL_VARIABLE;
4996 gfc_commit_symbols ();
4997 omp_udr->combiner_ns = combiner_ns;
4998 omp_udr->omp_out = omp_out->n.sym;
4999 omp_udr->omp_in = omp_in->n.sym;
5000
5001 locus old_loc = gfc_current_locus;
5002
5003 if (!match_udr_expr (omp_out, omp_in))
5004 {
5005 syntax:
5006 gfc_current_locus = old_loc;
5007 gfc_current_ns = combiner_ns->parent;
5008 gfc_undo_symbols ();
5009 gfc_free_omp_udr (omp_udr);
5010 return MATCH_ERROR;
5011 }
5012
5013 if (gfc_match (" initializer ( ") == MATCH_YES)
5014 {
5015 gfc_current_ns = combiner_ns->parent;
5016 initializer_ns = gfc_get_namespace (gfc_current_ns, 1);
5017 gfc_current_ns = initializer_ns;
5018 initializer_ns->proc_name = initializer_ns->parent->proc_name;
5019
5020 gfc_get_sym_tree ("omp_priv", initializer_ns, &omp_priv, false);
5021 gfc_get_sym_tree ("omp_orig", initializer_ns, &omp_orig, false);
5022 initializer_ns->omp_udr_ns = 1;
5023 omp_priv->n.sym->ts = tss[i];
5024 omp_orig->n.sym->ts = tss[i];
5025 omp_priv->n.sym->attr.omp_udr_artificial_var = 1;
5026 omp_orig->n.sym->attr.omp_udr_artificial_var = 1;
5027 omp_priv->n.sym->attr.flavor = FL_VARIABLE;
5028 omp_orig->n.sym->attr.flavor = FL_VARIABLE;
5029 gfc_commit_symbols ();
5030 omp_udr->initializer_ns = initializer_ns;
5031 omp_udr->omp_priv = omp_priv->n.sym;
5032 omp_udr->omp_orig = omp_orig->n.sym;
5033
5034 if (!match_udr_expr (omp_priv, omp_orig))
5035 goto syntax;
5036 }
5037
5038 gfc_current_ns = combiner_ns->parent;
5039 if (!end_loc_set)
5040 {
5041 end_loc_set = true;
5042 end_loc = gfc_current_locus;
5043 }
5044 gfc_current_locus = old_loc;
5045
5046 prev_udr = gfc_omp_udr_find (st, &tss[i]);
5047 if (gfc_omp_udr_predef (rop, name, &tss[i], &predef_name)
5048 /* Don't error on !$omp declare reduction (min : integer : ...)
5049 just yet, there could be integer :: min afterwards,
5050 making it valid. When the UDR is resolved, we'll get
5051 to it again. */
5052 && (rop != OMP_REDUCTION_USER || name[0] == '.'))
5053 {
5054 if (predef_name)
5055 gfc_error_now ("Redefinition of predefined %s "
5056 "!$OMP DECLARE REDUCTION at %L",
5057 predef_name, &where);
5058 else
5059 gfc_error_now ("Redefinition of predefined "
5060 "!$OMP DECLARE REDUCTION at %L", &where);
5061 }
5062 else if (prev_udr)
5063 {
5064 gfc_error_now ("Redefinition of !$OMP DECLARE REDUCTION at %L",
5065 &where);
5066 gfc_error_now ("Previous !$OMP DECLARE REDUCTION at %L",
5067 &prev_udr->where);
5068 }
5069 else if (st)
5070 {
5071 omp_udr->next = st->n.omp_udr;
5072 st->n.omp_udr = omp_udr;
5073 }
5074 else
5075 {
5076 st = gfc_new_symtree (&gfc_current_ns->omp_udr_root, name);
5077 st->n.omp_udr = omp_udr;
5078 }
5079 }
5080
5081 if (end_loc_set)
5082 {
5083 gfc_current_locus = end_loc;
5084 if (gfc_match_omp_eos () != MATCH_YES)
5085 {
5086 gfc_error ("Unexpected junk after !$OMP DECLARE REDUCTION at %C");
5087 gfc_current_locus = where;
5088 return MATCH_ERROR;
5089 }
5090
5091 return MATCH_YES;
5092 }
5093 gfc_clear_error ();
5094 return MATCH_ERROR;
5095}
5096
5097
5098match
5099gfc_match_omp_declare_target (void)
5100{
5101 locus old_loc;
5102 match m;
5103 gfc_omp_clauses *c = NULL__null;
5104 int list;
5105 gfc_omp_namelist *n;
5106 gfc_symbol *s;
5107
5108 old_loc = gfc_current_locus;
5109
5110 if (gfc_current_ns->proc_name
5111 && gfc_match_omp_eos () == MATCH_YES)
5112 {
5113 if (!gfc_add_omp_declare_target (&gfc_current_ns->proc_name->attr,
5114 gfc_current_ns->proc_name->name,
5115 &old_loc))
5116 goto cleanup;
5117 return MATCH_YES;
5118 }
5119
5120 if (gfc_current_ns->proc_name
5121 && gfc_current_ns->proc_name->attr.if_source == IFSRC_IFBODY)
5122 {
5123 gfc_error ("Only the !$OMP DECLARE TARGET form without "
5124 "clauses is allowed in interface block at %C");
5125 goto cleanup;
5126 }
5127
5128 m = gfc_match (" (");
5129 if (m == MATCH_YES)
5130 {
5131 c = gfc_get_omp_clauses ()((gfc_omp_clauses *) xcalloc (1, sizeof (gfc_omp_clauses)));
5132 gfc_current_locus = old_loc;
5133 m = gfc_match_omp_to_link (" (", &c->lists[OMP_LIST_ENTER]);
5134 if (m != MATCH_YES)
5135 goto syntax;
5136 if (gfc_match_omp_eos () != MATCH_YES)
5137 {
5138 gfc_error ("Unexpected junk after !$OMP DECLARE TARGET at %C");
5139 goto cleanup;
5140 }
5141 }
5142 else if (gfc_match_omp_clauses (&c, OMP_DECLARE_TARGET_CLAUSES(omp_mask (OMP_CLAUSE_ENTER) | OMP_CLAUSE_LINK | OMP_CLAUSE_DEVICE_TYPE
| OMP_CLAUSE_TO)
) != MATCH_YES)
5143 return MATCH_ERROR;
5144
5145 gfc_buffer_error (false);
5146
5147 static const int to_enter_link_lists[]
5148 = { OMP_LIST_TO, OMP_LIST_ENTER, OMP_LIST_LINK };
5149 for (size_t listn = 0; listn < ARRAY_SIZE (to_enter_link_lists)(sizeof (to_enter_link_lists) / sizeof ((to_enter_link_lists)
[0]))
5150 && (list = to_enter_link_lists[listn], true); ++listn)
5151 for (n = c->lists[list]; n; n = n->next)
5152 if (n->sym)
5153 n->sym->mark = 0;
5154 else if (n->u.common->head)
5155 n->u.common->head->mark = 0;
5156
5157 for (size_t listn = 0; listn < ARRAY_SIZE (to_enter_link_lists)(sizeof (to_enter_link_lists) / sizeof ((to_enter_link_lists)
[0]))
5158 && (list = to_enter_link_lists[listn], true); ++listn)
5159 for (n = c->lists[list]; n; n = n->next)
5160 if (n->sym)
5161 {
5162 if (n->sym->attr.in_common)
5163 gfc_error_now ("OMP DECLARE TARGET variable at %L is an "
5164 "element of a COMMON block", &n->where);
5165 else if (n->sym->mark)
5166 gfc_error_now ("Variable at %L mentioned multiple times in "
5167 "clauses of the same OMP DECLARE TARGET directive",
5168 &n->where);
5169 else if (n->sym->attr.omp_declare_target
5170 && n->sym->attr.omp_declare_target_link
5171 && list != OMP_LIST_LINK)
5172 gfc_error_now ("OMP DECLARE TARGET variable at %L previously "
5173 "mentioned in LINK clause and later in %s clause",
5174 &n->where, list == OMP_LIST_TO ? "TO" : "ENTER");
5175 else if (n->sym->attr.omp_declare_target
5176 && !n->sym->attr.omp_declare_target_link
5177 && list == OMP_LIST_LINK)
5178 gfc_error_now ("OMP DECLARE TARGET variable at %L previously "
5179 "mentioned in TO or ENTER clause and later in "
5180 "LINK clause", &n->where);
5181 else if (gfc_add_omp_declare_target (&n->sym->attr, n->sym->name,
5182 &n->sym->declared_at))
5183 {
5184 if (list == OMP_LIST_LINK)
5185 gfc_add_omp_declare_target_link (&n->sym->attr, n->sym->name,
5186 &n->sym->declared_at);
5187 }
5188 if (c->device_type != OMP_DEVICE_TYPE_UNSET)
5189 {
5190 if (n->sym->attr.omp_device_type != OMP_DEVICE_TYPE_UNSET
5191 && n->sym->attr.omp_device_type != c->device_type)
5192 gfc_error_now ("List item %qs at %L set in previous OMP DECLARE "
5193 "TARGET directive to a different DEVICE_TYPE",
5194 n->sym->name, &n->where);
5195 n->sym->attr.omp_device_type = c->device_type;
5196 }
5197 n->sym->mark = 1;
5198 }
5199 else if (n->u.common->omp_declare_target
5200 && n->u.common->omp_declare_target_link
5201 && list != OMP_LIST_LINK)
5202 gfc_error_now ("OMP DECLARE TARGET COMMON at %L previously "
5203 "mentioned in LINK clause and later in %s clause",
5204 &n->where, list == OMP_LIST_TO ? "TO" : "ENTER");
5205 else if (n->u.common->omp_declare_target
5206 && !n->u.common->omp_declare_target_link
5207 && list == OMP_LIST_LINK)
5208 gfc_error_now ("OMP DECLARE TARGET COMMON at %L previously "
5209 "mentioned in TO or ENTER clause and later in "
5210 "LINK clause", &n->where);
5211 else if (n->u.common->head && n->u.common->head->mark)
5212 gfc_error_now ("COMMON at %L mentioned multiple times in "
5213 "clauses of the same OMP DECLARE TARGET directive",
5214 &n->where);
5215 else
5216 {
5217 n->u.common->omp_declare_target = 1;
5218 n->u.common->omp_declare_target_link = (list == OMP_LIST_LINK);
5219 if (n->u.common->omp_device_type != OMP_DEVICE_TYPE_UNSET
5220 && n->u.common->omp_device_type != c->device_type)
5221 gfc_error_now ("COMMON at %L set in previous OMP DECLARE "
5222 "TARGET directive to a different DEVICE_TYPE",
5223 &n->where);
5224 n->u.common->omp_device_type = c->device_type;
5225
5226 for (s = n->u.common->head; s; s = s->common_next)
5227 {
5228 s->mark = 1;
5229 if (gfc_add_omp_declare_target (&s->attr, s->name,
5230 &s->declared_at))
5231 {
5232 if (list == OMP_LIST_LINK)
5233 gfc_add_omp_declare_target_link (&s->attr, s->name,
5234 &s->declared_at);
5235 }
5236 if (s->attr.omp_device_type != OMP_DEVICE_TYPE_UNSET
5237 && s->attr.omp_device_type != c->device_type)
5238 gfc_error_now ("List item %qs at %L set in previous OMP DECLARE"
5239 " TARGET directive to a different DEVICE_TYPE",
5240 s->name, &n->where);
5241 s->attr.omp_device_type = c->device_type;
5242 }
5243 }
5244 if (c->device_type
5245 && !c->lists[OMP_LIST_ENTER]
5246 && !c->lists[OMP_LIST_TO]
5247 && !c->lists[OMP_LIST_LINK])
5248 gfc_warning_now (0, "OMP DECLARE TARGET directive at %L with only "
5249 "DEVICE_TYPE clause is ignored", &old_loc);
5250
5251 gfc_buffer_error (true);
5252
5253 if (c)
5254 gfc_free_omp_clauses (c);
5255 return MATCH_YES;
5256
5257syntax:
5258 gfc_error ("Syntax error in !$OMP DECLARE TARGET list at %C");
5259
5260cleanup:
5261 gfc_current_locus = old_loc;
5262 if (c)
5263 gfc_free_omp_clauses (c);
5264 return MATCH_ERROR;
5265}
5266
5267
5268static const char *const omp_construct_selectors[] = {
5269 "simd", "target", "teams", "parallel", "do", NULL__null };
5270static const char *const omp_device_selectors[] = {
5271 "kind", "isa", "arch", NULL__null };
5272static const char *const omp_implementation_selectors[] = {
5273 "vendor", "extension", "atomic_default_mem_order", "unified_address",
5274 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL__null };
5275static const char *const omp_user_selectors[] = {
5276 "condition", NULL__null };
5277
5278
5279/* OpenMP 5.0:
5280
5281 trait-selector:
5282 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
5283
5284 trait-score:
5285 score(score-expression) */
5286
5287match
5288gfc_match_omp_context_selector (gfc_omp_set_selector *oss)
5289{
5290 do
5291 {
5292 char selector[GFC_MAX_SYMBOL_LEN63 + 1];
5293
5294 if (gfc_match_name (selector) != MATCH_YES)
5295 {
5296 gfc_error ("expected trait selector name at %C");
5297 return MATCH_ERROR;
5298 }
5299
5300 gfc_omp_selector *os = gfc_get_omp_selector ()((gfc_omp_selector *) xcalloc (1, sizeof (gfc_omp_selector)));
5301 os->trait_selector_name = XNEWVEC (char, strlen (selector) + 1)((char *) xmalloc (sizeof (char) * (strlen (selector) + 1)));
5302 strcpy (os->trait_selector_name, selector);
5303 os->next = oss->trait_selectors;
5304 oss->trait_selectors = os;
5305
5306 const char *const *selectors = NULL__null;
5307 bool allow_score = true;
5308 bool allow_user = false;
5309 int property_limit = 0;
5310 enum gfc_omp_trait_property_kind property_kind = CTX_PROPERTY_NONE;
5311 switch (oss->trait_set_selector_name[0])
5312 {
5313 case 'c': /* construct */
5314 selectors = omp_construct_selectors;
5315 allow_score = false;
5316 property_limit = 1;
5317 property_kind = CTX_PROPERTY_SIMD;
5318 break;
5319 case 'd': /* device */
5320 selectors = omp_device_selectors;
5321 allow_score = false;
5322 allow_user = true;
5323 property_limit = 3;
5324 property_kind = CTX_PROPERTY_NAME_LIST;
5325 break;
5326 case 'i': /* implementation */
5327 selectors = omp_implementation_selectors;
5328 allow_user = true;
5329 property_limit = 3;
5330 property_kind = CTX_PROPERTY_NAME_LIST;
5331 break;
5332 case 'u': /* user */
5333 selectors = omp_user_selectors;
5334 property_limit = 1;
5335 property_kind = CTX_PROPERTY_EXPR;
5336 break;
5337 default:
5338 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/fortran/openmp.cc"
, 5338, __FUNCTION__))
;
5339 }
5340 for (int i = 0; ; i++)
5341 {
5342 if (selectors[i] == NULL__null)
5343 {
5344 if (allow_user)
5345 {
5346 property_kind = CTX_PROPERTY_USER;
5347 break;
5348 }
5349 else
5350 {
5351 gfc_error ("selector %qs not allowed for context selector "
5352 "set %qs at %C",
5353 selector, oss->trait_set_selector_name);
5354 return MATCH_ERROR;
5355 }
5356 }
5357 if (i == property_limit)
5358 property_kind = CTX_PROPERTY_NONE;
5359 if (strcmp (selectors[i], selector) == 0)
5360 break;
5361 }
5362 if (property_kind == CTX_PROPERTY_NAME_LIST
5363 && oss->trait_set_selector_name[0] == 'i'
5364 && strcmp (selector, "atomic_default_mem_order") == 0)
5365 property_kind = CTX_PROPERTY_ID;
5366
5367 if (gfc_match (" (") == MATCH_YES)
5368 {
5369 if (property_kind == CTX_PROPERTY_NONE)
5370 {
5371 gfc_error ("selector %qs does not accept any properties at %C",
5372 selector);
5373 return MATCH_ERROR;
5374 }
5375
5376 if (allow_score && gfc_match (" score") == MATCH_YES)
5377 {
5378 if (gfc_match (" (") != MATCH_YES)
5379 {
5380 gfc_error ("expected %<(%> at %C");
5381 return MATCH_ERROR;
5382 }
5383 if (gfc_match_expr (&os->score) != MATCH_YES
5384 || !gfc_resolve_expr (os->score)
5385 || os->score->ts.type != BT_INTEGER
5386 || os->score->rank != 0)
5387 {
5388 gfc_error ("score argument must be constant integer "
5389 "expression at %C");
5390 return MATCH_ERROR;
5391 }
5392
5393 if (os->score->expr_type == EXPR_CONSTANT
5394 && mpz_sgn (os->score->value.integer)((os->score->value.integer)->_mp_size < 0 ? -1 : (
os->score->value.integer)->_mp_size > 0)
< 0)
5395 {
5396 gfc_error ("score argument must be non-negative at %C");
5397 return MATCH_ERROR;
5398 }
5399
5400 if (gfc_match (" )") != MATCH_YES)
5401 {
5402 gfc_error ("expected %<)%> at %C");
5403 return MATCH_ERROR;
5404 }
5405
5406 if (gfc_match (" :") != MATCH_YES)
5407 {
5408 gfc_error ("expected : at %C");
5409 return MATCH_ERROR;
5410 }
5411 }
5412
5413 gfc_omp_trait_property *otp = gfc_get_omp_trait_property ()((gfc_omp_trait_property *) xcalloc (1, sizeof (gfc_omp_trait_property
)))
;
5414 otp->property_kind = property_kind;
5415 otp->next = os->properties;
5416 os->properties = otp;
5417
5418 switch (property_kind)
5419 {
5420 case CTX_PROPERTY_USER:
5421 do
5422 {
5423 if (gfc_match_expr (&otp->expr) != MATCH_YES)
5424 {
5425 gfc_error ("property must be constant integer "
5426 "expression or string literal at %C");
5427 return MATCH_ERROR;
5428 }
5429
5430 if (gfc_match (" ,") != MATCH_YES)
5431 break;
5432 }
5433 while (1);
5434 break;
5435 case CTX_PROPERTY_ID:
5436 {
5437 char buf[GFC_MAX_SYMBOL_LEN63 + 1];
5438 if (gfc_match_name (buf) == MATCH_YES)
5439 {
5440 otp->name = XNEWVEC (char, strlen (buf) + 1)((char *) xmalloc (sizeof (char) * (strlen (buf) + 1)));
5441 strcpy (otp->name, buf);
5442 }
5443 else
5444 {
5445 gfc_error ("expected identifier at %C");
5446 return MATCH_ERROR;
5447 }
5448 }
5449 break;
5450 case CTX_PROPERTY_NAME_LIST:
5451 do
5452 {
5453 char buf[GFC_MAX_SYMBOL_LEN63 + 1];
5454 if (gfc_match_name (buf) == MATCH_YES)
5455 {
5456 otp->name = XNEWVEC (char, strlen (buf) + 1)((char *) xmalloc (sizeof (char) * (strlen (buf) + 1)));
5457 strcpy (otp->name, buf);
5458 otp->is_name = true;
5459 }
5460 else if (gfc_match_literal_constant (&otp->expr, 0)
5461 != MATCH_YES
5462 || otp->expr->ts.type != BT_CHARACTER)
5463 {
5464 gfc_error ("expected identifier or string literal "
5465 "at %C");
5466 return MATCH_ERROR;
5467 }
5468
5469 if (gfc_match (" ,") == MATCH_YES)
5470 {
5471 otp = gfc_get_omp_trait_property ()((gfc_omp_trait_property *) xcalloc (1, sizeof (gfc_omp_trait_property
)))
;
5472 otp->property_kind = property_kind;
5473 otp->next = os->properties;
5474 os->properties = otp;
5475 }
5476 else
5477 break;
5478 }
5479 while (1);
5480 break;
5481 case CTX_PROPERTY_EXPR:
5482 if (gfc_match_expr (&otp->expr) != MATCH_YES)
5483 {
5484 gfc_error ("expected expression at %C");
5485 return MATCH_ERROR;
5486 }
5487 if (!gfc_resolve_expr (otp->expr)
5488 || (otp->expr->ts.type != BT_LOGICAL
5489 && otp->expr->ts.type != BT_INTEGER)
5490 || otp->expr->rank != 0)
5491 {
5492 gfc_error ("property must be constant integer or logical "
5493 "expression at %C");
5494 return MATCH_ERROR;
5495 }
5496 break;
5497 case CTX_PROPERTY_SIMD:
5498 {
5499 if (gfc_match_omp_clauses (&otp->clauses,
5500 OMP_DECLARE_SIMD_CLAUSES(omp_mask (OMP_CLAUSE_SIMDLEN) | OMP_CLAUSE_LINEAR | OMP_CLAUSE_UNIFORM
| OMP_CLAUSE_ALIGNED | OMP_CLAUSE_INBRANCH | OMP_CLAUSE_NOTINBRANCH
)
,
5501 true, false, false, true)
5502 != MATCH_YES)
5503 {
5504 gfc_error ("expected simd clause at %C");
5505 return MATCH_ERROR;
5506 }
5507 break;
5508 }
5509 default:
5510 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/fortran/openmp.cc"
, 5510, __FUNCTION__))
;
5511 }
5512
5513 if (gfc_match (" )") != MATCH_YES)
5514 {
5515 gfc_error ("expected %<)%> at %C");
5516 return MATCH_ERROR;
5517 }
5518 }
5519 else if (property_kind == CTX_PROPERTY_NAME_LIST
5520 || property_kind == CTX_PROPERTY_ID
5521 || property_kind == CTX_PROPERTY_EXPR)
5522 {
5523 if (gfc_match (" (") != MATCH_YES)
5524 {
5525 gfc_error ("expected %<(%> at %C");
5526 return MATCH_ERROR;
5527 }
5528 }
5529
5530 if (gfc_match (" ,") != MATCH_YES)
5531 break;
5532 }
5533 while (1);
5534
5535 return MATCH_YES;
5536}
5537
5538/* OpenMP 5.0:
5539
5540 trait-set-selector[,trait-set-selector[,...]]
5541
5542 trait-set-selector:
5543 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
5544
5545 trait-set-selector-name:
5546 constructor
5547 device
5548 implementation
5549 user */
5550
5551match
5552gfc_match_omp_context_selector_specification (gfc_omp_declare_variant *odv)
5553{
5554 do
5555 {
5556 match m;
5557 const char *selector_sets[] = { "construct", "device",
5558 "implementation", "user" };
5559 const int selector_set_count = ARRAY_SIZE (selector_sets)(sizeof (selector_sets) / sizeof ((selector_sets)[0]));
5560 int i;
5561 char buf[GFC_MAX_SYMBOL_LEN63 + 1];
5562
5563 m = gfc_match_name (buf);
5564 if (m == MATCH_YES)
5565 for (i = 0; i < selector_set_count; i++)
5566 if (strcmp (buf, selector_sets[i]) == 0)
5567 break;
5568
5569 if (m != MATCH_YES || i == selector_set_count)
5570 {
5571 gfc_error ("expected %<construct%>, %<device%>, %<implementation%> "
5572 "or %<user%> at %C");
5573 return MATCH_ERROR;
5574 }
5575
5576 m = gfc_match (" =");
5577 if (m != MATCH_YES)
5578 {
5579 gfc_error ("expected %<=%> at %C");
5580 return MATCH_ERROR;
5581 }
5582
5583 m = gfc_match (" {");
5584 if (m != MATCH_YES)
5585 {
5586 gfc_error ("expected %<{%> at %C");
5587 return MATCH_ERROR;
5588 }
5589
5590 gfc_omp_set_selector *oss = gfc_get_omp_set_selector ()((gfc_omp_set_selector *) xcalloc (1, sizeof (gfc_omp_set_selector
)))
;
5591 oss->next = odv->set_selectors;
5592 oss->trait_set_selector_name = selector_sets[i];
5593 odv->set_selectors = oss;
5594
5595 if (gfc_match_omp_context_selector (oss) != MATCH_YES)
5596 return MATCH_ERROR;
5597
5598 m = gfc_match (" }");
5599 if (m != MATCH_YES)
5600 {
5601 gfc_error ("expected %<}%> at %C");
5602 return MATCH_ERROR;
5603 }
5604
5605 m = gfc_match (" ,");
5606 if (m != MATCH_YES)
5607 break;
5608 }
5609 while (1);
5610
5611 return MATCH_YES;
5612}
5613
5614
5615match
5616gfc_match_omp_declare_variant (void)
5617{
5618 bool first_p = true;
5619 char buf[GFC_MAX_SYMBOL_LEN63 + 1];
5620
5621 if (gfc_match (" (") != MATCH_YES)
5622 {
5623 gfc_error ("expected %<(%> at %C");
5624 return MATCH_ERROR;
5625 }
5626
5627 gfc_symtree *base_proc_st, *variant_proc_st;
5628 if (gfc_match_name (buf) != MATCH_YES)
5629 {
5630 gfc_error ("expected name at %C");
5631 return MATCH_ERROR;
5632 }
5633
5634 if (gfc_get_ha_sym_tree (buf, &base_proc_st))
5635 return MATCH_ERROR;
5636
5637 if (gfc_match (" :") == MATCH_YES)
5638 {
5639 if (gfc_match_name (buf) != MATCH_YES)
5640 {
5641 gfc_error ("expected variant name at %C");
5642 return MATCH_ERROR;
5643 }
5644
5645 if (gfc_get_ha_sym_tree (buf, &variant_proc_st))
5646 return MATCH_ERROR;
5647 }
5648 else
5649 {
5650 /* Base procedure not specified. */
5651 variant_proc_st = base_proc_st;
5652 base_proc_st = NULL__null;
5653 }
5654
5655 gfc_omp_declare_variant *odv;
5656 odv = gfc_get_omp_declare_variant ()((gfc_omp_declare_variant *) xcalloc (1, sizeof (gfc_omp_declare_variant
)))
;
5657 odv->where = gfc_current_locus;
5658 odv->variant_proc_symtree = variant_proc_st;
5659 odv->base_proc_symtree = base_proc_st;
5660 odv->next = NULL__null;
5661 odv->error_p = false;
5662
5663 /* Add the new declare variant to the end of the list. */
5664 gfc_omp_declare_variant **prev_next = &gfc_current_ns->omp_declare_variant;
5665 while (*prev_next)
5666 prev_next = &((*prev_next)->next);
5667 *prev_next = odv;
5668
5669 if (gfc_match (" )") != MATCH_YES)
5670 {
5671 gfc_error ("expected %<)%> at %C");
5672 return MATCH_ERROR;
5673 }
5674
5675 for (;;)
5676 {
5677 if (gfc_match (" match") != MATCH_YES)
5678 {
5679 if (first_p)
5680 {
5681 gfc_error ("expected %<match%> at %C");
5682 return MATCH_ERROR;
5683 }
5684 else
5685 break;
5686 }
5687
5688 if (gfc_match (" (") != MATCH_YES)
5689 {
5690 gfc_error ("expected %<(%> at %C");
5691 return MATCH_ERROR;
5692 }
5693
5694 if (gfc_match_omp_context_selector_specification (odv) != MATCH_YES)
5695 return MATCH_ERROR;
5696
5697 if (gfc_match (" )") != MATCH_YES)
5698 {
5699 gfc_error ("expected %<)%> at %C");
5700 return MATCH_ERROR;
5701 }
5702
5703 first_p = false;
5704 }
5705
5706 return MATCH_YES;
5707}
5708
5709
5710match
5711gfc_match_omp_threadprivate (void)
5712{
5713 locus old_loc;
5714 char n[GFC_MAX_SYMBOL_LEN63+1];
5715 gfc_symbol *sym;
5716 match m;
5717 gfc_symtree *st;
5718
5719 old_loc = gfc_current_locus;
5720
5721 m = gfc_match (" (");
5722 if (m != MATCH_YES)
5723 return m;
5724
5725 for (;;)
5726 {
5727 m = gfc_match_symbol (&sym, 0);
5728 switch (m)
5729 {
5730 case MATCH_YES:
5731 if (sym->attr.in_common)
5732 gfc_error_now ("Threadprivate variable at %C is an element of "
5733 "a COMMON block");
5734 else if (!gfc_add_threadprivate (&sym->attr, sym->name, &sym->declared_at))
5735 goto cleanup;
5736 goto next_item;
5737 case MATCH_NO:
5738 break;
5739 case MATCH_ERROR:
5740 goto cleanup;
5741 }
5742
5743 m = gfc_match (" / %n /", n);
5744 if (m == MATCH_ERROR)
5745 goto cleanup;
5746 if (m == MATCH_NO || n[0] == '\0')
5747 goto syntax;
5748
5749 st = gfc_find_symtree (gfc_current_ns->common_root, n);
5750 if (st == NULL__null)
5751 {
5752 gfc_error ("COMMON block /%s/ not found at %C", n);
5753 goto cleanup;
5754 }
5755 st->n.common->threadprivate = 1;
5756 for (sym = st->n.common->head; sym; sym = sym->common_next)
5757 if (!gfc_add_threadprivate (&sym->attr, sym->name, &sym->declared_at))
5758 goto cleanup;
5759
5760 next_item:
5761 if (gfc_match_char (')') == MATCH_YES)
5762 break;
5763 if (gfc_match_char (',') != MATCH_YES)
5764 goto syntax;
5765 }
5766
5767 if (gfc_match_omp_eos () != MATCH_YES)
5768 {
5769 gfc_error ("Unexpected junk after OMP THREADPRIVATE at %C");
5770 goto cleanup;
5771 }
5772
5773 return MATCH_YES;
5774
5775syntax:
5776 gfc_error ("Syntax error in !$OMP THREADPRIVATE list at %C");
5777
5778cleanup:
5779 gfc_current_locus = old_loc;
5780 return MATCH_ERROR;
5781}
5782
5783
5784match
5785gfc_match_omp_parallel (void)
5786{
5787 return match_omp (EXEC_OMP_PARALLEL, OMP_PARALLEL_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF |
OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PROC_BIND
| OMP_CLAUSE_ALLOCATE)
);
5788}
5789
5790
5791match
5792gfc_match_omp_parallel_do (void)
5793{
5794 return match_omp (EXEC_OMP_PARALLEL_DO,
5795 (OMP_PARALLEL_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF |
OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PROC_BIND
| OMP_CLAUSE_ALLOCATE)
| OMP_DO_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ORDER
| OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT)
)
5796 & ~(omp_mask (OMP_CLAUSE_NOWAIT)));
5797}
5798
5799
5800match
5801gfc_match_omp_parallel_do_simd (void)
5802{
5803 return match_omp (EXEC_OMP_PARALLEL_DO_SIMD,
5804 (OMP_PARALLEL_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF |
OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PROC_BIND
| OMP_CLAUSE_ALLOCATE)
| OMP_DO_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ORDER
| OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT)
| OMP_SIMD_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN | OMP_CLAUSE_LINEAR
| OMP_CLAUSE_ALIGNED | OMP_CLAUSE_SIMDLEN | OMP_CLAUSE_IF | OMP_CLAUSE_ORDER
| OMP_CLAUSE_NOTEMPORAL)
)
5805 & ~(omp_mask (OMP_CLAUSE_NOWAIT)));
5806}
5807
5808
5809match
5810gfc_match_omp_parallel_masked (void)
5811{
5812 return match_omp (EXEC_OMP_PARALLEL_MASKED,
5813 OMP_PARALLEL_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF |
OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PROC_BIND
| OMP_CLAUSE_ALLOCATE)
| OMP_MASKED_CLAUSES(omp_mask (OMP_CLAUSE_FILTER)));
5814}
5815
5816match
5817gfc_match_omp_parallel_masked_taskloop (void)
5818{
5819 return match_omp (EXEC_OMP_PARALLEL_MASKED_TASKLOOP,
5820 (OMP_PARALLEL_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF |
OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PROC_BIND
| OMP_CLAUSE_ALLOCATE)
| OMP_MASKED_CLAUSES(omp_mask (OMP_CLAUSE_FILTER))
5821 | OMP_TASKLOOP_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_SHARED | OMP_CLAUSE_IF | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_UNTIED
| OMP_CLAUSE_FINAL | OMP_CLAUSE_MERGEABLE | OMP_CLAUSE_PRIORITY
| OMP_CLAUSE_GRAINSIZE | OMP_CLAUSE_NUM_TASKS | OMP_CLAUSE_COLLAPSE
| OMP_CLAUSE_NOGROUP | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IN_REDUCTION
| OMP_CLAUSE_ALLOCATE)
)
5822 & ~(omp_mask (OMP_CLAUSE_IN_REDUCTION)));
5823}
5824
5825match
5826gfc_match_omp_parallel_masked_taskloop_simd (void)
5827{
5828 return match_omp (EXEC_OMP_PARALLEL_MASKED_TASKLOOP_SIMD,
5829 (OMP_PARALLEL_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF |
OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PROC_BIND
| OMP_CLAUSE_ALLOCATE)
| OMP_MASKED_CLAUSES(omp_mask (OMP_CLAUSE_FILTER))
5830 | OMP_TASKLOOP_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_SHARED | OMP_CLAUSE_IF | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_UNTIED
| OMP_CLAUSE_FINAL | OMP_CLAUSE_MERGEABLE | OMP_CLAUSE_PRIORITY
| OMP_CLAUSE_GRAINSIZE | OMP_CLAUSE_NUM_TASKS | OMP_CLAUSE_COLLAPSE
| OMP_CLAUSE_NOGROUP | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IN_REDUCTION
| OMP_CLAUSE_ALLOCATE)
| OMP_SIMD_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN | OMP_CLAUSE_LINEAR
| OMP_CLAUSE_ALIGNED | OMP_CLAUSE_SIMDLEN | OMP_CLAUSE_IF | OMP_CLAUSE_ORDER
| OMP_CLAUSE_NOTEMPORAL)
)
5831 & ~(omp_mask (OMP_CLAUSE_IN_REDUCTION)));
5832}
5833
5834match
5835gfc_match_omp_parallel_master (void)
5836{
5837 return match_omp (EXEC_OMP_PARALLEL_MASTER, OMP_PARALLEL_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF |
OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PROC_BIND
| OMP_CLAUSE_ALLOCATE)
);
5838}
5839
5840match
5841gfc_match_omp_parallel_master_taskloop (void)
5842{
5843 return match_omp (EXEC_OMP_PARALLEL_MASTER_TASKLOOP,
5844 (OMP_PARALLEL_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF |
OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PROC_BIND
| OMP_CLAUSE_ALLOCATE)
| OMP_TASKLOOP_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_SHARED | OMP_CLAUSE_IF | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_UNTIED
| OMP_CLAUSE_FINAL | OMP_CLAUSE_MERGEABLE | OMP_CLAUSE_PRIORITY
| OMP_CLAUSE_GRAINSIZE | OMP_CLAUSE_NUM_TASKS | OMP_CLAUSE_COLLAPSE
| OMP_CLAUSE_NOGROUP | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IN_REDUCTION
| OMP_CLAUSE_ALLOCATE)
)
5845 & ~(omp_mask (OMP_CLAUSE_IN_REDUCTION)));
5846}
5847
5848match
5849gfc_match_omp_parallel_master_taskloop_simd (void)
5850{
5851 return match_omp (EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD,
5852 (OMP_PARALLEL_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF |
OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PROC_BIND
| OMP_CLAUSE_ALLOCATE)
| OMP_TASKLOOP_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_SHARED | OMP_CLAUSE_IF | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_UNTIED
| OMP_CLAUSE_FINAL | OMP_CLAUSE_MERGEABLE | OMP_CLAUSE_PRIORITY
| OMP_CLAUSE_GRAINSIZE | OMP_CLAUSE_NUM_TASKS | OMP_CLAUSE_COLLAPSE
| OMP_CLAUSE_NOGROUP | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IN_REDUCTION
| OMP_CLAUSE_ALLOCATE)
5853 | OMP_SIMD_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN | OMP_CLAUSE_LINEAR
| OMP_CLAUSE_ALIGNED | OMP_CLAUSE_SIMDLEN | OMP_CLAUSE_IF | OMP_CLAUSE_ORDER
| OMP_CLAUSE_NOTEMPORAL)
)
5854 & ~(omp_mask (OMP_CLAUSE_IN_REDUCTION)));
5855}
5856
5857match
5858gfc_match_omp_parallel_sections (void)
5859{
5860 return match_omp (EXEC_OMP_PARALLEL_SECTIONS,
5861 (OMP_PARALLEL_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF |
OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PROC_BIND
| OMP_CLAUSE_ALLOCATE)
| OMP_SECTIONS_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT
)
)
5862 & ~(omp_mask (OMP_CLAUSE_NOWAIT)));
5863}
5864
5865
5866match
5867gfc_match_omp_parallel_workshare (void)
5868{
5869 return match_omp (EXEC_OMP_PARALLEL_WORKSHARE, OMP_PARALLEL_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF |
OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PROC_BIND
| OMP_CLAUSE_ALLOCATE)
);
5870}
5871
5872void
5873gfc_check_omp_requires (gfc_namespace *ns, int ref_omp_requires)
5874{
5875 if (ns->omp_target_seen
5876 && (ns->omp_requires & OMP_REQ_TARGET_MASK)
5877 != (ref_omp_requires & OMP_REQ_TARGET_MASK))
5878 {
5879 gcc_assert (ns->proc_name)((void)(!(ns->proc_name) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/fortran/openmp.cc"
, 5879, __FUNCTION__), 0 : 0))
;
5880 if ((ref_omp_requires & OMP_REQ_REVERSE_OFFLOAD)
5881 && !(ns->omp_requires & OMP_REQ_REVERSE_OFFLOAD))
5882 gfc_error ("Program unit at %L has OpenMP device constructs/routines "
5883 "but does not set !$OMP REQUIRES REVERSE_OFFLOAD but other "
5884 "program units do", &ns->proc_name->declared_at);
5885 if ((ref_omp_requires & OMP_REQ_UNIFIED_ADDRESS)
5886 && !(ns->omp_requires & OMP_REQ_UNIFIED_ADDRESS))
5887 gfc_error ("Program unit at %L has OpenMP device constructs/routines "
5888 "but does not set !$OMP REQUIRES UNIFIED_ADDRESS but other "
5889 "program units do", &ns->proc_name->declared_at);
5890 if ((ref_omp_requires & OMP_REQ_UNIFIED_SHARED_MEMORY)
5891 && !(ns->omp_requires & OMP_REQ_UNIFIED_SHARED_MEMORY))
5892 gfc_error ("Program unit at %L has OpenMP device constructs/routines "
5893 "but does not set !$OMP REQUIRES UNIFIED_SHARED_MEMORY but "
5894 "other program units do", &ns->proc_name->declared_at);
5895 }
5896}
5897
5898bool
5899gfc_omp_requires_add_clause (gfc_omp_requires_kind clause,
5900 const char *clause_name, locus *loc,
5901 const char *module_name)
5902{
5903 gfc_namespace *prog_unit = gfc_current_ns;
5904 while (prog_unit->parent)
5905 {
5906 if (gfc_state_stack->previous
5907 && gfc_state_stack->previous->state == COMP_INTERFACE)
5908 break;
5909 prog_unit = prog_unit->parent;
5910 }
5911
5912 /* Requires added after use. */
5913 if (prog_unit->omp_target_seen
5914 && (clause & OMP_REQ_TARGET_MASK)
5915 && !(prog_unit->omp_requires & clause))
5916 {
5917 if (module_name)
5918 gfc_error ("!$OMP REQUIRES clause %qs specified via module %qs use "
5919 "at %L comes after using a device construct/routine",
5920 clause_name, module_name, loc);
5921 else
5922 gfc_error ("!$OMP REQUIRES clause %qs specified at %L comes after "
5923 "using a device construct/routine", clause_name, loc);
5924 return false;
5925 }
5926
5927 /* Overriding atomic_default_mem_order clause value. */
5928 if ((clause & OMP_REQ_ATOMIC_MEM_ORDER_MASK)
5929 && (prog_unit->omp_requires & OMP_REQ_ATOMIC_MEM_ORDER_MASK)
5930 && (prog_unit->omp_requires & OMP_REQ_ATOMIC_MEM_ORDER_MASK)
5931 != (int) clause)
5932 {
5933 const char *other;
5934 if (prog_unit->omp_requires & OMP_REQ_ATOMIC_MEM_ORDER_SEQ_CST)
5935 other = "seq_cst";
5936 else if (prog_unit->omp_requires & OMP_REQ_ATOMIC_MEM_ORDER_ACQ_REL)
5937 other = "acq_rel";
5938 else if (prog_unit->omp_requires & OMP_REQ_ATOMIC_MEM_ORDER_RELAXED)
5939 other = "relaxed";
5940 else
5941 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/fortran/openmp.cc"
, 5941, __FUNCTION__))
;
5942
5943 if (module_name)
5944 gfc_error ("!$OMP REQUIRES clause %<atomic_default_mem_order(%s)%> "
5945 "specified via module %qs use at %L overrides a previous "
5946 "%<atomic_default_mem_order(%s)%> (which might be through "
5947 "using a module)", clause_name, module_name, loc, other);
5948 else
5949 gfc_error ("!$OMP REQUIRES clause %<atomic_default_mem_order(%s)%> "
5950 "specified at %L overrides a previous "
5951 "%<atomic_default_mem_order(%s)%> (which might be through "
5952 "using a module)", clause_name, loc, other);
5953 return false;
5954 }
5955
5956 /* Requires via module not at program-unit level and not repeating clause. */
5957 if (prog_unit != gfc_current_ns && !(prog_unit->omp_requires & clause))
5958 {
5959 if (clause & OMP_REQ_ATOMIC_MEM_ORDER_MASK)
5960 gfc_error ("!$OMP REQUIRES clause %<atomic_default_mem_order(%s)%> "
5961 "specified via module %qs use at %L but same clause is "
5962 "not specified for the program unit", clause_name,
5963 module_name, loc);
5964 else
5965 gfc_error ("!$OMP REQUIRES clause %qs specified via module %qs use at "
5966 "%L but same clause is not specified for the program unit",
5967 clause_name, module_name, loc);
5968 return false;
5969 }
5970
5971 if (!gfc_state_stack->previous
5972 || gfc_state_stack->previous->state != COMP_INTERFACE)
5973 prog_unit->omp_requires |= clause;
5974 return true;
5975}
5976
5977match
5978gfc_match_omp_requires (void)
5979{
5980 static const char *clauses[] = {"reverse_offload",
5981 "unified_address",
5982 "unified_shared_memory",
5983 "dynamic_allocators",
5984 "atomic_default"};
5985 const char *clause = NULL__null;
5986 int requires_clauses = 0;
5987 bool first = true;
5988 locus old_loc;
5989
5990 if (gfc_current_ns->parent
5991 && (!gfc_state_stack->previous
5992 || gfc_state_stack->previous->state != COMP_INTERFACE))
5993 {
5994 gfc_error ("!$OMP REQUIRES at %C must appear in the specification part "
5995 "of a program unit");
5996 return MATCH_ERROR;
5997 }
5998
5999 while (true)
6000 {
6001 old_loc = gfc_current_locus;
6002 gfc_omp_requires_kind requires_clause;
6003 if ((first || gfc_match_char (',') != MATCH_YES)
6004 && (first && gfc_match_space () != MATCH_YES))
6005 goto error;
6006 first = false;
6007 gfc_gobble_whitespace ();
6008 old_loc = gfc_current_locus;
6009
6010 if (gfc_match_omp_eos () != MATCH_NO)
6011 break;
6012 if (gfc_match (clauses[0]) == MATCH_YES)
6013 {
6014 clause = clauses[0];
6015 requires_clause = OMP_REQ_REVERSE_OFFLOAD;
6016 if (requires_clauses & OMP_REQ_REVERSE_OFFLOAD)
6017 goto duplicate_clause;
6018 }
6019 else if (gfc_match (clauses[1]) == MATCH_YES)
6020 {
6021 clause = clauses[1];
6022 requires_clause = OMP_REQ_UNIFIED_ADDRESS;
6023 if (requires_clauses & OMP_REQ_UNIFIED_ADDRESS)
6024 goto duplicate_clause;
6025 }
6026 else if (gfc_match (clauses[2]) == MATCH_YES)
6027 {
6028 clause = clauses[2];
6029 requires_clause = OMP_REQ_UNIFIED_SHARED_MEMORY;
6030 if (requires_clauses & OMP_REQ_UNIFIED_SHARED_MEMORY)
6031 goto duplicate_clause;
6032 }
6033 else if (gfc_match (clauses[3]) == MATCH_YES)
6034 {
6035 clause = clauses[3];
6036 requires_clause = OMP_REQ_DYNAMIC_ALLOCATORS;
6037 if (requires_clauses & OMP_REQ_DYNAMIC_ALLOCATORS)
6038 goto duplicate_clause;
6039 }
6040 else if (gfc_match ("atomic_default_mem_order (") == MATCH_YES)
6041 {
6042 clause = clauses[4];
6043 if (requires_clauses & OMP_REQ_ATOMIC_MEM_ORDER_MASK)
6044 goto duplicate_clause;
6045 if (gfc_match (" seq_cst )") == MATCH_YES)
6046 {
6047 clause = "seq_cst";
6048 requires_clause = OMP_REQ_ATOMIC_MEM_ORDER_SEQ_CST;
6049 }
6050 else if (gfc_match (" acq_rel )") == MATCH_YES)
6051 {
6052 clause = "acq_rel";
6053 requires_clause = OMP_REQ_ATOMIC_MEM_ORDER_ACQ_REL;
6054 }
6055 else if (gfc_match (" relaxed )") == MATCH_YES)
6056 {
6057 clause = "relaxed";
6058 requires_clause = OMP_REQ_ATOMIC_MEM_ORDER_RELAXED;
6059 }
6060 else
6061 {
6062 gfc_error ("Expected SEQ_CST, ACQ_REL or RELAXED for "
6063 "ATOMIC_DEFAULT_MEM_ORDER clause at %C");
6064 goto error;
6065 }
6066 }
6067 else
6068 goto error;
6069
6070 if (!gfc_omp_requires_add_clause (requires_clause, clause, &old_loc, NULL__null))
6071 goto error;
6072 requires_clauses |= requires_clause;
6073 }
6074
6075 if (requires_clauses == 0)
6076 {
6077 if (!gfc_error_flag_test ())
6078 gfc_error ("Clause expected at %C");
6079 goto error;
6080 }
6081 return MATCH_YES;
6082
6083duplicate_clause:
6084 gfc_error ("%qs clause at %L specified more than once", clause, &old_loc);
6085error:
6086 if (!gfc_error_flag_test ())
6087 gfc_error ("Expected UNIFIED_ADDRESS, UNIFIED_SHARED_MEMORY, "
6088 "DYNAMIC_ALLOCATORS, REVERSE_OFFLOAD, or "
6089 "ATOMIC_DEFAULT_MEM_ORDER clause at %L", &old_loc);
6090 return MATCH_ERROR;
6091}
6092
6093
6094match
6095gfc_match_omp_scan (void)
6096{
6097 bool incl;
6098 gfc_omp_clauses *c = gfc_get_omp_clauses ()((gfc_omp_clauses *) xcalloc (1, sizeof (gfc_omp_clauses)));
6099 gfc_gobble_whitespace ();
6100 if ((incl = (gfc_match ("inclusive") == MATCH_YES))
6101 || gfc_match ("exclusive") == MATCH_YES)
6102 {
6103 if (gfc_match_omp_variable_list (" (", &c->lists[incl ? OMP_LIST_SCAN_IN
6104 : OMP_LIST_SCAN_EX],
6105 false) != MATCH_YES)
6106 {
6107 gfc_free_omp_clauses (c);
6108 return MATCH_ERROR;
6109 }
6110 }
6111 else
6112 {
6113 gfc_error ("Expected INCLUSIVE or EXCLUSIVE clause at %C");
6114 gfc_free_omp_clauses (c);
6115 return MATCH_ERROR;
6116 }
6117 if (gfc_match_omp_eos () != MATCH_YES)
6118 {
6119 gfc_error ("Unexpected junk after !$OMP SCAN at %C");
6120 gfc_free_omp_clauses (c);
6121 return MATCH_ERROR;
6122 }
6123
6124 new_st.op = EXEC_OMP_SCAN;
6125 new_st.ext.omp_clauses = c;
6126 return MATCH_YES;
6127}
6128
6129
6130match
6131gfc_match_omp_scope (void)
6132{
6133 return match_omp (EXEC_OMP_SCOPE, OMP_SCOPE_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) |OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_REDUCTION
| OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT)
);
6134}
6135
6136
6137match
6138gfc_match_omp_sections (void)
6139{
6140 return match_omp (EXEC_OMP_SECTIONS, OMP_SECTIONS_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT
)
);
6141}
6142
6143
6144match
6145gfc_match_omp_simd (void)
6146{
6147 return match_omp (EXEC_OMP_SIMD, OMP_SIMD_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN | OMP_CLAUSE_LINEAR
| OMP_CLAUSE_ALIGNED | OMP_CLAUSE_SIMDLEN | OMP_CLAUSE_IF | OMP_CLAUSE_ORDER
| OMP_CLAUSE_NOTEMPORAL)
);
6148}
6149
6150
6151match
6152gfc_match_omp_single (void)
6153{
6154 return match_omp (EXEC_OMP_SINGLE, OMP_SINGLE_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_ALLOCATE
| OMP_CLAUSE_NOWAIT | OMP_CLAUSE_COPYPRIVATE)
);
6155}
6156
6157
6158match
6159gfc_match_omp_target (void)
6160{
6161 return match_omp (EXEC_OMP_TARGET, OMP_TARGET_CLAUSES(omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF
| OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE
| OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP | OMP_CLAUSE_IS_DEVICE_PTR
| OMP_CLAUSE_IN_REDUCTION | OMP_CLAUSE_THREAD_LIMIT | OMP_CLAUSE_ALLOCATE
| OMP_CLAUSE_HAS_DEVICE_ADDR)
);
6162}
6163
6164
6165match
6166gfc_match_omp_target_data (void)
6167{
6168 return match_omp (EXEC_OMP_TARGET_DATA, OMP_TARGET_DATA_CLAUSES(omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF
| OMP_CLAUSE_USE_DEVICE_PTR | OMP_CLAUSE_USE_DEVICE_ADDR)
);
6169}
6170
6171
6172match
6173gfc_match_omp_target_enter_data (void)
6174{
6175 return match_omp (EXEC_OMP_TARGET_ENTER_DATA, OMP_TARGET_ENTER_DATA_CLAUSES(omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF
| OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
);
6176}
6177
6178
6179match
6180gfc_match_omp_target_exit_data (void)
6181{
6182 return match_omp (EXEC_OMP_TARGET_EXIT_DATA, OMP_TARGET_EXIT_DATA_CLAUSES(omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF
| OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
);
6183}
6184
6185
6186match
6187gfc_match_omp_target_parallel (void)
6188{
6189 return match_omp (EXEC_OMP_TARGET_PARALLEL,
6190 (OMP_TARGET_CLAUSES(omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF
| OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE
| OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP | OMP_CLAUSE_IS_DEVICE_PTR
| OMP_CLAUSE_IN_REDUCTION | OMP_CLAUSE_THREAD_LIMIT | OMP_CLAUSE_ALLOCATE
| OMP_CLAUSE_HAS_DEVICE_ADDR)
| OMP_PARALLEL_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF |
OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PROC_BIND
| OMP_CLAUSE_ALLOCATE)
)
6191 & ~(omp_mask (OMP_CLAUSE_COPYIN)));
6192}
6193
6194
6195match
6196gfc_match_omp_target_parallel_do (void)
6197{
6198 return match_omp (EXEC_OMP_TARGET_PARALLEL_DO,
6199 (OMP_TARGET_CLAUSES(omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF
| OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE
| OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP | OMP_CLAUSE_IS_DEVICE_PTR
| OMP_CLAUSE_IN_REDUCTION | OMP_CLAUSE_THREAD_LIMIT | OMP_CLAUSE_ALLOCATE
| OMP_CLAUSE_HAS_DEVICE_ADDR)
| OMP_PARALLEL_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF |
OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PROC_BIND
| OMP_CLAUSE_ALLOCATE)
6200 | OMP_DO_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ORDER
| OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT)
) & ~(omp_mask (OMP_CLAUSE_COPYIN)));
6201}
6202
6203
6204match
6205gfc_match_omp_target_parallel_do_simd (void)
6206{
6207 return match_omp (EXEC_OMP_TARGET_PARALLEL_DO_SIMD,
6208 (OMP_TARGET_CLAUSES(omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF
| OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE
| OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP | OMP_CLAUSE_IS_DEVICE_PTR
| OMP_CLAUSE_IN_REDUCTION | OMP_CLAUSE_THREAD_LIMIT | OMP_CLAUSE_ALLOCATE
| OMP_CLAUSE_HAS_DEVICE_ADDR)
| OMP_PARALLEL_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF |
OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PROC_BIND
| OMP_CLAUSE_ALLOCATE)
| OMP_DO_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ORDER
| OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT)
6209 | OMP_SIMD_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN | OMP_CLAUSE_LINEAR
| OMP_CLAUSE_ALIGNED | OMP_CLAUSE_SIMDLEN | OMP_CLAUSE_IF | OMP_CLAUSE_ORDER
| OMP_CLAUSE_NOTEMPORAL)
) & ~(omp_mask (OMP_CLAUSE_COPYIN)));
6210}
6211
6212
6213match
6214gfc_match_omp_target_simd (void)
6215{
6216 return match_omp (EXEC_OMP_TARGET_SIMD,
6217 OMP_TARGET_CLAUSES(omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF
| OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE
| OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP | OMP_CLAUSE_IS_DEVICE_PTR
| OMP_CLAUSE_IN_REDUCTION | OMP_CLAUSE_THREAD_LIMIT | OMP_CLAUSE_ALLOCATE
| OMP_CLAUSE_HAS_DEVICE_ADDR)
| OMP_SIMD_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN | OMP_CLAUSE_LINEAR
| OMP_CLAUSE_ALIGNED | OMP_CLAUSE_SIMDLEN | OMP_CLAUSE_IF | OMP_CLAUSE_ORDER
| OMP_CLAUSE_NOTEMPORAL)
);
6218}
6219
6220
6221match
6222gfc_match_omp_target_teams (void)
6223{
6224 return match_omp (EXEC_OMP_TARGET_TEAMS,
6225 OMP_TARGET_CLAUSES(omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF
| OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE
| OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP | OMP_CLAUSE_IS_DEVICE_PTR
| OMP_CLAUSE_IN_REDUCTION | OMP_CLAUSE_THREAD_LIMIT | OMP_CLAUSE_ALLOCATE
| OMP_CLAUSE_HAS_DEVICE_ADDR)
| OMP_TEAMS_CLAUSES(omp_mask (OMP_CLAUSE_NUM_TEAMS) | OMP_CLAUSE_THREAD_LIMIT | OMP_CLAUSE_DEFAULT
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE)
);
6226}
6227
6228
6229match
6230gfc_match_omp_target_teams_distribute (void)
6231{
6232 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE,
6233 OMP_TARGET_CLAUSES(omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF
| OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE
| OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP | OMP_CLAUSE_IS_DEVICE_PTR
| OMP_CLAUSE_IN_REDUCTION | OMP_CLAUSE_THREAD_LIMIT | OMP_CLAUSE_ALLOCATE
| OMP_CLAUSE_HAS_DEVICE_ADDR)
| OMP_TEAMS_CLAUSES(omp_mask (OMP_CLAUSE_NUM_TEAMS) | OMP_CLAUSE_THREAD_LIMIT | OMP_CLAUSE_DEFAULT
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE)
6234 | OMP_DISTRIBUTE_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_DIST_SCHEDULE | OMP_CLAUSE_ORDER
| OMP_CLAUSE_ALLOCATE)
);
6235}
6236
6237
6238match
6239gfc_match_omp_target_teams_distribute_parallel_do (void)
6240{
6241 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO,
6242 (OMP_TARGET_CLAUSES(omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF
| OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE
| OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP | OMP_CLAUSE_IS_DEVICE_PTR
| OMP_CLAUSE_IN_REDUCTION | OMP_CLAUSE_THREAD_LIMIT | OMP_CLAUSE_ALLOCATE
| OMP_CLAUSE_HAS_DEVICE_ADDR)
| OMP_TEAMS_CLAUSES(omp_mask (OMP_CLAUSE_NUM_TEAMS) | OMP_CLAUSE_THREAD_LIMIT | OMP_CLAUSE_DEFAULT
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE)
6243 | OMP_DISTRIBUTE_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_DIST_SCHEDULE | OMP_CLAUSE_ORDER
| OMP_CLAUSE_ALLOCATE)
| OMP_PARALLEL_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF |
OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PROC_BIND
| OMP_CLAUSE_ALLOCATE)
6244 | OMP_DO_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ORDER
| OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT)
)
6245 & ~(omp_mask (OMP_CLAUSE_ORDERED))
6246 & ~(omp_mask (OMP_CLAUSE_LINEAR)));
6247}
6248
6249
6250match
6251gfc_match_omp_target_teams_distribute_parallel_do_simd (void)
6252{
6253 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD,
6254 (OMP_TARGET_CLAUSES(omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF
| OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE
| OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP | OMP_CLAUSE_IS_DEVICE_PTR
| OMP_CLAUSE_IN_REDUCTION | OMP_CLAUSE_THREAD_LIMIT | OMP_CLAUSE_ALLOCATE
| OMP_CLAUSE_HAS_DEVICE_ADDR)
| OMP_TEAMS_CLAUSES(omp_mask (OMP_CLAUSE_NUM_TEAMS) | OMP_CLAUSE_THREAD_LIMIT | OMP_CLAUSE_DEFAULT
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE)
6255 | OMP_DISTRIBUTE_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_DIST_SCHEDULE | OMP_CLAUSE_ORDER
| OMP_CLAUSE_ALLOCATE)
| OMP_PARALLEL_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF |
OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PROC_BIND
| OMP_CLAUSE_ALLOCATE)
6256 | OMP_DO_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ORDER
| OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT)
| OMP_SIMD_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN | OMP_CLAUSE_LINEAR
| OMP_CLAUSE_ALIGNED | OMP_CLAUSE_SIMDLEN | OMP_CLAUSE_IF | OMP_CLAUSE_ORDER
| OMP_CLAUSE_NOTEMPORAL)
)
6257 & ~(omp_mask (OMP_CLAUSE_ORDERED)));
6258}
6259
6260
6261match
6262gfc_match_omp_target_teams_distribute_simd (void)
6263{
6264 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD,
6265 OMP_TARGET_CLAUSES(omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF
| OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE
| OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP | OMP_CLAUSE_IS_DEVICE_PTR
| OMP_CLAUSE_IN_REDUCTION | OMP_CLAUSE_THREAD_LIMIT | OMP_CLAUSE_ALLOCATE
| OMP_CLAUSE_HAS_DEVICE_ADDR)
| OMP_TEAMS_CLAUSES(omp_mask (OMP_CLAUSE_NUM_TEAMS) | OMP_CLAUSE_THREAD_LIMIT | OMP_CLAUSE_DEFAULT
| OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED
| OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE)
6266 | OMP_DISTRIBUTE_CLAUSES(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_LASTPRIVATE
| OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_DIST_SCHEDULE | OMP_CL