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

1

2

3

4

5

6

7

8

9

10

11

12

19

20using namespace clang;

21

22namespace {

23bool checkValidAfterDeviceType(

26

27

28

29

30

31

32

35 return false;

36

37

38

39

47 return false;

48 default:

49 break;

50 }

52

53

54

64 return false;

65 default:

66 break;

67 }

69

84 return false;

85 default:

86 break;

87 }

89

90

94 return false;

95 default:

96 break;

97 }

101

102 return false;

104

105

109 return false;

110 default:

111 break;

112 }

114

115

122 return false;

123 default:

124 break;

125 }

126 }

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

131 diag::note_acc_active_applies_clause_here)

132 << diag::ACCDeviceTypeApp::Active << DeviceTypeClause.getClauseKind();

133 return true;

134}

135

136

137

138

142

143 return DC;

144}

145

146class SemaOpenACCClauseVisitor {

147 SemaOpenACC &SemaRef;

148 ASTContext &Ctx;

149 ArrayRef<const OpenACCClause *> ExistingClauses;

150

151

152

153

154 bool

155 DiagGangWorkerVectorSeqConflict(SemaOpenACC::OpenACCParsedClause &Clause) {

156 if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop &&

158 return false;

159 assert(Clause.getClauseKind() == OpenACCClauseKind::Gang ||

160 Clause.getClauseKind() == OpenACCClauseKind::Worker ||

161 Clause.getClauseKind() == OpenACCClauseKind::Vector);

162 const auto *Itr =

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

164

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

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

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

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

170 << (*Itr)->getClauseKind();

171

172 return true;

173 }

174 return false;

175 }

176

178 CheckModifierList(SemaOpenACC::OpenACCParsedClause &Clause,

185 return CurMods;

186

187 SemaRef.Diag(Clause.getLParenLoc(), diag::err_acc_invalid_modifier)

189

190 return CurMods ^ Bit;

191 };

193 if ((Mods | ValidKinds) == ValidKinds)

194 return Mods;

195

196 Mods = CheckSingle(Mods, ValidKinds, OpenACCModifierKind::Always);

197 Mods = CheckSingle(Mods, ValidKinds, OpenACCModifierKind::AlwaysIn);

198 Mods = CheckSingle(Mods, ValidKinds, OpenACCModifierKind::AlwaysOut);

199 Mods = CheckSingle(Mods, ValidKinds, OpenACCModifierKind::Readonly);

200 Mods = CheckSingle(Mods, ValidKinds, OpenACCModifierKind::Zero);

201 Mods = CheckSingle(Mods, ValidKinds, OpenACCModifierKind::Capture);

202 return Mods;

203 };

204

205

206

207 bool IsStructuredDataOrCompute =

211

213 default:

214 llvm_unreachable("Only for copy, copyin, copyout, create");

215 case OpenACCClauseKind::Copy:

216 case OpenACCClauseKind::PCopy:

217 case OpenACCClauseKind::PresentOrCopy:

218

219 return Check(OpenACCModifierKind::Always | OpenACCModifierKind::AlwaysIn |

220 OpenACCModifierKind::AlwaysOut |

221 OpenACCModifierKind::Capture);

222 case OpenACCClauseKind::CopyIn:

223 case OpenACCClauseKind::PCopyIn:

224 case OpenACCClauseKind::PresentOrCopyIn:

225

226 return Check(OpenACCModifierKind::Always | OpenACCModifierKind::AlwaysIn |

227 OpenACCModifierKind::Readonly |

228 (IsStructuredDataOrCompute ? OpenACCModifierKind::Capture

229 : OpenACCModifierKind::Invalid));

230 case OpenACCClauseKind::CopyOut:

231 case OpenACCClauseKind::PCopyOut:

232 case OpenACCClauseKind::PresentOrCopyOut:

233

234 return Check(OpenACCModifierKind::Always |

235 OpenACCModifierKind::AlwaysOut | OpenACCModifierKind::Zero |

236 (IsStructuredDataOrCompute ? OpenACCModifierKind::Capture

237 : OpenACCModifierKind::Invalid));

238 case OpenACCClauseKind::Create:

239 case OpenACCClauseKind::PCreate:

240 case OpenACCClauseKind::PresentOrCreate:

241

242 return Check(OpenACCModifierKind::Zero |

243 (IsStructuredDataOrCompute ? OpenACCModifierKind::Capture

244 : OpenACCModifierKind::Invalid));

245 }

246 llvm_unreachable("didn't return from switch above?");

247 }

248

249

250

251

252

253

254

255 template

256 bool DisallowSinceLastDeviceType(Pred HasPredicate,

257 SemaOpenACC::OpenACCParsedClause &Clause,

258 bool DTOverrides = true) {

259 using ItrTy = decltype(ExistingClauses.begin());

260 llvm::SmallVector DeviceTypeClauses;

261

262 ItrTy DevTypeItr =

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

264 while (DevTypeItr != ExistingClauses.end()) {

265 DeviceTypeClauses.push_back(DevTypeItr);

266 DevTypeItr = std::find_if(std::next(DevTypeItr), ExistingClauses.end(),

267 llvm::IsaPred);

268 }

269

270 auto SinceLastDevType =

271 std::find_if(DeviceTypeClauses.empty() ? ExistingClauses.begin()

272 : DeviceTypeClauses.back(),

273 ExistingClauses.end(), HasPredicate);

274

275

276

277 if (SinceLastDevType != ExistingClauses.end()) {

279 diag::err_acc_clause_cannot_combine_same_device_type)

281 << (*SinceLastDevType)->getClauseKind() << !DeviceTypeClauses.empty();

282

283 SemaRef.Diag((*SinceLastDevType)->getBeginLoc(),

284 diag::note_acc_previous_clause_here)

285 << (*SinceLastDevType)->getClauseKind();

286

287 if (!DeviceTypeClauses.empty()) {

288 SemaRef.Diag((*DeviceTypeClauses.back())->getBeginLoc(),

289 diag::note_acc_active_applies_clause_here)

290 << diag::ACCDeviceTypeApp::Active

291 << (*DeviceTypeClauses.back())->getClauseKind();

292 }

293

294 return true;

295 }

296

297

298

299

300 if (DeviceTypeClauses.empty())

301 return false;

302

303 if (!DTOverrides) {

304

305

306

307 auto BeforeFirstDevType = std::find_if(

308 ExistingClauses.begin(), DeviceTypeClauses.front(), HasPredicate);

309

310 if (BeforeFirstDevType != DeviceTypeClauses.front()) {

312 diag::err_acc_clause_cannot_combine_before_device_type)

314 << (*BeforeFirstDevType)->getClauseKind();

315

316 SemaRef.Diag((*BeforeFirstDevType)->getBeginLoc(),

317 diag::note_acc_previous_clause_here)

318 << (*BeforeFirstDevType)->getClauseKind();

319

320 SemaRef.Diag((*DeviceTypeClauses.back())->getBeginLoc(),

321 diag::note_acc_active_applies_clause_here)

322 << diag::ACCDeviceTypeApp::Active

323 << (*DeviceTypeClauses.back())->getClauseKind();

324 return true;

325 }

