clang: lib/Sema/SemaOpenACCClause.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

18

19using namespace clang;

20

21namespace {

24 switch (ClauseKind) {

25

26

27 case OpenACCClauseKind::Default:

28 switch (DirectiveKind) {

29 case OpenACCDirectiveKind::Parallel:

30 case OpenACCDirectiveKind::Serial:

31 case OpenACCDirectiveKind::Kernels:

32 case OpenACCDirectiveKind::ParallelLoop:

33 case OpenACCDirectiveKind::SerialLoop:

34 case OpenACCDirectiveKind::KernelsLoop:

35 case OpenACCDirectiveKind::Data:

36 return true;

37 default:

38 return false;

39 }

40 case OpenACCClauseKind::If:

41 switch (DirectiveKind) {

42 case OpenACCDirectiveKind::Parallel:

43 case OpenACCDirectiveKind::Serial:

44 case OpenACCDirectiveKind::Kernels:

45 case OpenACCDirectiveKind::Data:

46 case OpenACCDirectiveKind::EnterData:

47 case OpenACCDirectiveKind::ExitData:

48 case OpenACCDirectiveKind::HostData:

49 case OpenACCDirectiveKind::Init:

50 case OpenACCDirectiveKind::Shutdown:

51 case OpenACCDirectiveKind::Set:

52 case OpenACCDirectiveKind::Update:

53 case OpenACCDirectiveKind::Wait:

54 case OpenACCDirectiveKind::ParallelLoop:

55 case OpenACCDirectiveKind::SerialLoop:

56 case OpenACCDirectiveKind::KernelsLoop:

57 return true;

58 default:

59 return false;

60 }

61 case OpenACCClauseKind::Self:

62 switch (DirectiveKind) {

63 case OpenACCDirectiveKind::Parallel:

64 case OpenACCDirectiveKind::Serial:

65 case OpenACCDirectiveKind::Kernels:

66 case OpenACCDirectiveKind::Update:

67 case OpenACCDirectiveKind::ParallelLoop:

68 case OpenACCDirectiveKind::SerialLoop:

69 case OpenACCDirectiveKind::KernelsLoop:

70 return true;

71 default:

72 return false;

73 }

74 case OpenACCClauseKind::NumGangs:

75 case OpenACCClauseKind::NumWorkers:

76 case OpenACCClauseKind::VectorLength:

77 switch (DirectiveKind) {

78 case OpenACCDirectiveKind::Parallel:

79 case OpenACCDirectiveKind::Kernels:

80 case OpenACCDirectiveKind::ParallelLoop:

81 case OpenACCDirectiveKind::KernelsLoop:

82 return true;

83 default:

84 return false;

85 }

86 case OpenACCClauseKind::FirstPrivate:

87 switch (DirectiveKind) {

88 case OpenACCDirectiveKind::Parallel:

89 case OpenACCDirectiveKind::Serial:

90 case OpenACCDirectiveKind::ParallelLoop:

91 case OpenACCDirectiveKind::SerialLoop:

92 return true;

93 default:

94 return false;

95 }

96 case OpenACCClauseKind::Private:

97 switch (DirectiveKind) {

98 case OpenACCDirectiveKind::Parallel:

99 case OpenACCDirectiveKind::Serial:

100 case OpenACCDirectiveKind::Loop:

101 case OpenACCDirectiveKind::ParallelLoop:

102 case OpenACCDirectiveKind::SerialLoop:

103 case OpenACCDirectiveKind::KernelsLoop:

104 return true;

105 default:

106 return false;

107 }

108 case OpenACCClauseKind::NoCreate:

109 switch (DirectiveKind) {

110 case OpenACCDirectiveKind::Parallel:

111 case OpenACCDirectiveKind::Serial:

112 case OpenACCDirectiveKind::Kernels:

113 case OpenACCDirectiveKind::Data:

114 case OpenACCDirectiveKind::ParallelLoop:

115 case OpenACCDirectiveKind::SerialLoop:

116 case OpenACCDirectiveKind::KernelsLoop:

117 return true;

118 default:

119 return false;

120 }

121 case OpenACCClauseKind::Present:

122 switch (DirectiveKind) {

123 case OpenACCDirectiveKind::Parallel:

124 case OpenACCDirectiveKind::Serial:

125 case OpenACCDirectiveKind::Kernels:

126 case OpenACCDirectiveKind::Data:

127 case OpenACCDirectiveKind::Declare:

128 case OpenACCDirectiveKind::ParallelLoop:

129 case OpenACCDirectiveKind::SerialLoop:

130 case OpenACCDirectiveKind::KernelsLoop:

131 return true;

132 default:

133 return false;

134 }

135

136 case OpenACCClauseKind::Copy:

137 case OpenACCClauseKind::PCopy:

138 case OpenACCClauseKind::PresentOrCopy:

139 switch (DirectiveKind) {

140 case OpenACCDirectiveKind::Parallel:

141 case OpenACCDirectiveKind::Serial:

142 case OpenACCDirectiveKind::Kernels:

143 case OpenACCDirectiveKind::Data:

144 case OpenACCDirectiveKind::Declare:

145 case OpenACCDirectiveKind::ParallelLoop:

146 case OpenACCDirectiveKind::SerialLoop:

147 case OpenACCDirectiveKind::KernelsLoop:

148 return true;

149 default:

150 return false;

151 }

152 case OpenACCClauseKind::CopyIn:

153 case OpenACCClauseKind::PCopyIn:

154 case OpenACCClauseKind::PresentOrCopyIn:

155 switch (DirectiveKind) {

156 case OpenACCDirectiveKind::Parallel:

157 case OpenACCDirectiveKind::Serial:

158 case OpenACCDirectiveKind::Kernels:

159 case OpenACCDirectiveKind::Data:

160 case OpenACCDirectiveKind::EnterData:

161 case OpenACCDirectiveKind::Declare:

162 case OpenACCDirectiveKind::ParallelLoop:

163 case OpenACCDirectiveKind::SerialLoop:

164 case OpenACCDirectiveKind::KernelsLoop:

165 return true;

166 default:

167 return false;

168 }

169 case OpenACCClauseKind::CopyOut:

170 case OpenACCClauseKind::PCopyOut:

171 case OpenACCClauseKind::PresentOrCopyOut:

172 switch (DirectiveKind) {

173 case OpenACCDirectiveKind::Parallel:

174 case OpenACCDirectiveKind::Serial:

175 case OpenACCDirectiveKind::Kernels:

176 case OpenACCDirectiveKind::Data:

177 case OpenACCDirectiveKind::ExitData:

178 case OpenACCDirectiveKind::Declare:

179 case OpenACCDirectiveKind::ParallelLoop:

180 case OpenACCDirectiveKind::SerialLoop:

181 case OpenACCDirectiveKind::KernelsLoop:

182 return true;

183 default:

184 return false;

185 }

186 case OpenACCClauseKind::Create:

187 case OpenACCClauseKind::PCreate:

188 case OpenACCClauseKind::PresentOrCreate:

189 switch (DirectiveKind) {

190 case OpenACCDirectiveKind::Parallel:

191 case OpenACCDirectiveKind::Serial:

192 case OpenACCDirectiveKind::Kernels:

193 case OpenACCDirectiveKind::Data:

194 case OpenACCDirectiveKind::EnterData:

195 case OpenACCDirectiveKind::ParallelLoop:

196 case OpenACCDirectiveKind::SerialLoop:

197 case OpenACCDirectiveKind::KernelsLoop:

198 return true;

199 default:

200 return false;

201 }

202

203 case OpenACCClauseKind::Attach:

204 switch (DirectiveKind) {

205 case OpenACCDirectiveKind::Parallel:

206 case OpenACCDirectiveKind::Serial:

207 case OpenACCDirectiveKind::Kernels:

208 case OpenACCDirectiveKind::Data:

209 case OpenACCDirectiveKind::EnterData:

210 case OpenACCDirectiveKind::ParallelLoop:

211 case OpenACCDirectiveKind::SerialLoop:

212 case OpenACCDirectiveKind::KernelsLoop:

213 return true;

214 default:

215 return false;

216 }

217 case OpenACCClauseKind::DevicePtr:

218 switch (DirectiveKind) {

219 case OpenACCDirectiveKind::Parallel:

220 case OpenACCDirectiveKind::Serial:

221 case OpenACCDirectiveKind::Kernels:

222 case OpenACCDirectiveKind::Data:

223 case OpenACCDirectiveKind::Declare:

224 case OpenACCDirectiveKind::ParallelLoop:

225 case OpenACCDirectiveKind::SerialLoop:

226 case OpenACCDirectiveKind::KernelsLoop:

227 return true;

228 default:

229 return false;

230 }

231 case OpenACCClauseKind::Async:

232 switch (DirectiveKind) {

233 case OpenACCDirectiveKind::Parallel:

234 case OpenACCDirectiveKind::Serial:

235 case OpenACCDirectiveKind::Kernels:

236 case OpenACCDirectiveKind::Data:

237 case OpenACCDirectiveKind::EnterData:

238 case OpenACCDirectiveKind::ExitData:

239 case OpenACCDirectiveKind::Set:

240 case OpenACCDirectiveKind::Update:

241 case OpenACCDirectiveKind::Wait:

242 case OpenACCDirectiveKind::ParallelLoop:

243 case OpenACCDirectiveKind::SerialLoop:

244 case OpenACCDirectiveKind::KernelsLoop:

245 return true;

246 default:

247 return false;

248 }

249 case OpenACCClauseKind::Wait:

250 switch (DirectiveKind) {

251 case OpenACCDirectiveKind::Parallel:

252 case OpenACCDirectiveKind::Serial:

253 case OpenACCDirectiveKind::Kernels:

254 case OpenACCDirectiveKind::Data:

255 case OpenACCDirectiveKind::EnterData:

256 case OpenACCDirectiveKind::ExitData:

257 case OpenACCDirectiveKind::Update:

258 case OpenACCDirectiveKind::ParallelLoop:

259 case OpenACCDirectiveKind::SerialLoop:

260 case OpenACCDirectiveKind::KernelsLoop:

261 return true;

262 default:

263 return false;

264 }

265

266 case OpenACCClauseKind::Seq:

267 switch (DirectiveKind) {

268 case OpenACCDirectiveKind::Loop:

269 case OpenACCDirectiveKind::Routine:

270 case OpenACCDirectiveKind::ParallelLoop:

271 case OpenACCDirectiveKind::SerialLoop:

272 case OpenACCDirectiveKind::KernelsLoop:

273 return true;

274 default:

275 return false;

276 }

277

278 case OpenACCClauseKind::Independent:

279 case OpenACCClauseKind::Auto:

280 switch (DirectiveKind) {

281 case OpenACCDirectiveKind::Loop:

282 case OpenACCDirectiveKind::ParallelLoop:

283 case OpenACCDirectiveKind::SerialLoop:

284 case OpenACCDirectiveKind::KernelsLoop:

285 return true;

286 default:

287 return false;

288 }

289

290 case OpenACCClauseKind::Reduction:

291 switch (DirectiveKind) {

292 case OpenACCDirectiveKind::Parallel:

293 case OpenACCDirectiveKind::Serial:

294 case OpenACCDirectiveKind::Loop:

295 case OpenACCDirectiveKind::ParallelLoop:

296 case OpenACCDirectiveKind::SerialLoop:

297 case OpenACCDirectiveKind::KernelsLoop:

298 return true;

299 default:

300 return false;

301 }

302

303 case OpenACCClauseKind::DeviceType:

304 case OpenACCClauseKind::DType:

305 switch (DirectiveKind) {

306 case OpenACCDirectiveKind::Parallel:

307 case OpenACCDirectiveKind::Serial:

308 case OpenACCDirectiveKind::Kernels:

309 case OpenACCDirectiveKind::Data:

310 case OpenACCDirectiveKind::Init:

311 case OpenACCDirectiveKind::Shutdown:

312 case OpenACCDirectiveKind::Set:

313 case OpenACCDirectiveKind::Update:

314 case OpenACCDirectiveKind::Loop:

315 case OpenACCDirectiveKind::Routine:

316 case OpenACCDirectiveKind::ParallelLoop:

317 case OpenACCDirectiveKind::SerialLoop:

318 case OpenACCDirectiveKind::KernelsLoop:

319 return true;

320 default:

321 return false;

322 }

323

324 case OpenACCClauseKind::Collapse: {

325 switch (DirectiveKind) {

326 case OpenACCDirectiveKind::Loop:

327 case OpenACCDirectiveKind::ParallelLoop:

328 case OpenACCDirectiveKind::SerialLoop:

329 case OpenACCDirectiveKind::KernelsLoop:

330 return true;

331 default:

332 return false;

333 }

334 }

335 case OpenACCClauseKind::Tile: {

336 switch (DirectiveKind) {

337 case OpenACCDirectiveKind::Loop:

338 case OpenACCDirectiveKind::ParallelLoop:

339 case OpenACCDirectiveKind::SerialLoop:

340 case OpenACCDirectiveKind::KernelsLoop:

341 return true;

342 default:

343 return false;

344 }

345 }

346

347 case OpenACCClauseKind::Gang: {

348 switch (DirectiveKind) {

349 case OpenACCDirectiveKind::Loop:

350 case OpenACCDirectiveKind::ParallelLoop:

351 case OpenACCDirectiveKind::SerialLoop:

352 case OpenACCDirectiveKind::KernelsLoop:

353 case OpenACCDirectiveKind::Routine:

354 return true;

355 default:

356 return false;

357 }

358 case OpenACCClauseKind::Worker: {

359 switch (DirectiveKind) {

360 case OpenACCDirectiveKind::Loop:

361 case OpenACCDirectiveKind::ParallelLoop:

362 case OpenACCDirectiveKind::SerialLoop:

363 case OpenACCDirectiveKind::KernelsLoop:

364 case OpenACCDirectiveKind::Routine:

365 return true;

366 default:

367 return false;

368 }

369 }

370 case OpenACCClauseKind::Vector: {

371 switch (DirectiveKind) {

372 case OpenACCDirectiveKind::Loop:

373 case OpenACCDirectiveKind::ParallelLoop:

374 case OpenACCDirectiveKind::SerialLoop:

375 case OpenACCDirectiveKind::KernelsLoop:

376 case OpenACCDirectiveKind::Routine:

377 return true;

378 default:

379 return false;

380 }

381 }

382 case OpenACCClauseKind::Finalize: {

383 switch (DirectiveKind) {

384 case OpenACCDirectiveKind::ExitData:

385 return true;

386 default:

387 return false;

388 }

389 }

390 case OpenACCClauseKind::IfPresent: {

391 switch (DirectiveKind) {

392 case OpenACCDirectiveKind::HostData:

393 case OpenACCDirectiveKind::Update:

394 return true;

395 default:

396 return false;

397 }

398 }

399 case OpenACCClauseKind::Delete: {

400 switch (DirectiveKind) {

401 case OpenACCDirectiveKind::ExitData:

402 return true;

403 default:

404 return false;

405 }

406 }

407

408 case OpenACCClauseKind::Detach: {

409 switch (DirectiveKind) {

410 case OpenACCDirectiveKind::ExitData:

411 return true;

412 default:

413 return false;

414 }

415 }

416

417 case OpenACCClauseKind::DeviceNum: {

418 switch (DirectiveKind) {

419 case OpenACCDirectiveKind::Init:

420 case OpenACCDirectiveKind::Shutdown:

421 case OpenACCDirectiveKind::Set:

422 return true;

423 default:

424 return false;

425 }

426 }

427

428 case OpenACCClauseKind::UseDevice: {

429 switch (DirectiveKind) {

430 case OpenACCDirectiveKind::HostData:

431 return true;

432 default:

433 return false;

434 }

435 }

436 case OpenACCClauseKind::DefaultAsync: {

437 switch (DirectiveKind) {

438 case OpenACCDirectiveKind::Set:

439 return true;

440 default:

441 return false;

442 }

443 }

444 case OpenACCClauseKind::Device: {

445 switch (DirectiveKind) {

446 case OpenACCDirectiveKind::Update:

447 return true;

448 default:

449 return false;

450 }

451 }

452 case OpenACCClauseKind::Host: {

453 switch (DirectiveKind) {

454 case OpenACCDirectiveKind::Update:

455 return true;

456 default:

457 return false;

458 }

459 }

460 }

461

462 default:

463

464 return true;

465 }

466 llvm_unreachable("Invalid clause kind");

467}

