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