1//===--- OpenMPKinds.cpp - Token Kinds Support ----------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9/// \file
10/// \brief This file implements the OpenMP enum and support functions.
11///
12//===----------------------------------------------------------------------===//
13
14#include "clang/Basic/OpenMPKinds.h"
15#include "clang/Basic/IdentifierTable.h"
16#include "llvm/ADT/StringRef.h"
17#include "llvm/ADT/StringSwitch.h"
18#include "llvm/Support/ErrorHandling.h"
19#include <cassert>
20
21using namespace clang;
22
23OpenMPDirectiveKind clang::getOpenMPDirectiveKind(StringRef Str) {
24  return llvm::StringSwitch<OpenMPDirectiveKind>(Str)
25#define OPENMP_DIRECTIVE(Name) .Case(#Name, OMPD_##Name)
26#define OPENMP_DIRECTIVE_EXT(Name, Str) .Case(Str, OMPD_##Name)
27#include "clang/Basic/OpenMPKinds.def"
28      .Default(OMPD_unknown);
29}
30
31const char *clang::getOpenMPDirectiveName(OpenMPDirectiveKind Kind) {
32  assert(Kind <= OMPD_unknown);
33  switch (Kind) {
34  case OMPD_unknown:
35    return "unknown";
36#define OPENMP_DIRECTIVE(Name)                                                 \
37  case OMPD_##Name:                                                            \
38    return #Name;
39#define OPENMP_DIRECTIVE_EXT(Name, Str)                                        \
40  case OMPD_##Name:                                                            \
41    return Str;
42#include "clang/Basic/OpenMPKinds.def"
43    break;
44  }
45  llvm_unreachable("Invalid OpenMP directive kind");
46}
47
48OpenMPClauseKind clang::getOpenMPClauseKind(StringRef Str) {
49  return llvm::StringSwitch<OpenMPClauseKind>(Str)
50#define OPENMP_CLAUSE(Name, Class) .Case(#Name, OMPC_##Name)
51#include "clang/Basic/OpenMPKinds.def"
52      .Default(OMPC_unknown);
53}
54
55const char *clang::getOpenMPClauseName(OpenMPClauseKind Kind) {
56  assert(Kind <= OMPC_unknown);
57  switch (Kind) {
58  case OMPC_unknown:
59    return "unknown";
60#define OPENMP_CLAUSE(Name, Class)                                             \
61  case OMPC_##Name:                                                            \
62    return #Name;
63#include "clang/Basic/OpenMPKinds.def"
64  case OMPC_threadprivate:
65    return "threadprivate or thread local";
66  }
67  llvm_unreachable("Invalid OpenMP clause kind");
68}
69
70unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
71                                          StringRef Str) {
72  switch (Kind) {
73  case OMPC_default:
74    return llvm::StringSwitch<OpenMPDefaultClauseKind>(Str)
75#define OPENMP_DEFAULT_KIND(Name) .Case(#Name, OMPC_DEFAULT_##Name)
76#include "clang/Basic/OpenMPKinds.def"
77        .Default(OMPC_DEFAULT_unknown);
78  case OMPC_proc_bind:
79    return llvm::StringSwitch<OpenMPProcBindClauseKind>(Str)
80#define OPENMP_PROC_BIND_KIND(Name) .Case(#Name, OMPC_PROC_BIND_##Name)
81#include "clang/Basic/OpenMPKinds.def"
82        .Default(OMPC_PROC_BIND_unknown);
83  case OMPC_schedule:
84    return llvm::StringSwitch<OpenMPScheduleClauseKind>(Str)
85#define OPENMP_SCHEDULE_KIND(Name) .Case(#Name, OMPC_SCHEDULE_##Name)
86#include "clang/Basic/OpenMPKinds.def"
87        .Default(OMPC_SCHEDULE_unknown);
88  case OMPC_unknown:
89  case OMPC_threadprivate:
90  case OMPC_if:
91  case OMPC_num_threads:
92  case OMPC_safelen:
93  case OMPC_collapse:
94  case OMPC_private:
95  case OMPC_firstprivate:
96  case OMPC_lastprivate:
97  case OMPC_shared:
98  case OMPC_reduction:
99  case OMPC_linear:
100  case OMPC_aligned:
101  case OMPC_copyin:
102  case OMPC_copyprivate:
103  case OMPC_ordered:
104  case OMPC_nowait:
105    break;
106  }
107  llvm_unreachable("Invalid OpenMP simple clause kind");
108}
109
110const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
111                                                 unsigned Type) {
112  switch (Kind) {
113  case OMPC_default:
114    switch (Type) {
115    case OMPC_DEFAULT_unknown:
116      return "unknown";
117#define OPENMP_DEFAULT_KIND(Name)                                              \
118  case OMPC_DEFAULT_##Name:                                                    \
119    return #Name;
120#include "clang/Basic/OpenMPKinds.def"
121    }
122    llvm_unreachable("Invalid OpenMP 'default' clause type");
123  case OMPC_proc_bind:
124    switch (Type) {
125    case OMPC_PROC_BIND_unknown:
126      return "unknown";
127#define OPENMP_PROC_BIND_KIND(Name)                                            \
128  case OMPC_PROC_BIND_##Name:                                                  \
129    return #Name;
130#include "clang/Basic/OpenMPKinds.def"
131    }
132    llvm_unreachable("Invalid OpenMP 'proc_bind' clause type");
133  case OMPC_schedule:
134    switch (Type) {
135    case OMPC_SCHEDULE_unknown:
136      return "unknown";
137#define OPENMP_SCHEDULE_KIND(Name)                                             \
138  case OMPC_SCHEDULE_##Name:                                                   \
139    return #Name;
140#include "clang/Basic/OpenMPKinds.def"
141    }
142    llvm_unreachable("Invalid OpenMP 'schedule' clause type");
143  case OMPC_unknown:
144  case OMPC_threadprivate:
145  case OMPC_if:
146  case OMPC_num_threads:
147  case OMPC_safelen:
148  case OMPC_collapse:
149  case OMPC_private:
150  case OMPC_firstprivate:
151  case OMPC_lastprivate:
152  case OMPC_shared:
153  case OMPC_reduction:
154  case OMPC_linear:
155  case OMPC_aligned:
156  case OMPC_copyin:
157  case OMPC_copyprivate:
158  case OMPC_ordered:
159  case OMPC_nowait:
160    break;
161  }
162  llvm_unreachable("Invalid OpenMP simple clause kind");
163}
164
165bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
166                                        OpenMPClauseKind CKind) {
167  assert(DKind <= OMPD_unknown);
168  assert(CKind <= OMPC_unknown);
169  switch (DKind) {
170  case OMPD_parallel:
171    switch (CKind) {
172#define OPENMP_PARALLEL_CLAUSE(Name)                                           \
173  case OMPC_##Name:                                                            \
174    return true;
175#include "clang/Basic/OpenMPKinds.def"
176    default:
177      break;
178    }
179    break;
180  case OMPD_simd:
181    switch (CKind) {
182#define OPENMP_SIMD_CLAUSE(Name)                                               \
183  case OMPC_##Name:                                                            \
184    return true;
185#include "clang/Basic/OpenMPKinds.def"
186    default:
187      break;
188    }
189    break;
190  case OMPD_for:
191    switch (CKind) {
192#define OPENMP_FOR_CLAUSE(Name)                                                \
193  case OMPC_##Name:                                                            \
194    return true;
195#include "clang/Basic/OpenMPKinds.def"
196    default:
197      break;
198    }
199    break;
200  case OMPD_sections:
201    switch (CKind) {
202#define OPENMP_SECTIONS_CLAUSE(Name)                                           \
203  case OMPC_##Name:                                                            \
204    return true;
205#include "clang/Basic/OpenMPKinds.def"
206    default:
207      break;
208    }
209    break;
210  case OMPD_single:
211    switch (CKind) {
212#define OPENMP_SINGLE_CLAUSE(Name)                                             \
213  case OMPC_##Name:                                                            \
214    return true;
215#include "clang/Basic/OpenMPKinds.def"
216    default:
217      break;
218    }
219    break;
220  case OMPD_parallel_for:
221    switch (CKind) {
222#define OPENMP_PARALLEL_FOR_CLAUSE(Name)                                       \
223  case OMPC_##Name:                                                            \
224    return true;
225#include "clang/Basic/OpenMPKinds.def"
226    default:
227      break;
228    }
229    break;
230  case OMPD_parallel_sections:
231    switch (CKind) {
232#define OPENMP_PARALLEL_SECTIONS_CLAUSE(Name)                                  \
233  case OMPC_##Name:                                                            \
234    return true;
235#include "clang/Basic/OpenMPKinds.def"
236    default:
237      break;
238    }
239    break;
240  case OMPD_unknown:
241  case OMPD_threadprivate:
242  case OMPD_task:
243  case OMPD_section:
244    break;
245  }
246  return false;
247}
248
249bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) {
250  return DKind == OMPD_simd || DKind == OMPD_for ||
251         DKind == OMPD_parallel_for; // TODO add next directives.
252}
253
254bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) {
255  return DKind == OMPD_for || DKind == OMPD_sections || DKind == OMPD_section ||
256         DKind == OMPD_single || DKind == OMPD_parallel_for ||
257         DKind == OMPD_parallel_sections; // TODO add next directives.
258}
259
260bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) {
261  return DKind == OMPD_parallel || DKind == OMPD_parallel_for ||
262         DKind == OMPD_parallel_sections; // TODO add next directives.
263}
264
265bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) {
266  return DKind == OMPD_simd; // TODO || DKind == OMPD_for_simd || ...
267}
268
269bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) {
270  return Kind == OMPC_private || Kind == OMPC_firstprivate ||
271         Kind == OMPC_lastprivate || Kind == OMPC_linear ||
272         Kind == OMPC_reduction; // TODO add next clauses like 'reduction'.
273}
274
275bool clang::isOpenMPThreadPrivate(OpenMPClauseKind Kind) {
276  return Kind == OMPC_threadprivate ||
277         Kind == OMPC_copyin; // TODO add next clauses like 'copyprivate'.
278}
279
280