468

469bool checkAlreadyHasClauseOfKind(

472 const auto *Itr = llvm::find_if(ExistingClauses, [&](const OpenACCClause *C) {

474 });

475 if (Itr != ExistingClauses.end()) {

476 S.Diag(Clause.getBeginLoc(), diag::err_acc_duplicate_clause_disallowed)

478 S.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);

479 return true;

480 }

481 return false;

482}

483bool checkValidAfterDeviceType(

486

487

488 if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Routine)

489 return false;

490

491

492

493

494

495

496

497

498 if (NewClause.getClauseKind() == OpenACCClauseKind::DType ||

499 NewClause.getClauseKind() == OpenACCClauseKind::DeviceType)

500 return false;

501

502

503

504

507 case OpenACCClauseKind::Async:

508 case OpenACCClauseKind::Wait:

509 case OpenACCClauseKind::NumGangs:

510 case OpenACCClauseKind::NumWorkers:

511 case OpenACCClauseKind::VectorLength:

512 return false;

513 default:

514 break;

515 }

516 } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Loop) {

517

518

519

521 case OpenACCClauseKind::Collapse:

522 case OpenACCClauseKind::Gang:

523 case OpenACCClauseKind::Worker:

524 case OpenACCClauseKind::Vector:

525 case OpenACCClauseKind::Seq:

526 case OpenACCClauseKind::Independent:

527 case OpenACCClauseKind::Auto:

528 case OpenACCClauseKind::Tile:

529 return false;

530 default:

531 break;

532 }

