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

1

2

3

4

5

6

7

8

9

10

11

12

13

19#include "llvm/ADT/StringExtras.h"

20#include "llvm/Support/Casting.h"

21

22using namespace clang;

23

24namespace {

27 switch (K) {

28 default:

29 case OpenACCDirectiveKind::Invalid:

30

31

32 break;

33 case OpenACCDirectiveKind::ParallelLoop:

34 case OpenACCDirectiveKind::SerialLoop:

35 case OpenACCDirectiveKind::KernelsLoop:

36 case OpenACCDirectiveKind::Parallel:

37 case OpenACCDirectiveKind::Serial:

38 case OpenACCDirectiveKind::Kernels:

39 case OpenACCDirectiveKind::Loop:

40 case OpenACCDirectiveKind::Data:

41 case OpenACCDirectiveKind::EnterData:

42 case OpenACCDirectiveKind::ExitData:

43 case OpenACCDirectiveKind::HostData:

44 case OpenACCDirectiveKind::Wait:

45 if (!IsStmt)

46 return S.Diag(StartLoc, diag::err_acc_construct_appertainment) << K;

47 break;

48 }

49 return false;

50}

51

52void CollectActiveReductionClauses(

55 for (auto *CurClause : CurClauses) {

56 if (auto *RedClause = dyn_cast(CurClause);

57 RedClause && !RedClause->getVarList().empty())

58 ActiveClauses.push_back(RedClause);

59 }

60}

61

62

63

65 switch (DK) {

66 case OpenACCDirectiveKind::Parallel:

67 case OpenACCDirectiveKind::ParallelLoop:

68 case OpenACCDirectiveKind::Serial:

69 case OpenACCDirectiveKind::SerialLoop:

70 case OpenACCDirectiveKind::Kernels:

71 case OpenACCDirectiveKind::KernelsLoop:

72 case OpenACCDirectiveKind::Loop:

73 return false;

74 case OpenACCDirectiveKind::Data:

75 case OpenACCDirectiveKind::HostData:

76 return true;

77 case OpenACCDirectiveKind::EnterData:

78 case OpenACCDirectiveKind::ExitData:

79 case OpenACCDirectiveKind::Wait:

80 case OpenACCDirectiveKind::Init:

81 case OpenACCDirectiveKind::Shutdown:

82 case OpenACCDirectiveKind::Set:

83 case OpenACCDirectiveKind::Update:

84 llvm_unreachable("Doesn't have an associated stmt");

85 default:

86 case OpenACCDirectiveKind::Invalid:

87 llvm_unreachable("Unhandled directive kind?");

88 }

89 llvm_unreachable("Unhandled directive kind?");

90}

91

92}

93

95

100 : SemaRef(S), OldActiveComputeConstructInfo(S.ActiveComputeConstructInfo),

101 DirKind(DK), OldLoopGangClauseOnKernel(S.LoopGangClauseOnKernel),

102 OldLoopWorkerClauseLoc(S.LoopWorkerClauseLoc),

103 OldLoopVectorClauseLoc(S.LoopVectorClauseLoc),

104 OldLoopWithoutSeqInfo(S.LoopWithoutSeqInfo),

105 ActiveReductionClauses(S.ActiveReductionClauses),

106 LoopRAII(SemaRef, PreserveLoopRAIIDepthInAssociatedStmtRAII(DirKind)) {

107

108

112 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);

113 SemaRef.ActiveComputeConstructInfo.Kind = DirKind;

114 SemaRef.ActiveComputeConstructInfo.Clauses = Clauses;

115

116

117

118

119

120

121

129 SemaRef.ActiveComputeConstructInfo.Kind = DirKind;

130 SemaRef.ActiveComputeConstructInfo.Clauses = Clauses;

131

132 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);

135

139

140

141

143 if (Clauses.end() ==

144 llvm::find_if(Clauses, llvm::IsaPred))

146

147

148

149

150

151

152

153

154

156

157 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred);

158 if (Itr != Clauses.end())

160 }

161

162 if (UnInstClauses.empty()) {

163 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred);

164 if (Itr != Clauses.end())

166

167 auto *Itr2 = llvm::find_if(Clauses, llvm::IsaPred);

168 if (Itr2 != Clauses.end())

170 }

172 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses);

175

176

177

179 if (Clauses.end() ==

180 llvm::find_if(Clauses, llvm::IsaPred))

182

183

184

185

186

187

188

189

190

193 UnInstClauses.empty()) {

194

195 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred);

196 if (Itr != Clauses.end())

199 }

200

201 if (UnInstClauses.empty()) {

202 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred);

203 if (Itr != Clauses.end())

205

206 auto *Itr2 = llvm::find_if(Clauses, llvm::IsaPred);

207 if (Itr2 != Clauses.end())

209 }

210 }

211}

212

216

217

218 SemaRef.LoopInfo.CurLevelHasLoopAlready = false;

219 SemaRef.CollapseInfo.CollapseDepthSatisfied = true;

220 SemaRef.TileInfo.TileDepthSatisfied = true;

221

222

223

224

225

226

227 auto *CollapseClauseItr =

228 llvm::find_if(Clauses, llvm::IsaPred);

229 auto *UnInstCollapseClauseItr =

230 llvm::find_if(UnInstClauses, llvm::IsaPred);

231

232 if (Clauses.end() == CollapseClauseItr)

233 return;

234

236 cast(*CollapseClauseItr);

237

238 SemaRef.CollapseInfo.ActiveCollapse = CollapseClause;

240

241

242

244 return;

245

246

247

248 if (UnInstCollapseClauseItr != UnInstClauses.end() &&

249 !cast(*UnInstCollapseClauseItr)

250 ->getLoopCount()

251 ->isInstantiationDependent())

252 return;

253

254 SemaRef.CollapseInfo.CollapseDepthSatisfied = false;

255 SemaRef.CollapseInfo.CurCollapseCount =

256 cast(LoopCount)->getResultAsAPSInt();

257 SemaRef.CollapseInfo.DirectiveKind = DirKind;

