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 #define OPENMP_DIRECTIVE_EXT(Name, Str) .Case(Str, OMPD_##Name) 27 #include "clang/Basic/OpenMPKinds.def" 28 .Default(OMPD_unknown); 29 } 30 31 const 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 48 OpenMPClauseKind clang::getOpenMPClauseKind(StringRef Str) { 49 // 'flush' clause cannot be specified explicitly, because this is an implicit 50 // clause for 'flush' directive. If the 'flush' clause is explicitly specified 51 // the Parser should generate a warning about extra tokens at the end of the 52 // directive. 53 if (Str == "flush") 54 return OMPC_unknown; 55 return llvm::StringSwitch<OpenMPClauseKind>(Str) 56 #define OPENMP_CLAUSE(Name, Class) .Case(#Name, OMPC_##Name) 57 #include "clang/Basic/OpenMPKinds.def" 58 .Default(OMPC_unknown); 59 } 60 61 const char *clang::getOpenMPClauseName(OpenMPClauseKind Kind) { 62 assert(Kind <= OMPC_unknown); 63 switch (Kind) { 64 case OMPC_unknown: 65 return "unknown"; 66 #define OPENMP_CLAUSE(Name, Class) \ 67 case OMPC_##Name: \ 68 return #Name; 69 #include "clang/Basic/OpenMPKinds.def" 70 case OMPC_threadprivate: 71 return "threadprivate or thread local"; 72 } 73 llvm_unreachable("Invalid OpenMP clause kind"); 74 } 75 76 unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, 77 StringRef Str) { 78 switch (Kind) { 79 case OMPC_default: 80 return llvm::StringSwitch<OpenMPDefaultClauseKind>(Str) 81 #define OPENMP_DEFAULT_KIND(Name) .Case(#Name, OMPC_DEFAULT_##Name) 82 #include "clang/Basic/OpenMPKinds.def" 83 .Default(OMPC_DEFAULT_unknown); 84 case OMPC_proc_bind: 85 return llvm::StringSwitch<OpenMPProcBindClauseKind>(Str) 86 #define OPENMP_PROC_BIND_KIND(Name) .Case(#Name, OMPC_PROC_BIND_##Name) 87 #include "clang/Basic/OpenMPKinds.def" 88 .Default(OMPC_PROC_BIND_unknown); 89 case OMPC_schedule: 90 return llvm::StringSwitch<OpenMPScheduleClauseKind>(Str) 91 #define OPENMP_SCHEDULE_KIND(Name) .Case(#Name, OMPC_SCHEDULE_##Name) 92 #include "clang/Basic/OpenMPKinds.def" 93 .Default(OMPC_SCHEDULE_unknown); 94 case OMPC_depend: 95 return llvm::StringSwitch<OpenMPDependClauseKind>(Str) 96 #define OPENMP_DEPEND_KIND(Name) .Case(#Name, OMPC_DEPEND_##Name) 97 #include "clang/Basic/OpenMPKinds.def" 98 .Default(OMPC_DEPEND_unknown); 99 case OMPC_unknown: 100 case OMPC_threadprivate: 101 case OMPC_if: 102 case OMPC_final: 103 case OMPC_num_threads: 104 case OMPC_safelen: 105 case OMPC_collapse: 106 case OMPC_private: 107 case OMPC_firstprivate: 108 case OMPC_lastprivate: 109 case OMPC_shared: 110 case OMPC_reduction: 111 case OMPC_linear: 112 case OMPC_aligned: 113 case OMPC_copyin: 114 case OMPC_copyprivate: 115 case OMPC_ordered: 116 case OMPC_nowait: 117 case OMPC_untied: 118 case OMPC_mergeable: 119 case OMPC_flush: 120 case OMPC_read: 121 case OMPC_write: 122 case OMPC_update: 123 case OMPC_capture: 124 case OMPC_seq_cst: 125 break; 126 } 127 llvm_unreachable("Invalid OpenMP simple clause kind"); 128 } 129 130 const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, 131 unsigned Type) { 132 switch (Kind) { 133 case OMPC_default: 134 switch (Type) { 135 case OMPC_DEFAULT_unknown: 136 return "unknown"; 137 #define OPENMP_DEFAULT_KIND(Name) \ 138 case OMPC_DEFAULT_##Name: \ 139 return #Name; 140 #include "clang/Basic/OpenMPKinds.def" 141 } 142 llvm_unreachable("Invalid OpenMP 'default' clause type"); 143 case OMPC_proc_bind: 144 switch (Type) { 145 case OMPC_PROC_BIND_unknown: 146 return "unknown"; 147 #define OPENMP_PROC_BIND_KIND(Name) \ 148 case OMPC_PROC_BIND_##Name: \ 149 return #Name; 150 #include "clang/Basic/OpenMPKinds.def" 151 } 152 llvm_unreachable("Invalid OpenMP 'proc_bind' clause type"); 153 case OMPC_schedule: 154 switch (Type) { 155 case OMPC_SCHEDULE_unknown: 156 return "unknown"; 157 #define OPENMP_SCHEDULE_KIND(Name) \ 158 case OMPC_SCHEDULE_##Name: \ 159 return #Name; 160 #include "clang/Basic/OpenMPKinds.def" 161 } 162 case OMPC_depend: 163 switch (Type) { 164 case OMPC_DEPEND_unknown: 165 return "unknown"; 166 #define OPENMP_DEPEND_KIND(Name) \ 167 case OMPC_DEPEND_##Name: \ 168 return #Name; 169 #include "clang/Basic/OpenMPKinds.def" 170 } 171 llvm_unreachable("Invalid OpenMP 'schedule' clause type"); 172 case OMPC_unknown: 173 case OMPC_threadprivate: 174 case OMPC_if: 175 case OMPC_final: 176 case OMPC_num_threads: 177 case OMPC_safelen: 178 case OMPC_collapse: 179 case OMPC_private: 180 case OMPC_firstprivate: 181 case OMPC_lastprivate: 182 case OMPC_shared: 183 case OMPC_reduction: 184 case OMPC_linear: 185 case OMPC_aligned: 186 case OMPC_copyin: 187 case OMPC_copyprivate: 188 case OMPC_ordered: 189 case OMPC_nowait: 190 case OMPC_untied: 191 case OMPC_mergeable: 192 case OMPC_flush: 193 case OMPC_read: 194 case OMPC_write: 195 case OMPC_update: 196 case OMPC_capture: 197 case OMPC_seq_cst: 198 break; 199 } 200 llvm_unreachable("Invalid OpenMP simple clause kind"); 201 } 202 203 bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, 204 OpenMPClauseKind CKind) { 205 assert(DKind <= OMPD_unknown); 206 assert(CKind <= OMPC_unknown); 207 switch (DKind) { 208 case OMPD_parallel: 209 switch (CKind) { 210 #define OPENMP_PARALLEL_CLAUSE(Name) \ 211 case OMPC_##Name: \ 212 return true; 213 #include "clang/Basic/OpenMPKinds.def" 214 default: 215 break; 216 } 217 break; 218 case OMPD_simd: 219 switch (CKind) { 220 #define OPENMP_SIMD_CLAUSE(Name) \ 221 case OMPC_##Name: \ 222 return true; 223 #include "clang/Basic/OpenMPKinds.def" 224 default: 225 break; 226 } 227 break; 228 case OMPD_for: 229 switch (CKind) { 230 #define OPENMP_FOR_CLAUSE(Name) \ 231 case OMPC_##Name: \ 232 return true; 233 #include "clang/Basic/OpenMPKinds.def" 234 default: 235 break; 236 } 237 break; 238 case OMPD_for_simd: 239 switch (CKind) { 240 #define OPENMP_FOR_SIMD_CLAUSE(Name) \ 241 case OMPC_##Name: \ 242 return true; 243 #include "clang/Basic/OpenMPKinds.def" 244 default: 245 break; 246 } 247 break; 248 case OMPD_sections: 249 switch (CKind) { 250 #define OPENMP_SECTIONS_CLAUSE(Name) \ 251 case OMPC_##Name: \ 252 return true; 253 #include "clang/Basic/OpenMPKinds.def" 254 default: 255 break; 256 } 257 break; 258 case OMPD_single: 259 switch (CKind) { 260 #define OPENMP_SINGLE_CLAUSE(Name) \ 261 case OMPC_##Name: \ 262 return true; 263 #include "clang/Basic/OpenMPKinds.def" 264 default: 265 break; 266 } 267 break; 268 case OMPD_parallel_for: 269 switch (CKind) { 270 #define OPENMP_PARALLEL_FOR_CLAUSE(Name) \ 271 case OMPC_##Name: \ 272 return true; 273 #include "clang/Basic/OpenMPKinds.def" 274 default: 275 break; 276 } 277 break; 278 case OMPD_parallel_for_simd: 279 switch (CKind) { 280 #define OPENMP_PARALLEL_FOR_SIMD_CLAUSE(Name) \ 281 case OMPC_##Name: \ 282 return true; 283 #include "clang/Basic/OpenMPKinds.def" 284 default: 285 break; 286 } 287 break; 288 case OMPD_parallel_sections: 289 switch (CKind) { 290 #define OPENMP_PARALLEL_SECTIONS_CLAUSE(Name) \ 291 case OMPC_##Name: \ 292 return true; 293 #include "clang/Basic/OpenMPKinds.def" 294 default: 295 break; 296 } 297 break; 298 case OMPD_task: 299 switch (CKind) { 300 #define OPENMP_TASK_CLAUSE(Name) \ 301 case OMPC_##Name: \ 302 return true; 303 #include "clang/Basic/OpenMPKinds.def" 304 default: 305 break; 306 } 307 break; 308 case OMPD_flush: 309 return CKind == OMPC_flush; 310 break; 311 case OMPD_atomic: 312 switch (CKind) { 313 #define OPENMP_ATOMIC_CLAUSE(Name) \ 314 case OMPC_##Name: \ 315 return true; 316 #include "clang/Basic/OpenMPKinds.def" 317 default: 318 break; 319 } 320 break; 321 case OMPD_target: 322 switch (CKind) { 323 #define OPENMP_TARGET_CLAUSE(Name) \ 324 case OMPC_##Name: \ 325 return true; 326 #include "clang/Basic/OpenMPKinds.def" 327 default: 328 break; 329 } 330 break; 331 case OMPD_teams: 332 switch (CKind) { 333 #define OPENMP_TEAMS_CLAUSE(Name) \ 334 case OMPC_##Name: \ 335 return true; 336 #include "clang/Basic/OpenMPKinds.def" 337 default: 338 break; 339 } 340 break; 341 case OMPD_unknown: 342 case OMPD_threadprivate: 343 case OMPD_section: 344 case OMPD_master: 345 case OMPD_critical: 346 case OMPD_taskyield: 347 case OMPD_barrier: 348 case OMPD_taskwait: 349 case OMPD_taskgroup: 350 case OMPD_cancellation_point: 351 case OMPD_cancel: 352 case OMPD_ordered: 353 break; 354 } 355 return false; 356 } 357 358 bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) { 359 return DKind == OMPD_simd || DKind == OMPD_for || DKind == OMPD_for_simd || 360 DKind == OMPD_parallel_for || 361 DKind == OMPD_parallel_for_simd; // TODO add next directives. 362 } 363 364 bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) { 365 return DKind == OMPD_for || DKind == OMPD_for_simd || 366 DKind == OMPD_sections || DKind == OMPD_section || 367 DKind == OMPD_single || DKind == OMPD_parallel_for || 368 DKind == OMPD_parallel_for_simd || 369 DKind == OMPD_parallel_sections; // TODO add next directives. 370 } 371 372 bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) { 373 return DKind == OMPD_parallel || DKind == OMPD_parallel_for || 374 DKind == OMPD_parallel_for_simd || 375 DKind == OMPD_parallel_sections; // TODO add next directives. 376 } 377 378 bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind) { 379 return DKind == OMPD_teams; // TODO add next directives. 380 } 381 382 bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) { 383 return DKind == OMPD_simd || DKind == OMPD_for_simd || 384 DKind == OMPD_parallel_for_simd; // TODO add next directives. 385 } 386 387 bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) { 388 return Kind == OMPC_private || Kind == OMPC_firstprivate || 389 Kind == OMPC_lastprivate || Kind == OMPC_linear || 390 Kind == OMPC_reduction; // TODO add next clauses like 'reduction'. 391 } 392 393 bool clang::isOpenMPThreadPrivate(OpenMPClauseKind Kind) { 394 return Kind == OMPC_threadprivate || Kind == OMPC_copyin; 395 } 396 397