326 }

327

328

329

330

333

334

336 return true;

337

339 return false;

341 StringRef RHSName = RHS.getIdentifierInfo()->getName();

342 if (LHSName.equals_insensitive(RHSName))

343 return true;

344

345

346

347 return (LHSName.equals_insensitive("acc_device_nvidia") &&

348 RHSName.equals_insensitive("nvidia")) ||

349 (RHSName.equals_insensitive("acc_device_nvidia") &&

350 LHSName.equals_insensitive("nvidia"));

351 };

352 const OpenACCDeviceTypeClause *ActiveDTClause =

354

355

356

357 for (unsigned Idx = 0; Idx < DeviceTypeClauses.size() - 1; ++Idx) {

358 ItrTy ProhibitedClause = std::find_if(

359 DeviceTypeClauses[Idx], DeviceTypeClauses[Idx + 1], HasPredicate);

360

361

362

363 if (ProhibitedClause == DeviceTypeClauses[Idx + 1])

364 continue;

365

366 const OpenACCDeviceTypeClause *CurDTClause =

368

373 if (areSameArch(CurArch, ActiveArch)) {

375 diag::err_acc_clause_conflicts_prev_dev_type)

377 << (ActiveArch.getIdentifierInfo()

378 ? ActiveArch.getIdentifierInfo()->getName()

379 : "*")

380 << (*ProhibitedClause)->getClauseKind();

381

382 SemaRef.Diag(ActiveDTClause->getBeginLoc(),

383 diag::note_acc_active_applies_clause_here)

384 << diag::ACCDeviceTypeApp::Active

386

387 SemaRef.Diag((*ProhibitedClause)->getBeginLoc(),

388 diag::note_acc_previous_clause_here)

389 << (*ProhibitedClause)->getClauseKind();

390

392 diag::note_acc_active_applies_clause_here)

393 << diag::ACCDeviceTypeApp::Applies

395

396 return true;

397 }

398 }

399 }

400

401

402

403 }

404

405

406 return false;

407 }

408

409

410

411 bool CheckValidRoutineGangWorkerVectorSeqNewClause(

412 SemaOpenACC::OpenACCParsedClause &Clause) {

413 if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Routine)

414 return false;

415 if (Clause.getClauseKind() != OpenACCClauseKind::Gang &&

416 Clause.getClauseKind() != OpenACCClauseKind::Vector &&

417 Clause.getClauseKind() != OpenACCClauseKind::Worker &&

418 Clause.getClauseKind() != OpenACCClauseKind::Seq)

419 return false;

420 auto ProhibitedPred = llvm::IsaPred<OpenACCGangClause, OpenACCWorkerClause,

421 OpenACCVectorClause, OpenACCSeqClause>;

422

423 return DisallowSinceLastDeviceType(ProhibitedPred, Clause,

424 false);

425 }

426

427

428

429

430 bool

431 CheckValidRoutineBindNewClause(SemaOpenACC::OpenACCParsedClause &Clause) {

432 if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Routine)

433 return false;

434 if (Clause.getClauseKind() != OpenACCClauseKind::Bind)

435 return false;

436

437 auto HasBindPred = llvm::IsaPred;

438 return DisallowSinceLastDeviceType(HasBindPred, Clause,

439 false);

440 }

441

442public:

443 SemaOpenACCClauseVisitor(SemaOpenACC &S,

444 ArrayRef<const OpenACCClause *> ExistingClauses)

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

446

447 OpenACCClause *Visit(SemaOpenACC::OpenACCParsedClause &Clause) {

448

449 if (SemaRef.DiagnoseAllowedOnceClauses(

451 Clause.getBeginLoc(), ExistingClauses) ||

455 return nullptr;

456 if (CheckValidRoutineGangWorkerVectorSeqNewClause(Clause) ||

457 CheckValidRoutineBindNewClause(Clause))

458 return nullptr;

459

461 case OpenACCClauseKind::Shortloop:

462 llvm_unreachable("Shortloop shouldn't be generated in clang");

463 case OpenACCClauseKind::Invalid:

464 return nullptr;

465#define VISIT_CLAUSE(CLAUSE_NAME) \

466 case OpenACCClauseKind::CLAUSE_NAME: \

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

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

469 case OpenACCClauseKind::ALIAS: \

470 if (DEPRECATED) \

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

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

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

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

475 }

476 llvm_unreachable("Invalid clause kind");

477 }

478

479#define VISIT_CLAUSE(CLAUSE_NAME) \

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

481 SemaOpenACC::OpenACCParsedClause &Clause);

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

483};

484

485OpenACCClause *SemaOpenACCClauseVisitor::VisitDefaultClause(

487

489 return nullptr;

490

494}

495

496OpenACCClause *SemaOpenACCClauseVisitor::VisitTileClause(

497 SemaOpenACC::OpenACCParsedClause &Clause) {

498

499 if (DisallowSinceLastDeviceType(llvm::IsaPred, Clause))

500 return nullptr;

501

502 llvm::SmallVector<Expr *> NewSizeExprs;

503

504

507

509 return nullptr;

510

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

512 }

513

517}

518

519OpenACCClause *SemaOpenACCClauseVisitor::VisitIfClause(

520 SemaOpenACC::OpenACCParsedClause &Clause) {

521

522

523

524

525

526

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

528 const auto *Itr =

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

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

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

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

533 << (*Itr)->getClauseKind();

534 }

535 }

536

540}

541

542OpenACCClause *SemaOpenACCClauseVisitor::VisitSelfClause(

543 SemaOpenACC::OpenACCParsedClause &Clause) {

544

545

546

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

551

552 const auto *Itr =

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

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

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

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

557 << (*Itr)->getClauseKind();

558 }

562}

563

564OpenACCClause *SemaOpenACCClauseVisitor::VisitNumGangsClause(

565 SemaOpenACC::OpenACCParsedClause &Clause) {

566

567 if (DisallowSinceLastDeviceType(llvm::IsaPred, Clause))

568 return nullptr;

569

570

571

572

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

575 << 0;

576

577 unsigned MaxArgs =

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

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

580 ? 3

581 : 1;

582

583

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

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

588

589

590

591

594 auto *GangClauseItr =

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

596 auto *ReductionClauseItr =

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

598

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

600 ReductionClauseItr != ExistingClauses.end()) {

602 diag::err_acc_gang_reduction_numgangs_conflict)

603 << OpenACCClauseKind::Reduction << OpenACCClauseKind::Gang

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

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

606 diag::note_acc_previous_clause_here)

