xref: /llvm-project/clang/lib/Basic/OpenMPKinds.cpp (revision 435e58468a1a99a4bbfad88d060abd37a9bc6928)
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 
20 using namespace clang;
21 using namespace llvm::omp;
22 
23 unsigned 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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(OMPC_ALLOCATE_unknown);
188   case OMPC_unknown:
189   case OMPC_threadprivate:
190   case OMPC_if:
191   case OMPC_final:
192   case OMPC_num_threads:
193   case OMPC_safelen:
194   case OMPC_simdlen:
195   case OMPC_sizes:
196   case OMPC_permutation:
197   case OMPC_allocator:
198   case OMPC_collapse:
199   case OMPC_private:
200   case OMPC_firstprivate:
201   case OMPC_shared:
202   case OMPC_task_reduction:
203   case OMPC_in_reduction:
204   case OMPC_aligned:
205   case OMPC_copyin:
206   case OMPC_copyprivate:
207   case OMPC_ordered:
208   case OMPC_nowait:
209   case OMPC_untied:
210   case OMPC_mergeable:
211   case OMPC_flush:
212   case OMPC_depobj:
213   case OMPC_read:
214   case OMPC_write:
215   case OMPC_capture:
216   case OMPC_compare:
217   case OMPC_seq_cst:
218   case OMPC_acq_rel:
219   case OMPC_acquire:
220   case OMPC_release:
221   case OMPC_relaxed:
222   case OMPC_threads:
223   case OMPC_simd:
224   case OMPC_num_teams:
225   case OMPC_thread_limit:
226   case OMPC_priority:
227   case OMPC_nogroup:
228   case OMPC_hint:
229   case OMPC_uniform:
230   case OMPC_use_device_ptr:
231   case OMPC_use_device_addr:
232   case OMPC_is_device_ptr:
233   case OMPC_has_device_addr:
234   case OMPC_unified_address:
235   case OMPC_unified_shared_memory:
236   case OMPC_reverse_offload:
237   case OMPC_dynamic_allocators:
238   case OMPC_match:
239   case OMPC_nontemporal:
240   case OMPC_destroy:
241   case OMPC_novariants:
242   case OMPC_nocontext:
243   case OMPC_detach:
244   case OMPC_inclusive:
245   case OMPC_exclusive:
246   case OMPC_uses_allocators:
247   case OMPC_affinity:
248   case OMPC_when:
249   case OMPC_append_args:
250     break;
251   default:
252     break;
253   }
254   llvm_unreachable("Invalid OpenMP simple clause kind");
255 }
256 
257 const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
258                                                  unsigned Type) {
259   switch (Kind) {
260   case OMPC_default:
261     switch (llvm::omp::DefaultKind(Type)) {
262 #define OMP_DEFAULT_KIND(Enum, Name)                                           \
263   case Enum:                                                                   \
264     return Name;
265 #include "llvm/Frontend/OpenMP/OMPKinds.def"
266     }
267     llvm_unreachable("Invalid OpenMP 'default' clause type");
268   case OMPC_proc_bind:
269     switch (Type) {
270 #define OMP_PROC_BIND_KIND(Enum, Name, Value)                                  \
271   case Value:                                                                  \
272     return Name;
273 #include "llvm/Frontend/OpenMP/OMPKinds.def"
274     }
275     llvm_unreachable("Invalid OpenMP 'proc_bind' clause type");
276   case OMPC_schedule:
277     switch (Type) {
278     case OMPC_SCHEDULE_unknown:
279     case OMPC_SCHEDULE_MODIFIER_last:
280       return "unknown";
281 #define OPENMP_SCHEDULE_KIND(Name)                                             \
282     case OMPC_SCHEDULE_##Name:                                                 \
283       return #Name;
284 #define OPENMP_SCHEDULE_MODIFIER(Name)                                         \
285     case OMPC_SCHEDULE_MODIFIER_##Name:                                        \
286       return #Name;
287 #include "clang/Basic/OpenMPKinds.def"
288     }
289     llvm_unreachable("Invalid OpenMP 'schedule' clause type");
290   case OMPC_depend:
291     switch (Type) {
292     case OMPC_DEPEND_unknown:
293       return "unknown";
294 #define OPENMP_DEPEND_KIND(Name)                                             \
295   case OMPC_DEPEND_##Name:                                                   \
296     return #Name;
297 #include "clang/Basic/OpenMPKinds.def"
298     }
299     llvm_unreachable("Invalid OpenMP 'depend' clause type");
300   case OMPC_doacross:
301     switch (Type) {
302     case OMPC_DOACROSS_unknown:
303       return "unknown";
304 #define OPENMP_DOACROSS_MODIFIER(Name)                                         \
305   case OMPC_DOACROSS_##Name:                                                   \
306     return #Name;
307 #include "clang/Basic/OpenMPKinds.def"
308     }
309     llvm_unreachable("Invalid OpenMP 'doacross' clause type");
310   case OMPC_linear:
311     switch (Type) {
312     case OMPC_LINEAR_unknown:
313       return "unknown";
314 #define OPENMP_LINEAR_KIND(Name)                                             \
315   case OMPC_LINEAR_##Name:                                                   \
316     return #Name;
317 #include "clang/Basic/OpenMPKinds.def"
318     }
319     llvm_unreachable("Invalid OpenMP 'linear' clause type");
320   case OMPC_map:
321     switch (Type) {
322     case OMPC_MAP_unknown:
323     case OMPC_MAP_MODIFIER_last:
324       return "unknown";
325 #define OPENMP_MAP_KIND(Name)                                                \
326   case OMPC_MAP_##Name:                                                      \
327     return #Name;
328 #define OPENMP_MAP_MODIFIER_KIND(Name)                                       \
329   case OMPC_MAP_MODIFIER_##Name:                                             \
330     return #Name;
331 #include "clang/Basic/OpenMPKinds.def"
332     default:
333       break;
334     }
335     llvm_unreachable("Invalid OpenMP 'map' clause type");
336   case OMPC_to:
337   case OMPC_from:
338     switch (Type) {
339     case OMPC_MOTION_MODIFIER_unknown:
340       return "unknown";
341 #define OPENMP_MOTION_MODIFIER_KIND(Name)                                      \
342   case OMPC_MOTION_MODIFIER_##Name:                                            \
343     return #Name;
344 #include "clang/Basic/OpenMPKinds.def"
345     default:
346       break;
347     }
348     llvm_unreachable("Invalid OpenMP 'to' or 'from' clause type");
349   case OMPC_dist_schedule:
350     switch (Type) {
351     case OMPC_DIST_SCHEDULE_unknown:
352       return "unknown";
353 #define OPENMP_DIST_SCHEDULE_KIND(Name)                                      \
354   case OMPC_DIST_SCHEDULE_##Name:                                            \
355     return #Name;
356 #include "clang/Basic/OpenMPKinds.def"
357     }
358     llvm_unreachable("Invalid OpenMP 'dist_schedule' clause type");
359   case OMPC_defaultmap:
360     switch (Type) {
361     case OMPC_DEFAULTMAP_unknown:
362     case OMPC_DEFAULTMAP_MODIFIER_last:
363       return "unknown";
364 #define OPENMP_DEFAULTMAP_KIND(Name)                                         \
365     case OMPC_DEFAULTMAP_##Name:                                             \
366       return #Name;
367 #define OPENMP_DEFAULTMAP_MODIFIER(Name)                                     \
368     case OMPC_DEFAULTMAP_MODIFIER_##Name:                                    \
369       return #Name;
370 #include "clang/Basic/OpenMPKinds.def"
371     }
372     llvm_unreachable("Invalid OpenMP 'schedule' clause type");
373   case OMPC_atomic_default_mem_order:
374     switch (Type) {
375     case OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown:
376       return "unknown";
377 #define OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(Name)                           \
378     case OMPC_ATOMIC_DEFAULT_MEM_ORDER_##Name:                               \
379       return #Name;
380 #include "clang/Basic/OpenMPKinds.def"
381 }
382     llvm_unreachable("Invalid OpenMP 'atomic_default_mem_order' clause type");
383   case OMPC_device_type:
384     switch (Type) {
385     case OMPC_DEVICE_TYPE_unknown:
386       return "unknown";
387 #define OPENMP_DEVICE_TYPE_KIND(Name)                                          \
388     case OMPC_DEVICE_TYPE_##Name:                                              \
389       return #Name;
390 #include "clang/Basic/OpenMPKinds.def"
391     }
392     llvm_unreachable("Invalid OpenMP 'device_type' clause type");
393   case OMPC_at:
394     switch (Type) {
395     case OMPC_AT_unknown:
396       return "unknown";
397 #define OPENMP_AT_KIND(Name)                                                   \
398   case OMPC_AT_##Name:                                                         \
399     return #Name;
400 #include "clang/Basic/OpenMPKinds.def"
401     }
402     llvm_unreachable("Invalid OpenMP 'at' clause type");
403   case OMPC_severity:
404     switch (Type) {
405     case OMPC_SEVERITY_unknown:
406       return "unknown";
407 #define OPENMP_SEVERITY_KIND(Name)                                             \
408   case OMPC_SEVERITY_##Name:                                                   \
409     return #Name;
410 #include "clang/Basic/OpenMPKinds.def"
411     }
412     llvm_unreachable("Invalid OpenMP 'severity' clause type");
413   case OMPC_lastprivate:
414     switch (Type) {
415     case OMPC_LASTPRIVATE_unknown:
416       return "unknown";
417 #define OPENMP_LASTPRIVATE_KIND(Name)                                          \
418     case OMPC_LASTPRIVATE_##Name:                                              \
419       return #Name;
420 #include "clang/Basic/OpenMPKinds.def"
421     }
422     llvm_unreachable("Invalid OpenMP 'lastprivate' clause type");
423   case OMPC_order:
424     switch (Type) {
425     case OMPC_ORDER_unknown:
426     case OMPC_ORDER_MODIFIER_last:
427       return "unknown";
428 #define OPENMP_ORDER_KIND(Name)                                                \
429   case OMPC_ORDER_##Name:                                                      \
430     return #Name;
431 #define OPENMP_ORDER_MODIFIER(Name)                                            \
432   case OMPC_ORDER_MODIFIER_##Name:                                             \
433     return #Name;
434 #include "clang/Basic/OpenMPKinds.def"
435     }
436     llvm_unreachable("Invalid OpenMP 'order' clause type");
437   case OMPC_update:
438     switch (Type) {
439     case OMPC_DEPEND_unknown:
440       return "unknown";
441 #define OPENMP_DEPEND_KIND(Name)                                               \
442   case OMPC_DEPEND_##Name:                                                     \
443     return #Name;
444 #include "clang/Basic/OpenMPKinds.def"
445     }
446     llvm_unreachable("Invalid OpenMP 'depend' clause type");
447   case OMPC_fail: {
448     OpenMPClauseKind CK = static_cast<OpenMPClauseKind>(Type);
449     return getOpenMPClauseName(CK).data();
450     llvm_unreachable("Invalid OpenMP 'fail' clause modifier");
451   }
452   case OMPC_device:
453     switch (Type) {
454     case OMPC_DEVICE_unknown:
455       return "unknown";
456 #define OPENMP_DEVICE_MODIFIER(Name)                                           \
457   case OMPC_DEVICE_##Name:                                                     \
458     return #Name;
459 #include "clang/Basic/OpenMPKinds.def"
460     }
461     llvm_unreachable("Invalid OpenMP 'device' clause modifier");
462   case OMPC_reduction:
463     switch (Type) {
464     case OMPC_REDUCTION_unknown:
465       return "unknown";
466 #define OPENMP_REDUCTION_MODIFIER(Name)                                        \
467   case OMPC_REDUCTION_##Name:                                                  \
468     return #Name;
469 #include "clang/Basic/OpenMPKinds.def"
470     }
471     llvm_unreachable("Invalid OpenMP 'reduction' clause modifier");
472   case OMPC_adjust_args:
473     switch (Type) {
474     case OMPC_ADJUST_ARGS_unknown:
475       return "unknown";
476 #define OPENMP_ADJUST_ARGS_KIND(Name)                                          \
477   case OMPC_ADJUST_ARGS_##Name:                                                \
478     return #Name;
479 #include "clang/Basic/OpenMPKinds.def"
480     }
481     llvm_unreachable("Invalid OpenMP 'adjust_args' clause kind");
482   case OMPC_bind:
483     switch (Type) {
484     case OMPC_BIND_unknown:
485       return "unknown";
486 #define OPENMP_BIND_KIND(Name)                                                 \
487   case OMPC_BIND_##Name:                                                       \
488     return #Name;
489 #include "clang/Basic/OpenMPKinds.def"
490     }
491     llvm_unreachable("Invalid OpenMP 'bind' clause type");
492   case OMPC_grainsize:
493     switch (Type) {
494     case OMPC_GRAINSIZE_unknown:
495       return "unknown";
496 #define OPENMP_GRAINSIZE_MODIFIER(Name)                                        \
497   case OMPC_GRAINSIZE_##Name:                                                  \
498     return #Name;
499 #include "clang/Basic/OpenMPKinds.def"
500     }
501     llvm_unreachable("Invalid OpenMP 'grainsize' clause modifier");
502   case OMPC_num_tasks:
503     switch (Type) {
504     case OMPC_NUMTASKS_unknown:
505       return "unknown";
506 #define OPENMP_NUMTASKS_MODIFIER(Name)                                         \
507   case OMPC_NUMTASKS_##Name:                                                   \
508     return #Name;
509 #include "clang/Basic/OpenMPKinds.def"
510     }
511     llvm_unreachable("Invalid OpenMP 'num_tasks' clause modifier");
512   case OMPC_allocate:
513     switch (Type) {
514     case OMPC_ALLOCATE_unknown:
515       return "unknown";
516 #define OPENMP_ALLOCATE_MODIFIER(Name)                                         \
517   case OMPC_ALLOCATE_##Name:                                                   \
518     return #Name;
519 #include "clang/Basic/OpenMPKinds.def"
520     }
521     llvm_unreachable("Invalid OpenMP 'allocate' clause modifier");
522   case OMPC_unknown:
523   case OMPC_threadprivate:
524   case OMPC_if:
525   case OMPC_final:
526   case OMPC_num_threads:
527   case OMPC_safelen:
528   case OMPC_simdlen:
529   case OMPC_sizes:
530   case OMPC_permutation:
531   case OMPC_allocator:
532   case OMPC_collapse:
533   case OMPC_private:
534   case OMPC_firstprivate:
535   case OMPC_shared:
536   case OMPC_task_reduction:
537   case OMPC_in_reduction:
538   case OMPC_aligned:
539   case OMPC_copyin:
540   case OMPC_copyprivate:
541   case OMPC_ordered:
542   case OMPC_nowait:
543   case OMPC_untied:
544   case OMPC_mergeable:
545   case OMPC_flush:
546   case OMPC_depobj:
547   case OMPC_read:
548   case OMPC_write:
549   case OMPC_capture:
550   case OMPC_compare:
551   case OMPC_seq_cst:
552   case OMPC_acq_rel:
553   case OMPC_acquire:
554   case OMPC_release:
555   case OMPC_relaxed:
556   case OMPC_threads:
557   case OMPC_simd:
558   case OMPC_num_teams:
559   case OMPC_thread_limit:
560   case OMPC_priority:
561   case OMPC_nogroup:
562   case OMPC_hint:
563   case OMPC_uniform:
564   case OMPC_use_device_ptr:
565   case OMPC_use_device_addr:
566   case OMPC_is_device_ptr:
567   case OMPC_has_device_addr:
568   case OMPC_unified_address:
569   case OMPC_unified_shared_memory:
570   case OMPC_reverse_offload:
571   case OMPC_dynamic_allocators:
572   case OMPC_match:
573   case OMPC_nontemporal:
574   case OMPC_destroy:
575   case OMPC_detach:
576   case OMPC_novariants:
577   case OMPC_nocontext:
578   case OMPC_inclusive:
579   case OMPC_exclusive:
580   case OMPC_uses_allocators:
581   case OMPC_affinity:
582   case OMPC_when:
583   case OMPC_append_args:
584     break;
585   default:
586     break;
587   }
588   llvm_unreachable("Invalid OpenMP simple clause kind");
589 }
590 
591 bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) {
592   return getDirectiveAssociation(DKind) == Association::Loop;
593 }
594 
595 bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) {
596   return DKind == OMPD_for || DKind == OMPD_for_simd ||
597          DKind == OMPD_sections || DKind == OMPD_section ||
598          DKind == OMPD_single || DKind == OMPD_parallel_for ||
599          DKind == OMPD_parallel_for_simd || DKind == OMPD_parallel_sections ||
600          DKind == OMPD_target_parallel_for ||
601          DKind == OMPD_distribute_parallel_for ||
602          DKind == OMPD_distribute_parallel_for_simd ||
603          DKind == OMPD_target_parallel_for_simd ||
604          DKind == OMPD_teams_distribute_parallel_for_simd ||
605          DKind == OMPD_teams_distribute_parallel_for ||
606          DKind == OMPD_target_teams_distribute_parallel_for ||
607          DKind == OMPD_target_teams_distribute_parallel_for_simd ||
608          DKind == OMPD_parallel_loop || DKind == OMPD_teams_loop ||
609          DKind == OMPD_target_parallel_loop || DKind == OMPD_target_teams_loop;
610 }
611 
612 bool clang::isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind) {
613   return DKind == OMPD_taskloop ||
614          llvm::is_contained(getLeafConstructs(DKind), OMPD_taskloop);
615 }
616 
617 bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) {
618   if (DKind == OMPD_teams_loop)
619     return true;
620   return DKind == OMPD_parallel ||
621          llvm::is_contained(getLeafConstructs(DKind), OMPD_parallel);
622 }
623 
624 bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) {
625   return DKind == OMPD_target ||
626          llvm::is_contained(getLeafConstructs(DKind), OMPD_target);
627 }
628 
629 bool clang::isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind) {
630   return DKind == OMPD_target_data || DKind == OMPD_target_enter_data ||
631          DKind == OMPD_target_exit_data || DKind == OMPD_target_update;
632 }
633 
634 bool clang::isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind) {
635   if (DKind == OMPD_teams)
636     return true;
637   ArrayRef<Directive> Leaves = getLeafConstructs(DKind);
638   return !Leaves.empty() && Leaves.front() == OMPD_teams;
639 }
640 
641 bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind) {
642   return DKind == OMPD_teams ||
643          llvm::is_contained(getLeafConstructs(DKind), OMPD_teams);
644 }
645 
646 bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) {
647   // Avoid OMPD_declare_simd
648   if (getDirectiveAssociation(DKind) != Association::Loop)
649     return false;
650   // Formally, OMPD_end_do_simd also has a loop association, but
651   // it's a Fortran-specific directive.
652 
653   return DKind == OMPD_simd ||
654          llvm::is_contained(getLeafConstructs(DKind), OMPD_simd);
655 }
656 
657 bool clang::isOpenMPNestingDistributeDirective(OpenMPDirectiveKind Kind) {
658   if (Kind == OMPD_distribute)
659     return true;
660   ArrayRef<Directive> Leaves = getLeafConstructs(Kind);
661   return !Leaves.empty() && Leaves.front() == OMPD_distribute;
662 }
663 
664 bool clang::isOpenMPDistributeDirective(OpenMPDirectiveKind Kind) {
665   return Kind == OMPD_distribute ||
666          llvm::is_contained(getLeafConstructs(Kind), OMPD_distribute);
667 }
668 
669 bool clang::isOpenMPGenericLoopDirective(OpenMPDirectiveKind Kind) {
670   if (Kind == OMPD_loop)
671     return true;
672   ArrayRef<Directive> Leaves = getLeafConstructs(Kind);
673   return !Leaves.empty() && Leaves.back() == OMPD_loop;
674 }
675 
676 bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) {
677   return Kind == OMPC_private || Kind == OMPC_firstprivate ||
678          Kind == OMPC_lastprivate || Kind == OMPC_linear ||
679          Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
680          Kind == OMPC_in_reduction; // TODO add next clauses like 'reduction'.
681 }
682 
683 bool clang::isOpenMPThreadPrivate(OpenMPClauseKind Kind) {
684   return Kind == OMPC_threadprivate || Kind == OMPC_copyin;
685 }
686 
687 bool clang::isOpenMPTaskingDirective(OpenMPDirectiveKind Kind) {
688   return Kind == OMPD_task || isOpenMPTaskLoopDirective(Kind);
689 }
690 
691 bool clang::isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind) {
692   return Kind == OMPD_distribute_parallel_for ||
693          Kind == OMPD_distribute_parallel_for_simd ||
694          Kind == OMPD_teams_distribute_parallel_for_simd ||
695          Kind == OMPD_teams_distribute_parallel_for ||
696          Kind == OMPD_target_teams_distribute_parallel_for ||
697          Kind == OMPD_target_teams_distribute_parallel_for_simd ||
698          Kind == OMPD_teams_loop || Kind == OMPD_target_teams_loop;
699 }
700 
701 bool clang::isOpenMPLoopTransformationDirective(OpenMPDirectiveKind DKind) {
702   return DKind == OMPD_tile || DKind == OMPD_unroll || DKind == OMPD_reverse ||
703          DKind == OMPD_interchange;
704 }
705 
706 bool clang::isOpenMPCombinedParallelADirective(OpenMPDirectiveKind DKind) {
707   return DKind == OMPD_parallel_for || DKind == OMPD_parallel_for_simd ||
708          DKind == OMPD_parallel_master ||
709          DKind == OMPD_parallel_master_taskloop ||
710          DKind == OMPD_parallel_master_taskloop_simd ||
711          DKind == OMPD_parallel_sections;
712 }
713 
714 bool clang::needsTaskBasedThreadLimit(OpenMPDirectiveKind DKind) {
715   return DKind == OMPD_target || DKind == OMPD_target_parallel ||
716          DKind == OMPD_target_parallel_for ||
717          DKind == OMPD_target_parallel_for_simd || DKind == OMPD_target_simd ||
718          DKind == OMPD_target_parallel_loop;
719 }
720 
721 bool clang::isOpenMPExecutableDirective(OpenMPDirectiveKind DKind) {
722   if (DKind == OMPD_error)
723     return true;
724   Category Cat = getDirectiveCategory(DKind);
725   return Cat == Category::Executable || Cat == Category::Subsidiary;
726 }
727 
728 bool clang::isOpenMPInformationalDirective(OpenMPDirectiveKind DKind) {
729   if (DKind == OMPD_error)
730     return true;
731   Category Cat = getDirectiveCategory(DKind);
732   return Cat == Category::Informational;
733 }
734 
735 bool clang::isOpenMPCapturingDirective(OpenMPDirectiveKind DKind) {
736   if (isOpenMPExecutableDirective(DKind)) {
737     switch (DKind) {
738     case OMPD_atomic:
739     case OMPD_barrier:
740     case OMPD_cancel:
741     case OMPD_cancellation_point:
742     case OMPD_critical:
743     case OMPD_depobj:
744     case OMPD_error:
745     case OMPD_flush:
746     case OMPD_masked:
747     case OMPD_master:
748     case OMPD_section:
749     case OMPD_taskwait:
750     case OMPD_taskyield:
751     case OMPD_assume:
752       return false;
753     default:
754       return !isOpenMPLoopTransformationDirective(DKind);
755     }
756   }
757   // Non-executable directives.
758   switch (DKind) {
759   case OMPD_metadirective:
760   case OMPD_nothing:
761     return true;
762   default:
763     break;
764   }
765   return false;
766 }
767 
768 void clang::getOpenMPCaptureRegions(
769     SmallVectorImpl<OpenMPDirectiveKind> &CaptureRegions,
770     OpenMPDirectiveKind DKind) {
771   assert(unsigned(DKind) < llvm::omp::Directive_enumSize);
772   assert(isOpenMPCapturingDirective(DKind) && "Expecting capturing directive");
773 
774   auto GetRegionsForLeaf = [&](OpenMPDirectiveKind LKind) {
775     assert(isLeafConstruct(LKind) && "Epecting leaf directive");
776     // Whether a leaf would require OMPD_unknown if it occured on its own.
777     switch (LKind) {
778     case OMPD_metadirective:
779       CaptureRegions.push_back(OMPD_metadirective);
780       break;
781     case OMPD_nothing:
782       CaptureRegions.push_back(OMPD_nothing);
783       break;
784     case OMPD_parallel:
785       CaptureRegions.push_back(OMPD_parallel);
786       break;
787     case OMPD_target:
788       CaptureRegions.push_back(OMPD_task);
789       CaptureRegions.push_back(OMPD_target);
790       break;
791     case OMPD_task:
792     case OMPD_target_enter_data:
793     case OMPD_target_exit_data:
794     case OMPD_target_update:
795       CaptureRegions.push_back(OMPD_task);
796       break;
797     case OMPD_teams:
798       CaptureRegions.push_back(OMPD_teams);
799       break;
800     case OMPD_taskloop:
801       CaptureRegions.push_back(OMPD_taskloop);
802       break;
803     case OMPD_loop:
804       // TODO: 'loop' may require different capture regions depending on the
805       // bind clause or the parent directive when there is no bind clause.
806       // If any of the directives that push regions here are parents of 'loop',
807       // assume 'parallel'. Otherwise do nothing.
808       if (!CaptureRegions.empty() &&
809           !llvm::is_contained(CaptureRegions, OMPD_parallel))
810         CaptureRegions.push_back(OMPD_parallel);
811       else
812         return true;
813       break;
814     case OMPD_dispatch:
815     case OMPD_distribute:
816     case OMPD_for:
817     case OMPD_ordered:
818     case OMPD_scope:
819     case OMPD_sections:
820     case OMPD_simd:
821     case OMPD_single:
822     case OMPD_target_data:
823     case OMPD_taskgroup:
824       // These directives (when standalone) use OMPD_unknown as the region,
825       // but when they're constituents of a compound directive, and other
826       // leafs from that directive have specific regions, then these directives
827       // add no additional regions.
828       return true;
829     case OMPD_masked:
830     case OMPD_master:
831       return false;
832     default:
833       llvm::errs() << getOpenMPDirectiveName(LKind) << '\n';
834       llvm_unreachable("Unexpected directive");
835     }
836     return false;
837   };
838 
839   bool MayNeedUnknownRegion = false;
840   for (OpenMPDirectiveKind L : getLeafConstructsOrSelf(DKind))
841     MayNeedUnknownRegion |= GetRegionsForLeaf(L);
842 
843   // We need OMPD_unknown when no regions were added, and specific leaf
844   // constructs were present. Push a single OMPD_unknown as the capture
845   /// region.
846   if (CaptureRegions.empty() && MayNeedUnknownRegion)
847     CaptureRegions.push_back(OMPD_unknown);
848 
849   // OMPD_unknown is only expected as the only region. If other regions
850   // are present OMPD_unknown should not be present.
851   assert((CaptureRegions[0] == OMPD_unknown ||
852           !llvm::is_contained(CaptureRegions, OMPD_unknown)) &&
853          "Misplaced OMPD_unknown");
854 }
855 
856 bool clang::checkFailClauseParameter(OpenMPClauseKind FailClauseParameter) {
857   return FailClauseParameter == llvm::omp::OMPC_acquire ||
858          FailClauseParameter == llvm::omp::OMPC_relaxed ||
859          FailClauseParameter == llvm::omp::OMPC_seq_cst;
860 }
861 
862