534

536 case OpenACCClauseKind::Async:

537 case OpenACCClauseKind::Wait:

538 case OpenACCClauseKind::NumGangs:

539 case OpenACCClauseKind::NumWorkers:

540 case OpenACCClauseKind::VectorLength:

541 case OpenACCClauseKind::Collapse:

542 case OpenACCClauseKind::Gang:

543 case OpenACCClauseKind::Worker:

544 case OpenACCClauseKind::Vector:

545 case OpenACCClauseKind::Seq:

546 case OpenACCClauseKind::Independent:

547 case OpenACCClauseKind::Auto:

548 case OpenACCClauseKind::Tile:

549 return false;

550 default:

551 break;

552 }

553 } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Data) {

554

555

557 case OpenACCClauseKind::Async:

558 case OpenACCClauseKind::Wait:

559 return false;

560 default:

561 break;

562 }

563 } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Set ||

564 NewClause.getDirectiveKind() == OpenACCDirectiveKind::Init ||

565 NewClause.getDirectiveKind() == OpenACCDirectiveKind::Shutdown) {

566

567 return false;

568 } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Update) {

569

570

572 case OpenACCClauseKind::Async:

573 case OpenACCClauseKind::Wait:

574 return false;

575 default:

576 break;

577 }

578 }

579 S.Diag(NewClause.getBeginLoc(), diag::err_acc_clause_after_device_type)

581 << NewClause.getDirectiveKind();

582 S.Diag(DeviceTypeClause.getBeginLoc(), diag::note_acc_previous_clause_here);

583 return true;

584}

585

586

587

588

589

591 return DK != OpenACCDirectiveKind::Declare &&

592 DK != OpenACCDirectiveKind::Atomic &&

593 DK != OpenACCDirectiveKind::Routine;

594}

595

596class SemaOpenACCClauseVisitor {

600 bool NotImplemented = false;

601

603 NotImplemented = true;

604 return nullptr;

605 }

606

607

608

609

611 const auto *Itr =

612 llvm::find_if(ExistingClauses, llvm::IsaPred);

613

614 if (Itr != ExistingClauses.end()) {

615 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine)

616 << Clause.getClauseKind() << (*Itr)->getClauseKind()

618 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);

619

620 return true;

621 }

622 return false;

623 }

624

625public:

628 : SemaRef(S), Ctx(S.getASTContext()), ExistingClauses(ExistingClauses) {}

629

630

631

632 bool diagNotImplemented() { return NotImplemented; }

633

636#define VISIT_CLAUSE(CLAUSE_NAME) \

637 case OpenACCClauseKind::CLAUSE_NAME: \

638 return Visit##CLAUSE_NAME##Clause(Clause);

639#define CLAUSE_ALIAS(ALIAS, CLAUSE_NAME, DEPRECATED) \

640 case OpenACCClauseKind::ALIAS: \

641 if (DEPRECATED) \

642 SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name) \

643 << Clause.getClauseKind() << OpenACCClauseKind::CLAUSE_NAME; \

644 return Visit##CLAUSE_NAME##Clause(Clause);

645#include "clang/Basic/OpenACCClauses.def"

646 default:

647 return isNotImplemented();

648 }

649 llvm_unreachable("Invalid clause kind");

650 }

651

652#define VISIT_CLAUSE(CLAUSE_NAME) \

653 OpenACCClause *Visit##CLAUSE_NAME##Clause( \

654 SemaOpenACC::OpenACCParsedClause &Clause);

655#include "clang/Basic/OpenACCClauses.def"

656};

657

658OpenACCClause *SemaOpenACCClauseVisitor::VisitDefaultClause(

660

662 return nullptr;

663

664

665

666

667

668 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))

669 return nullptr;

670

674}

675

676OpenACCClause *SemaOpenACCClauseVisitor::VisitTileClause(

678

679

680

681

682

683

684 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))

685 return nullptr;

686

688

689

692

694 return nullptr;

695

696 NewSizeExprs.push_back(Res.get());

697 }

698

702}

703

704OpenACCClause *SemaOpenACCClauseVisitor::VisitIfClause(

706

707

708

709

710

711

712 if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Init &&

713 Clause.getDirectiveKind() != OpenACCDirectiveKind::Shutdown &&

714 checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))

715 return nullptr;

716

717

718

719

720

721

722 if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Update) {

723 const auto *Itr =

724 llvm::find_if(ExistingClauses, llvm::IsaPred);

725 if (Itr != ExistingClauses.end()) {

726 SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict);

727 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);

728 }

729 }

730

734}

735

736OpenACCClause *SemaOpenACCClauseVisitor::VisitSelfClause(

738

739

740

741 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))

742 return nullptr;

743

744

745

746 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Update)

750

751 const auto *Itr =

752 llvm::find_if(ExistingClauses, llvm::IsaPred);

753 if (Itr != ExistingClauses.end()) {

754 SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict);

755 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);

756 }

760}

761

762OpenACCClause *SemaOpenACCClauseVisitor::VisitNumGangsClause(

764

765

766

767 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))