258}

259

263

264

265

266 if (UnInstClauses.size() > 0)

267 return;

268 auto *TileClauseItr =

269 llvm::find_if(Clauses, llvm::IsaPred);

270

271 if (Clauses.end() == TileClauseItr)

272 return;

273

274 OpenACCTileClause *TileClause = cast(*TileClauseItr);

275 SemaRef.TileInfo.ActiveTile = TileClause;

276 SemaRef.TileInfo.TileDepthSatisfied = false;

278 SemaRef.TileInfo.DirectiveKind = DirKind;

279}

280

289 SemaRef.ActiveComputeConstructInfo = OldActiveComputeConstructInfo;

290 SemaRef.LoopGangClauseOnKernel = OldLoopGangClauseOnKernel;

291 SemaRef.LoopWorkerClauseLoc = OldLoopWorkerClauseLoc;

292 SemaRef.LoopVectorClauseLoc = OldLoopVectorClauseLoc;

293 SemaRef.LoopWithoutSeqInfo = OldLoopWithoutSeqInfo;

294 SemaRef.ActiveReductionClauses.swap(ActiveReductionClauses);

297

298

299 }

300}

301

304

307

308 switch (K) {

310

311

312

313

314 break;

330

331

332 break;

334

335

336 break;

337 default:

338 Diag(DirLoc, diag::warn_acc_construct_unimplemented) << K;

339 break;

340 }

341}

342

345 Expr *IntExpr) {

346

353 "Only one of directive or clause kind should be provided");

354

358 Expr *IntExpr;

359

360

361

362 unsigned getDiagKind() const {

363 if (ClauseKind != OpenACCClauseKind::Invalid)

364 return 0;

365 if (DirectiveKind != OpenACCDirectiveKind::Invalid)

366 return 1;

367 return 2;

368 }

369

370 public:

372 Expr *IntExpr)

373 : ICEConvertDiagnoser(false,

374 false,

375 true),

376 DirectiveKind(DK), ClauseKind(CK), IntExpr(IntExpr) {}

377

379

380

382 }

385 return S.Diag(Loc, diag::err_acc_int_expr_requires_integer)

386 << getDiagKind() << ClauseKind << DirectiveKind << T;

387 }

388

391 return S.Diag(Loc, diag::err_acc_int_expr_incomplete_class_type)

393 }

394

398 return S.Diag(Loc, diag::err_acc_int_expr_explicit_conversion)

399 << T << ConvTy;

400 }

401

405 return S.Diag(Conv->getLocation(), diag::note_acc_int_expr_conversion)

407 }

408

411 return S.Diag(Loc, diag::err_acc_int_expr_multiple_conversions) << T;

412 }

413

416 return S.Diag(Conv->getLocation(), diag::note_acc_int_expr_conversion)

418 }

419

423 llvm_unreachable("conversion functions are permitted");

424 }

425 } IntExprDiagnoser(DK, CK, IntExpr);

426

427 if (!IntExpr)

429

431 Loc, IntExpr, IntExprDiagnoser);

434

435 IntExpr = IntExprResult.get();

438

439

440

441 return IntExpr;

442}

443

445 Expr *VarExpr) {

446

447

448

449

450

452 return false;

453

456 Diag(VarExpr->getExprLoc(), diag::err_array_section_use) << 0;

457 Diag(VarExpr->getExprLoc(), diag::note_acc_expected_pointer_var);

458 return true;

459 }

460

463

464

466 return false;

467

469 return Diag(VarExpr->getExprLoc(), diag::err_acc_var_not_pointer_type)

470 << ClauseKind << Ty;

471 return false;

472}

473

476

477

478

479

481 isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {

482 Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref_use_device);

484 }

485

486

487

488 while (isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {

489 if (auto *SubScrpt = dyn_cast(CurVarExpr))

491 else

492 CurVarExpr =

494 }

495

496

497 if (const auto *DRE = dyn_cast(CurVarExpr)) {

498 if (isa<VarDecl, NonTypeTemplateParmDecl>(

499 DRE->getFoundDecl()->getCanonicalDecl()))

500 return VarExpr;

501 }

502

503

504

505

506

507

508

511 if (const auto *ME = dyn_cast(CurVarExpr)) {

512 if (isa(ME->getMemberDecl()->getCanonicalDecl()))

513 return VarExpr;

514 }

515 }

516

517

518

520 return VarExpr;

521

522

523

524 if (isa(CurVarExpr) ||

526 isa(CurVarExpr)))

527 return VarExpr;

528

529

530

531 if (isa(CurVarExpr))

533

535 Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref_use_device);

536 else

537 Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref)

540}

541

543 Expr *LowerBound,

545 Expr *Length,

548

549

550 if (Base->hasPlaceholderType() &&

551 Base->hasPlaceholderType(BuiltinType::ArraySection)) {

553 if (Result.isInvalid())

556 }

559 if (Result.isInvalid())

562 if (Result.isInvalid())

564 LowerBound = Result.get();

565 }

566 if (Length && Length->getType()->isNonOverloadPlaceholderType()) {

568 if (Result.isInvalid())

571 if (Result.isInvalid())

573 Length = Result.get();

574 }

575

576

577

580 if (Base->isTypeDependent()) {

583 } else if (OriginalBaseTy->isArrayType()) {

585 } else {

587 Diag(Base->getExprLoc(), diag::err_acc_typecheck_subarray_value)

588 << Base->getSourceRange());

589 }

590

592 Diag(Base->getExprLoc(), diag::err_acc_subarray_function_type)

593 << ResultTy << Base->getSourceRange();

595 }

596

598 diag::err_acc_subarray_incomplete_type,

601

602 if (Base->hasPlaceholderType(BuiltinType::ArraySection)) {

604 if (Result.isInvalid())

607 }

608 }

609

613 return Recovery.isUsable() ? Recovery.get() : nullptr;

614 };

615

616

620 LowerBound->getExprLoc(), LowerBound);

621

624 LowerBound =

