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/Basic/OpenACCKinds.h" 14 #include "clang/Parse/ParseDiagnostic.h" 15 #include "clang/Parse/Parser.h" 16 #include "clang/Parse/RAIIObjectsForParser.h" 17 #include "llvm/ADT/StringRef.h" 18 #include "llvm/ADT/StringSwitch.h" 19 20 using namespace clang; 21 using namespace llvm; 22 23 namespace { 24 // An enum that contains the extended 'partial' parsed variants. This type 25 // should never escape the initial parse functionality, but is useful for 26 // simplifying the implementation. 27 enum class OpenACCDirectiveKindEx { 28 Invalid = static_cast<int>(OpenACCDirectiveKind::Invalid), 29 // 'enter data' and 'exit data' 30 Enter, 31 Exit, 32 }; 33 34 // Translate single-token string representations to the OpenACC Directive Kind. 35 // This doesn't completely comprehend 'Compound Constructs' (as it just 36 // identifies the first token), and doesn't fully handle 'enter data', 'exit 37 // data', nor any of the 'atomic' variants, just the first token of each. So 38 // this should only be used by `ParseOpenACCDirectiveKind`. 39 OpenACCDirectiveKindEx getOpenACCDirectiveKind(Token Tok) { 40 if (!Tok.is(tok::identifier)) 41 return OpenACCDirectiveKindEx::Invalid; 42 OpenACCDirectiveKind DirKind = 43 llvm::StringSwitch<OpenACCDirectiveKind>( 44 Tok.getIdentifierInfo()->getName()) 45 .Case("parallel", OpenACCDirectiveKind::Parallel) 46 .Case("serial", OpenACCDirectiveKind::Serial) 47 .Case("kernels", OpenACCDirectiveKind::Kernels) 48 .Case("data", OpenACCDirectiveKind::Data) 49 .Case("host_data", OpenACCDirectiveKind::HostData) 50 .Case("loop", OpenACCDirectiveKind::Loop) 51 .Case("cache", OpenACCDirectiveKind::Cache) 52 .Case("atomic", OpenACCDirectiveKind::Atomic) 53 .Case("routine", OpenACCDirectiveKind::Routine) 54 .Case("declare", OpenACCDirectiveKind::Declare) 55 .Case("init", OpenACCDirectiveKind::Init) 56 .Case("shutdown", OpenACCDirectiveKind::Shutdown) 57 .Case("set", OpenACCDirectiveKind::Shutdown) 58 .Case("update", OpenACCDirectiveKind::Update) 59 .Case("wait", OpenACCDirectiveKind::Wait) 60 .Default(OpenACCDirectiveKind::Invalid); 61 62 if (DirKind != OpenACCDirectiveKind::Invalid) 63 return static_cast<OpenACCDirectiveKindEx>(DirKind); 64 65 return llvm::StringSwitch<OpenACCDirectiveKindEx>( 66 Tok.getIdentifierInfo()->getName()) 67 .Case("enter", OpenACCDirectiveKindEx::Enter) 68 .Case("exit", OpenACCDirectiveKindEx::Exit) 69 .Default(OpenACCDirectiveKindEx::Invalid); 70 } 71 72 // Translate single-token string representations to the OpenCC Clause Kind. 73 OpenACCClauseKind getOpenACCClauseKind(Token Tok) { 74 // auto is a keyword in some language modes, so make sure we parse it 75 // correctly. 76 if (Tok.is(tok::kw_auto)) 77 return OpenACCClauseKind::Auto; 78 79 // default is a keyword, so make sure we parse it correctly. 80 if (Tok.is(tok::kw_default)) 81 return OpenACCClauseKind::Default; 82 83 // if is also a keyword, make sure we parse it correctly. 84 if (Tok.is(tok::kw_if)) 85 return OpenACCClauseKind::If; 86 87 if (!Tok.is(tok::identifier)) 88 return OpenACCClauseKind::Invalid; 89 90 return llvm::StringSwitch<OpenACCClauseKind>( 91 Tok.getIdentifierInfo()->getName()) 92 .Case("attach", OpenACCClauseKind::Attach) 93 .Case("auto", OpenACCClauseKind::Auto) 94 .Case("bind", OpenACCClauseKind::Bind) 95 .Case("create", OpenACCClauseKind::Create) 96 .Case("collapse", OpenACCClauseKind::Collapse) 97 .Case("copy", OpenACCClauseKind::Copy) 98 .Case("copyin", OpenACCClauseKind::CopyIn) 99 .Case("copyout", OpenACCClauseKind::CopyOut) 100 .Case("default", OpenACCClauseKind::Default) 101 .Case("default_async", OpenACCClauseKind::DefaultAsync) 102 .Case("delete", OpenACCClauseKind::Delete) 103 .Case("detach", OpenACCClauseKind::Detach) 104 .Case("device", OpenACCClauseKind::Device) 105 .Case("device_num", OpenACCClauseKind::DeviceNum) 106 .Case("device_resident", OpenACCClauseKind::DeviceResident) 107 .Case("device_type", OpenACCClauseKind::DeviceType) 108 .Case("deviceptr", OpenACCClauseKind::DevicePtr) 109 .Case("dtype", OpenACCClauseKind::DType) 110 .Case("finalize", OpenACCClauseKind::Finalize) 111 .Case("firstprivate", OpenACCClauseKind::FirstPrivate) 112 .Case("host", OpenACCClauseKind::Host) 113 .Case("if", OpenACCClauseKind::If) 114 .Case("if_present", OpenACCClauseKind::IfPresent) 115 .Case("independent", OpenACCClauseKind::Independent) 116 .Case("link", OpenACCClauseKind::Link) 117 .Case("no_create", OpenACCClauseKind::NoCreate) 118 .Case("num_gangs", OpenACCClauseKind::NumGangs) 119 .Case("num_workers", OpenACCClauseKind::NumWorkers) 120 .Case("nohost", OpenACCClauseKind::NoHost) 121 .Case("present", OpenACCClauseKind::Present) 122 .Case("private", OpenACCClauseKind::Private) 123 .Case("reduction", OpenACCClauseKind::Reduction) 124 .Case("self", OpenACCClauseKind::Self) 125 .Case("seq", OpenACCClauseKind::Seq) 126 .Case("use_device", OpenACCClauseKind::UseDevice) 127 .Case("vector", OpenACCClauseKind::Vector) 128 .Case("vector_length", OpenACCClauseKind::VectorLength) 129 .Case("worker", OpenACCClauseKind::Worker) 130 .Default(OpenACCClauseKind::Invalid); 131 } 132 133 // Since 'atomic' is effectively a compound directive, this will decode the 134 // second part of the directive. 135 OpenACCAtomicKind getOpenACCAtomicKind(Token Tok) { 136 if (!Tok.is(tok::identifier)) 137 return OpenACCAtomicKind::Invalid; 138 return llvm::StringSwitch<OpenACCAtomicKind>( 139 Tok.getIdentifierInfo()->getName()) 140 .Case("read", OpenACCAtomicKind::Read) 141 .Case("write", OpenACCAtomicKind::Write) 142 .Case("update", OpenACCAtomicKind::Update) 143 .Case("capture", OpenACCAtomicKind::Capture) 144 .Default(OpenACCAtomicKind::Invalid); 145 } 146 147 OpenACCDefaultClauseKind getOpenACCDefaultClauseKind(Token Tok) { 148 if (!Tok.is(tok::identifier)) 149 return OpenACCDefaultClauseKind::Invalid; 150 151 return llvm::StringSwitch<OpenACCDefaultClauseKind>( 152 Tok.getIdentifierInfo()->getName()) 153 .Case("none", OpenACCDefaultClauseKind::None) 154 .Case("present", OpenACCDefaultClauseKind::Present) 155 .Default(OpenACCDefaultClauseKind::Invalid); 156 } 157 158 enum class OpenACCSpecialTokenKind { 159 ReadOnly, 160 DevNum, 161 Queues, 162 Zero, 163 Force, 164 Num, 165 Length, 166 }; 167 168 bool isOpenACCSpecialToken(OpenACCSpecialTokenKind Kind, Token Tok) { 169 if (!Tok.is(tok::identifier)) 170 return false; 171 172 switch (Kind) { 173 case OpenACCSpecialTokenKind::ReadOnly: 174 return Tok.getIdentifierInfo()->isStr("readonly"); 175 case OpenACCSpecialTokenKind::DevNum: 176 return Tok.getIdentifierInfo()->isStr("devnum"); 177 case OpenACCSpecialTokenKind::Queues: 178 return Tok.getIdentifierInfo()->isStr("queues"); 179 case OpenACCSpecialTokenKind::Zero: 180 return Tok.getIdentifierInfo()->isStr("zero"); 181 case OpenACCSpecialTokenKind::Force: 182 return Tok.getIdentifierInfo()->isStr("force"); 183 case OpenACCSpecialTokenKind::Num: 184 return Tok.getIdentifierInfo()->isStr("num"); 185 case OpenACCSpecialTokenKind::Length: 186 return Tok.getIdentifierInfo()->isStr("length"); 187 } 188 llvm_unreachable("Unknown 'Kind' Passed"); 189 } 190 191 /// Used for cases where we have a token we want to check against an 192 /// 'identifier-like' token, but don't want to give awkward error messages in 193 /// cases where it is accidentially a keyword. 194 bool isTokenIdentifierOrKeyword(Parser &P, Token Tok) { 195 if (Tok.is(tok::identifier)) 196 return true; 197 198 if (!Tok.isAnnotation() && Tok.getIdentifierInfo() && 199 Tok.getIdentifierInfo()->isKeyword(P.getLangOpts())) 200 return true; 201 202 return false; 203 } 204 205 /// Parses and consumes an identifer followed immediately by a single colon, and 206 /// diagnoses if it is not the 'special token' kind that we require. Used when 207 /// the tag is the only valid value. 208 /// Return 'true' if the special token was matched, false if no special token, 209 /// or an invalid special token was found. 210 template <typename DirOrClauseTy> 211 bool tryParseAndConsumeSpecialTokenKind(Parser &P, OpenACCSpecialTokenKind Kind, 212 DirOrClauseTy DirOrClause) { 213 Token IdentTok = P.getCurToken(); 214 // If this is an identifier-like thing followed by ':', it is one of the 215 // OpenACC 'special' name tags, so consume it. 216 if (isTokenIdentifierOrKeyword(P, IdentTok) && P.NextToken().is(tok::colon)) { 217 P.ConsumeToken(); 218 P.ConsumeToken(); 219 220 if (!isOpenACCSpecialToken(Kind, IdentTok)) { 221 P.Diag(IdentTok, diag::err_acc_invalid_tag_kind) 222 << IdentTok.getIdentifierInfo() << DirOrClause 223 << std::is_same_v<DirOrClauseTy, OpenACCClauseKind>; 224 return false; 225 } 226 227 return true; 228 } 229 230 return false; 231 } 232 233 bool isOpenACCDirectiveKind(OpenACCDirectiveKind Kind, Token Tok) { 234 if (!Tok.is(tok::identifier)) 235 return false; 236 237 switch (Kind) { 238 case OpenACCDirectiveKind::Parallel: 239 return Tok.getIdentifierInfo()->isStr("parallel"); 240 case OpenACCDirectiveKind::Serial: 241 return Tok.getIdentifierInfo()->isStr("serial"); 242 case OpenACCDirectiveKind::Kernels: 243 return Tok.getIdentifierInfo()->isStr("kernels"); 244 case OpenACCDirectiveKind::Data: 245 return Tok.getIdentifierInfo()->isStr("data"); 246 case OpenACCDirectiveKind::HostData: 247 return Tok.getIdentifierInfo()->isStr("host_data"); 248 case OpenACCDirectiveKind::Loop: 249 return Tok.getIdentifierInfo()->isStr("loop"); 250 case OpenACCDirectiveKind::Cache: 251 return Tok.getIdentifierInfo()->isStr("cache"); 252 253 case OpenACCDirectiveKind::ParallelLoop: 254 case OpenACCDirectiveKind::SerialLoop: 255 case OpenACCDirectiveKind::KernelsLoop: 256 case OpenACCDirectiveKind::EnterData: 257 case OpenACCDirectiveKind::ExitData: 258 return false; 259 260 case OpenACCDirectiveKind::Atomic: 261 return Tok.getIdentifierInfo()->isStr("atomic"); 262 case OpenACCDirectiveKind::Routine: 263 return Tok.getIdentifierInfo()->isStr("routine"); 264 case OpenACCDirectiveKind::Declare: 265 return Tok.getIdentifierInfo()->isStr("declare"); 266 case OpenACCDirectiveKind::Init: 267 return Tok.getIdentifierInfo()->isStr("init"); 268 case OpenACCDirectiveKind::Shutdown: 269 return Tok.getIdentifierInfo()->isStr("shutdown"); 270 case OpenACCDirectiveKind::Set: 271 return Tok.getIdentifierInfo()->isStr("set"); 272 case OpenACCDirectiveKind::Update: 273 return Tok.getIdentifierInfo()->isStr("update"); 274 case OpenACCDirectiveKind::Wait: 275 return Tok.getIdentifierInfo()->isStr("wait"); 276 case OpenACCDirectiveKind::Invalid: 277 return false; 278 } 279 llvm_unreachable("Unknown 'Kind' Passed"); 280 } 281 282 OpenACCReductionOperator ParseReductionOperator(Parser &P) { 283 // If there is no colon, treat as if the reduction operator was missing, else 284 // we probably will not recover from it in the case where an expression starts 285 // with one of the operator tokens. 286 if (P.NextToken().isNot(tok::colon)) { 287 P.Diag(P.getCurToken(), diag::err_acc_expected_reduction_operator); 288 return OpenACCReductionOperator::Invalid; 289 } 290 Token ReductionKindTok = P.getCurToken(); 291 // Consume both the kind and the colon. 292 P.ConsumeToken(); 293 P.ConsumeToken(); 294 295 switch (ReductionKindTok.getKind()) { 296 case tok::plus: 297 return OpenACCReductionOperator::Addition; 298 case tok::star: 299 return OpenACCReductionOperator::Multiplication; 300 case tok::amp: 301 return OpenACCReductionOperator::BitwiseAnd; 302 case tok::pipe: 303 return OpenACCReductionOperator::BitwiseOr; 304 case tok::caret: 305 return OpenACCReductionOperator::BitwiseXOr; 306 case tok::ampamp: 307 return OpenACCReductionOperator::And; 308 case tok::pipepipe: 309 return OpenACCReductionOperator::Or; 310 case tok::identifier: 311 if (ReductionKindTok.getIdentifierInfo()->isStr("max")) 312 return OpenACCReductionOperator::Max; 313 if (ReductionKindTok.getIdentifierInfo()->isStr("min")) 314 return OpenACCReductionOperator::Min; 315 LLVM_FALLTHROUGH; 316 default: 317 P.Diag(ReductionKindTok, diag::err_acc_invalid_reduction_operator); 318 return OpenACCReductionOperator::Invalid; 319 } 320 llvm_unreachable("Reduction op token kind not caught by 'default'?"); 321 } 322 323 /// Used for cases where we expect an identifier-like token, but don't want to 324 /// give awkward error messages in cases where it is accidentially a keyword. 325 bool expectIdentifierOrKeyword(Parser &P) { 326 Token Tok = P.getCurToken(); 327 328 if (isTokenIdentifierOrKeyword(P, Tok)) 329 return false; 330 331 P.Diag(P.getCurToken(), diag::err_expected) << tok::identifier; 332 return true; 333 } 334 335 OpenACCDirectiveKind 336 ParseOpenACCEnterExitDataDirective(Parser &P, Token FirstTok, 337 OpenACCDirectiveKindEx ExtDirKind) { 338 Token SecondTok = P.getCurToken(); 339 340 if (SecondTok.isAnnotation()) { 341 P.Diag(FirstTok, diag::err_acc_invalid_directive) 342 << 0 << FirstTok.getIdentifierInfo(); 343 return OpenACCDirectiveKind::Invalid; 344 } 345 346 // Consume the second name anyway, this way we can continue on without making 347 // this oddly look like a clause. 348 P.ConsumeAnyToken(); 349 350 if (!isOpenACCDirectiveKind(OpenACCDirectiveKind::Data, SecondTok)) { 351 if (!SecondTok.is(tok::identifier)) 352 P.Diag(SecondTok, diag::err_expected) << tok::identifier; 353 else 354 P.Diag(FirstTok, diag::err_acc_invalid_directive) 355 << 1 << FirstTok.getIdentifierInfo()->getName() 356 << SecondTok.getIdentifierInfo()->getName(); 357 return OpenACCDirectiveKind::Invalid; 358 } 359 360 return ExtDirKind == OpenACCDirectiveKindEx::Enter 361 ? OpenACCDirectiveKind::EnterData 362 : OpenACCDirectiveKind::ExitData; 363 } 364 365 OpenACCAtomicKind ParseOpenACCAtomicKind(Parser &P) { 366 Token AtomicClauseToken = P.getCurToken(); 367 368 // #pragma acc atomic is equivilent to update: 369 if (AtomicClauseToken.isAnnotation()) 370 return OpenACCAtomicKind::Update; 371 372 OpenACCAtomicKind AtomicKind = getOpenACCAtomicKind(AtomicClauseToken); 373 374 // If we don't know what this is, treat it as 'nothing', and treat the rest of 375 // this as a clause list, which, despite being invalid, is likely what the 376 // user was trying to do. 377 if (AtomicKind == OpenACCAtomicKind::Invalid) 378 return OpenACCAtomicKind::Update; 379 380 P.ConsumeToken(); 381 return AtomicKind; 382 } 383 384 // Parse and consume the tokens for OpenACC Directive/Construct kinds. 385 OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) { 386 Token FirstTok = P.getCurToken(); 387 388 // Just #pragma acc can get us immediately to the end, make sure we don't 389 // introspect on the spelling before then. 390 if (FirstTok.isNot(tok::identifier)) { 391 P.Diag(FirstTok, diag::err_acc_missing_directive); 392 393 if (P.getCurToken().isNot(tok::annot_pragma_openacc_end)) 394 P.ConsumeAnyToken(); 395 396 return OpenACCDirectiveKind::Invalid; 397 } 398 399 P.ConsumeToken(); 400 401 OpenACCDirectiveKindEx ExDirKind = getOpenACCDirectiveKind(FirstTok); 402 403 // OpenACCDirectiveKindEx is meant to be an extended list 404 // over OpenACCDirectiveKind, so any value below Invalid is one of the 405 // OpenACCDirectiveKind values. This switch takes care of all of the extra 406 // parsing required for the Extended values. At the end of this block, 407 // ExDirKind can be assumed to be a valid OpenACCDirectiveKind, so we can 408 // immediately cast it and use it as that. 409 if (ExDirKind >= OpenACCDirectiveKindEx::Invalid) { 410 switch (ExDirKind) { 411 case OpenACCDirectiveKindEx::Invalid: { 412 P.Diag(FirstTok, diag::err_acc_invalid_directive) 413 << 0 << FirstTok.getIdentifierInfo(); 414 return OpenACCDirectiveKind::Invalid; 415 } 416 case OpenACCDirectiveKindEx::Enter: 417 case OpenACCDirectiveKindEx::Exit: 418 return ParseOpenACCEnterExitDataDirective(P, FirstTok, ExDirKind); 419 } 420 } 421 422 OpenACCDirectiveKind DirKind = static_cast<OpenACCDirectiveKind>(ExDirKind); 423 424 // Combined Constructs allows parallel loop, serial loop, or kernels loop. Any 425 // other attempt at a combined construct will be diagnosed as an invalid 426 // clause. 427 Token SecondTok = P.getCurToken(); 428 if (!SecondTok.isAnnotation() && 429 isOpenACCDirectiveKind(OpenACCDirectiveKind::Loop, SecondTok)) { 430 switch (DirKind) { 431 default: 432 // Nothing to do except in the below cases, as they should be diagnosed as 433 // a clause. 434 break; 435 case OpenACCDirectiveKind::Parallel: 436 P.ConsumeToken(); 437 return OpenACCDirectiveKind::ParallelLoop; 438 case OpenACCDirectiveKind::Serial: 439 P.ConsumeToken(); 440 return OpenACCDirectiveKind::SerialLoop; 441 case OpenACCDirectiveKind::Kernels: 442 P.ConsumeToken(); 443 return OpenACCDirectiveKind::KernelsLoop; 444 } 445 } 446 447 return DirKind; 448 } 449 450 enum ClauseParensKind { 451 None, 452 Optional, 453 Required 454 }; 455 456 ClauseParensKind getClauseParensKind(OpenACCDirectiveKind DirKind, 457 OpenACCClauseKind Kind) { 458 switch (Kind) { 459 case OpenACCClauseKind::Self: 460 return DirKind == OpenACCDirectiveKind::Update ? ClauseParensKind::Required 461 : ClauseParensKind::Optional; 462 case OpenACCClauseKind::Worker: 463 case OpenACCClauseKind::Vector: 464 return ClauseParensKind::Optional; 465 466 case OpenACCClauseKind::Default: 467 case OpenACCClauseKind::If: 468 case OpenACCClauseKind::Create: 469 case OpenACCClauseKind::Copy: 470 case OpenACCClauseKind::CopyIn: 471 case OpenACCClauseKind::CopyOut: 472 case OpenACCClauseKind::UseDevice: 473 case OpenACCClauseKind::NoCreate: 474 case OpenACCClauseKind::Present: 475 case OpenACCClauseKind::DevicePtr: 476 case OpenACCClauseKind::Attach: 477 case OpenACCClauseKind::Detach: 478 case OpenACCClauseKind::Private: 479 case OpenACCClauseKind::FirstPrivate: 480 case OpenACCClauseKind::Delete: 481 case OpenACCClauseKind::DeviceResident: 482 case OpenACCClauseKind::Device: 483 case OpenACCClauseKind::Link: 484 case OpenACCClauseKind::Host: 485 case OpenACCClauseKind::Reduction: 486 case OpenACCClauseKind::Collapse: 487 case OpenACCClauseKind::Bind: 488 case OpenACCClauseKind::VectorLength: 489 case OpenACCClauseKind::NumGangs: 490 case OpenACCClauseKind::NumWorkers: 491 case OpenACCClauseKind::DeviceNum: 492 case OpenACCClauseKind::DefaultAsync: 493 case OpenACCClauseKind::DeviceType: 494 case OpenACCClauseKind::DType: 495 return ClauseParensKind::Required; 496 497 case OpenACCClauseKind::Auto: 498 case OpenACCClauseKind::Finalize: 499 case OpenACCClauseKind::IfPresent: 500 case OpenACCClauseKind::Independent: 501 case OpenACCClauseKind::Invalid: 502 case OpenACCClauseKind::NoHost: 503 case OpenACCClauseKind::Seq: 504 return ClauseParensKind::None; 505 } 506 llvm_unreachable("Unhandled clause kind"); 507 } 508 509 bool ClauseHasOptionalParens(OpenACCDirectiveKind DirKind, 510 OpenACCClauseKind Kind) { 511 return getClauseParensKind(DirKind, Kind) == ClauseParensKind::Optional; 512 } 513 514 bool ClauseHasRequiredParens(OpenACCDirectiveKind DirKind, 515 OpenACCClauseKind Kind) { 516 return getClauseParensKind(DirKind, Kind) == ClauseParensKind::Required; 517 } 518 519 ExprResult ParseOpenACCConditionalExpr(Parser &P) { 520 // FIXME: It isn't clear if the spec saying 'condition' means the same as 521 // it does in an if/while/etc (See ParseCXXCondition), however as it was 522 // written with Fortran/C in mind, we're going to assume it just means an 523 // 'expression evaluating to boolean'. 524 return P.getActions().CorrectDelayedTyposInExpr(P.ParseExpression()); 525 } 526 527 // Skip until we see the end of pragma token, but don't consume it. This is us 528 // just giving up on the rest of the pragma so we can continue executing. We 529 // have to do this because 'SkipUntil' considers paren balancing, which isn't 530 // what we want. 531 void SkipUntilEndOfDirective(Parser &P) { 532 while (P.getCurToken().isNot(tok::annot_pragma_openacc_end)) 533 P.ConsumeAnyToken(); 534 } 535 536 } // namespace 537 538 // OpenACC 3.3, section 1.7: 539 // To simplify the specification and convey appropriate constraint information, 540 // a pqr-list is a comma-separated list of pdr items. The one exception is a 541 // clause-list, which is a list of one or more clauses optionally separated by 542 // commas. 543 void Parser::ParseOpenACCClauseList(OpenACCDirectiveKind DirKind) { 544 bool FirstClause = true; 545 while (getCurToken().isNot(tok::annot_pragma_openacc_end)) { 546 // Comma is optional in a clause-list. 547 if (!FirstClause && getCurToken().is(tok::comma)) 548 ConsumeToken(); 549 FirstClause = false; 550 551 // Recovering from a bad clause is really difficult, so we just give up on 552 // error. 553 if (ParseOpenACCClause(DirKind)) { 554 SkipUntilEndOfDirective(*this); 555 return; 556 } 557 } 558 } 559 560 ExprResult Parser::ParseOpenACCIntExpr() { 561 // FIXME: this is required to be an integer expression (or dependent), so we 562 // should ensure that is the case by passing this to SEMA here. 563 return getActions().CorrectDelayedTyposInExpr(ParseAssignmentExpression()); 564 } 565 566 bool Parser::ParseOpenACCClauseVarList(OpenACCClauseKind Kind) { 567 // FIXME: Future clauses will require 'special word' parsing, check for one, 568 // then parse it based on whether it is a clause that requires a 'special 569 // word'. 570 (void)Kind; 571 572 // If the var parsing fails, skip until the end of the directive as this is 573 // an expression and gets messy if we try to continue otherwise. 574 if (ParseOpenACCVar()) 575 return true; 576 577 while (!getCurToken().isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) { 578 ExpectAndConsume(tok::comma); 579 580 // If the var parsing fails, skip until the end of the directive as this is 581 // an expression and gets messy if we try to continue otherwise. 582 if (ParseOpenACCVar()) 583 return true; 584 } 585 return false; 586 } 587 588 /// OpenACC 3.3 Section 2.4: 589 /// The argument to the device_type clause is a comma-separated list of one or 590 /// more device architecture name identifiers, or an asterisk. 591 /// 592 /// The syntax of the device_type clause is 593 /// device_type( * ) 594 /// device_type( device-type-list ) 595 /// 596 /// The device_type clause may be abbreviated to dtype. 597 bool Parser::ParseOpenACCDeviceTypeList() { 598 599 if (expectIdentifierOrKeyword(*this)) { 600 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end, 601 Parser::StopBeforeMatch); 602 return false; 603 } 604 ConsumeToken(); 605 606 while (!getCurToken().isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) { 607 ExpectAndConsume(tok::comma); 608 609 if (expectIdentifierOrKeyword(*this)) { 610 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end, 611 Parser::StopBeforeMatch); 612 return false; 613 } 614 ConsumeToken(); 615 } 616 return false; 617 } 618 619 // The OpenACC Clause List is a comma or space-delimited list of clauses (see 620 // the comment on ParseOpenACCClauseList). The concept of a 'clause' doesn't 621 // really have its owner grammar and each individual one has its own definition. 622 // However, they all are named with a single-identifier (or auto/default!) 623 // token, followed in some cases by either braces or parens. 624 bool Parser::ParseOpenACCClause(OpenACCDirectiveKind DirKind) { 625 // A number of clause names are actually keywords, so accept a keyword that 626 // can be converted to a name. 627 if (expectIdentifierOrKeyword(*this)) 628 return true; 629 630 OpenACCClauseKind Kind = getOpenACCClauseKind(getCurToken()); 631 632 if (Kind == OpenACCClauseKind::Invalid) 633 return Diag(getCurToken(), diag::err_acc_invalid_clause) 634 << getCurToken().getIdentifierInfo(); 635 636 // Consume the clause name. 637 ConsumeToken(); 638 639 return ParseOpenACCClauseParams(DirKind, Kind); 640 } 641 642 bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind, 643 OpenACCClauseKind Kind) { 644 BalancedDelimiterTracker Parens(*this, tok::l_paren, 645 tok::annot_pragma_openacc_end); 646 647 if (ClauseHasRequiredParens(DirKind, Kind)) { 648 if (Parens.expectAndConsume()) { 649 // We are missing a paren, so assume that the person just forgot the 650 // parameter. Return 'false' so we try to continue on and parse the next 651 // clause. 652 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openacc_end, 653 Parser::StopBeforeMatch); 654 return false; 655 } 656 657 switch (Kind) { 658 case OpenACCClauseKind::Default: { 659 Token DefKindTok = getCurToken(); 660 661 if (expectIdentifierOrKeyword(*this)) 662 break; 663 664 ConsumeToken(); 665 666 if (getOpenACCDefaultClauseKind(DefKindTok) == 667 OpenACCDefaultClauseKind::Invalid) 668 Diag(DefKindTok, diag::err_acc_invalid_default_clause_kind); 669 670 break; 671 } 672 case OpenACCClauseKind::If: { 673 ExprResult CondExpr = ParseOpenACCConditionalExpr(*this); 674 // An invalid expression can be just about anything, so just give up on 675 // this clause list. 676 if (CondExpr.isInvalid()) 677 return true; 678 break; 679 } 680 case OpenACCClauseKind::CopyIn: 681 tryParseAndConsumeSpecialTokenKind( 682 *this, OpenACCSpecialTokenKind::ReadOnly, Kind); 683 if (ParseOpenACCClauseVarList(Kind)) 684 return true; 685 break; 686 case OpenACCClauseKind::Create: 687 case OpenACCClauseKind::CopyOut: 688 tryParseAndConsumeSpecialTokenKind(*this, OpenACCSpecialTokenKind::Zero, 689 Kind); 690 if (ParseOpenACCClauseVarList(Kind)) 691 return true; 692 break; 693 case OpenACCClauseKind::Reduction: 694 // If we're missing a clause-kind (or it is invalid), see if we can parse 695 // the var-list anyway. 696 ParseReductionOperator(*this); 697 if (ParseOpenACCClauseVarList(Kind)) 698 return true; 699 break; 700 case OpenACCClauseKind::Self: 701 // The 'self' clause is a var-list instead of a 'condition' in the case of 702 // the 'update' clause, so we have to handle it here. U se an assert to 703 // make sure we get the right differentiator. 704 assert(DirKind == OpenACCDirectiveKind::Update); 705 LLVM_FALLTHROUGH; 706 case OpenACCClauseKind::Attach: 707 case OpenACCClauseKind::Copy: 708 case OpenACCClauseKind::Delete: 709 case OpenACCClauseKind::Detach: 710 case OpenACCClauseKind::Device: 711 case OpenACCClauseKind::DeviceResident: 712 case OpenACCClauseKind::DevicePtr: 713 case OpenACCClauseKind::FirstPrivate: 714 case OpenACCClauseKind::Host: 715 case OpenACCClauseKind::Link: 716 case OpenACCClauseKind::NoCreate: 717 case OpenACCClauseKind::Present: 718 case OpenACCClauseKind::Private: 719 case OpenACCClauseKind::UseDevice: 720 if (ParseOpenACCClauseVarList(Kind)) 721 return true; 722 break; 723 case OpenACCClauseKind::Collapse: { 724 tryParseAndConsumeSpecialTokenKind(*this, OpenACCSpecialTokenKind::Force, 725 Kind); 726 ExprResult NumLoops = 727 getActions().CorrectDelayedTyposInExpr(ParseConstantExpression()); 728 if (NumLoops.isInvalid()) 729 return true; 730 break; 731 } 732 case OpenACCClauseKind::Bind: { 733 ExprResult BindArg = ParseOpenACCBindClauseArgument(); 734 if (BindArg.isInvalid()) 735 return true; 736 break; 737 } 738 case OpenACCClauseKind::NumGangs: 739 case OpenACCClauseKind::NumWorkers: 740 case OpenACCClauseKind::DeviceNum: 741 case OpenACCClauseKind::DefaultAsync: 742 case OpenACCClauseKind::VectorLength: { 743 ExprResult IntExpr = ParseOpenACCIntExpr(); 744 if (IntExpr.isInvalid()) 745 return true; 746 break; 747 } 748 case OpenACCClauseKind::DType: 749 case OpenACCClauseKind::DeviceType: 750 if (getCurToken().is(tok::star)) { 751 // FIXME: We want to mark that this is an 'everything else' type of 752 // device_type in Sema. 753 ConsumeToken(); 754 } else if (ParseOpenACCDeviceTypeList()) { 755 return true; 756 } 757 break; 758 default: 759 llvm_unreachable("Not a required parens type?"); 760 } 761 762 return Parens.consumeClose(); 763 } else if (ClauseHasOptionalParens(DirKind, Kind)) { 764 if (!Parens.consumeOpen()) { 765 switch (Kind) { 766 case OpenACCClauseKind::Self: { 767 assert(DirKind != OpenACCDirectiveKind::Update); 768 ExprResult CondExpr = ParseOpenACCConditionalExpr(*this); 769 // An invalid expression can be just about anything, so just give up on 770 // this clause list. 771 if (CondExpr.isInvalid()) 772 return true; 773 break; 774 } 775 case OpenACCClauseKind::Vector: 776 case OpenACCClauseKind::Worker: { 777 tryParseAndConsumeSpecialTokenKind(*this, 778 Kind == OpenACCClauseKind::Vector 779 ? OpenACCSpecialTokenKind::Length 780 : OpenACCSpecialTokenKind::Num, 781 Kind); 782 ExprResult IntExpr = ParseOpenACCIntExpr(); 783 if (IntExpr.isInvalid()) 784 return true; 785 break; 786 } 787 default: 788 llvm_unreachable("Not an optional parens type?"); 789 } 790 Parens.consumeClose(); 791 } 792 } 793 return false; 794 } 795 796 /// OpenACC 3.3, section 2.16: 797 /// In this section and throughout the specification, the term wait-argument 798 /// means: 799 /// [ devnum : int-expr : ] [ queues : ] async-argument-list 800 bool Parser::ParseOpenACCWaitArgument() { 801 // [devnum : int-expr : ] 802 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::DevNum, Tok) && 803 NextToken().is(tok::colon)) { 804 // Consume devnum. 805 ConsumeToken(); 806 // Consume colon. 807 ConsumeToken(); 808 809 ExprResult IntExpr = 810 getActions().CorrectDelayedTyposInExpr(ParseAssignmentExpression()); 811 if (IntExpr.isInvalid()) 812 return true; 813 814 if (ExpectAndConsume(tok::colon)) 815 return true; 816 } 817 818 // [ queues : ] 819 if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Queues, Tok) && 820 NextToken().is(tok::colon)) { 821 // Consume queues. 822 ConsumeToken(); 823 // Consume colon. 824 ConsumeToken(); 825 } 826 827 // OpenACC 3.3, section 2.16: 828 // the term 'async-argument' means a nonnegative scalar integer expression, or 829 // one of the special values 'acc_async_noval' or 'acc_async_sync', as defined 830 // in the C header file and the Fortran opacc module. 831 // 832 // We are parsing this simply as list of assignment expressions (to avoid 833 // comma being troublesome), and will ensure it is an integral type. The 834 // 'special' types are defined as macros, so we can't really check those 835 // (other than perhaps as values at one point?), but the standard does say it 836 // is implementation-defined to use any other negative value. 837 // 838 // 839 bool FirstArg = true; 840 while (!getCurToken().isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) { 841 if (!FirstArg) { 842 if (ExpectAndConsume(tok::comma)) 843 return true; 844 } 845 FirstArg = false; 846 847 ExprResult CurArg = 848 getActions().CorrectDelayedTyposInExpr(ParseAssignmentExpression()); 849 850 if (CurArg.isInvalid()) 851 return true; 852 } 853 854 return false; 855 } 856 857 ExprResult Parser::ParseOpenACCIDExpression() { 858 ExprResult Res; 859 if (getLangOpts().CPlusPlus) { 860 Res = ParseCXXIdExpression(/*isAddressOfOperand=*/true); 861 } else { 862 // There isn't anything quite the same as ParseCXXIdExpression for C, so we 863 // need to get the identifier, then call into Sema ourselves. 864 865 if (Tok.isNot(tok::identifier)) { 866 Diag(Tok, diag::err_expected) << tok::identifier; 867 return ExprError(); 868 } 869 870 Token FuncName = getCurToken(); 871 UnqualifiedId Name; 872 CXXScopeSpec ScopeSpec; 873 SourceLocation TemplateKWLoc; 874 Name.setIdentifier(FuncName.getIdentifierInfo(), ConsumeToken()); 875 876 // Ensure this is a valid identifier. We don't accept causing implicit 877 // function declarations per the spec, so always claim to not have trailing 878 // L Paren. 879 Res = Actions.ActOnIdExpression(getCurScope(), ScopeSpec, TemplateKWLoc, 880 Name, /*HasTrailingLParen=*/false, 881 /*isAddressOfOperand=*/false); 882 } 883 884 return getActions().CorrectDelayedTyposInExpr(Res); 885 } 886 887 ExprResult Parser::ParseOpenACCBindClauseArgument() { 888 // OpenACC 3.3 section 2.15: 889 // The bind clause specifies the name to use when calling the procedure on a 890 // device other than the host. If the name is specified as an identifier, it 891 // is called as if that name were specified in the language being compiled. If 892 // the name is specified as a string, the string is used for the procedure 893 // name unmodified. 894 if (getCurToken().is(tok::r_paren)) { 895 Diag(getCurToken(), diag::err_acc_incorrect_bind_arg); 896 return ExprError(); 897 } 898 899 if (tok::isStringLiteral(getCurToken().getKind())) 900 return getActions().CorrectDelayedTyposInExpr(ParseStringLiteralExpression( 901 /*AllowUserDefinedLiteral=*/false, /*Unevaluated=*/true)); 902 903 return ParseOpenACCIDExpression(); 904 } 905 906 /// OpenACC 3.3, section 1.6: 907 /// In this spec, a 'var' (in italics) is one of the following: 908 /// - a variable name (a scalar, array, or compisite variable name) 909 /// - a subarray specification with subscript ranges 910 /// - an array element 911 /// - a member of a composite variable 912 /// - a common block name between slashes (fortran only) 913 bool Parser::ParseOpenACCVar() { 914 OpenACCArraySectionRAII ArraySections(*this); 915 ExprResult Res = 916 getActions().CorrectDelayedTyposInExpr(ParseAssignmentExpression()); 917 return Res.isInvalid(); 918 } 919 920 /// OpenACC 3.3, section 2.10: 921 /// In C and C++, the syntax of the cache directive is: 922 /// 923 /// #pragma acc cache ([readonly:]var-list) new-line 924 void Parser::ParseOpenACCCacheVarList() { 925 // If this is the end of the line, just return 'false' and count on the close 926 // paren diagnostic to catch the issue. 927 if (getCurToken().isAnnotation()) 928 return; 929 930 // The VarList is an optional `readonly:` followed by a list of a variable 931 // specifications. Consume something that looks like a 'tag', and diagnose if 932 // it isn't 'readonly'. 933 if (tryParseAndConsumeSpecialTokenKind(*this, 934 OpenACCSpecialTokenKind::ReadOnly, 935 OpenACCDirectiveKind::Cache)) { 936 // FIXME: Record that this is a 'readonly' so that we can use that during 937 // Sema/AST generation. 938 } 939 940 bool FirstArray = true; 941 while (!getCurToken().isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) { 942 if (!FirstArray) 943 ExpectAndConsume(tok::comma); 944 FirstArray = false; 945 946 // OpenACC 3.3, section 2.10: 947 // A 'var' in a cache directive must be a single array element or a simple 948 // subarray. In C and C++, a simple subarray is an array name followed by 949 // an extended array range specification in brackets, with a start and 950 // length such as: 951 // 952 // arr[lower:length] 953 // 954 if (ParseOpenACCVar()) 955 SkipUntil(tok::r_paren, tok::annot_pragma_openacc_end, tok::comma, 956 StopBeforeMatch); 957 } 958 } 959 960 void Parser::ParseOpenACCDirective() { 961 OpenACCDirectiveKind DirKind = ParseOpenACCDirectiveKind(*this); 962 963 // Once we've parsed the construct/directive name, some have additional 964 // specifiers that need to be taken care of. Atomic has an 'atomic-clause' 965 // that needs to be parsed. 966 if (DirKind == OpenACCDirectiveKind::Atomic) 967 ParseOpenACCAtomicKind(*this); 968 969 // We've successfully parsed the construct/directive name, however a few of 970 // the constructs have optional parens that contain further details. 971 BalancedDelimiterTracker T(*this, tok::l_paren, 972 tok::annot_pragma_openacc_end); 973 974 if (!T.consumeOpen()) { 975 switch (DirKind) { 976 default: 977 Diag(T.getOpenLocation(), diag::err_acc_invalid_open_paren); 978 T.skipToEnd(); 979 break; 980 case OpenACCDirectiveKind::Routine: { 981 // Routine has an optional paren-wrapped name of a function in the local 982 // scope. We parse the name, emitting any diagnostics 983 ExprResult RoutineName = ParseOpenACCIDExpression(); 984 // If the routine name is invalid, just skip until the closing paren to 985 // recover more gracefully. 986 if (RoutineName.isInvalid()) 987 T.skipToEnd(); 988 else 989 T.consumeClose(); 990 break; 991 } 992 case OpenACCDirectiveKind::Cache: 993 ParseOpenACCCacheVarList(); 994 // The ParseOpenACCCacheVarList function manages to recover from failures, 995 // so we can always consume the close. 996 T.consumeClose(); 997 break; 998 case OpenACCDirectiveKind::Wait: 999 // OpenACC has an optional paren-wrapped 'wait-argument'. 1000 if (ParseOpenACCWaitArgument()) 1001 T.skipToEnd(); 1002 else 1003 T.consumeClose(); 1004 break; 1005 } 1006 } else if (DirKind == OpenACCDirectiveKind::Cache) { 1007 // Cache's paren var-list is required, so error here if it isn't provided. 1008 // We know that the consumeOpen above left the first non-paren here, so 1009 // diagnose, then continue as if it was completely omitted. 1010 Diag(Tok, diag::err_expected) << tok::l_paren; 1011 } 1012 1013 // Parses the list of clauses, if present. 1014 ParseOpenACCClauseList(DirKind); 1015 1016 Diag(getCurToken(), diag::warn_pragma_acc_unimplemented); 1017 assert(Tok.is(tok::annot_pragma_openacc_end) && 1018 "Didn't parse all OpenACC Clauses"); 1019 ConsumeAnnotationToken(); 1020 } 1021 1022 // Parse OpenACC directive on a declaration. 1023 Parser::DeclGroupPtrTy Parser::ParseOpenACCDirectiveDecl() { 1024 assert(Tok.is(tok::annot_pragma_openacc) && "expected OpenACC Start Token"); 1025 1026 ParsingOpenACCDirectiveRAII DirScope(*this); 1027 ConsumeAnnotationToken(); 1028 1029 ParseOpenACCDirective(); 1030 1031 return nullptr; 1032 } 1033 1034 // Parse OpenACC Directive on a Statement. 1035 StmtResult Parser::ParseOpenACCDirectiveStmt() { 1036 assert(Tok.is(tok::annot_pragma_openacc) && "expected OpenACC Start Token"); 1037 1038 ParsingOpenACCDirectiveRAII DirScope(*this); 1039 ConsumeAnnotationToken(); 1040 1041 ParseOpenACCDirective(); 1042 1043 return StmtEmpty(); 1044 } 1045