768 return nullptr;

769

770

771

772

774 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args)

775 << 0;

776

777 unsigned MaxArgs =

778 (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel ||

779 Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop)

780 ? 3

781 : 1;

782

783

784 if (Clause.getIntExprs().size() > MaxArgs)

785 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args)

788

789

790

791

794 auto *GangClauseItr =

795 llvm::find_if(ExistingClauses, llvm::IsaPred);

796 auto *ReductionClauseItr =

797 llvm::find_if(ExistingClauses, llvm::IsaPred);

798

799 if (GangClauseItr != ExistingClauses.end() &&

800 ReductionClauseItr != ExistingClauses.end()) {

802 diag::err_acc_gang_reduction_numgangs_conflict)

803 << OpenACCClauseKind::Reduction << OpenACCClauseKind::Gang

804 << Clause.getDirectiveKind() << 1;

805 SemaRef.Diag((*ReductionClauseItr)->getBeginLoc(),

806 diag::note_acc_previous_clause_here);

807 SemaRef.Diag((*GangClauseItr)->getBeginLoc(),

808 diag::note_acc_previous_clause_here);

809 return nullptr;

810 }

811 }

812

813

814

815

816 if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel ||

817 Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop) &&

820 llvm::find_if(ExistingClauses, llvm::IsaPred);

821

822 if (Parallel != ExistingClauses.end()) {

824 diag::err_acc_reduction_num_gangs_conflict)

825 << 1 << Clause.getClauseKind()

826 << Clause.getDirectiveKind() << OpenACCClauseKind::Reduction;

827 SemaRef.Diag((*Parallel)->getBeginLoc(),

828 diag::note_acc_previous_clause_here);

829 return nullptr;

830 }

831 }

832

833

834

835

836 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) {

837 auto GangClauses = llvm::make_filter_range(

838 ExistingClauses, llvm::IsaPred);

839

840 for (auto *GC : GangClauses) {

841 if (cast(GC)->hasExprOfKind(OpenACCGangKind::Num)) {

843 diag::err_acc_num_arg_conflict_reverse)

844 << OpenACCClauseKind::NumGangs << OpenACCClauseKind::Gang

845 << 1;

846 SemaRef.Diag(GC->getBeginLoc(), diag::note_acc_previous_clause_here);

847 return nullptr;

848 }

849 }

850 }

851

855}

856

857OpenACCClause *SemaOpenACCClauseVisitor::VisitNumWorkersClause(

859

860

861

862 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))

863 return nullptr;

864

865

866

867

868 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) {

869 auto WorkerClauses = llvm::make_filter_range(

870 ExistingClauses, llvm::IsaPred);

871

872 for (auto *WC : WorkerClauses) {

873 if (cast(WC)->hasIntExpr()) {

875 diag::err_acc_num_arg_conflict_reverse)

876 << OpenACCClauseKind::NumWorkers << OpenACCClauseKind::Worker

877 << 0;

878 SemaRef.Diag(WC->getBeginLoc(), diag::note_acc_previous_clause_here);

879 return nullptr;

880 }

881 }

882 }

883

884 assert(Clause.getIntExprs().size() == 1 &&

885 "Invalid number of expressions for NumWorkers");

889}

890

891OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorLengthClause(

893

894

895

896 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))

897 return nullptr;

898

899

900

901

902 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) {

903 auto VectorClauses = llvm::make_filter_range(

904 ExistingClauses, llvm::IsaPred);

905

906 for (auto *VC : VectorClauses) {

907 if (cast(VC)->hasIntExpr()) {

909 diag::err_acc_num_arg_conflict_reverse)

910 << OpenACCClauseKind::VectorLength << OpenACCClauseKind::Vector

911 << 0;

912 SemaRef.Diag(VC->getBeginLoc(), diag::note_acc_previous_clause_here);

913 return nullptr;

914 }

915 }

916 }

917

918 assert(Clause.getIntExprs().size() == 1 &&

919 "Invalid number of expressions for NumWorkers");

923}

924

925OpenACCClause *SemaOpenACCClauseVisitor::VisitAsyncClause(

927

928

929

930 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))

931 return nullptr;

932

934 "Invalid number of expressions for Async");

939}

940

941OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceNumClause(

943

944

946 return isNotImplemented();

947

948

949

950 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Set &&

951 checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))

952 return nullptr;

953

955 "Invalid number of expressions for device_num");

959}

960

961OpenACCClause *SemaOpenACCClauseVisitor::VisitDefaultAsyncClause(

963

964

965 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))

966 return nullptr;

967

969 "Invalid number of expressions for default_async");

973}

974

975OpenACCClause *SemaOpenACCClauseVisitor::VisitPrivateClause(

977

978

979

980

984}

985

986OpenACCClause *SemaOpenACCClauseVisitor::VisitFirstPrivateClause(

988

989

990

991

995}

996

997OpenACCClause *SemaOpenACCClauseVisitor::VisitNoCreateClause(

999

1000

1001

1002

1006}

1007

1008OpenACCClause *SemaOpenACCClauseVisitor::VisitPresentClause(

1010

1011

1012

1013

1015 return isNotImplemented();

1016

1017

1018

1019

1023}

1024

1025OpenACCClause *SemaOpenACCClauseVisitor::VisitHostClause(

1027

1028

1029

1030

1034}

1035

1036OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceClause(

1038

1039

1040

1041

1045}

1046

1047OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyClause(

1049

1050

1051

1052

1054 return isNotImplemented();

1055

1056

1057

1058

1062}

1063

1064OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyInClause(

1066

1067

1068

1069

1071 return isNotImplemented();

1072

1073

1074

1075

1079}

1080

1081OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyOutClause(

1083

1084

1085

1086

1088 return isNotImplemented();

1089

1090

1091

1092

1096}

1097

1098OpenACCClause *SemaOpenACCClauseVisitor::VisitCreateClause(

1100

1101

1102

1103

1107}

1108

1109OpenACCClause *SemaOpenACCClauseVisitor::VisitAttachClause(

1111

1112

1114 llvm::erase_if(VarList, [&](Expr *E) {

1116 });

1118 false, false);

1122}

1123

1124OpenACCClause *SemaOpenACCClauseVisitor::VisitDetachClause(

1126

1127

1129 llvm::erase_if(VarList, [&](Expr *E) {

1131 });

1133 false, false);

1137}

1138

1139OpenACCClause *SemaOpenACCClauseVisitor::VisitDeleteClause(

1141

1142

1143

1147}

1148

1149OpenACCClause *SemaOpenACCClauseVisitor::VisitUseDeviceClause(

1151

1152

1156}

1157

1158OpenACCClause *SemaOpenACCClauseVisitor::VisitDevicePtrClause(

1160

1161

1162

1163

1165 return isNotImplemented();

1166

1167

1168

1170 llvm::erase_if(VarList, [&](Expr *E) {

1172 });

1174 false, false);

1175

1179}

1180

1181OpenACCClause *SemaOpenACCClauseVisitor::VisitWaitClause(

1186}

1187

1188OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceTypeClause(

1190

1191 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Routine)

1192 return isNotImplemented();

1193

1194

1195

1196 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Set &&

1197 checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))

1198 return nullptr;

1199

1200

1201

1202

1203

1207}

1208

1209OpenACCClause *SemaOpenACCClauseVisitor::VisitAutoClause(

1211

1212

1213 const auto *Itr =

1214 llvm::find_if(ExistingClauses,

1215 llvm::IsaPred<OpenACCIndependentClause, OpenACCSeqClause>);

1216 if (Itr != ExistingClauses.end()) {

1217 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict)

1219 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);

1220 return nullptr;