625 LBRes.isUsable() ? LBRes.get() : GetRecovery(LowerBound, Context.IntTy);

626 }

627

628 if (Length && !Length->isTypeDependent()) {

631 Length->getExprLoc(), Length);

632

635 Length =

636 LenRes.isUsable() ? LenRes.get() : GetRecovery(Length, Context.IntTy);

637 }

638

639

640 if (!Length && (OriginalBaseTy.isNull() ||

644 bool IsArray = !OriginalBaseTy.isNull() && OriginalBaseTy->isArrayType();

645 Diag(ColonLoc, diag::err_acc_subarray_no_length) << IsArray;

646

647

650 Length = Recovery.isUsable() ? Recovery.get() : nullptr;

651 }

652

653

654

655

656

657

658

659

660

661 std::optionalllvm::APSInt BaseSize;

664 BaseSize = ArrayTy->getSize();

665 }

666

667 auto GetBoundValue = [&](Expr *E) -> std::optionalllvm::APSInt {

669 return std::nullopt;

670

673 return std::nullopt;

675 };

676

677 std::optionalllvm::APSInt LowerBoundValue = GetBoundValue(LowerBound);

678 std::optionalllvm::APSInt LengthValue = GetBoundValue(Length);

679

680

681 if (LowerBoundValue.has_value()) {

682 if (LowerBoundValue->isNegative()) {

683 Diag(LowerBound->getExprLoc(), diag::err_acc_subarray_negative)

684 << 0 << toString(*LowerBoundValue, 10);

685 LowerBoundValue.reset();

686 LowerBound = GetRecovery(LowerBound, LowerBound->getType());

687 } else if (BaseSize.has_value() &&

688 llvm::APSInt::compareValues(*LowerBoundValue, *BaseSize) >= 0) {

689

690 Diag(LowerBound->getExprLoc(), diag::err_acc_subarray_out_of_range)

691 << 0 << toString(*LowerBoundValue, 10)

692 << toString(*BaseSize, 10);

693 LowerBoundValue.reset();

694 LowerBound = GetRecovery(LowerBound, LowerBound->getType());

695 }

696 }

697

698

699 if (LengthValue.has_value()) {

700 if (LengthValue->isNegative()) {

701 Diag(Length->getExprLoc(), diag::err_acc_subarray_negative)

702 << 1 << toString(*LengthValue, 10);

703 LengthValue.reset();

704 Length = GetRecovery(Length, Length->getType());

705 } else if (BaseSize.has_value() &&

706 llvm::APSInt::compareValues(*LengthValue, *BaseSize) > 0) {

707

708 Diag(Length->getExprLoc(), diag::err_acc_subarray_out_of_range)

709 << 1 << toString(*LengthValue, 10)

710 << toString(*BaseSize, 10);

711 LengthValue.reset();

712 Length = GetRecovery(Length, Length->getType());

713 }

714 }

715

716

717 auto AddAPSInt = [](llvm::APSInt LHS, llvm::APSInt RHS) -> llvm::APSInt {

718 if (LHS.isSigned() == RHS.isSigned())

719 return LHS + RHS;

720

721 unsigned Width = std::max(LHS.getBitWidth(), RHS.getBitWidth()) + 1;

722 return llvm::APSInt(LHS.sext(Width) + RHS.sext(Width), true);

723 };

724

725

726

727 if (BaseSize.has_value() && LowerBoundValue.has_value() &&

728 LengthValue.has_value() &&

729 llvm::APSInt::compareValues(AddAPSInt(*LowerBoundValue, *LengthValue),

730 *BaseSize) > 0) {

732 diag::err_acc_subarray_base_plus_length_out_of_range)

733 << toString(*LowerBoundValue, 10)

734 << toString(*LengthValue, 10)

735 << toString(*BaseSize, 10);

736

737 LowerBoundValue.reset();

738 LowerBound = GetRecovery(LowerBound, LowerBound->getType());

739 LengthValue.reset();

740 Length = GetRecovery(Length, Length->getType());

741 }

742

743

745 if (Base->isTypeDependent() ||

747 (Length && Length->isInstantiationDependent()))

749

750 return new (Context)

753}

754

757 return;

758

759 if (!LoopInfo.TopLevelLoopSeen)

760 return;

761

762 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {

763 Diag(WhileLoc, diag::err_acc_invalid_in_loop)

764 << 1 << CollapseInfo.DirectiveKind

766 assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");

767 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),

768 diag::note_acc_active_clause_here)

770

771

772

773 CollapseInfo.CurCollapseCount = std::nullopt;

774 }

775

776 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {

777 Diag(WhileLoc, diag::err_acc_invalid_in_loop)

778 << 1 << TileInfo.DirectiveKind

780 assert(TileInfo.ActiveTile && "tile count without object?");

781 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)

783

784

785

786 TileInfo.CurTileCount = std::nullopt;

787 }

788}

789

792 return;

793

794 if (!LoopInfo.TopLevelLoopSeen)

795 return;

796

797 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {

798 Diag(DoLoc, diag::err_acc_invalid_in_loop)

799 << 2 << CollapseInfo.DirectiveKind

801 assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");

802 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),

803 diag::note_acc_active_clause_here)

805

806

807

808 CollapseInfo.CurCollapseCount = std::nullopt;

809 }

810

811 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {

812 Diag(DoLoc, diag::err_acc_invalid_in_loop)

814 assert(TileInfo.ActiveTile && "tile count without object?");

815 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)

817

818

819

820 TileInfo.CurTileCount = std::nullopt;

821 }

822}

823

824void SemaOpenACC::ForStmtBeginHelper(SourceLocation ForLoc,

825 ForStmtBeginChecker &C) {

826 assert(getLangOpts().OpenACC && "Check enabled when not OpenACC?");

827

828

829 LoopInfo.TopLevelLoopSeen = true;

830

831 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {

832 C.check();

833

834

835

836

837

838

839 if (LoopInfo.CurLevelHasLoopAlready) {

840 Diag(ForLoc, diag::err_acc_clause_multiple_loops)

842 assert(CollapseInfo.ActiveCollapse && "No collapse object?");

843 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),

844 diag::note_acc_active_clause_here)

846 } else {

847 --(*CollapseInfo.CurCollapseCount);

848

849

850

851 if (*CollapseInfo.CurCollapseCount == 0)

852 CollapseInfo.CollapseDepthSatisfied = true;

853 }