607 << (*ReductionClauseItr)->getClauseKind();

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

609 diag::note_acc_previous_clause_here)

610 << (*GangClauseItr)->getClauseKind();

611 return nullptr;

612 }

613 }

614

615

616

617

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

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

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

623

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

626 diag::err_acc_reduction_num_gangs_conflict)

627 << 1 << Clause.getClauseKind()

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

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

630 diag::note_acc_previous_clause_here)

631 << (*Parallel)->getClauseKind();

632 return nullptr;

633 }

634 }

635

636

637

638

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

640 auto GangClauses = llvm::make_filter_range(

641 ExistingClauses, llvm::IsaPred);

642

643 for (auto *GC : GangClauses) {

646 diag::err_acc_num_arg_conflict_reverse)

647 << OpenACCClauseKind::NumGangs << OpenACCClauseKind::Gang

648 << 1;

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

650 << GC->getClauseKind();

651 return nullptr;

652 }

653 }

654 }

655

659}

660

661OpenACCClause *SemaOpenACCClauseVisitor::VisitNumWorkersClause(

662 SemaOpenACC::OpenACCParsedClause &Clause) {

663

664 if (DisallowSinceLastDeviceType(llvm::IsaPred,

665 Clause))

666 return nullptr;

667

668

669

670

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

672 auto WorkerClauses = llvm::make_filter_range(

673 ExistingClauses, llvm::IsaPred);

674

675 for (auto *WC : WorkerClauses) {

678 diag::err_acc_num_arg_conflict_reverse)

679 << OpenACCClauseKind::NumWorkers << OpenACCClauseKind::Worker

680 << 0;

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

682 << WC->getClauseKind();

683 return nullptr;

684 }

685 }

686 }

687

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

689 "Invalid number of expressions for NumWorkers");

693}

694

695OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorLengthClause(

696 SemaOpenACC::OpenACCParsedClause &Clause) {

697

698 if (DisallowSinceLastDeviceType(llvm::IsaPred,

699 Clause))

700 return nullptr;

701

702

703

704

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

706 auto VectorClauses = llvm::make_filter_range(

707 ExistingClauses, llvm::IsaPred);

708

709 for (auto *VC : VectorClauses) {

712 diag::err_acc_num_arg_conflict_reverse)

713 << OpenACCClauseKind::VectorLength << OpenACCClauseKind::Vector

714 << 0;

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

716 << VC->getClauseKind();

717 return nullptr;

718 }

719 }

720 }

721

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

723 "Invalid number of expressions for NumWorkers");

727}

728

729OpenACCClause *SemaOpenACCClauseVisitor::VisitAsyncClause(

730 SemaOpenACC::OpenACCParsedClause &Clause) {

731 if (DisallowSinceLastDeviceType(llvm::IsaPred, Clause))

732 return nullptr;

733

735 "Invalid number of expressions for Async");

740}

741

742OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceNumClause(

743 SemaOpenACC::OpenACCParsedClause &Clause) {

745 "Invalid number of expressions for device_num");

749}

750

751OpenACCClause *SemaOpenACCClauseVisitor::VisitDefaultAsyncClause(

752 SemaOpenACC::OpenACCParsedClause &Clause) {

754 "Invalid number of expressions for default_async");

758}

759

760OpenACCClause *SemaOpenACCClauseVisitor::VisitPrivateClause(

761 SemaOpenACC::OpenACCParsedClause &Clause) {

762

763

764

765

766 llvm::SmallVector InitRecipes;

767

768

769 for (const Expr *VarExpr : Clause.getVarList())

771

774 InitRecipes, Clause.getEndLoc());

775}

776

777OpenACCClause *SemaOpenACCClauseVisitor::VisitFirstPrivateClause(

778 SemaOpenACC::OpenACCParsedClause &Clause) {

779

780

781

782

783 llvm::SmallVector InitRecipes;

784

785

786 for (const Expr *VarExpr : Clause.getVarList())

788

791 InitRecipes, Clause.getEndLoc());

792}

793

794OpenACCClause *SemaOpenACCClauseVisitor::VisitNoCreateClause(

795 SemaOpenACC::OpenACCParsedClause &Clause) {

796

797

798

799

803}

804

805OpenACCClause *SemaOpenACCClauseVisitor::VisitPresentClause(

806 SemaOpenACC::OpenACCParsedClause &Clause) {

807

808

809

810

811

812

813 if (SemaRef.CheckDeclareClause(Clause, OpenACCModifierKind::Invalid))

814 return nullptr;

815

819}

820

821OpenACCClause *SemaOpenACCClauseVisitor::VisitHostClause(

822 SemaOpenACC::OpenACCParsedClause &Clause) {

823

824

825

826

830}

831

832OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceClause(

833 SemaOpenACC::OpenACCParsedClause &Clause) {

834

835

836

837

841}

842

843OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyClause(

844 SemaOpenACC::OpenACCParsedClause &Clause) {

845

846

847

848

851

852

853

855 return nullptr;

856

860}

861

862OpenACCClause *SemaOpenACCClauseVisitor::VisitLinkClause(

863 SemaOpenACC::OpenACCParsedClause &Clause) {

864

865

866 if (SemaRef.CheckDeclareClause(Clause, OpenACCModifierKind::Invalid))

867 return nullptr;

868

870 OpenACCModifierKind::Invalid);

871

875}

876

877OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceResidentClause(

878 SemaOpenACC::OpenACCParsedClause &Clause) {

879

880

881 if (SemaRef.CheckDeclareClause(Clause, OpenACCModifierKind::Invalid))

882 return nullptr;

883

887}

888

889OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyInClause(

890 SemaOpenACC::OpenACCParsedClause &Clause) {

891

892

893

894

897

898

899

901 return nullptr;

902

906}

907

908OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyOutClause(

909 SemaOpenACC::OpenACCParsedClause &Clause) {

910

911

912

913

916

917

918

920 return nullptr;

921

925}

926

927OpenACCClause *SemaOpenACCClauseVisitor::VisitCreateClause(

928 SemaOpenACC::OpenACCParsedClause &Clause) {

929

930

931

932

935

936

937

939 return nullptr;

940

944}

945

946OpenACCClause *SemaOpenACCClauseVisitor::VisitAttachClause(

947 SemaOpenACC::OpenACCParsedClause &Clause) {

948

949

950 llvm::SmallVector<Expr *> VarList{Clause.getVarList()};

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

953 });

958}

959

960OpenACCClause *SemaOpenACCClauseVisitor::VisitDetachClause(

961 SemaOpenACC::OpenACCParsedClause &Clause) {

962

963

964 llvm::SmallVector<Expr *> VarList{Clause.getVarList()};

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

967 });

972}

973

974OpenACCClause *SemaOpenACCClauseVisitor::VisitDeleteClause(

975 SemaOpenACC::OpenACCParsedClause &Clause) {

976

977

978

982}