1221 }

1222

1225}

1226

1227OpenACCClause *SemaOpenACCClauseVisitor::VisitIndependentClause(

1229

1230

1231 const auto *Itr = llvm::find_if(

1232 ExistingClauses, llvm::IsaPred<OpenACCAutoClause, OpenACCSeqClause>);

1233 if (Itr != ExistingClauses.end()) {

1234 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict)

1236 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);

1237 return nullptr;

1238 }

1239

1242}

1243

1245 if (isa(E))

1246 return E;

1247 return S.ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Gang,

1249}

1250

1252 return DK == OpenACCDirectiveKind::Loop &&

1253 AssocKind == OpenACCDirectiveKind::Invalid;

1254}

1255

1257 return DK == OpenACCDirectiveKind::Loop &&

1258 AssocKind != OpenACCDirectiveKind::Invalid;

1259}

1260

1265 << GK << CK << IsOrphanLoop(DK, AssocKind) << DK

1266 << HasAssocKind(DK, AssocKind) << AssocKind;

1268}

1273 << TagKind << CK << IsOrphanLoop(DK, AssocKind) << DK

1274 << HasAssocKind(DK, AssocKind) << AssocKind;

1276}

1277

1281 switch (GK) {

1282 case OpenACCGangKind::Static:

1283 return CheckGangStaticExpr(S, E);

1284 case OpenACCGangKind::Num:

1285

1286

1287

1288 return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind);

1289 case OpenACCGangKind::Dim: {

1290

1291

1292

1293

1294 if (E)

1297 S.ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Gang,

1299

1301 return Res;

1302

1304 return Res;

1305

1306 std::optionalllvm::APSInt ICE =

1308

1309 if (!ICE || *ICE <= 0 || ICE > 3) {

1311 << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue();

1313 }

1314

1317 }

1318 }

1319 llvm_unreachable("Unknown gang kind in gang parallel check");

1320}

1321

1327 switch (GK) {

1328

1329

1330

1331 case OpenACCGangKind::Dim:

1332 return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind);

1333 case OpenACCGangKind::Num: {

1334

1335

1336

1337

1338

1339

1340

1341

1342

1344 ? ExistingClauses

1345 : S.getActiveComputeConstructInfo().Clauses;

1346

1347 const auto *Itr =

1348 llvm::find_if(Collection, llvm::IsaPred);

1349

1350 if (Itr != Collection.end()) {

1352 << "num" << OpenACCClauseKind::Gang << DK

1353 << HasAssocKind(DK, AssocKind) << AssocKind

1354 << OpenACCClauseKind::NumGangs;

1355

1356 S.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);

1358 }

1360 }

1361 case OpenACCGangKind::Static:

1362 return CheckGangStaticExpr(S, E);

1363 }

1364 llvm_unreachable("Unknown gang kind in gang kernels check");

1365}

1366

1370 switch (GK) {

1371

1372

1373 case OpenACCGangKind::Dim:

1374 case OpenACCGangKind::Num:

1375 return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind);

1376 case OpenACCGangKind::Static:

1377 return CheckGangStaticExpr(S, E);

1378 }

1379 llvm_unreachable("Unknown gang kind in gang serial check");

1380}

1381

1382OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorClause(

1384 if (DiagIfSeqClause(Clause))

1385 return nullptr;

1386

1387

1388

1389

1391 return isNotImplemented();

1392

1393 Expr *IntExpr =

1395 if (IntExpr) {

1398 case OpenACCDirectiveKind::Invalid:

1399 case OpenACCDirectiveKind::Parallel:

1400

1401 break;

1402 case OpenACCDirectiveKind::Serial:

1403

1404

1405 DiagIntArgInvalid(SemaRef, IntExpr, "length", OpenACCClauseKind::Vector,

1408 IntExpr = nullptr;

1409 break;

1410 case OpenACCDirectiveKind::Kernels: {

1411 const auto *Itr =

1413 llvm::IsaPred);

1415 SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)

1416 << "length" << OpenACCClauseKind::Vector

1421 << OpenACCClauseKind::VectorLength;

1422 SemaRef.Diag((*Itr)->getBeginLoc(),

1423 diag::note_acc_previous_clause_here);

1424

1425 IntExpr = nullptr;

1426 }

1427 break;

1428 }

1429 default:

1430 llvm_unreachable("Non compute construct in active compute construct");

1431 }

1432 } else {

1433 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::SerialLoop) {

1434 DiagIntArgInvalid(SemaRef, IntExpr, "length", OpenACCClauseKind::Vector,

1437 IntExpr = nullptr;

1439 OpenACCDirectiveKind::KernelsLoop) {

1440 const auto *Itr = llvm::find_if(

1441 ExistingClauses, llvm::IsaPred);

1442 if (Itr != ExistingClauses.end()) {

1443 SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)

1444 << "length" << OpenACCClauseKind::Vector

1449 << OpenACCClauseKind::VectorLength;

1450 SemaRef.Diag((*Itr)->getBeginLoc(),

1451 diag::note_acc_previous_clause_here);

1452

1453 IntExpr = nullptr;

1454 }

1455 }

1456 }

1457 }

1458

1460

1461

1462

1464

1465

1466 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)

1467 << OpenACCClauseKind::Vector << OpenACCClauseKind::Vector

1468 << 0;

1470 diag::note_acc_previous_clause_here);

1471 return nullptr;

1472 }

1473 }

1474

1478}

1479

1480OpenACCClause *SemaOpenACCClauseVisitor::VisitWorkerClause(

1482 if (DiagIfSeqClause(Clause))

1483 return nullptr;

1484

1485

1486

1487

1489 return isNotImplemented();

1490

1491 Expr *IntExpr =

1493

1494 if (IntExpr) {

1497 case OpenACCDirectiveKind::Invalid:

1498 case OpenACCDirectiveKind::ParallelLoop:

1499 case OpenACCDirectiveKind::SerialLoop:

1500 case OpenACCDirectiveKind::Parallel:

1501 case OpenACCDirectiveKind::Serial:

1502 DiagIntArgInvalid(SemaRef, IntExpr, OpenACCGangKind::Num,

1505 IntExpr = nullptr;

1506 break;

1507 case OpenACCDirectiveKind::KernelsLoop:

1508 case OpenACCDirectiveKind::Kernels: {

1509 const auto *Itr =

1511 llvm::IsaPred);

1513 SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)

1514 << "num" << OpenACCClauseKind::Worker << Clause.getDirectiveKind()

1518 << OpenACCClauseKind::NumWorkers;

1519 SemaRef.Diag((*Itr)->getBeginLoc(),

1520 diag::note_acc_previous_clause_here);

1521

1522 IntExpr = nullptr;

1523 }

1524 break;

1525 }

1526 default:

1527 llvm_unreachable("Non compute construct in active compute construct");

1528 }

1529 } else {

1530 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop ||

1531 Clause.getDirectiveKind() == OpenACCDirectiveKind::SerialLoop) {

1532 DiagIntArgInvalid(SemaRef, IntExpr, OpenACCGangKind::Num,

1535 IntExpr = nullptr;

1536 } else {

1537 assert(Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop &&

1538 "Unknown combined directive kind?");

1539 const auto *Itr = llvm::find_if(ExistingClauses,

1540 llvm::IsaPred);

1541 if (Itr != ExistingClauses.end()) {

1542 SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict)

1543 << "num" << OpenACCClauseKind::Worker << Clause.getDirectiveKind()

1547 << OpenACCClauseKind::NumWorkers;

1548 SemaRef.Diag((*Itr)->getBeginLoc(),

1549 diag::note_acc_previous_clause_here);

1550

1551 IntExpr = nullptr;

1552 }

1553 }

1554 }