854 }

855

856 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {

857 C.check();

858

859 if (LoopInfo.CurLevelHasLoopAlready) {

860 Diag(ForLoc, diag::err_acc_clause_multiple_loops)

862 assert(TileInfo.ActiveTile && "No tile object?");

863 Diag(TileInfo.ActiveTile->getBeginLoc(),

864 diag::note_acc_active_clause_here)

866 } else {

867 --(*TileInfo.CurTileCount);

868

869

870 if (*TileInfo.CurTileCount == 0)

871 TileInfo.TileDepthSatisfied = true;

872 }

873 }

874

875

876

877 LoopInfo.CurLevelHasLoopAlready = false;

878}

879

880namespace {

881bool isValidLoopVariableType(QualType LoopVarTy) {

882

884 return true;

885

886

888 return true;

889

890

892 return true;

893

894

896

897

898

899

900

901

902

903

904 for (const auto *TD :

905 llvm::make_filter_range(RD->decls(), llvm::IsaPred)) {

906 const auto *TDND = cast(TD)->getCanonicalDecl();

907

908 if (TDND->getName() != "iterator_category")

909 continue;

910

911

912 if (TDND->getUnderlyingType().isNull())

913 return false;

914

916 TDND->getUnderlyingType()->getAsCXXRecordDecl();

917

918

919 if (!ItrCategoryDecl)

920 return false;

921

922 auto IsRandomAccessIteratorTag = [](const CXXRecordDecl *RD) {

923 if (RD->getName() != "random_access_iterator_tag")

924 return false;

925

927 };

928

929 if (IsRandomAccessIteratorTag(ItrCategoryDecl))

930 return true;

931

932

933

935

936 if (IsRandomAccessIteratorTag(BS.getType()->getAsCXXRecordDecl()))

937 return true;

938 }

939

940 return false;

941 }

942 }

943

944 return false;

945}

946

947}

948

949void SemaOpenACC::ForStmtBeginChecker::check() {

951 return;

952

953 if (AlreadyChecked)

954 return;

955 AlreadyChecked = true;

956

957

958

959

960

961

962

963

964

965

966

967

968

969

970

971

972 if (IsRangeFor) {

973

974

975 if (!RangeFor.has_value())

976 return;

977

978

979 const DeclStmt *RangeStmt = (*RangeFor)->getBeginStmt();

980

981

982

983 if (!RangeStmt)

984 return;

985

988 if (!isValidLoopVariableType(VarType)) {

990 << SemaRef.LoopWithoutSeqInfo.Kind << VarType;

992 diag::note_acc_construct_here)

993 << SemaRef.LoopWithoutSeqInfo.Kind;

994 }

995 return;

996 }

997

998

999

1000

1001 const ValueDecl *InitVar = checkInit();

1002 if (Cond.has_value())

1003 checkCond();

1004 if (Inc.has_value())

1005 checkInc(InitVar);

1006}

1007const ValueDecl *SemaOpenACC::ForStmtBeginChecker::checkInit() {

1008 if (Init) {

1009 if (InitChanged) {

1010 SemaRef.Diag(ForLoc, diag::err_acc_loop_variable)

1011 << SemaRef.LoopWithoutSeqInfo.Kind;

1013 diag::note_acc_construct_here)

1014 << SemaRef.LoopWithoutSeqInfo.Kind;

1015 }

1016 return nullptr;

1017 }

1018

1019 auto DiagLoopVar = [&]() {

1020 if (InitChanged) {

1021 SemaRef.Diag(Init->getBeginLoc(), diag::err_acc_loop_variable)

1022 << SemaRef.LoopWithoutSeqInfo.Kind;

1024 diag::note_acc_construct_here)

1025 << SemaRef.LoopWithoutSeqInfo.Kind;

1026 }

1027 return nullptr;

1028 };

1029

1030 if (const auto *ExprTemp = dyn_cast(Init))

1031 Init = ExprTemp->getSubExpr();

1032 if (const auto *E = dyn_cast(Init))

1034

1035 const ValueDecl *InitVar = nullptr;

1036

1037 if (const auto *BO = dyn_cast(Init)) {

1038

1039

1040 if (!BO->isAssignmentOp())

1041 return DiagLoopVar();

1042

1044

1045 if (const auto *DRE = dyn_cast(LHS))

1046 InitVar = DRE->getDecl();

1047 } else if (const auto *DS = dyn_cast(Init)) {

1048

1049 if (!DS->isSingleDecl())

1050 return DiagLoopVar();

1051

1052 InitVar = dyn_cast(DS->getSingleDecl());

1053

1054

1055

1056 if (InitVar) {

1057 if (!isa(InitVar))

1058 return DiagLoopVar();

1059

1062 !cast(InitVar)->hasInit())

1063 return DiagLoopVar();

1064 }

1065 } else if (auto *CE = dyn_cast(Init)) {

1066

1067 if (CE->getOperator() != OO_Equal)

1068 return DiagLoopVar();

1069

1071

1072 if (auto *DRE = dyn_cast(LHS)) {

1073 InitVar = DRE->getDecl();

1074 } else if (auto *ME = dyn_cast(LHS)) {

1075 if (isa(ME->getBase()->IgnoreParenImpCasts()))

1076 InitVar = ME->getMemberDecl();

1077 }

1078 }

1079

1080 if (!InitVar)

1081 return DiagLoopVar();

1082

1085

1086

1087 if (!isValidLoopVariableType(VarType)) {

1088 if (InitChanged) {

1090 << SemaRef.LoopWithoutSeqInfo.Kind << VarType;

1092 diag::note_acc_construct_here)

1093 << SemaRef.LoopWithoutSeqInfo.Kind;

1094 }