983

984OpenACCClause *SemaOpenACCClauseVisitor::VisitUseDeviceClause(

985 SemaOpenACC::OpenACCParsedClause &Clause) {

986

987

991}

992

993OpenACCClause *SemaOpenACCClauseVisitor::VisitDevicePtrClause(

994 SemaOpenACC::OpenACCParsedClause &Clause) {

995

996

997 llvm::SmallVector<Expr *> VarList{Clause.getVarList()};

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

1000 });

1001 Clause.setVarListDetails(VarList, OpenACCModifierKind::Invalid);

1002

1003

1004

1005 if (SemaRef.CheckDeclareClause(Clause, OpenACCModifierKind::Invalid))

1006 return nullptr;

1007

1011}

1012

1013OpenACCClause *SemaOpenACCClauseVisitor::VisitWaitClause(

1014 SemaOpenACC::OpenACCParsedClause &Clause) {

1018}

1019

1020OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceTypeClause(

1021 SemaOpenACC::OpenACCParsedClause &Clause) {

1022

1023

1024

1025

1026

1027 if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Init ||

1028 Clause.getDirectiveKind() == OpenACCDirectiveKind::Shutdown ||

1032 diag::err_acc_device_type_multiple_archs)

1034 return nullptr;

1035 }

1036

1037

1038

1039

1040

1041 const std::array<llvm::StringLiteral, 6> ValidValues{

1042 "default", "nvidia", "acc_device_nvidia", "radeon", "host", "multicore"};

1043

1044

1045

1046 std::string ValidValuesString =

1047 "'default', 'nvidia', 'acc_device_nvidia', 'radeon', 'host', 'multicore'";

1048

1049 llvm::SmallVector Architectures{

1051

1052

1053

1054

1055 bool Diagnosed = false;

1057

1058 if (Arch.getIdentifierInfo())

1059 return false;

1060 return llvm::find_if(ValidValues, [&](StringRef RHS) {

1061 return Arch.getIdentifierInfo()->getName().equals_insensitive(RHS);

1062 }) == ValidValues.end();

1063 };

1064

1066 Diagnosed = SemaRef.Diag(Arch.getLoc(), diag::err_acc_invalid_default_type)

1068 << ValidValuesString;

1069 };

1070

1071

1072

1073

1074

1075 llvm::for_each(llvm::make_filter_range(Architectures, FilterPred), Diagnose);

1076 if (Diagnosed)

1077 llvm::erase_if(Architectures, FilterPred);

1078

1081 Architectures, Clause.getEndLoc());

1082}

1083

1084OpenACCClause *SemaOpenACCClauseVisitor::VisitAutoClause(

1085 SemaOpenACC::OpenACCParsedClause &Clause) {

1086

1089}

1090

1091OpenACCClause *SemaOpenACCClauseVisitor::VisitNoHostClause(

1092 SemaOpenACC::OpenACCParsedClause &Clause) {

1095}

1096

1097OpenACCClause *SemaOpenACCClauseVisitor::VisitIndependentClause(

1098 SemaOpenACC::OpenACCParsedClause &Clause) {

1099

1102}

1103

1104ExprResult CheckGangStaticExpr(SemaOpenACC &S, Expr *E) {

1106 return E;

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

1109}

1110

1112 return DK == OpenACCDirectiveKind::Loop &&

1113 AssocKind == OpenACCDirectiveKind::Invalid;

1114}

1115

1117 return DK == OpenACCDirectiveKind::Loop &&

1118 AssocKind != OpenACCDirectiveKind::Invalid;

1119}

1120

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

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

1128}

1129ExprResult DiagIntArgInvalid(SemaOpenACC &S, Expr *E, StringRef TagKind,

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

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

1136}

1137

1138ExprResult CheckGangDimExpr(SemaOpenACC &S, Expr *E) {

1139

1140

1141

1142

1143

1144

1145

1146 if (!E)

1149 OpenACCClauseKind::Gang, E->getBeginLoc(), E);

1150

1152 return Res;

1153

1155 return Res;

1156

1157 std::optionalllvm::APSInt ICE =

1159

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

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

1164 }

1165

1168}

1169

1173 switch (GK) {

1174 case OpenACCGangKind::Static:

1175 return CheckGangStaticExpr(S, E);

1176 case OpenACCGangKind::Num:

1177

1178

1179

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

1181 case OpenACCGangKind::Dim:

1182 return CheckGangDimExpr(S, E);

1183 }

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

1185}

1186

1187ExprResult CheckGangKernelsExpr(SemaOpenACC &S,

1188 ArrayRef<const OpenACCClause *> ExistingClauses,

1192 switch (GK) {

1193

1194

1195

1196 case OpenACCGangKind::Dim:

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

1198 case OpenACCGangKind::Num: {

1199

1200

1201

1202

1203

1204

1205

1206

1207

1209 ? ExistingClauses

1211

1212 const auto *Itr =

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

1214

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

1216 S.Diag(E->getBeginLoc(), diag::err_acc_num_arg_conflict)

1217 << "num" << OpenACCClauseKind::Gang << DK

1218 << HasAssocKind(DK, AssocKind) << AssocKind

1219 << OpenACCClauseKind::NumGangs;

1220

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

1222 << (*Itr)->getClauseKind();

1224 }

1226 }

1227 case OpenACCGangKind::Static:

1228 return CheckGangStaticExpr(S, E);

1229 }

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

1231}

1232

1236 switch (GK) {

1237

1238

1239 case OpenACCGangKind::Dim:

1240 case OpenACCGangKind::Num:

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

1242 case OpenACCGangKind::Static:

1243 return CheckGangStaticExpr(S, E);

1244 }

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

1246}

1247

1251 switch (GK) {

1252

1253 case OpenACCGangKind::Num:

1254 case OpenACCGangKind::Static:

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

1256 case OpenACCGangKind::Dim:

1257 return CheckGangDimExpr(S, E);

1258 }

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

1260}

1261

1262OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorClause(

1263 SemaOpenACC::OpenACCParsedClause &Clause) {

1264 if (DiagGangWorkerVectorSeqConflict(Clause))

1265 return nullptr;

1266

1267 Expr *IntExpr =

1269 if (IntExpr) {

1271 default:

1272 llvm_unreachable("Invalid directive kind for this clause");

1273 case OpenACCDirectiveKind::Loop:

1275 case OpenACCDirectiveKind::Invalid:

1276 case OpenACCDirectiveKind::Parallel:

1277 case OpenACCDirectiveKind::ParallelLoop:

1278

1279 break;

1280 case OpenACCDirectiveKind::Serial:

1281 case OpenACCDirectiveKind::SerialLoop:

1282

1283

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

1287 IntExpr = nullptr;

1288 break;

1289 case OpenACCDirectiveKind::Kernels:

1290 case OpenACCDirectiveKind::KernelsLoop: {

1291 const auto *Itr =

1293 llvm::IsaPred);

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

1296 << "length" << OpenACCClauseKind::Vector

1301 << OpenACCClauseKind::VectorLength;

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

1303 diag::note_acc_previous_clause_here)

1304 << (*Itr)->getClauseKind();

1305

1306 IntExpr = nullptr;

1307 }

