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_unknown: 95 case OMPC_threadprivate: 96 case OMPC_if: 97 case OMPC_final: 98 case OMPC_num_threads: 99 case OMPC_safelen: 100 case OMPC_collapse: 101 case OMPC_private: 102 case OMPC_firstprivate: 103 case OMPC_lastprivate: 104 case OMPC_shared: 105 case OMPC_reduction: 106 case OMPC_linear: 107 case OMPC_aligned: 108 case OMPC_copyin: 109 case OMPC_copyprivate: 110 case OMPC_ordered: 111 case OMPC_nowait: 112 case OMPC_untied: 113 case OMPC_mergeable: 114 case OMPC_flush: 115 case OMPC_read: 116 case OMPC_write: 117 case OMPC_update: 118 case OMPC_capture: 119 case OMPC_seq_cst: 120 break; 121 } 122 llvm_unreachable("Invalid OpenMP simple clause kind"); 123 } 124 125 const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, 126 unsigned Type) { 127 switch (Kind) { 128 case OMPC_default: 129 switch (Type) { 130 case OMPC_DEFAULT_unknown: 131 return "unknown"; 132 #define OPENMP_DEFAULT_KIND(Name) \ 133 case OMPC_DEFAULT_##Name: \ 134 return #Name; 135 #include "clang/Basic/OpenMPKinds.def" 136 } 137 llvm_unreachable("Invalid OpenMP 'default' clause type"); 138 case OMPC_proc_bind: 139 switch (Type) { 140 case OMPC_PROC_BIND_unknown: 141 return "unknown"; 142 #define OPENMP_PROC_BIND_KIND(Name) \ 143 case OMPC_PROC_BIND_##Name: \ 144 return #Name; 145 #include "clang/Basic/OpenMPKinds.def" 146 } 147 llvm_unreachable("Invalid OpenMP 'proc_bind' clause type"); 148 case OMPC_schedule: 149 switch (Type) { 150 case OMPC_SCHEDULE_unknown: 151 return "unknown"; 152 #define OPENMP_SCHEDULE_KIND(Name) \ 153 case OMPC_SCHEDULE_##Name: \ 154 return #Name; 155 #include "clang/Basic/OpenMPKinds.def" 156 } 157 llvm_unreachable("Invalid OpenMP 'schedule' clause type"); 158 case OMPC_unknown: 159 case OMPC_threadprivate: 160 case OMPC_if: 161 case OMPC_final: 162 case OMPC_num_threads: 163 case OMPC_safelen: 164 case OMPC_collapse: 165 case OMPC_private: 166 case OMPC_firstprivate: 167 case OMPC_lastprivate: 168 case OMPC_shared: 169 case OMPC_reduction: 170 case OMPC_linear: 171 case OMPC_aligned: 172 case OMPC_copyin: 173 case OMPC_copyprivate: 174 case OMPC_ordered: 175 case OMPC_nowait: 176 case OMPC_untied: 177 case OMPC_mergeable: 178 case OMPC_flush: 179 case OMPC_read: 180 case OMPC_write: 181 case OMPC_update: 182 case OMPC_capture: 183 case OMPC_seq_cst: 184 break; 185 } 186 llvm_unreachable("Invalid OpenMP simple clause kind"); 187 } 188 189 bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, 190 OpenMPClauseKind CKind) { 191 assert(DKind <= OMPD_unknown); 192 assert(CKind <= OMPC_unknown); 193 switch (DKind) { 194 case OMPD_parallel: 195 switch (CKind) { 196 #define OPENMP_PARALLEL_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_simd: 205 switch (CKind) { 206 #define OPENMP_SIMD_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_for: 215 switch (CKind) { 216 #define OPENMP_FOR_CLAUSE(Name) \ 217 case OMPC_##Name: \ 218 return true; 219 #include "clang/Basic/OpenMPKinds.def" 220 default: 221 break; 222 } 223 break; 224 case OMPD_for_simd: 225 switch (CKind) { 226 #define OPENMP_FOR_SIMD_CLAUSE(Name) \ 227 case OMPC_##Name: \ 228 return true; 229 #include "clang/Basic/OpenMPKinds.def" 230 default: 231 break; 232 } 233 break; 234 case OMPD_sections: 235 switch (CKind) { 236 #define OPENMP_SECTIONS_CLAUSE(Name) \ 237 case OMPC_##Name: \ 238 return true; 239 #include "clang/Basic/OpenMPKinds.def" 240 default: 241 break; 242 } 243 break; 244 case OMPD_single: 245 switch (CKind) { 246 #define OPENMP_SINGLE_CLAUSE(Name) \ 247 case OMPC_##Name: \ 248 return true; 249 #include "clang/Basic/OpenMPKinds.def" 250 default: 251 break; 252 } 253 break; 254 case OMPD_parallel_for: 255 switch (CKind) { 256 #define OPENMP_PARALLEL_FOR_CLAUSE(Name) \ 257 case OMPC_##Name: \ 258 return true; 259 #include "clang/Basic/OpenMPKinds.def" 260 default: 261 break; 262 } 263 break; 264 case OMPD_parallel_for_simd: 265 switch (CKind) { 266 #define OPENMP_PARALLEL_FOR_SIMD_CLAUSE(Name) \ 267 case OMPC_##Name: \ 268 return true; 269 #include "clang/Basic/OpenMPKinds.def" 270 default: 271 break; 272 } 273 break; 274 case OMPD_parallel_sections: 275 switch (CKind) { 276 #define OPENMP_PARALLEL_SECTIONS_CLAUSE(Name) \ 277 case OMPC_##Name: \ 278 return true; 279 #include "clang/Basic/OpenMPKinds.def" 280 default: 281 break; 282 } 283 break; 284 case OMPD_task: 285 switch (CKind) { 286 #define OPENMP_TASK_CLAUSE(Name) \ 287 case OMPC_##Name: \ 288 return true; 289 #include "clang/Basic/OpenMPKinds.def" 290 default: 291 break; 292 } 293 break; 294 case OMPD_flush: 295 return CKind == OMPC_flush; 296 break; 297 case OMPD_atomic: 298 switch (CKind) { 299 #define OPENMP_ATOMIC_CLAUSE(Name) \ 300 case OMPC_##Name: \ 301 return true; 302 #include "clang/Basic/OpenMPKinds.def" 303 default: 304 break; 305 } 306 break; 307 case OMPD_target: 308 switch (CKind) { 309 #define OPENMP_TARGET_CLAUSE(Name) \ 310 case OMPC_##Name: \ 311 return true; 312 #include "clang/Basic/OpenMPKinds.def" 313 default: 314 break; 315 } 316 break; 317 case OMPD_teams: 318 switch (CKind) { 319 #define OPENMP_TEAMS_CLAUSE(Name) \ 320 case OMPC_##Name: \ 321 return true; 322 #include "clang/Basic/OpenMPKinds.def" 323 default: 324 break; 325 } 326 break; 327 case OMPD_unknown: 328 case OMPD_threadprivate: 329 case OMPD_section: 330 case OMPD_master: 331 case OMPD_critical: 332 case OMPD_taskyield: 333 case OMPD_barrier: 334 case OMPD_taskwait: 335 case OMPD_ordered: 336 break; 337 } 338 return false; 339 } 340 341 bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) { 342 return DKind == OMPD_simd || DKind == OMPD_for || DKind == OMPD_for_simd || 343 DKind == OMPD_parallel_for || 344 DKind == OMPD_parallel_for_simd; // TODO add next directives. 345 } 346 347 bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) { 348 return DKind == OMPD_for || DKind == OMPD_for_simd || 349 DKind == OMPD_sections || DKind == OMPD_section || 350 DKind == OMPD_single || DKind == OMPD_parallel_for || 351 DKind == OMPD_parallel_for_simd || 352 DKind == OMPD_parallel_sections; // TODO add next directives. 353 } 354 355 bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) { 356 return DKind == OMPD_parallel || DKind == OMPD_parallel_for || 357 DKind == OMPD_parallel_for_simd || 358 DKind == OMPD_parallel_sections; // TODO add next directives. 359 } 360 361 bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind) { 362 return DKind == OMPD_teams; // TODO add next directives. 363 } 364 365 bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) { 366 return DKind == OMPD_simd || DKind == OMPD_for_simd || 367 DKind == OMPD_parallel_for_simd; // TODO add next directives. 368 } 369 370 bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) { 371 return Kind == OMPC_private || Kind == OMPC_firstprivate || 372 Kind == OMPC_lastprivate || Kind == OMPC_linear || 373 Kind == OMPC_reduction; // TODO add next clauses like 'reduction'. 374 } 375 376 bool clang::isOpenMPThreadPrivate(OpenMPClauseKind Kind) { 377 return Kind == OMPC_threadprivate || Kind == OMPC_copyin; 378 } 379 380