1555 }

1556

1558

1559

1560

1562

1563

1564 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)

1565 << OpenACCClauseKind::Worker << OpenACCClauseKind::Worker

1566 << 0;

1568 diag::note_acc_previous_clause_here);

1569 return nullptr;

1570 }

1571

1572

1573

1574

1576

1577

1578 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)

1579 << OpenACCClauseKind::Worker << OpenACCClauseKind::Vector

1580 << 0;

1582 diag::note_acc_previous_clause_here);

1583 return nullptr;

1584 }

1585 }

1586

1590}

1591

1592OpenACCClause *SemaOpenACCClauseVisitor::VisitGangClause(

1594 if (DiagIfSeqClause(Clause))

1595 return nullptr;

1596

1597

1598

1599

1601 return isNotImplemented();

1602

1603

1604

1605

1606 if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop &&

1608 OpenACCDirectiveKind::Invalid) ||

1610

1611 auto ActiveComputeConstructContainer =

1613 ? ExistingClauses

1615 auto *NumGangsClauseItr = llvm::find_if(

1616 ActiveComputeConstructContainer, llvm::IsaPred);

1617

1618 if (NumGangsClauseItr != ActiveComputeConstructContainer.end() &&

1619 cast(*NumGangsClauseItr)->getIntExprs().size() >

1620 1) {

1621 auto *ReductionClauseItr =

1622 llvm::find_if(ExistingClauses, llvm::IsaPred);

1623

1624 if (ReductionClauseItr != ExistingClauses.end()) {

1626 diag::err_acc_gang_reduction_numgangs_conflict)

1627 << OpenACCClauseKind::Gang << OpenACCClauseKind::Reduction

1630 SemaRef.Diag((*ReductionClauseItr)->getBeginLoc(),

1631 diag::note_acc_previous_clause_here);

1632 SemaRef.Diag((*NumGangsClauseItr)->getBeginLoc(),

1633 diag::note_acc_previous_clause_here);

1634 return nullptr;

1635 }

1636 }

1637 }

1638

1641

1642

1643

1645

1646 for (unsigned I = 0; I < Clause.getIntExprs().size(); ++I) {

1651

1653 continue;

1654

1655

1656

1657 if (ExistingElemLoc[static_cast<unsigned>(GK)].isValid()) {

1658 SemaRef.Diag(ER.get()->getBeginLoc(), diag::err_acc_gang_multiple_elt)

1659 << static_cast<unsigned>(GK);

1660 SemaRef.Diag(ExistingElemLoc[static_cast<unsigned>(GK)],

1661 diag::note_acc_previous_expr_here);

1662 continue;

1663 }

1664

1665 ExistingElemLoc[static_cast<unsigned>(GK)] = ER.get()->getBeginLoc();

1666 GangKinds.push_back(GK);

1667 IntExprs.push_back(ER.get());

1668 }

1669

1671

1672

1673

1674

1676

1677

1678 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)

1679 << OpenACCClauseKind::Gang << OpenACCClauseKind::Gang

1680 << 1

1683 diag::note_acc_previous_clause_here);

1684 return nullptr;

1685 }

1686

1687

1688

1689

1691

1692

1693 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)

1694 << OpenACCClauseKind::Gang << OpenACCClauseKind::Worker

1695 << 0;

1697 diag::note_acc_previous_clause_here);

1698 return nullptr;

1699 }

1700

1701

1702

1703

1705

1706

1707 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region)

1708 << OpenACCClauseKind::Gang << OpenACCClauseKind::Vector

1709 << 0;

1711 diag::note_acc_previous_clause_here);

1712 return nullptr;

1713 }

1714 }

1715

1718 GangKinds, IntExprs, Clause.getEndLoc());

1719}

1720

1721OpenACCClause *SemaOpenACCClauseVisitor::VisitFinalizeClause(

1723

1724

1727}

1728

1729OpenACCClause *SemaOpenACCClauseVisitor::VisitIfPresentClause(

1731

1732

1735}

1736

1737OpenACCClause *SemaOpenACCClauseVisitor::VisitSeqClause(

1739

1740

1741

1743 return isNotImplemented();

1744

1745

1746

1747 const auto *Itr =

1748 llvm::find_if(ExistingClauses,

1749 llvm::IsaPred<OpenACCAutoClause, OpenACCIndependentClause>);

1750 if (Itr != ExistingClauses.end()) {

1751 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict)

1753 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);

1754 return nullptr;

1755 }

1756

1757

1758

1759

1760 Itr = llvm::find_if(ExistingClauses,

1763

1764 if (Itr != ExistingClauses.end()) {

1765 SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine)

1766 << Clause.getClauseKind() << (*Itr)->getClauseKind()

1768 SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);

1769 return nullptr;

1770 }

1771

1774}

1775

1776OpenACCClause *SemaOpenACCClauseVisitor::VisitReductionClause(

1778

1779

1780

1781 if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop &&

1783 OpenACCDirectiveKind::Invalid) ||

1785

1786 auto ActiveComputeConstructContainer =

1788 ? ExistingClauses

1790 auto *NumGangsClauseItr = llvm::find_if(

1791 ActiveComputeConstructContainer, llvm::IsaPred);

1792

1793 if (NumGangsClauseItr != ActiveComputeConstructContainer.end() &&

1794 cast(*NumGangsClauseItr)->getIntExprs().size() >

1795 1) {

1796 auto *GangClauseItr =

1797 llvm::find_if(ExistingClauses, llvm::IsaPred);

1798

1799 if (GangClauseItr != ExistingClauses.end()) {

1801 diag::err_acc_gang_reduction_numgangs_conflict)

1802 << OpenACCClauseKind::Reduction << OpenACCClauseKind::Gang

1805 SemaRef.Diag((*GangClauseItr)->getBeginLoc(),

1806 diag::note_acc_previous_clause_here);

1807 SemaRef.Diag((*NumGangsClauseItr)->getBeginLoc(),

1808 diag::note_acc_previous_clause_here);

1809 return nullptr;

1810 }

1811 }

1812 }

1813

1814

1815

1816

1817

1818

1819

1820

1821

1822

1823

1824

1825

1826

1827

1828

1829

1830

1831

1832

1833

1834 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel ||

1835 Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop) {

1836 auto NumGangsClauses = llvm::make_filter_range(

1837 ExistingClauses, llvm::IsaPred);

1838

1839 for (auto *NGC : NumGangsClauses) {

1840 unsigned NumExprs =

1841 cast(NGC)->getIntExprs().size();

1842

1843 if (NumExprs > 1) {

1845 diag::err_acc_reduction_num_gangs_conflict)

1846 << 0 << Clause.getClauseKind()

1847 << Clause.getDirectiveKind() << OpenACCClauseKind::NumGangs;

1848 SemaRef.Diag(NGC->getBeginLoc(), diag::note_acc_previous_clause_here);

1849 return nullptr;

1850 }

1851 }

1852 }

1853

1855

1859

1861 ValidVars.push_back(Res.get());

1862 }

1863

1868}

1869

1870OpenACCClause *SemaOpenACCClauseVisitor::VisitCollapseClause(

1872

1873

1874

1875

1876

1877 if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))

1878 return nullptr;

1879

1881

1883 return nullptr;

1884

1888}

1889

1890

1891