1095 return nullptr;

1096 }

1097

1098 return InitVar;

1099}

1100void SemaOpenACC::ForStmtBeginChecker::checkCond() {

1101 if (!*Cond) {

1102 SemaRef.Diag(ForLoc, diag::err_acc_loop_terminating_condition)

1103 << SemaRef.LoopWithoutSeqInfo.Kind;

1104 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc, diag::note_acc_construct_here)

1105 << SemaRef.LoopWithoutSeqInfo.Kind;

1106 }

1107

1108

1109

1110

1111

1112}

1113

1114void SemaOpenACC::ForStmtBeginChecker::checkInc(const ValueDecl *Init) {

1115

1116 if (!*Inc) {

1117 SemaRef.Diag(ForLoc, diag::err_acc_loop_not_monotonic)

1118 << SemaRef.LoopWithoutSeqInfo.Kind;

1119 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc, diag::note_acc_construct_here)

1120 << SemaRef.LoopWithoutSeqInfo.Kind;

1121 return;

1122 }

1123 auto DiagIncVar = [this] {

1124 SemaRef.Diag((*Inc)->getBeginLoc(), diag::err_acc_loop_not_monotonic)

1125 << SemaRef.LoopWithoutSeqInfo.Kind;

1126 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc, diag::note_acc_construct_here)

1127 << SemaRef.LoopWithoutSeqInfo.Kind;

1128 return;

1129 };

1130

1131 if (const auto *ExprTemp = dyn_cast(*Inc))

1132 Inc = ExprTemp->getSubExpr();

1133 if (const auto *E = dyn_cast(*Inc))

1135

1138 if (const auto *FE = dyn_cast(E))

1139 E = FE->getSubExpr();

1140

1142

1143 if (E)

1144 return nullptr;

1145 if (const auto *DRE = dyn_cast(E))

1146 return dyn_cast(DRE->getDecl());

1147

1148 if (const auto *ME = dyn_cast(E))

1149 if (isa(ME->getBase()->IgnoreParenImpCasts()))

1150 return ME->getMemberDecl();

1151

1152 return nullptr;

1153 };

1154

1155 const ValueDecl *IncVar = nullptr;

1156

1157

1158 if (const auto *UO = dyn_cast(*Inc)) {

1159

1160 if (!UO->isIncrementDecrementOp())

1161 return DiagIncVar();

1163 } else if (const auto *BO = dyn_cast(*Inc)) {

1164 switch (BO->getOpcode()) {

1165 default:

1166 return DiagIncVar();

1167 case BO_AddAssign:

1168 case BO_SubAssign:

1169 case BO_MulAssign:

1170 case BO_DivAssign:

1171 case BO_Assign:

1172

1173

1174

1175

1176

1177 break;

1178 }

1180 } else if (const auto *CE = dyn_cast(*Inc)) {

1181 switch (CE->getOperator()) {

1182 default:

1183 return DiagIncVar();

1184 case OO_PlusPlus:

1185 case OO_MinusMinus:

1186 case OO_PlusEqual:

1187 case OO_MinusEqual:

1188 case OO_StarEqual:

1189 case OO_SlashEqual:

1190 case OO_Equal:

1191

1192

1193

1194

1195

1196 break;

1197 }

1198

1200

1201 } else if (const auto *ME = dyn_cast(*Inc)) {

1202 IncVar = getDeclFromExpr(ME->getImplicitObjectArgument());

1203

1204

1205 }

1206

1207 if (!IncVar)

1208 return DiagIncVar();

1209

1210

1211

1212

1214 return DiagIncVar();

1215

1216 return;

1217}

1218

1221 const Stmt *Second, const Stmt *OldThird,

1222 const Stmt *Third) {

1224 return;

1225

1226 std::optional<const Stmt *> S;

1227 if (OldSecond == Second)

1228 S = std::nullopt;

1229 else

1230 S = Second;

1231 std::optional<const Stmt *> T;

1232 if (OldThird == Third)

1233 S = std::nullopt;

1234 else

1235 S = Third;

1236

1237 bool InitChanged = false;

1238 if (OldFirst != First) {

1239 InitChanged = true;

1240

1241

1242

1243

1246 if (const auto *DS = dyn_cast(OldFirst))

1247 if (const VarDecl *VD = dyn_cast_if_present(

1248 DS->isSingleDecl() ? DS->getSingleDecl() : nullptr))

1249 OldVDTy = VD->getType();

1250 if (const auto *DS = dyn_cast(First))

1251 if (const VarDecl *VD = dyn_cast_if_present(

1252 DS->isSingleDecl() ? DS->getSingleDecl() : nullptr))

1253 NewVDTy = VD->getType();

1254

1258 }

1259

1260 ForStmtBeginChecker FSBC{*this, ForLoc, First, InitChanged, S, T};

1261 if (!LoopInfo.TopLevelLoopSeen) {

1262 FSBC.check();

1263 }

1264

1265 ForStmtBeginHelper(ForLoc, FSBC);

1266}

1267

1269 const Stmt *Second, const Stmt *Third) {

1271 return;

1272

1273 ForStmtBeginChecker FSBC{*this, ForLoc, First, true,

1274 Second, Third};

1275 if (!LoopInfo.TopLevelLoopSeen) {

1276 FSBC.check();

1277 }

1278

1279 ForStmtBeginHelper(ForLoc, FSBC);

1280}

1281

1283 const Stmt *OldRangeFor,

1284 const Stmt *RangeFor) {

1286 return;

1287

1288 std::optional<const CXXForRangeStmt *> RF;

1289

1290 if (OldRangeFor == RangeFor)

1291 RF = std::nullopt;

1292 else

1293 RF = cast(RangeFor);

1294

1295 ForStmtBeginChecker FSBC{*this, ForLoc, RF};

1296 if (!LoopInfo.TopLevelLoopSeen) {

1297 FSBC.check();

1298 }

1299 ForStmtBeginHelper(ForLoc, FSBC);

1300}

1301

