1 //===--- ParseOpenACC.cpp - OpenACC-specific parsing support --------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements the parsing logic for OpenACC language features. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "clang/AST/OpenACCClause.h" 14 #include "clang/Basic/OpenACCKinds.h" 15 #include "clang/Parse/ParseDiagnostic.h" 16 #include "clang/Parse/Parser.h" 17 #include "clang/Parse/RAIIObjectsForParser.h" 18 #include "clang/Sema/SemaOpenACC.h" 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/ADT/StringSwitch.h" 21 22 using namespace clang; 23 using namespace llvm; 24 25 namespace { 26 // An enum that contains the extended 'partial' parsed variants. This type 27 // should never escape the initial parse functionality, but is useful for 28 // simplifying the implementation. 29 enum class OpenACCDirectiveKindEx { 30 Invalid = static_cast<int>(OpenACCDirectiveKind::Invalid), 31 // 'enter data' and 'exit data' 32 Enter, 33 Exit, 34 }; 35 36 // Translate single-token string representations to the OpenACC Directive Kind. 37 // This doesn't completely comprehend 'Compound Constructs' (as it just 38 // identifies the first token), and doesn't fully handle 'enter data', 'exit 39 // data', nor any of the 'atomic' variants, just the first token of each. So 40 // this should only be used by `ParseOpenACCDirectiveKind`. 41 OpenACCDirectiveKindEx getOpenACCDirectiveKind(Token Tok) { 42 if (!Tok.is(tok::identifier)) 43 return OpenACCDirectiveKindEx::Invalid; 44 OpenACCDirectiveKind DirKind = 45 llvm::StringSwitch<OpenACCDirectiveKind>( 46 Tok.getIdentifierInfo()->getName()) 47 .Case("parallel", OpenACCDirectiveKind::Parallel) 48 .Case("serial", OpenACCDirectiveKind::Serial) 49 .Case("kernels", OpenACCDirectiveKind::Kernels) 50 .Case("data", OpenACCDirectiveKind::Data) 51 .Case("host_data", OpenACCDirectiveKind::HostData) 52 .Case("loop", OpenACCDirectiveKind::Loop) 53 .Case("cache", OpenACCDirectiveKind::Cache) 54 .Case("atomic", OpenACCDirectiveKind::Atomic) 55 .Case("routine", OpenACCDirectiveKind::Routine) 56 .Case("declare", OpenACCDirectiveKind::Declare) 57 .Case("init", OpenACCDirectiveKind::Init) 58 .Case("shutdown", OpenACCDirectiveKind::Shutdown) 59 .Case("set", OpenACCDirectiveKind::Set) 60 .Case("update", OpenACCDirectiveKind::Update) 61 .Case("wait", OpenACCDirectiveKind::Wait) 62 .Default(OpenACCDirectiveKind::Invalid); 63 64 if (DirKind != OpenACCDirectiveKind::Invalid) 65 return static_cast<OpenACCDirectiveKindEx>(DirKind); 66 67 return llvm::StringSwitch<OpenACCDirectiveKindEx>( 68 Tok.getIdentifierInfo()->getName()) 69 .Case("enter", OpenACCDirectiveKindEx::Enter) 70 .Case("exit", OpenACCDirectiveKindEx::Exit) 71 .Default(OpenACCDirectiveKindEx::Invalid); 72 } 73 74 // Translate single-token string representations to the OpenCC Clause Kind. 75 OpenACCClauseKind getOpenACCClauseKind(Token Tok) { 76 // auto is a keyword in some language modes, so make sure we parse it 77 // correctly. 78 if (Tok.is(tok::kw_auto)) 79 return OpenACCClauseKind::Auto; 80 81 // default is a keyword, so make sure we parse it correctly. 82 if (Tok.is(tok::kw_default)) 83 return OpenACCClauseKind::Default; 84 85 // if is also a keyword, make sure we parse it correctly. 86 if (Tok.is(tok::kw_if)) 87 return OpenACCClauseKind::If; 88 89 // 'private' is also a keyword, make sure we pare it correctly. 90 if (Tok.is(tok::kw_private)) 91 return OpenACCClauseKind::Private; 92 93 if (!Tok.is(tok::identifier)) 94 return OpenACCClauseKind::Invalid; 95 96 return llvm::StringSwitch<OpenACCClauseKind>( 97 Tok.getIdentifierInfo()->getName()) 98 .Case("async", OpenACCClauseKind::Async) 99 .Case("attach", OpenACCClauseKind::Attach) 100 .Case("auto", OpenACCClauseKind::Auto) 101 .Case("bind", OpenACCClauseKind::Bind) 102 .Case("create", OpenACCClauseKind::Create) 103 .Case("pcreate", OpenACCClauseKind::PCreate) 104 .Case("present_or_create", OpenACCClauseKind::PresentOrCreate) 105 .Case("collapse", OpenACCClauseKind::Collapse) 106 .Case("copy", OpenACCClauseKind::Copy) 107 .Case("pcopy", OpenACCClauseKind::PCopy) 108 .Case("present_or_copy", OpenACCClauseKind::PresentOrCopy) 109 .Case("copyin", OpenACCClauseKind::CopyIn) 110 .Case("pcopyin", OpenACCClauseKind::PCopyIn) 111 .Case("present_or_copyin", OpenACCClauseKind::PresentOrCopyIn) 112 .Case("copyout", OpenACCClauseKind::CopyOut) 113 .Case("pcopyout", OpenACCClauseKind::PCopyOut) 114 .Case("present_or_copyout", OpenACCClauseKind::PresentOrCopyOut) 115 .Case("default", OpenACCClauseKind::Default) 116 .Case("default_async", OpenACCClauseKind::DefaultAsync) 117 .Case("delete", OpenACCClauseKind::Delete) 118 .Case("detach", OpenACCClauseKind::Detach) 119 .Case("device", OpenACCClauseKind::Device) 120 .Case("device_num", OpenACCClauseKind::DeviceNum) 121 .Case("device_resident", OpenACCClauseKind::DeviceResident) 122 .Case("device_type", OpenACCClauseKind::DeviceType) 123 .Case("deviceptr", OpenACCClauseKind::DevicePtr) 124 .Case("dtype", OpenACCClauseKind::DType) 125 .Case("finalize", OpenACCClauseKind::Finalize) 126 .Case("firstprivate", OpenACCClauseKind::FirstPrivate) 127 .Case("gang", OpenACCClauseKind::Gang) 128 .Case("host", OpenACCClauseKind::Host) 129 .Case("if", OpenACCClauseKind::If) 130 .Case("if_present", OpenACCClauseKind::IfPresent) 131 .Case("independent", OpenACCClauseKind::Independent) 132 .Case("link", OpenACCClauseKind::Link) 133 .Case("no_create", OpenACCClauseKind::NoCreate) 134 .Case("num_gangs", OpenACCClauseKind::NumGangs) 135 .Case("num_workers", OpenACCClauseKind::NumWorkers) 136 .Case("nohost", OpenACCClauseKind::NoHost) 137 .Case("present", OpenACCClauseKind::Present) 138 .Case("private", OpenACCClauseKind::Private) 139 .Case("reduction", OpenACCClauseKind::Reduction) 140 .Case("self", OpenACCClauseKind::Self) 141 .Case("seq", OpenACCClauseKind::Seq) 142 .Case("tile", OpenACCClauseKind::Tile) 143 .Case("use_device", OpenACCClauseKind::UseDevice) 144 .Case("vector", OpenACCClauseKind::Vector) 145 .Case("vector_length", OpenACCClauseKind::VectorLength) 146 .Case("wait", OpenACCClauseKind::Wait) 147 .Case("worker", OpenACCClauseKind::Worker) 148 .Default(OpenACCClauseKind::Invalid); 149 } 150 151 // Since 'atomic' is effectively a compound directive, this will decode the 152 // second part of the directive. 153 OpenACCAtomicKind getOpenACCAtomicKind(Token Tok) { 154 if (!Tok.is(tok::identifier)) 155 return OpenACCAtomicKind::Invalid; 156 return llvm::StringSwitch<OpenACCAtomicKind>( 157 Tok.getIdentifierInfo()->getName()) 158 .Case("read", OpenACCAtomicKind::Read) 159 .Case("write", OpenACCAtomicKind::Write) 160 .Case("update", OpenACCAtomicKind::Update) 161 .Case("capture", OpenACCAtomicKind::Capture) 162 .Default(OpenACCAtomicKind::Invalid); 163 } 164 165 OpenACCDefaultClauseKind getOpenACCDefaultClauseKind(Token Tok) { 166 if (!Tok.is(tok::identifier)) 167 return OpenACCDefaultClauseKind::Invalid; 168 169 return llvm::StringSwitch<OpenACCDefaultClauseKind>( 170 Tok.getIdentifierInfo()->getName()) 171 .Case("none", OpenACCDefaultClauseKind::None) 172 .Case("present", OpenACCDefaultClauseKind::Present) 173 .Default(OpenACCDefaultClauseKind::Invalid); 174 } 175 176 enum class OpenACCSpecialTokenKind { 177 ReadOnly, 178 DevNum, 179 Queues, 180 Zero, 181 Force, 182 Num, 183 Length, 184 Dim, 185 Static, 186 }; 187 188 bool isOpenACCSpecialToken(OpenACCSpecialTokenKind Kind, Token Tok) { 189 if (Tok.is(tok::kw_static) && Kind == OpenACCSpecialTokenKind::Static) 190 return true; 191 192 if (!Tok.is(tok::identifier)) 193 return false; 194 195 switch (Kind) { 196 case OpenACCSpecialTokenKind::ReadOnly: 197 return Tok.getIdentifierInfo()->isStr("readonly"); 198 case OpenACCSpecialTokenKind::DevNum: 199 return Tok.getIdentifierInfo()->isStr("devnum"); 200 case OpenACCSpecialTokenKind::Queues: 201 return Tok.getIdentifierInfo()->isStr("queues"); 202 case OpenACCSpecialTokenKind::Zero: 203 return Tok.getIdentifierInfo()->isStr("zero"); 204 case OpenACCSpecialTokenKind::Force: 205 return Tok.getIdentifierInfo()->isStr("force"); 206 case OpenACCSpecialTokenKind::Num: 207 return Tok.getIdentifierInfo()->isStr("num"); 208 case OpenACCSpecialTokenKind::Length: 209 return Tok.getIdentifierInfo()->isStr("length"); 210 case OpenACCSpecialTokenKind::Dim: 211 return Tok.getIdentifierInfo()->isStr("dim"); 212 case OpenACCSpecialTokenKind::Static: 213 return Tok.getIdentifierInfo()->isStr("static"); 214 } 215 llvm_unreachable("Unknown 'Kind' Passed"); 216 } 217 218 /// Used for cases where we have a token we want to check against an 219 /// 'identifier-like' token, but don't want to give awkward error messages in 220 /// cases where it is accidentially a keyword. 221 bool isTokenIdentifierOrKeyword(Parser &P, Token Tok) { 222 if (Tok.is(tok::identifier)) 223 return true; 224 225 if (!Tok.isAnnotation() && Tok.getIdentifierInfo() && 226 Tok.getIdentifierInfo()->isKeyword(P.getLangOpts())) 227 return true; 228 229 return false; 230 } 231 232 /// Parses and consumes an identifer followed immediately by a single colon, and 233 /// diagnoses if it is not the 'special token' kind that we require. Used when 234 /// the tag is the only valid value. 235 /// Return 'true' if the special token was matched, false if no special token, 236 /// or an invalid special token was found. 237 template <typename DirOrClauseTy> 238 bool tryParseAndConsumeSpecialTokenKind(Parser &P, OpenACCSpecialTokenKind Kind, 239 DirOrClauseTy DirOrClause) { 240 Token IdentTok = P.getCurToken(); 241 // If this is an identifier-like thing followed by ':', it is one of the 242 // OpenACC 'special' name tags, so consume it. 243 if (isTokenIdentifierOrKeyword(P, IdentTok) && P.NextToken().is(tok::colon)) { 244 P.ConsumeToken(); 245 P.ConsumeToken(); 246 247 if (!isOpenACCSpecialToken(Kind, IdentTok)) { 248 P.Diag(IdentTok, diag::err_acc_invalid_tag_kind) 249 << IdentTok.getIdentifierInfo() << DirOrClause 250 << std::is_same_v<DirOrClauseTy, OpenACCClauseKind>; 251 return false; 252 } 253 254 return true; 255 } 256 257 return false; 258 } 259 260 bool isOpenACCDirectiveKind(OpenACCDirectiveKind Kind, Token Tok) { 261 if (!Tok.is(tok::identifier)) 262 return false; 263 264 switch (Kind) { 265 case OpenACCDirectiveKind::Parallel: 266 return Tok.getIdentifierInfo()->isStr("parallel"); 267 case OpenACCDirectiveKind::Serial: 268 return Tok.getIdentifierInfo()->isStr("serial"); 269 case OpenACCDirectiveKind::Kernels: 270 return Tok.getIdentifierInfo()->isStr("kernels"); 271 case OpenACCDirectiveKind::Data: 272 return Tok.getIdentifierInfo()->isStr("data"); 273 case OpenACCDirectiveKind::HostData: 274 return Tok.getIdentifierInfo()->isStr("host_data"); 275 case OpenACCDirectiveKind::Loop: 276 return Tok.getIdentifierInfo()->isStr("loop"); 277 case OpenACCDirectiveKind::Cache: 278 return Tok.getIdentifierInfo()->isStr("cache"); 279 280 case OpenACCDirectiveKind::ParallelLoop: 281 case OpenACCDirectiveKind::SerialLoop: 282 case OpenACCDirectiveKind::KernelsLoop: 283 case OpenACCDirectiveKind::EnterData: 284 case OpenACCDirectiveKind::ExitData: 285 return false; 286 287 case OpenACCDirectiveKind::Atomic: 288 return Tok.getIdentifierInfo()->isStr("atomic"); 289 case OpenACCDirectiveKind::Routine: 290 return Tok.getIdentifierInfo()->isStr("routine"); 291 case OpenACCDirectiveKind::Declare: 292 return Tok.getIdentifierInfo()->isStr("declare"); 293 case OpenACCDirectiveKind::Init: 294 return Tok.getIdentifierInfo()->isStr("init"); 295 case OpenACCDirectiveKind::Shutdown: 296 return Tok.getIdentifierInfo()->isStr("shutdown"); 297 case OpenACCDirectiveKind::Set: 298 return Tok.getIdentifierInfo()->isStr("set"); 299 case OpenACCDirectiveKind::Update: 300 return Tok.getIdentifierInfo()->isStr("update"); 301 case OpenACCDirectiveKind::Wait: 302 return Tok.getIdentifierInfo()->isStr("wait"); 303 case OpenACCDirectiveKind::Invalid: 304 return false; 305 } 306 llvm_unreachable("Unknown 'Kind' Passed"); 307 } 308 309 OpenACCReductionOperator ParseReductionOperator(Parser &P) { 310 // If there is no colon, treat as if the reduction operator was missing, else 311 // we probably will not recover from it in the case where an expression starts 312 // with one of the operator tokens. 313 if (P.NextToken().isNot(tok::colon)) { 314 P.Diag(P.getCurToken(), diag::err_acc_expected_reduction_operator); 315 return OpenACCReductionOperator::Invalid; 316 } 317 Token ReductionKindTok = P.getCurToken(); 318 // Consume both the kind and the colon. 319 P.ConsumeToken(); 320 P.ConsumeToken(); 321 322 switch (ReductionKindTok.getKind()) { 323 case tok::plus: 324 return OpenACCReductionOperator::Addition; 325 case tok::star: 326 return OpenACCReductionOperator::Multiplication; 327 case tok::amp: 328 return OpenACCReductionOperator::BitwiseAnd; 329 case tok::pipe: 330 return OpenACCReductionOperator::BitwiseOr; 331 case tok::caret: 332 return OpenACCReductionOperator::BitwiseXOr; 333 case tok::ampamp: 334 return OpenACCReductionOperator::And; 335 case tok::pipepipe: 336 return OpenACCReductionOperator::Or; 337 case tok::identifier: 338 if (ReductionKindTok.getIdentifierInfo()->isStr("max")) 339 return OpenACCReductionOperator::Max; 340 if (ReductionKindTok.getIdentifierInfo()->isStr("min")) 341 return OpenACCReductionOperator::Min; 342 [[fallthrough]]; 343 default: 344 P.Diag(ReductionKindTok, diag::err_acc_invalid_reduction_operator); 345 return OpenACCReductionOperator::Invalid; 346 } 347 llvm_unreachable("Reduction op token kind not caught by 'default'?"); 348 } 349 350 /// Used for cases where we expect an identifier-like token, but don't want to 351 /// give awkward error messages in cases where it is accidentially a keyword. 352 bool expectIdentifierOrKeyword(Parser &P) { 353 Token Tok = P.getCurToken(); 354 355 if (isTokenIdentifierOrKeyword(P, Tok)) 356 return false; 357 358 P.Diag(P.getCurToken(), diag::err_expected) << tok::identifier; 359 return true; 360 } 361 362 OpenACCDirectiveKind 363 ParseOpenACCEnterExitDataDirective(Parser &P, Token FirstTok, 364 OpenACCDirectiveKindEx ExtDirKind) { 365 Token SecondTok = P.getCurToken(); 366 367 if (SecondTok.isAnnotation()) { 368 P.Diag(FirstTok, diag::err_acc_invalid_directive) 369 << 0 << FirstTok.getIdentifierInfo(); 370 return OpenACCDirectiveKind::Invalid; 371 } 372 373 // Consume the second name anyway, this way we can continue on without making 374 // this oddly look like a clause. 375 P.ConsumeAnyToken(); 376 377 if (!isOpenACCDirectiveKind(OpenACCDirectiveKind::Data, SecondTok)) { 378 if (!SecondTok.is(tok::identifier)) 379 P.Diag(SecondTok, diag::err_expected) << tok::identifier; 380 else 381 P.Diag(FirstTok, diag::err_acc_invalid_directive) 382 << 1 << FirstTok.getIdentifierInfo()->getName() 383 << SecondTok.getIdentifierInfo()->getName(); 384 return OpenACCDirectiveKind::Invalid; 385 } 386 387 return ExtDirKind == OpenACCDirectiveKindEx::Enter 388 ? OpenACCDirectiveKind::EnterData 389 : OpenACCDirectiveKind::ExitData; 390 } 391 392 OpenACCAtomicKind ParseOpenACCAtomicKind(Parser &P) { 393 Token AtomicClauseToken = P.getCurToken(); 394 395 // #pragma acc atomic is equivilent to update: 396 if (AtomicClauseToken.isAnnotation()) 397 return OpenACCAtomicKind::Update; 398 399 OpenACCAtomicKind AtomicKind = getOpenACCAtomicKind(AtomicClauseToken); 400 401 // If we don't know what this is, treat it as 'nothing', and treat the rest of 402 // this as a clause list, which, despite being invalid, is likely what the 403 // user was trying to do. 404 if (AtomicKind == OpenACCAtomicKind::Invalid) 405 return OpenACCAtomicKind::Update; 406 407 P.ConsumeToken(); 408 return AtomicKind; 409 } 410 411 // Parse and consume the tokens for OpenACC Directive/Construct kinds. 412 OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) { 413 Token FirstTok = P.getCurToken(); 414 415 // Just #pragma acc can get us immediately to the end, make sure we don't 416 // introspect on the spelling before then. 417 if (FirstTok.isNot(tok::identifier)) { 418 P.Diag(FirstTok, diag::err_acc_missing_directive); 419 420 if (P.getCurToken().isNot(tok::annot_pragma_openacc_end)) 421 P.ConsumeAnyToken(); 422 423 return OpenACCDirectiveKind::Invalid; 424 } 425 426 P.ConsumeToken(); 427 428 OpenACCDirectiveKindEx ExDirKind = getOpenACCDirectiveKind(FirstTok); 429 430 // OpenACCDirectiveKindEx is meant to be an extended list 431 // over OpenACCDirectiveKind, so any value below Invalid is one of the 432 // OpenACCDirectiveKind values. This switch takes care of all of the extra 433 // parsing required for the Extended values. At the end of this block, 434 // ExDirKind can be assumed to be a valid OpenACCDirectiveKind, so we can 435 // immediately cast it and use it as that. 436 if (ExDirKind >= OpenACCDirectiveKindEx::Invalid) { 437 switch (ExDirKind) { 438 case OpenACCDirectiveKindEx::Invalid: { 439 P.Diag(FirstTok, diag::err_acc_invalid_directive) 440 << 0 << FirstTok.getIdentifierInfo(); 441 return OpenACCDirectiveKind::Invalid; 442 } 443 case OpenACCDirectiveKindEx::Enter: 444 case OpenACCDirectiveKindEx::Exit: 445 return ParseOpenACCEnterExitDataDirective(P, FirstTok, ExDirKind); 446 } 447 } 448 449 OpenACCDirectiveKind DirKind = static_cast<OpenACCDirectiveKind>(ExDirKind); 450 451 // Combined Constructs allows parallel loop, serial loop, or kernels loop. Any 452 // other attempt at a combined construct will be diagnosed as an invalid 453 // clause. 454 Token SecondTok = P.getCurToken(); 455 if (!SecondTok.isAnnotation() && 456 isOpenACCDirectiveKind(OpenACCDirectiveKind::Loop, SecondTok)) { 457 switch (DirKind) { 458 default: 459 // Nothing to do except in the below cases, as they should be diagnosed as 460 // a clause. 461 break; 462 case OpenACCDirectiveKind::Parallel: 463 P.ConsumeToken(); 464 return OpenACCDirectiveKind::ParallelLoop; 465 case OpenACCDirectiveKind::Serial: 466 P.ConsumeToken(); 467 return OpenACCDirectiveKind::SerialLoop; 468 case OpenACCDirectiveKind::Kernels: 469 P.ConsumeToken(); 470 return OpenACCDirectiveKind::KernelsLoop; 471 } 472 } 473 474 return DirKind; 475 } 476 477 enum ClauseParensKind { 478 None, 479 Optional, 480 Required 481 }; 482 483 ClauseParensKind getClauseParensKind(OpenACCDirectiveKind DirKind, 484 OpenACCClauseKind Kind) { 485 switch (Kind) { 486 case OpenACCClauseKind::Self: 487 return DirKind == OpenACCDirectiveKind::Update ? ClauseParensKind::Required 488 : ClauseParensKind::Optional; 489 case OpenACCClauseKind::Async: 490 case OpenACCClauseKind::Worker: 491 case OpenACCClauseKind::Vector: 492 case OpenACCClauseKind::Gang: 493 case OpenACCClauseKind::Wait: 494 return ClauseParensKind::Optional; 495 496 case OpenACCClauseKind::Default: 497 case OpenACCClauseKind::If: 498 case OpenACCClauseKind::Create: 499 case OpenACCClauseKind::PCreate: 500 case OpenACCClauseKind::PresentOrCreate: 501 case OpenACCClauseKind::Copy: 502 case OpenACCClauseKind::PCopy: 503 case OpenACCClauseKind::PresentOrCopy: 504 case OpenACCClauseKind::CopyIn: 505 case OpenACCClauseKind::PCopyIn: 506 case OpenACCClauseKind::PresentOrCopyIn: 507 case OpenACCClauseKind::CopyOut: 508 case OpenACCClauseKind::PCopyOut: 509 case OpenACCClauseKind::PresentOrCopyOut: 510 case OpenACCClauseKind::UseDevice: 511 case OpenACCClauseKind::NoCreate: 512 case OpenACCClauseKind::Present: 513 case OpenACCClauseKind::DevicePtr: 514 case OpenACCClauseKind::Attach: 515 case OpenACCClauseKind::Detach: 516 case OpenACCClauseKind::Private: 517 case OpenACCClauseKind::FirstPrivate: 518 case OpenACCClauseKind::Delete: 519 case OpenACCClauseKind::DeviceResident: 520 case OpenACCClauseKind::Device: 521 case OpenACCClauseKind::Link: 522 case OpenACCClauseKind::Host: 523 case OpenACCClauseKind::Reduction: 524 case OpenACCClauseKind::Collapse: 525 case OpenACCClauseKind::Bind: 526 case OpenACCClauseKind::VectorLength: 527 case OpenACCClauseKind::NumGangs: 528 case OpenACCClauseKind::NumWorkers: 529 case OpenACCClauseKind::DeviceNum: 530 case OpenACCClauseKind::DefaultAsync: 531 case OpenACCClauseKind::DeviceType: 532 case OpenACCClauseKind::DType: 533 case OpenACCClauseKind::Tile: 534 return ClauseParensKind::Required; 535 536 case OpenACCClauseKind::Auto: 537 case OpenACCClauseKind::Finalize: 538 case OpenACCClauseKind::IfPresent: 539 case OpenACCClauseKind::Independent: 540 case OpenACCClauseKind::Invalid: 541 case OpenACCClauseKind::NoHost: 542 case OpenACCClauseKind::Seq: 543 return ClauseParensKind::None; 544 } 545 llvm_unreachable("Unhandled clause kind"); 546 } 547 548 bool ClauseHasOptionalParens(OpenACCDirectiveKind DirKind, 549 OpenACCClauseKind Kind) { 550 return getClauseParensKind(DirKind, Kind) == ClauseParensKind::Optional; 551 } 552 553 bool ClauseHasRequiredParens(OpenACCDirectiveKind DirKind, 554 OpenACCClauseKind Kind) { 555 return getClauseParensKind(DirKind, Kind) == ClauseParensKind::Required; 556 } 557 558 // Skip until we see the end of pragma token, but don't consume it. This is us 559 // just giving up on the rest of the pragma so we can continue executing. We 560 // have to do this because 'SkipUntil' considers paren balancing, which isn't 561 // what we want. 562 void SkipUntilEndOfDirective(Parser &P) { 563 while (P.getCurToken().isNot(tok::annot_pragma_openacc_end)) 564 P.ConsumeAnyToken(); 565 } 566 567 bool doesDirectiveHaveAssociatedStmt(OpenACCDirectiveKind DirKind) { 568 switch (DirKind) { 569 default: 570 return false; 571 case OpenACCDirectiveKind::Parallel: 572 case OpenACCDirectiveKind::Serial: 573 case OpenACCDirectiveKind::Kernels: 574 case OpenACCDirectiveKind::Loop: 575 return true; 576 } 577 llvm_unreachable("Unhandled directive->assoc stmt"); 578 } 579 580 unsigned getOpenACCScopeFlags(OpenACCDirectiveKind DirKind) { 581 switch (DirKind) { 582 case OpenACCDirectiveKind::Parallel: 583 case OpenACCDirectiveKind::Serial: 584 case OpenACCDirectiveKind::Kernels: 585 // Mark this as a BreakScope/ContinueScope as well as a compute construct 586 // so that we can diagnose trying to 'break'/'continue' inside of one. 587 return Scope::BreakScope | Scope::ContinueScope | 588 Scope::OpenACCComputeConstructScope; 589 case OpenACCDirectiveKind::Invalid: 590 llvm_unreachable("Shouldn't be creating a scope for an invalid construct"); 591 default: 592 break; 593 } 594 return 0; 595 } 596 597 } // namespace 598 599 Parser::OpenACCClauseParseResult Parser::OpenACCCanContinue() { 600 return {nullptr, OpenACCParseCanContinue::Can}; 601 } 602 603 Parser::OpenACCClauseParseResult Parser::OpenACCCannotContinue() { 604 return {nullptr, OpenACCParseCanContinue::Cannot}; 605 } 606 607 Parser::OpenACCClauseParseResult Parser::OpenACCSuccess(OpenACCClause *Clause) { 608 return {Clause, OpenACCParseCanContinue::Can}; 609 } 610 611 ExprResult Parser::ParseOpenACCConditionExpr() { 612 // FIXME: It isn't clear if the spec saying 'condition' means the same as 613 // it does in an if/while/etc (See ParseCXXCondition), however as it was 614 // written with Fortran/C in mind, we're going to assume it just means an 615 // 'expression evaluating to boolean'. 616 ExprResult ER = getActions().CorrectDelayedTyposInExpr(ParseExpression()); 617 618 if (!ER.isUsable()) 619 return ER; 620 621 Sema::ConditionResult R = 622 getActions().ActOnCondition(getCurScope(), ER.get()->getExprLoc(), 623 ER.get(), Sema::ConditionKind::Boolean); 624 625 return R.isInvalid() ? ExprError() : R.get().second; 626 } 627 628 // OpenACC 3.3, section 1.7: 629 // To simplify the specification and convey appropriate constraint information, 630 // a pqr-list is a comma-separated list of pdr items. The one exception is a 631 // clause-list, which is a list of one or more clauses optionally separated by 632 // commas. 633 SmallVector<OpenACCClause *> 634 Parser::ParseOpenACCClauseList(OpenACCDirectiveKind DirKind) { 635 SmallVector<OpenACCClause *> Clauses; 636 bool FirstClause = true; 637 while (getCurToken().isNot(tok::annot_pragma_openacc_end)) { 638 // Comma is optional in a clause-list. 639 if (!FirstClause && getCurToken().is(tok::comma)) 640 ConsumeToken(); 641 FirstClause = false; 642 643 OpenACCClauseParseResult Result = ParseOpenACCClause(Clauses, DirKind); 644 if (OpenACCClause *Clause = Result.getPointer()) { 645 Clauses.push_back(Clause); 646 } else if (Result.getInt() == OpenACCParseCanContinue::Cannot) { 647 // Recovering from a bad clause is really difficult, so we just give up on 648 // error. 649 SkipUntilEndOfDirective(*this); 650 return Clauses; 651 } 652 } 653 return Clauses; 654 } 655 656 Parser::OpenACCIntExprParseResult 657 Parser::ParseOpenACCIntExpr(OpenACCDirectiveKind DK, OpenACCClauseKind CK, 658 SourceLocation Loc) { 659 ExprResult ER = ParseAssignmentExpression(); 660 661 // If the actual parsing failed, we don't know the state of the parse, so 662 // don't try to continue. 663 if (!ER.isUsable()) 664 return {ER, OpenACCParseCanContinue::Cannot}; 665 666 // Parsing can continue after the initial assignment expression parsing, so 667 // even if there was a typo, we can continue. 668 ER = getActions().CorrectDelayedTyposInExpr(ER); 669 if (!ER.isUsable()) 670 return {ER, OpenACCParseCanContinue::Can}; 671 672 return {getActions().OpenACC().ActOnIntExpr(DK, CK, Loc, ER.get()), 673 OpenACCParseCanContinue::Can}; 674 } 675 676 bool Parser::ParseOpenACCIntExprList(OpenACCDirectiveKind DK, 677 OpenACCClauseKind CK, SourceLocation Loc, 678 llvm::SmallVectorImpl<Expr *> &IntExprs) { 679 OpenACCIntExprParseResult CurResult = ParseOpenACCIntExpr(DK, CK, Loc); 680 681 if (!CurResult.first.isUsable() && 682 CurResult.second == OpenACCParseCanContinue::Cannot) { 683 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end, 684 Parser::StopBeforeMatch); 685 return true; 686 } 687 688 IntExprs.push_back(CurResult.first.get()); 689 690 while (!getCurToken().isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) { 691 ExpectAndConsume(tok::comma); 692 693 CurResult = ParseOpenACCIntExpr(DK, CK, Loc); 694 695 if (!CurResult.first.isUsable() && 696 CurResult.second == OpenACCParseCanContinue::Cannot) { 697 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end, 698 Parser::StopBeforeMatch); 699 return true; 700 } 701 IntExprs.push_back(CurResult.first.get()); 702 } 703 return false; 704 } 705 706 /// OpenACC 3.3 Section 2.4: 707 /// The argument to the device_type clause is a comma-separated list of one or 708 /// more device architecture name identifiers, or an asterisk. 709 /// 710 /// The syntax of the device_type clause is 711 /// device_type( * ) 712 /// device_type( device-type-list ) 713 /// 714 /// The device_type clause may be abbreviated to dtype. 715 bool Parser::ParseOpenACCDeviceTypeList( 716 llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>> &Archs) { 717 718 if (expectIdentifierOrKeyword(*this)) { 719 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end, 720 Parser::StopBeforeMatch); 721 return true; 722 } 723 IdentifierInfo *Ident = getCurToken().getIdentifierInfo(); 724 Archs.emplace_back(Ident, ConsumeToken()); 725 726 while (!getCurToken().isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) { 727 ExpectAndConsume(tok::comma); 728 729 if (expectIdentifierOrKeyword(*this)) { 730 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end, 731 Parser::StopBeforeMatch); 732 return true; 733 } 734 Ident = getCurToken().getIdentifierInfo(); 735 Archs.emplace_back(Ident, ConsumeToken()); 736 } 737 return false; 738 } 739 740 /// OpenACC 3.3 Section 2.9: 741 /// size-expr is one of: 742 // * 743 // int-expr 744 // Note that this is specified under 'gang-arg-list', but also applies to 'tile' 745 // via reference. 746 bool Parser::ParseOpenACCSizeExpr() { 747 // FIXME: Ensure these are constant expressions. 748 749 // The size-expr ends up being ambiguous when only looking at the current 750 // token, as it could be a deref of a variable/expression. 751 if (getCurToken().is(tok::star) && 752 NextToken().isOneOf(tok::comma, tok::r_paren, 753 tok::annot_pragma_openacc_end)) { 754 ConsumeToken(); 755 return false; 756 } 757 758 return getActions() 759 .CorrectDelayedTyposInExpr(ParseAssignmentExpression()) 760 .isInvalid(); 761 } 762 763 bool Parser::ParseOpenACCSizeExprList() { 764 if (ParseOpenACCSizeExpr()) { 765 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end, 766 Parser::StopBeforeMatch); 767 return false; 768 } 769 770 while (!getCurToken().isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) { 771 ExpectAndConsume(tok::comma); 772 773 if (ParseOpenACCSizeExpr()) { 774 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end, 775 Parser::StopBeforeMatch); 776 return false; 777 } 778 } 779 return false; 780 } 781 782 /// OpenACC 3.3 Section 2.9: 783 /// 784 /// where gang-arg is one of: 785 /// [num:]int-expr 786 /// dim:int-expr 787 /// static:size-expr 788 bool Parser::ParseOpenACCGangArg(SourceLocation GangLoc) { 789 790 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Static, getCurToken()) && 791 NextToken().is(tok::colon)) { 792 // 'static' just takes a size-expr, which is an int-expr or an asterisk. 793 ConsumeToken(); 794 ConsumeToken(); 795 return ParseOpenACCSizeExpr(); 796 } 797 798 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Dim, getCurToken()) && 799 NextToken().is(tok::colon)) { 800 ConsumeToken(); 801 ConsumeToken(); 802 return ParseOpenACCIntExpr(OpenACCDirectiveKind::Invalid, 803 OpenACCClauseKind::Gang, GangLoc) 804 .first.isInvalid(); 805 } 806 807 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Num, getCurToken()) && 808 NextToken().is(tok::colon)) { 809 ConsumeToken(); 810 ConsumeToken(); 811 // Fallthrough to the 'int-expr' handling for when 'num' is omitted. 812 } 813 // This is just the 'num' case where 'num' is optional. 814 return ParseOpenACCIntExpr(OpenACCDirectiveKind::Invalid, 815 OpenACCClauseKind::Gang, GangLoc) 816 .first.isInvalid(); 817 } 818 819 bool Parser::ParseOpenACCGangArgList(SourceLocation GangLoc) { 820 if (ParseOpenACCGangArg(GangLoc)) { 821 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end, 822 Parser::StopBeforeMatch); 823 return false; 824 } 825 826 while (!getCurToken().isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) { 827 ExpectAndConsume(tok::comma); 828 829 if (ParseOpenACCGangArg(GangLoc)) { 830 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end, 831 Parser::StopBeforeMatch); 832 return false; 833 } 834 } 835 return false; 836 } 837 838 // The OpenACC Clause List is a comma or space-delimited list of clauses (see 839 // the comment on ParseOpenACCClauseList). The concept of a 'clause' doesn't 840 // really have its owner grammar and each individual one has its own definition. 841 // However, they all are named with a single-identifier (or auto/default!) 842 // token, followed in some cases by either braces or parens. 843 Parser::OpenACCClauseParseResult 844 Parser::ParseOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses, 845 OpenACCDirectiveKind DirKind) { 846 // A number of clause names are actually keywords, so accept a keyword that 847 // can be converted to a name. 848 if (expectIdentifierOrKeyword(*this)) 849 return OpenACCCannotContinue(); 850 851 OpenACCClauseKind Kind = getOpenACCClauseKind(getCurToken()); 852 853 if (Kind == OpenACCClauseKind::Invalid) { 854 Diag(getCurToken(), diag::err_acc_invalid_clause) 855 << getCurToken().getIdentifierInfo(); 856 return OpenACCCannotContinue(); 857 } 858 859 // Consume the clause name. 860 SourceLocation ClauseLoc = ConsumeToken(); 861 862 return ParseOpenACCClauseParams(ExistingClauses, DirKind, Kind, ClauseLoc); 863 } 864 865 Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams( 866 ArrayRef<const OpenACCClause *> ExistingClauses, 867 OpenACCDirectiveKind DirKind, OpenACCClauseKind ClauseKind, 868 SourceLocation ClauseLoc) { 869 BalancedDelimiterTracker Parens(*this, tok::l_paren, 870 tok::annot_pragma_openacc_end); 871 SemaOpenACC::OpenACCParsedClause ParsedClause(DirKind, ClauseKind, ClauseLoc); 872 873 if (ClauseHasRequiredParens(DirKind, ClauseKind)) { 874 if (Parens.expectAndConsume()) { 875 // We are missing a paren, so assume that the person just forgot the 876 // parameter. Return 'false' so we try to continue on and parse the next 877 // clause. 878 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openacc_end, 879 Parser::StopBeforeMatch); 880 return OpenACCCanContinue(); 881 } 882 ParsedClause.setLParenLoc(Parens.getOpenLocation()); 883 884 switch (ClauseKind) { 885 case OpenACCClauseKind::Default: { 886 Token DefKindTok = getCurToken(); 887 888 if (expectIdentifierOrKeyword(*this)) { 889 Parens.skipToEnd(); 890 return OpenACCCanContinue(); 891 } 892 893 ConsumeToken(); 894 895 OpenACCDefaultClauseKind DefKind = 896 getOpenACCDefaultClauseKind(DefKindTok); 897 898 if (DefKind == OpenACCDefaultClauseKind::Invalid) { 899 Diag(DefKindTok, diag::err_acc_invalid_default_clause_kind); 900 Parens.skipToEnd(); 901 return OpenACCCanContinue(); 902 } 903 904 ParsedClause.setDefaultDetails(DefKind); 905 break; 906 } 907 case OpenACCClauseKind::If: { 908 ExprResult CondExpr = ParseOpenACCConditionExpr(); 909 ParsedClause.setConditionDetails(CondExpr.isUsable() ? CondExpr.get() 910 : nullptr); 911 912 if (CondExpr.isInvalid()) { 913 Parens.skipToEnd(); 914 return OpenACCCanContinue(); 915 } 916 917 break; 918 } 919 case OpenACCClauseKind::CopyIn: 920 case OpenACCClauseKind::PCopyIn: 921 case OpenACCClauseKind::PresentOrCopyIn: { 922 bool IsReadOnly = tryParseAndConsumeSpecialTokenKind( 923 *this, OpenACCSpecialTokenKind::ReadOnly, ClauseKind); 924 ParsedClause.setVarListDetails(ParseOpenACCVarList(ClauseKind), 925 IsReadOnly, 926 /*IsZero=*/false); 927 break; 928 } 929 case OpenACCClauseKind::Create: 930 case OpenACCClauseKind::PCreate: 931 case OpenACCClauseKind::PresentOrCreate: 932 case OpenACCClauseKind::CopyOut: 933 case OpenACCClauseKind::PCopyOut: 934 case OpenACCClauseKind::PresentOrCopyOut: { 935 bool IsZero = tryParseAndConsumeSpecialTokenKind( 936 *this, OpenACCSpecialTokenKind::Zero, ClauseKind); 937 ParsedClause.setVarListDetails(ParseOpenACCVarList(ClauseKind), 938 /*IsReadOnly=*/false, IsZero); 939 break; 940 } 941 case OpenACCClauseKind::Reduction: { 942 // If we're missing a clause-kind (or it is invalid), see if we can parse 943 // the var-list anyway. 944 OpenACCReductionOperator Op = ParseReductionOperator(*this); 945 ParsedClause.setReductionDetails(Op, ParseOpenACCVarList(ClauseKind)); 946 break; 947 } 948 case OpenACCClauseKind::Self: 949 // The 'self' clause is a var-list instead of a 'condition' in the case of 950 // the 'update' clause, so we have to handle it here. U se an assert to 951 // make sure we get the right differentiator. 952 assert(DirKind == OpenACCDirectiveKind::Update); 953 [[fallthrough]]; 954 case OpenACCClauseKind::Delete: 955 case OpenACCClauseKind::Detach: 956 case OpenACCClauseKind::Device: 957 case OpenACCClauseKind::DeviceResident: 958 case OpenACCClauseKind::Host: 959 case OpenACCClauseKind::Link: 960 case OpenACCClauseKind::UseDevice: 961 ParseOpenACCVarList(ClauseKind); 962 break; 963 case OpenACCClauseKind::Attach: 964 case OpenACCClauseKind::DevicePtr: 965 ParsedClause.setVarListDetails(ParseOpenACCVarList(ClauseKind), 966 /*IsReadOnly=*/false, /*IsZero=*/false); 967 break; 968 case OpenACCClauseKind::Copy: 969 case OpenACCClauseKind::PCopy: 970 case OpenACCClauseKind::PresentOrCopy: 971 case OpenACCClauseKind::FirstPrivate: 972 case OpenACCClauseKind::NoCreate: 973 case OpenACCClauseKind::Present: 974 case OpenACCClauseKind::Private: 975 ParsedClause.setVarListDetails(ParseOpenACCVarList(ClauseKind), 976 /*IsReadOnly=*/false, /*IsZero=*/false); 977 break; 978 case OpenACCClauseKind::Collapse: { 979 tryParseAndConsumeSpecialTokenKind(*this, OpenACCSpecialTokenKind::Force, 980 ClauseKind); 981 ExprResult NumLoops = 982 getActions().CorrectDelayedTyposInExpr(ParseConstantExpression()); 983 if (NumLoops.isInvalid()) { 984 Parens.skipToEnd(); 985 return OpenACCCanContinue(); 986 } 987 break; 988 } 989 case OpenACCClauseKind::Bind: { 990 ExprResult BindArg = ParseOpenACCBindClauseArgument(); 991 if (BindArg.isInvalid()) { 992 Parens.skipToEnd(); 993 return OpenACCCanContinue(); 994 } 995 break; 996 } 997 case OpenACCClauseKind::NumGangs: { 998 llvm::SmallVector<Expr *> IntExprs; 999 1000 if (ParseOpenACCIntExprList(OpenACCDirectiveKind::Invalid, 1001 OpenACCClauseKind::NumGangs, ClauseLoc, 1002 IntExprs)) { 1003 Parens.skipToEnd(); 1004 return OpenACCCanContinue(); 1005 } 1006 ParsedClause.setIntExprDetails(std::move(IntExprs)); 1007 break; 1008 } 1009 case OpenACCClauseKind::NumWorkers: 1010 case OpenACCClauseKind::DeviceNum: 1011 case OpenACCClauseKind::DefaultAsync: 1012 case OpenACCClauseKind::VectorLength: { 1013 ExprResult IntExpr = ParseOpenACCIntExpr(OpenACCDirectiveKind::Invalid, 1014 ClauseKind, ClauseLoc) 1015 .first; 1016 if (IntExpr.isInvalid()) { 1017 Parens.skipToEnd(); 1018 return OpenACCCanContinue(); 1019 } 1020 1021 // TODO OpenACC: as we implement the 'rest' of the above, this 'if' should 1022 // be removed leaving just the 'setIntExprDetails'. 1023 if (ClauseKind == OpenACCClauseKind::NumWorkers || 1024 ClauseKind == OpenACCClauseKind::VectorLength) 1025 ParsedClause.setIntExprDetails(IntExpr.get()); 1026 1027 break; 1028 } 1029 case OpenACCClauseKind::DType: 1030 case OpenACCClauseKind::DeviceType: { 1031 llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>> Archs; 1032 if (getCurToken().is(tok::star)) { 1033 // FIXME: We want to mark that this is an 'everything else' type of 1034 // device_type in Sema. 1035 ParsedClause.setDeviceTypeDetails({{nullptr, ConsumeToken()}}); 1036 } else if (!ParseOpenACCDeviceTypeList(Archs)) { 1037 ParsedClause.setDeviceTypeDetails(std::move(Archs)); 1038 } else { 1039 Parens.skipToEnd(); 1040 return OpenACCCanContinue(); 1041 } 1042 break; 1043 } 1044 case OpenACCClauseKind::Tile: 1045 if (ParseOpenACCSizeExprList()) { 1046 Parens.skipToEnd(); 1047 return OpenACCCanContinue(); 1048 } 1049 break; 1050 default: 1051 llvm_unreachable("Not a required parens type?"); 1052 } 1053 1054 ParsedClause.setEndLoc(getCurToken().getLocation()); 1055 1056 if (Parens.consumeClose()) 1057 return OpenACCCannotContinue(); 1058 1059 } else if (ClauseHasOptionalParens(DirKind, ClauseKind)) { 1060 if (!Parens.consumeOpen()) { 1061 ParsedClause.setLParenLoc(Parens.getOpenLocation()); 1062 switch (ClauseKind) { 1063 case OpenACCClauseKind::Self: { 1064 assert(DirKind != OpenACCDirectiveKind::Update); 1065 ExprResult CondExpr = ParseOpenACCConditionExpr(); 1066 ParsedClause.setConditionDetails(CondExpr.isUsable() ? CondExpr.get() 1067 : nullptr); 1068 1069 if (CondExpr.isInvalid()) { 1070 Parens.skipToEnd(); 1071 return OpenACCCanContinue(); 1072 } 1073 break; 1074 } 1075 case OpenACCClauseKind::Vector: 1076 case OpenACCClauseKind::Worker: { 1077 tryParseAndConsumeSpecialTokenKind(*this, 1078 ClauseKind == 1079 OpenACCClauseKind::Vector 1080 ? OpenACCSpecialTokenKind::Length 1081 : OpenACCSpecialTokenKind::Num, 1082 ClauseKind); 1083 ExprResult IntExpr = ParseOpenACCIntExpr(OpenACCDirectiveKind::Invalid, 1084 ClauseKind, ClauseLoc) 1085 .first; 1086 if (IntExpr.isInvalid()) { 1087 Parens.skipToEnd(); 1088 return OpenACCCanContinue(); 1089 } 1090 break; 1091 } 1092 case OpenACCClauseKind::Async: { 1093 ExprResult AsyncArg = 1094 ParseOpenACCAsyncArgument(OpenACCDirectiveKind::Invalid, 1095 OpenACCClauseKind::Async, ClauseLoc) 1096 .first; 1097 ParsedClause.setIntExprDetails(AsyncArg.isUsable() ? AsyncArg.get() 1098 : nullptr); 1099 if (AsyncArg.isInvalid()) { 1100 Parens.skipToEnd(); 1101 return OpenACCCanContinue(); 1102 } 1103 break; 1104 } 1105 case OpenACCClauseKind::Gang: 1106 if (ParseOpenACCGangArgList(ClauseLoc)) { 1107 Parens.skipToEnd(); 1108 return OpenACCCanContinue(); 1109 } 1110 break; 1111 case OpenACCClauseKind::Wait: { 1112 OpenACCWaitParseInfo Info = 1113 ParseOpenACCWaitArgument(ClauseLoc, 1114 /*IsDirective=*/false); 1115 if (Info.Failed) { 1116 Parens.skipToEnd(); 1117 return OpenACCCanContinue(); 1118 } 1119 1120 ParsedClause.setWaitDetails(Info.DevNumExpr, Info.QueuesLoc, 1121 std::move(Info.QueueIdExprs)); 1122 break; 1123 } 1124 default: 1125 llvm_unreachable("Not an optional parens type?"); 1126 } 1127 ParsedClause.setEndLoc(getCurToken().getLocation()); 1128 if (Parens.consumeClose()) 1129 return OpenACCCannotContinue(); 1130 } else { 1131 // If we have optional parens, make sure we set the end-location to the 1132 // clause, as we are a 'single token' clause. 1133 ParsedClause.setEndLoc(ClauseLoc); 1134 } 1135 } else { 1136 ParsedClause.setEndLoc(ClauseLoc); 1137 } 1138 return OpenACCSuccess( 1139 Actions.OpenACC().ActOnClause(ExistingClauses, ParsedClause)); 1140 } 1141 1142 /// OpenACC 3.3 section 2.16: 1143 /// In this section and throughout the specification, the term async-argument 1144 /// means a nonnegative scalar integer expression (int for C or C++, integer for 1145 /// Fortran), or one of the special values acc_async_noval or acc_async_sync, as 1146 /// defined in the C header file and the Fortran openacc module. The special 1147 /// values are negative values, so as not to conflict with a user-specified 1148 /// nonnegative async-argument. 1149 Parser::OpenACCIntExprParseResult 1150 Parser::ParseOpenACCAsyncArgument(OpenACCDirectiveKind DK, OpenACCClauseKind CK, 1151 SourceLocation Loc) { 1152 return ParseOpenACCIntExpr(DK, CK, Loc); 1153 } 1154 1155 /// OpenACC 3.3, section 2.16: 1156 /// In this section and throughout the specification, the term wait-argument 1157 /// means: 1158 /// [ devnum : int-expr : ] [ queues : ] async-argument-list 1159 Parser::OpenACCWaitParseInfo 1160 Parser::ParseOpenACCWaitArgument(SourceLocation Loc, bool IsDirective) { 1161 OpenACCWaitParseInfo Result; 1162 // [devnum : int-expr : ] 1163 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::DevNum, Tok) && 1164 NextToken().is(tok::colon)) { 1165 // Consume devnum. 1166 ConsumeToken(); 1167 // Consume colon. 1168 ConsumeToken(); 1169 1170 OpenACCIntExprParseResult Res = ParseOpenACCIntExpr( 1171 IsDirective ? OpenACCDirectiveKind::Wait 1172 : OpenACCDirectiveKind::Invalid, 1173 IsDirective ? OpenACCClauseKind::Invalid : OpenACCClauseKind::Wait, 1174 Loc); 1175 if (Res.first.isInvalid() && 1176 Res.second == OpenACCParseCanContinue::Cannot) { 1177 Result.Failed = true; 1178 return Result; 1179 } 1180 1181 if (ExpectAndConsume(tok::colon)) { 1182 Result.Failed = true; 1183 return Result; 1184 } 1185 1186 Result.DevNumExpr = Res.first.get(); 1187 } 1188 1189 // [ queues : ] 1190 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Queues, Tok) && 1191 NextToken().is(tok::colon)) { 1192 // Consume queues. 1193 Result.QueuesLoc = ConsumeToken(); 1194 // Consume colon. 1195 ConsumeToken(); 1196 } 1197 1198 // OpenACC 3.3, section 2.16: 1199 // the term 'async-argument' means a nonnegative scalar integer expression, or 1200 // one of the special values 'acc_async_noval' or 'acc_async_sync', as defined 1201 // in the C header file and the Fortran opacc module. 1202 bool FirstArg = true; 1203 while (!getCurToken().isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) { 1204 if (!FirstArg) { 1205 if (ExpectAndConsume(tok::comma)) { 1206 Result.Failed = true; 1207 return Result; 1208 } 1209 } 1210 FirstArg = false; 1211 1212 OpenACCIntExprParseResult Res = ParseOpenACCAsyncArgument( 1213 IsDirective ? OpenACCDirectiveKind::Wait 1214 : OpenACCDirectiveKind::Invalid, 1215 IsDirective ? OpenACCClauseKind::Invalid : OpenACCClauseKind::Wait, 1216 Loc); 1217 1218 if (Res.first.isInvalid() && 1219 Res.second == OpenACCParseCanContinue::Cannot) { 1220 Result.Failed = true; 1221 return Result; 1222 } 1223 1224 Result.QueueIdExprs.push_back(Res.first.get()); 1225 } 1226 1227 return Result; 1228 } 1229 1230 ExprResult Parser::ParseOpenACCIDExpression() { 1231 ExprResult Res; 1232 if (getLangOpts().CPlusPlus) { 1233 Res = ParseCXXIdExpression(/*isAddressOfOperand=*/true); 1234 } else { 1235 // There isn't anything quite the same as ParseCXXIdExpression for C, so we 1236 // need to get the identifier, then call into Sema ourselves. 1237 1238 if (Tok.isNot(tok::identifier)) { 1239 Diag(Tok, diag::err_expected) << tok::identifier; 1240 return ExprError(); 1241 } 1242 1243 Token FuncName = getCurToken(); 1244 UnqualifiedId Name; 1245 CXXScopeSpec ScopeSpec; 1246 SourceLocation TemplateKWLoc; 1247 Name.setIdentifier(FuncName.getIdentifierInfo(), ConsumeToken()); 1248 1249 // Ensure this is a valid identifier. We don't accept causing implicit 1250 // function declarations per the spec, so always claim to not have trailing 1251 // L Paren. 1252 Res = Actions.ActOnIdExpression(getCurScope(), ScopeSpec, TemplateKWLoc, 1253 Name, /*HasTrailingLParen=*/false, 1254 /*isAddressOfOperand=*/false); 1255 } 1256 1257 return getActions().CorrectDelayedTyposInExpr(Res); 1258 } 1259 1260 ExprResult Parser::ParseOpenACCBindClauseArgument() { 1261 // OpenACC 3.3 section 2.15: 1262 // The bind clause specifies the name to use when calling the procedure on a 1263 // device other than the host. If the name is specified as an identifier, it 1264 // is called as if that name were specified in the language being compiled. If 1265 // the name is specified as a string, the string is used for the procedure 1266 // name unmodified. 1267 if (getCurToken().is(tok::r_paren)) { 1268 Diag(getCurToken(), diag::err_acc_incorrect_bind_arg); 1269 return ExprError(); 1270 } 1271 1272 if (tok::isStringLiteral(getCurToken().getKind())) 1273 return getActions().CorrectDelayedTyposInExpr(ParseStringLiteralExpression( 1274 /*AllowUserDefinedLiteral=*/false, /*Unevaluated=*/true)); 1275 1276 return ParseOpenACCIDExpression(); 1277 } 1278 1279 /// OpenACC 3.3, section 1.6: 1280 /// In this spec, a 'var' (in italics) is one of the following: 1281 /// - a variable name (a scalar, array, or composite variable name) 1282 /// - a subarray specification with subscript ranges 1283 /// - an array element 1284 /// - a member of a composite variable 1285 /// - a common block name between slashes (fortran only) 1286 Parser::OpenACCVarParseResult Parser::ParseOpenACCVar(OpenACCClauseKind CK) { 1287 OpenACCArraySectionRAII ArraySections(*this); 1288 1289 ExprResult Res = ParseAssignmentExpression(); 1290 if (!Res.isUsable()) 1291 return {Res, OpenACCParseCanContinue::Cannot}; 1292 1293 Res = getActions().CorrectDelayedTyposInExpr(Res.get()); 1294 if (!Res.isUsable()) 1295 return {Res, OpenACCParseCanContinue::Can}; 1296 1297 Res = getActions().OpenACC().ActOnVar(CK, Res.get()); 1298 1299 return {Res, OpenACCParseCanContinue::Can}; 1300 } 1301 1302 llvm::SmallVector<Expr *> Parser::ParseOpenACCVarList(OpenACCClauseKind CK) { 1303 llvm::SmallVector<Expr *> Vars; 1304 1305 auto [Res, CanContinue] = ParseOpenACCVar(CK); 1306 if (Res.isUsable()) { 1307 Vars.push_back(Res.get()); 1308 } else if (CanContinue == OpenACCParseCanContinue::Cannot) { 1309 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end, StopBeforeMatch); 1310 return Vars; 1311 } 1312 1313 while (!getCurToken().isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) { 1314 ExpectAndConsume(tok::comma); 1315 1316 auto [Res, CanContinue] = ParseOpenACCVar(CK); 1317 1318 if (Res.isUsable()) { 1319 Vars.push_back(Res.get()); 1320 } else if (CanContinue == OpenACCParseCanContinue::Cannot) { 1321 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end, StopBeforeMatch); 1322 return Vars; 1323 } 1324 } 1325 return Vars; 1326 } 1327 1328 /// OpenACC 3.3, section 2.10: 1329 /// In C and C++, the syntax of the cache directive is: 1330 /// 1331 /// #pragma acc cache ([readonly:]var-list) new-line 1332 void Parser::ParseOpenACCCacheVarList() { 1333 // If this is the end of the line, just return 'false' and count on the close 1334 // paren diagnostic to catch the issue. 1335 if (getCurToken().isAnnotation()) 1336 return; 1337 1338 // The VarList is an optional `readonly:` followed by a list of a variable 1339 // specifications. Consume something that looks like a 'tag', and diagnose if 1340 // it isn't 'readonly'. 1341 if (tryParseAndConsumeSpecialTokenKind(*this, 1342 OpenACCSpecialTokenKind::ReadOnly, 1343 OpenACCDirectiveKind::Cache)) { 1344 // FIXME: Record that this is a 'readonly' so that we can use that during 1345 // Sema/AST generation. 1346 } 1347 1348 // ParseOpenACCVarList should leave us before a r-paren, so no need to skip 1349 // anything here. 1350 ParseOpenACCVarList(OpenACCClauseKind::Invalid); 1351 } 1352 1353 Parser::OpenACCDirectiveParseInfo 1354 Parser::ParseOpenACCDirective() { 1355 SourceLocation StartLoc = ConsumeAnnotationToken(); 1356 SourceLocation DirLoc = getCurToken().getLocation(); 1357 OpenACCDirectiveKind DirKind = ParseOpenACCDirectiveKind(*this); 1358 1359 getActions().OpenACC().ActOnConstruct(DirKind, DirLoc); 1360 1361 // Once we've parsed the construct/directive name, some have additional 1362 // specifiers that need to be taken care of. Atomic has an 'atomic-clause' 1363 // that needs to be parsed. 1364 if (DirKind == OpenACCDirectiveKind::Atomic) 1365 ParseOpenACCAtomicKind(*this); 1366 1367 // We've successfully parsed the construct/directive name, however a few of 1368 // the constructs have optional parens that contain further details. 1369 BalancedDelimiterTracker T(*this, tok::l_paren, 1370 tok::annot_pragma_openacc_end); 1371 1372 if (!T.consumeOpen()) { 1373 switch (DirKind) { 1374 default: 1375 Diag(T.getOpenLocation(), diag::err_acc_invalid_open_paren); 1376 T.skipToEnd(); 1377 break; 1378 case OpenACCDirectiveKind::Routine: { 1379 // Routine has an optional paren-wrapped name of a function in the local 1380 // scope. We parse the name, emitting any diagnostics 1381 ExprResult RoutineName = ParseOpenACCIDExpression(); 1382 // If the routine name is invalid, just skip until the closing paren to 1383 // recover more gracefully. 1384 if (RoutineName.isInvalid()) 1385 T.skipToEnd(); 1386 else 1387 T.consumeClose(); 1388 break; 1389 } 1390 case OpenACCDirectiveKind::Cache: 1391 ParseOpenACCCacheVarList(); 1392 // The ParseOpenACCCacheVarList function manages to recover from failures, 1393 // so we can always consume the close. 1394 T.consumeClose(); 1395 break; 1396 case OpenACCDirectiveKind::Wait: 1397 // OpenACC has an optional paren-wrapped 'wait-argument'. 1398 if (ParseOpenACCWaitArgument(DirLoc, /*IsDirective=*/true).Failed) 1399 T.skipToEnd(); 1400 else 1401 T.consumeClose(); 1402 break; 1403 } 1404 } else if (DirKind == OpenACCDirectiveKind::Cache) { 1405 // Cache's paren var-list is required, so error here if it isn't provided. 1406 // We know that the consumeOpen above left the first non-paren here, so 1407 // diagnose, then continue as if it was completely omitted. 1408 Diag(Tok, diag::err_expected) << tok::l_paren; 1409 } 1410 1411 // Parses the list of clauses, if present, plus set up return value. 1412 OpenACCDirectiveParseInfo ParseInfo{DirKind, StartLoc, DirLoc, 1413 SourceLocation{}, 1414 ParseOpenACCClauseList(DirKind)}; 1415 1416 assert(Tok.is(tok::annot_pragma_openacc_end) && 1417 "Didn't parse all OpenACC Clauses"); 1418 ParseInfo.EndLoc = ConsumeAnnotationToken(); 1419 assert(ParseInfo.EndLoc.isValid() && 1420 "Terminating annotation token not present"); 1421 1422 return ParseInfo; 1423 } 1424 1425 // Parse OpenACC directive on a declaration. 1426 Parser::DeclGroupPtrTy Parser::ParseOpenACCDirectiveDecl() { 1427 assert(Tok.is(tok::annot_pragma_openacc) && "expected OpenACC Start Token"); 1428 1429 ParsingOpenACCDirectiveRAII DirScope(*this); 1430 1431 OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective(); 1432 1433 if (getActions().OpenACC().ActOnStartDeclDirective(DirInfo.DirKind, 1434 DirInfo.StartLoc)) 1435 return nullptr; 1436 1437 // TODO OpenACC: Do whatever decl parsing is required here. 1438 return DeclGroupPtrTy::make(getActions().OpenACC().ActOnEndDeclDirective()); 1439 } 1440 1441 // Parse OpenACC Directive on a Statement. 1442 StmtResult Parser::ParseOpenACCDirectiveStmt() { 1443 assert(Tok.is(tok::annot_pragma_openacc) && "expected OpenACC Start Token"); 1444 1445 ParsingOpenACCDirectiveRAII DirScope(*this); 1446 1447 OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective(); 1448 if (getActions().OpenACC().ActOnStartStmtDirective(DirInfo.DirKind, 1449 DirInfo.StartLoc)) 1450 return StmtError(); 1451 1452 StmtResult AssocStmt; 1453 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(getActions().OpenACC(), 1454 DirInfo.DirKind); 1455 if (doesDirectiveHaveAssociatedStmt(DirInfo.DirKind)) { 1456 ParsingOpenACCDirectiveRAII DirScope(*this, /*Value=*/false); 1457 ParseScope ACCScope(this, getOpenACCScopeFlags(DirInfo.DirKind)); 1458 1459 AssocStmt = getActions().OpenACC().ActOnAssociatedStmt( 1460 DirInfo.StartLoc, DirInfo.DirKind, ParseStatement()); 1461 } 1462 1463 return getActions().OpenACC().ActOnEndStmtDirective( 1464 DirInfo.DirKind, DirInfo.StartLoc, DirInfo.DirLoc, DirInfo.EndLoc, 1465 DirInfo.Clauses, AssocStmt); 1466 } 1467