1892bool areVarsEqual(Expr *VarExpr1, Expr *VarExpr2) {

1895 return false;

1896

1899

1900

1901

1902

1903

1904 if (isa(VarExpr1)) {

1905 auto *Expr2AS = dyn_cast(VarExpr2);

1906 if (!Expr2AS)

1907 return false;

1908

1909 auto *Expr1AS = cast(VarExpr1);

1910

1911 if (!areVarsEqual(Expr1AS->getBase(), Expr2AS->getBase()))

1912 return false;

1913

1914

1915 return true;

1916 }

1917

1918

1919 if (isa(VarExpr1)) {

1920 auto *Expr2AS = dyn_cast(VarExpr2);

1921 if (!Expr2AS)

1922 return false;

1923

1924 auto *Expr1AS = cast(VarExpr1);

1925

1926 if (!areVarsEqual(Expr1AS->getBase(), Expr2AS->getBase()))

1927 return false;

1928

1929

1930

1931

1932 return true;

1933 }

1934

1935

1936 if (isa(VarExpr1)) {

1937 auto *Expr2DRE = dyn_cast(VarExpr2);

1938 if (!Expr2DRE)

1939 return false;

1940

1941 auto *Expr1DRE = cast(VarExpr1);

1942

1943 return Expr1DRE->getDecl()->getMostRecentDecl() ==

1944 Expr2DRE->getDecl()->getMostRecentDecl();

1945 }

1946

1947 llvm_unreachable("Unknown variable type encountered");

1948}

1949}

1950

1955 return nullptr;

1956

1957

1960 Diag(Clause.getBeginLoc(), diag::err_acc_clause_appertainment)

1962 return nullptr;

1963 }

1964

1965 if (const auto *DevTypeClause =

1966 llvm::find_if(ExistingClauses,

1968 return isa(C);

1969 });

1970 DevTypeClause != ExistingClauses.end()) {

1971 if (checkValidAfterDeviceType(

1972 *this, *cast(*DevTypeClause), Clause))

1973 return nullptr;

1974 }

1975

1976 SemaOpenACCClauseVisitor Visitor{*this, ExistingClauses};

1979 "Created wrong clause?");

1980

1981 if (Visitor.diagNotImplemented())

1982 Diag(Clause.getBeginLoc(), diag::warn_acc_clause_unimplemented)

1984

1986

1987}

1988

1989

1990

1991

1992

1993

1994

1995

1998 Expr *VarExpr) {

2000

2001 auto TypeIsValid = [](QualType Ty) {

2002 return Ty->isDependentType() || Ty->isScalarType();

2003 };

2004

2005 if (isa(VarExpr)) {

2006 Expr *ASExpr = VarExpr;

2009

2010 if (!TypeIsValid(EltTy)) {

2011 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_type)

2012 << EltTy << 1;

2014 }

2016 if (!RD->isStruct() && !RD->isClass()) {

2017 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type)

2018 << 0 << VarExpr->getType();

2020 }

2021

2022 if (!RD->isCompleteDefinition()) {

2023 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type)

2024 << 1 << VarExpr->getType();

2026 }

2027 if (const auto *CXXRD = dyn_cast(RD);

2028 CXXRD && !CXXRD->isAggregate()) {

2029 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type)

2030 << 2 << VarExpr->getType();

2032 }

2033

2034 for (FieldDecl *FD : RD->fields()) {

2035 if (!TypeIsValid(FD->getType())) {

2037 diag::err_acc_reduction_composite_member_type);

2038 Diag(FD->getLocation(), diag::note_acc_reduction_composite_member_loc);

2040 }

2041 }

2042 } else if (!TypeIsValid(VarExpr->getType())) {

2043 Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_type)

2044 << VarExpr->getType() << 0;

2046 }

2047

2048

2049

2051

2053 if (RClause->getReductionOp() == ReductionOp)

2054 break;

2055

2056 for (Expr *OldVarExpr : RClause->getVarList()) {

2057 if (OldVarExpr->isInstantiationDependent())

2058 continue;

2059

2060 if (areVarsEqual(VarExpr, OldVarExpr)) {

2061 Diag(VarExpr->getExprLoc(), diag::err_reduction_op_mismatch)

2062 << ReductionOp << RClause->getReductionOp();

2063 Diag(OldVarExpr->getExprLoc(), diag::note_acc_previous_clause_here);

2065 }

2066 }

2067 }

2068 }

2069

2070 return VarExpr;

2071}

2072

2074 if (!SizeExpr)

2076

2079 "size argument non integer?");

2080

2081

2083 isa(SizeExpr))

2085

2086 std::optionalllvm::APSInt ICE =

2088

2089

2090

2091 if (!ICE || *ICE <= 0) {

2092 Diag(SizeExpr->getBeginLoc(), diag::err_acc_size_expr_value)

2093 << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue();

2095 }

2096

2099}

2100

2102 if (!LoopCount)

2104

2107 "Loop argument non integer?");

2108

2109

2112

2113 std::optionalllvm::APSInt ICE =

2115

2116

2117

2118

2119 if (!ICE || *ICE <= 0) {

2120 Diag(LoopCount->getBeginLoc(), diag::err_acc_collapse_loop_count)

2121 << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue();

2123 }

2124

2127}

2128

2133

2134

2135

2136

2137 switch (DK) {

2139 return CheckGangParallelExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK,

2140 E);

2142 return CheckGangSerialExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK,

2143 E);

2145 return CheckGangKernelsExpr(*this, ExistingClauses, DK,

2146 ActiveComputeConstructInfo.Kind, GK, E);

2148 switch (ActiveComputeConstructInfo.Kind) {

2152 return CheckGangParallelExpr(*this, DK, ActiveComputeConstructInfo.Kind,

2153 GK, E);

2156 return CheckGangSerialExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK,

2157 E);

2160 return CheckGangKernelsExpr(*this, ExistingClauses, DK,

2161 ActiveComputeConstructInfo.Kind, GK, E);

2162 default:

2163 llvm_unreachable("Non compute construct in active compute construct?");

2164 }

2165 default:

2166

2167

2168 llvm_unreachable("Invalid directive kind for a Gang clause");

2169 }

2170 llvm_unreachable("Compute construct directive not handled?");

2171}

2172

2179

2180

2181

2182 const auto *ReductionItr =

2183 llvm::find_if(ExistingClauses, llvm::IsaPred);

2184

2185 if (ReductionItr != ExistingClauses.end()) {

2186 const auto GangZip = llvm::zip_equal(GangKinds, IntExprs);

2187 const auto GangItr = llvm::find_if(GangZip, [](const auto &Tuple) {

2189 });

2190

2191 if (GangItr != GangZip.end()) {

2192 const Expr *DimExpr = std::get<1>(*GangItr);

2193

2194 assert(

2196 "Improperly formed gang argument");

2197 if (const auto *DimVal = dyn_cast(DimExpr);

2198 DimVal && DimVal->getResultAsAPSInt() > 1) {

2199 Diag(DimVal->getBeginLoc(), diag::err_acc_gang_reduction_conflict)

2200 << 0 << DirKind;

2201 Diag((*ReductionItr)->getBeginLoc(),

2202 diag::note_acc_previous_clause_here);

2203 return nullptr;

2204 }

2205 }

2206 }

2207

2209 GangKinds, IntExprs, EndLoc);

2210}

2211

2219

2220

2221

2222 const auto GangClauses = llvm::make_filter_range(

2223 ExistingClauses, llvm::IsaPred);

2224

2225 for (auto *GC : GangClauses) {

2226 const auto *GangClause = cast(GC);

2227 for (unsigned I = 0; I < GangClause->getNumExprs(); ++I) {

2228 std::pair<OpenACCGangKind, const Expr *> EPair = GangClause->getExpr(I);

2230 continue;

2231

2232 if (const auto *DimVal = dyn_cast(EPair.second);

2233 DimVal && DimVal->getResultAsAPSInt() > 1) {

2234 Diag(BeginLoc, diag::err_acc_gang_reduction_conflict)

2235 << 1 << DirectiveKind;

2236 Diag(GangClause->getBeginLoc(), diag::note_acc_previous_clause_here);

2237 return nullptr;

2238 }

2239 }

2240 }

