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_copyprivate:
99   case OMPC_ordered:
100   case OMPC_nowait:
101     break;
102   }
103   llvm_unreachable("Invalid OpenMP simple clause kind");
104 }
105 
106 const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
107                                                  unsigned Type) {
108   switch (Kind) {
109   case OMPC_default:
110     switch (Type) {
111     case OMPC_DEFAULT_unknown:
112       return "unknown";
113 #define OPENMP_DEFAULT_KIND(Name)                                              \
114   case OMPC_DEFAULT_##Name:                                                    \
115     return #Name;
116 #include "clang/Basic/OpenMPKinds.def"
117     }
118     llvm_unreachable("Invalid OpenMP 'default' clause type");
119   case OMPC_proc_bind:
120     switch (Type) {
121     case OMPC_PROC_BIND_unknown:
122       return "unknown";
123 #define OPENMP_PROC_BIND_KIND(Name)                                            \
124   case OMPC_PROC_BIND_##Name:                                                  \
125     return #Name;
126 #include "clang/Basic/OpenMPKinds.def"
127     }
128     llvm_unreachable("Invalid OpenMP 'proc_bind' clause type");
129   case OMPC_schedule:
130     switch (Type) {
131     case OMPC_SCHEDULE_unknown:
132       return "unknown";
133 #define OPENMP_SCHEDULE_KIND(Name)                                             \
134   case OMPC_SCHEDULE_##Name:                                                   \
135     return #Name;
136 #include "clang/Basic/OpenMPKinds.def"
137     }
138     llvm_unreachable("Invalid OpenMP 'schedule' clause type");
139   case OMPC_unknown:
140   case OMPC_threadprivate:
141   case OMPC_if:
142   case OMPC_num_threads:
143   case OMPC_safelen:
144   case OMPC_collapse:
145   case OMPC_private:
146   case OMPC_firstprivate:
147   case OMPC_lastprivate:
148   case OMPC_shared:
149   case OMPC_reduction:
150   case OMPC_linear:
151   case OMPC_aligned:
152   case OMPC_copyin:
153   case OMPC_copyprivate:
154   case OMPC_ordered:
155   case OMPC_nowait:
156     break;
157   }
158   llvm_unreachable("Invalid OpenMP simple clause kind");
159 }
160 
161 bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
162                                         OpenMPClauseKind CKind) {
163   assert(DKind <= OMPD_unknown);
164   assert(CKind <= OMPC_unknown);
165   switch (DKind) {
166   case OMPD_parallel:
167     switch (CKind) {
168 #define OPENMP_PARALLEL_CLAUSE(Name)                                           \
169   case OMPC_##Name:                                                            \
170     return true;
171 #include "clang/Basic/OpenMPKinds.def"
172     default:
173       break;
174     }
175     break;
176   case OMPD_simd:
177     switch (CKind) {
178 #define OPENMP_SIMD_CLAUSE(Name)                                               \
179   case OMPC_##Name:                                                            \
180     return true;
181 #include "clang/Basic/OpenMPKinds.def"
182     default:
183       break;
184     }
185     break;
186   case OMPD_for:
187     switch (CKind) {
188 #define OPENMP_FOR_CLAUSE(Name)                                                \
189   case OMPC_##Name:                                                            \
190     return true;
191 #include "clang/Basic/OpenMPKinds.def"
192     default:
193       break;
194     }
195     break;
196   case OMPD_sections:
197     switch (CKind) {
198 #define OPENMP_SECTIONS_CLAUSE(Name)                                           \
199   case OMPC_##Name:                                                            \
200     return true;
201 #include "clang/Basic/OpenMPKinds.def"
202     default:
203       break;
204     }
205     break;
206   case OMPD_single:
207     switch (CKind) {
208 #define OPENMP_SINGLE_CLAUSE(Name)                                             \
209   case OMPC_##Name:                                                            \
210     return true;
211 #include "clang/Basic/OpenMPKinds.def"
212     default:
213       break;
214     }
215     break;
216   case OMPD_unknown:
217   case OMPD_threadprivate:
218   case OMPD_task:
219   case OMPD_section:
220     break;
221   }
222   return false;
223 }
224 
225 bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) {
226   return DKind == OMPD_simd || DKind == OMPD_for; // TODO add next directives.
227 }
228 
229 bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) {
230   return DKind == OMPD_for || DKind == OMPD_sections || DKind == OMPD_section ||
231          DKind == OMPD_single; // TODO add next directives.
232 }
233 
234 bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) {
235   return DKind == OMPD_parallel; // TODO add next directives.
236 }
237 
238 bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) {
239   return DKind == OMPD_simd; // TODO || DKind == OMPD_for_simd || ...
240 }
241 
242 bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) {
243   return Kind == OMPC_private || Kind == OMPC_firstprivate ||
244          Kind == OMPC_lastprivate || Kind == OMPC_linear ||
245          Kind == OMPC_reduction; // TODO add next clauses like 'reduction'.
246 }
247 
248 bool clang::isOpenMPThreadPrivate(OpenMPClauseKind Kind) {
249   return Kind == OMPC_threadprivate ||
250          Kind == OMPC_copyin; // TODO add next clauses like 'copyprivate'.
251 }
252 
253