1308 break;

1309 }

1310 default:

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

1312 }

1313 break;

1314 case OpenACCDirectiveKind::KernelsLoop: {

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

1316 llvm::IsaPred);

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

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

1319 << "length" << OpenACCClauseKind::Vector

1324 << OpenACCClauseKind::VectorLength;

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

1326 << (*Itr)->getClauseKind();

1327

1328 IntExpr = nullptr;

1329 }

1330 break;

1331 }

1332 case OpenACCDirectiveKind::SerialLoop:

1333 case OpenACCDirectiveKind::Routine:

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

1337 IntExpr = nullptr;

1338 break;

1339 case OpenACCDirectiveKind::ParallelLoop:

1340 break;

1341 case OpenACCDirectiveKind::Invalid:

1342

1343

1344

1345

1346 break;

1347 }

1348 }

1349

1350 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop) {

1351

1352

1353

1355

1356

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

1358 << OpenACCClauseKind::Vector << OpenACCClauseKind::Vector

1359 << 0;

1361 diag::note_acc_previous_clause_here)

1362 << "vector";

1363 return nullptr;

1364 }

1365 }

1366

1370}

1371

1372OpenACCClause *SemaOpenACCClauseVisitor::VisitWorkerClause(

1373 SemaOpenACC::OpenACCParsedClause &Clause) {

1374 if (DiagGangWorkerVectorSeqConflict(Clause))

1375 return nullptr;

1376

1377 Expr *IntExpr =

1379

1380 if (IntExpr) {

1382 default:

1383 llvm_unreachable("Invalid directive kind for this clause");

1384 case OpenACCDirectiveKind::Invalid:

1385

1386

1387

1388

1389

1390

1391 break;

1392 case OpenACCDirectiveKind::Loop:

1394 case OpenACCDirectiveKind::Invalid:

1395 case OpenACCDirectiveKind::ParallelLoop:

1396 case OpenACCDirectiveKind::SerialLoop:

1397 case OpenACCDirectiveKind::Parallel:

1398 case OpenACCDirectiveKind::Serial:

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

1402 IntExpr = nullptr;

1403 break;

1404 case OpenACCDirectiveKind::KernelsLoop:

1405 case OpenACCDirectiveKind::Kernels: {

1406 const auto *Itr =

1408 llvm::IsaPred);

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

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

1415 << OpenACCClauseKind::NumWorkers;

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

1417 diag::note_acc_previous_clause_here)

1418 << (*Itr)->getClauseKind();

1419

1420 IntExpr = nullptr;

1421 }

1422 break;

1423 }

1424 default:

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

1426 }

1427 break;

1428 case OpenACCDirectiveKind::ParallelLoop:

1429 case OpenACCDirectiveKind::SerialLoop:

1430 case OpenACCDirectiveKind::Routine:

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

1434 IntExpr = nullptr;

1435 break;

1436 case OpenACCDirectiveKind::KernelsLoop: {

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

1438 llvm::IsaPred);

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

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

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

1445 << OpenACCClauseKind::NumWorkers;

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

1447 << (*Itr)->getClauseKind();

1448

1449 IntExpr = nullptr;

1450 }

1451 }

1452 }

1453 }

1454

1455 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop) {

1456

1457

1458

1460

1461

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

1463 << OpenACCClauseKind::Worker << OpenACCClauseKind::Worker

1464 << 0;

1466 diag::note_acc_previous_clause_here)

1467 << "worker";

1468 return nullptr;

1469 }

1470

1471

1472

1473

1475

1476

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

1478 << OpenACCClauseKind::Worker << OpenACCClauseKind::Vector

1479 << 0;

1481 diag::note_acc_previous_clause_here)

1482 << "vector";

1483 return nullptr;

1484 }

1485 }

1486

1490}

1491

1492OpenACCClause *SemaOpenACCClauseVisitor::VisitGangClause(

1493 SemaOpenACC::OpenACCParsedClause &Clause) {

1494

1495 if (DiagGangWorkerVectorSeqConflict(Clause))

1496 return nullptr;

1497

1498

1499

1500

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

1503 OpenACCDirectiveKind::Invalid) ||

1505

1506 auto ActiveComputeConstructContainer =

1508 ? ExistingClauses

1510 auto *NumGangsClauseItr = llvm::find_if(

1511 ActiveComputeConstructContainer, llvm::IsaPred);

1512

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

1515 1) {

1516 auto *ReductionClauseItr =

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

1518

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

1521 diag::err_acc_gang_reduction_numgangs_conflict)

1522 << OpenACCClauseKind::Gang << OpenACCClauseKind::Reduction

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

1526 diag::note_acc_previous_clause_here)

1527 << (*ReductionClauseItr)->getClauseKind();

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

1529 diag::note_acc_previous_clause_here)

1530 << (*NumGangsClauseItr)->getClauseKind();

1531 return nullptr;

1532 }

1533 }

1534 }

1535

1536 llvm::SmallVector GangKinds;

1537 llvm::SmallVector<Expr *> IntExprs;

1538

1539

1540

1541 SourceLocation ExistingElemLoc[3];

1542

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

1548

1550 continue;

1551

1552

1553

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

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

1556 << static_cast<unsigned>(GK);

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

1558 diag::note_acc_previous_expr_here);

1559 continue;

1560 }

1561

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

1563 GangKinds.push_back(GK);

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

1565 }

1566

1567 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop) {

1568

1569

1570

1571

1573

1574

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

1576 << OpenACCClauseKind::Gang << OpenACCClauseKind::Gang

1577 << 1

1580 diag::note_acc_previous_clause_here)

1581 << "gang";

1582 return nullptr;

1583 }

1584

1585

1586

1587

1589

1590

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

1592 << OpenACCClauseKind::Gang << OpenACCClauseKind::Worker

1593 << 0;

1595 diag::note_acc_previous_clause_here)

1596 << "worker";

1597 return nullptr;

1598 }

1599

1600

1601

1602

1604

1605

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

1607 << OpenACCClauseKind::Gang << OpenACCClauseKind::Vector

1608 << 0;

1610 diag::note_acc_previous_clause_here)

1611 << "vector";

1612 return nullptr;

1613 }

1614 }

1615

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

1619}

1620

1621OpenACCClause *SemaOpenACCClauseVisitor::VisitFinalizeClause(

1622 SemaOpenACC::OpenACCParsedClause &Clause) {

1623

1624

1627}

1628