1303 const Stmt *RangeFor) {

1305 return;

1306

1307 ForStmtBeginChecker FSBC{*this, ForLoc, cast(RangeFor)};

1308 if (!LoopInfo.TopLevelLoopSeen) {

1309 FSBC.check();

1310 }

1311 ForStmtBeginHelper(ForLoc, FSBC);

1312}

1313

1314namespace {

1316

1317

1318

1319

1320 if (!CurStmt ||

1321 isa<ForStmt, NullStmt, ForStmt, CXXForRangeStmt, WhileStmt, DoStmt>(

1322 CurStmt))

1324

1325

1326 if (isa(CurStmt))

1328

1329

1330

1331 if (const auto *CS = dyn_cast(CurStmt)) {

1332 for (const auto *ChildStmt : CS->children()) {

1333 SourceLocation ChildStmtLoc = FindInterveningCodeInLoop(ChildStmt);

1334 if (ChildStmtLoc.isValid())

1335 return ChildStmtLoc;

1336 }

1337

1339 }

1341}

1342}

1343

1346 return;

1347

1348

1349 LoopInfo.CurLevelHasLoopAlready = true;

1350

1352 return;

1353

1354 bool IsActiveCollapse = CollapseInfo.CurCollapseCount &&

1355 *CollapseInfo.CurCollapseCount > 0 &&

1356 !CollapseInfo.ActiveCollapse->hasForce();

1357 bool IsActiveTile = TileInfo.CurTileCount && *TileInfo.CurTileCount > 0;

1358

1359 if (IsActiveCollapse || IsActiveTile) {

1360 SourceLocation OtherStmtLoc = FindInterveningCodeInLoop(Body.get());

1361

1362 if (OtherStmtLoc.isValid() && IsActiveCollapse) {

1363 Diag(OtherStmtLoc, diag::err_acc_intervening_code)

1365 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),

1366 diag::note_acc_active_clause_here)

1368 }

1369

1370 if (OtherStmtLoc.isValid() && IsActiveTile) {

1371 Diag(OtherStmtLoc, diag::err_acc_intervening_code)

1373 Diag(TileInfo.ActiveTile->getBeginLoc(),

1374 diag::note_acc_active_clause_here)

1376 }

1377 }

1378}

1379

1380namespace {

1381

1382

1384 assert(!Clauses.empty() && "empty clause list not supported");

1385

1386 std::string Output;

1387 llvm::raw_string_ostream OS{Output};

1388

1389 if (Clauses.size() == 1) {

1390 OS << '\'' << Clauses[0] << '\'';

1391 return Output;

1392 }

1393

1395 Clauses.end() - 1};

1396

1397 llvm::interleave(

1398 AllButLast, [&](OpenACCClauseKind K) { OS << '\'' << K << '\''; },

1399 [&] { OS << ", "; });

1400

1401 OS << " or \'" << Clauses.back() << '\'';

1402 return Output;

1403}

1404}

1405

1411

1412

1413

1414

1415

1416

1417 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) {

1418 Diag(StartLoc, diag::err_acc_invalid_in_loop)

1419 << 0 << CollapseInfo.DirectiveKind

1421 assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");

1422 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),

1423 diag::note_acc_active_clause_here)

1425 }

1426 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) {

1427 Diag(StartLoc, diag::err_acc_invalid_in_loop)

1428 << 0 << TileInfo.DirectiveKind

1430 assert(TileInfo.ActiveTile && "Tile count without object?");

1431 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here)

1433 }

1434

1435

1436

1437

1439 llvm::find_if(Clauses,

1445 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)

1446 << K

1447 << GetListOfClauses(

1453

1454

1455

1457 llvm::find_if(Clauses,

1460 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)

1461 << K

1462 << GetListOfClauses({

1466 });

1467

1468

1470 llvm::find_if(Clauses,

1473 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)

1474 << K

1475 << GetListOfClauses({

1479 });

1480

1481

1483 llvm::find_if(Clauses, llvm::IsaPred) ==

1484 Clauses.end())

1485 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)

1487

1488

1489

1491 llvm::find_if(

1492 Clauses,

1495 Clauses.end())

1496 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)

1497 << K

1502

1503

1504

1508 Clauses.end())

1509 return Diag(StartLoc, diag::err_acc_construct_one_clause_of)

1510 << K

1514

1515 return diagnoseConstructAppertainment(*this, K, StartLoc, true);

1516}

1517

1523 switch (K) {

1524 default:

1532 getASTContext(), K, StartLoc, DirLoc, EndLoc, Clauses,

1533 AssocStmt.isUsable() ? AssocStmt.get() : nullptr);

1534 }

1539 getASTContext(), K, StartLoc, DirLoc, EndLoc, Clauses,

1540 AssocStmt.isUsable() ? AssocStmt.get() : nullptr);

1541 }

1544 getASTContext(), ActiveComputeConstructInfo.Kind, StartLoc, DirLoc,

1545 EndLoc, Clauses, AssocStmt.isUsable() ? AssocStmt.get() : nullptr);

1546 }

1549 getASTContext(), StartLoc, DirLoc, EndLoc, Clauses,

1550 AssocStmt.isUsable() ? AssocStmt.get() : nullptr);

1551 }

1554 EndLoc, Clauses);

1555 }

1558 EndLoc, Clauses);

1559 }

1562 getASTContext(), StartLoc, DirLoc, EndLoc, Clauses,

1563 AssocStmt.isUsable() ? AssocStmt.get() : nullptr);

1564 }

1567 getASTContext(), StartLoc, DirLoc, LParenLoc, Exprs.front(), MiscLoc,

1568 Exprs.drop_front(), RParenLoc, EndLoc, Clauses);

1569 }

1572 EndLoc, Clauses);

1573 }

1576 EndLoc, Clauses);

1577 }

1580 EndLoc, Clauses);

1581 }

1584 EndLoc, Clauses);

1585 }

1586 }

1587 llvm_unreachable("Unhandled case in directive handling?");

1588}

1589