2241 }

2242

2244 getASTContext(), BeginLoc, LParenLoc, ReductionOp, Vars, EndLoc);

2245 return Ret;

2246}

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

Defines some OpenACC-specific enums and functions.

This file declares semantic analysis for OpenACC constructs and clauses.

APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

QualType getBaseElementType(const ArrayType *VAT) const

Return the innermost element type of an array type.

static QualType getBaseOriginalType(const Expr *Base)

Return original type of the base expression for array section.

static ConstantExpr * Create(const ASTContext &Context, Expr *E, const APValue &Result)

This represents one expression.

Expr * IgnoreParenCasts() LLVM_READONLY

Skip past any parentheses and casts which might surround this expression until reaching a fixed point...

bool isInstantiationDependent() const

Whether this expression is instantiation-dependent, meaning that it depends in some way on.

SourceLocation getExprLoc() const LLVM_READONLY

getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...

std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const

isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.

Represents a member of a struct/union/class.

static OpenACCAsyncClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)

static OpenACCAttachClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)

static OpenACCAutoClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)

This is the base type for all OpenACC Clauses.

OpenACCClauseKind getClauseKind() const

SourceLocation getBeginLoc() const

static OpenACCCollapseClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, bool HasForce, Expr *LoopCount, SourceLocation EndLoc)

static OpenACCCopyClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)

static OpenACCCopyInClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsReadOnly, ArrayRef< Expr * > VarList, SourceLocation EndLoc)

static OpenACCCopyOutClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsZero, ArrayRef< Expr * > VarList, SourceLocation EndLoc)

static OpenACCCreateClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsZero, ArrayRef< Expr * > VarList, SourceLocation EndLoc)

static OpenACCDefaultAsyncClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)

static OpenACCDefaultClause * Create(const ASTContext &C, OpenACCDefaultClauseKind K, SourceLocation BeginLoc, SourceLocation LParenLoc, SourceLocation EndLoc)

static OpenACCDeleteClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)

static OpenACCDetachClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)

static OpenACCDeviceClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)

static OpenACCDeviceNumClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)

static OpenACCDevicePtrClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)

A 'device_type' or 'dtype' clause, takes a list of either an 'asterisk' or an identifier.

static OpenACCDeviceTypeClause * Create(const ASTContext &C, OpenACCClauseKind K, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< DeviceTypeArgument > Archs, SourceLocation EndLoc)

static OpenACCFinalizeClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)

static OpenACCFirstPrivateClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)

static OpenACCGangClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< OpenACCGangKind > GangKinds, ArrayRef< Expr * > IntExprs, SourceLocation EndLoc)

static OpenACCHostClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)

static OpenACCIfClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *ConditionExpr, SourceLocation EndLoc)

static OpenACCIfPresentClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)

static OpenACCIndependentClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)

static OpenACCNoCreateClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)

static OpenACCNumGangsClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > IntExprs, SourceLocation EndLoc)

static OpenACCNumWorkersClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)

static OpenACCPresentClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)

static OpenACCPrivateClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)

static OpenACCReductionClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, OpenACCReductionOperator Operator, ArrayRef< Expr * > VarList, SourceLocation EndLoc)

static OpenACCSelfClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *ConditionExpr, SourceLocation EndLoc)

static OpenACCSeqClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)

static OpenACCTileClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > SizeExprs, SourceLocation EndLoc)

static OpenACCUseDeviceClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)

static OpenACCVectorClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)

static OpenACCVectorLengthClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)

static OpenACCWaitClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef< Expr * > QueueIdExprs, SourceLocation EndLoc)

static OpenACCWorkerClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)

A (possibly-)qualified type.

SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)

Emit a diagnostic.

ASTContext & getASTContext() const

A type to represent all the data for an OpenACC Clause that has been parsed, but not yet created/sema...

ArrayRef< Expr * > getIntExprs()

ArrayRef< Expr * > getQueueIdExprs() const

OpenACCDirectiveKind getDirectiveKind() const

ArrayRef< OpenACCGangKind > getGangKinds() const

OpenACCReductionOperator getReductionOp() const

SourceLocation getEndLoc() const

OpenACCClauseKind getClauseKind() const

const Expr * getConditionExpr() const

SourceLocation getLParenLoc() const

ArrayRef< DeviceTypeArgument > getDeviceTypeArchitectures() const

SourceLocation getBeginLoc() const

SourceLocation getQueuesLoc() const

void setVarListDetails(ArrayRef< Expr * > VarList, bool IsReadOnly, bool IsZero)

Expr * getDevNumExpr() const

ArrayRef< Expr * > getVarList()

unsigned getNumIntExprs() const

Expr * getLoopCount() const

OpenACCDefaultClauseKind getDefaultClauseKind() const

ComputeConstructInfo & getActiveComputeConstructInfo()

SourceLocation LoopWorkerClauseLoc

If there is a current 'active' loop construct with a 'worker' clause on it (on any sort of construct)...

OpenACCClause * ActOnClause(ArrayRef< const OpenACCClause * > ExistingClauses, OpenACCParsedClause &Clause)

Called after parsing an OpenACC Clause so that it can be checked.

bool CheckVarIsPointerType(OpenACCClauseKind ClauseKind, Expr *VarExpr)

Called to check the 'var' type is a variable of pointer type, necessary for 'deviceptr' and 'attach' ...

struct clang::SemaOpenACC::LoopGangOnKernelTy LoopGangClauseOnKernel

ExprResult CheckReductionVar(OpenACCDirectiveKind DirectiveKind, OpenACCReductionOperator ReductionOp, Expr *VarExpr)

Called while semantically analyzing the reduction clause, ensuring the var is the correct kind of ref...

ExprResult CheckCollapseLoopCount(Expr *LoopCount)

Checks the loop depth value for a collapse clause.

OpenACCClause * CheckReductionClause(ArrayRef< const OpenACCClause * > ExistingClauses, OpenACCDirectiveKind DirectiveKind, SourceLocation BeginLoc, SourceLocation LParenLoc, OpenACCReductionOperator ReductionOp, ArrayRef< Expr * > Vars, SourceLocation EndLoc)

SourceLocation LoopVectorClauseLoc

If there is a current 'active' loop construct with a 'vector' clause on it (on any sort of construct)...

ExprResult CheckGangExpr(ArrayRef< const OpenACCClause * > ExistingClauses, OpenACCDirectiveKind DK, OpenACCGangKind GK, Expr *E)

OpenACCClause * CheckGangClause(OpenACCDirectiveKind DirKind, ArrayRef< const OpenACCClause * > ExistingClauses, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< OpenACCGangKind > GangKinds, ArrayRef< Expr * > IntExprs, SourceLocation EndLoc)

ExprResult CheckTileSizeExpr(Expr *SizeExpr)

Checks a single size expr for a tile clause.

ASTContext & getASTContext() const

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

SourceLocation getBeginLoc() const LLVM_READONLY

bool isIntegerType() const

isIntegerType() does not include complex integers (a GCC extension).

RecordDecl * getAsRecordDecl() const

Retrieves the RecordDecl this type refers to.

The JSON file list parser is used to communicate input to InstallAPI.

bool isOpenACCComputeDirectiveKind(OpenACCDirectiveKind K)

bool isOpenACCCombinedDirectiveKind(OpenACCDirectiveKind K)

OpenACCClauseKind

Represents the kind of an OpenACC clause.

@ Invalid

Represents an invalid clause, for the purposes of parsing.

@ Result

The result type of a method or function.

OpenACCDirectiveKind DirKind