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_unknown:
195   case OMPD_threadprivate:
196   case OMPD_task:
197     break;
198   }
199   return false;
200 }
201 
202 bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) {
203   return DKind == OMPD_simd || DKind == OMPD_for; // TODO add next directives.
204 }
205 
206 bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) {
207   return DKind == OMPD_for; // TODO add next directives.
208 }
209 
210 bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) {
211   return DKind == OMPD_parallel; // TODO add next directives.
212 }
213 
214 bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) {
215   return DKind == OMPD_simd; // TODO || DKind == OMPD_for_simd || ...
216 }
217 
218 bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) {
219   return Kind == OMPC_private || Kind == OMPC_firstprivate ||
220          Kind == OMPC_lastprivate || Kind == OMPC_linear ||
221          Kind == OMPC_reduction; // TODO add next clauses like 'reduction'.
222 }
223 
224 bool clang::isOpenMPThreadPrivate(OpenMPClauseKind Kind) {
225   return Kind == OMPC_threadprivate ||
226          Kind == OMPC_copyin; // TODO add next clauses like 'copyprivate'.
227 }
228 
229