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 
21 using namespace clang;
22 
23 OpenMPDirectiveKind clang::getOpenMPDirectiveKind(StringRef Str) {
24   return llvm::StringSwitch<OpenMPDirectiveKind>(Str)
25 #define OPENMP_DIRECTIVE(Name) .Case(#Name, OMPD_##Name)
26 #include "clang/Basic/OpenMPKinds.def"
27       .Default(OMPD_unknown);
28 }
29 
30 const char *clang::getOpenMPDirectiveName(OpenMPDirectiveKind Kind) {
31   assert(Kind <= OMPD_unknown);
32   switch (Kind) {
33   case OMPD_unknown:
34     return "unknown";
35 #define OPENMP_DIRECTIVE(Name)                                                 \
36   case OMPD_##Name:                                                            \
37     return #Name;
38 #include "clang/Basic/OpenMPKinds.def"
39     break;
40   }
41   llvm_unreachable("Invalid OpenMP directive kind");
42 }
43 
44 OpenMPClauseKind clang::getOpenMPClauseKind(StringRef Str) {
45   return llvm::StringSwitch<OpenMPClauseKind>(Str)
46 #define OPENMP_CLAUSE(Name, Class) .Case(#Name, OMPC_##Name)
47 #include "clang/Basic/OpenMPKinds.def"
48       .Default(OMPC_unknown);
49 }
50 
51 const char *clang::getOpenMPClauseName(OpenMPClauseKind Kind) {
52   assert(Kind <= OMPC_unknown);
53   switch (Kind) {
54   case OMPC_unknown:
55     return "unknown";
56 #define OPENMP_CLAUSE(Name, Class)                                             \
57   case OMPC_##Name:                                                            \
58     return #Name;
59 #include "clang/Basic/OpenMPKinds.def"
60   case OMPC_threadprivate:
61     return "threadprivate or thread local";
62   }
63   llvm_unreachable("Invalid OpenMP clause kind");
64 }
65 
66 unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
67                                           StringRef Str) {
68   switch (Kind) {
69   case OMPC_default:
70     return llvm::StringSwitch<OpenMPDefaultClauseKind>(Str)
71 #define OPENMP_DEFAULT_KIND(Name) .Case(#Name, OMPC_DEFAULT_##Name)
72 #include "clang/Basic/OpenMPKinds.def"
73         .Default(OMPC_DEFAULT_unknown);
74   case OMPC_proc_bind:
75     return llvm::StringSwitch<OpenMPProcBindClauseKind>(Str)
76 #define OPENMP_PROC_BIND_KIND(Name) .Case(#Name, OMPC_PROC_BIND_##Name)
77 #include "clang/Basic/OpenMPKinds.def"
78         .Default(OMPC_PROC_BIND_unknown);
79   case OMPC_schedule:
80     return llvm::StringSwitch<OpenMPScheduleClauseKind>(Str)
81 #define OPENMP_SCHEDULE_KIND(Name) .Case(#Name, OMPC_SCHEDULE_##Name)
82 #include "clang/Basic/OpenMPKinds.def"
83         .Default(OMPC_SCHEDULE_unknown);
84   case OMPC_unknown:
85   case OMPC_threadprivate:
86   case OMPC_if:
87   case OMPC_num_threads:
88   case OMPC_safelen:
89   case OMPC_collapse:
90   case OMPC_private:
91   case OMPC_firstprivate:
92   case OMPC_lastprivate:
93   case OMPC_shared:
94   case OMPC_reduction:
95   case OMPC_linear:
96   case OMPC_aligned:
97   case OMPC_copyin:
98   case OMPC_ordered:
99   case OMPC_nowait:
100     break;
101   }
102   llvm_unreachable("Invalid OpenMP simple clause kind");
103 }
104 
105 const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
106                                                  unsigned Type) {
107   switch (Kind) {
108   case OMPC_default:
109     switch (Type) {
110     case OMPC_DEFAULT_unknown:
111       return "unknown";
112 #define OPENMP_DEFAULT_KIND(Name)                                              \
113   case OMPC_DEFAULT_##Name:                                                    \
114     return #Name;
115 #include "clang/Basic/OpenMPKinds.def"
116     }
117     llvm_unreachable("Invalid OpenMP 'default' clause type");
118   case OMPC_proc_bind:
119     switch (Type) {
120     case OMPC_PROC_BIND_unknown:
121       return "unknown";
122 #define OPENMP_PROC_BIND_KIND(Name)                                            \
123   case OMPC_PROC_BIND_##Name:                                                  \
124     return #Name;
125 #include "clang/Basic/OpenMPKinds.def"
126     }
127     llvm_unreachable("Invalid OpenMP 'proc_bind' clause type");
128   case OMPC_schedule:
129     switch (Type) {
130     case OMPC_SCHEDULE_unknown:
131       return "unknown";
132 #define OPENMP_SCHEDULE_KIND(Name)                                             \
133   case OMPC_SCHEDULE_##Name:                                                   \
134     return #Name;
135 #include "clang/Basic/OpenMPKinds.def"
136     }
137     llvm_unreachable("Invalid OpenMP 'schedule' clause type");
138   case OMPC_unknown:
139   case OMPC_threadprivate:
140   case OMPC_if:
141   case OMPC_num_threads:
142   case OMPC_safelen:
143   case OMPC_collapse:
144   case OMPC_private:
145   case OMPC_firstprivate:
146   case OMPC_lastprivate:
147   case OMPC_shared:
148   case OMPC_reduction:
149   case OMPC_linear:
150   case OMPC_aligned:
151   case OMPC_copyin:
152   case OMPC_ordered:
153   case OMPC_nowait:
154     break;
155   }
156   llvm_unreachable("Invalid OpenMP simple clause kind");
157 }
158 
159 bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
160                                         OpenMPClauseKind CKind) {
161   assert(DKind <= OMPD_unknown);
162   assert(CKind <= OMPC_unknown);
163   switch (DKind) {
164   case OMPD_parallel:
165     switch (CKind) {
166 #define OPENMP_PARALLEL_CLAUSE(Name)                                           \
167   case OMPC_##Name:                                                            \
168     return true;
169 #include "clang/Basic/OpenMPKinds.def"
170     default:
171       break;
172     }
173     break;
174   case OMPD_simd:
175     switch (CKind) {
176 #define OPENMP_SIMD_CLAUSE(Name)                                               \
177   case OMPC_##Name:                                                            \
178     return true;
179 #include "clang/Basic/OpenMPKinds.def"
180     default:
181       break;
182     }
183     break;
184   case OMPD_for:
185     switch (CKind) {
186 #define OPENMP_FOR_CLAUSE(Name)                                                \
187   case OMPC_##Name:                                                            \
188     return true;
189 #include "clang/Basic/OpenMPKinds.def"
190     default:
191       break;
192     }
193     break;
194   case OMPD_sections:
195     switch (CKind) {
196 #define OPENMP_SECTIONS_CLAUSE(Name)                                                \
197   case OMPC_##Name:                                                            \
198     return true;
199 #include "clang/Basic/OpenMPKinds.def"
200     default:
201       break;
202     }
203     break;
204   case OMPD_single:
205     switch (CKind) {
206 #define OPENMP_SINGLE_CLAUSE(Name)                                                \
207   case OMPC_##Name:                                                            \
208     return true;
209 #include "clang/Basic/OpenMPKinds.def"
210     default:
211       break;
212     }
213     break;
214   case OMPD_unknown:
215   case OMPD_threadprivate:
216   case OMPD_task:
217   case OMPD_section:
218     break;
219   }
220   return false;
221 }
222 
223 bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) {
224   return DKind == OMPD_simd || DKind == OMPD_for; // TODO add next directives.
225 }
226 
227 bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) {
228   return DKind == OMPD_for || DKind == OMPD_sections || DKind == OMPD_section ||
229          DKind == OMPD_single; // TODO add next directives.
230 }
231 
232 bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) {
233   return DKind == OMPD_parallel; // TODO add next directives.
234 }
235 
236 bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) {
237   return DKind == OMPD_simd; // TODO || DKind == OMPD_for_simd || ...
238 }
239 
240 bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) {
241   return Kind == OMPC_private || Kind == OMPC_firstprivate ||
242          Kind == OMPC_lastprivate || Kind == OMPC_linear ||
243          Kind == OMPC_reduction; // TODO add next clauses like 'reduction'.
244 }
245 
246 bool clang::isOpenMPThreadPrivate(OpenMPClauseKind Kind) {
247   return Kind == OMPC_threadprivate ||
248          Kind == OMPC_copyin; // TODO add next clauses like 'copyprivate'.
249 }
250 
251