1629OpenACCClause *SemaOpenACCClauseVisitor::VisitIfPresentClause(

1630 SemaOpenACC::OpenACCParsedClause &Clause) {

1631

1632

1635}

1636

1637OpenACCClause *SemaOpenACCClauseVisitor::VisitSeqClause(

1638 SemaOpenACC::OpenACCParsedClause &Clause) {

1639

1640

1641

1642 if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop ||

1644 const auto *Itr = llvm::find_if(

1645 ExistingClauses, llvm::IsaPred<OpenACCGangClause, OpenACCVectorClause,

1646 OpenACCWorkerClause>);

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

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

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

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

1652 << (*Itr)->getClauseKind();

1653 return nullptr;

1654 }

1655 }

1656

1659}

1660

1661OpenACCClause *SemaOpenACCClauseVisitor::VisitReductionClause(

1662 SemaOpenACC::OpenACCParsedClause &Clause) {

1663

1664

1665

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

1668 OpenACCDirectiveKind::Invalid) ||

1670

1671 auto ActiveComputeConstructContainer =

1673 ? ExistingClauses

1675 auto *NumGangsClauseItr = llvm::find_if(

1676 ActiveComputeConstructContainer, llvm::IsaPred);

1677

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

1680 1) {

1681 auto *GangClauseItr =

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

1683

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

1686 diag::err_acc_gang_reduction_numgangs_conflict)

1687 << OpenACCClauseKind::Reduction << OpenACCClauseKind::Gang

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

1691 diag::note_acc_previous_clause_here)

1692 << (*GangClauseItr)->getClauseKind();

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

1694 diag::note_acc_previous_clause_here)

1695 << (*NumGangsClauseItr)->getClauseKind();

1696 return nullptr;

1697 }

1698 }

1699 }

1700

1701

1702

1703

1704

1705

1706

1707

1708

1709

1710

1711

1712

1713

1714

1715

1716

1717

1718

1719

1720

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

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

1723 auto NumGangsClauses = llvm::make_filter_range(

1724 ExistingClauses, llvm::IsaPred);

1725

1726 for (auto *NGC : NumGangsClauses) {

1727 unsigned NumExprs =

1729

1730 if (NumExprs > 1) {

1732 diag::err_acc_reduction_num_gangs_conflict)

1733 << 0 << Clause.getClauseKind()

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

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

1736 << NGC->getClauseKind();

1737 return nullptr;

1738 }

1739 }

1740 }

1741

1742 SmallVector<Expr *> ValidVars;

1743 SmallVector Recipes;

1744

1745 for (Expr *Var : Clause.getVarList()) {

1748

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

1751

1754 }

1755 }

1756

1760 Recipes,

1762}

1763

1764OpenACCClause *SemaOpenACCClauseVisitor::VisitCollapseClause(

1765 SemaOpenACC::OpenACCParsedClause &Clause) {

1766

1767 if (DisallowSinceLastDeviceType(llvm::IsaPred, Clause))

1768 return nullptr;

1769

1771

1773 return nullptr;

1774

1778}

1779

1780OpenACCClause *SemaOpenACCClauseVisitor::VisitBindClause(

1781 SemaOpenACC::OpenACCParsedClause &Clause) {

1782

1783 if (std::holds_alternative<StringLiteral *>(Clause.getBindDetails()))

1790}

1791

1792

1793

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

1797 return false;

1798

1801

1802

1803

1804

1805

1807 auto *Expr2AS = dyn_cast(VarExpr2);

1808 if (!Expr2AS)

1809 return false;

1810

1812

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

1814 return false;

1815

1816

1817 return true;

1818 }

1819

1820

1822 auto *Expr2AS = dyn_cast(VarExpr2);

1823 if (!Expr2AS)

1824 return false;

1825

1827

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

1829 return false;

1830

1831

1832

1833

1834 return true;

1835 }

1836

1837

1839 auto *Expr2DRE = dyn_cast(VarExpr2);

1840 if (!Expr2DRE)

1841 return false;

1842

1844

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

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

1847 }

1848

1849 llvm_unreachable("Unknown variable type encountered");

1850}

1851}

1852

1853OpenACCClause *

1857 return nullptr;

1858

1859 if (DiagnoseAllowedClauses(Clause.getDirectiveKind(), Clause.getClauseKind(),

1860 Clause.getBeginLoc()))

1861 return nullptr;

1862

1863 if (const auto *DevTypeClause = llvm::find_if(

1864 ExistingClauses, llvm::IsaPred);

1865 DevTypeClause != ExistingClauses.end()) {

1866 if (checkValidAfterDeviceType(

1868 return nullptr;

1869 }

1870

1871 SemaOpenACCClauseVisitor Visitor{*this, ExistingClauses};

1873 assert((Result || Result->getClauseKind() == Clause.getClauseKind()) &&

1874 "Created wrong clause?");

1875

1877}

1878

1881

1883

1884

1885

1886

1890

1891

1892

1893

1894 if (CurType.isNull())

1895 return false;

1896

1897

1898

1899

1900 if (auto *AT = getASTContext().getAsArrayType(CurType)) {

1901

1902

1904 << diag::OACCReductionArray::ArrayTy << CurType;

1905 Notes.push_back({VarLoc, PD});

1906 CurType = AT->getElementType();

1907 }

1908

1909 auto IsValidMemberOfComposite = [](QualType Ty) {

1910 return !Ty->isAnyComplexType() &&

1911 (Ty->isDependentType() ||

1912 (Ty->isScalarType() && !Ty->isPointerType()));

1913 };

1914

1916 Diag(Loc, PD);

1917

1918 for (auto [Loc, PD] : Notes)

1919 Diag(Loc, PD);

1920

1921 return Diag(VarLoc, diag::note_acc_reduction_type_summary);

1922 };

1923

1924

1925 if (IsValidMemberOfComposite(CurType)) {

1926

1928 if (!RD->isStruct() && !RD->isClass())

1929 return EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type)

1930 << RD

1931 << diag::OACCReductionTy::NotClassStruct);

1932

1933 if (!RD->isCompleteDefinition())

1934 return EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type)

1935 << RD << diag::OACCReductionTy::NotComplete);

1936

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

1938 CXXRD && !CXXRD->isAggregate())

1939 return EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type)

1940 << CXXRD << diag::OACCReductionTy::NotAgg);

1941

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

1943 if (!IsValidMemberOfComposite(FD->getType())) {

1945 PDiag(diag::note_acc_reduction_member_of_composite)

1946 << FD->getName() << RD->getName();

1947 Notes.push_back({FD->getBeginLoc(), PD});

1948

1949 return EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type)

1950 << FD->getType()

1951 << diag::OACCReductionTy::MemberNotScalar);

1952 }

1953 }

1954 } else {

1955 return EmitDiags(VarLoc, PDiag(diag::err_acc_reduction_type)

1956 << CurType

1957 << diag::OACCReductionTy::NotScalar);

1958 }