1593 switch (K) {

1594 default:

1595 llvm_unreachable("Unimplemented associated statement application");

1602 llvm_unreachable(

1603 "these don't have associated statements, so shouldn't get here");

1609

1610

1611

1612

1613

1614

1615

1616

1617

1618 return AssocStmt;

1625

1626 if (!isa<CXXForRangeStmt, ForStmt>(AssocStmt.get())) {

1627 Diag(AssocStmt.get()->getBeginLoc(), diag::err_acc_loop_not_for_loop)

1628 << K;

1629 Diag(DirectiveLoc, diag::note_acc_construct_here) << K;

1631 }

1632

1633 if (!CollapseInfo.CollapseDepthSatisfied || !TileInfo.TileDepthSatisfied) {

1634 if (!CollapseInfo.CollapseDepthSatisfied) {

1635 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)

1637 assert(CollapseInfo.ActiveCollapse && "Collapse count without object?");

1638 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(),

1639 diag::note_acc_active_clause_here)

1641 }

1642

1643 if (!TileInfo.TileDepthSatisfied) {

1644 Diag(DirectiveLoc, diag::err_acc_insufficient_loops)

1646 assert(TileInfo.ActiveTile && "Collapse count without object?");

1647 Diag(TileInfo.ActiveTile->getBeginLoc(),

1648 diag::note_acc_active_clause_here)

1650 }

1652 }

1653

1654 return AssocStmt.get();

1655 }

1656 llvm_unreachable("Invalid associated statement application");

1657}

1658

1661

1662

1663

1666 return diagnoseConstructAppertainment(*this, K, StartLoc, false);

1667}

1668

1670

1674}

1675

1679}

Defines some OpenACC-specific enums and functions.

static std::string toString(const clang::SanitizerSet &Sanitizers)

Produce a string containing comma-separated names of sanitizers in Sanitizers set.

static NamedDecl * getDeclFromExpr(Expr *E)

This file declares semantic analysis for OpenACC constructs and clauses.

This file defines OpenACC AST classes for statement-level contructs.

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

const ConstantArrayType * getAsConstantArrayType(QualType T) const

CanQualType ArraySectionTy

This class represents BOTH the OpenMP Array Section and OpenACC 'subarray', with a boolean differenti...

static QualType getBaseOriginalType(const Expr *Base)

Return original type of the base expression for array section.

QualType getElementType() const

Represents a base class of a C++ class.

Represents a C++ conversion function within a class.

Represents a C++ struct/union/class.

llvm::APInt getSize() const

Return the constant array size as an APInt.

bool isStdNamespace() const

DeclContext * getEnclosingNamespaceContext()

Retrieve the nearest enclosing namespace context.

DeclStmt - Adaptor class for mixing declarations with statements and expressions.

const Decl * getSingleDecl() const

SourceLocation getLocation() const

SourceLocation getBeginLoc() const LLVM_READONLY

virtual Decl * getCanonicalDecl()

Retrieves the "canonical" declaration of the given declaration.

This represents one expression.

bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const

EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...

bool isTypeDependent() const

Determines whether the type of this expression depends on.

Expr * IgnoreParenImpCasts() LLVM_READONLY

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

bool containsErrors() const

Whether this expression contains subexpressions which had errors, e.g.

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

bool hasPlaceholderType() const

Returns whether this expression has a placeholder type.

static OpenACCAsteriskSizeExpr * Create(const ASTContext &C, SourceLocation Loc)

Represents a 'collapse' clause on a 'loop' construct.

const Expr * getLoopCount() const

static OpenACCCombinedConstruct * Create(const ASTContext &C, OpenACCDirectiveKind K, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses, Stmt *StructuredBlock)

static OpenACCComputeConstruct * Create(const ASTContext &C, OpenACCDirectiveKind K, SourceLocation BeginLoc, SourceLocation DirectiveLoc, SourceLocation EndLoc, ArrayRef< const OpenACCClause * > Clauses, Stmt *StructuredBlock)

static OpenACCDataConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses, Stmt *StructuredBlock)

A 'default' clause, has the optional 'none' or 'present' argument.

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

static OpenACCEnterDataConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses)

static OpenACCExitDataConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses)

static OpenACCHostDataConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses, Stmt *StructuredBlock)

An 'if' clause, which has a required condition expression.

static OpenACCInitConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses)

static OpenACCLoopConstruct * Create(const ASTContext &C, OpenACCDirectiveKind ParentKind, SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation EndLoc, ArrayRef< const OpenACCClause * > Clauses, Stmt *Loop)

A 'self' clause, which has an optional condition expression, or, in the event of an 'update' directiv...

static OpenACCSetConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses)

static OpenACCShutdownConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses)

llvm::ArrayRef< Expr * > getSizeExprs()

static OpenACCUpdateConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses)

static OpenACCWaitConstruct * Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation LParenLoc, Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef< Expr * > QueueIdExprs, SourceLocation RParenLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses)

A (possibly-)qualified type.

bool isNull() const

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

QualType getNonReferenceType() const

If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...

QualType getUnqualifiedType() const

Retrieve the unqualified variant of the given type, removing as little sugar as possible.

A generic diagnostic builder for errors which may or may not be deferred.

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

Emit a diagnostic.

ASTContext & getASTContext() const

const LangOptions & getLangOpts() const

AssociatedStmtRAII(SemaOpenACC &, OpenACCDirectiveKind, SourceLocation, ArrayRef< const OpenACCClause * >, ArrayRef< OpenACCClause * >)

void SetTileInfoBeforeAssociatedStmt(ArrayRef< const OpenACCClause * > UnInstClauses, ArrayRef< OpenACCClause * > Clauses)

void SetCollapseInfoBeforeAssociatedStmt(ArrayRef< const OpenACCClause * > UnInstClauses, ArrayRef< OpenACCClause * > Clauses)

ExprResult ActOnVar(OpenACCClauseKind CK, Expr *VarExpr)

Called when encountering a 'var' for OpenACC, ensures it is actually a declaration reference to a var...

