32 using namespace clang;
46 template <
class T>
struct MatchesAny {
47 explicit MatchesAny(
ArrayRef<T> Arr) : Arr(std::move(Arr)) {}
48 bool operator()(T
Kind) {
49 for (
auto KindEl : Arr)
58 struct MatchesAlways {
60 template <
class T>
bool operator()(T) {
return true; }
63 typedef MatchesAny<OpenMPClauseKind> MatchesAnyClause;
64 typedef MatchesAny<OpenMPDirectiveKind> MatchesAnyDirective;
85 typedef llvm::SmallDenseMap<VarDecl *, DSAInfo, 64> DeclSAMapTy;
86 typedef llvm::SmallDenseMap<VarDecl *, DeclRefExpr *, 64> AlignedMapTy;
90 DeclSAMapTy SharingMap;
91 AlignedMapTy AlignedMap;
92 LoopControlVariablesSetTy LCVSet;
101 unsigned CollapseNumber;
105 : SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified),
106 Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope),
107 ConstructLoc(Loc), OrderedRegion(
false), NowaitRegion(
false),
108 CollapseNumber(1), InnerTeamsRegionLoc() {}
110 : SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified),
112 ConstructLoc(), OrderedRegion(
false), NowaitRegion(
false),
113 CollapseNumber(1), InnerTeamsRegionLoc() {}
128 DSAVarData getDSA(StackTy::reverse_iterator Iter,
VarDecl *D);
131 bool isOpenMPLocal(
VarDecl *D, StackTy::reverse_iterator Iter);
134 explicit DSAStackTy(
Sema &
S)
136 ForceCapturing(
false) {}
138 bool isClauseParsingMode()
const {
return ClauseKindMode !=
OMPC_unknown; }
141 bool isForceVarCapturing()
const {
return ForceCapturing; }
142 void setForceVarCapturing(
bool V) { ForceCapturing = V; }
146 Stack.push_back(SharingMapTy(DKind, DirName, CurScope, Loc));
147 Stack.back().DefaultAttrLoc = Loc;
151 assert(
Stack.size() > 1 &&
"Data-sharing attributes stack is empty!");
161 void addLoopControlVariable(
VarDecl *D);
164 bool isLoopControlVariable(
VarDecl *D);
171 DSAVarData getTopDSA(
VarDecl *D,
bool FromParent);
173 DSAVarData getImplicitDSA(
VarDecl *D,
bool FromParent);
177 template <
class ClausesPredicate,
class DirectivesPredicate>
178 DSAVarData hasDSA(
VarDecl *D, ClausesPredicate CPred,
179 DirectivesPredicate DPred,
bool FromParent);
183 template <
class ClausesPredicate,
class DirectivesPredicate>
184 DSAVarData hasInnermostDSA(
VarDecl *D, ClausesPredicate CPred,
185 DirectivesPredicate DPred,
190 bool hasExplicitDSA(
VarDecl *D,
194 template <
class NamedDirectivesPredicate>
195 bool hasDirective(NamedDirectivesPredicate DPred,
bool FromParent);
199 return Stack.back().Directive;
203 if (
Stack.size() > 2)
210 Stack.back().DefaultAttr = DSA_none;
211 Stack.back().DefaultAttrLoc = Loc;
215 Stack.back().DefaultAttr = DSA_shared;
216 Stack.back().DefaultAttrLoc = Loc;
220 return Stack.back().DefaultAttr;
223 return Stack.back().DefaultAttrLoc;
227 bool isThreadPrivate(
VarDecl *D) {
228 DSAVarData DVar = getTopDSA(D,
false);
233 void setOrderedRegion(
bool IsOrdered =
true) {
234 Stack.back().OrderedRegion = IsOrdered;
238 bool isParentOrderedRegion()
const {
239 if (
Stack.size() > 2)
244 void setNowaitRegion(
bool IsNowait =
true) {
245 Stack.back().NowaitRegion = IsNowait;
249 bool isParentNowaitRegion()
const {
250 if (
Stack.size() > 2)
256 void setCollapseNumber(
unsigned Val) {
Stack.back().CollapseNumber = Val; }
258 unsigned getCollapseNumber()
const {
259 return Stack.back().CollapseNumber;
265 if (
Stack.size() > 2)
266 Stack[
Stack.size() - 2].InnerTeamsRegionLoc = TeamsRegionLoc;
269 bool hasInnerTeamsRegion()
const {
270 return getInnerTeamsRegionLoc().
isValid();
274 if (
Stack.size() > 1)
275 return Stack.back().InnerTeamsRegionLoc;
279 Scope *getCurScope()
const {
return Stack.back().CurScope; }
280 Scope *getCurScope() {
return Stack.back().CurScope; }
289 DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator Iter,
293 if (Iter == std::prev(
Stack.rend())) {
300 DVar.CKind = OMPC_shared;
307 DVar.CKind = OMPC_shared;
312 DVar.DKind = Iter->Directive;
319 DVar.CKind = OMPC_private;
325 if (Iter->SharingMap.count(D)) {
326 DVar.RefExpr = Iter->SharingMap[D].RefExpr;
327 DVar.CKind = Iter->SharingMap[D].Attributes;
328 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
336 switch (Iter->DefaultAttr) {
338 DVar.CKind = OMPC_shared;
339 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
343 case DSA_unspecified:
348 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
351 DVar.CKind = OMPC_shared;
360 if (DVar.DKind == OMPD_task) {
362 for (StackTy::reverse_iterator I = std::next(Iter), EE =
Stack.rend();
370 DVarTemp = getDSA(I, D);
371 if (DVarTemp.CKind != OMPC_shared) {
372 DVar.RefExpr =
nullptr;
373 DVar.DKind = OMPD_task;
374 DVar.CKind = OMPC_firstprivate;
377 if (isParallelOrTaskRegion(I->Directive))
380 DVar.DKind = OMPD_task;
382 (DVarTemp.CKind ==
OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
391 return getDSA(std::next(Iter), D);
395 assert(
Stack.size() > 1 &&
"Data sharing attributes stack is empty");
397 auto It =
Stack.back().AlignedMap.find(D);
398 if (It ==
Stack.back().AlignedMap.end()) {
399 assert(NewDE &&
"Unexpected nullptr expr to be added into aligned map");
400 Stack.back().AlignedMap[D] = NewDE;
403 assert(It->second &&
"Unexpected nullptr expr in the aligned map");
409 void DSAStackTy::addLoopControlVariable(
VarDecl *D) {
410 assert(
Stack.size() > 1 &&
"Data-sharing attributes stack is empty");
412 Stack.back().LCVSet.insert(D);
415 bool DSAStackTy::isLoopControlVariable(
VarDecl *D) {
416 assert(
Stack.size() > 1 &&
"Data-sharing attributes stack is empty");
418 return Stack.back().LCVSet.count(D) > 0;
424 Stack[0].SharingMap[D].Attributes = A;
425 Stack[0].SharingMap[D].RefExpr = E;
427 assert(
Stack.size() > 1 &&
"Data-sharing attributes stack is empty");
428 Stack.back().SharingMap[D].Attributes = A;
429 Stack.back().SharingMap[D].RefExpr = E;
433 bool DSAStackTy::isOpenMPLocal(
VarDecl *D, StackTy::reverse_iterator Iter) {
435 if (
Stack.size() > 2) {
436 reverse_iterator I = Iter, E = std::prev(
Stack.rend());
437 Scope *TopScope =
nullptr;
438 while (I != E && !isParallelOrTaskRegion(I->Directive)) {
443 TopScope = I->CurScope ? I->CurScope->
getParent() :
nullptr;
444 Scope *CurScope = getCurScope();
445 while (CurScope != TopScope && !CurScope->
isDeclScope(D)) {
448 return CurScope != TopScope;
467 bool RefersToCapture =
false) {
475 DSAStackTy::DSAVarData DSAStackTy::getTopDSA(
VarDecl *D,
bool FromParent) {
483 !(D->
hasAttr<OMPThreadPrivateDeclAttr>() &&
484 SemaRef.getLangOpts().OpenMPUseTLS &&
485 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
492 if (
Stack[0].SharingMap.count(D)) {
493 DVar.RefExpr =
Stack[0].SharingMap[D].RefExpr;
503 FromParent ? getParentDirective() : getCurrentDirective();
504 auto StartI = std::next(
Stack.rbegin());
505 auto EndI = std::prev(
Stack.rend());
506 if (FromParent && StartI != EndI) {
507 StartI = std::next(StartI);
509 if (!isParallelOrTaskRegion(Kind)) {
510 if (isOpenMPLocal(D, StartI) &&
513 isa<ParmVarDecl>(D))) {
514 DVar.CKind = OMPC_private;
526 DSAVarData DVarTemp =
531 DVar.CKind = OMPC_shared;
537 bool IsConstant = Type.
isConstant(SemaRef.getASTContext());
538 Type = SemaRef.getASTContext().getBaseElementType(Type);
549 DSAVarData DVarTemp = hasDSA(D, MatchesAnyClause(OMPC_firstprivate),
550 MatchesAlways(), FromParent);
551 if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
554 DVar.CKind = OMPC_shared;
560 auto I = std::prev(StartI);
561 if (I->SharingMap.count(D)) {
562 DVar.RefExpr = I->SharingMap[D].RefExpr;
563 DVar.CKind = I->SharingMap[D].Attributes;
564 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
570 DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(
VarDecl *D,
bool FromParent) {
572 auto StartI =
Stack.rbegin();
573 auto EndI = std::prev(
Stack.rend());
574 if (FromParent && StartI != EndI) {
575 StartI = std::next(StartI);
577 return getDSA(StartI, D);
580 template <
class ClausesPredicate,
class DirectivesPredicate>
581 DSAStackTy::DSAVarData DSAStackTy::hasDSA(
VarDecl *D, ClausesPredicate CPred,
582 DirectivesPredicate DPred,
585 auto StartI = std::next(
Stack.rbegin());
586 auto EndI = std::prev(
Stack.rend());
587 if (FromParent && StartI != EndI) {
588 StartI = std::next(StartI);
590 for (
auto I = StartI, EE = EndI; I != EE; ++I) {
591 if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive))
593 DSAVarData DVar = getDSA(I, D);
594 if (CPred(DVar.CKind))
600 template <
class ClausesPredicate,
class DirectivesPredicate>
601 DSAStackTy::DSAVarData
602 DSAStackTy::hasInnermostDSA(
VarDecl *D, ClausesPredicate CPred,
603 DirectivesPredicate DPred,
bool FromParent) {
605 auto StartI = std::next(
Stack.rbegin());
606 auto EndI = std::prev(
Stack.rend());
607 if (FromParent && StartI != EndI) {
608 StartI = std::next(StartI);
610 for (
auto I = StartI, EE = EndI; I != EE; ++I) {
611 if (!DPred(I->Directive))
613 DSAVarData DVar = getDSA(I, D);
614 if (CPred(DVar.CKind))
621 bool DSAStackTy::hasExplicitDSA(
624 if (CPred(ClauseKindMode))
626 if (isClauseParsingMode())
629 auto StartI =
Stack.rbegin();
630 auto EndI = std::prev(
Stack.rend());
631 if (std::distance(StartI, EndI) <= (int)Level)
633 std::advance(StartI, Level);
634 return (StartI->SharingMap.count(D) > 0) && StartI->SharingMap[D].RefExpr &&
635 CPred(StartI->SharingMap[D].Attributes);
638 template <
class NamedDirectivesPredicate>
639 bool DSAStackTy::hasDirective(NamedDirectivesPredicate DPred,
bool FromParent) {
640 auto StartI = std::next(
Stack.rbegin());
641 auto EndI = std::prev(
Stack.rend());
642 if (FromParent && StartI != EndI) {
643 StartI = std::next(StartI);
645 for (
auto I = StartI, EE = EndI; I != EE; ++I) {
646 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
652 void Sema::InitDataSharingAttributesStack() {
653 VarDataSharingAttributesStack =
new DSAStackTy(*
this);
656 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
659 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
662 (!
DSAStack->isClauseParsingMode() ||
664 if (
DSAStack->isLoopControlVariable(VD) ||
666 isParallelOrTaskRegion(
DSAStack->getCurrentDirective())) ||
669 auto DVarPrivate =
DSAStack->getTopDSA(VD,
DSAStack->isClauseParsingMode());
680 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
685 void Sema::DestroyDataSharingAttributesStack() {
delete DSAStack; }
690 DSAStack->push(DKind, DirName, CurScope, Loc);
708 if (
auto D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
709 for (
auto *
C : D->clauses()) {
710 if (
auto *Clause = dyn_cast<OMPLastprivateClause>(
C)) {
712 for (
auto *DE : Clause->varlists()) {
713 if (DE->isValueDependent() || DE->isTypeDependent()) {
714 PrivateCopies.push_back(
nullptr);
717 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(DE)->getDecl());
719 auto DVar =
DSAStack->getTopDSA(VD,
false);
720 if (DVar.CKind == OMPC_lastprivate) {
727 buildVarDecl(*
this, DE->getExprLoc(), Type.getUnqualifiedType(),
730 if (VDPrivate->isInvalidDecl())
733 *
this, VDPrivate, DE->getType(), DE->getExprLoc()));
737 PrivateCopies.push_back(
nullptr);
741 if (PrivateCopies.size() == Clause->varlist_size()) {
742 Clause->setPrivateCopies(PrivateCopies);
764 explicit VarDeclFilterCCC(
Sema &
S) : SemaRef(S) {}
765 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
767 if (
VarDecl *VD = dyn_cast_or_null<VarDecl>(ND)) {
768 return VD->hasGlobalStorage() &&
769 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
770 SemaRef.getCurScope());
793 ? diag::err_undeclared_var_use_suggest
794 : diag::err_omp_expected_var_arg_suggest)
796 VD = Corrected.getCorrectionDeclAs<
VarDecl>();
799 : diag::err_omp_expected_var_arg)
815 Diag(Id.
getLoc(), diag::err_omp_global_var_arg)
820 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
826 NamedDecl *ND = cast<NamedDecl>(CanonicalVD);
837 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
852 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
868 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
882 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
912 class LocalVarRefChecker :
public ConstStmtVisitor<LocalVarRefChecker, bool> {
917 if (
auto VD = dyn_cast<VarDecl>(E->
getDecl())) {
918 if (VD->hasLocalStorage()) {
920 diag::err_omp_local_var_in_threadprivate_init)
921 << E->getSourceRange();
922 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
923 << VD << VD->getSourceRange();
929 bool VisitStmt(
const Stmt *
S) {
930 for (
auto Child : S->children()) {
931 if (Child && Visit(Child))
936 explicit LocalVarRefChecker(
Sema &SemaRef) : SemaRef(SemaRef) {}
943 for (
auto &RefExpr : VarList) {
958 diag::err_omp_threadprivate_incomplete_type)) {
964 if (VD->getType()->isReferenceType()) {
965 Diag(ILoc, diag::err_omp_ref_type_arg)
969 Diag(VD->getLocation(),
970 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
978 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
981 (VD->getStorageClass() ==
SC_Register && VD->hasAttr<AsmLabelAttr>() &&
982 !VD->isLocalVarDecl())) {
983 Diag(ILoc, diag::err_omp_var_thread_local)
987 Diag(VD->getLocation(),
988 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
995 if (
auto Init = VD->getAnyInitializer()) {
996 LocalVarRefChecker Checker(*
this);
997 if (Checker.Visit(Init))
1001 Vars.push_back(RefExpr);
1003 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
1006 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
1009 if (!Vars.empty()) {
1018 const VarDecl *VD, DSAStackTy::DSAVarData DVar,
1019 bool IsLoopIterVar =
false) {
1021 SemaRef.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
1026 PDSA_StaticMemberShared,
1027 PDSA_StaticLocalVarShared,
1028 PDSA_LoopIterVarPrivate,
1029 PDSA_LoopIterVarLinear,
1030 PDSA_LoopIterVarLastprivate,
1031 PDSA_ConstVarShared,
1032 PDSA_GlobalVarShared,
1033 PDSA_TaskVarFirstprivate,
1034 PDSA_LocalVarPrivate,
1036 } Reason = PDSA_Implicit;
1037 bool ReportHint =
false;
1039 if (IsLoopIterVar) {
1040 if (DVar.CKind == OMPC_private)
1041 Reason = PDSA_LoopIterVarPrivate;
1042 else if (DVar.CKind == OMPC_lastprivate)
1043 Reason = PDSA_LoopIterVarLastprivate;
1045 Reason = PDSA_LoopIterVarLinear;
1046 }
else if (DVar.DKind == OMPD_task && DVar.CKind == OMPC_firstprivate) {
1047 Reason = PDSA_TaskVarFirstprivate;
1048 ReportLoc = DVar.ImplicitDSALoc;
1050 Reason = PDSA_StaticLocalVarShared;
1052 Reason = PDSA_StaticMemberShared;
1054 Reason = PDSA_GlobalVarShared;
1056 Reason = PDSA_ConstVarShared;
1059 Reason = PDSA_LocalVarPrivate;
1061 if (Reason != PDSA_Implicit) {
1062 SemaRef.
Diag(ReportLoc, diag::note_omp_predetermined_dsa)
1063 << Reason << ReportHint
1065 }
else if (DVar.ImplicitDSALoc.isValid()) {
1066 SemaRef.
Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
1072 class DSAAttrChecker :
public StmtVisitor<DSAAttrChecker, void> {
1078 llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA;
1082 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
1084 if (VD->isLocalVarDecl() && !CS->capturesVariable(VD))
1087 auto DVar =
Stack->getTopDSA(VD,
false);
1089 if (DVar.RefExpr)
return;
1092 auto DKind =
Stack->getCurrentDirective();
1098 isParallelOrTaskRegion(DKind) &&
1099 VarsWithInheritedDSA.count(VD) == 0) {
1100 VarsWithInheritedDSA[VD] = E;
1108 DVar =
Stack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction),
1115 if (DKind == OMPD_task && DVar.CKind == OMPC_reduction) {
1117 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
1123 DVar =
Stack->getImplicitDSA(VD,
false);
1124 if (DKind == OMPD_task && DVar.CKind != OMPC_shared)
1125 ImplicitFirstprivate.push_back(E);
1132 if (
C && (!isa<OMPFirstprivateClause>(
C) ||
C->getLocStart().isValid()))
1133 for (
auto *CC :
C->children()) {
1139 void VisitStmt(
Stmt *S) {
1140 for (
auto *
C : S->children()) {
1141 if (
C && !isa<OMPExecutableDirective>(
C))
1146 bool isErrorFound() {
return ErrorFound; }
1147 ArrayRef<Expr *> getImplicitFirstprivate() {
return ImplicitFirstprivate; }
1148 llvm::DenseMap<VarDecl *, Expr *> &getVarsWithInheritedDSA() {
1149 return VarsWithInheritedDSA;
1153 :
Stack(S), SemaRef(SemaRef), ErrorFound(
false), CS(CS) {}
1159 case OMPD_parallel: {
1163 std::make_pair(
".global_tid.", KmpInt32PtrTy),
1164 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
1165 std::make_pair(StringRef(),
QualType())
1173 std::make_pair(StringRef(),
QualType())
1181 std::make_pair(StringRef(),
QualType())
1187 case OMPD_for_simd: {
1189 std::make_pair(StringRef(),
QualType())
1195 case OMPD_sections: {
1197 std::make_pair(StringRef(),
QualType())
1203 case OMPD_section: {
1205 std::make_pair(StringRef(),
QualType())
1213 std::make_pair(StringRef(),
QualType())
1221 std::make_pair(StringRef(),
QualType())
1227 case OMPD_critical: {
1229 std::make_pair(StringRef(),
QualType())
1235 case OMPD_parallel_for: {
1239 std::make_pair(
".global_tid.", KmpInt32PtrTy),
1240 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
1241 std::make_pair(StringRef(),
QualType())
1247 case OMPD_parallel_for_simd: {
1251 std::make_pair(
".global_tid.", KmpInt32PtrTy),
1252 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
1253 std::make_pair(StringRef(),
QualType())
1259 case OMPD_parallel_sections: {
1263 std::make_pair(
".global_tid.", KmpInt32PtrTy),
1264 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
1265 std::make_pair(StringRef(),
QualType())
1278 std::make_pair(
".global_tid.", KmpInt32Ty),
1279 std::make_pair(
".part_id.", KmpInt32Ty),
1280 std::make_pair(
".privates.",
1285 std::make_pair(StringRef(),
QualType())
1292 AlwaysInlineAttr::CreateImplicit(
1296 case OMPD_ordered: {
1298 std::make_pair(StringRef(),
QualType())
1306 std::make_pair(StringRef(),
QualType())
1314 std::make_pair(StringRef(),
QualType())
1324 std::make_pair(
".global_tid.", KmpInt32PtrTy),
1325 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
1326 std::make_pair(StringRef(),
QualType())
1332 case OMPD_taskgroup: {
1334 std::make_pair(StringRef(),
QualType())
1340 case OMPD_threadprivate:
1341 case OMPD_taskyield:
1344 case OMPD_cancellation_point:
1347 llvm_unreachable(
"OpenMP Directive is not allowed");
1349 llvm_unreachable(
"Unknown OpenMP directive");
1360 for (
auto *Clause : Clauses) {
1362 Clause->getClauseKind() == OMPC_copyprivate ||
1365 Clause->getClauseKind() == OMPC_copyin)) {
1366 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
1368 for (
auto *VarRef : Clause->children()) {
1369 if (
auto *E = cast_or_null<Expr>(VarRef)) {
1373 DSAStack->setForceVarCapturing(
false);
1374 }
else if (isParallelOrTaskRegion(
DSAStack->getCurrentDirective()) &&
1375 Clause->getClauseKind() == OMPC_schedule) {
1379 if (
auto *E = cast_or_null<Expr>(
1380 cast<OMPScheduleClause>(Clause)->getHelperChunkSize())) {
1838 if (Stack->getCurScope()) {
1839 auto ParentRegion = Stack->getParentDirective();
1840 bool NestingProhibited =
false;
1841 bool CloseNesting =
true;
1844 ShouldBeInParallelRegion,
1845 ShouldBeInOrderedRegion,
1846 ShouldBeInTargetRegion
1847 } Recommend = NoRecommend;
1851 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_simd);
1854 if (ParentRegion == OMPD_atomic) {
1857 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
1860 if (CurrentRegion == OMPD_section) {
1865 if (ParentRegion != OMPD_sections &&
1866 ParentRegion != OMPD_parallel_sections) {
1867 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_section_directive)
1878 if (CurrentRegion == OMPD_cancellation_point ||
1879 CurrentRegion == OMPD_cancel) {
1892 !((CancelRegion == OMPD_parallel && ParentRegion == OMPD_parallel) ||
1893 (CancelRegion == OMPD_for && ParentRegion == OMPD_for) ||
1894 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
1895 (CancelRegion == OMPD_sections &&
1896 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections)));
1897 }
else if (CurrentRegion == OMPD_master) {
1902 ParentRegion == OMPD_task;
1903 }
else if (CurrentRegion == OMPD_critical && CurrentName.
getName()) {
1910 Stack->hasDirective([CurrentName, &PreviousCriticalLoc](
1915 if (K == OMPD_critical &&
1917 PreviousCriticalLoc = Loc;
1924 SemaRef.
Diag(StartLoc,
1925 diag::err_omp_prohibited_region_critical_same_name)
1927 if (PreviousCriticalLoc.
isValid())
1928 SemaRef.
Diag(PreviousCriticalLoc,
1929 diag::note_omp_previous_critical_region);
1932 }
else if (CurrentRegion == OMPD_barrier) {
1938 ParentRegion == OMPD_task || ParentRegion == OMPD_master ||
1939 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
1947 ParentRegion == OMPD_task || ParentRegion == OMPD_master ||
1948 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
1949 Recommend = ShouldBeInParallelRegion;
1950 }
else if (CurrentRegion == OMPD_ordered) {
1956 NestingProhibited = ParentRegion == OMPD_critical ||
1957 ParentRegion == OMPD_task ||
1958 !Stack->isParentOrderedRegion();
1959 Recommend = ShouldBeInOrderedRegion;
1964 NestingProhibited = ParentRegion != OMPD_target;
1965 Recommend = ShouldBeInTargetRegion;
1966 Stack->setParentTeamsRegionLoc(Stack->getConstructLoc());
1975 Recommend = ShouldBeInParallelRegion;
1977 if (NestingProhibited) {
1978 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region)
1997 llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA;
1998 bool ErrorFound =
false;
1999 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
2001 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
2004 DSAAttrChecker DSAChecker(
DSAStack, *
this, cast<CapturedStmt>(AStmt));
2005 DSAChecker.Visit(cast<CapturedStmt>(AStmt)->getCapturedStmt());
2006 if (DSAChecker.isErrorFound())
2009 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
2011 if (!DSAChecker.getImplicitFirstprivate().empty()) {
2015 ClausesWithImplicit.push_back(Implicit);
2016 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
2017 DSAChecker.getImplicitFirstprivate().size();
2030 VarsWithInheritedDSA);
2034 VarsWithInheritedDSA);
2038 EndLoc, VarsWithInheritedDSA);
2045 assert(ClausesWithImplicit.empty() &&
2046 "No clauses are allowed for 'omp section' directive");
2054 assert(ClausesWithImplicit.empty() &&
2055 "No clauses are allowed for 'omp master' directive");
2059 assert(ClausesWithImplicit.empty() &&
2060 "No clauses are allowed for 'omp critical' directive");
2063 case OMPD_parallel_for:
2065 EndLoc, VarsWithInheritedDSA);
2067 case OMPD_parallel_for_simd:
2069 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2071 case OMPD_parallel_sections:
2079 case OMPD_taskyield:
2080 assert(ClausesWithImplicit.empty() &&
2081 "No clauses are allowed for 'omp taskyield' directive");
2082 assert(AStmt ==
nullptr &&
2083 "No associated statement allowed for 'omp taskyield' directive");
2087 assert(ClausesWithImplicit.empty() &&
2088 "No clauses are allowed for 'omp barrier' directive");
2089 assert(AStmt ==
nullptr &&
2090 "No associated statement allowed for 'omp barrier' directive");
2094 assert(ClausesWithImplicit.empty() &&
2095 "No clauses are allowed for 'omp taskwait' directive");
2096 assert(AStmt ==
nullptr &&
2097 "No associated statement allowed for 'omp taskwait' directive");
2100 case OMPD_taskgroup:
2101 assert(ClausesWithImplicit.empty() &&
2102 "No clauses are allowed for 'omp taskgroup' directive");
2106 assert(AStmt ==
nullptr &&
2107 "No associated statement allowed for 'omp flush' directive");
2111 assert(ClausesWithImplicit.empty() &&
2112 "No clauses are allowed for 'omp ordered' directive");
2127 case OMPD_cancellation_point:
2128 assert(ClausesWithImplicit.empty() &&
2129 "No clauses are allowed for 'omp cancellation point' directive");
2130 assert(AStmt ==
nullptr &&
"No associated statement allowed for 'omp "
2131 "cancellation point' directive");
2135 assert(ClausesWithImplicit.empty() &&
2136 "No clauses are allowed for 'omp cancel' directive");
2137 assert(AStmt ==
nullptr &&
2138 "No associated statement allowed for 'omp cancel' directive");
2141 case OMPD_threadprivate:
2142 llvm_unreachable(
"OpenMP Directive is not allowed");
2144 llvm_unreachable(
"Unknown OpenMP directive");
2147 for (
auto P : VarsWithInheritedDSA) {
2148 Diag(
P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
2149 <<
P.first <<
P.second->getSourceRange();
2151 if (!VarsWithInheritedDSA.empty())
2163 assert(AStmt && isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
2182 class OpenMPIterationSpaceChecker {
2212 bool TestIsStrictOp;
2218 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc),
2220 IncrementSrcRange(
SourceRange()), Var(nullptr), VarRef(nullptr),
2221 LB(nullptr), UB(nullptr),
Step(nullptr), TestIsLessOp(
false),
2222 TestIsStrictOp(
false), SubtractStep(
false) {}
2225 bool CheckInit(
Stmt *S,
bool EmitDiags =
true);
2228 bool CheckCond(
Expr *S);
2231 bool CheckInc(
Expr *S);
2233 VarDecl *GetLoopVar()
const {
return Var; }
2235 DeclRefExpr *GetLoopVarRefExpr()
const {
return VarRef; }
2237 SourceRange GetInitSrcRange()
const {
return InitSrcRange; }
2239 SourceRange GetConditionSrcRange()
const {
return ConditionSrcRange; }
2241 SourceRange GetIncrementSrcRange()
const {
return IncrementSrcRange; }
2243 bool ShouldSubtractStep()
const {
return SubtractStep; }
2245 Expr *BuildNumIterations(
Scope *S,
const bool LimitedType)
const;
2249 Expr *BuildCounterVar()
const;
2253 Expr *BuildCounterStep()
const;
2255 bool Dependent()
const;
2260 bool CheckIncRHS(
Expr *RHS);
2264 bool SetUB(
Expr *NewUB,
bool LessOp,
bool StrictOp,
const SourceRange &SR,
2267 bool SetStep(
Expr *NewStep,
bool Subtract);
2270 bool OpenMPIterationSpaceChecker::Dependent()
const {
2272 assert(!LB && !UB && !
Step);
2275 return Var->getType()->isDependentType() || (LB && LB->isValueDependent()) ||
2276 (UB && UB->isValueDependent()) || (
Step &&
Step->isValueDependent());
2279 template <
typename T>
2280 static T *getExprAsWritten(T *E) {
2281 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(E))
2282 E = ExprTemp->getSubExpr();
2284 if (
auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
2285 E = MTE->GetTemporaryExpr();
2287 while (
auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
2288 E = Binder->getSubExpr();
2290 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E))
2291 E = ICE->getSubExprAsWritten();
2292 return E->IgnoreParens();
2295 bool OpenMPIterationSpaceChecker::SetVarAndLB(
VarDecl *NewVar,
2299 assert(Var ==
nullptr && LB ==
nullptr && VarRef ==
nullptr &&
2300 UB ==
nullptr &&
Step ==
nullptr && !TestIsLessOp && !TestIsStrictOp);
2301 if (!NewVar || !NewLB)
2304 VarRef = NewVarRefExpr;
2305 if (
auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
2307 if ((Ctor->isCopyOrMoveConstructor() ||
2308 Ctor->isConvertingConstructor(
false)) &&
2309 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
2315 bool OpenMPIterationSpaceChecker::SetUB(
Expr *NewUB,
bool LessOp,
bool StrictOp,
2319 assert(Var !=
nullptr && LB !=
nullptr && UB ==
nullptr &&
Step ==
nullptr &&
2320 !TestIsLessOp && !TestIsStrictOp);
2324 TestIsLessOp = LessOp;
2325 TestIsStrictOp = StrictOp;
2326 ConditionSrcRange = SR;
2331 bool OpenMPIterationSpaceChecker::SetStep(
Expr *NewStep,
bool Subtract) {
2333 assert(Var !=
nullptr && LB !=
nullptr &&
Step ==
nullptr);
2340 SemaRef.PerformOpenMPImplicitIntegerConversion(StepLoc, NewStep);
2343 NewStep = Val.
get();
2360 IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
2362 IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
2363 bool IsConstZero = IsConstant && !Result.getBoolValue();
2364 if (UB && (IsConstZero ||
2365 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
2366 : (IsConstPos || (IsUnsigned && !Subtract))))) {
2368 diag::err_omp_loop_incr_not_compatible)
2369 << Var << TestIsLessOp << NewStep->getSourceRange();
2370 SemaRef.Diag(ConditionLoc,
2371 diag::note_omp_loop_cond_requres_compatible_incr)
2372 << TestIsLessOp << ConditionSrcRange;
2375 if (TestIsLessOp == Subtract) {
2378 Subtract = !Subtract;
2383 SubtractStep = Subtract;
2387 bool OpenMPIterationSpaceChecker::CheckInit(
Stmt *S,
bool EmitDiags) {
2398 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
2402 InitSrcRange = S->getSourceRange();
2403 if (
Expr *E = dyn_cast<Expr>(S))
2404 S = E->IgnoreParens();
2405 if (
auto BO = dyn_cast<BinaryOperator>(S)) {
2407 if (
auto DRE = dyn_cast<DeclRefExpr>(BO->getLHS()->IgnoreParens()))
2408 return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), DRE,
2410 }
else if (
auto DS = dyn_cast<DeclStmt>(S)) {
2411 if (DS->isSingleDecl()) {
2412 if (
auto Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
2413 if (Var->hasInit()) {
2416 SemaRef.Diag(S->getLocStart(),
2417 diag::ext_omp_loop_not_canonical_init)
2418 << S->getSourceRange();
2419 return SetVarAndLB(Var,
nullptr, Var->getInit());
2423 }
else if (
auto CE = dyn_cast<CXXOperatorCallExpr>(S))
2424 if (CE->getOperator() == OO_Equal)
2425 if (
auto DRE = dyn_cast<DeclRefExpr>(CE->getArg(0)))
2426 return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), DRE,
2430 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init)
2431 << S->getSourceRange();
2438 static const VarDecl *GetInitVarDecl(
const Expr *E) {
2441 E = getExprAsWritten(E);
2442 if (
auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
2444 if ((Ctor->isCopyOrMoveConstructor() ||
2445 Ctor->isConvertingConstructor(
false)) &&
2446 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
2448 auto DRE = dyn_cast_or_null<DeclRefExpr>(E);
2451 return dyn_cast<
VarDecl>(DRE->getDecl());
2454 bool OpenMPIterationSpaceChecker::CheckCond(
Expr *S) {
2462 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << Var;
2465 S = getExprAsWritten(S);
2467 if (
auto BO = dyn_cast<BinaryOperator>(S)) {
2468 if (BO->isRelationalOp()) {
2469 if (GetInitVarDecl(BO->getLHS()) == Var)
2470 return SetUB(BO->getRHS(),
2471 (BO->getOpcode() ==
BO_LT || BO->getOpcode() ==
BO_LE),
2472 (BO->getOpcode() ==
BO_LT || BO->getOpcode() ==
BO_GT),
2473 BO->getSourceRange(), BO->getOperatorLoc());
2474 if (GetInitVarDecl(BO->getRHS()) == Var)
2475 return SetUB(BO->getLHS(),
2476 (BO->getOpcode() ==
BO_GT || BO->getOpcode() ==
BO_GE),
2477 (BO->getOpcode() ==
BO_LT || BO->getOpcode() ==
BO_GT),
2478 BO->getSourceRange(), BO->getOperatorLoc());
2480 }
else if (
auto CE = dyn_cast<CXXOperatorCallExpr>(S)) {
2481 if (CE->getNumArgs() == 2) {
2482 auto Op = CE->getOperator();
2485 case OO_GreaterEqual:
2488 if (GetInitVarDecl(CE->getArg(0)) == Var)
2489 return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
2490 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
2491 CE->getOperatorLoc());
2492 if (GetInitVarDecl(CE->getArg(1)) == Var)
2493 return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
2494 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
2495 CE->getOperatorLoc());
2502 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
2503 << S->getSourceRange() << Var;
2507 bool OpenMPIterationSpaceChecker::CheckIncRHS(
Expr *RHS) {
2514 if (
auto BO = dyn_cast<BinaryOperator>(RHS)) {
2515 if (BO->isAdditiveOp()) {
2516 bool IsAdd = BO->getOpcode() ==
BO_Add;
2517 if (GetInitVarDecl(BO->getLHS()) == Var)
2518 return SetStep(BO->getRHS(), !IsAdd);
2519 if (IsAdd && GetInitVarDecl(BO->getRHS()) == Var)
2520 return SetStep(BO->getLHS(),
false);
2522 }
else if (
auto CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
2523 bool IsAdd = CE->getOperator() == OO_Plus;
2524 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
2525 if (GetInitVarDecl(CE->getArg(0)) == Var)
2526 return SetStep(CE->getArg(1), !IsAdd);
2527 if (IsAdd && GetInitVarDecl(CE->getArg(1)) == Var)
2528 return SetStep(CE->getArg(0),
false);
2531 SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr)
2532 << RHS->getSourceRange() << Var;
2536 bool OpenMPIterationSpaceChecker::CheckInc(
Expr *S) {
2551 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << Var;
2554 IncrementSrcRange = S->getSourceRange();
2556 if (
auto UO = dyn_cast<UnaryOperator>(S)) {
2557 if (UO->isIncrementDecrementOp() && GetInitVarDecl(UO->getSubExpr()) == Var)
2559 SemaRef.ActOnIntegerConstant(UO->getLocStart(),
2560 (UO->isDecrementOp() ? -1 : 1)).get(),
2562 }
else if (
auto BO = dyn_cast<BinaryOperator>(S)) {
2563 switch (BO->getOpcode()) {
2566 if (GetInitVarDecl(BO->getLHS()) == Var)
2567 return SetStep(BO->getRHS(), BO->getOpcode() ==
BO_SubAssign);
2570 if (GetInitVarDecl(BO->getLHS()) == Var)
2571 return CheckIncRHS(BO->getRHS());
2576 }
else if (
auto CE = dyn_cast<CXXOperatorCallExpr>(S)) {
2577 switch (CE->getOperator()) {
2580 if (GetInitVarDecl(CE->getArg(0)) == Var)
2582 SemaRef.ActOnIntegerConstant(
2584 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)).
get(),
2589 if (GetInitVarDecl(CE->getArg(0)) == Var)
2590 return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
2593 if (GetInitVarDecl(CE->getArg(0)) == Var)
2594 return CheckIncRHS(CE->getArg(1));
2600 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr)
2601 << S->getSourceRange() << Var;
2608 class TransformToNewDefs :
public TreeTransform<TransformToNewDefs> {
2612 TransformToNewDefs(
Sema &SemaRef) : BaseTransform(SemaRef) {}
2615 if (
auto *VD = cast<VarDecl>(D))
2616 if (!isa<ParmVarDecl>(D) && !isa<VarTemplateSpecializationDecl>(D) &&
2617 !isa<ImplicitParamDecl>(D)) {
2619 SemaRef.Context, VD->getDeclContext(), VD->getLocStart(),
2620 VD->getLocation(), VD->getIdentifier(), VD->getType(),
2621 VD->getTypeSourceInfo(), VD->getStorageClass());
2623 NewVD->setInit(VD->getInit());
2624 NewVD->setInitStyle(VD->getInitStyle());
2625 NewVD->setExceptionVariable(VD->isExceptionVariable());
2626 NewVD->setNRVOVariable(VD->isNRVOVariable());
2627 NewVD->setCXXForRangeDecl(VD->isInExternCXXContext());
2628 NewVD->setConstexpr(VD->isConstexpr());
2629 NewVD->setInitCapture(VD->isInitCapture());
2630 NewVD->setPreviousDeclInSameBlockScope(
2631 VD->isPreviousDeclInSameBlockScope());
2632 VD->getDeclContext()->addHiddenDecl(NewVD);
2633 transformedLocalDecl(VD, NewVD);
2636 return BaseTransform::TransformDefinition(Loc, D);
2642 NewD->setReferenced();
2643 NewD->markUsed(SemaRef.Context);
2649 return BaseTransform::TransformDeclRefExpr(E);
2656 OpenMPIterationSpaceChecker::BuildNumIterations(
Scope *S,
2657 const bool LimitedType)
const {
2658 TransformToNewDefs Transform(SemaRef);
2660 auto VarType = Var->getType().getNonReferenceType();
2661 if (VarType->isIntegerType() || VarType->isPointerType() ||
2662 SemaRef.getLangOpts().CPlusPlus) {
2664 auto *UBExpr = TestIsLessOp ? UB : LB;
2665 auto *LBExpr = TestIsLessOp ? LB : UB;
2666 Expr *Upper = Transform.TransformExpr(UBExpr).get();
2667 Expr *Lower = Transform.TransformExpr(LBExpr).get();
2668 if (!Upper || !Lower)
2670 Upper = SemaRef.PerformImplicitConversion(Upper, UBExpr->
getType(),
2674 Lower = SemaRef.PerformImplicitConversion(Lower, LBExpr->
getType(),
2678 if (!Upper || !Lower)
2681 Diff = SemaRef.BuildBinOp(S, DefaultLoc,
BO_Sub, Upper, Lower);
2683 if (!Diff.
isUsable() && VarType->getAsCXXRecordDecl()) {
2686 SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx)
2687 << Upper->getSourceRange() << Lower->getSourceRange();
2697 Diff = SemaRef.BuildBinOp(
2704 auto NewStep = Transform.TransformExpr(
Step->IgnoreImplicit());
2705 if (NewStep.isInvalid())
2707 NewStep = SemaRef.PerformImplicitConversion(
2710 if (NewStep.isInvalid())
2712 Diff = SemaRef.BuildBinOp(S, DefaultLoc,
BO_Add, Diff.
get(), NewStep.get());
2717 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.
get());
2722 NewStep = Transform.TransformExpr(
Step->IgnoreImplicit());
2723 if (NewStep.isInvalid())
2725 NewStep = SemaRef.PerformImplicitConversion(
2728 if (NewStep.isInvalid())
2730 Diff = SemaRef.BuildBinOp(S, DefaultLoc,
BO_Div, Diff.
get(), NewStep.get());
2736 auto &
C = SemaRef.Context;
2737 bool UseVarType = VarType->hasIntegerRepresentation() &&
2738 C.getTypeSize(Type) >
C.getTypeSize(VarType);
2741 UseVarType ?
C.getTypeSize(VarType) :
C.getTypeSize(Type);
2742 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
2744 Type =
C.getIntTypeForBitwidth(NewSize, IsSigned);
2745 Diff = SemaRef.PerformImplicitConversion(
2751 unsigned NewSize = (
C.getTypeSize(Type) > 32) ? 64 : 32;
2752 if (NewSize !=
C.getTypeSize(Type)) {
2753 if (NewSize <
C.getTypeSize(Type)) {
2754 assert(NewSize == 64 &&
"incorrect loop var size");
2755 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
2756 << InitSrcRange << ConditionSrcRange;
2758 QualType NewType =
C.getIntTypeForBitwidth(
2760 C.getTypeSize(Type) < NewSize);
2761 Diff = SemaRef.PerformImplicitConversion(Diff.
get(), NewType,
2771 Expr *OpenMPIterationSpaceChecker::BuildPreCond(
Scope *S,
Expr *Cond)
const {
2773 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
2774 SemaRef.getDiagnostics().setSuppressAllDiagnostics(
true);
2775 TransformToNewDefs Transform(SemaRef);
2777 auto NewLB = Transform.TransformExpr(LB);
2778 auto NewUB = Transform.TransformExpr(UB);
2779 if (NewLB.isInvalid() || NewUB.isInvalid())
2781 NewLB = SemaRef.PerformImplicitConversion(NewLB.get(), LB->
getType(),
2784 NewUB = SemaRef.PerformImplicitConversion(NewUB.get(), UB->
getType(),
2787 if (NewLB.isInvalid() || NewUB.isInvalid())
2789 auto CondExpr = SemaRef.BuildBinOp(
2790 S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ?
BO_LT :
BO_LE)
2792 NewLB.get(), NewUB.get());
2793 if (CondExpr.isUsable()) {
2794 CondExpr = SemaRef.PerformImplicitConversion(
2798 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
2800 return CondExpr.isUsable() ? CondExpr.get() : Cond;
2804 Expr *OpenMPIterationSpaceChecker::BuildCounterVar()
const {
2812 Expr *OpenMPIterationSpaceChecker::BuildCounterStep()
const {
return Step; }
2815 struct LoopIterationSpace {
2820 Expr *NumIterations;
2841 assert(
getLangOpts().OpenMP &&
"OpenMP is not active.");
2842 assert(Init &&
"Expected loop in canonical form.");
2843 unsigned CollapseIteration =
DSAStack->getCollapseNumber();
2844 if (CollapseIteration > 0 &&
2846 OpenMPIterationSpaceChecker ISC(*
this, ForLoc);
2847 if (!ISC.CheckInit(Init,
false)) {
2848 DSAStack->addLoopControlVariable(ISC.GetLoopVar());
2850 DSAStack->setCollapseNumber(CollapseIteration - 1);
2858 unsigned CurrentNestedLoopCount,
unsigned NestedLoopCount,
2859 Expr *NestedLoopCountExpr,
2860 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA,
2861 LoopIterationSpace &ResultIterSpace) {
2864 auto For = dyn_cast_or_null<ForStmt>(
S);
2866 SemaRef.
Diag(S->getLocStart(), diag::err_omp_not_for)
2868 << NestedLoopCount << (CurrentNestedLoopCount > 0)
2869 << CurrentNestedLoopCount;
2870 if (NestedLoopCount > 1)
2872 diag::note_omp_collapse_expr)
2873 << NestedLoopCountExpr->getSourceRange();
2876 assert(For->getBody());
2878 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
2881 auto Init = For->getInit();
2882 if (ISC.CheckInit(Init)) {
2886 bool HasErrors =
false;
2889 auto Var = ISC.GetLoopVar();
2896 auto VarType = Var->
getType();
2897 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
2898 !VarType->isPointerType() &&
2899 !(SemaRef.
getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
2900 SemaRef.
Diag(Init->getLocStart(), diag::err_omp_loop_variable_type)
2914 VarsWithImplicitDSA.erase(Var);
2923 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(Var,
false);
2924 auto LoopVarRefExpr = ISC.GetLoopVarRefExpr();
2927 auto PredeterminedCKind =
2929 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
2934 DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_private &&
2937 DVar.RefExpr !=
nullptr)) {
2938 SemaRef.
Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa)
2941 if (DVar.RefExpr ==
nullptr)
2942 DVar.CKind = PredeterminedCKind;
2945 }
else if (LoopVarRefExpr !=
nullptr) {
2952 DSA.addDSA(Var, LoopVarRefExpr, PredeterminedCKind);
2958 HasErrors |= ISC.CheckCond(For->getCond());
2961 HasErrors |= ISC.CheckInc(For->getInc());
2967 ResultIterSpace.PreCond = ISC.BuildPreCond(DSA.getCurScope(), For->getCond());
2968 ResultIterSpace.NumIterations = ISC.BuildNumIterations(
2970 ResultIterSpace.CounterVar = ISC.BuildCounterVar();
2971 ResultIterSpace.CounterInit = ISC.BuildCounterInit();
2972 ResultIterSpace.CounterStep = ISC.BuildCounterStep();
2973 ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange();
2974 ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange();
2975 ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange();
2976 ResultIterSpace.Subtract = ISC.ShouldSubtractStep();
2978 HasErrors |= (ResultIterSpace.PreCond ==
nullptr ||
2979 ResultIterSpace.NumIterations ==
nullptr ||
2980 ResultIterSpace.CounterVar ==
nullptr ||
2981 ResultIterSpace.CounterInit ==
nullptr ||
2982 ResultIterSpace.CounterStep ==
nullptr);
2990 TransformToNewDefs Transform(SemaRef);
2993 if (NewStart.isInvalid())
2999 if (NewStart.isInvalid())
3004 if (!NewStart.isUsable())
3023 TransformToNewDefs Transform(SemaRef);
3025 if (NewStep.isInvalid())
3031 if (NewStep.isInvalid())
3040 if (NewStart.isInvalid())
3046 if (NewStart.isInvalid())
3049 NewStart.get(), Update.
get());
3070 unsigned HasBits =
C.getTypeSize(OldType);
3071 if (HasBits >= Bits)
3074 QualType NewType =
C.getIntTypeForBitwidth(Bits,
true);
3086 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
3095 Stmt *AStmt,
Sema &SemaRef, DSAStackTy &DSA,
3096 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA,
3098 unsigned NestedLoopCount = 1;
3099 if (NestedLoopCountExpr) {
3103 NestedLoopCount = Result.getLimitedValue();
3108 IterSpaces.resize(NestedLoopCount);
3109 Stmt *CurStmt = AStmt->IgnoreContainers(
true);
3110 for (
unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
3112 NestedLoopCount, NestedLoopCountExpr,
3113 VarsWithImplicitDSA, IterSpaces[Cnt]))
3120 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
3123 Built.
clear( NestedLoopCount);
3126 return NestedLoopCount;
3158 auto PreCond =
ExprResult(IterSpaces[0].PreCond);
3159 auto N0 = IterSpaces[0].NumIterations;
3162 N0->IgnoreImpCasts(), N0->getType(),
3168 N0->IgnoreImpCasts(), N0->getType(),
3173 if (!LastIteration32.
isUsable() || !LastIteration64.isUsable())
3174 return NestedLoopCount;
3177 bool AllCountsNeedLessThan32Bits =
C.getTypeSize(N0->getType()) < 32;
3179 Scope *CurScope = DSA.getCurScope();
3180 for (
unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
3181 if (PreCond.isUsable()) {
3183 PreCond.get(), IterSpaces[Cnt].PreCond);
3185 auto N = IterSpaces[Cnt].NumIterations;
3186 AllCountsNeedLessThan32Bits &=
C.getTypeSize(N->getType()) < 32;
3194 if (LastIteration64.isUsable())
3206 C.getTypeSize(LastIteration32.
get()->
getType()) == 32 &&
3207 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
3211 LastIteration64.get(), SemaRef)))
3212 LastIteration = LastIteration32;
3237 ".omp.last.iteration");
3239 SemaRef, SaveVar, LastIteration.
get()->
getType(), SaveLoc);
3241 SaveRef.get(), LastIteration.
get());
3242 LastIteration = SaveRef;
3246 CurScope, SaveLoc,
BO_Add, SaveRef.get(),
3291 UB.
get(), LastIteration.
get());
3293 InitLoc, InitLoc, IsUBGreater.
get(), LastIteration.
get(), UB.
get());
3318 NumIterations.
get());
3359 bool HasErrors =
false;
3360 Built.
Counters.resize(NestedLoopCount);
3361 Built.
Inits.resize(NestedLoopCount);
3362 Built.
Updates.resize(NestedLoopCount);
3363 Built.
Finals.resize(NestedLoopCount);
3367 for (
int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
3368 LoopIterationSpace &IS = IterSpaces[Cnt];
3378 assert((Cnt == (
int)NestedLoopCount - 1) &&
3379 "unusable div expected on first iteration only");
3392 SemaRef, cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()),
3393 IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
3397 if (!Init.isUsable()) {
3403 IS.CounterInit, Iter, IS.CounterStep, IS.Subtract);
3411 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
3412 IS.NumIterations, IS.CounterStep, IS.Subtract);
3421 Div = IS.NumIterations;
3439 Built.
Counters[Cnt] = IS.CounterVar;
3440 Built.
Inits[Cnt] = Init.get();
3455 Built.
PreCond = PreCond.get();
3459 Built.
LB = LB.
get();
3460 Built.
UB = UB.
get();
3461 Built.
IL = IL.
get();
3462 Built.
ST = ST.
get();
3464 Built.
NLB = NextLB.
get();
3465 Built.
NUB = NextUB.
get();
3467 return NestedLoopCount;
3471 auto &&CollapseFilter = [](
const OMPClause *
C) ->
bool {
3472 return C->getClauseKind() == OMPC_collapse;
3475 Clauses, std::move(CollapseFilter));
3477 return cast<OMPCollapseClause>(*I)->getNumForLoops();
3484 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
3487 unsigned NestedLoopCount =
3489 *
DSAStack, VarsWithImplicitDSA, B);
3490 if (NestedLoopCount == 0)
3494 "omp simd loop exprs were not built");
3498 for (
auto C : Clauses) {
3499 if (
auto LC = dyn_cast<OMPLinearClause>(
C))
3514 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
3517 unsigned NestedLoopCount =
3519 *
DSAStack, VarsWithImplicitDSA, B);
3520 if (NestedLoopCount == 0)
3524 "omp for loop exprs were not built");
3534 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
3537 unsigned NestedLoopCount =
3539 *
this, *
DSAStack, VarsWithImplicitDSA, B);
3540 if (NestedLoopCount == 0)
3544 "omp for simd loop exprs were not built");
3548 for (
auto C : Clauses) {
3549 if (
auto LC = dyn_cast<OMPLinearClause>(
C))
3565 assert(AStmt && isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
3566 auto BaseStmt = AStmt;
3567 while (
CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
3568 BaseStmt = CS->getCapturedStmt();
3569 if (
auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
3570 auto S =
C->children();
3575 for (
Stmt *SectionStmt : ++S) {
3576 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
3578 Diag(SectionStmt->getLocStart(),
3579 diag::err_omp_sections_substmt_not_section);
3584 Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt);
3597 assert(AStmt && isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
3608 assert(AStmt && isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
3616 for (
auto *Clause : Clauses) {
3617 if (Clause->getClauseKind() == OMPC_nowait)
3619 else if (Clause->getClauseKind() == OMPC_copyprivate)
3620 Copyprivate = Clause;
3621 if (Copyprivate && Nowait) {
3623 diag::err_omp_single_copyprivate_with_nowait);
3635 assert(AStmt && isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
3646 assert(AStmt && isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
3657 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
3658 assert(AStmt && isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
3669 unsigned NestedLoopCount =
3671 *
this, *
DSAStack, VarsWithImplicitDSA, B);
3672 if (NestedLoopCount == 0)
3676 "omp parallel for loop exprs were not built");
3680 NestedLoopCount, Clauses, AStmt, B);
3686 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
3687 assert(AStmt && isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
3698 unsigned NestedLoopCount =
3700 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
3701 if (NestedLoopCount == 0)
3706 for (
auto C : Clauses) {
3707 if (
auto LC = dyn_cast<OMPLinearClause>(
C))
3716 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
3723 assert(AStmt && isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
3724 auto BaseStmt = AStmt;
3725 while (
CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
3726 BaseStmt = CS->getCapturedStmt();
3727 if (
auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
3728 auto S =
C->children();
3733 for (
Stmt *SectionStmt : ++S) {
3734 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
3736 Diag(SectionStmt->getLocStart(),
3737 diag::err_omp_parallel_sections_substmt_not_section);
3742 Diag(AStmt->getLocStart(),
3743 diag::err_omp_parallel_sections_not_compound_stmt);
3756 assert(AStmt && isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
3788 assert(AStmt && isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
3798 assert(Clauses.size() <= 1 &&
"Extra clauses in flush directive");
3805 assert(AStmt && isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
3815 class OpenMPAtomicUpdateChecker {
3817 enum ExprAnalysisErrorCode {
3821 NotABinaryOrUnaryExpression,
3823 NotAnUnaryIncDecExpression,
3829 NotABinaryExpression,
3835 NotAnUpdateExpression,
3853 bool IsXLHSInRHSPart;
3858 bool IsPostfixUpdate;
3861 OpenMPAtomicUpdateChecker(
Sema &SemaRef)
3862 : SemaRef(SemaRef),
X(nullptr), E(nullptr), UpdateExpr(nullptr),
3871 bool checkStatement(
Stmt *S,
unsigned DiagId = 0,
unsigned NoteId = 0);
3873 Expr *getX()
const {
return X; }
3875 Expr *getExpr()
const {
return E; }
3879 Expr *getUpdateExpr()
const {
return UpdateExpr; }
3882 bool isXLHSInRHSPart()
const {
return IsXLHSInRHSPart; }
3886 bool isPostfixUpdate()
const {
return IsPostfixUpdate; }
3889 bool checkBinaryOperation(
BinaryOperator *AtomicBinOp,
unsigned DiagId = 0,
3890 unsigned NoteId = 0);
3894 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
3896 ExprAnalysisErrorCode ErrorFound = NoError;
3904 if (
auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
3906 if (AtomicInnerBinOp->isMultiplicativeOp() ||
3907 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
3908 AtomicInnerBinOp->isBitwiseOp()) {
3909 Op = AtomicInnerBinOp->getOpcode();
3910 OpLoc = AtomicInnerBinOp->getOperatorLoc();
3911 auto *LHS = AtomicInnerBinOp->getLHS();
3912 auto *RHS = AtomicInnerBinOp->getRHS();
3913 llvm::FoldingSetNodeID XId, LHSId, RHSId;
3914 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
3916 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
3922 IsXLHSInRHSPart =
true;
3923 }
else if (XId == RHSId) {
3925 IsXLHSInRHSPart =
false;
3927 ErrorLoc = AtomicInnerBinOp->getExprLoc();
3928 ErrorRange = AtomicInnerBinOp->getSourceRange();
3929 NoteLoc =
X->getExprLoc();
3930 NoteRange =
X->getSourceRange();
3931 ErrorFound = NotAnUpdateExpression;
3934 ErrorLoc = AtomicInnerBinOp->getExprLoc();
3935 ErrorRange = AtomicInnerBinOp->getSourceRange();
3936 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
3938 ErrorFound = NotABinaryOperator;
3942 NoteRange = ErrorRange = AtomicBinOp->
getRHS()->getSourceRange();
3943 ErrorFound = NotABinaryExpression;
3947 ErrorRange = AtomicBinOp->getSourceRange();
3950 ErrorFound = NotAnAssignmentOp;
3952 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
3953 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
3954 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
3956 }
else if (SemaRef.CurContext->isDependentContext())
3957 E =
X = UpdateExpr =
nullptr;
3958 return ErrorFound != NoError;
3961 bool OpenMPAtomicUpdateChecker::checkStatement(
Stmt *S,
unsigned DiagId,
3963 ExprAnalysisErrorCode ErrorFound = NoError;
3974 if (
auto *AtomicBody = dyn_cast<Expr>(S)) {
3975 AtomicBody = AtomicBody->IgnoreParenImpCasts();
3976 if (AtomicBody->getType()->isScalarType() ||
3977 AtomicBody->isInstantiationDependent()) {
3978 if (
auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
3979 AtomicBody->IgnoreParenImpCasts())) {
3982 AtomicCompAssignOp->getOpcode());
3983 OpLoc = AtomicCompAssignOp->getOperatorLoc();
3984 E = AtomicCompAssignOp->getRHS();
3985 X = AtomicCompAssignOp->getLHS();
3986 IsXLHSInRHSPart =
true;
3987 }
else if (
auto *AtomicBinOp = dyn_cast<BinaryOperator>(
3988 AtomicBody->IgnoreParenImpCasts())) {
3990 if(checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
3992 }
else if (
auto *AtomicUnaryOp =
3993 dyn_cast<UnaryOperator>(AtomicBody->IgnoreParenImpCasts())) {
3995 if (AtomicUnaryOp->isIncrementDecrementOp()) {
3996 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
3998 OpLoc = AtomicUnaryOp->getOperatorLoc();
3999 X = AtomicUnaryOp->getSubExpr();
4000 E = SemaRef.ActOnIntegerConstant(OpLoc, 1).get();
4001 IsXLHSInRHSPart =
true;
4003 ErrorFound = NotAnUnaryIncDecExpression;
4004 ErrorLoc = AtomicUnaryOp->getExprLoc();
4005 ErrorRange = AtomicUnaryOp->getSourceRange();
4006 NoteLoc = AtomicUnaryOp->getOperatorLoc();
4010 ErrorFound = NotABinaryOrUnaryExpression;
4011 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
4012 NoteRange = ErrorRange = AtomicBody->getSourceRange();
4015 ErrorFound = NotAScalarType;
4016 NoteLoc = ErrorLoc = AtomicBody->getLocStart();
4017 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
4020 ErrorFound = NotAnExpression;
4021 NoteLoc = ErrorLoc = S->getLocStart();
4022 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
4024 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
4025 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
4026 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
4028 }
else if (SemaRef.CurContext->isDependentContext())
4029 E =
X = UpdateExpr =
nullptr;
4030 if (ErrorFound == NoError && E &&
X) {
4034 auto *OVEX =
new (SemaRef.getASTContext())
4036 auto *OVEExpr =
new (SemaRef.getASTContext())
4039 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
4040 IsXLHSInRHSPart ? OVEExpr : OVEX);
4041 if (Update.isInvalid())
4043 Update = SemaRef.PerformImplicitConversion(Update.get(),
X->getType(),
4045 if (Update.isInvalid())
4047 UpdateExpr = Update.get();
4049 return ErrorFound != NoError;
4056 assert(AStmt && isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
4057 auto CS = cast<CapturedStmt>(AStmt);
4065 for (
auto *
C : Clauses) {
4066 if (
C->getClauseKind() == OMPC_read ||
C->getClauseKind() == OMPC_write ||
4067 C->getClauseKind() == OMPC_update ||
4068 C->getClauseKind() == OMPC_capture) {
4070 Diag(
C->getLocStart(), diag::err_omp_atomic_several_clauses)
4072 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
4075 AtomicKind =
C->getClauseKind();
4076 AtomicKindLoc =
C->getLocStart();
4081 auto Body = CS->getCapturedStmt();
4082 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Body))
4083 Body = EWC->getSubExpr();
4089 bool IsXLHSInRHSPart =
false;
4090 bool IsPostfixUpdate =
false;
4113 if (AtomicKind == OMPC_read) {
4120 } ErrorFound = NoError;
4125 if (
auto AtomicBody = dyn_cast<Expr>(Body)) {
4134 auto NotLValueExpr = X->
isLValue() ? V :
X;
4135 ErrorFound = NotAnLValue;
4137 ErrorRange = AtomicBinOp->getSourceRange();
4138 NoteLoc = NotLValueExpr->getExprLoc();
4139 NoteRange = NotLValueExpr->getSourceRange();
4143 auto NotScalarExpr =
4147 ErrorFound = NotAScalarType;
4149 ErrorRange = AtomicBinOp->getSourceRange();
4150 NoteLoc = NotScalarExpr->getExprLoc();
4151 NoteRange = NotScalarExpr->getSourceRange();
4154 ErrorFound = NotAnAssignmentOp;
4155 ErrorLoc = AtomicBody->getExprLoc();
4156 ErrorRange = AtomicBody->getSourceRange();
4158 : AtomicBody->getExprLoc();
4159 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
4160 : AtomicBody->getSourceRange();
4163 ErrorFound = NotAnExpression;
4164 NoteLoc = ErrorLoc = Body->getLocStart();
4165 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
4167 if (ErrorFound != NoError) {
4168 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
4170 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
4175 }
else if (AtomicKind == OMPC_write) {
4182 } ErrorFound = NoError;
4187 if (
auto AtomicBody = dyn_cast<Expr>(Body)) {
4191 X = AtomicBinOp->
getLHS();
4192 E = AtomicBinOp->
getRHS();
4196 ErrorFound = NotAnLValue;
4198 ErrorRange = AtomicBinOp->getSourceRange();
4200 NoteRange = X->getSourceRange();
4204 auto NotScalarExpr =
4208 ErrorFound = NotAScalarType;
4210 ErrorRange = AtomicBinOp->getSourceRange();
4211 NoteLoc = NotScalarExpr->getExprLoc();
4212 NoteRange = NotScalarExpr->getSourceRange();
4215 ErrorFound = NotAnAssignmentOp;
4216 ErrorLoc = AtomicBody->getExprLoc();
4217 ErrorRange = AtomicBody->getSourceRange();
4219 : AtomicBody->getExprLoc();
4220 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
4221 : AtomicBody->getSourceRange();
4224 ErrorFound = NotAnExpression;
4225 NoteLoc = ErrorLoc = Body->getLocStart();
4226 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
4228 if (ErrorFound != NoError) {
4229 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
4231 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
4236 }
else if (AtomicKind == OMPC_update || AtomicKind ==
OMPC_unknown) {
4245 OpenMPAtomicUpdateChecker Checker(*
this);
4246 if (Checker.checkStatement(
4247 Body, (AtomicKind == OMPC_update)
4248 ? diag::err_omp_atomic_update_not_expression_statement
4249 : diag::err_omp_atomic_not_expression_statement,
4250 diag::note_omp_atomic_update))
4253 E = Checker.getExpr();
4255 UE = Checker.getUpdateExpr();
4256 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
4258 }
else if (AtomicKind == OMPC_capture) {
4261 NotACompoundStatement,
4262 NotTwoSubstatements,
4263 NotASpecificExpression,
4265 } ErrorFound = NoError;
4268 if (
auto *AtomicBody = dyn_cast<Expr>(Body)) {
4280 V = AtomicBinOp->
getLHS();
4282 OpenMPAtomicUpdateChecker Checker(*
this);
4283 if (Checker.checkStatement(
4284 Body, diag::err_omp_atomic_capture_not_expression_statement,
4285 diag::note_omp_atomic_update))
4287 E = Checker.getExpr();
4289 UE = Checker.getUpdateExpr();
4290 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
4291 IsPostfixUpdate = Checker.isPostfixUpdate();
4293 ErrorLoc = AtomicBody->getExprLoc();
4294 ErrorRange = AtomicBody->getSourceRange();
4296 : AtomicBody->getExprLoc();
4297 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
4298 : AtomicBody->getSourceRange();
4299 ErrorFound = NotAnAssignmentOp;
4301 if (ErrorFound != NoError) {
4302 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
4304 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
4307 UE = V = E = X =
nullptr;
4326 if (
auto *CS = dyn_cast<CompoundStmt>(Body)) {
4328 if (CS->size() == 2) {
4329 auto *First = CS->body_front();
4330 auto *Second = CS->body_back();
4331 if (
auto *EWC = dyn_cast<ExprWithCleanups>(First))
4333 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Second))
4336 OpenMPAtomicUpdateChecker Checker(*
this);
4337 bool IsUpdateExprFound = !Checker.checkStatement(Second);
4339 if (IsUpdateExprFound) {
4353 llvm::FoldingSetNodeID XId, PossibleXId;
4354 Checker.getX()->Profile(XId,
Context,
true);
4355 PossibleX->Profile(PossibleXId,
Context,
true);
4356 IsUpdateExprFound = XId == PossibleXId;
4357 if (IsUpdateExprFound) {
4360 E = Checker.getExpr();
4361 UE = Checker.getUpdateExpr();
4362 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
4363 IsPostfixUpdate =
true;
4366 if (!IsUpdateExprFound) {
4367 IsUpdateExprFound = !Checker.checkStatement(First);
4369 if (IsUpdateExprFound) {
4383 llvm::FoldingSetNodeID XId, PossibleXId;
4384 Checker.getX()->Profile(XId,
Context,
true);
4385 PossibleX->Profile(PossibleXId,
Context,
true);
4386 IsUpdateExprFound = XId == PossibleXId;
4387 if (IsUpdateExprFound) {
4390 E = Checker.getExpr();
4391 UE = Checker.getUpdateExpr();
4392 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
4393 IsPostfixUpdate =
false;
4397 if (!IsUpdateExprFound) {
4400 if (!FirstBinOp || FirstBinOp->getOpcode() !=
BO_Assign) {
4401 ErrorFound = NotAnAssignmentOp;
4402 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
4403 : First->getLocStart();
4404 NoteRange = ErrorRange = FirstBinOp
4405 ? FirstBinOp->getSourceRange()
4409 if (!SecondBinOp || SecondBinOp->getOpcode() !=
BO_Assign) {
4410 ErrorFound = NotAnAssignmentOp;
4411 NoteLoc = ErrorLoc = SecondBinOp ? SecondBinOp->getOperatorLoc()
4412 : Second->getLocStart();
4413 NoteRange = ErrorRange = SecondBinOp
4414 ? SecondBinOp->getSourceRange()
4417 auto *PossibleXRHSInFirst =
4418 FirstBinOp->getRHS()->IgnoreParenImpCasts();
4419 auto *PossibleXLHSInSecond =
4420 SecondBinOp->getLHS()->IgnoreParenImpCasts();
4421 llvm::FoldingSetNodeID X1Id, X2Id;
4422 PossibleXRHSInFirst->Profile(X1Id,
Context,
true);
4423 PossibleXLHSInSecond->Profile(X2Id,
Context,
4425 IsUpdateExprFound = X1Id == X2Id;
4426 if (IsUpdateExprFound) {
4427 V = FirstBinOp->getLHS();
4428 X = SecondBinOp->getLHS();
4429 E = SecondBinOp->getRHS();
4431 IsXLHSInRHSPart =
false;
4432 IsPostfixUpdate =
true;
4434 ErrorFound = NotASpecificExpression;
4435 ErrorLoc = FirstBinOp->getExprLoc();
4436 ErrorRange = FirstBinOp->getSourceRange();
4437 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
4438 NoteRange = SecondBinOp->getRHS()->getSourceRange();
4444 NoteLoc = ErrorLoc = Body->getLocStart();
4445 NoteRange = ErrorRange =
4446 SourceRange(Body->getLocStart(), Body->getLocStart());
4447 ErrorFound = NotTwoSubstatements;
4450 NoteLoc = ErrorLoc = Body->getLocStart();
4451 NoteRange = ErrorRange =
4452 SourceRange(Body->getLocStart(), Body->getLocStart());
4453 ErrorFound = NotACompoundStatement;
4455 if (ErrorFound != NoError) {
4456 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
4458 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
4461 UE = V = E = X =
nullptr;
4469 X, V, E, UE, IsXLHSInRHSPart,
4477 assert(AStmt && isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
4483 if (
DSAStack->hasInnerTeamsRegion()) {
4484 auto S = AStmt->IgnoreContainers(
true);
4485 bool OMPTeamsFound =
true;
4486 if (
auto *CS = dyn_cast<CompoundStmt>(S)) {
4487 auto I = CS->body_begin();
4488 while (I != CS->body_end()) {
4491 OMPTeamsFound =
false;
4496 assert(I != CS->body_end() &&
"Not found statement");
4499 if (!OMPTeamsFound) {
4500 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
4502 diag::note_omp_nested_teams_construct_here);
4503 Diag(S->getLocStart(), diag::note_omp_nested_statement_here)
4504 << isa<OMPExecutableDirective>(S);
4517 assert(AStmt && isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
4535 if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for &&
4536 CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) {
4537 Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4541 if (
DSAStack->isParentNowaitRegion()) {
4542 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
4545 if (
DSAStack->isParentOrderedRegion()) {
4546 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
4556 if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for &&
4557 CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) {
4558 Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4562 if (
DSAStack->isParentNowaitRegion()) {
4563 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
4566 if (
DSAStack->isParentOrderedRegion()) {
4567 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
4585 case OMPC_num_threads:
4595 case OMPC_proc_bind:
4598 case OMPC_firstprivate:
4599 case OMPC_lastprivate:
4601 case OMPC_reduction:
4605 case OMPC_copyprivate:
4609 case OMPC_mergeable:
4619 llvm_unreachable(
"Clause is not allowed.");
4627 Expr *ValExpr = Condition;
4636 ValExpr = Val.
get();
4646 Expr *ValExpr = Condition;
4655 ValExpr = Val.
get();
4667 IntConvertDiagnoser()
4671 return S.
Diag(Loc, diag::err_omp_not_integral) << T;
4675 return S.
Diag(Loc, diag::err_omp_incomplete_type) << T;
4680 return S.
Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
4689 return S.
Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
4698 llvm_unreachable(
"conversion functions are permitted");
4708 Expr *ValExpr = NumThreads;
4717 ValExpr = Val.
get();
4723 !Result.isStrictlyPositive()) {
4724 Diag(NumThreadsLoc, diag::err_omp_negative_expression_in_clause)
4725 <<
"num_threads" << NumThreads->getSourceRange();
4745 if (!Result.isStrictlyPositive()) {
4746 Diag(E->
getExprLoc(), diag::err_omp_negative_expression_in_clause)
4750 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
4752 << E->getSourceRange();
4755 if (CKind == OMPC_collapse) {
4756 DSAStack->setCollapseNumber(Result.getExtValue());
4767 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
4784 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
4799 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
4801 case OMPC_proc_bind:
4803 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
4808 case OMPC_num_threads:
4813 case OMPC_firstprivate:
4814 case OMPC_lastprivate:
4816 case OMPC_reduction:
4820 case OMPC_copyprivate:
4824 case OMPC_mergeable:
4834 llvm_unreachable(
"Clause is not allowed.");
4847 "OMPC_DEFAULT_unknown not greater than 0");
4848 std::string Sep(
", ");
4854 case OMPC_DEFAULT_unknown - 2:
4857 case OMPC_DEFAULT_unknown - 1:
4864 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
4869 case OMPC_DEFAULT_none:
4870 DSAStack->setDefaultDSANone(KindKwLoc);
4872 case OMPC_DEFAULT_shared:
4873 DSAStack->setDefaultDSAShared(KindKwLoc);
4876 llvm_unreachable(
"Clause kind is not allowed.");
4890 std::string Sep(
", ");
4896 case OMPC_PROC_BIND_unknown - 2:
4899 case OMPC_PROC_BIND_unknown - 1:
4906 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
4923 static_cast<OpenMPScheduleClauseKind>(Argument), Expr, StartLoc,
4924 LParenLoc, ArgumentLoc, CommaLoc, EndLoc);
4928 case OMPC_num_threads:
4932 case OMPC_proc_bind:
4934 case OMPC_firstprivate:
4935 case OMPC_lastprivate:
4937 case OMPC_reduction:
4941 case OMPC_copyprivate:
4945 case OMPC_mergeable:
4955 llvm_unreachable(
"Clause is not allowed.");
4966 std::string Sep(
", ");
4972 case OMPC_SCHEDULE_unknown - 2:
4975 case OMPC_SCHEDULE_unknown - 1:
4982 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
4986 Expr *ValExpr = ChunkSize;
4987 Expr *HelperValExpr =
nullptr;
4998 ValExpr = Val.
get();
5005 if (Result.isSigned() && !Result.isStrictlyPositive()) {
5006 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
5007 <<
"schedule" << ChunkSize->getSourceRange();
5010 }
else if (isParallelOrTaskRegion(
DSAStack->getCurrentDirective())) {
5012 ChunkSize->
getType(),
".chunk.");
5016 HelperValExpr = ImpVarRef;
5022 EndLoc, Kind, ValExpr, HelperValExpr);
5039 case OMPC_mergeable:
5059 case OMPC_num_threads:
5064 case OMPC_firstprivate:
5065 case OMPC_lastprivate:
5067 case OMPC_reduction:
5071 case OMPC_copyprivate:
5073 case OMPC_proc_bind:
5078 llvm_unreachable(
"Clause is not allowed.");
5141 case OMPC_firstprivate:
5144 case OMPC_lastprivate:
5150 case OMPC_reduction:
5152 EndLoc, ReductionIdScopeSpec, ReductionId);
5165 case OMPC_copyprivate:
5177 case OMPC_num_threads:
5181 case OMPC_proc_bind:
5186 case OMPC_mergeable:
5194 llvm_unreachable(
"Clause is not allowed.");
5205 for (
auto &RefExpr : VarList) {
5206 assert(RefExpr &&
"NULL expr in OpenMP private clause.");
5207 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
5209 Vars.push_back(RefExpr);
5210 PrivateCopies.push_back(
nullptr);
5220 DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5221 if (!DE || !isa<VarDecl>(DE->
getDecl())) {
5222 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
5226 VarDecl *VD = cast<VarDecl>(D);
5229 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
5232 PrivateCopies.push_back(
nullptr);
5240 diag::err_omp_private_incomplete_type)) {
5243 if (Type->isReferenceType()) {
5244 Diag(ELoc, diag::err_omp_clause_ref_type_arg)
5249 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
5261 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(VD,
false);
5262 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_private) {
5270 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
5271 DSAStack->getCurrentDirective() == OMPD_task) {
5272 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
5278 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
5292 Type = Type.getUnqualifiedType();
5295 if (VDPrivate->isInvalidDecl())
5300 DSAStack->addDSA(VD, DE, OMPC_private);
5302 PrivateCopies.push_back(VDPrivateRefExpr);
5313 class DiagsUninitializedSeveretyRAII {
5322 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
5324 Diags.
setSeverity( diag::warn_uninit_self_reference_in_init,
5328 ~DiagsUninitializedSeveretyRAII() {
5342 bool IsImplicitClause =
5344 auto ImplicitClauseLoc =
DSAStack->getConstructLoc();
5346 for (
auto &RefExpr : VarList) {
5347 assert(RefExpr &&
"NULL expr in OpenMP firstprivate clause.");
5348 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
5350 Vars.push_back(RefExpr);
5351 PrivateCopies.push_back(
nullptr);
5352 Inits.push_back(
nullptr);
5357 IsImplicitClause ? ImplicitClauseLoc : RefExpr->getExprLoc();
5363 DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5364 if (!DE || !isa<VarDecl>(DE->
getDecl())) {
5365 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
5369 VarDecl *VD = cast<VarDecl>(D);
5372 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
5375 PrivateCopies.push_back(
nullptr);
5376 Inits.push_back(
nullptr);
5384 diag::err_omp_firstprivate_incomplete_type)) {
5387 if (Type->isReferenceType()) {
5388 if (IsImplicitClause) {
5389 Diag(ImplicitClauseLoc,
5390 diag::err_omp_task_predetermined_firstprivate_ref_type_arg)
5392 Diag(RefExpr->getExprLoc(), diag::note_used_here);
5394 Diag(ELoc, diag::err_omp_clause_ref_type_arg)
5400 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
5412 if (!IsImplicitClause) {
5413 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(VD,
false);
5414 bool IsConstant = ElemType.isConstant(
Context);
5419 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
5420 DVar.CKind != OMPC_lastprivate && DVar.RefExpr) {
5421 Diag(ELoc, diag::err_omp_wrong_dsa)
5440 DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_shared) {
5441 Diag(ELoc, diag::err_omp_wrong_dsa)
5456 DVar =
DSAStack->getImplicitDSA(VD,
true);
5457 if (DVar.CKind != OMPC_shared &&
5460 Diag(ELoc, diag::err_omp_required_access)
5478 if (CurrDir == OMPD_task) {
5480 DSAStack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction),
5486 if (DVar.CKind == OMPC_reduction &&
5489 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
5498 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
5499 DSAStack->getCurrentDirective() == OMPD_task) {
5500 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
5506 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
5511 Type = Type.getUnqualifiedType();
5518 Expr *VDInitRefExpr =
nullptr;
5521 if (Type->isArrayType()) {
5526 ElemType = ElemType.getUnqualifiedType();
5528 ".firstprivate.temp");
5536 VDPrivate->setInvalidDecl();
5538 VDPrivate->setInit(Result.
getAs<
Expr>());
5548 if (VDPrivate->isInvalidDecl()) {
5549 if (IsImplicitClause) {
5551 diag::note_omp_task_predetermined_firstprivate_here);
5558 DSAStack->addDSA(VD, DE, OMPC_firstprivate);
5560 PrivateCopies.push_back(VDPrivateRefExpr);
5561 Inits.push_back(VDInitRefExpr);
5568 Vars, PrivateCopies, Inits);
5579 for (
auto &RefExpr : VarList) {
5580 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
5581 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
5583 Vars.push_back(RefExpr);
5584 SrcExprs.push_back(
nullptr);
5585 DstExprs.push_back(
nullptr);
5586 AssignmentOps.push_back(
nullptr);
5596 DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5597 if (!DE || !isa<VarDecl>(DE->
getDecl())) {
5598 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
5602 VarDecl *VD = cast<VarDecl>(D);
5605 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
5608 SrcExprs.push_back(
nullptr);
5609 DstExprs.push_back(
nullptr);
5610 AssignmentOps.push_back(
nullptr);
5618 diag::err_omp_lastprivate_incomplete_type)) {
5621 if (Type->isReferenceType()) {
5622 Diag(ELoc, diag::err_omp_clause_ref_type_arg)
5627 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
5637 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(VD,
false);
5638 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
5639 DVar.CKind != OMPC_firstprivate &&
5640 (DVar.CKind != OMPC_private || DVar.RefExpr !=
nullptr)) {
5641 Diag(ELoc, diag::err_omp_wrong_dsa)
5655 DSAStackTy::DSAVarData TopDVar = DVar;
5658 DVar =
DSAStack->getImplicitDSA(VD,
true);
5659 if (DVar.CKind != OMPC_shared) {
5660 Diag(ELoc, diag::err_omp_required_access)
5677 Type.getUnqualifiedType(),
".lastprivate.src");
5679 *
this, SrcVD, Type.getUnqualifiedType(), DE->
getExprLoc());
5682 auto *PseudoDstExpr =
5687 PseudoDstExpr, PseudoSrcExpr);
5688 if (AssignmentOp.isInvalid())
5692 if (AssignmentOp.isInvalid())
5695 if (TopDVar.CKind != OMPC_firstprivate)
5696 DSAStack->addDSA(VD, DE, OMPC_lastprivate);
5698 SrcExprs.push_back(PseudoSrcExpr);
5699 DstExprs.push_back(PseudoDstExpr);
5700 AssignmentOps.push_back(AssignmentOp.get());
5707 Vars, SrcExprs, DstExprs, AssignmentOps);
5715 for (
auto &RefExpr : VarList) {
5716 assert(RefExpr &&
"NULL expr in OpenMP shared clause.");
5717 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
5719 Vars.push_back(RefExpr);
5731 if (!DE || !isa<VarDecl>(DE->
getDecl())) {
5732 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
5736 VarDecl *VD = cast<VarDecl>(D);
5739 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
5752 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(VD,
false);
5753 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_shared &&
5761 DSAStack->addDSA(VD, DE, OMPC_shared);
5772 class DSARefChecker :
public StmtVisitor<DSARefChecker, bool> {
5778 DSAStackTy::DSAVarData DVar =
Stack->getTopDSA(VD,
false);
5779 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
5783 DSAStackTy::DSAVarData DVarPrivate =
5791 bool VisitStmt(
Stmt *S) {
5792 for (
auto Child : S->children()) {
5793 if (Child && Visit(Child))
5798 explicit DSARefChecker(DSAStackTy *S) :
Stack(S) {}
5809 assert(ReductionIdScopeSpec.
isEmpty() &&
5810 "No support for scoped reduction identifiers yet.");
5812 auto DN = ReductionId.
getName();
5850 case OO_Array_Delete:
5859 case OO_GreaterEqual:
5864 case OO_PercentEqual:
5869 case OO_GreaterGreater:
5870 case OO_LessLessEqual:
5871 case OO_GreaterGreaterEqual:
5873 case OO_ExclaimEqual:
5881 case OO_Conditional:
5883 llvm_unreachable(
"Unexpected reduction identifier");
5885 if (
auto II = DN.getAsIdentifierInfo()) {
5886 if (II->isStr(
"max"))
5888 else if (II->isStr(
"min"))
5894 if (ReductionIdScopeSpec.
isValid()) {
5900 Diag(ReductionId.
getLocStart(), diag::err_omp_unknown_reduction_identifier)
5901 << ReductionIdRange;
5909 for (
auto RefExpr : VarList) {
5910 assert(RefExpr &&
"nullptr expr in OpenMP reduction clause.");
5911 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
5913 Vars.push_back(RefExpr);
5914 LHSs.push_back(
nullptr);
5915 RHSs.push_back(
nullptr);
5916 ReductionOps.push_back(
nullptr);
5920 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
5921 RefExpr->isInstantiationDependent() ||
5922 RefExpr->containsUnexpandedParameterPack()) {
5924 Vars.push_back(RefExpr);
5925 LHSs.push_back(
nullptr);
5926 RHSs.push_back(
nullptr);
5927 ReductionOps.push_back(
nullptr);
5931 auto ELoc = RefExpr->getExprLoc();
5932 auto ERange = RefExpr->getSourceRange();
5941 if (!DE || !isa<VarDecl>(DE->getDecl())) {
5942 Diag(ELoc, diag::err_omp_expected_var_name) << ERange;
5945 auto D = DE->getDecl();
5946 auto VD = cast<VarDecl>(D);
5947 auto Type = VD->getType();
5952 diag::err_omp_reduction_incomplete_type))
5956 if (Type.getNonReferenceType()->isArrayType()) {
5957 Diag(ELoc, diag::err_omp_reduction_type_array) << Type << ERange;
5960 Diag(VD->getLocation(),
5961 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
5968 if (Type.getNonReferenceType().isConstant(
Context)) {
5969 Diag(ELoc, diag::err_omp_const_variable)
5973 Diag(VD->getLocation(),
5974 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
5982 if (Type->isReferenceType() && VDDef) {
5984 if (Check.Visit(VDDef->
getInit())) {
5985 Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange;
5999 !(Type->isScalarType() ||
6000 (
getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
6001 Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
6005 Diag(VD->getLocation(),
6006 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
6011 !
getLangOpts().CPlusPlus && Type->isFloatingType()) {
6012 Diag(ELoc, diag::err_omp_clause_floating_type_arg);
6015 Diag(VD->getLocation(),
6016 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
6031 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(VD,
false);
6032 if (DVar.CKind == OMPC_reduction) {
6033 Diag(ELoc, diag::err_omp_once_referenced)
6036 Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
6039 Diag(ELoc, diag::err_omp_wrong_dsa)
6053 DVar =
DSAStack->getImplicitDSA(VD,
true);
6054 if (DVar.CKind != OMPC_shared) {
6055 Diag(ELoc, diag::err_omp_required_access)
6062 Type = Type.getNonLValueExprType(
Context).getUnqualifiedType();
6063 auto *LHSVD =
buildVarDecl(*
this, ELoc, Type,
".reduction.lhs");
6064 auto *RHSVD =
buildVarDecl(*
this, ELoc, Type, VD->getName());
6066 Expr *Init =
nullptr;
6073 if (Type->isScalarType() || Type->isAnyComplexType()) {
6079 if (Type->isScalarType() || Type->isAnyComplexType()) {
6088 Type = ComplexTy->getElementType();
6090 if (Type->isRealFloatingType()) {
6091 llvm::APFloat InitValue =
6096 }
else if (Type->isScalarType()) {
6099 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
6116 if (Type->isIntegerType() || Type->isPointerType()) {
6117 bool IsSigned = Type->hasSignedIntegerRepresentation();
6121 llvm::APInt InitValue =
6123 ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
6124 : llvm::APInt::getMinValue(Size)
6125 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
6126 : llvm::APInt::getMaxValue(Size);
6128 if (Type->isPointerType()) {
6137 }
else if (Type->isRealFloatingType()) {
6138 llvm::APFloat InitValue = llvm::APFloat::getLargest(
6168 llvm_unreachable(
"Unexpected reduction operation");
6176 if (!RHSVD->hasInit()) {
6177 Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type
6178 << ReductionIdRange;
6181 Diag(VD->getLocation(),
6182 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
6211 DSAStack->addDSA(VD, DE, OMPC_reduction);
6213 LHSs.push_back(LHSDRE);
6214 RHSs.push_back(RHSDRE);
6215 ReductionOps.push_back(ReductionOp.
get());
6222 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars,
6224 RHSs, ReductionOps);
6234 for (
auto &RefExpr : VarList) {
6235 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
6236 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
6238 Vars.push_back(RefExpr);
6239 Inits.push_back(
nullptr);
6258 if (!DE || !isa<VarDecl>(DE->
getDecl())) {
6259 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
6269 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(VD,
false);
6281 Inits.push_back(
nullptr);
6287 diag::err_omp_linear_incomplete_type)) {
6291 Diag(ELoc, diag::err_omp_clause_ref_type_arg)
6296 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
6303 Diag(ELoc, diag::err_omp_const_variable)
6308 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
6318 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << QType;
6322 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
6333 DSAStack->addDSA(VD, DE, OMPC_linear);
6335 Inits.push_back(InitRef);
6342 Expr *CalcStepExpr =
nullptr;
6350 StepExpr = Val.
get();
6364 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
6365 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
6366 << (Vars.size() > 1);
6367 if (!IsConstant && CalcStep.isUsable()) {
6370 CalcStepExpr = CalcStep.get();
6375 Vars, Inits, StepExpr, CalcStepExpr);
6379 Expr *NumIterations,
Sema &SemaRef,
6388 if (Step ==
nullptr)
6391 Step = cast<BinaryOperator>(
CalcStep)->getLHS();
6392 bool HasErrors =
false;
6393 auto CurInit = Clause.inits().begin();
6394 for (
auto &RefExpr : Clause.
varlists()) {
6395 Expr *InitExpr = *CurInit;
6398 auto DE = cast<DeclRefExpr>(RefExpr);
6401 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
6407 InitExpr, IV,
Step,
false);
6413 InitExpr, NumIterations,
Step,
false);
6415 if (!Update.isUsable() || !Final.isUsable()) {
6416 Updates.push_back(
nullptr);
6417 Finals.push_back(
nullptr);
6420 Updates.push_back(Update.get());
6421 Finals.push_back(Final.get());
6425 Clause.setUpdates(Updates);
6426 Clause.setFinals(Finals);
6435 for (
auto &RefExpr : VarList) {
6436 assert(RefExpr &&
"NULL expr in OpenMP aligned clause.");
6437 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
6439 Vars.push_back(RefExpr);
6447 if (!DE || !isa<VarDecl>(DE->
getDecl())) {
6448 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
6462 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
6463 << QType <<
getLangOpts().CPlusPlus << RefExpr->getSourceRange();
6467 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
6475 Diag(ELoc, diag::err_omp_aligned_twice) << RefExpr->getSourceRange();
6476 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
6489 if (Alignment !=
nullptr) {
6491 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
6494 Alignment = AlignResult.
get();
6500 EndLoc, Vars, Alignment);
6511 for (
auto &RefExpr : VarList) {
6512 assert(RefExpr &&
"NULL expr in OpenMP copyin clause.");
6513 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
6515 Vars.push_back(RefExpr);
6516 SrcExprs.push_back(
nullptr);
6517 DstExprs.push_back(
nullptr);
6518 AssignmentOps.push_back(
nullptr);
6528 if (!DE || !isa<VarDecl>(DE->
getDecl())) {
6529 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
6534 VarDecl *VD = cast<VarDecl>(D);
6537 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
6540 SrcExprs.push_back(
nullptr);
6541 DstExprs.push_back(
nullptr);
6542 AssignmentOps.push_back(
nullptr);
6548 if (!
DSAStack->isThreadPrivate(VD)) {
6549 Diag(ELoc, diag::err_omp_required_access)
6561 ElemType.getUnqualifiedType(),
".copyin.src");
6563 *
this, SrcVD, ElemType.getUnqualifiedType(), DE->
getExprLoc());
6566 auto *PseudoDstExpr =
6571 PseudoDstExpr, PseudoSrcExpr);
6572 if (AssignmentOp.isInvalid())
6576 if (AssignmentOp.isInvalid())
6579 DSAStack->addDSA(VD, DE, OMPC_copyin);
6581 SrcExprs.push_back(PseudoSrcExpr);
6582 DstExprs.push_back(PseudoDstExpr);
6583 AssignmentOps.push_back(AssignmentOp.get());
6590 SrcExprs, DstExprs, AssignmentOps);
6601 for (
auto &RefExpr : VarList) {
6602 assert(RefExpr &&
"NULL expr in OpenMP copyprivate clause.");
6603 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
6605 Vars.push_back(RefExpr);
6606 SrcExprs.push_back(
nullptr);
6607 DstExprs.push_back(
nullptr);
6608 AssignmentOps.push_back(
nullptr);
6618 if (!DE || !isa<VarDecl>(DE->
getDecl())) {
6619 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
6624 VarDecl *VD = cast<VarDecl>(D);
6627 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
6630 SrcExprs.push_back(
nullptr);
6631 DstExprs.push_back(
nullptr);
6632 AssignmentOps.push_back(
nullptr);
6639 if (!
DSAStack->isThreadPrivate(VD)) {
6640 auto DVar =
DSAStack->getTopDSA(VD,
false);
6641 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
6643 Diag(ELoc, diag::err_omp_wrong_dsa)
6654 DVar =
DSAStack->getImplicitDSA(VD,
false);
6655 if (DVar.CKind == OMPC_shared) {
6656 Diag(ELoc, diag::err_omp_required_access)
6658 <<
"threadprivate or private in the enclosing context";
6666 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
6667 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
6673 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
6685 auto *PseudoSrcExpr =
6689 auto *PseudoDstExpr =
6692 PseudoDstExpr, PseudoSrcExpr);
6693 if (AssignmentOp.isInvalid())
6697 if (AssignmentOp.isInvalid())
6703 SrcExprs.push_back(PseudoSrcExpr);
6704 DstExprs.push_back(PseudoDstExpr);
6705 AssignmentOps.push_back(AssignmentOp.get());
6712 Vars, SrcExprs, DstExprs, AssignmentOps);
6719 if (VarList.empty())
6732 std::string Sep(
", ");
6738 case OMPC_DEPEND_unknown - 2:
6741 case OMPC_DEPEND_unknown - 1:
6748 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
6753 for (
auto &RefExpr : VarList) {
6754 assert(RefExpr &&
"NULL expr in OpenMP shared clause.");
6755 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
6757 Vars.push_back(RefExpr);
6766 auto *SimpleExpr = RefExpr->IgnoreParenCasts();
6769 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || (!ASE && !DE) ||
6770 (DE && !isa<VarDecl>(DE->
getDecl())) ||
6771 (ASE && !ASE->getBase()->getType()->isAnyPointerType() &&
6772 !ASE->getBase()->getType()->isArrayType())) {
6773 Diag(ELoc, diag::err_omp_expected_var_name_or_array_item)
6774 << RefExpr->getSourceRange();
6778 Vars.push_back(RefExpr->IgnoreParenImpCasts());
6785 DepLoc, ColonLoc, Vars);
static OMPPrivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PrivateVL)
Creates clause with a list of variables VL.
Expr * NLB
Update of LowerBound for statically sheduled 'omp for' loops.
Defines the clang::ASTContext interface.
void MarkDeclarationsReferencedInExpr(Expr *E, bool SkipLocalVariables=false)
Mark any declarations that appear within this expression or any potentially-evaluated subexpressions ...
SmallVector< Expr *, 4 > Finals
Final loop counter values for GodeGen.
SmallVector< Expr *, 4 > Updates
Expressions for loop counters update for CodeGen.
StmtResult ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp master' after parsing of the associated statement.
ExprResult ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id)
Called on correct id-expression from the '#pragma omp threadprivate'.
static OMPSectionDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt)
Creates directive.
void setImplicit(bool I=true)
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
void setNothrow(bool Nothrow=true)
StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp section' after parsing of the associated statement.
StringRef getName() const
OMPClause * ActOnOpenMPLastprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'lastprivate' clause.
Simple class containing the result of Sema::CorrectTypo.
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates)...
ArrayRef< OMPClause * > clauses()
static Opcode getOpForCompoundAssignment(Opcode Opc)
DeclContext * getCurLexicalContext() const
void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, CapturedRegionKind Kind, unsigned NumParams)
StmtResult ActOnOpenMPFlushDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp flush'.
ExprResult ActOnConditionalOp(SourceLocation QuestionLoc, SourceLocation ColonLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr)
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val)
void EndOpenMPDSABlock(Stmt *CurDirective)
Called on end of data sharing attribute block.
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
const LangOptions & getLangOpts() const
OMPClause * ActOnOpenMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'untied' clause.
DeclClass * getAsSingle() const
StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel sections' after parsing of the associated statement...
SourceLocation getEndLoc() const
getEndLoc - Retrieve the location of the last token.
static ExprResult BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start)
Build 'VarRef = Start.
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
const Scope * getParent() const
ActionResult< Expr * > ExprResult
static OMPCopyprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps)
Creates clause with a list of variables VL.
The current expression is potentially evaluated at run time, which means that code may be generated t...
Expr * EUB
EnsureUpperBound – expression LB = min(LB, NumIterations).
StmtResult ActOnOpenMPTeamsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp teams' after parsing of the associated statement.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
ExprResult PerformContextualImplicitConversion(SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter)
Perform a contextual implicit conversion.
This represents 'if' clause in the '#pragma omp ...' directive.
bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, bool AllowBuiltinCreation=false, bool EnteringContext=false)
Performs name lookup for a name that was parsed in the source code, and may contain a C++ scope speci...
OMPClause * ActOnOpenMPFirstprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'firstprivate' clause.
static OMPCopyinClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps)
Creates clause with a list of variables VL.
static OMPSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
bool isEnumeralType() const
static OMPAtomicDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V, Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate)
Creates directive with a list of Clauses and 'x', 'v' and 'expr' parts of the atomic construct (see S...
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
const char * getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type)
OMPClause * ActOnOpenMPScheduleClause(OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'schedule' clause.
const Expr * getInit() const
A container of type source information.
This represents 'update' clause in the '#pragma omp atomic' directive.
Wrapper for void* pointer.
OMPClause * ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'proc_bind' clause.
SourceLocation getOperatorLoc() const
static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef)
Check if the given expression E is a constant integer that fits into Bits bits.
StmtResult ActOnOpenMPSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp simd' after parsing of the associated statement.
Represents a C++ constructor within a class.
StmtResult ActOnOpenMPTargetDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target' after parsing of the associated statement.
StmtResult ActOnOpenMPParallelDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel' after parsing of the associated statement.
SourceLocation getTemplateKeywordLoc() const
Retrieve the location of the template keyword preceding this name, if any.
static OMPParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
This represents 'read' clause in the '#pragma omp atomic' directive.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
bool isFileVarDecl() const
isFileVarDecl - Returns true for file scoped variable declaration.
DiagnosticsEngine & Diags
This represents 'num_threads' clause in the '#pragma omp ...' directive.
OMPClause * ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'final' clause.
TLSKind getTLSKind() const
ExtProtoInfo - Extra information about a function prototype.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
Expr * IgnoreImplicit() LLVM_READONLY
void setBegin(SourceLocation b)
StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp barrier'.
static Expr * GetCollapseNumberExpr(ArrayRef< OMPClause * > Clauses)
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
void setHasBranchProtectedScope()
bool isEmpty() const
No scope specifier.
CapturedDecl * TheCapturedDecl
The CapturedDecl for this statement.
void ActOnUninitializedDecl(Decl *dcl, bool TypeMayContainAuto)
QualType withConst() const
Retrieves a version of this type with const applied. Note that this does not always yield a canonical...
This represents 'safelen' clause in the '#pragma omp ...' directive.
Expr * LastIteration
Loop last iteration number.
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, AssignmentAction Action, bool AllowExplicit=false)
const char * getOpenMPClauseName(OpenMPClauseKind Kind)
DeclarationName getName() const
getName - Returns the embedded declaration name.
bool isScalarType() const
static OMPSharedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
static OMPFirstprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PrivateVL, ArrayRef< Expr * > InitVL)
Creates clause with a list of variables VL.
A C++ nested-name-specifier augmented with source location information.
OMPClause * ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'depend' clause.
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
bool isReferenceType() const
SourceLocation getLocStart() const
Returns the starting location of the clause.
void StartOpenMPDSABlock(OpenMPDirectiveKind K, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc)
Called on start of new data sharing attribute block.
bool isTranslationUnit() const
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr)
StmtResult ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp critical' after parsing of the associated statement.
StmtResult ActOnOpenMPOrderedDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp ordered' after parsing of the associated statement.
Defines some OpenMP-specific enums and functions.
bool isOpenMPPrivateVar(VarDecl *VD, unsigned Level)
void PopExpressionEvaluationContext()
void EndOpenMPClause()
End analysis of clauses.
OMPClause * ActOnOpenMPSharedClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'shared' clause.
StorageClass getStorageClass() const
Returns the storage class as written in the source. For the computed linkage of symbol, see getLinkage.
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
VerifyDiagnosticConsumer::Directive Directive
ExprResult ActOnBooleanCondition(Scope *S, SourceLocation Loc, Expr *SubExpr)
StmtResult ActOnOpenMPForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for' after parsing of the associated statement.
StmtResult ActOnOpenMPAtomicDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp atomic' after parsing of the associated statement.
Represents the results of name lookup.
const TargetInfo & getTargetInfo() const
bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a teams-kind directive.
OMPClause * ActOnOpenMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'read' clause.
DeclarationNameInfo getNameInfo() const
bool isFunctionOrMethodVarDecl() const
static bool CheckOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, Expr *NestedLoopCountExpr, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA, LoopIterationSpace &ResultIterSpace)
Called on a for stmt to check and extract its iteration space for further processing (such as collaps...
static DeclRefExpr * buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, SourceLocation Loc, bool RefersToCapture=false)
Concrete class used by the front-end to report problems and issues.
OMPClause * ActOnOpenMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'capture' clause.
A builtin binary operation expression such as "x + y" or "x <= y".
bool isValueDependent() const
OMPClause * ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc)
std::pair< StringRef, QualType > CapturedParamNameType
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep)
Creates clause with a list of variables VL and a linear step Step.
This represents 'default' clause in the '#pragma omp ...' directive.
ExprResult Perform(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, QualType *ResultType=nullptr)
Perform the actual initialization of the given entity based on the computed initialization sequence...
static OMPReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr * > LHSExprs, ArrayRef< Expr * > RHSExprs, ArrayRef< Expr * > ReductionOps)
Creates clause with a list of variables VL.
This represents 'final' clause in the '#pragma omp ...' directive.
This represents 'mergeable' clause in the '#pragma omp ...' directive.
Expr * CalcLastIteration
Calculation of last iteration.
Represents a C++ nested-name-specifier or a global scope specifier.
bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a worksharing directive.
bool isStaticLocal() const
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
An ordinary object is located at an address in memory.
static unsigned CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA, OMPLoopDirective::HelperExprs &Built)
Called on a for stmt to check itself and nested loops (if any).
OMPClause * ActOnOpenMPSafelenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'safelen' clause.
OMPClause * ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'default' clause.
const LangOptions & LangOpts
Expr * NUB
Update of UpperBound for statically sheduled 'omp for' loops.
Expr * Cond
Loop condition.
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
Expr * PreCond
Loop pre-condition.
static OMPSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
The expressions built for the OpenMP loop CodeGen for the whole collapsed loop nest.
OMPClause * ActOnOpenMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'write' clause.
Sema - This implements semantic analysis and AST building for C.
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit, bool TypeMayContainAuto)
StmtResult ActOnOpenMPSingleDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp single' after parsing of the associated statement.
ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
OMPClause * ActOnOpenMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'nowait' clause.
bool isOpenMPPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of private clauses like 'private', 'firstprivate', 'reduction' etc..
static OMPThreadPrivateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< Expr * > VL)
StmtResult ActOnOpenMPSectionsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp sections' after parsing of the associated statement.
std::vector< bool > & Stack
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on a template...
Expr * IterationVarRef
Loop iteration variable.
static OMPTargetDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static OMPFlushClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
const Type * getTypePtrOrNull() const
This represents 'proc_bind' clause in the '#pragma omp ...' directive.
This represents 'capture' clause in the '#pragma omp atomic' directive.
void StartOpenMPClause(OpenMPClauseKind K)
Start analysis of clauses.
static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract)
Build 'VarRef = Start + Iter * Step'.
bool isDeclScope(Decl *D)
bool isAnyComplexType() const
bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a parallel-kind directive.
OMPClause * ActOnOpenMPFlushClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'flush' pseudo clause.
static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, OpenMPDirectiveKind CurrentRegion, const DeclarationNameInfo &CurrentName, OpenMPDirectiveKind CancelRegion, SourceLocation StartLoc)
bool Encloses(const DeclContext *DC) const
Determine whether this declaration context encloses the declaration context DC.
OMPClause * ActOnOpenMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'mergeable' clause.
Inits[]
Gets the list of initial values for linear variables.
static InitializedEntity InitializeVariable(VarDecl *Var)
Create the initialization entity for a variable.
static OMPMasterDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt)
Creates directive.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup. Asserts that one was found.
OMPClause * ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'ordered' clause.
Defines the clang::Preprocessor interface.
ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, VerifyICEDiagnoser &Diagnoser, bool AllowFold=true)
OpenMPClauseKind
OpenMP clauses.
StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskyield'.
DeclContext * getDeclContext()
static FloatingLiteral * Create(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L)
bool RequireCompleteType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
bool builtAll()
Check if all the expressions are built (does not check the worksharing ones).
This represents 'ordered' clause in the '#pragma omp ...' directive.
void DiscardCleanupsInEvaluationContext()
bool isDependentType() const
bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
This represents 'collapse' clause in the '#pragma omp ...' directive.
Represents a C++ conversion function within a class.
The result type of a method or function.
static OMPDependClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
OpenMPProcBindClauseKind
OpenMP attributes for 'proc_bind' clause.
NestedNameSpecifierLoc getQualifierLoc() const
If the name was qualified, retrieves the nested-name-specifier that precedes the name, with source-location information.
static OMPTaskDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
DefaultDataSharingAttributes
Default data sharing attributes, which can be applied to directive.
Expr * NumIterations
Loop number of iterations.
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
ExprResult ActOnFinishFullExpr(Expr *Expr)
static ExprResult WidenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef)
Convert integer expression E to make it have at least Bits bits.
This represents 'seq_cst' clause in the '#pragma omp atomic' directive.
This represents 'untied' clause in the '#pragma omp ...' directive.
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
Expr * ST
Stride - local variable passed to runtime.
OMPClause * ActOnOpenMPCopyinClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyin' clause.
This captures a statement into a function. For example, the following pragma annotated compound state...
SmallVector< Expr *, 4 > Counters
Counters Loop counters.
static OMPCriticalDirective * Create(const ASTContext &C, const DeclarationNameInfo &Name, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt)
Creates directive.
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
OpenMPDependClauseKind
OpenMP attributes for 'depend' clause.
StmtResult ActOnOpenMPTaskDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp task' after parsing of the associated statement.
OMPClause * ActOnOpenMPPrivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'private' clause.
static OMPCancelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Creates directive.
StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
This is a basic class for representing single OpenMP executable directive.
static OMPTeamsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
bool isValid() const
Return true if this is a valid SourceLocation object.
OverloadedOperatorKind getCXXOverloadedOperator() const
bool isConstant(ASTContext &Ctx) const
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context...
This represents 'schedule' clause in the '#pragma omp ...' directive.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location, which defaults to the empty location.
ASTContext & getASTContext() const
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
bool isLocalVarDecl() const
void setReferenced(bool R=true)
OpenMPDirectiveKind
OpenMP directives.
IdentifierTable & getIdentifierTable()
QualType withConst() const
StmtResult ActOnCapturedRegionEnd(Stmt *S)
StmtResult ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancellation point'.
ExprResult DefaultLvalueConversion(Expr *E)
C-style initialization with assignment.
This file defines OpenMP nodes for declarative directives.
bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx, SourceLocation *Loc=nullptr, bool isEvaluated=true) const
This is a basic class for representing single OpenMP clause.
OMPClause * ActOnOpenMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'update' clause.
Describes the kind of initialization being performed, along with location information for tokens rela...
This declaration is only a declaration.
OMPClause * ActOnOpenMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'seq_cst' clause.
bool isTypeDependent() const
SourceLocation getBeginLoc() const
static OMPAlignedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, Expr *A)
Creates clause with a list of variables VL and alignment A.
bool isFileContext() const
sema::FunctionScopeInfo * getCurFunction() const
sema::CapturedRegionScopeInfo * getCurCapturedRegion()
Retrieve the current captured region, if any.
Expr * LB
LowerBound - local variable passed to runtime.
void clear(unsigned Size)
Initialize all the fields to null.
Expr * Init
Loop iteration variable init.
ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op)
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation getExprLoc() const LLVM_READONLY
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
OMPClause * ActOnOpenMPReductionClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId)
Called on well-formed 'reduction' clause.
static OMPParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
void diagnoseTypo(const TypoCorrection &Correction, const PartialDiagnostic &TypoDiag, bool ErrorRecovery=true)
OMPClause * ActOnOpenMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_threads' clause.
StmtResult ActOnOpenMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancel'.
SourceLocation getLocStart() const LLVM_READONLY
OMPClause * ActOnOpenMPLinearClause(ArrayRef< Expr * > VarList, Expr *Step, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'linear' clause.
SmallVector< Expr *, 4 > Inits
Expressions for loop counters inits for CodeGen.
static OMPParallelSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
void ActOnCapturedRegionError()
OMPClause * ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope)
Initialization of captured region for OpenMP region.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
bool isUsed(bool CheckUsedAttr=true) const
Whether this declaration was used, meaning that a definition is required.
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition. If this could be a tentative definition (in C)...
This represents clause 'linear' in the '#pragma omp ...' directives.
StmtResult ActOnOpenMPTaskgroupDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskgroup'.
bool isSingleResult() const
bool isOpenMPThreadPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of threadprivate clauses like 'threadprivate', 'copyin' or 'copyprivate'.
OMPClause * ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, unsigned Argument, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ArgumentLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Expr * IgnoreParenImpCasts() LLVM_READONLY
QualType getNonReferenceType() const
bool IsOpenMPCapturedVar(VarDecl *VD)
Check if the specified variable is used in a private clause in Checks if the specified variable is us...
bool empty() const
Return true if no decls were found.
OMPClause * ActOnOpenMPAlignedClause(ArrayRef< Expr * > VarList, Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'aligned' clause.
static OMPOrderedDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt)
Creates directive.
NamedDecl * getCorrectionDecl() const
Gets the pointer to the declaration of the typo correction.
Not an overloaded operator.
static OMPForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
QualType getCanonicalType() const
This file defines OpenMP AST classes for executable directives and clauses.
void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl=nullptr, bool IsDecltype=false)
void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc)
This allows the client to specify that certain warnings are ignored.
bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S=nullptr, bool AllowInlineNamespace=false)
Expr * Inc
Loop increment.
OpenMPScheduleClauseKind
OpenMP attributes for 'schedule' clause.
static OMPForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
bool popMappings(SourceLocation Loc)
Pops the current DiagMappings off the top of the stack, causing the new top of the stack to be the ac...
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
QualType withRestrict() const
OpenMPDefaultClauseKind
OpenMP attributes for 'default' clause.
void addDecl(Decl *D)
Add the declaration D into this context.
static OMPSingleDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(SourceLocation Loc, ArrayRef< Expr * > VarList)
Called on well-formed '#pragma omp threadprivate'.
SourceLocation getExprLoc() const LLVM_READONLY
bool isStaticDataMember() const
Determines whether this is a static data member.
This represents 'write' clause in the '#pragma omp atomic' directive.
ASTMutationListener * getASTMutationListener() const
Retrieve a pointer to the AST mutation listener associated with this AST context, if any...
const char * getOpenMPDirectiveName(OpenMPDirectiveKind Kind)
OMPThreadPrivateDecl * CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef< Expr * > VarList)
Builds a new OpenMPThreadPrivateDecl and checks its correctness.
void markUsed(ASTContext &C)
Mark the declaration used, in the sense of odr-use.
bool isTLSSupported() const
Whether the target supports thread-local storage.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
static OMPTaskyieldDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Expr * UB
UpperBound - local variable passed to runtime.
StmtResult ActOnOpenMPParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for simd' after parsing of the associated statement...
Describes the sequence of initializations required to initialize a given object or reference with a s...
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
This represents 'nowait' clause in the '#pragma omp ...' directive.
void setEnd(SourceLocation e)
Represents a C++ struct/union/class.
void setTSCSpec(ThreadStorageClassSpecifier TSC)
StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskwait'.
static OMPBarrierDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Do not present this diagnostic, ignore it.
StmtResult ActOnOpenMPForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for simd' after parsing of the associated statement.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Defines the clang::TargetInfo interface.
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC...
static OMPTaskgroupDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt)
Creates directive.
OMPClause * ActOnOpenMPIfClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'if' clause.
static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, Expr *NumIterations, Sema &SemaRef, Scope *S)
static OMPParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static OMPTaskwaitDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
static OpaquePtr make(PtrTy P)
OMPClause * ActOnOpenMPCopyprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyprivate' clause.
bool isValid() const
A scope specifier is present, and it refers to a real scope.
A reference to a declared variable, function, enum, etc. [C99 6.5.1p2].
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init)
Check if the current region is an OpenMP loop region and if it is, mark loop control variable...
OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr * > Vars, Expr *TailExpr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, SourceLocation DepLoc)
static VarDecl * buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, StringRef Name)
Build a variable declaration for OpenMP loop iteration variable.
void suppressDiagnostics()
An l-value expression is a reference to an object with independent storage.
static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack, const VarDecl *VD, DSAStackTy::DSAVarData DVar, bool IsLoopIterVar=false)
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
Expr * IL
IsLastIteration - local flag variable passed to runtime.
A trivial tuple used to represent a source range.
SourceLocation getLocation() const
TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, std::unique_ptr< CorrectionCandidateCallback > CCC, CorrectTypoKind Mode, DeclContext *MemberContext=nullptr, bool EnteringContext=false, const ObjCObjectPointerType *OPT=nullptr, bool RecordFailure=true)
Try to "correct" a typo in the source code by finding visible declarations whose names are similar to...
static OMPCancellationPointDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Creates directive.
static OMPFlushDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive with a list of Clauses.
void setAccess(AccessSpecifier AS)
OMPClause * ActOnOpenMPCollapseClause(Expr *NumForLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'collapse' clause.
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g., it is an signed integer type or a vector.
Describes an entity that is being initialized.
StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef< OMPClause * > Clauses)
End of OpenMP region.
SourceLocation ColonLoc
Location of ':'.
This represents '#pragma omp threadprivate ...' directive. For example, in the following, both 'a' and 'A::b' are threadprivate:
bool isIntegralType(ASTContext &Ctx) const
Determine whether this type is an integral type.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
bool isIntegerType() const
bool hasLocalStorage() const
Helper class that creates diagnostics with optional template instantiation stacks.
Expr * IgnoreParens() LLVM_READONLY
Iterates over a filtered subrange of clauses applied to a directive.
StmtResult ActOnOpenMPParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for' after parsing of the associated statement.
bool isPointerType() const
static OMPLastprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps)
Creates clause with a list of variables VL.