1959

1960 return false;

1961}

1962

1963

1964

1965

1966

1967

1968

1969

1972 Expr *VarExpr) {

1973

1974

1976

1979

1980

1981

1983

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

1986 break;

1987

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

1989 if (OldVarExpr->isInstantiationDependent())

1990 continue;

1991

1992 if (areVarsEqual(VarExpr, OldVarExpr)) {

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

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

1995 Diag(OldVarExpr->getExprLoc(), diag::note_acc_previous_clause_here)

1996 << RClause->getClauseKind();

1998 }

1999 }

2000 }

2001 }

2002

2003 return VarExpr;

2004}

2005

2007 if (!SizeExpr)

2009

2012 "size argument non integer?");

2013

2014

2018

2019 std::optionalllvm::APSInt ICE =

2021

2022

2023

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

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

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

2028 }

2029

2032}

2033

2035 if (!LoopCount)

2037

2040 "Loop argument non integer?");

2041

2042

2045

2046 std::optionalllvm::APSInt ICE =

2048

2049

2050

2051

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

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

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

2056 }

2057

2060}

2061

2066

2067

2068

2069

2070 switch (DK) {

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

2073 E);

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

2076 E);

2078 return CheckGangKernelsExpr(*this, ExistingClauses, DK,

2079 ActiveComputeConstructInfo.Kind, GK, E);

2081 return CheckGangRoutineExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK,

2082 E);

2084 switch (ActiveComputeConstructInfo.Kind) {

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

2089 GK, E);

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

2093 E);

2096 return CheckGangKernelsExpr(*this, ExistingClauses, DK,

2097 ActiveComputeConstructInfo.Kind, GK, E);

2098 default:

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

2100 }

2102

2103

2104

2105

2107 default:

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

2109 }

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

2111}

2112

2119

2121

2122

2123

2124 const auto *ReductionItr =

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

2126

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

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

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

2131 });

2132

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

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

2135

2138 "Improperly formed gang argument");

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

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

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

2142 << 0 << DirKind;

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

2144 diag::note_acc_previous_clause_here)

2145 << (*ReductionItr)->getClauseKind();

2146 return nullptr;

2147 }

2148 }

2149 }

2150 }

2151

2153 GangKinds, IntExprs, EndLoc);

2154}

2155

2164

2165

2166

2167 const auto GangClauses = llvm::make_filter_range(

2168 ExistingClauses, llvm::IsaPred);

2169

2170 for (auto *GC : GangClauses) {

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

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

2175 continue;

2176

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

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

2179 Diag(BeginLoc, diag::err_acc_gang_reduction_conflict)

2180 << 1 << DirectiveKind;

2181 Diag(GangClause->getBeginLoc(), diag::note_acc_previous_clause_here)

2182 << GangClause->getClauseKind();

2183 return nullptr;

2184 }

2185 }

2186 }

2187 }

2188

2190 getASTContext(), BeginLoc, LParenLoc, ReductionOp, Vars, Recipes, EndLoc);

2191 return Ret;

2192}

2193

2197

2198

2199

2202

2204

2205 for (Expr *VarExpr : VarExprs) {

2207 NewVarList.push_back(VarExpr);

2208 continue;

2209 }

2210

2211

2212

2213

2214

2216 NewVarList.push_back(VarExpr);

2217 continue;

2218 }

2219

2220 Expr *OrigExpr = VarExpr;

2221

2223 if (auto *ASE = dyn_cast(VarExpr))

2224 VarExpr = ASE->getBase()->IgnoreParenImpCasts();

2225 else

2226 VarExpr =

2228 }

2229

2231 const VarDecl *Var = dyn_cast(DRE->getDecl());

2232

2234 Diag(VarExpr->getBeginLoc(), diag::err_acc_link_not_extern);

2235 else

2236 NewVarList.push_back(OrigExpr);

2237 }

2238

2239 return NewVarList;

2240}

2243

2245 return false;

2246

2248

2249

2250

2251 bool IsSpecialClause =

2257

2258

2259

2260

2261

2263 return Diag(Clause.getBeginLoc(), diag::err_acc_declare_clause_at_global)

2264 << Clause.getClauseKind();

2265 }

2266

2269 for (Expr *VarExpr : Clause.getVarList()) {

2271

2272

2273 } else if (const auto *MemExpr = dyn_cast(VarExpr)) {

2275 cast(MemExpr->getMemberDecl()->getCanonicalDecl());

2276 CurDecl = FD;

2277

2278 if (removeLinkageSpecDC(

2280 Diag(MemExpr->getBeginLoc(), diag::err_acc_declare_same_scope)

2281 << Clause.getClauseKind();

2282 continue;

2283 }

2284 } else {

2285

2286 const Expr *VarExprTemp = VarExpr;

2287

2288 while (const auto *ASE = dyn_cast(VarExprTemp))

2290

2292 if (const auto *Var = dyn_cast(DRE->getDecl())) {

2294

2295

2296

2297

2298

2299

2300

2301

2302 if (removeLinkageSpecDC(

2303 Var->getLexicalDeclContext()->getPrimaryContext()) != DC) {

2304 Diag(VarExpr->getBeginLoc(), diag::err_acc_declare_same_scope)

2305 << Clause.getClauseKind();

2306 continue;

2307 }

2308

2309

2310

2311

2312 if (!IsSpecialClause && Var->hasExternalStorage()) {

2313 Diag(VarExpr->getBeginLoc(), diag::err_acc_declare_extern)

2314 << Clause.getClauseKind();

2315 continue;

2316 }

2317 }

2318

2319

2320

2321

2322

2323 if (CurDecl) {

2324 auto [Itr, Inserted] = DeclareVarReferences.try_emplace(CurDecl);

2325 if (!Inserted) {

2326 Diag(VarExpr->getBeginLoc(), diag::err_acc_multiple_references)

2327 << Clause.getClauseKind();

2328 Diag(Itr->second, diag::note_acc_previous_reference);

2329 continue;

2330 } else {

2331 Itr->second = VarExpr->getBeginLoc();

2332 }

2333 }

2334 }

2335 FilteredVarList.push_back(VarExpr);

2336 }

2337

2338 Clause.setVarListDetails(FilteredVarList, Mods);

2339 return false;

2340}

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

Defines the clang::Expr interface and subclasses for C++ expressions.

static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)

Produce a diagnostic highlighting some portion of a literal.

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],...

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

DeclContext - This is used only as base class of specific decl types that can act as declaration cont...

DeclContext * getParent()

getParent - Returns the containing DeclContext.

DeclContext * getPrimaryContext()

getPrimaryContext - There may be many different declarations of the same entity (including forward de...

DeclContext * getLexicalDeclContext()

getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).

virtual Decl * getCanonicalDecl()