ComputeConstructInfo & getActiveComputeConstructInfo()

bool ActOnStartStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, ArrayRef< const OpenACCClause * > Clauses)

Called after the directive, including its clauses, have been parsed and parsing has consumed the 'ann...

ExprResult BuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc)

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

void ActOnWhileStmt(SourceLocation WhileLoc)

SourceLocation LoopWorkerClauseLoc

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

bool ActOnStartDeclDirective(OpenACCDirectiveKind K, SourceLocation StartLoc)

Called after the directive, including its clauses, have been parsed and parsing has consumed the 'ann...

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

struct clang::SemaOpenACC::LoopWithoutSeqCheckingInfo LoopWithoutSeqInfo

StmtResult ActOnEndStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc, SourceLocation LParenLoc, SourceLocation MiscLoc, ArrayRef< Expr * > Exprs, SourceLocation RParenLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses, StmtResult AssocStmt)

Called after the directive has been completely parsed, including the declaration group or associated ...

DeclGroupRef ActOnEndDeclDirective()

Called after the directive has been completely parsed, including the declaration group or associated ...

SourceLocation LoopVectorClauseLoc

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

void ActOnConstruct(OpenACCDirectiveKind K, SourceLocation DirLoc)

Called after the construct has been parsed, but clauses haven't been parsed.

ExprResult ActOnOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc)

void ActOnDoStmt(SourceLocation DoLoc)

void ActOnRangeForStmtBegin(SourceLocation ForLoc, const Stmt *OldRangeFor, const Stmt *RangeFor)

void ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body)

StmtResult ActOnAssociatedStmt(SourceLocation DirectiveLoc, OpenACCDirectiveKind K, ArrayRef< const OpenACCClause * > Clauses, StmtResult AssocStmt)

Called when we encounter an associated statement for our construct, this should check legality of the...

void ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *First, const Stmt *Second, const Stmt *Third)

ExprResult ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc, Expr *LowerBound, SourceLocation ColonLocFirst, Expr *Length, SourceLocation RBLoc)

Checks and creates an Array Section used in an OpenACC construct/clause.

Sema - This implements semantic analysis and AST building for C.

void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl=nullptr, ExpressionEvaluationContextRecord::ExpressionKind Type=ExpressionEvaluationContextRecord::EK_Other)

ExprResult PerformContextualImplicitConversion(SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter)

Perform a contextual implicit conversion.

ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)

void PopExpressionEvaluationContext()

ExprResult DefaultLvalueConversion(Expr *E)

ExprResult CheckPlaceholderExpr(Expr *E)

Check for operands with placeholder types and complain if found.

@ PotentiallyEvaluated

The current expression is potentially evaluated at run time, which means that code may be generated t...

bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)

Ensure that the type T is a complete type.

void DiscardCleanupsInEvaluationContext()

ExprResult CreateRecoveryExpr(SourceLocation Begin, SourceLocation End, ArrayRef< Expr * > SubExprs, QualType T=QualType())

Attempts to produce a RecoveryExpr after some AST node cannot be created.

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

Stmt - This represents one statement.

SourceLocation getEndLoc() const LLVM_READONLY

SourceRange getSourceRange() const LLVM_READONLY

SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...

SourceLocation getBeginLoc() const LLVM_READONLY

CXXRecordDecl * getAsCXXRecordDecl() const

Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...

bool isDependentSizedArrayType() const

bool isConstantArrayType() const

bool isPointerType() const

bool isIntegerType() const

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

bool isEnumeralType() const

QualType getPointeeType() const

If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.

bool isNonOverloadPlaceholderType() const

Test for a placeholder type other than Overload; see BuiltinType::isNonOverloadPlaceholderType.

bool isInstantiationDependentType() const

Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...

bool isDependentType() const

Whether this type is a dependent type, meaning that its definition somehow depends on a template para...

const ArrayType * getAsArrayTypeUnsafe() const

A variant of getAs<> for array types which silently discards qualifiers from the outermost type.

bool isFunctionType() const

bool isAnyPointerType() const

bool isRecordType() const

Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...

Represents a variable declaration or definition.

SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)

Returns the results of matching Matcher on Node.

bool Inc(InterpState &S, CodePtr OpPC)

  1. Pops a pointer from the stack 2) Load the value from the pointer 3) Writes the value increased by ...

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

@ OK_Ordinary

An ordinary object is located at an address in memory.

OpenACCClauseKind

Represents the kind of an OpenACC clause.

@ DevicePtr

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

@ Collapse

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

@ DeviceNum

'device_num' clause, allowed on 'init', 'shutdown', and 'set' constructs.

@ Invalid

Represents an invalid clause, for the purposes of parsing.

@ Copy

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

@ 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',...

@ DefaultAsync

'default_async' clause, allowed on 'set' construct.

@ Attach

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

@ If

'if' clause, allowed on all the Compute Constructs, Data Constructs, Executable Constructs,...

@ Default

'default' clause, allowed on parallel, serial, kernel (and compound) constructs.

@ UseDevice

'use_device' clause, allowed on 'host_data' construct.

@ NoCreate

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

@ Reduction

'reduction' clause, allowed on Parallel, Serial, Loop, and the combined constructs.

@ Self

'self' clause, allowed on Compute and Combined Constructs, plus 'update'.

@ CopyOut

'copyout' clause, allowed on Compute and Combined constructs, plus 'data', 'exit data',...

@ Host

'host' clause, allowed on 'update' construct.

@ Tile

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

@ Present

'present' clause, allowed on Compute and Combined constructs, plus 'data' and 'declare'.

@ CopyIn

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

@ Device

'device' clause, allowed on the 'update' construct.

@ Detach

'detach' clause, allowed on the 'exit data' construct.

@ Delete

'delete' clause, allowed on the 'exit data' construct.

@ Result

The result type of a method or function.

@ VK_LValue

An l-value expression is a reference to an object with independent storage.

const FunctionProtoType * T

EvalResult is a struct with detailed info about an evaluated expression.

APValue Val

Val - This is the value the expression can be folded to.