1//===--- OpenMPKinds.cpp - Token Kinds Support ----------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file implements the OpenMP enum and support functions.
10///
11//===----------------------------------------------------------------------===//
12
13#include "clang/Basic/OpenMPKinds.h"
14#include "clang/Basic/IdentifierTable.h"
15#include "llvm/ADT/StringRef.h"
16#include "llvm/ADT/StringSwitch.h"
17#include "llvm/Support/ErrorHandling.h"
18#include <cassert>
19
20using namespace clang;
21using namespace llvm::omp;
22
23unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
24 const LangOptions &LangOpts) {
25 switch (Kind) {
26 case OMPC_default:
27 return llvm::StringSwitch<unsigned>(Str)
28#define OMP_DEFAULT_KIND(Enum, Name) .Case(Name, unsigned(Enum))
29#include "llvm/Frontend/OpenMP/OMPKinds.def"
30 .Default(Value: unsigned(llvm::omp::OMP_DEFAULT_unknown));
31 case OMPC_proc_bind:
32 return llvm::StringSwitch<unsigned>(Str)
33#define OMP_PROC_BIND_KIND(Enum, Name, Value) .Case(Name, Value)
34#include "llvm/Frontend/OpenMP/OMPKinds.def"
35 .Default(Value: unsigned(llvm::omp::OMP_PROC_BIND_unknown));
36 case OMPC_schedule:
37 return llvm::StringSwitch<unsigned>(Str)
38#define OPENMP_SCHEDULE_KIND(Name) \
39 .Case(#Name, static_cast<unsigned>(OMPC_SCHEDULE_##Name))
40#define OPENMP_SCHEDULE_MODIFIER(Name) \
41 .Case(#Name, static_cast<unsigned>(OMPC_SCHEDULE_MODIFIER_##Name))
42#include "clang/Basic/OpenMPKinds.def"
43 .Default(Value: OMPC_SCHEDULE_unknown);
44 case OMPC_depend: {
45 unsigned Type = llvm::StringSwitch<unsigned>(Str)
46#define OPENMP_DEPEND_KIND(Name) .Case(#Name, OMPC_DEPEND_##Name)
47#include "clang/Basic/OpenMPKinds.def"
48 .Default(Value: OMPC_DEPEND_unknown);
49 if (LangOpts.OpenMP < 51 && Type == OMPC_DEPEND_inoutset)
50 return OMPC_DEPEND_unknown;
51 return Type;
52 }
53 case OMPC_doacross:
54 return llvm::StringSwitch<OpenMPDoacrossClauseModifier>(Str)
55#define OPENMP_DOACROSS_MODIFIER(Name) .Case(#Name, OMPC_DOACROSS_##Name)
56#include "clang/Basic/OpenMPKinds.def"
57 .Default(Value: OMPC_DOACROSS_unknown);
58 case OMPC_linear:
59 return llvm::StringSwitch<OpenMPLinearClauseKind>(Str)
60#define OPENMP_LINEAR_KIND(Name) .Case(#Name, OMPC_LINEAR_##Name)
61#include "clang/Basic/OpenMPKinds.def"
62 .Default(Value: OMPC_LINEAR_unknown);
63 case OMPC_map: {
64 unsigned Type = llvm::StringSwitch<unsigned>(Str)
65#define OPENMP_MAP_KIND(Name) \
66 .Case(#Name, static_cast<unsigned>(OMPC_MAP_##Name))
67#define OPENMP_MAP_MODIFIER_KIND(Name) \
68 .Case(#Name, static_cast<unsigned>(OMPC_MAP_MODIFIER_##Name))
69#include "clang/Basic/OpenMPKinds.def"
70 .Default(Value: OMPC_MAP_unknown);
71 if (LangOpts.OpenMP < 51 && Type == OMPC_MAP_MODIFIER_present)
72 return OMPC_MAP_MODIFIER_unknown;
73 if (!LangOpts.OpenMPExtensions && Type == OMPC_MAP_MODIFIER_ompx_hold)
74 return OMPC_MAP_MODIFIER_unknown;
75 return Type;
76 }
77 case OMPC_to:
78 case OMPC_from: {
79 unsigned Type = llvm::StringSwitch<unsigned>(Str)
80#define OPENMP_MOTION_MODIFIER_KIND(Name) \
81 .Case(#Name, static_cast<unsigned>(OMPC_MOTION_MODIFIER_##Name))
82#include "clang/Basic/OpenMPKinds.def"
83 .Default(Value: OMPC_MOTION_MODIFIER_unknown);
84 if (LangOpts.OpenMP < 51 && Type == OMPC_MOTION_MODIFIER_present)
85 return OMPC_MOTION_MODIFIER_unknown;
86 return Type;
87 }
88 case OMPC_dist_schedule:
89 return llvm::StringSwitch<OpenMPDistScheduleClauseKind>(Str)
90#define OPENMP_DIST_SCHEDULE_KIND(Name) .Case(#Name, OMPC_DIST_SCHEDULE_##Name)
91#include "clang/Basic/OpenMPKinds.def"
92 .Default(Value: OMPC_DIST_SCHEDULE_unknown);
93 case OMPC_defaultmap:
94 return llvm::StringSwitch<unsigned>(Str)
95#define OPENMP_DEFAULTMAP_KIND(Name) \
96 .Case(#Name, static_cast<unsigned>(OMPC_DEFAULTMAP_##Name))
97#define OPENMP_DEFAULTMAP_MODIFIER(Name) \
98 .Case(#Name, static_cast<unsigned>(OMPC_DEFAULTMAP_MODIFIER_##Name))
99#include "clang/Basic/OpenMPKinds.def"
100 .Default(Value: OMPC_DEFAULTMAP_unknown);
101 case OMPC_atomic_default_mem_order:
102 return llvm::StringSwitch<OpenMPAtomicDefaultMemOrderClauseKind>(Str)
103#define OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(Name) \
104 .Case(#Name, OMPC_ATOMIC_DEFAULT_MEM_ORDER_##Name)
105#include "clang/Basic/OpenMPKinds.def"
106 .Default(Value: OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown);
107 case OMPC_fail:
108 return static_cast<unsigned int>(llvm::StringSwitch<llvm::omp::Clause>(Str)
109#define OPENMP_ATOMIC_FAIL_MODIFIER(Name) .Case(#Name, OMPC_##Name)
110#include "clang/Basic/OpenMPKinds.def"
111 .Default(Value: OMPC_unknown));
112 case OMPC_device_type:
113 return llvm::StringSwitch<OpenMPDeviceType>(Str)
114#define OPENMP_DEVICE_TYPE_KIND(Name) .Case(#Name, OMPC_DEVICE_TYPE_##Name)
115#include "clang/Basic/OpenMPKinds.def"
116 .Default(Value: OMPC_DEVICE_TYPE_unknown);
117 case OMPC_at:
118 return llvm::StringSwitch<OpenMPAtClauseKind>(Str)
119#define OPENMP_AT_KIND(Name) .Case(#Name, OMPC_AT_##Name)
120#include "clang/Basic/OpenMPKinds.def"
121 .Default(Value: OMPC_AT_unknown);
122 case OMPC_severity:
123 return llvm::StringSwitch<OpenMPSeverityClauseKind>(Str)
124#define OPENMP_SEVERITY_KIND(Name) .Case(#Name, OMPC_SEVERITY_##Name)
125#include "clang/Basic/OpenMPKinds.def"
126 .Default(Value: OMPC_SEVERITY_unknown);
127 case OMPC_lastprivate:
128 return llvm::StringSwitch<OpenMPLastprivateModifier>(Str)
129#define OPENMP_LASTPRIVATE_KIND(Name) .Case(#Name, OMPC_LASTPRIVATE_##Name)
130#include "clang/Basic/OpenMPKinds.def"
131 .Default(Value: OMPC_LASTPRIVATE_unknown);
132 case OMPC_order:
133 return llvm::StringSwitch<unsigned>(Str)
134#define OPENMP_ORDER_KIND(Name) \
135 .Case(#Name, static_cast<unsigned>(OMPC_ORDER_##Name))
136#define OPENMP_ORDER_MODIFIER(Name) \
137 .Case(#Name, static_cast<unsigned>(OMPC_ORDER_MODIFIER_##Name))
138#include "clang/Basic/OpenMPKinds.def"
139 .Default(Value: OMPC_ORDER_unknown);
140 case OMPC_update:
141 return llvm::StringSwitch<OpenMPDependClauseKind>(Str)
142#define OPENMP_DEPEND_KIND(Name) .Case(#Name, OMPC_DEPEND_##Name)
143#include "clang/Basic/OpenMPKinds.def"
144 .Default(Value: OMPC_DEPEND_unknown);
145 case OMPC_device:
146 return llvm::StringSwitch<OpenMPDeviceClauseModifier>(Str)
147#define OPENMP_DEVICE_MODIFIER(Name) .Case(#Name, OMPC_DEVICE_##Name)
148#include "clang/Basic/OpenMPKinds.def"
149 .Default(Value: OMPC_DEVICE_unknown);
150 case OMPC_reduction:
151 return llvm::StringSwitch<OpenMPReductionClauseModifier>(Str)
152#define OPENMP_REDUCTION_MODIFIER(Name) .Case(#Name, OMPC_REDUCTION_##Name)
153#include "clang/Basic/OpenMPKinds.def"
154 .Default(Value: OMPC_REDUCTION_unknown);
155 case OMPC_adjust_args:
156 return llvm::StringSwitch<OpenMPAdjustArgsOpKind>(Str)
157#define OPENMP_ADJUST_ARGS_KIND(Name) .Case(#Name, OMPC_ADJUST_ARGS_##Name)
158#include "clang/Basic/OpenMPKinds.def"
159 .Default(Value: OMPC_ADJUST_ARGS_unknown);
160 case OMPC_bind:
161 return llvm::StringSwitch<unsigned>(Str)
162#define OPENMP_BIND_KIND(Name) .Case(#Name, OMPC_BIND_##Name)
163#include "clang/Basic/OpenMPKinds.def"
164 .Default(Value: OMPC_BIND_unknown);
165 case OMPC_grainsize: {
166 unsigned Type = llvm::StringSwitch<unsigned>(Str)
167#define OPENMP_GRAINSIZE_MODIFIER(Name) .Case(#Name, OMPC_GRAINSIZE_##Name)
168#include "clang/Basic/OpenMPKinds.def"
169 .Default(Value: OMPC_GRAINSIZE_unknown);
170 if (LangOpts.OpenMP < 51)
171 return OMPC_GRAINSIZE_unknown;
172 return Type;
173 }
174 case OMPC_num_tasks: {
175 unsigned Type = llvm::StringSwitch<unsigned>(Str)
176#define OPENMP_NUMTASKS_MODIFIER(Name) .Case(#Name, OMPC_NUMTASKS_##Name)
177#include "clang/Basic/OpenMPKinds.def"
178 .Default(Value: OMPC_NUMTASKS_unknown);
179 if (LangOpts.OpenMP < 51)
180 return OMPC_NUMTASKS_unknown;
181 return Type;
182 }
183 case OMPC_allocate:
184 return llvm::StringSwitch<OpenMPAllocateClauseModifier>(Str)
185#define OPENMP_ALLOCATE_MODIFIER(Name) .Case(#Name, OMPC_ALLOCATE_##Name)
186#include "clang/Basic/OpenMPKinds.def"
187 .Default(Value: OMPC_ALLOCATE_unknown);
188 case OMPC_num_threads: {
189 unsigned Type = llvm::StringSwitch<unsigned>(Str)
190#define OPENMP_NUMTHREADS_MODIFIER(Name) .Case(#Name, OMPC_NUMTHREADS_##Name)
191#include "clang/Basic/OpenMPKinds.def"
192 .Default(Value: OMPC_NUMTHREADS_unknown);
193 if (LangOpts.OpenMP < 60)
194 return OMPC_NUMTHREADS_unknown;
195 return Type;
196 }
197 case OMPC_unknown:
198 case OMPC_threadprivate:
199 case OMPC_if:
200 case OMPC_final:
201 case OMPC_safelen:
202 case OMPC_simdlen:
203 case OMPC_sizes:
204 case OMPC_permutation:
205 case OMPC_allocator:
206 case OMPC_collapse:
207 case OMPC_private:
208 case OMPC_firstprivate:
209 case OMPC_shared:
210 case OMPC_task_reduction:
211 case OMPC_in_reduction:
212 case OMPC_aligned:
213 case OMPC_copyin:
214 case OMPC_copyprivate:
215 case OMPC_ordered:
216 case OMPC_nowait:
217 case OMPC_untied:
218 case OMPC_mergeable:
219 case OMPC_flush:
220 case OMPC_depobj:
221 case OMPC_read:
222 case OMPC_write:
223 case OMPC_capture:
224 case OMPC_compare:
225 case OMPC_seq_cst:
226 case OMPC_acq_rel:
227 case OMPC_acquire:
228 case OMPC_release:
229 case OMPC_relaxed:
230 case OMPC_threads:
231 case OMPC_simd:
232 case OMPC_num_teams:
233 case OMPC_thread_limit:
234 case OMPC_priority:
235 case OMPC_nogroup:
236 case OMPC_hint:
237 case OMPC_uniform:
238 case OMPC_use_device_ptr:
239 case OMPC_use_device_addr:
240 case OMPC_is_device_ptr:
241 case OMPC_has_device_addr:
242 case OMPC_unified_address:
243 case OMPC_unified_shared_memory:
244 case OMPC_reverse_offload:
245 case OMPC_dynamic_allocators:
246 case OMPC_self_maps:
247 case OMPC_match:
248 case OMPC_nontemporal:
249 case OMPC_destroy:
250 case OMPC_novariants:
251 case OMPC_nocontext:
252 case OMPC_detach:
253 case OMPC_inclusive:
254 case OMPC_exclusive:
255 case OMPC_uses_allocators:
256 case OMPC_affinity:
257 case OMPC_when:
258 case OMPC_append_args:
259 break;
260 default:
261 break;
262 }
263 llvm_unreachable("Invalid OpenMP simple clause kind");
264}
265
266const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
267 unsigned Type) {
268 switch (Kind) {
269 case OMPC_default:
270 switch (llvm::omp::DefaultKind(Type)) {
271#define OMP_DEFAULT_KIND(Enum, Name) \
272 case Enum: \
273 return Name;
274#include "llvm/Frontend/OpenMP/OMPKinds.def"
275 }
276 llvm_unreachable("Invalid OpenMP 'default' clause type");
277 case OMPC_proc_bind:
278 switch (Type) {
279#define OMP_PROC_BIND_KIND(Enum, Name, Value) \
280 case Value: \
281 return Name;
282#include "llvm/Frontend/OpenMP/OMPKinds.def"
283 }
284 llvm_unreachable("Invalid OpenMP 'proc_bind' clause type");
285 case OMPC_schedule:
286 switch (Type) {
287 case OMPC_SCHEDULE_unknown:
288 case OMPC_SCHEDULE_MODIFIER_last:
289 return "unknown";
290#define OPENMP_SCHEDULE_KIND(Name) \
291 case OMPC_SCHEDULE_##Name: \
292 return #Name;
293#define OPENMP_SCHEDULE_MODIFIER(Name) \
294 case OMPC_SCHEDULE_MODIFIER_##Name: \
295 return #Name;
296#include "clang/Basic/OpenMPKinds.def"
297 }
298 llvm_unreachable("Invalid OpenMP 'schedule' clause type");
299 case OMPC_depend:
300 switch (Type) {
301 case OMPC_DEPEND_unknown:
302 return "unknown";
303#define OPENMP_DEPEND_KIND(Name) \
304 case OMPC_DEPEND_##Name: \
305 return #Name;
306#include "clang/Basic/OpenMPKinds.def"
307 }
308 llvm_unreachable("Invalid OpenMP 'depend' clause type");
309 case OMPC_doacross:
310 switch (Type) {
311 case OMPC_DOACROSS_unknown:
312 return "unknown";
313#define OPENMP_DOACROSS_MODIFIER(Name) \
314 case OMPC_DOACROSS_##Name: \
315 return #Name;
316#include "clang/Basic/OpenMPKinds.def"
317 }
318 llvm_unreachable("Invalid OpenMP 'doacross' clause type");
319 case OMPC_linear:
320 switch (Type) {
321 case OMPC_LINEAR_unknown:
322 return "unknown";
323#define OPENMP_LINEAR_KIND(Name) \
324 case OMPC_LINEAR_##Name: \
325 return #Name;
326#include "clang/Basic/OpenMPKinds.def"
327 }
328 llvm_unreachable("Invalid OpenMP 'linear' clause type");
329 case OMPC_map:
330 switch (Type) {
331 case OMPC_MAP_unknown:
332 case OMPC_MAP_MODIFIER_last:
333 return "unknown";
334#define OPENMP_MAP_KIND(Name) \
335 case OMPC_MAP_##Name: \
336 return #Name;
337#define OPENMP_MAP_MODIFIER_KIND(Name) \
338 case OMPC_MAP_MODIFIER_##Name: \
339 return #Name;
340#include "clang/Basic/OpenMPKinds.def"
341 default:
342 break;
343 }
344 llvm_unreachable("Invalid OpenMP 'map' clause type");
345 case OMPC_to:
346 case OMPC_from:
347 switch (Type) {
348 case OMPC_MOTION_MODIFIER_unknown:
349 return "unknown";
350#define OPENMP_MOTION_MODIFIER_KIND(Name) \
351 case OMPC_MOTION_MODIFIER_##Name: \
352 return #Name;
353#include "clang/Basic/OpenMPKinds.def"
354 default:
355 break;
356 }
357 llvm_unreachable("Invalid OpenMP 'to' or 'from' clause type");
358 case OMPC_dist_schedule:
359 switch (Type) {
360 case OMPC_DIST_SCHEDULE_unknown:
361 return "unknown";
362#define OPENMP_DIST_SCHEDULE_KIND(Name) \
363 case OMPC_DIST_SCHEDULE_##Name: \
364 return #Name;
365#include "clang/Basic/OpenMPKinds.def"
366 }
367 llvm_unreachable("Invalid OpenMP 'dist_schedule' clause type");
368 case OMPC_defaultmap:
369 switch (Type) {
370 case OMPC_DEFAULTMAP_unknown:
371 case OMPC_DEFAULTMAP_MODIFIER_last:
372 return "unknown";
373#define OPENMP_DEFAULTMAP_KIND(Name) \
374 case OMPC_DEFAULTMAP_##Name: \
375 return #Name;
376#define OPENMP_DEFAULTMAP_MODIFIER(Name) \
377 case OMPC_DEFAULTMAP_MODIFIER_##Name: \
378 return #Name;
379#include "clang/Basic/OpenMPKinds.def"
380 }
381 llvm_unreachable("Invalid OpenMP 'schedule' clause type");
382 case OMPC_atomic_default_mem_order:
383 switch (Type) {
384 case OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown:
385 return "unknown";
386#define OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(Name) \
387 case OMPC_ATOMIC_DEFAULT_MEM_ORDER_##Name: \
388 return #Name;
389#include "clang/Basic/OpenMPKinds.def"
390}
391 llvm_unreachable("Invalid OpenMP 'atomic_default_mem_order' clause type");
392 case OMPC_device_type:
393 switch (Type) {
394 case OMPC_DEVICE_TYPE_unknown:
395 return "unknown";
396#define OPENMP_DEVICE_TYPE_KIND(Name) \
397 case OMPC_DEVICE_TYPE_##Name: \
398 return #Name;
399#include "clang/Basic/OpenMPKinds.def"
400 }
401 llvm_unreachable("Invalid OpenMP 'device_type' clause type");
402 case OMPC_at:
403 switch (Type) {
404 case OMPC_AT_unknown:
405 return "unknown";
406#define OPENMP_AT_KIND(Name) \
407 case OMPC_AT_##Name: \
408 return #Name;
409#include "clang/Basic/OpenMPKinds.def"
410 }
411 llvm_unreachable("Invalid OpenMP 'at' clause type");
412 case OMPC_severity:
413 switch (Type) {
414 case OMPC_SEVERITY_unknown:
415 return "unknown";
416#define OPENMP_SEVERITY_KIND(Name) \
417 case OMPC_SEVERITY_##Name: \
418 return #Name;
419#include "clang/Basic/OpenMPKinds.def"
420 }
421 llvm_unreachable("Invalid OpenMP 'severity' clause type");
422 case OMPC_lastprivate:
423 switch (Type) {
424 case OMPC_LASTPRIVATE_unknown:
425 return "unknown";
426#define OPENMP_LASTPRIVATE_KIND(Name) \
427 case OMPC_LASTPRIVATE_##Name: \
428 return #Name;
429#include "clang/Basic/OpenMPKinds.def"
430 }
431 llvm_unreachable("Invalid OpenMP 'lastprivate' clause type");
432 case OMPC_order:
433 switch (Type) {
434 case OMPC_ORDER_unknown:
435 case OMPC_ORDER_MODIFIER_last:
436 return "unknown";
437#define OPENMP_ORDER_KIND(Name) \
438 case OMPC_ORDER_##Name: \
439 return #Name;
440#define OPENMP_ORDER_MODIFIER(Name) \
441 case OMPC_ORDER_MODIFIER_##Name: \
442 return #Name;
443#include "clang/Basic/OpenMPKinds.def"
444 }
445 llvm_unreachable("Invalid OpenMP 'order' clause type");
446 case OMPC_update:
447 switch (Type) {
448 case OMPC_DEPEND_unknown:
449 return "unknown";
450#define OPENMP_DEPEND_KIND(Name) \
451 case OMPC_DEPEND_##Name: \
452 return #Name;
453#include "clang/Basic/OpenMPKinds.def"
454 }
455 llvm_unreachable("Invalid OpenMP 'depend' clause type");
456 case OMPC_fail: {
457 OpenMPClauseKind CK = static_cast<OpenMPClauseKind>(Type);
458 return getOpenMPClauseName(C: CK).data();
459 llvm_unreachable("Invalid OpenMP 'fail' clause modifier");
460 }
461 case OMPC_device:
462 switch (Type) {
463 case OMPC_DEVICE_unknown:
464 return "unknown";
465#define OPENMP_DEVICE_MODIFIER(Name) \
466 case OMPC_DEVICE_##Name: \
467 return #Name;
468#include "clang/Basic/OpenMPKinds.def"
469 }
470 llvm_unreachable("Invalid OpenMP 'device' clause modifier");
471 case OMPC_reduction:
472 switch (Type) {
473 case OMPC_REDUCTION_unknown:
474 return "unknown";
475#define OPENMP_REDUCTION_MODIFIER(Name) \
476 case OMPC_REDUCTION_##Name: \
477 return #Name;
478#include "clang/Basic/OpenMPKinds.def"
479 }
480 llvm_unreachable("Invalid OpenMP 'reduction' clause modifier");
481 case OMPC_adjust_args:
482 switch (Type) {
483 case OMPC_ADJUST_ARGS_unknown:
484 return "unknown";
485#define OPENMP_ADJUST_ARGS_KIND(Name) \
486 case OMPC_ADJUST_ARGS_##Name: \
487 return #Name;
488#include "clang/Basic/OpenMPKinds.def"
489 }
490 llvm_unreachable("Invalid OpenMP 'adjust_args' clause kind");
491 case OMPC_bind:
492 switch (Type) {
493 case OMPC_BIND_unknown:
494 return "unknown";
495#define OPENMP_BIND_KIND(Name) \
496 case OMPC_BIND_##Name: \
497 return #Name;
498#include "clang/Basic/OpenMPKinds.def"
499 }
500 llvm_unreachable("Invalid OpenMP 'bind' clause type");
501 case OMPC_grainsize:
502 switch (Type) {
503 case OMPC_GRAINSIZE_unknown:
504 return "unknown";
505#define OPENMP_GRAINSIZE_MODIFIER(Name) \
506 case OMPC_GRAINSIZE_##Name: \
507 return #Name;
508#include "clang/Basic/OpenMPKinds.def"
509 }
510 llvm_unreachable("Invalid OpenMP 'grainsize' clause modifier");
511 case OMPC_num_tasks:
512 switch (Type) {
513 case OMPC_NUMTASKS_unknown:
514 return "unknown";
515#define OPENMP_NUMTASKS_MODIFIER(Name) \
516 case OMPC_NUMTASKS_##Name: \
517 return #Name;
518#include "clang/Basic/OpenMPKinds.def"
519 }
520 llvm_unreachable("Invalid OpenMP 'num_tasks' clause modifier");
521 case OMPC_allocate:
522 switch (Type) {
523 case OMPC_ALLOCATE_unknown:
524 return "unknown";
525#define OPENMP_ALLOCATE_MODIFIER(Name) \
526 case OMPC_ALLOCATE_##Name: \
527 return #Name;
528#include "clang/Basic/OpenMPKinds.def"
529 }
530 llvm_unreachable("Invalid OpenMP 'allocate' clause modifier");
531 case OMPC_num_threads:
532 switch (Type) {
533 case OMPC_NUMTHREADS_unknown:
534 return "unknown";
535#define OPENMP_NUMTHREADS_MODIFIER(Name) \
536 case OMPC_NUMTHREADS_##Name: \
537 return #Name;
538#include "clang/Basic/OpenMPKinds.def"
539 }
540 llvm_unreachable("Invalid OpenMP 'num_threads' clause modifier");
541 case OMPC_unknown:
542 case OMPC_threadprivate:
543 case OMPC_if:
544 case OMPC_final:
545 case OMPC_safelen:
546 case OMPC_simdlen:
547 case OMPC_sizes:
548 case OMPC_permutation:
549 case OMPC_allocator:
550 case OMPC_collapse:
551 case OMPC_private:
552 case OMPC_firstprivate:
553 case OMPC_shared:
554 case OMPC_task_reduction:
555 case OMPC_in_reduction:
556 case OMPC_aligned:
557 case OMPC_copyin:
558 case OMPC_copyprivate:
559 case OMPC_ordered:
560 case OMPC_nowait:
561 case OMPC_untied:
562 case OMPC_mergeable:
563 case OMPC_flush:
564 case OMPC_depobj:
565 case OMPC_read:
566 case OMPC_write:
567 case OMPC_capture:
568 case OMPC_compare:
569 case OMPC_seq_cst:
570 case OMPC_acq_rel:
571 case OMPC_acquire:
572 case OMPC_release:
573 case OMPC_relaxed:
574 case OMPC_threads:
575 case OMPC_simd:
576 case OMPC_num_teams:
577 case OMPC_thread_limit:
578 case OMPC_priority:
579 case OMPC_nogroup:
580 case OMPC_hint:
581 case OMPC_uniform:
582 case OMPC_use_device_ptr:
583 case OMPC_use_device_addr:
584 case OMPC_is_device_ptr:
585 case OMPC_has_device_addr:
586 case OMPC_unified_address:
587 case OMPC_unified_shared_memory:
588 case OMPC_reverse_offload:
589 case OMPC_dynamic_allocators:
590 case OMPC_self_maps:
591 case OMPC_match:
592 case OMPC_nontemporal:
593 case OMPC_destroy:
594 case OMPC_detach:
595 case OMPC_novariants:
596 case OMPC_nocontext:
597 case OMPC_inclusive:
598 case OMPC_exclusive:
599 case OMPC_uses_allocators:
600 case OMPC_affinity:
601 case OMPC_when:
602 case OMPC_append_args:
603 break;
604 default:
605 break;
606 }
607 llvm_unreachable("Invalid OpenMP simple clause kind");
608}
609
610bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) {
611 return getDirectiveAssociation(D: DKind) == Association::Loop;
612}
613
614bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) {
615 return DKind == OMPD_for || DKind == OMPD_for_simd ||
616 DKind == OMPD_sections || DKind == OMPD_section ||
617 DKind == OMPD_single || DKind == OMPD_parallel_for ||
618 DKind == OMPD_parallel_for_simd || DKind == OMPD_parallel_sections ||
619 DKind == OMPD_target_parallel_for ||
620 DKind == OMPD_distribute_parallel_for ||
621 DKind == OMPD_distribute_parallel_for_simd ||
622 DKind == OMPD_target_parallel_for_simd ||
623 DKind == OMPD_teams_distribute_parallel_for_simd ||
624 DKind == OMPD_teams_distribute_parallel_for ||
625 DKind == OMPD_target_teams_distribute_parallel_for ||
626 DKind == OMPD_target_teams_distribute_parallel_for_simd ||
627 DKind == OMPD_parallel_loop || DKind == OMPD_teams_loop ||
628 DKind == OMPD_target_parallel_loop || DKind == OMPD_target_teams_loop;
629}
630
631bool clang::isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind) {
632 return DKind == OMPD_taskloop ||
633 llvm::is_contained(Range: getLeafConstructs(D: DKind), Element: OMPD_taskloop);
634}
635
636bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) {
637 if (DKind == OMPD_teams_loop)
638 return true;
639 return DKind == OMPD_parallel ||
640 llvm::is_contained(Range: getLeafConstructs(D: DKind), Element: OMPD_parallel);
641}
642
643bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) {
644 return DKind == OMPD_target ||
645 llvm::is_contained(Range: getLeafConstructs(D: DKind), Element: OMPD_target);
646}
647
648bool clang::isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind) {
649 return DKind == OMPD_target_data || DKind == OMPD_target_enter_data ||
650 DKind == OMPD_target_exit_data || DKind == OMPD_target_update;
651}
652
653bool clang::isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind) {
654 if (DKind == OMPD_teams)
655 return true;
656 ArrayRef<Directive> Leaves = getLeafConstructs(D: DKind);
657 return !Leaves.empty() && Leaves.front() == OMPD_teams;
658}
659
660bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind) {
661 return DKind == OMPD_teams ||
662 llvm::is_contained(Range: getLeafConstructs(D: DKind), Element: OMPD_teams);
663}
664
665bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) {
666 // Avoid OMPD_declare_simd
667 if (getDirectiveAssociation(D: DKind) != Association::Loop)
668 return false;
669 // Formally, OMPD_end_do_simd also has a loop association, but
670 // it's a Fortran-specific directive.
671
672 return DKind == OMPD_simd ||
673 llvm::is_contained(Range: getLeafConstructs(D: DKind), Element: OMPD_simd);
674}
675
676bool clang::isOpenMPNestingDistributeDirective(OpenMPDirectiveKind Kind) {
677 if (Kind == OMPD_distribute)
678 return true;
679 ArrayRef<Directive> Leaves = getLeafConstructs(D: Kind);
680 return !Leaves.empty() && Leaves.front() == OMPD_distribute;
681}
682
683bool clang::isOpenMPDistributeDirective(OpenMPDirectiveKind Kind) {
684 return Kind == OMPD_distribute ||
685 llvm::is_contained(Range: getLeafConstructs(D: Kind), Element: OMPD_distribute);
686}
687
688bool clang::isOpenMPGenericLoopDirective(OpenMPDirectiveKind Kind) {
689 if (Kind == OMPD_loop)
690 return true;
691 ArrayRef<Directive> Leaves = getLeafConstructs(D: Kind);
692 return !Leaves.empty() && Leaves.back() == OMPD_loop;
693}
694
695bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) {
696 return Kind == OMPC_private || Kind == OMPC_firstprivate ||
697 Kind == OMPC_lastprivate || Kind == OMPC_linear ||
698 Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
699 Kind == OMPC_in_reduction; // TODO add next clauses like 'reduction'.
700}
701
702bool clang::isOpenMPThreadPrivate(OpenMPClauseKind Kind) {
703 return Kind == OMPC_threadprivate || Kind == OMPC_copyin;
704}
705
706bool clang::isOpenMPTaskingDirective(OpenMPDirectiveKind Kind) {
707 return Kind == OMPD_task || isOpenMPTaskLoopDirective(DKind: Kind);
708}
709
710bool clang::isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind) {
711 return Kind == OMPD_distribute_parallel_for ||
712 Kind == OMPD_distribute_parallel_for_simd ||
713 Kind == OMPD_teams_distribute_parallel_for_simd ||
714 Kind == OMPD_teams_distribute_parallel_for ||
715 Kind == OMPD_target_teams_distribute_parallel_for ||
716 Kind == OMPD_target_teams_distribute_parallel_for_simd ||
717 Kind == OMPD_teams_loop || Kind == OMPD_target_teams_loop;
718}
719
720bool clang::isOpenMPLoopTransformationDirective(OpenMPDirectiveKind DKind) {
721 return DKind == OMPD_tile || DKind == OMPD_unroll || DKind == OMPD_reverse ||
722 DKind == OMPD_interchange || DKind == OMPD_stripe;
723}
724
725bool clang::isOpenMPCombinedParallelADirective(OpenMPDirectiveKind DKind) {
726 return DKind == OMPD_parallel_for || DKind == OMPD_parallel_for_simd ||
727 DKind == OMPD_parallel_master ||
728 DKind == OMPD_parallel_master_taskloop ||
729 DKind == OMPD_parallel_master_taskloop_simd ||
730 DKind == OMPD_parallel_sections;
731}
732
733bool clang::needsTaskBasedThreadLimit(OpenMPDirectiveKind DKind) {
734 return DKind == OMPD_target || DKind == OMPD_target_parallel ||
735 DKind == OMPD_target_parallel_for ||
736 DKind == OMPD_target_parallel_for_simd || DKind == OMPD_target_simd ||
737 DKind == OMPD_target_parallel_loop;
738}
739
740bool clang::isOpenMPExecutableDirective(OpenMPDirectiveKind DKind) {
741 if (DKind == OMPD_error)
742 return true;
743 Category Cat = getDirectiveCategory(D: DKind);
744 return Cat == Category::Executable || Cat == Category::Subsidiary;
745}
746
747bool clang::isOpenMPInformationalDirective(OpenMPDirectiveKind DKind) {
748 if (DKind == OMPD_error)
749 return true;
750 Category Cat = getDirectiveCategory(D: DKind);
751 return Cat == Category::Informational;
752}
753
754bool clang::isOpenMPCapturingDirective(OpenMPDirectiveKind DKind) {
755 if (isOpenMPExecutableDirective(DKind)) {
756 switch (DKind) {
757 case OMPD_atomic:
758 case OMPD_barrier:
759 case OMPD_cancel:
760 case OMPD_cancellation_point:
761 case OMPD_critical:
762 case OMPD_depobj:
763 case OMPD_error:
764 case OMPD_flush:
765 case OMPD_masked:
766 case OMPD_master:
767 case OMPD_section:
768 case OMPD_taskwait:
769 case OMPD_taskyield:
770 case OMPD_assume:
771 return false;
772 default:
773 return !isOpenMPLoopTransformationDirective(DKind);
774 }
775 }
776 // Non-executable directives.
777 switch (DKind) {
778 case OMPD_metadirective:
779 case OMPD_nothing:
780 return true;
781 default:
782 break;
783 }
784 return false;
785}
786
787bool clang::isOpenMPOrderConcurrentNestableDirective(
788 OpenMPDirectiveKind DKind, const LangOptions &LangOpts) {
789 // Directives strictly nestable in a construct with order(concurrent) are:
790 // OpenMP 5.x: loop, parallel, simd, combined directive starting with parallel
791 // OpenMP 6.0: above plus atomic and all loop-transformation directives
792
793 if (DKind == OMPD_loop || DKind == OMPD_parallel || DKind == OMPD_simd ||
794 isOpenMPCombinedParallelADirective(DKind))
795 return true;
796
797 if (LangOpts.OpenMP >= 60)
798 return DKind == OMPD_atomic ||
799 isOpenMPLoopTransformationDirective(DKind);
800
801 return false;
802}
803
804void clang::getOpenMPCaptureRegions(
805 SmallVectorImpl<OpenMPDirectiveKind> &CaptureRegions,
806 OpenMPDirectiveKind DKind) {
807 assert(unsigned(DKind) < llvm::omp::Directive_enumSize);
808 assert(isOpenMPCapturingDirective(DKind) && "Expecting capturing directive");
809
810 auto GetRegionsForLeaf = [&](OpenMPDirectiveKind LKind) {
811 assert(isLeafConstruct(LKind) && "Epecting leaf directive");
812 // Whether a leaf would require OMPD_unknown if it occured on its own.
813 switch (LKind) {
814 case OMPD_metadirective:
815 CaptureRegions.push_back(Elt: OMPD_metadirective);
816 break;
817 case OMPD_nothing:
818 CaptureRegions.push_back(Elt: OMPD_nothing);
819 break;
820 case OMPD_parallel:
821 CaptureRegions.push_back(Elt: OMPD_parallel);
822 break;
823 case OMPD_target:
824 CaptureRegions.push_back(Elt: OMPD_task);
825 CaptureRegions.push_back(Elt: OMPD_target);
826 break;
827 case OMPD_task:
828 case OMPD_target_enter_data:
829 case OMPD_target_exit_data:
830 case OMPD_target_update:
831 CaptureRegions.push_back(Elt: OMPD_task);
832 break;
833 case OMPD_teams:
834 CaptureRegions.push_back(Elt: OMPD_teams);
835 break;
836 case OMPD_taskloop:
837 CaptureRegions.push_back(Elt: OMPD_taskloop);
838 break;
839 case OMPD_loop:
840 // TODO: 'loop' may require different capture regions depending on the
841 // bind clause or the parent directive when there is no bind clause.
842 // If any of the directives that push regions here are parents of 'loop',
843 // assume 'parallel'. Otherwise do nothing.
844 if (!CaptureRegions.empty() &&
845 !llvm::is_contained(Range&: CaptureRegions, Element: OMPD_parallel))
846 CaptureRegions.push_back(Elt: OMPD_parallel);
847 else
848 return true;
849 break;
850 case OMPD_dispatch:
851 case OMPD_distribute:
852 case OMPD_for:
853 case OMPD_ordered:
854 case OMPD_scope:
855 case OMPD_sections:
856 case OMPD_simd:
857 case OMPD_single:
858 case OMPD_target_data:
859 case OMPD_taskgroup:
860 case OMPD_stripe:
861 // These directives (when standalone) use OMPD_unknown as the region,
862 // but when they're constituents of a compound directive, and other
863 // leafs from that directive have specific regions, then these directives
864 // add no additional regions.
865 return true;
866 case OMPD_masked:
867 case OMPD_master:
868 return false;
869 default:
870 llvm::errs() << getOpenMPDirectiveName(D: LKind, Ver: llvm::omp::FallbackVersion)
871 << '\n';
872 llvm_unreachable("Unexpected directive");
873 }
874 return false;
875 };
876
877 bool MayNeedUnknownRegion = false;
878 for (OpenMPDirectiveKind L : getLeafConstructsOrSelf(D: DKind))
879 MayNeedUnknownRegion |= GetRegionsForLeaf(L);
880
881 // We need OMPD_unknown when no regions were added, and specific leaf
882 // constructs were present. Push a single OMPD_unknown as the capture
883 /// region.
884 if (CaptureRegions.empty() && MayNeedUnknownRegion)
885 CaptureRegions.push_back(Elt: OMPD_unknown);
886
887 // OMPD_unknown is only expected as the only region. If other regions
888 // are present OMPD_unknown should not be present.
889 assert((CaptureRegions[0] == OMPD_unknown ||
890 !llvm::is_contained(CaptureRegions, OMPD_unknown)) &&
891 "Misplaced OMPD_unknown");
892}
893
894bool clang::checkFailClauseParameter(OpenMPClauseKind FailClauseParameter) {
895 return FailClauseParameter == llvm::omp::OMPC_acquire ||
896 FailClauseParameter == llvm::omp::OMPC_relaxed ||
897 FailClauseParameter == llvm::omp::OMPC_seq_cst;
898}
899
900