Retrieves the "canonical" declaration of the given declaration.

Represents a ValueDecl that came out of a declarator.

This represents one expression.

Expr * IgnoreParenCasts() LLVM_READONLY

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

Expr * IgnoreParenImpCasts() LLVM_READONLY

Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...

std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const

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

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...

Represents a member of a struct/union/class.

StringRef getName() const

Return the actual identifier string.

IdentifierInfo * getIdentifierInfo() const

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)

static OpenACCBindClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, const IdentifierInfo *ID, 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, OpenACCModifierKind Mods, ArrayRef< Expr * > VarList, SourceLocation EndLoc)

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

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

static OpenACCCreateClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, OpenACCModifierKind Mods, 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)

static OpenACCDeviceResidentClause * 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.

ArrayRef< DeviceTypeArgument > getArchitectures() const

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, ArrayRef< OpenACCFirstPrivateRecipe > InitRecipes, 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 OpenACCLinkClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)

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

static OpenACCNoHostClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, 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, ArrayRef< OpenACCPrivateRecipe > InitRecipes, SourceLocation EndLoc)

static OpenACCReductionClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, OpenACCReductionOperator Operator, ArrayRef< Expr * > VarList, ArrayRef< OpenACCReductionRecipeWithStorage > Recipes, 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.

bool isNull() const

Return true if this QualType doesn't point to a type yet.

PartialDiagnostic PDiag(unsigned DiagID=0)

Build a partial diagnostic.

ASTContext & getASTContext() const

DeclContext * getCurContext() const

SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)

Emit a diagnostic.

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

void setVarListDetails(ArrayRef< Expr * > VarList, OpenACCModifierKind ModKind)

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

std::variant< std::monostate, clang::StringLiteral *, IdentifierInfo * > getBindDetails() const

SourceLocation getBeginLoc() const

SourceLocation getQueuesLoc() const

OpenACCModifierKind getModifierList() const

Expr * getDevNumExpr() const

ArrayRef< Expr * > getVarList()

unsigned getNumIntExprs() const

Expr * getLoopCount() const

OpenACCDefaultClauseKind getDefaultClauseKind() const

bool CheckDeclareClause(SemaOpenACC::OpenACCParsedClause &Clause, OpenACCModifierKind Mods)

Definition SemaOpenACCClause.cpp:2241

OpenACCPrivateRecipe CreatePrivateInitRecipe(const Expr *VarExpr)

ComputeConstructInfo & getActiveComputeConstructInfo()

ExprResult ActOnIntExpr(OpenACCDirectiveKind DK, OpenACCClauseKind CK, SourceLocation Loc, Expr *IntExpr)

Called when encountering an 'int-expr' for OpenACC, and manages conversions and diagnostics to 'int'.

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.

Definition SemaOpenACCClause.cpp:1854

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...

Definition SemaOpenACCClause.cpp:1970

llvm::SmallVector< Expr * > CheckLinkClauseVarList(ArrayRef< Expr * > VarExpr)

Definition SemaOpenACCClause.cpp:2195

ExprResult CheckCollapseLoopCount(Expr *LoopCount)

Checks the loop depth value for a collapse clause.

Definition SemaOpenACCClause.cpp:2034

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)

Definition SemaOpenACCClause.cpp:2063

OpenACCFirstPrivateRecipe CreateFirstPrivateInitRecipe(const Expr *VarExpr)

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

Definition SemaOpenACCClause.cpp:2114

bool CheckReductionVarType(Expr *VarExpr)

Definition SemaOpenACCClause.cpp:1879

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

Definition SemaOpenACCClause.cpp:2156

ExprResult CheckTileSizeExpr(Expr *SizeExpr)

Checks a single size expr for a tile clause.

Definition SemaOpenACCClause.cpp:2006

OpenACCReductionRecipeWithStorage CreateReductionInitRecipe(OpenACCReductionOperator ReductionOperator, const Expr *VarExpr)

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

SourceLocation getBeginLoc() const LLVM_READONLY

RecordDecl * getAsRecordDecl() const

Retrieves the RecordDecl this type refers to.

bool isIntegerType() const

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

Represents a variable declaration or definition.

bool hasExternalStorage() const

Returns true if a variable has extern or private_extern storage.

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

bool isa(CodeGen::Address addr)

bool isOpenACCComputeDirectiveKind(OpenACCDirectiveKind K)

bool isOpenACCCombinedDirectiveKind(OpenACCDirectiveKind K)

OpenACCClauseKind

Represents the kind of an OpenACC clause.

@ Auto

'auto' clause, allowed on 'loop' directives.

@ Bind

'bind' clause, allowed on routine constructs.

@ Gang

'gang' clause, allowed on 'loop' and Combined constructs.

@ Wait

'wait' clause, allowed on Compute, Data, 'update', and Combined constructs.

@ DevicePtr

'deviceptr' clause, allowed on Compute and Combined Constructs, plus 'data' and 'declare'.

@ VectorLength

'vector_length' clause, allowed on 'parallel', 'kernels', 'parallel loop', and 'kernels loop' constru...

@ Async

'async' clause, allowed on Compute, Data, 'update', 'wait', and Combined constructs.

@ Collapse

'collapse' clause, allowed on 'loop' and Combined constructs.

@ Invalid

Represents an invalid clause, for the purposes of parsing.

@ Vector

'vector' clause, allowed on 'loop', Combined, and 'routine' directives.

@ Worker

'worker' clause, allowed on 'loop', Combined, and 'routine' directives.

@ Create

'create' clause, allowed on Compute and Combined constructs, plus 'data', 'enter data',...

@ DeviceType

'device_type' clause, allowed on Compute, 'data', 'init', 'shutdown', 'set', update',...

@ NumGangs

'num_gangs' clause, allowed on 'parallel', 'kernels', parallel loop', and 'kernels loop' constructs.

@ Link

'link' clause, allowed on 'declare' construct.

@ Seq

'seq' clause, allowed on 'loop' and 'routine' directives.

@ Tile

'tile' clause, allowed on 'loop' and Combined constructs.

@ DeviceResident

'device_resident' clause, allowed on the 'declare' construct.

@ DType

'dtype' clause, an alias for 'device_type', stored separately for diagnostic purposes.

@ CopyIn

'copyin' clause, allowed on Compute and Combined constructs, plus 'data', 'enter data',...

@ Independent

'independent' clause, allowed on 'loop' directives.

@ NumWorkers

'num_workers' clause, allowed on 'parallel', 'kernels', parallel loop', and 'kernels loop' constructs...

IdentifierLoc DeviceTypeArgument

@ Result

The result type of a method or function.

bool isOpenACCModifierBitSet(OpenACCModifierKind List, OpenACCModifierKind Bit)

U cast(CodeGen::Address addr)

ActionResult< Expr * > ExprResult

OpenACCDirectiveKind DirKind