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;
90 typedef llvm::SmallDenseMap<VarDecl *, DSAInfo, 64> DeclSAMapTy;
91 typedef llvm::SmallDenseMap<VarDecl *, DeclRefExpr *, 64> AlignedMapTy;
92 typedef llvm::DenseMap<VarDecl *, unsigned> LoopControlVariablesMapTy;
93 typedef llvm::SmallDenseMap<VarDecl *, MapInfo, 64> MappedDeclsTy;
94 typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>>
98 DeclSAMapTy SharingMap;
99 AlignedMapTy AlignedMap;
100 MappedDeclsTy MappedDecls;
101 LoopControlVariablesMapTy LCVMap;
111 llvm::PointerIntPair<Expr *, 1, bool> OrderedRegion;
114 unsigned AssociatedLoops;
118 : SharingMap(), AlignedMap(), LCVMap(), DefaultAttr(DSA_unspecified),
119 Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope),
120 ConstructLoc(Loc), OrderedRegion(), NowaitRegion(
false),
121 CancelRegion(
false), AssociatedLoops(1), InnerTeamsRegionLoc() {}
123 : SharingMap(), AlignedMap(), LCVMap(), DefaultAttr(DSA_unspecified),
125 ConstructLoc(), OrderedRegion(), NowaitRegion(
false),
126 CancelRegion(
false), AssociatedLoops(1), InnerTeamsRegionLoc() {}
138 CriticalsWithHintsTy Criticals;
142 DSAVarData getDSA(StackTy::reverse_iterator Iter,
VarDecl *D);
145 bool isOpenMPLocal(
VarDecl *D, StackTy::reverse_iterator Iter);
148 explicit DSAStackTy(
Sema &
S)
150 ForceCapturing(
false) {}
152 bool isClauseParsingMode()
const {
return ClauseKindMode !=
OMPC_unknown; }
155 bool isForceVarCapturing()
const {
return ForceCapturing; }
156 void setForceVarCapturing(
bool V) { ForceCapturing = V; }
160 Stack.push_back(SharingMapTy(DKind, DirName, CurScope, Loc));
161 Stack.back().DefaultAttrLoc = Loc;
165 assert(
Stack.size() > 1 &&
"Data-sharing attributes stack is empty!");
172 const std::pair<OMPCriticalDirective *, llvm::APSInt>
175 if (
I != Criticals.end())
177 return std::make_pair(
nullptr, llvm::APSInt());
185 void addLoopControlVariable(
VarDecl *D);
190 unsigned isLoopControlVariable(
VarDecl *D);
195 unsigned isParentLoopControlVariable(
VarDecl *D);
198 VarDecl *getParentLoopControlVariable(
unsigned I);
205 DSAVarData getTopDSA(
VarDecl *D,
bool FromParent);
207 DSAVarData getImplicitDSA(
VarDecl *D,
bool FromParent);
211 template <
class ClausesPredicate,
class DirectivesPredicate>
212 DSAVarData hasDSA(
VarDecl *D, ClausesPredicate CPred,
213 DirectivesPredicate DPred,
bool FromParent);
217 template <
class ClausesPredicate,
class DirectivesPredicate>
218 DSAVarData hasInnermostDSA(
VarDecl *D, ClausesPredicate CPred,
219 DirectivesPredicate DPred,
224 bool hasExplicitDSA(
VarDecl *D,
230 bool hasExplicitDirective(
235 template <
class NamedDirectivesPredicate>
236 bool hasDirective(NamedDirectivesPredicate DPred,
bool FromParent);
240 return Stack.back().Directive;
244 if (
Stack.size() > 2)
253 Stack.back().DefaultAttr = DSA_none;
254 Stack.back().DefaultAttrLoc = Loc;
258 Stack.back().DefaultAttr = DSA_shared;
259 Stack.back().DefaultAttrLoc = Loc;
263 return Stack.back().DefaultAttr;
266 return Stack.back().DefaultAttrLoc;
270 bool isThreadPrivate(
VarDecl *D) {
271 DSAVarData DVar = getTopDSA(D,
false);
276 void setOrderedRegion(
bool IsOrdered,
Expr *Param) {
277 Stack.back().OrderedRegion.setInt(IsOrdered);
278 Stack.back().OrderedRegion.setPointer(Param);
282 bool isParentOrderedRegion()
const {
283 if (
Stack.size() > 2)
284 return Stack[
Stack.size() - 2].OrderedRegion.getInt();
288 Expr *getParentOrderedRegionParam()
const {
289 if (
Stack.size() > 2)
290 return Stack[
Stack.size() - 2].OrderedRegion.getPointer();
294 void setNowaitRegion(
bool IsNowait =
true) {
295 Stack.back().NowaitRegion = IsNowait;
299 bool isParentNowaitRegion()
const {
300 if (
Stack.size() > 2)
305 void setParentCancelRegion(
bool Cancel =
true) {
306 if (
Stack.size() > 2)
308 Stack[
Stack.size() - 2].CancelRegion || Cancel;
311 bool isCancelRegion()
const {
312 return Stack.back().CancelRegion;
316 void setAssociatedLoops(
unsigned Val) {
Stack.back().AssociatedLoops = Val; }
318 unsigned getAssociatedLoops()
const {
return Stack.back().AssociatedLoops; }
323 if (
Stack.size() > 2)
324 Stack[
Stack.size() - 2].InnerTeamsRegionLoc = TeamsRegionLoc;
327 bool hasInnerTeamsRegion()
const {
328 return getInnerTeamsRegionLoc().
isValid();
332 if (
Stack.size() > 1)
333 return Stack.back().InnerTeamsRegionLoc;
337 Scope *getCurScope()
const {
return Stack.back().CurScope; }
338 Scope *getCurScope() {
return Stack.back().CurScope; }
341 MapInfo getMapInfoForVar(
VarDecl *VD) {
343 for (
auto Cnt =
Stack.size() - 1; Cnt > 0; --Cnt) {
344 if (
Stack[Cnt].MappedDecls.count(VD)) {
345 VarMI =
Stack[Cnt].MappedDecls[VD];
352 void addMapInfoForVar(
VarDecl *VD, MapInfo MI) {
353 if (
Stack.size() > 1) {
354 Stack.back().MappedDecls[VD] = MI;
358 MapInfo IsMappedInCurrentRegion(
VarDecl *VD) {
359 assert(
Stack.size() > 1 &&
"Target level is 0");
361 if (
Stack.size() > 1 &&
Stack.back().MappedDecls.count(VD)) {
362 VarMI =
Stack.back().MappedDecls[VD];
374 DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator Iter,
378 if (Iter == std::prev(
Stack.rend())) {
385 DVar.CKind = OMPC_shared;
392 DVar.CKind = OMPC_shared;
397 DVar.DKind = Iter->Directive;
404 DVar.CKind = OMPC_private;
410 if (Iter->SharingMap.count(D)) {
411 DVar.RefExpr = Iter->SharingMap[D].RefExpr;
412 DVar.CKind = Iter->SharingMap[D].Attributes;
413 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
421 switch (Iter->DefaultAttr) {
423 DVar.CKind = OMPC_shared;
424 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
428 case DSA_unspecified:
433 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
436 DVar.CKind = OMPC_shared;
445 if (DVar.DKind == OMPD_task) {
447 for (StackTy::reverse_iterator
I = std::next(Iter), EE =
Stack.rend();
455 DVarTemp = getDSA(
I, D);
456 if (DVarTemp.CKind != OMPC_shared) {
457 DVar.RefExpr =
nullptr;
458 DVar.DKind = OMPD_task;
459 DVar.CKind = OMPC_firstprivate;
462 if (isParallelOrTaskRegion(
I->Directive))
465 DVar.DKind = OMPD_task;
467 (DVarTemp.CKind ==
OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
476 return getDSA(std::next(Iter), D);
480 assert(
Stack.size() > 1 &&
"Data sharing attributes stack is empty");
482 auto It =
Stack.back().AlignedMap.find(D);
483 if (It ==
Stack.back().AlignedMap.end()) {
484 assert(NewDE &&
"Unexpected nullptr expr to be added into aligned map");
485 Stack.back().AlignedMap[D] = NewDE;
488 assert(It->second &&
"Unexpected nullptr expr in the aligned map");
494 void DSAStackTy::addLoopControlVariable(
VarDecl *D) {
495 assert(
Stack.size() > 1 &&
"Data-sharing attributes stack is empty");
497 Stack.back().LCVMap.insert(std::make_pair(D,
Stack.back().LCVMap.size() + 1));
500 unsigned DSAStackTy::isLoopControlVariable(
VarDecl *D) {
501 assert(
Stack.size() > 1 &&
"Data-sharing attributes stack is empty");
503 return Stack.back().LCVMap.count(D) > 0 ?
Stack.back().LCVMap[D] : 0;
506 unsigned DSAStackTy::isParentLoopControlVariable(
VarDecl *D) {
507 assert(
Stack.size() > 2 &&
"Data-sharing attributes stack is empty");
509 return Stack[
Stack.size() - 2].LCVMap.count(D) > 0
514 VarDecl *DSAStackTy::getParentLoopControlVariable(
unsigned I) {
515 assert(
Stack.size() > 2 &&
"Data-sharing attributes stack is empty");
518 for (
auto &Pair :
Stack[
Stack.size() - 2].LCVMap) {
519 if (Pair.second == I)
528 Stack[0].SharingMap[D].Attributes = A;
529 Stack[0].SharingMap[D].RefExpr =
E;
531 assert(
Stack.size() > 1 &&
"Data-sharing attributes stack is empty");
532 Stack.back().SharingMap[D].Attributes = A;
533 Stack.back().SharingMap[D].RefExpr =
E;
537 bool DSAStackTy::isOpenMPLocal(
VarDecl *D, StackTy::reverse_iterator Iter) {
539 if (
Stack.size() > 2) {
540 reverse_iterator I = Iter, E = std::prev(
Stack.rend());
541 Scope *TopScope =
nullptr;
542 while (I != E && !isParallelOrTaskRegion(I->Directive)) {
547 TopScope = I->CurScope ? I->CurScope->getParent() :
nullptr;
548 Scope *CurScope = getCurScope();
549 while (CurScope != TopScope && !CurScope->
isDeclScope(D)) {
552 return CurScope != TopScope;
559 StringRef Name,
const AttrVec *Attrs =
nullptr) {
576 bool RefersToCapture =
false) {
584 DSAStackTy::DSAVarData DSAStackTy::getTopDSA(
VarDecl *D,
bool FromParent) {
592 !(D->
hasAttr<OMPThreadPrivateDeclAttr>() &&
593 SemaRef.getLangOpts().OpenMPUseTLS &&
594 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
601 if (
Stack[0].SharingMap.count(D)) {
602 DVar.RefExpr =
Stack[0].SharingMap[D].RefExpr;
615 DSAVarData DVarTemp =
620 DVar.CKind = OMPC_shared;
625 bool IsConstant = Type.
isConstant(SemaRef.getASTContext());
626 Type = SemaRef.getASTContext().getBaseElementType(Type);
633 if (
auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
634 if (
auto *CTD = CTSD->getSpecializedTemplate())
635 RD = CTD->getTemplatedDecl();
637 !(SemaRef.getLangOpts().CPlusPlus && RD && RD->
hasDefinition() &&
641 DSAVarData DVarTemp = hasDSA(D, MatchesAnyClause(OMPC_firstprivate),
642 MatchesAlways(), FromParent);
643 if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
646 DVar.CKind = OMPC_shared;
652 auto StartI = std::next(
Stack.rbegin());
653 auto EndI = std::prev(
Stack.rend());
654 if (FromParent && StartI != EndI) {
655 StartI = std::next(StartI);
657 auto I = std::prev(StartI);
658 if (I->SharingMap.count(D)) {
659 DVar.RefExpr = I->SharingMap[D].RefExpr;
660 DVar.CKind = I->SharingMap[D].Attributes;
661 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
667 DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(
VarDecl *D,
bool FromParent) {
669 auto StartI =
Stack.rbegin();
670 auto EndI = std::prev(
Stack.rend());
671 if (FromParent && StartI != EndI) {
672 StartI = std::next(StartI);
674 return getDSA(StartI, D);
677 template <
class ClausesPredicate,
class DirectivesPredicate>
678 DSAStackTy::DSAVarData DSAStackTy::hasDSA(
VarDecl *D, ClausesPredicate CPred,
679 DirectivesPredicate DPred,
682 auto StartI = std::next(
Stack.rbegin());
683 auto EndI = std::prev(
Stack.rend());
684 if (FromParent && StartI != EndI) {
685 StartI = std::next(StartI);
687 for (
auto I = StartI, EE = EndI; I != EE; ++
I) {
688 if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive))
690 DSAVarData DVar = getDSA(I, D);
691 if (CPred(DVar.CKind))
697 template <
class ClausesPredicate,
class DirectivesPredicate>
698 DSAStackTy::DSAVarData
699 DSAStackTy::hasInnermostDSA(
VarDecl *D, ClausesPredicate CPred,
700 DirectivesPredicate DPred,
bool FromParent) {
702 auto StartI = std::next(
Stack.rbegin());
703 auto EndI = std::prev(
Stack.rend());
704 if (FromParent && StartI != EndI) {
705 StartI = std::next(StartI);
707 for (
auto I = StartI, EE = EndI; I != EE; ++
I) {
708 if (!DPred(I->Directive))
710 DSAVarData DVar = getDSA(I, D);
711 if (CPred(DVar.CKind))
718 bool DSAStackTy::hasExplicitDSA(
721 if (CPred(ClauseKindMode))
723 if (isClauseParsingMode())
726 auto StartI =
Stack.rbegin();
727 auto EndI = std::prev(
Stack.rend());
728 if (std::distance(StartI, EndI) <= (int)Level)
730 std::advance(StartI, Level);
731 return (StartI->SharingMap.count(D) > 0) && StartI->SharingMap[D].RefExpr &&
732 CPred(StartI->SharingMap[D].Attributes);
735 bool DSAStackTy::hasExplicitDirective(
738 if (isClauseParsingMode())
740 auto StartI =
Stack.rbegin();
741 auto EndI = std::prev(
Stack.rend());
742 if (std::distance(StartI, EndI) <= (int)Level)
744 std::advance(StartI, Level);
745 return DPred(StartI->Directive);
748 template <
class NamedDirectivesPredicate>
749 bool DSAStackTy::hasDirective(NamedDirectivesPredicate DPred,
bool FromParent) {
750 auto StartI = std::next(
Stack.rbegin());
751 auto EndI = std::prev(
Stack.rend());
752 if (FromParent && StartI != EndI) {
753 StartI = std::next(StartI);
755 for (
auto I = StartI, EE = EndI; I != EE; ++
I) {
756 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
763 for (
auto I =
Stack.rbegin(), EE =
Stack.rend(); I != EE; ++
I)
764 if (I->CurScope == S)
769 void Sema::InitDataSharingAttributesStack() {
770 VarDataSharingAttributesStack =
new DSAStackTy(*
this);
773 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
777 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
845 if (Ty->isReferenceType())
855 (Ctx.getTypeSizeInChars(Ty) >
856 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
857 Ctx.getDeclAlign(VD) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType())))
864 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
875 if (
DSAStack->getCurrentDirective() == OMPD_target &&
891 (!
DSAStack->isClauseParsingMode() ||
893 if (
DSAStack->isLoopControlVariable(VD) ||
895 isParallelOrTaskRegion(
DSAStack->getCurrentDirective())) ||
898 auto DVarPrivate =
DSAStack->getTopDSA(VD,
DSAStack->isClauseParsingMode());
909 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
915 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
922 void Sema::DestroyDataSharingAttributesStack() {
delete DSAStack; }
927 DSAStack->push(DKind, DirName, CurScope, Loc);
945 if (
auto D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
946 for (
auto *
C : D->clauses()) {
947 if (
auto *Clause = dyn_cast<OMPLastprivateClause>(
C)) {
949 for (
auto *DE : Clause->varlists()) {
950 if (DE->isValueDependent() || DE->isTypeDependent()) {
951 PrivateCopies.push_back(
nullptr);
954 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(DE)->getDecl());
956 auto DVar =
DSAStack->getTopDSA(VD,
false);
957 if (DVar.CKind == OMPC_lastprivate) {
964 *
this, DE->getExprLoc(), Type.getUnqualifiedType(),
967 if (VDPrivate->isInvalidDecl())
970 *
this, VDPrivate, DE->getType(), DE->getExprLoc()));
974 PrivateCopies.push_back(
nullptr);
978 if (PrivateCopies.size() == Clause->varlist_size()) {
979 Clause->setPrivateCopies(PrivateCopies);
1001 explicit VarDeclFilterCCC(
Sema &S) : SemaRef(S) {}
1002 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1004 if (
VarDecl *VD = dyn_cast_or_null<VarDecl>(ND)) {
1006 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1007 SemaRef.getCurScope());
1030 ? diag::err_undeclared_var_use_suggest
1031 : diag::err_omp_expected_var_arg_suggest)
1033 VD = Corrected.getCorrectionDeclAs<
VarDecl>();
1036 : diag::err_omp_expected_var_arg)
1052 Diag(Id.
getLoc(), diag::err_omp_global_var_arg)
1057 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1063 NamedDecl *ND = cast<NamedDecl>(CanonicalVD);
1074 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1089 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1105 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1119 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1149 class LocalVarRefChecker :
public ConstStmtVisitor<LocalVarRefChecker, bool> {
1154 if (
auto VD = dyn_cast<VarDecl>(E->
getDecl())) {
1157 diag::err_omp_local_var_in_threadprivate_init)
1158 << E->getSourceRange();
1159 SemaRef.Diag(VD->
getLocation(), diag::note_defined_here)
1166 bool VisitStmt(
const Stmt *S) {
1167 for (
auto Child : S->children()) {
1168 if (Child && Visit(Child))
1173 explicit LocalVarRefChecker(
Sema &SemaRef) : SemaRef(SemaRef) {}
1180 for (
auto &RefExpr : VarList) {
1195 diag::err_omp_threadprivate_incomplete_type)) {
1201 if (VD->getType()->isReferenceType()) {
1202 Diag(ILoc, diag::err_omp_ref_type_arg)
1206 Diag(VD->getLocation(),
1207 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1215 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1218 (VD->getStorageClass() ==
SC_Register && VD->hasAttr<AsmLabelAttr>() &&
1219 !VD->isLocalVarDecl())) {
1220 Diag(ILoc, diag::err_omp_var_thread_local)
1224 Diag(VD->getLocation(),
1225 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1232 if (
auto Init = VD->getAnyInitializer()) {
1233 LocalVarRefChecker Checker(*
this);
1234 if (Checker.Visit(Init))
1238 Vars.push_back(RefExpr);
1240 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
1243 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
1246 if (!Vars.empty()) {
1255 const VarDecl *VD, DSAStackTy::DSAVarData DVar,
1256 bool IsLoopIterVar =
false) {
1258 SemaRef.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
1263 PDSA_StaticMemberShared,
1264 PDSA_StaticLocalVarShared,
1265 PDSA_LoopIterVarPrivate,
1266 PDSA_LoopIterVarLinear,
1267 PDSA_LoopIterVarLastprivate,
1268 PDSA_ConstVarShared,
1269 PDSA_GlobalVarShared,
1270 PDSA_TaskVarFirstprivate,
1271 PDSA_LocalVarPrivate,
1273 } Reason = PDSA_Implicit;
1274 bool ReportHint =
false;
1276 if (IsLoopIterVar) {
1277 if (DVar.CKind == OMPC_private)
1278 Reason = PDSA_LoopIterVarPrivate;
1279 else if (DVar.CKind == OMPC_lastprivate)
1280 Reason = PDSA_LoopIterVarLastprivate;
1282 Reason = PDSA_LoopIterVarLinear;
1283 }
else if (DVar.DKind == OMPD_task && DVar.CKind == OMPC_firstprivate) {
1284 Reason = PDSA_TaskVarFirstprivate;
1285 ReportLoc = DVar.ImplicitDSALoc;
1287 Reason = PDSA_StaticLocalVarShared;
1289 Reason = PDSA_StaticMemberShared;
1291 Reason = PDSA_GlobalVarShared;
1293 Reason = PDSA_ConstVarShared;
1296 Reason = PDSA_LocalVarPrivate;
1298 if (Reason != PDSA_Implicit) {
1299 SemaRef.
Diag(ReportLoc, diag::note_omp_predetermined_dsa)
1300 << Reason << ReportHint
1302 }
else if (DVar.ImplicitDSALoc.isValid()) {
1303 SemaRef.
Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
1309 class DSAAttrChecker :
public StmtVisitor<DSAAttrChecker, void> {
1315 llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA;
1319 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
1324 auto DVar =
Stack->getTopDSA(VD,
false);
1326 if (DVar.RefExpr)
return;
1329 auto DKind =
Stack->getCurrentDirective();
1335 isParallelOrTaskRegion(DKind) &&
1336 VarsWithInheritedDSA.count(VD) == 0) {
1337 VarsWithInheritedDSA[VD] =
E;
1345 DVar =
Stack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction),
1352 if (DKind == OMPD_task && DVar.CKind == OMPC_reduction) {
1354 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
1360 DVar =
Stack->getImplicitDSA(VD,
false);
1361 if (DKind == OMPD_task && DVar.CKind != OMPC_shared)
1362 ImplicitFirstprivate.push_back(E);
1369 if (
C && (!isa<OMPFirstprivateClause>(
C) ||
C->getLocStart().isValid()))
1370 for (
auto *CC :
C->children()) {
1376 void VisitStmt(
Stmt *S) {
1377 for (
auto *
C : S->children()) {
1378 if (
C && !isa<OMPExecutableDirective>(
C))
1383 bool isErrorFound() {
return ErrorFound; }
1384 ArrayRef<Expr *> getImplicitFirstprivate() {
return ImplicitFirstprivate; }
1385 llvm::DenseMap<VarDecl *, Expr *> &getVarsWithInheritedDSA() {
1386 return VarsWithInheritedDSA;
1390 :
Stack(S), SemaRef(SemaRef), ErrorFound(
false), CS(CS) {}
1396 case OMPD_parallel: {
1401 std::make_pair(
".global_tid.", KmpInt32PtrTy),
1402 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
1403 std::make_pair(StringRef(),
QualType())
1411 std::make_pair(StringRef(),
QualType())
1419 std::make_pair(StringRef(),
QualType())
1425 case OMPD_for_simd: {
1427 std::make_pair(StringRef(),
QualType())
1433 case OMPD_sections: {
1435 std::make_pair(StringRef(),
QualType())
1441 case OMPD_section: {
1443 std::make_pair(StringRef(),
QualType())
1451 std::make_pair(StringRef(),
QualType())
1459 std::make_pair(StringRef(),
QualType())
1465 case OMPD_critical: {
1467 std::make_pair(StringRef(),
QualType())
1473 case OMPD_parallel_for: {
1478 std::make_pair(
".global_tid.", KmpInt32PtrTy),
1479 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
1480 std::make_pair(StringRef(),
QualType())
1486 case OMPD_parallel_for_simd: {
1491 std::make_pair(
".global_tid.", KmpInt32PtrTy),
1492 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
1493 std::make_pair(StringRef(),
QualType())
1499 case OMPD_parallel_sections: {
1504 std::make_pair(
".global_tid.", KmpInt32PtrTy),
1505 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
1506 std::make_pair(StringRef(),
QualType())
1519 std::make_pair(
".global_tid.", KmpInt32Ty),
1520 std::make_pair(
".part_id.", KmpInt32Ty),
1521 std::make_pair(
".privates.",
1526 std::make_pair(StringRef(),
QualType())
1533 AlwaysInlineAttr::CreateImplicit(
1537 case OMPD_ordered: {
1539 std::make_pair(StringRef(),
QualType())
1547 std::make_pair(StringRef(),
QualType())
1553 case OMPD_target_data:
1556 std::make_pair(StringRef(),
QualType())
1567 std::make_pair(
".global_tid.", KmpInt32PtrTy),
1568 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
1569 std::make_pair(StringRef(),
QualType())
1575 case OMPD_taskgroup: {
1577 std::make_pair(StringRef(),
QualType())
1583 case OMPD_taskloop: {
1585 std::make_pair(StringRef(),
QualType())
1591 case OMPD_taskloop_simd: {
1593 std::make_pair(StringRef(),
QualType())
1599 case OMPD_distribute: {
1601 std::make_pair(StringRef(),
QualType())
1607 case OMPD_threadprivate:
1608 case OMPD_taskyield:
1611 case OMPD_cancellation_point:
1614 llvm_unreachable(
"OpenMP Directive is not allowed");
1616 llvm_unreachable(
"Unknown OpenMP directive");
1631 for (
auto *Clause : Clauses) {
1633 Clause->getClauseKind() == OMPC_copyprivate ||
1636 Clause->getClauseKind() == OMPC_copyin)) {
1637 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
1639 for (
auto *VarRef : Clause->children()) {
1640 if (
auto *E = cast_or_null<Expr>(VarRef)) {
1644 DSAStack->setForceVarCapturing(
false);
1645 }
else if (isParallelOrTaskRegion(
DSAStack->getCurrentDirective()) &&
1646 Clause->getClauseKind() == OMPC_schedule) {
1650 if (
auto *E = cast_or_null<Expr>(
1651 cast<OMPScheduleClause>(Clause)->getHelperChunkSize()))
1654 if (Clause->getClauseKind() == OMPC_schedule)
1655 SC = cast<OMPScheduleClause>(Clause);
1656 else if (Clause->getClauseKind() == OMPC_ordered)
1657 OC = cast<OMPOrderedClause>(Clause);
1658 else if (Clause->getClauseKind() == OMPC_linear)
1659 LCs.push_back(cast<OMPLinearClause>(Clause));
1661 bool ErrorFound =
false;
1668 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
1673 diag::err_omp_schedule_nonmonotonic_ordered)
1678 for (
auto *
C : LCs) {
1679 Diag(
C->getLocStart(), diag::err_omp_linear_ordered)
2285 if (Stack->getCurScope()) {
2286 auto ParentRegion = Stack->getParentDirective();
2287 bool NestingProhibited =
false;
2288 bool CloseNesting =
true;
2291 ShouldBeInParallelRegion,
2292 ShouldBeInOrderedRegion,
2293 ShouldBeInTargetRegion,
2294 ShouldBeInTeamsRegion
2295 } Recommend = NoRecommend;
2302 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_simd);
2305 if (ParentRegion == OMPD_atomic) {
2308 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
2311 if (CurrentRegion == OMPD_section) {
2316 if (ParentRegion != OMPD_sections &&
2317 ParentRegion != OMPD_parallel_sections) {
2318 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_section_directive)
2329 if (CurrentRegion == OMPD_cancellation_point ||
2330 CurrentRegion == OMPD_cancel) {
2343 !((CancelRegion == OMPD_parallel && ParentRegion == OMPD_parallel) ||
2344 (CancelRegion == OMPD_for &&
2345 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for)) ||
2346 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
2347 (CancelRegion == OMPD_sections &&
2348 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
2349 ParentRegion == OMPD_parallel_sections)));
2350 }
else if (CurrentRegion == OMPD_master) {
2355 ParentRegion == OMPD_task ||
2357 }
else if (CurrentRegion == OMPD_critical && CurrentName.
getName()) {
2364 Stack->hasDirective([CurrentName, &PreviousCriticalLoc](
2369 if (K == OMPD_critical &&
2371 PreviousCriticalLoc = Loc;
2378 SemaRef.
Diag(StartLoc,
2379 diag::err_omp_prohibited_region_critical_same_name)
2381 if (PreviousCriticalLoc.
isValid())
2382 SemaRef.
Diag(PreviousCriticalLoc,
2383 diag::note_omp_previous_critical_region);
2386 }
else if (CurrentRegion == OMPD_barrier) {
2392 ParentRegion == OMPD_task || ParentRegion == OMPD_master ||
2393 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered ||
2402 ParentRegion == OMPD_task || ParentRegion == OMPD_master ||
2403 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered ||
2405 Recommend = ShouldBeInParallelRegion;
2406 }
else if (CurrentRegion == OMPD_ordered) {
2415 NestingProhibited = ParentRegion == OMPD_critical ||
2416 ParentRegion == OMPD_task ||
2419 Stack->isParentOrderedRegion());
2420 Recommend = ShouldBeInOrderedRegion;
2425 NestingProhibited = ParentRegion != OMPD_target;
2426 Recommend = ShouldBeInTargetRegion;
2427 Stack->setParentTeamsRegionLoc(Stack->getConstructLoc());
2436 Recommend = ShouldBeInParallelRegion;
2443 Recommend = ShouldBeInTeamsRegion;
2445 if (NestingProhibited) {
2446 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region)
2458 bool ErrorFound =
false;
2459 unsigned NamedModifiersNumber = 0;
2463 for (
const auto *
C : Clauses) {
2464 if (
const auto *IC = dyn_cast_or_null<OMPIfClause>(
C)) {
2468 if (FoundNameModifiers[CurNM]) {
2469 S.
Diag(
C->getLocStart(), diag::err_omp_more_one_clause)
2474 NameModifierLoc.push_back(IC->getNameModifierLoc());
2475 ++NamedModifiersNumber;
2477 FoundNameModifiers[CurNM] = IC;
2484 bool MatchFound =
false;
2485 for (
auto NM : AllowedNameModifiers) {
2492 S.
Diag(IC->getNameModifierLoc(),
2493 diag::err_omp_wrong_if_directive_name_modifier)
2501 if (FoundNameModifiers[
OMPD_unknown] && NamedModifiersNumber > 0) {
2502 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
2504 diag::err_omp_no_more_if_clause);
2507 std::string Sep(
", ");
2508 unsigned AllowedCnt = 0;
2509 unsigned TotalAllowedNum =
2510 AllowedNameModifiers.size() - NamedModifiersNumber;
2511 for (
unsigned Cnt = 0,
End = AllowedNameModifiers.size(); Cnt <
End;
2514 if (!FoundNameModifiers[NM]) {
2518 if (AllowedCnt + 2 == TotalAllowedNum)
2520 else if (AllowedCnt + 1 != TotalAllowedNum)
2526 diag::err_omp_unnamed_if_clause)
2527 << (TotalAllowedNum > 1) << Values;
2529 for (
auto Loc : NameModifierLoc) {
2530 S.
Diag(Loc, diag::note_omp_previous_named_if_clause);
2547 llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA;
2548 bool ErrorFound =
false;
2549 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
2551 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
2554 DSAAttrChecker DSAChecker(
DSAStack, *
this, cast<CapturedStmt>(AStmt));
2555 DSAChecker.Visit(cast<CapturedStmt>(AStmt)->getCapturedStmt());
2556 if (DSAChecker.isErrorFound())
2559 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
2561 if (!DSAChecker.getImplicitFirstprivate().empty()) {
2565 ClausesWithImplicit.push_back(Implicit);
2566 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
2567 DSAChecker.getImplicitFirstprivate().size();
2578 AllowedNameModifiers.push_back(OMPD_parallel);
2582 VarsWithInheritedDSA);
2586 VarsWithInheritedDSA);
2590 EndLoc, VarsWithInheritedDSA);
2597 assert(ClausesWithImplicit.empty() &&
2598 "No clauses are allowed for 'omp section' directive");
2606 assert(ClausesWithImplicit.empty() &&
2607 "No clauses are allowed for 'omp master' directive");
2614 case OMPD_parallel_for:
2616 EndLoc, VarsWithInheritedDSA);
2617 AllowedNameModifiers.push_back(OMPD_parallel);
2619 case OMPD_parallel_for_simd:
2621 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2622 AllowedNameModifiers.push_back(OMPD_parallel);
2624 case OMPD_parallel_sections:
2627 AllowedNameModifiers.push_back(OMPD_parallel);
2632 AllowedNameModifiers.push_back(OMPD_task);
2634 case OMPD_taskyield:
2635 assert(ClausesWithImplicit.empty() &&
2636 "No clauses are allowed for 'omp taskyield' directive");
2637 assert(AStmt ==
nullptr &&
2638 "No associated statement allowed for 'omp taskyield' directive");
2642 assert(ClausesWithImplicit.empty() &&
2643 "No clauses are allowed for 'omp barrier' directive");
2644 assert(AStmt ==
nullptr &&
2645 "No associated statement allowed for 'omp barrier' directive");
2649 assert(ClausesWithImplicit.empty() &&
2650 "No clauses are allowed for 'omp taskwait' directive");
2651 assert(AStmt ==
nullptr &&
2652 "No associated statement allowed for 'omp taskwait' directive");
2655 case OMPD_taskgroup:
2656 assert(ClausesWithImplicit.empty() &&
2657 "No clauses are allowed for 'omp taskgroup' directive");
2661 assert(AStmt ==
nullptr &&
2662 "No associated statement allowed for 'omp flush' directive");
2680 AllowedNameModifiers.push_back(OMPD_target);
2682 case OMPD_cancellation_point:
2683 assert(ClausesWithImplicit.empty() &&
2684 "No clauses are allowed for 'omp cancellation point' directive");
2685 assert(AStmt ==
nullptr &&
"No associated statement allowed for 'omp "
2686 "cancellation point' directive");
2690 assert(AStmt ==
nullptr &&
2691 "No associated statement allowed for 'omp cancel' directive");
2694 AllowedNameModifiers.push_back(OMPD_cancel);
2696 case OMPD_target_data:
2699 AllowedNameModifiers.push_back(OMPD_target_data);
2703 EndLoc, VarsWithInheritedDSA);
2704 AllowedNameModifiers.push_back(OMPD_taskloop);
2706 case OMPD_taskloop_simd:
2708 EndLoc, VarsWithInheritedDSA);
2709 AllowedNameModifiers.push_back(OMPD_taskloop);
2711 case OMPD_distribute:
2713 EndLoc, VarsWithInheritedDSA);
2715 case OMPD_threadprivate:
2716 llvm_unreachable(
"OpenMP Directive is not allowed");
2718 llvm_unreachable(
"Unknown OpenMP directive");
2721 for (
auto P : VarsWithInheritedDSA) {
2722 Diag(
P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
2723 <<
P.first <<
P.second->getSourceRange();
2725 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
2727 if (!AllowedNameModifiers.empty())
2728 ErrorFound =
checkIfClauses(*
this, Kind, Clauses, AllowedNameModifiers) ||
2761 class OpenMPIterationSpaceChecker {
2791 bool TestIsStrictOp;
2797 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc),
2799 IncrementSrcRange(
SourceRange()), Var(nullptr), VarRef(nullptr),
2800 LB(nullptr), UB(nullptr),
Step(nullptr), TestIsLessOp(
false),
2801 TestIsStrictOp(
false), SubtractStep(
false) {}
2804 bool CheckInit(
Stmt *S,
bool EmitDiags =
true);
2807 bool CheckCond(
Expr *S);
2810 bool CheckInc(
Expr *S);
2812 VarDecl *GetLoopVar()
const {
return Var; }
2814 DeclRefExpr *GetLoopVarRefExpr()
const {
return VarRef; }
2816 SourceRange GetInitSrcRange()
const {
return InitSrcRange; }
2818 SourceRange GetConditionSrcRange()
const {
return ConditionSrcRange; }
2820 SourceRange GetIncrementSrcRange()
const {
return IncrementSrcRange; }
2822 bool ShouldSubtractStep()
const {
return SubtractStep; }
2824 Expr *BuildNumIterations(
Scope *S,
const bool LimitedType)
const;
2828 Expr *BuildCounterVar()
const;
2831 Expr *BuildPrivateCounterVar()
const;
2835 Expr *BuildCounterStep()
const;
2837 bool Dependent()
const;
2842 bool CheckIncRHS(
Expr *RHS);
2849 bool SetStep(
Expr *NewStep,
bool Subtract);
2852 bool OpenMPIterationSpaceChecker::Dependent()
const {
2854 assert(!LB && !UB && !
Step);
2857 return Var->getType()->isDependentType() || (LB && LB->isValueDependent()) ||
2858 (UB && UB->isValueDependent()) || (
Step &&
Step->isValueDependent());
2861 template <
typename T>
2862 static T *getExprAsWritten(T *E) {
2863 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(E))
2864 E = ExprTemp->getSubExpr();
2866 if (
auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
2867 E = MTE->GetTemporaryExpr();
2869 while (
auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
2870 E = Binder->getSubExpr();
2872 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E))
2873 E = ICE->getSubExprAsWritten();
2874 return E->IgnoreParens();
2877 bool OpenMPIterationSpaceChecker::SetVarAndLB(
VarDecl *NewVar,
2881 assert(Var ==
nullptr && LB ==
nullptr && VarRef ==
nullptr &&
2882 UB ==
nullptr &&
Step ==
nullptr && !TestIsLessOp && !TestIsStrictOp);
2883 if (!NewVar || !NewLB)
2886 VarRef = NewVarRefExpr;
2887 if (
auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
2889 if ((Ctor->isCopyOrMoveConstructor() ||
2890 Ctor->isConvertingConstructor(
false)) &&
2891 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
2897 bool OpenMPIterationSpaceChecker::SetUB(
Expr *NewUB,
bool LessOp,
bool StrictOp,
2900 assert(Var !=
nullptr && LB !=
nullptr && UB ==
nullptr &&
Step ==
nullptr &&
2901 !TestIsLessOp && !TestIsStrictOp);
2905 TestIsLessOp = LessOp;
2906 TestIsStrictOp = StrictOp;
2907 ConditionSrcRange = SR;
2912 bool OpenMPIterationSpaceChecker::SetStep(
Expr *NewStep,
bool Subtract) {
2914 assert(Var !=
nullptr && LB !=
nullptr &&
Step ==
nullptr);
2921 SemaRef.PerformOpenMPImplicitIntegerConversion(StepLoc, NewStep);
2924 NewStep = Val.
get();
2941 IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
2943 IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
2944 bool IsConstZero = IsConstant && !Result.getBoolValue();
2945 if (UB && (IsConstZero ||
2946 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
2947 : (IsConstPos || (IsUnsigned && !Subtract))))) {
2949 diag::err_omp_loop_incr_not_compatible)
2950 << Var << TestIsLessOp << NewStep->getSourceRange();
2951 SemaRef.Diag(ConditionLoc,
2952 diag::note_omp_loop_cond_requres_compatible_incr)
2953 << TestIsLessOp << ConditionSrcRange;
2956 if (TestIsLessOp == Subtract) {
2959 Subtract = !Subtract;
2964 SubtractStep = Subtract;
2968 bool OpenMPIterationSpaceChecker::CheckInit(
Stmt *S,
bool EmitDiags) {
2979 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
2983 InitSrcRange = S->getSourceRange();
2984 if (
Expr *E = dyn_cast<Expr>(S))
2985 S = E->IgnoreParens();
2986 if (
auto BO = dyn_cast<BinaryOperator>(S)) {
2988 if (
auto DRE = dyn_cast<DeclRefExpr>(BO->getLHS()->IgnoreParens()))
2989 return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), DRE,
2991 }
else if (
auto DS = dyn_cast<DeclStmt>(S)) {
2992 if (DS->isSingleDecl()) {
2993 if (
auto Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
2994 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
2997 SemaRef.Diag(S->getLocStart(),
2998 diag::ext_omp_loop_not_canonical_init)
2999 << S->getSourceRange();
3000 return SetVarAndLB(Var,
nullptr, Var->getInit());
3004 }
else if (
auto CE = dyn_cast<CXXOperatorCallExpr>(S))
3005 if (CE->getOperator() == OO_Equal)
3006 if (
auto DRE = dyn_cast<DeclRefExpr>(CE->getArg(0)))
3007 return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), DRE,
3011 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init)
3012 << S->getSourceRange();
3019 static const VarDecl *GetInitVarDecl(
const Expr *E) {
3022 E = getExprAsWritten(E);
3023 if (
auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
3025 if ((Ctor->isCopyOrMoveConstructor() ||
3026 Ctor->isConvertingConstructor(
false)) &&
3027 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
3029 auto DRE = dyn_cast_or_null<DeclRefExpr>(
E);
3032 return dyn_cast<
VarDecl>(DRE->getDecl());
3035 bool OpenMPIterationSpaceChecker::CheckCond(
Expr *S) {
3043 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << Var;
3046 S = getExprAsWritten(S);
3048 if (
auto BO = dyn_cast<BinaryOperator>(S)) {
3049 if (BO->isRelationalOp()) {
3050 if (GetInitVarDecl(BO->getLHS()) == Var)
3051 return SetUB(BO->getRHS(),
3052 (BO->getOpcode() ==
BO_LT || BO->getOpcode() ==
BO_LE),
3053 (BO->getOpcode() ==
BO_LT || BO->getOpcode() ==
BO_GT),
3054 BO->getSourceRange(), BO->getOperatorLoc());
3055 if (GetInitVarDecl(BO->getRHS()) == Var)
3056 return SetUB(BO->getLHS(),
3057 (BO->getOpcode() ==
BO_GT || BO->getOpcode() ==
BO_GE),
3058 (BO->getOpcode() ==
BO_LT || BO->getOpcode() ==
BO_GT),
3059 BO->getSourceRange(), BO->getOperatorLoc());
3061 }
else if (
auto CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3062 if (CE->getNumArgs() == 2) {
3063 auto Op = CE->getOperator();
3066 case OO_GreaterEqual:
3069 if (GetInitVarDecl(CE->getArg(0)) == Var)
3070 return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
3071 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
3072 CE->getOperatorLoc());
3073 if (GetInitVarDecl(CE->getArg(1)) == Var)
3074 return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
3075 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
3076 CE->getOperatorLoc());
3083 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
3084 << S->getSourceRange() << Var;
3088 bool OpenMPIterationSpaceChecker::CheckIncRHS(
Expr *RHS) {
3095 if (
auto BO = dyn_cast<BinaryOperator>(RHS)) {
3096 if (BO->isAdditiveOp()) {
3097 bool IsAdd = BO->getOpcode() ==
BO_Add;
3098 if (GetInitVarDecl(BO->getLHS()) == Var)
3099 return SetStep(BO->getRHS(), !IsAdd);
3100 if (IsAdd && GetInitVarDecl(BO->getRHS()) == Var)
3101 return SetStep(BO->getLHS(),
false);
3103 }
else if (
auto CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
3104 bool IsAdd = CE->getOperator() == OO_Plus;
3105 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
3106 if (GetInitVarDecl(CE->getArg(0)) == Var)
3107 return SetStep(CE->getArg(1), !IsAdd);
3108 if (IsAdd && GetInitVarDecl(CE->getArg(1)) == Var)
3109 return SetStep(CE->getArg(0),
false);
3112 SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr)
3113 << RHS->getSourceRange() << Var;
3117 bool OpenMPIterationSpaceChecker::CheckInc(
Expr *S) {
3132 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << Var;
3135 IncrementSrcRange = S->getSourceRange();
3137 if (
auto UO = dyn_cast<UnaryOperator>(S)) {
3138 if (UO->isIncrementDecrementOp() && GetInitVarDecl(UO->getSubExpr()) == Var)
3140 SemaRef.ActOnIntegerConstant(UO->getLocStart(),
3141 (UO->isDecrementOp() ? -1 : 1)).get(),
3143 }
else if (
auto BO = dyn_cast<BinaryOperator>(S)) {
3144 switch (BO->getOpcode()) {
3147 if (GetInitVarDecl(BO->getLHS()) == Var)
3148 return SetStep(BO->getRHS(), BO->getOpcode() ==
BO_SubAssign);
3151 if (GetInitVarDecl(BO->getLHS()) == Var)
3152 return CheckIncRHS(BO->getRHS());
3157 }
else if (
auto CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3158 switch (CE->getOperator()) {
3161 if (GetInitVarDecl(CE->getArg(0)) == Var)
3163 SemaRef.ActOnIntegerConstant(
3165 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)).
get(),
3170 if (GetInitVarDecl(CE->getArg(0)) == Var)
3171 return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
3174 if (GetInitVarDecl(CE->getArg(0)) == Var)
3175 return CheckIncRHS(CE->getArg(1));
3181 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr)
3182 << S->getSourceRange() << Var;
3189 class TransformToNewDefs :
public TreeTransform<TransformToNewDefs> {
3193 TransformToNewDefs(
Sema &SemaRef) : BaseTransform(SemaRef) {}
3196 if (
auto *VD = cast<VarDecl>(D))
3197 if (!isa<ParmVarDecl>(D) && !isa<VarTemplateSpecializationDecl>(D) &&
3198 !isa<ImplicitParamDecl>(D)) {
3204 NewVD->setInit(VD->
getInit());
3211 NewVD->setPreviousDeclInSameBlockScope(
3216 transformedLocalDecl(VD, NewVD);
3219 return BaseTransform::TransformDefinition(Loc, D);
3225 NewD->setReferenced();
3226 NewD->markUsed(SemaRef.Context);
3232 return BaseTransform::TransformDeclRefExpr(E);
3239 OpenMPIterationSpaceChecker::BuildNumIterations(
Scope *S,
3240 const bool LimitedType)
const {
3241 TransformToNewDefs Transform(SemaRef);
3243 auto VarType = Var->getType().getNonReferenceType();
3244 if (VarType->isIntegerType() || VarType->isPointerType() ||
3245 SemaRef.getLangOpts().CPlusPlus) {
3247 auto *UBExpr = TestIsLessOp ? UB : LB;
3248 auto *LBExpr = TestIsLessOp ? LB : UB;
3249 Expr *Upper = Transform.TransformExpr(UBExpr).get();
3250 Expr *Lower = Transform.TransformExpr(LBExpr).get();
3251 if (!Upper || !Lower)
3253 if (!SemaRef.Context.hasSameType(Upper->
getType(), UBExpr->getType())) {
3255 .PerformImplicitConversion(Upper, UBExpr->
getType(),
3260 if (!SemaRef.Context.hasSameType(Lower->
getType(), LBExpr->getType())) {
3262 .PerformImplicitConversion(Lower, LBExpr->
getType(),
3267 if (!Upper || !Lower)
3270 Diff = SemaRef.BuildBinOp(S, DefaultLoc,
BO_Sub, Upper, Lower);
3272 if (!Diff.
isUsable() && VarType->getAsCXXRecordDecl()) {
3275 SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx)
3276 << Upper->getSourceRange() << Lower->getSourceRange();
3286 Diff = SemaRef.BuildBinOp(
3293 auto *StepNoImp =
Step->IgnoreImplicit();
3294 auto NewStep = Transform.TransformExpr(StepNoImp);
3295 if (NewStep.isInvalid())
3297 if (!SemaRef.Context.hasSameType(NewStep.get()->
getType(),
3298 StepNoImp->getType())) {
3299 NewStep = SemaRef.PerformImplicitConversion(
3302 if (NewStep.isInvalid())
3305 Diff = SemaRef.BuildBinOp(S, DefaultLoc,
BO_Add, Diff.
get(), NewStep.get());
3310 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.
get());
3315 NewStep = Transform.TransformExpr(StepNoImp);
3316 if (NewStep.isInvalid())
3318 if (!SemaRef.Context.hasSameType(NewStep.get()->
getType(),
3319 StepNoImp->getType())) {
3320 NewStep = SemaRef.PerformImplicitConversion(
3323 if (NewStep.isInvalid())
3326 Diff = SemaRef.BuildBinOp(S, DefaultLoc,
BO_Div, Diff.
get(), NewStep.get());
3332 auto &
C = SemaRef.Context;
3333 bool UseVarType = VarType->hasIntegerRepresentation() &&
3334 C.getTypeSize(Type) >
C.getTypeSize(VarType);
3337 UseVarType ?
C.getTypeSize(VarType) :
C.getTypeSize(Type);
3338 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
3340 Type =
C.getIntTypeForBitwidth(NewSize, IsSigned);
3341 if (!SemaRef.Context.hasSameType(Diff.
get()->
getType(), Type)) {
3342 Diff = SemaRef.PerformImplicitConversion(
3349 unsigned NewSize = (
C.getTypeSize(Type) > 32) ? 64 : 32;
3350 if (NewSize !=
C.getTypeSize(Type)) {
3351 if (NewSize <
C.getTypeSize(Type)) {
3352 assert(NewSize == 64 &&
"incorrect loop var size");
3353 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
3354 << InitSrcRange << ConditionSrcRange;
3356 QualType NewType =
C.getIntTypeForBitwidth(
3358 C.getTypeSize(Type) < NewSize);
3359 if (!SemaRef.Context.hasSameType(Diff.
get()->
getType(), NewType)) {
3360 Diff = SemaRef.PerformImplicitConversion(Diff.
get(), NewType,
3371 Expr *OpenMPIterationSpaceChecker::BuildPreCond(
Scope *S,
Expr *Cond)
const {
3373 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
3374 SemaRef.getDiagnostics().setSuppressAllDiagnostics(
true);
3375 TransformToNewDefs Transform(SemaRef);
3377 auto NewLB = Transform.TransformExpr(LB);
3378 auto NewUB = Transform.TransformExpr(UB);
3379 if (NewLB.isInvalid() || NewUB.isInvalid())
3381 if (!SemaRef.Context.hasSameType(NewLB.get()->
getType(), LB->getType())) {
3382 NewLB = SemaRef.PerformImplicitConversion(NewLB.get(), LB->
getType(),
3386 if (!SemaRef.Context.hasSameType(NewUB.get()->
getType(), UB->getType())) {
3387 NewUB = SemaRef.PerformImplicitConversion(NewUB.get(), UB->
getType(),
3391 if (NewLB.isInvalid() || NewUB.isInvalid())
3393 auto CondExpr = SemaRef.BuildBinOp(
3394 S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ?
BO_LT :
BO_LE)
3396 NewLB.get(), NewUB.get());
3397 if (CondExpr.isUsable()) {
3398 if (!SemaRef.Context.hasSameType(CondExpr.get()->getType(),
3399 SemaRef.Context.BoolTy))
3400 CondExpr = SemaRef.PerformImplicitConversion(
3404 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
3406 return CondExpr.isUsable() ? CondExpr.get() : Cond;
3410 Expr *OpenMPIterationSpaceChecker::BuildCounterVar()
const {
3411 return buildDeclRefExpr(SemaRef, Var, Var->getType().getNonReferenceType(),
3415 Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar()
const {
3416 if (Var && !Var->isInvalidDecl()) {
3417 auto Type = Var->getType().getNonReferenceType();
3419 buildVarDecl(SemaRef, DefaultLoc, Type, Var->getName(),
3420 Var->hasAttrs() ? &Var->getAttrs() :
nullptr);
3421 if (PrivateVar->isInvalidDecl())
3432 Expr *OpenMPIterationSpaceChecker::BuildCounterStep()
const {
return Step; }
3435 struct LoopIterationSpace {
3440 Expr *NumIterations;
3444 Expr *PrivateCounterVar;
3463 assert(
getLangOpts().OpenMP &&
"OpenMP is not active.");
3464 assert(Init &&
"Expected loop in canonical form.");
3465 unsigned AssociatedLoops =
DSAStack->getAssociatedLoops();
3466 if (AssociatedLoops > 0 &&
3468 OpenMPIterationSpaceChecker ISC(*
this, ForLoc);
3469 if (!ISC.CheckInit(Init,
false))
3470 DSAStack->addLoopControlVariable(ISC.GetLoopVar());
3471 DSAStack->setAssociatedLoops(AssociatedLoops - 1);
3479 unsigned CurrentNestedLoopCount,
unsigned NestedLoopCount,
3480 Expr *CollapseLoopCountExpr,
Expr *OrderedLoopCountExpr,
3481 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA,
3482 LoopIterationSpace &ResultIterSpace) {
3485 auto For = dyn_cast_or_null<ForStmt>(
S);
3487 SemaRef.
Diag(S->getLocStart(), diag::err_omp_not_for)
3488 << (CollapseLoopCountExpr !=
nullptr || OrderedLoopCountExpr !=
nullptr)
3490 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
3491 if (NestedLoopCount > 1) {
3492 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
3493 SemaRef.
Diag(DSA.getConstructLoc(),
3494 diag::note_omp_collapse_ordered_expr)
3495 << 2 << CollapseLoopCountExpr->getSourceRange()
3496 << OrderedLoopCountExpr->getSourceRange();
3497 else if (CollapseLoopCountExpr)
3499 diag::note_omp_collapse_ordered_expr)
3500 << 0 << CollapseLoopCountExpr->getSourceRange();
3503 diag::note_omp_collapse_ordered_expr)
3504 << 1 << OrderedLoopCountExpr->getSourceRange();
3508 assert(For->getBody());
3510 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
3513 auto Init = For->getInit();
3514 if (ISC.CheckInit(Init)) {
3518 bool HasErrors =
false;
3521 auto Var = ISC.GetLoopVar();
3529 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
3530 !VarType->isPointerType() &&
3531 !(SemaRef.
getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
3532 SemaRef.
Diag(Init->getLocStart(), diag::err_omp_loop_variable_type)
3546 VarsWithImplicitDSA.erase(Var);
3555 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(Var,
false);
3556 auto LoopVarRefExpr = ISC.GetLoopVarRefExpr();
3559 auto PredeterminedCKind =
3561 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
3564 DVar.CKind != PredeterminedCKind) ||
3568 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
3569 (DVar.CKind != OMPC_private || DVar.RefExpr !=
nullptr)) {
3570 SemaRef.
Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa)
3573 if (DVar.RefExpr ==
nullptr)
3574 DVar.CKind = PredeterminedCKind;
3577 }
else if (LoopVarRefExpr !=
nullptr) {
3585 DSA.addDSA(Var, LoopVarRefExpr, PredeterminedCKind);
3591 HasErrors |= ISC.CheckCond(For->getCond());
3594 HasErrors |= ISC.CheckInc(For->getInc());
3600 ResultIterSpace.PreCond = ISC.BuildPreCond(DSA.getCurScope(), For->getCond());
3601 ResultIterSpace.NumIterations = ISC.BuildNumIterations(
3605 ResultIterSpace.CounterVar = ISC.BuildCounterVar();
3606 ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar();
3607 ResultIterSpace.CounterInit = ISC.BuildCounterInit();
3608 ResultIterSpace.CounterStep = ISC.BuildCounterStep();
3609 ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange();
3610 ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange();
3611 ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange();
3612 ResultIterSpace.Subtract = ISC.ShouldSubtractStep();
3614 HasErrors |= (ResultIterSpace.PreCond ==
nullptr ||
3615 ResultIterSpace.NumIterations ==
nullptr ||
3616 ResultIterSpace.CounterVar ==
nullptr ||
3617 ResultIterSpace.PrivateCounterVar ==
nullptr ||
3618 ResultIterSpace.CounterInit ==
nullptr ||
3619 ResultIterSpace.CounterStep ==
nullptr);
3627 TransformToNewDefs Transform(SemaRef);
3630 auto NewStart = Transform.TransformExpr(StartNoImp);
3631 if (NewStart.isInvalid())
3634 StartNoImp->getType())) {
3638 if (NewStart.isInvalid())
3646 if (!NewStart.isUsable())
3667 TransformToNewDefs Transform(SemaRef);
3668 auto NewStep = Transform.TransformExpr(StepNoImp);
3669 if (NewStep.isInvalid())
3672 StepNoImp->getType())) {
3676 if (NewStep.isInvalid())
3686 auto NewStart = Transform.TransformExpr(StartNoImp);
3687 if (NewStart.isInvalid())
3690 StartNoImp->getType())) {
3694 if (NewStart.isInvalid())
3698 NewStart.get(), Update.
get());
3719 unsigned HasBits =
C.getTypeSize(OldType);
3720 if (HasBits >= Bits)
3723 QualType NewType =
C.getIntTypeForBitwidth(Bits,
true);
3735 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
3744 Expr *OrderedLoopCountExpr,
Stmt *AStmt,
Sema &SemaRef,
3746 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA,
3748 unsigned NestedLoopCount = 1;
3749 if (CollapseLoopCountExpr) {
3753 NestedLoopCount = Result.getLimitedValue();
3755 if (OrderedLoopCountExpr) {
3759 if (Result.getLimitedValue() < NestedLoopCount) {
3761 diag::err_omp_wrong_ordered_loop_count)
3762 << OrderedLoopCountExpr->getSourceRange();
3764 diag::note_collapse_loop_count)
3765 << CollapseLoopCountExpr->getSourceRange();
3767 NestedLoopCount = Result.getLimitedValue();
3773 IterSpaces.resize(NestedLoopCount);
3774 Stmt *CurStmt = AStmt->IgnoreContainers(
true);
3775 for (
unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
3777 NestedLoopCount, CollapseLoopCountExpr,
3778 OrderedLoopCountExpr, VarsWithImplicitDSA,
3786 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
3789 Built.
clear( NestedLoopCount);
3792 return NestedLoopCount;
3825 auto PreCond =
ExprResult(IterSpaces[0].PreCond);
3826 auto N0 = IterSpaces[0].NumIterations;
3829 N0->IgnoreImpCasts(), N0->getType(),
3835 N0->IgnoreImpCasts(), N0->getType(),
3840 if (!LastIteration32.
isUsable() || !LastIteration64.isUsable())
3841 return NestedLoopCount;
3844 bool AllCountsNeedLessThan32Bits =
C.getTypeSize(N0->getType()) < 32;
3846 Scope *CurScope = DSA.getCurScope();
3847 for (
unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
3848 if (PreCond.isUsable()) {
3850 PreCond.get(), IterSpaces[Cnt].PreCond);
3852 auto N = IterSpaces[Cnt].NumIterations;
3853 AllCountsNeedLessThan32Bits &=
C.getTypeSize(N->getType()) < 32;
3861 if (LastIteration64.isUsable())
3873 C.getTypeSize(LastIteration32.
get()->
getType()) == 32 &&
3874 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
3878 LastIteration64.get(), SemaRef)))
3879 LastIteration = LastIteration32;
3904 ".omp.last.iteration");
3906 SemaRef, SaveVar, LastIteration.
get()->
getType(), SaveLoc);
3908 SaveRef.get(), LastIteration.
get());
3909 LastIteration = SaveRef;
3913 CurScope, SaveLoc,
BO_Add, SaveRef.get(),
3959 UB.
get(), LastIteration.
get());
3961 InitLoc, InitLoc, IsUBGreater.
get(), LastIteration.
get(), UB.
get());
3989 NumIterations.
get());
4031 bool HasErrors =
false;
4032 Built.
Counters.resize(NestedLoopCount);
4033 Built.
Inits.resize(NestedLoopCount);
4034 Built.
Updates.resize(NestedLoopCount);
4035 Built.
Finals.resize(NestedLoopCount);
4039 for (
int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
4040 LoopIterationSpace &IS = IterSpaces[Cnt];
4050 assert((Cnt == (
int)NestedLoopCount - 1) &&
4051 "unusable div expected on first iteration only");
4064 SemaRef, cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()),
4065 IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
4069 if (!Init.isUsable()) {
4075 IS.CounterInit, Iter, IS.CounterStep, IS.Subtract);
4083 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
4084 IS.NumIterations, IS.CounterStep, IS.Subtract);
4093 Div = IS.NumIterations;
4111 Built.
Counters[Cnt] = IS.CounterVar;
4113 Built.
Inits[Cnt] = Init.get();
4128 Built.
PreCond = PreCond.get();
4132 Built.
LB = LB.
get();
4133 Built.
UB = UB.
get();
4134 Built.
IL = IL.
get();
4135 Built.
ST = ST.
get();
4137 Built.
NLB = NextLB.
get();
4138 Built.
NUB = NextUB.
get();
4140 return NestedLoopCount;
4144 auto CollapseClauses =
4145 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
4146 if (CollapseClauses.begin() != CollapseClauses.end())
4147 return (*CollapseClauses.begin())->getNumForLoops();
4152 auto OrderedClauses =
4153 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
4154 if (OrderedClauses.begin() != OrderedClauses.end())
4155 return (*OrderedClauses.begin())->getNumForLoops();
4160 const Expr *Safelen) {
4161 llvm::APSInt SimdlenRes, SafelenRes;
4175 if (SimdlenRes > SafelenRes) {
4176 S.
Diag(Simdlen->
getExprLoc(), diag::err_omp_wrong_simdlen_safelen_values)
4177 << Simdlen->getSourceRange() << Safelen->getSourceRange();
4186 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
4190 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
4196 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
4197 if (NestedLoopCount == 0)
4201 "omp simd loop exprs were not built");
4205 for (
auto C : Clauses) {
4206 if (
auto LC = dyn_cast<OMPLinearClause>(
C))
4218 for (
auto *Clause : Clauses) {
4219 if (Clause->getClauseKind() == OMPC_safelen)
4220 Safelen = cast<OMPSafelenClause>(Clause);
4221 else if (Clause->getClauseKind() == OMPC_simdlen)
4222 Simdlen = cast<OMPSimdlenClause>(Clause);
4223 if (Safelen && Simdlen)
4226 if (Simdlen && Safelen &&
4239 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
4243 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
4249 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
4250 if (NestedLoopCount == 0)
4254 "omp for loop exprs were not built");
4258 for (
auto C : Clauses) {
4259 if (
auto LC = dyn_cast<OMPLinearClause>(
C))
4268 Clauses, AStmt, B,
DSAStack->isCancelRegion());
4274 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
4278 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
4282 unsigned NestedLoopCount =
4285 VarsWithImplicitDSA, B);
4286 if (NestedLoopCount == 0)
4290 "omp for simd loop exprs were not built");
4294 for (
auto C : Clauses) {
4295 if (
auto LC = dyn_cast<OMPLinearClause>(
C))
4307 for (
auto *Clause : Clauses) {
4308 if (Clause->getClauseKind() == OMPC_safelen)
4309 Safelen = cast<OMPSafelenClause>(Clause);
4310 else if (Clause->getClauseKind() == OMPC_simdlen)
4311 Simdlen = cast<OMPSimdlenClause>(Clause);
4312 if (Safelen && Simdlen)
4315 if (Simdlen && Safelen &&
4332 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
4333 auto BaseStmt = AStmt;
4334 while (
CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
4335 BaseStmt = CS->getCapturedStmt();
4336 if (
auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
4337 auto S =
C->children();
4338 if (S.begin() == S.end())
4342 for (
Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
4343 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
4345 Diag(SectionStmt->getLocStart(),
4346 diag::err_omp_sections_substmt_not_section);
4349 cast<OMPSectionDirective>(SectionStmt)
4350 ->setHasCancel(
DSAStack->isCancelRegion());
4353 Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt);
4369 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
4385 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
4393 for (
auto *Clause : Clauses) {
4394 if (Clause->getClauseKind() == OMPC_nowait)
4396 else if (Clause->getClauseKind() == OMPC_copyprivate)
4397 Copyprivate = Clause;
4398 if (Copyprivate && Nowait) {
4400 diag::err_omp_single_copyprivate_with_nowait);
4415 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
4428 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
4430 bool ErrorFound =
false;
4433 bool DependentHint =
false;
4434 for (
auto *
C : Clauses) {
4435 if (
C->getClauseKind() == OMPC_hint) {
4437 Diag(
C->getLocStart(), diag::err_omp_hint_clause_no_name);
4440 Expr *E = cast<OMPHintClause>(
C)->getHint();
4443 DependentHint =
true;
4446 HintLoc =
C->getLocStart();
4452 auto Pair =
DSAStack->getCriticalWithHint(DirName);
4453 if (Pair.first && DirName.
getName() && !DependentHint) {
4454 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
4455 Diag(StartLoc, diag::err_omp_critical_with_hint);
4457 Diag(HintLoc, diag::note_omp_critical_hint_here)
4458 << 0 << Hint.toString(10,
false);
4460 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
4462 Diag(
C->getLocStart(), diag::note_omp_critical_hint_here)
4464 <<
C->getHint()->EvaluateKnownConstInt(
Context).toString(
4467 Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1;
4475 if (!Pair.first && DirName.
getName() && !DependentHint)
4476 DSAStack->addCriticalWithHint(Dir, Hint);
4483 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
4498 unsigned NestedLoopCount =
4501 VarsWithImplicitDSA, B);
4502 if (NestedLoopCount == 0)
4506 "omp parallel for loop exprs were not built");
4510 for (
auto C : Clauses) {
4511 if (
auto LC = dyn_cast<OMPLinearClause>(
C))
4520 NestedLoopCount, Clauses, AStmt, B,
4527 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
4542 unsigned NestedLoopCount =
4545 VarsWithImplicitDSA, B);
4546 if (NestedLoopCount == 0)
4551 for (
auto C : Clauses) {
4552 if (
auto LC = dyn_cast<OMPLinearClause>(
C))
4564 for (
auto *Clause : Clauses) {
4565 if (Clause->getClauseKind() == OMPC_safelen)
4566 Safelen = cast<OMPSafelenClause>(Clause);
4567 else if (Clause->getClauseKind() == OMPC_simdlen)
4568 Simdlen = cast<OMPSimdlenClause>(Clause);
4569 if (Safelen && Simdlen)
4572 if (Simdlen && Safelen &&
4579 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
4589 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
4590 auto BaseStmt = AStmt;
4591 while (
CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
4592 BaseStmt = CS->getCapturedStmt();
4593 if (
auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
4594 auto S =
C->children();
4595 if (S.begin() == S.end())
4599 for (
Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
4600 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
4602 Diag(SectionStmt->getLocStart(),
4603 diag::err_omp_parallel_sections_substmt_not_section);
4606 cast<OMPSectionDirective>(SectionStmt)
4607 ->setHasCancel(
DSAStack->isCancelRegion());
4610 Diag(AStmt->getLocStart(),
4611 diag::err_omp_parallel_sections_not_compound_stmt);
4618 Context, StartLoc, EndLoc, Clauses, AStmt,
DSAStack->isCancelRegion());
4662 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
4672 assert(Clauses.size() <= 1 &&
"Extra clauses in flush directive");
4681 OMPClause *DependSourceClause =
nullptr;
4683 bool ErrorFound =
false;
4686 for (
auto *
C : Clauses) {
4687 if (
auto *DC = dyn_cast<OMPDependClause>(
C)) {
4689 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
4690 if (DependSourceClause) {
4691 Diag(
C->getLocStart(), diag::err_omp_more_one_clause)
4696 DependSourceClause =
C;
4697 if (DependSinkClause) {
4698 Diag(
C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
4702 }
else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
4703 if (DependSourceClause) {
4704 Diag(
C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
4708 DependSinkClause =
C;
4710 }
else if (
C->getClauseKind() == OMPC_threads)
4711 TC = cast<OMPThreadsClause>(
C);
4712 else if (
C->getClauseKind() == OMPC_simd)
4713 SC = cast<OMPSIMDClause>(
C);
4715 if (!ErrorFound && !SC &&
4720 Diag(StartLoc, diag::err_omp_prohibited_region_simd);
4722 }
else if (DependFound && (TC || SC)) {
4723 Diag(DependFound->
getLocStart(), diag::err_omp_depend_clause_thread_simd)
4726 }
else if (DependFound && !
DSAStack->getParentOrderedRegionParam()) {
4728 diag::err_omp_ordered_directive_without_param);
4730 }
else if (TC || Clauses.empty()) {
4731 if (
auto *Param =
DSAStack->getParentOrderedRegionParam()) {
4733 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
4735 Diag(Param->getLocStart(), diag::note_omp_ordered_param);
4739 if ((!AStmt && !DependFound) || ErrorFound)
4743 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
4754 class OpenMPAtomicUpdateChecker {
4756 enum ExprAnalysisErrorCode {
4760 NotABinaryOrUnaryExpression,
4762 NotAnUnaryIncDecExpression,
4768 NotABinaryExpression,
4774 NotAnUpdateExpression,
4792 bool IsXLHSInRHSPart;
4797 bool IsPostfixUpdate;
4800 OpenMPAtomicUpdateChecker(
Sema &SemaRef)
4801 : SemaRef(SemaRef),
X(nullptr), E(nullptr), UpdateExpr(nullptr),
4810 bool checkStatement(
Stmt *S,
unsigned DiagId = 0,
unsigned NoteId = 0);
4812 Expr *getX()
const {
return X; }
4814 Expr *getExpr()
const {
return E; }
4818 Expr *getUpdateExpr()
const {
return UpdateExpr; }
4821 bool isXLHSInRHSPart()
const {
return IsXLHSInRHSPart; }
4825 bool isPostfixUpdate()
const {
return IsPostfixUpdate; }
4828 bool checkBinaryOperation(
BinaryOperator *AtomicBinOp,
unsigned DiagId = 0,
4829 unsigned NoteId = 0);
4833 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
4835 ExprAnalysisErrorCode ErrorFound = NoError;
4843 if (
auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
4845 if (AtomicInnerBinOp->isMultiplicativeOp() ||
4846 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
4847 AtomicInnerBinOp->isBitwiseOp()) {
4848 Op = AtomicInnerBinOp->getOpcode();
4849 OpLoc = AtomicInnerBinOp->getOperatorLoc();
4850 auto *LHS = AtomicInnerBinOp->getLHS();
4851 auto *RHS = AtomicInnerBinOp->getRHS();
4852 llvm::FoldingSetNodeID XId, LHSId, RHSId;
4853 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
4855 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
4861 IsXLHSInRHSPart =
true;
4862 }
else if (XId == RHSId) {
4864 IsXLHSInRHSPart =
false;
4866 ErrorLoc = AtomicInnerBinOp->getExprLoc();
4867 ErrorRange = AtomicInnerBinOp->getSourceRange();
4868 NoteLoc =
X->getExprLoc();
4869 NoteRange =
X->getSourceRange();
4870 ErrorFound = NotAnUpdateExpression;
4873 ErrorLoc = AtomicInnerBinOp->getExprLoc();
4874 ErrorRange = AtomicInnerBinOp->getSourceRange();
4875 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
4877 ErrorFound = NotABinaryOperator;
4881 NoteRange = ErrorRange = AtomicBinOp->
getRHS()->getSourceRange();
4882 ErrorFound = NotABinaryExpression;
4886 ErrorRange = AtomicBinOp->getSourceRange();
4889 ErrorFound = NotAnAssignmentOp;
4891 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
4892 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
4893 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
4895 }
else if (SemaRef.CurContext->isDependentContext())
4896 E =
X = UpdateExpr =
nullptr;
4897 return ErrorFound != NoError;
4900 bool OpenMPAtomicUpdateChecker::checkStatement(
Stmt *S,
unsigned DiagId,
4902 ExprAnalysisErrorCode ErrorFound = NoError;
4913 if (
auto *AtomicBody = dyn_cast<Expr>(S)) {
4914 AtomicBody = AtomicBody->IgnoreParenImpCasts();
4915 if (AtomicBody->getType()->isScalarType() ||
4916 AtomicBody->isInstantiationDependent()) {
4917 if (
auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
4918 AtomicBody->IgnoreParenImpCasts())) {
4921 AtomicCompAssignOp->getOpcode());
4922 OpLoc = AtomicCompAssignOp->getOperatorLoc();
4923 E = AtomicCompAssignOp->getRHS();
4924 X = AtomicCompAssignOp->getLHS();
4925 IsXLHSInRHSPart =
true;
4926 }
else if (
auto *AtomicBinOp = dyn_cast<BinaryOperator>(
4927 AtomicBody->IgnoreParenImpCasts())) {
4929 if(checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
4931 }
else if (
auto *AtomicUnaryOp =
4932 dyn_cast<UnaryOperator>(AtomicBody->IgnoreParenImpCasts())) {
4934 if (AtomicUnaryOp->isIncrementDecrementOp()) {
4935 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
4937 OpLoc = AtomicUnaryOp->getOperatorLoc();
4938 X = AtomicUnaryOp->getSubExpr();
4939 E = SemaRef.ActOnIntegerConstant(OpLoc, 1).get();
4940 IsXLHSInRHSPart =
true;
4942 ErrorFound = NotAnUnaryIncDecExpression;
4943 ErrorLoc = AtomicUnaryOp->getExprLoc();
4944 ErrorRange = AtomicUnaryOp->getSourceRange();
4945 NoteLoc = AtomicUnaryOp->getOperatorLoc();
4948 }
else if (!AtomicBody->isInstantiationDependent()) {
4949 ErrorFound = NotABinaryOrUnaryExpression;
4950 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
4951 NoteRange = ErrorRange = AtomicBody->getSourceRange();
4954 ErrorFound = NotAScalarType;
4955 NoteLoc = ErrorLoc = AtomicBody->getLocStart();
4956 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
4959 ErrorFound = NotAnExpression;
4960 NoteLoc = ErrorLoc = S->getLocStart();
4961 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
4963 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
4964 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
4965 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
4967 }
else if (SemaRef.CurContext->isDependentContext())
4968 E =
X = UpdateExpr =
nullptr;
4969 if (ErrorFound == NoError && E &&
X) {
4973 auto *OVEX =
new (SemaRef.getASTContext())
4975 auto *OVEExpr =
new (SemaRef.getASTContext())
4978 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
4979 IsXLHSInRHSPart ? OVEExpr : OVEX);
4980 if (Update.isInvalid())
4982 Update = SemaRef.PerformImplicitConversion(Update.get(),
X->getType(),
4984 if (Update.isInvalid())
4986 UpdateExpr = Update.get();
4988 return ErrorFound != NoError;
4998 auto CS = cast<CapturedStmt>(AStmt);
5006 for (
auto *
C : Clauses) {
5007 if (
C->getClauseKind() == OMPC_read ||
C->getClauseKind() == OMPC_write ||
5008 C->getClauseKind() == OMPC_update ||
5009 C->getClauseKind() == OMPC_capture) {
5011 Diag(
C->getLocStart(), diag::err_omp_atomic_several_clauses)
5013 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
5016 AtomicKind =
C->getClauseKind();
5017 AtomicKindLoc =
C->getLocStart();
5022 auto Body = CS->getCapturedStmt();
5023 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Body))
5024 Body = EWC->getSubExpr();
5030 bool IsXLHSInRHSPart =
false;
5031 bool IsPostfixUpdate =
false;
5054 if (AtomicKind == OMPC_read) {
5061 } ErrorFound = NoError;
5066 if (
auto AtomicBody = dyn_cast<Expr>(Body)) {
5075 auto NotLValueExpr = X->
isLValue() ? V :
X;
5076 ErrorFound = NotAnLValue;
5078 ErrorRange = AtomicBinOp->getSourceRange();
5079 NoteLoc = NotLValueExpr->getExprLoc();
5080 NoteRange = NotLValueExpr->getSourceRange();
5084 auto NotScalarExpr =
5088 ErrorFound = NotAScalarType;
5090 ErrorRange = AtomicBinOp->getSourceRange();
5091 NoteLoc = NotScalarExpr->getExprLoc();
5092 NoteRange = NotScalarExpr->getSourceRange();
5094 }
else if (!AtomicBody->isInstantiationDependent()) {
5095 ErrorFound = NotAnAssignmentOp;
5096 ErrorLoc = AtomicBody->getExprLoc();
5097 ErrorRange = AtomicBody->getSourceRange();
5099 : AtomicBody->getExprLoc();
5100 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
5101 : AtomicBody->getSourceRange();
5104 ErrorFound = NotAnExpression;
5105 NoteLoc = ErrorLoc = Body->getLocStart();
5106 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
5108 if (ErrorFound != NoError) {
5109 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
5111 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
5116 }
else if (AtomicKind == OMPC_write) {
5123 } ErrorFound = NoError;
5128 if (
auto AtomicBody = dyn_cast<Expr>(Body)) {
5132 X = AtomicBinOp->
getLHS();
5133 E = AtomicBinOp->
getRHS();
5137 ErrorFound = NotAnLValue;
5139 ErrorRange = AtomicBinOp->getSourceRange();
5141 NoteRange = X->getSourceRange();
5145 auto NotScalarExpr =
5149 ErrorFound = NotAScalarType;
5151 ErrorRange = AtomicBinOp->getSourceRange();
5152 NoteLoc = NotScalarExpr->getExprLoc();
5153 NoteRange = NotScalarExpr->getSourceRange();
5155 }
else if (!AtomicBody->isInstantiationDependent()) {
5156 ErrorFound = NotAnAssignmentOp;
5157 ErrorLoc = AtomicBody->getExprLoc();
5158 ErrorRange = AtomicBody->getSourceRange();
5160 : AtomicBody->getExprLoc();
5161 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
5162 : AtomicBody->getSourceRange();
5165 ErrorFound = NotAnExpression;
5166 NoteLoc = ErrorLoc = Body->getLocStart();
5167 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
5169 if (ErrorFound != NoError) {
5170 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
5172 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
5177 }
else if (AtomicKind == OMPC_update || AtomicKind ==
OMPC_unknown) {
5186 OpenMPAtomicUpdateChecker Checker(*
this);
5187 if (Checker.checkStatement(
5188 Body, (AtomicKind == OMPC_update)
5189 ? diag::err_omp_atomic_update_not_expression_statement
5190 : diag::err_omp_atomic_not_expression_statement,
5191 diag::note_omp_atomic_update))
5194 E = Checker.getExpr();
5196 UE = Checker.getUpdateExpr();
5197 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
5199 }
else if (AtomicKind == OMPC_capture) {
5202 NotACompoundStatement,
5203 NotTwoSubstatements,
5204 NotASpecificExpression,
5206 } ErrorFound = NoError;
5209 if (
auto *AtomicBody = dyn_cast<Expr>(Body)) {
5221 V = AtomicBinOp->
getLHS();
5223 OpenMPAtomicUpdateChecker Checker(*
this);
5224 if (Checker.checkStatement(
5225 Body, diag::err_omp_atomic_capture_not_expression_statement,
5226 diag::note_omp_atomic_update))
5228 E = Checker.getExpr();
5230 UE = Checker.getUpdateExpr();
5231 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
5232 IsPostfixUpdate = Checker.isPostfixUpdate();
5233 }
else if (!AtomicBody->isInstantiationDependent()) {
5234 ErrorLoc = AtomicBody->getExprLoc();
5235 ErrorRange = AtomicBody->getSourceRange();
5237 : AtomicBody->getExprLoc();
5238 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
5239 : AtomicBody->getSourceRange();
5240 ErrorFound = NotAnAssignmentOp;
5242 if (ErrorFound != NoError) {
5243 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
5245 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
5248 UE = V = E = X =
nullptr;
5267 if (
auto *CS = dyn_cast<CompoundStmt>(Body)) {
5269 if (CS->size() == 2) {
5270 auto *First = CS->body_front();
5271 auto *Second = CS->body_back();
5272 if (
auto *EWC = dyn_cast<ExprWithCleanups>(First))
5274 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Second))
5277 OpenMPAtomicUpdateChecker Checker(*
this);
5278 bool IsUpdateExprFound = !Checker.checkStatement(Second);
5280 if (IsUpdateExprFound) {
5294 llvm::FoldingSetNodeID XId, PossibleXId;
5295 Checker.getX()->Profile(XId,
Context,
true);
5296 PossibleX->Profile(PossibleXId,
Context,
true);
5297 IsUpdateExprFound = XId == PossibleXId;
5298 if (IsUpdateExprFound) {
5301 E = Checker.getExpr();
5302 UE = Checker.getUpdateExpr();
5303 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
5304 IsPostfixUpdate =
true;
5307 if (!IsUpdateExprFound) {
5308 IsUpdateExprFound = !Checker.checkStatement(First);
5310 if (IsUpdateExprFound) {
5324 llvm::FoldingSetNodeID XId, PossibleXId;
5325 Checker.getX()->Profile(XId,
Context,
true);
5326 PossibleX->Profile(PossibleXId,
Context,
true);
5327 IsUpdateExprFound = XId == PossibleXId;
5328 if (IsUpdateExprFound) {
5331 E = Checker.getExpr();
5332 UE = Checker.getUpdateExpr();
5333 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
5334 IsPostfixUpdate =
false;
5338 if (!IsUpdateExprFound) {
5340 auto *FirstExpr = dyn_cast<
Expr>(First);
5341 auto *SecondExpr = dyn_cast<
Expr>(Second);
5342 if (!FirstExpr || !SecondExpr ||
5343 !(FirstExpr->isInstantiationDependent() ||
5344 SecondExpr->isInstantiationDependent())) {
5346 if (!FirstBinOp || FirstBinOp->getOpcode() !=
BO_Assign) {
5347 ErrorFound = NotAnAssignmentOp;
5348 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
5349 : First->getLocStart();
5350 NoteRange = ErrorRange = FirstBinOp
5351 ? FirstBinOp->getSourceRange()
5355 if (!SecondBinOp || SecondBinOp->getOpcode() !=
BO_Assign) {
5356 ErrorFound = NotAnAssignmentOp;
5357 NoteLoc = ErrorLoc = SecondBinOp
5358 ? SecondBinOp->getOperatorLoc()
5359 : Second->getLocStart();
5360 NoteRange = ErrorRange =
5361 SecondBinOp ? SecondBinOp->getSourceRange()
5364 auto *PossibleXRHSInFirst =
5365 FirstBinOp->getRHS()->IgnoreParenImpCasts();
5366 auto *PossibleXLHSInSecond =
5367 SecondBinOp->getLHS()->IgnoreParenImpCasts();
5368 llvm::FoldingSetNodeID X1Id, X2Id;
5369 PossibleXRHSInFirst->Profile(X1Id,
Context,
5371 PossibleXLHSInSecond->Profile(X2Id,
Context,
5373 IsUpdateExprFound = X1Id == X2Id;
5374 if (IsUpdateExprFound) {
5375 V = FirstBinOp->getLHS();
5376 X = SecondBinOp->getLHS();
5377 E = SecondBinOp->getRHS();
5379 IsXLHSInRHSPart =
false;
5380 IsPostfixUpdate =
true;
5382 ErrorFound = NotASpecificExpression;
5383 ErrorLoc = FirstBinOp->getExprLoc();
5384 ErrorRange = FirstBinOp->getSourceRange();
5385 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
5386 NoteRange = SecondBinOp->getRHS()->getSourceRange();
5393 NoteLoc = ErrorLoc = Body->getLocStart();
5394 NoteRange = ErrorRange =
5395 SourceRange(Body->getLocStart(), Body->getLocStart());
5396 ErrorFound = NotTwoSubstatements;
5399 NoteLoc = ErrorLoc = Body->getLocStart();
5400 NoteRange = ErrorRange =
5401 SourceRange(Body->getLocStart(), Body->getLocStart());
5402 ErrorFound = NotACompoundStatement;
5404 if (ErrorFound != NoError) {
5405 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
5407 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
5410 UE = V = E = X =
nullptr;
5418 X, V, E, UE, IsXLHSInRHSPart,
5441 if (
DSAStack->hasInnerTeamsRegion()) {
5442 auto S = AStmt->IgnoreContainers(
true);
5443 bool OMPTeamsFound =
true;
5444 if (
auto *CS = dyn_cast<CompoundStmt>(S)) {
5445 auto I = CS->body_begin();
5446 while (I != CS->body_end()) {
5449 OMPTeamsFound =
false;
5454 assert(I != CS->body_end() &&
"Not found statement");
5457 if (!OMPTeamsFound) {
5458 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
5460 diag::note_omp_nested_teams_construct_here);
5461 Diag(S->getLocStart(), diag::note_omp_nested_statement_here)
5462 << isa<OMPExecutableDirective>(S);
5479 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5510 if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for &&
5511 CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) {
5512 Diag(StartLoc, diag::err_omp_wrong_cancel_region)
5516 if (
DSAStack->isParentNowaitRegion()) {
5517 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
5520 if (
DSAStack->isParentOrderedRegion()) {
5521 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
5532 if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for &&
5533 CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) {
5534 Diag(StartLoc, diag::err_omp_wrong_cancel_region)
5538 if (
DSAStack->isParentNowaitRegion()) {
5539 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
5542 if (
DSAStack->isParentOrderedRegion()) {
5543 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
5546 DSAStack->setParentCancelRegion(
true);
5554 bool ErrorFound =
false;
5555 for (
auto *
C : Clauses) {
5556 if (
C->getClauseKind() == OMPC_grainsize ||
5557 C->getClauseKind() == OMPC_num_tasks) {
5561 S.
Diag(
C->getLocStart(),
5562 diag::err_omp_grainsize_num_tasks_mutually_exclusive)
5566 diag::note_omp_previous_grainsize_num_tasks)
5578 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
5582 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5586 unsigned NestedLoopCount =
5589 VarsWithImplicitDSA, B);
5590 if (NestedLoopCount == 0)
5594 "omp for loop exprs were not built");
5604 NestedLoopCount, Clauses, AStmt, B);
5610 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
5614 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5618 unsigned NestedLoopCount =
5621 VarsWithImplicitDSA, B);
5622 if (NestedLoopCount == 0)
5626 "omp for loop exprs were not built");
5636 NestedLoopCount, Clauses, AStmt, B);
5642 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
5646 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5650 unsigned NestedLoopCount =
5653 *
this, *
DSAStack, VarsWithImplicitDSA, B);
5654 if (NestedLoopCount == 0)
5658 "omp for loop exprs were not built");
5662 NestedLoopCount, Clauses, AStmt, B);
5674 case OMPC_num_threads:
5692 case OMPC_num_teams:
5695 case OMPC_thread_limit:
5701 case OMPC_grainsize:
5704 case OMPC_num_tasks:
5712 case OMPC_proc_bind:
5715 case OMPC_firstprivate:
5716 case OMPC_lastprivate:
5718 case OMPC_reduction:
5722 case OMPC_copyprivate:
5725 case OMPC_mergeable:
5739 llvm_unreachable(
"Clause is not allowed.");
5750 Expr *ValExpr = Condition;
5759 ValExpr = Val.
get();
5763 NameModifierLoc, ColonLoc, EndLoc);
5770 Expr *ValExpr = Condition;
5779 ValExpr = Val.
get();
5791 IntConvertDiagnoser()
5795 return S.
Diag(Loc, diag::err_omp_not_integral) << T;
5799 return S.
Diag(Loc, diag::err_omp_incomplete_type) << T;
5804 return S.
Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
5813 return S.
Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
5822 llvm_unreachable(
"conversion functions are permitted");
5830 bool StrictlyPositive) {
5839 ValExpr = Value.
get();
5843 Result.isSigned() &&
5844 !((!StrictlyPositive && Result.isNonNegative()) ||
5845 (StrictlyPositive && Result.isStrictlyPositive()))) {
5846 SemaRef.
Diag(Loc, diag::err_omp_negative_expression_in_clause)
5848 << ValExpr->getSourceRange();
5859 Expr *ValExpr = NumThreads;
5873 bool StrictlyPositive) {
5883 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
5884 (!StrictlyPositive && !Result.isNonNegative())) {
5885 Diag(E->
getExprLoc(), diag::err_omp_negative_expression_in_clause)
5887 << E->getSourceRange();
5890 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
5892 << E->getSourceRange();
5895 if (CKind == OMPC_collapse &&
DSAStack->getAssociatedLoops() == 1)
5896 DSAStack->setAssociatedLoops(Result.getExtValue());
5897 else if (CKind == OMPC_ordered)
5898 DSAStack->setAssociatedLoops(Result.getExtValue());
5908 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
5921 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
5938 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
5948 Expr *NumForLoops) {
5954 if (NumForLoops && LParenLoc.
isValid()) {
5956 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
5959 NumForLoops = NumForLoopsResult.
get();
5961 NumForLoops =
nullptr;
5962 DSAStack->setOrderedRegion(
true, NumForLoops);
5975 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
5977 case OMPC_proc_bind:
5979 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
5984 case OMPC_num_threads:
5990 case OMPC_firstprivate:
5991 case OMPC_lastprivate:
5993 case OMPC_reduction:
5997 case OMPC_copyprivate:
6001 case OMPC_mergeable:
6014 case OMPC_num_teams:
6015 case OMPC_thread_limit:
6017 case OMPC_grainsize:
6019 case OMPC_num_tasks:
6022 llvm_unreachable(
"Clause is not allowed.");
6031 unsigned Bound = Last >= 2 ? Last - 2 : 0;
6032 unsigned Skipped = Exclude.size();
6033 auto S = Exclude.begin(), E = Exclude.end();
6034 for (
unsigned i = First; i <
Last; ++i) {
6035 if (std::find(S, E, i) != E) {
6042 if (i == Bound - Skipped)
6044 else if (i != Bound + 1 - Skipped)
6057 "OMPC_DEFAULT_unknown not greater than 0");
6058 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
6065 case OMPC_DEFAULT_none:
6066 DSAStack->setDefaultDSANone(KindKwLoc);
6068 case OMPC_DEFAULT_shared:
6069 DSAStack->setDefaultDSAShared(KindKwLoc);
6072 llvm_unreachable(
"Clause kind is not allowed.");
6085 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
6103 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
6104 assert(Argument.size() == NumberOfElements &&
6105 ArgumentLoc.size() == NumberOfElements);
6107 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
6108 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
6109 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
6110 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
6111 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
6114 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
6116 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
6120 case OMPC_num_threads:
6125 case OMPC_proc_bind:
6127 case OMPC_firstprivate:
6128 case OMPC_lastprivate:
6130 case OMPC_reduction:
6134 case OMPC_copyprivate:
6138 case OMPC_mergeable:
6151 case OMPC_num_teams:
6152 case OMPC_thread_limit:
6154 case OMPC_grainsize:
6156 case OMPC_num_tasks:
6159 llvm_unreachable(
"Clause is not allowed.");
6170 Excluded.push_back(M2);
6171 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
6172 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
6173 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
6174 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
6175 S.
Diag(M1Loc, diag::err_omp_unexpected_clause_value)
6198 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
6199 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
6200 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
6201 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
6202 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
6218 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
6225 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
6226 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
6227 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
6228 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
6229 diag::err_omp_schedule_nonmonotonic_static);
6232 Expr *ValExpr = ChunkSize;
6233 Expr *HelperValExpr =
nullptr;
6244 ValExpr = Val.
get();
6251 if (Result.isSigned() && !Result.isStrictlyPositive()) {
6252 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
6253 <<
"schedule" << 1 << ChunkSize->getSourceRange();
6256 }
else if (isParallelOrTaskRegion(
DSAStack->getCurrentDirective())) {
6258 ChunkSize->
getType(),
".chunk.");
6262 HelperValExpr = ImpVarRef;
6269 ValExpr, HelperValExpr, M1, M1Loc, M2, M2Loc);
6286 case OMPC_mergeable:
6315 case OMPC_num_threads:
6321 case OMPC_firstprivate:
6322 case OMPC_lastprivate:
6324 case OMPC_reduction:
6328 case OMPC_copyprivate:
6330 case OMPC_proc_bind:
6336 case OMPC_num_teams:
6337 case OMPC_thread_limit:
6339 case OMPC_grainsize:
6340 case OMPC_num_tasks:
6343 llvm_unreachable(
"Clause is not allowed.");
6416 case OMPC_firstprivate:
6419 case OMPC_lastprivate:
6425 case OMPC_reduction:
6427 EndLoc, ReductionIdScopeSpec, ReductionId);
6431 LinKind, DepLinMapLoc, ColonLoc, EndLoc);
6440 case OMPC_copyprivate:
6448 StartLoc, LParenLoc, EndLoc);
6452 VarList, StartLoc, LParenLoc, EndLoc);
6456 case OMPC_num_threads:
6461 case OMPC_proc_bind:
6466 case OMPC_mergeable:
6476 case OMPC_num_teams:
6477 case OMPC_thread_limit:
6479 case OMPC_grainsize:
6481 case OMPC_num_tasks:
6484 llvm_unreachable(
"Clause is not allowed.");
6495 for (
auto &RefExpr : VarList) {
6496 assert(RefExpr &&
"NULL expr in OpenMP private clause.");
6497 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
6499 Vars.push_back(RefExpr);
6500 PrivateCopies.push_back(
nullptr);
6510 DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
6511 if (!DE || !isa<VarDecl>(DE->
getDecl())) {
6512 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
6516 VarDecl *VD = cast<VarDecl>(D);
6519 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
6522 PrivateCopies.push_back(
nullptr);
6530 diag::err_omp_private_incomplete_type)) {
6533 Type = Type.getNonReferenceType();
6542 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(VD,
false);
6543 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_private) {
6551 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
6552 DSAStack->getCurrentDirective() == OMPD_task) {
6553 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
6559 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
6573 Type = Type.getUnqualifiedType();
6577 if (VDPrivate->isInvalidDecl())
6582 DSAStack->addDSA(VD, DE, OMPC_private);
6584 PrivateCopies.push_back(VDPrivateRefExpr);
6595 class DiagsUninitializedSeveretyRAII {
6604 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
6606 Diags.
setSeverity( diag::warn_uninit_self_reference_in_init,
6610 ~DiagsUninitializedSeveretyRAII() {
6624 bool IsImplicitClause =
6626 auto ImplicitClauseLoc =
DSAStack->getConstructLoc();
6628 for (
auto &RefExpr : VarList) {
6629 assert(RefExpr &&
"NULL expr in OpenMP firstprivate clause.");
6630 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
6632 Vars.push_back(RefExpr);
6633 PrivateCopies.push_back(
nullptr);
6634 Inits.push_back(
nullptr);
6639 IsImplicitClause ? ImplicitClauseLoc : RefExpr->getExprLoc();
6645 DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
6646 if (!DE || !isa<VarDecl>(DE->
getDecl())) {
6647 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
6651 VarDecl *VD = cast<VarDecl>(D);
6654 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
6657 PrivateCopies.push_back(
nullptr);
6658 Inits.push_back(
nullptr);
6666 diag::err_omp_firstprivate_incomplete_type)) {
6669 Type = Type.getNonReferenceType();
6678 if (!IsImplicitClause) {
6679 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(VD,
false);
6680 bool IsConstant = ElemType.isConstant(
Context);
6685 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
6686 DVar.CKind != OMPC_lastprivate && DVar.RefExpr) {
6687 Diag(ELoc, diag::err_omp_wrong_dsa)
6706 DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_shared) {
6707 Diag(ELoc, diag::err_omp_wrong_dsa)
6722 DVar =
DSAStack->getImplicitDSA(VD,
true);
6723 if (DVar.CKind != OMPC_shared &&
6726 Diag(ELoc, diag::err_omp_required_access)
6744 if (CurrDir == OMPD_task) {
6746 DSAStack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction),
6752 if (DVar.CKind == OMPC_reduction &&
6755 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
6775 if (CurrDir == OMPD_distribute) {
6776 DVar =
DSAStack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_private),
6782 Diag(ELoc, diag::err_omp_firstprivate_distribute_private_teams);
6786 DVar =
DSAStack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction),
6791 if (DVar.CKind == OMPC_reduction &&
6793 Diag(ELoc, diag::err_omp_firstprivate_distribute_in_teams_reduction);
6797 DVar =
DSAStack->getTopDSA(VD,
false);
6798 if (DVar.CKind == OMPC_lastprivate) {
6799 Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute);
6807 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
6808 DSAStack->getCurrentDirective() == OMPD_task) {
6809 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
6815 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
6820 Type = Type.getUnqualifiedType();
6828 Expr *VDInitRefExpr =
nullptr;
6831 if (Type->isArrayType()) {
6836 ElemType = ElemType.getUnqualifiedType();
6838 ".firstprivate.temp");
6846 VDPrivate->setInvalidDecl();
6848 VDPrivate->setInit(Result.
getAs<
Expr>());
6860 if (VDPrivate->isInvalidDecl()) {
6861 if (IsImplicitClause) {
6863 diag::note_omp_task_predetermined_firstprivate_here);
6870 DSAStack->addDSA(VD, DE, OMPC_firstprivate);
6872 PrivateCopies.push_back(VDPrivateRefExpr);
6873 Inits.push_back(VDInitRefExpr);
6880 Vars, PrivateCopies, Inits);
6891 for (
auto &RefExpr : VarList) {
6892 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
6893 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
6895 Vars.push_back(RefExpr);
6896 SrcExprs.push_back(
nullptr);
6897 DstExprs.push_back(
nullptr);
6898 AssignmentOps.push_back(
nullptr);
6908 DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
6909 if (!DE || !isa<VarDecl>(DE->
getDecl())) {
6910 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
6914 VarDecl *VD = cast<VarDecl>(D);
6917 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
6920 SrcExprs.push_back(
nullptr);
6921 DstExprs.push_back(
nullptr);
6922 AssignmentOps.push_back(
nullptr);
6930 diag::err_omp_lastprivate_incomplete_type)) {
6933 Type = Type.getNonReferenceType();
6940 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(VD,
false);
6941 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
6942 DVar.CKind != OMPC_firstprivate &&
6943 (DVar.CKind != OMPC_private || DVar.RefExpr !=
nullptr)) {
6944 Diag(ELoc, diag::err_omp_wrong_dsa)
6958 DSAStackTy::DSAVarData TopDVar = DVar;
6961 DVar =
DSAStack->getImplicitDSA(VD,
true);
6962 if (DVar.CKind != OMPC_shared) {
6963 Diag(ELoc, diag::err_omp_required_access)
6980 Type.getUnqualifiedType(),
".lastprivate.src",
6983 *
this, SrcVD, Type.getUnqualifiedType(), DE->
getExprLoc());
6987 auto *PseudoDstExpr =
6992 PseudoDstExpr, PseudoSrcExpr);
6993 if (AssignmentOp.isInvalid())
6997 if (AssignmentOp.isInvalid())
7003 if (CurrDir == OMPD_distribute) {
7004 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(VD,
false);
7005 if (DVar.CKind == OMPC_firstprivate) {
7006 Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute);
7012 if (TopDVar.CKind != OMPC_firstprivate)
7013 DSAStack->addDSA(VD, DE, OMPC_lastprivate);
7015 SrcExprs.push_back(PseudoSrcExpr);
7016 DstExprs.push_back(PseudoDstExpr);
7017 AssignmentOps.push_back(AssignmentOp.get());
7024 Vars, SrcExprs, DstExprs, AssignmentOps);
7032 for (
auto &RefExpr : VarList) {
7033 assert(RefExpr &&
"NULL expr in OpenMP shared clause.");
7034 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
7036 Vars.push_back(RefExpr);
7048 if (!DE || !isa<VarDecl>(DE->
getDecl())) {
7049 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
7053 VarDecl *VD = cast<VarDecl>(D);
7056 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
7069 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(VD,
false);
7070 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_shared &&
7078 DSAStack->addDSA(VD, DE, OMPC_shared);
7089 class DSARefChecker :
public StmtVisitor<DSARefChecker, bool> {
7095 DSAStackTy::DSAVarData DVar =
Stack->getTopDSA(VD,
false);
7096 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
7100 DSAStackTy::DSAVarData DVarPrivate =
7108 bool VisitStmt(
Stmt *S) {
7109 for (
auto Child : S->children()) {
7110 if (Child && Visit(Child))
7115 explicit DSARefChecker(DSAStackTy *S) :
Stack(S) {}
7126 assert(ReductionIdScopeSpec.
isEmpty() &&
7127 "No support for scoped reduction identifiers yet.");
7129 auto DN = ReductionId.
getName();
7167 case OO_Array_Delete:
7176 case OO_GreaterEqual:
7181 case OO_PercentEqual:
7186 case OO_GreaterGreater:
7187 case OO_LessLessEqual:
7188 case OO_GreaterGreaterEqual:
7190 case OO_ExclaimEqual:
7198 case OO_Conditional:
7201 llvm_unreachable(
"Unexpected reduction identifier");
7203 if (
auto II = DN.getAsIdentifierInfo()) {
7204 if (II->isStr(
"max"))
7206 else if (II->isStr(
"min"))
7212 if (ReductionIdScopeSpec.
isValid()) {
7218 Diag(ReductionId.
getLocStart(), diag::err_omp_unknown_reduction_identifier)
7219 << ReductionIdRange;
7228 for (
auto RefExpr : VarList) {
7229 assert(RefExpr &&
"nullptr expr in OpenMP reduction clause.");
7230 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
7232 Vars.push_back(RefExpr);
7233 Privates.push_back(
nullptr);
7234 LHSs.push_back(
nullptr);
7235 RHSs.push_back(
nullptr);
7236 ReductionOps.push_back(
nullptr);
7240 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
7241 RefExpr->isInstantiationDependent() ||
7242 RefExpr->containsUnexpandedParameterPack()) {
7244 Vars.push_back(RefExpr);
7245 Privates.push_back(
nullptr);
7246 LHSs.push_back(
nullptr);
7247 RHSs.push_back(
nullptr);
7248 ReductionOps.push_back(
nullptr);
7252 auto ELoc = RefExpr->getExprLoc();
7253 auto ERange = RefExpr->getSourceRange();
7264 if (!ASE && !OASE && (!DE || !isa<VarDecl>(DE->getDecl()))) {
7265 Diag(ELoc, diag::err_omp_expected_var_name_or_array_item) << ERange;
7271 auto D = DE->getDecl();
7272 VD = cast<VarDecl>(D);
7275 Type = ASE->getType();
7276 auto *
Base = ASE->getBase()->IgnoreParenImpCasts();
7277 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base))
7278 Base = TempASE->getBase()->IgnoreParenImpCasts();
7281 VD = dyn_cast<
VarDecl>(DE->getDecl());
7283 Diag(
Base->getExprLoc(), diag::err_omp_expected_base_var_name)
7284 << 0 <<
Base->getSourceRange();
7289 if (
auto *ATy = BaseType->getAsArrayTypeUnsafe())
7290 Type = ATy->getElementType();
7293 auto *
Base = OASE->getBase()->IgnoreParenImpCasts();
7294 while (
auto *TempOASE = dyn_cast<OMPArraySectionExpr>(
Base))
7295 Base = TempOASE->getBase()->IgnoreParenImpCasts();
7296 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base))
7297 Base = TempASE->getBase()->IgnoreParenImpCasts();
7300 VD = dyn_cast<
VarDecl>(DE->getDecl());
7302 Diag(
Base->getExprLoc(), diag::err_omp_expected_base_var_name)
7303 << 1 <<
Base->getSourceRange();
7312 diag::err_omp_reduction_incomplete_type))
7317 Diag(ELoc, diag::err_omp_reduction_type_array) << Type << ERange;
7318 if (!ASE && !OASE) {
7322 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
7331 Diag(ELoc, diag::err_omp_const_reduction_list_item)
7333 if (!ASE && !OASE) {
7337 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
7345 if (!ASE && !OASE) {
7349 if (Check.Visit(VDDef->
getInit())) {
7350 Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange;
7367 Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
7369 if (!ASE && !OASE) {
7373 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
7380 Diag(ELoc, diag::err_omp_clause_floating_type_arg);
7381 if (!ASE && !OASE) {
7385 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
7401 DSAStackTy::DSAVarData DVar;
7402 DVar =
DSAStack->getTopDSA(VD,
false);
7403 if (DVar.CKind == OMPC_reduction) {
7404 Diag(ELoc, diag::err_omp_once_referenced)
7407 Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
7410 Diag(ELoc, diag::err_omp_wrong_dsa)
7424 DVar =
DSAStack->getImplicitDSA(VD,
true);
7425 if (DVar.CKind != OMPC_shared) {
7426 Diag(ELoc, diag::err_omp_required_access)
7435 auto *LHSVD =
buildVarDecl(*
this, ELoc, Type,
".reduction.lhs",
7439 auto PrivateTy = Type;
7455 Expr *Init =
nullptr;
7477 Type = ComplexTy->getElementType();
7480 llvm::APFloat InitValue =
7488 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
7510 llvm::APInt InitValue =
7512 ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
7513 : llvm::APInt::getMinValue(Size)
7514 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
7515 : llvm::APInt::getMaxValue(Size);
7527 llvm::APFloat InitValue = llvm::APFloat::getLargest(
7557 llvm_unreachable(
"Unexpected reduction operation");
7564 if (!RHSVD->hasInit()) {
7565 Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type
7566 << ReductionIdRange;
7571 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
7578 PrivateVD->
setInit(RHSVD->getInit());
7579 PrivateVD->setInitStyle(RHSVD->getInitStyle());
7604 DSAStack->addDSA(VD, DE, OMPC_reduction);
7605 Vars.push_back(RefExpr);
7606 Privates.push_back(PrivateDRE);
7607 LHSs.push_back(LHSDRE);
7608 RHSs.push_back(RHSDRE);
7609 ReductionOps.push_back(ReductionOp.
get());
7616 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars,
7618 LHSs, RHSs, ReductionOps);
7628 if ((!
LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
7630 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) <<
LangOpts.CPlusPlus;
7631 LinKind = OMPC_LINEAR_val;
7633 for (
auto &RefExpr : VarList) {
7634 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
7635 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
7637 Vars.push_back(RefExpr);
7638 Privates.push_back(
nullptr);
7639 Inits.push_back(
nullptr);
7658 if (!DE || !isa<VarDecl>(DE->
getDecl())) {
7659 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
7669 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(VD,
false);
7681 Privates.push_back(
nullptr);
7682 Inits.push_back(
nullptr);
7688 diag::err_omp_linear_incomplete_type)) {
7691 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
7693 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
7701 Diag(ELoc, diag::err_omp_const_variable)
7706 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
7716 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << QType;
7720 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
7733 if (LinKind == OMPC_LINEAR_uval)
7741 DSAStack->addDSA(VD, DE, OMPC_linear);
7743 Privates.push_back(PrivateRef);
7744 Inits.push_back(InitRef);
7751 Expr *CalcStepExpr =
nullptr;
7759 StepExpr = Val.
get();
7774 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
7775 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
7776 << (Vars.size() > 1);
7777 if (!IsConstant && CalcStep.isUsable()) {
7780 CalcStepExpr = CalcStep.get();
7785 ColonLoc, EndLoc, Vars, Privates, Inits,
7786 StepExpr, CalcStepExpr);
7790 Expr *NumIterations,
Sema &SemaRef,
7799 if (Step ==
nullptr)
7802 Step = cast<BinaryOperator>(
CalcStep)->getLHS();
7803 bool HasErrors =
false;
7804 auto CurInit = Clause.inits().begin();
7805 auto CurPrivate = Clause.privates().begin();
7806 auto LinKind = Clause.getModifier();
7807 for (
auto &RefExpr : Clause.
varlists()) {
7808 Expr *InitExpr = *CurInit;
7811 auto DE = cast<DeclRefExpr>(RefExpr);
7813 if (LinKind == OMPC_LINEAR_uval)
7814 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
7818 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
7824 InitExpr, IV,
Step,
false);
7831 InitExpr, NumIterations,
Step,
false);
7834 if (!Update.isUsable() || !Final.isUsable()) {
7835 Updates.push_back(
nullptr);
7836 Finals.push_back(
nullptr);
7839 Updates.push_back(Update.get());
7840 Finals.push_back(Final.get());
7842 ++CurInit, ++CurPrivate;
7844 Clause.setUpdates(Updates);
7845 Clause.setFinals(Finals);
7854 for (
auto &RefExpr : VarList) {
7855 assert(RefExpr &&
"NULL expr in OpenMP aligned clause.");
7856 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
7858 Vars.push_back(RefExpr);
7866 if (!DE || !isa<VarDecl>(DE->
getDecl())) {
7867 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
7881 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
7882 << QType <<
getLangOpts().CPlusPlus << RefExpr->getSourceRange();
7886 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
7894 Diag(ELoc, diag::err_omp_aligned_twice) << RefExpr->getSourceRange();
7895 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
7908 if (Alignment !=
nullptr) {
7910 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
7913 Alignment = AlignResult.
get();
7919 EndLoc, Vars, Alignment);
7930 for (
auto &RefExpr : VarList) {
7931 assert(RefExpr &&
"NULL expr in OpenMP copyin clause.");
7932 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
7934 Vars.push_back(RefExpr);
7935 SrcExprs.push_back(
nullptr);
7936 DstExprs.push_back(
nullptr);
7937 AssignmentOps.push_back(
nullptr);
7947 if (!DE || !isa<VarDecl>(DE->
getDecl())) {
7948 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
7953 VarDecl *VD = cast<VarDecl>(D);
7956 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
7959 SrcExprs.push_back(
nullptr);
7960 DstExprs.push_back(
nullptr);
7961 AssignmentOps.push_back(
nullptr);
7967 if (!
DSAStack->isThreadPrivate(VD)) {
7968 Diag(ELoc, diag::err_omp_required_access)
7983 *
this, SrcVD, ElemType.getUnqualifiedType(), DE->
getExprLoc());
7987 auto *PseudoDstExpr =
7992 PseudoDstExpr, PseudoSrcExpr);
7993 if (AssignmentOp.isInvalid())
7997 if (AssignmentOp.isInvalid())
8000 DSAStack->addDSA(VD, DE, OMPC_copyin);
8002 SrcExprs.push_back(PseudoSrcExpr);
8003 DstExprs.push_back(PseudoDstExpr);
8004 AssignmentOps.push_back(AssignmentOp.get());
8011 SrcExprs, DstExprs, AssignmentOps);
8022 for (
auto &RefExpr : VarList) {
8023 assert(RefExpr &&
"NULL expr in OpenMP copyprivate clause.");
8024 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
8026 Vars.push_back(RefExpr);
8027 SrcExprs.push_back(
nullptr);
8028 DstExprs.push_back(
nullptr);
8029 AssignmentOps.push_back(
nullptr);
8039 if (!DE || !isa<VarDecl>(DE->
getDecl())) {
8040 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
8045 VarDecl *VD = cast<VarDecl>(D);
8048 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
8051 SrcExprs.push_back(
nullptr);
8052 DstExprs.push_back(
nullptr);
8053 AssignmentOps.push_back(
nullptr);
8060 if (!
DSAStack->isThreadPrivate(VD)) {
8061 auto DVar =
DSAStack->getTopDSA(VD,
false);
8062 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
8064 Diag(ELoc, diag::err_omp_wrong_dsa)
8075 DVar =
DSAStack->getImplicitDSA(VD,
false);
8076 if (DVar.CKind == OMPC_shared) {
8077 Diag(ELoc, diag::err_omp_required_access)
8079 <<
"threadprivate or private in the enclosing context";
8087 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
8088 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
8094 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
8104 .getUnqualifiedType();
8108 auto *PseudoSrcExpr =
8113 auto *PseudoDstExpr =
8116 PseudoDstExpr, PseudoSrcExpr);
8117 if (AssignmentOp.isInvalid())
8121 if (AssignmentOp.isInvalid())
8127 SrcExprs.push_back(PseudoSrcExpr);
8128 DstExprs.push_back(PseudoDstExpr);
8129 AssignmentOps.push_back(AssignmentOp.get());
8136 Vars, SrcExprs, DstExprs, AssignmentOps);
8143 if (VarList.empty())
8154 if (
DSAStack->getCurrentDirective() == OMPD_ordered &&
8155 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
8156 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
8160 if (
DSAStack->getCurrentDirective() != OMPD_ordered &&
8162 DepKind == OMPC_DEPEND_sink)) {
8163 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
8164 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
8171 llvm::APSInt DepCounter(32);
8172 llvm::APSInt TotalDepCount(32);
8173 if (DepKind == OMPC_DEPEND_sink) {
8174 if (
auto *OrderedCountExpr =
DSAStack->getParentOrderedRegionParam()) {
8175 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(
Context);
8176 TotalDepCount.setIsUnsigned(
true);
8179 if ((DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) ||
8180 DSAStack->getParentOrderedRegionParam()) {
8181 for (
auto &RefExpr : VarList) {
8182 assert(RefExpr &&
"NULL expr in OpenMP shared clause.");
8183 if (isa<DependentScopeDeclRefExpr>(RefExpr) ||
8186 Vars.push_back(RefExpr);
8191 auto *SimpleExpr = RefExpr->IgnoreParenCasts();
8192 if (DepKind == OMPC_DEPEND_sink) {
8193 if (DepCounter >= TotalDepCount) {
8194 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
8206 SimpleExpr = SimpleExpr->IgnoreImplicit();
8212 if (
auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
8214 OOLoc = BO->getOperatorLoc();
8217 }
else if (
auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
8218 OOK = OCE->getOperator();
8219 OOLoc = OCE->getOperatorLoc();
8222 }
else if (
auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
8223 OOK = MCE->getMethodDecl()
8226 .getCXXOverloadedOperator();
8227 OOLoc = MCE->getCallee()->getExprLoc();
8231 Diag(ELoc, diag::err_omp_depend_sink_wrong_expr);
8237 diag::err_omp_depend_sink_expected_loop_iteration)
8238 <<
DSAStack->getParentLoopControlVariable(
8239 DepCounter.getZExtValue());
8242 if (OOK != OO_Plus && OOK != OO_Minus) {
8243 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
8246 ExprResult Res = VerifyPositiveIntegerConstantInClause(
8247 RHS, OMPC_depend,
false);
8251 auto *VD = dyn_cast<
VarDecl>(DE->getDecl());
8253 DSAStack->getParentOrderedRegionParam() &&
8254 (!VD || DepCounter !=
DSAStack->isParentLoopControlVariable(VD))) {
8255 Diag(DE->getExprLoc(),
8256 diag::err_omp_depend_sink_expected_loop_iteration)
8257 <<
DSAStack->getParentLoopControlVariable(
8258 DepCounter.getZExtValue());
8269 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
8270 (!ASE && !DE && !OASE) || (DE && !isa<VarDecl>(DE->getDecl())) ||
8271 (ASE && !ASE->getBase()->getType()->isAnyPointerType() &&
8272 !ASE->getBase()->getType()->isArrayType())) {
8273 Diag(ELoc, diag::err_omp_expected_var_name_or_array_item)
8274 << RefExpr->getSourceRange();
8279 Vars.push_back(RefExpr->IgnoreParenImpCasts());
8283 TotalDepCount > VarList.size() &&
8284 DSAStack->getParentOrderedRegionParam()) {
8285 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
8286 <<
DSAStack->getParentLoopControlVariable(VarList.size() + 1);
8288 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
8294 DepLoc, ColonLoc, Vars);
8300 Expr *ValExpr = Device;
8316 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
8317 if (
auto *CTD = CTSD->getSpecializedTemplate())
8318 RD = CTD->getTemplatedDecl();
8321 SemaRef.
Diag(Loc, diag::err_omp_not_mappable_type) << QTy;
8322 SemaRef.
Diag(RD->
getLocation(), diag::note_omp_polymorphic_in_target);
8326 bool IsCorrect =
true;
8327 for (
auto *I : DC->decls()) {
8329 if (
auto *MD = dyn_cast<CXXMethodDecl>(I)) {
8330 if (MD->isStatic()) {
8331 SemaRef.
Diag(Loc, diag::err_omp_not_mappable_type) << QTy;
8332 SemaRef.
Diag(MD->getLocation(),
8333 diag::note_omp_static_member_in_target);
8336 }
else if (
auto *VD = dyn_cast<VarDecl>(I)) {
8338 SemaRef.
Diag(Loc, diag::err_omp_not_mappable_type) << QTy;
8340 diag::note_omp_static_member_in_target);
8347 for (
auto &I : RD->
bases()) {
8349 I.getType()->getAsCXXRecordDecl()))
8359 SemaRef.
Diag(SL, diag::err_incomplete_type) << QTy << SR;
8361 }
else if (
CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(ND)) {
8375 for (
auto &RE : VarList) {
8376 assert(RE &&
"Null expr in omp map");
8377 if (isa<DependentScopeDeclRefExpr>(RE)) {
8388 auto *VE = RE->IgnoreParenLValueCasts();
8390 if (VE->isValueDependent() || VE->isTypeDependent() ||
8391 VE->isInstantiationDependent() ||
8392 VE->containsUnexpandedParameterPack()) {
8398 auto *SimpleExpr = RE->IgnoreParenCasts();
8403 if (!RE->IgnoreParenImpCasts()->isLValue() ||
8404 (!OASE && !ASE && !DE) ||
8405 (DE && !isa<VarDecl>(DE->getDecl())) ||
8406 (ASE && !ASE->getBase()->getType()->isAnyPointerType() &&
8407 !ASE->getBase()->getType()->isArrayType())) {
8408 Diag(ELoc, diag::err_omp_expected_var_name_or_array_item)
8409 << RE->getSourceRange();
8417 auto *B = ASE->getBase()->IgnoreParenCasts();
8420 auto *B = OASE->getBase();
8423 assert(D &&
"Null decl on map clause.");
8424 auto *VD = cast<VarDecl>(D);
8428 if (
DSAStack->isThreadPrivate(VD)) {
8429 auto DVar =
DSAStack->getTopDSA(VD,
false);
8430 Diag(ELoc, diag::err_omp_threadprivate_in_map);
8445 DSAStackTy::MapInfo MI =
DSAStack->IsMappedInCurrentRegion(VD);
8447 Diag(ELoc, diag::err_omp_map_shared_storage) << ELoc;
8448 Diag(MI.RefExpr->getExprLoc(), diag::note_used_here)
8449 << MI.RefExpr->getSourceRange();
8463 MI =
DSAStack->getMapInfoForVar(VD);
8464 if (MI.RefExpr && (isa<DeclRefExpr>(MI.RefExpr->IgnoreParenLValueCasts()) !=
8465 isa<DeclRefExpr>(VE)) &&
8467 Diag(ELoc, diag::err_omp_map_shared_storage) << ELoc;
8468 Diag(MI.RefExpr->getExprLoc(), diag::note_used_here)
8469 << MI.RefExpr->getSourceRange();
8481 DSAStack->addMapInfoForVar(VD, MI);
8487 MapTypeModifier, MapType, MapLoc);
8494 Expr *ValExpr = NumTeams;
8509 Expr *ValExpr = ThreadLimit;
8525 Expr *ValExpr = Priority;
8540 Expr *ValExpr = Grainsize;
8556 Expr *ValExpr = NumTasks;
8574 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, SourceLocation M1Loc, SourceLocation M2Loc)
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'.
void setImplicit(bool I=true)
OMPClause * ActOnOpenMPSimdlenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'simdlen' clause.
OpenMPScheduleClauseModifier getSecondScheduleModifier() const
Get the second modifier of the clause.
This represents 'thread_limit' clause in the '#pragma omp ...' directive.
StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp section' after parsing of the associated statement.
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
OMPClause * ActOnOpenMPLastprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'lastprivate' clause.
A (possibly-)qualified type.
Simple class containing the result of Sema::CorrectTypo.
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates)...
static OMPDistributeDirective * 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.
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)
ActOnConditionalOp - Parse a ?: operation.
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val)
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
void EndOpenMPDSABlock(Stmt *CurDirective)
Called on end of data sharing attribute block.
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc...
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
Expr * getSimdlen() const
Return safe iteration space distance.
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type...
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.
static bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, QualType QTy)
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth, signed/unsigned.
const Scope * getParent() const
getParent - Return the scope that this is nested in.
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).
OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr * > Vars, Expr *TailExpr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType, SourceLocation DepLinMapLoc)
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.
Decl - This represents one declaration (or definition), e.g.
specific_attr_iterator - Iterates over a subrange of an AttrVec, only providing attributes that are o...
This represents 'grainsize' clause in the '#pragma omp ...' directive.
static OMPSectionDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt, bool HasCancel)
Creates directive.
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.
OMPClause * ActOnOpenMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'threads' clause.
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.
bool isEnumeralType() const
bool hasDefinition() const
This represents 'priority' clause in the '#pragma omp ...' directive.
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...
The base class of the type hierarchy.
OMPClause * ActOnOpenMPGrainsizeClause(Expr *Size, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'grainsize' clause.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
const char * getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type)
static OMPCriticalDirective * Create(const ASTContext &C, const DeclarationNameInfo &Name, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive.
QualType getRecordType(const RecordDecl *Decl) const
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.
OMPClause * ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'hint' clause.
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.
OMPClause * ActOnOpenMPPriorityClause(Expr *Priority, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'priority' clause.
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.
void setNothrow(bool Nothrow=true)
This represents 'read' clause in the '#pragma omp atomic' directive.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
bool isFileVarDecl() const
isFileVarDecl - Returns true for file scoped variable declaration.
static OMPTaskLoopSimdDirective * 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.
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
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
IgnoreImplicit - Skip past any implicit AST nodes which might surround this expression.
void setBegin(SourceLocation b)
static OMPParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp barrier'.
Expr * getNumForLoops() const
Return the number of associated for-loops.
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.
This represents 'nogroup' clause in the '#pragma omp ...' directive.
void ActOnUninitializedDecl(Decl *dcl, bool TypeMayContainAuto)
QualType withConst() const
Retrieves a version of this type with const applied.
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)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType...
OMPClause * ActOnOpenMPLinearClause(ArrayRef< Expr * > VarList, Expr *Step, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'linear' clause.
const char * getOpenMPClauseName(OpenMPClauseKind Kind)
DeclarationName getName() const
getName - Returns the embedded declaration name.
One of these records is kept for each identifier that is lexed.
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.
bool isOpenMPTargetCapturedVar(VarDecl *VD, unsigned Level)
Check if the specified variable is captured by 'target' directive.
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
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.
This represents 'simd' clause in the '#pragma omp ...' directive.
OpenMPScheduleClauseModifier getFirstScheduleModifier() const
Get the first modifier of the clause.
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
Scope * TheScope
This is the enclosing scope of the captured region.
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
OMPClause * ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'if' clause.
SourceLocation getLocStart() const
Returns the starting location of the clause.
void Deallocate(void *Ptr) const
void StartOpenMPDSABlock(OpenMPDirectiveKind K, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc)
Called on start of new data sharing attribute block.
bool isTranslationUnit() const
bool isPreviousDeclInSameBlockScope() const
Whether this local extern variable declaration's previous declaration was declared in the same block ...
StmtResult ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp critical' after parsing of the associated statement.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
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)
Defines some OpenMP-specific enums and functions.
bool isOpenMPPrivateVar(VarDecl *VD, unsigned Level)
Check if the specified variable is used in 'private' clause.
void PopExpressionEvaluationContext()
This represents '#pragma omp critical' directive.
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.
static bool IsNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, bool StrictlyPositive)
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
static OMPParallelSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
VerifyDiagnosticConsumer::Directive Directive
ExprResult ActOnBooleanCondition(Scope *S, SourceLocation Loc, Expr *SubExpr)
StmtResult ActOnOpenMPTargetDataDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target data' after parsing of the associated statement.
SourceLocation getFirstScheduleModifierLoc() const
Get the first modifier location.
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.
OMPClause * ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_teams' clause.
static OMPCancelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, OpenMPDirectiveKind CancelRegion)
Creates directive.
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 * ActOnOpenMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'nogroup' clause.
OMPClause * ActOnOpenMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'read' clause.
OMPClause * ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'schedule' clause.
DeclarationNameInfo getNameInfo() const
bool isFunctionOrMethodVarDecl() const
isFunctionOrMethodVarDecl - Similar to isLocalVarDecl, but excludes variables declared in blocks...
static DeclRefExpr * buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, SourceLocation Loc, bool RefersToCapture=false)
StmtResult ActOnOpenMPDistributeDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute' after parsing of the associated statement.
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".
StmtResult ActOnOpenMPCancelDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancel'.
bool isValueDependent() const
isValueDependent - Determines whether this expression is value-dependent (C++ [temp.dep.constexpr]).
OMPClause * ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc)
std::pair< StringRef, QualType > CapturedParamNameType
This represents 'default' clause in the '#pragma omp ...' directive.
Scope - A scope is a transient data structure that is used while parsing the program.
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...
This represents 'final' clause in the '#pragma omp ...' directive.
This represents 'mergeable' clause in the '#pragma omp ...' directive.
StmtResult ActOnOpenMPOrderedDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp ordered' after parsing of the associated statement.
SourceLocation getSecondScheduleModifierLoc() const
Get the second modifier location.
Expr * CalcLastIteration
Calculation of last iteration.
Represents a C++ nested-name-specifier or a global scope specifier.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types...
bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a worksharing directive.
bool isStaticLocal() const
isStaticLocal - Returns true if a variable with function scope is a static local variable.
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 QualType getBaseOriginalType(Expr *Base)
Return original type of the base expression for array section.
detail::InMemoryDirectory::const_iterator I
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.
static bool IsCXXRecordForMappable(Sema &SemaRef, SourceLocation Loc, DSAStackTy *Stack, CXXRecordDecl *RD)
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
Expr * PreCond
Loop pre-condition.
OpenMPClauseKind getClauseKind() const
Returns kind of OpenMP clause (private, shared, reduction, etc.).
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.
OpenMP 4.0 [2.4, Array Sections].
The expressions built for the OpenMP loop CodeGen for the whole collapsed loop nest.
SourceLocation getLocEnd() const
Returns the ending location of the clause.
OMPClause * ActOnOpenMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'write' clause.
ConditionalOperator - The ?: ternary operator.
Sema - This implements semantic analysis and AST building for C.
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit, bool TypeMayContainAuto)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
StmtResult ActOnOpenMPSingleDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp single' after parsing of the associated statement.
This represents 'threads' clause in the '#pragma omp ...' directive.
ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
CreateBuiltinBinOp - Creates a new built-in binary operation with operator Opc at location TokLoc...
OMPClause * ActOnOpenMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'nowait' clause.
Retains information about a captured region.
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.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
bool isRealFloatingType() const
Floating point categories.
static OMPTargetDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
OMPClause * ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'map' clause.
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.
Expr - This represents one expression.
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)
isDeclScope - Return true if this is the scope that the specified decl is declared in...
bool isAnyComplexType() const
static OMPMapClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, OpenMPMapClauseKind TypeModifier, OpenMPMapClauseKind Type, SourceLocation TypeLoc)
Creates clause with a list of variables VL.
This represents 'simdlen' clause in the '#pragma omp ...' directive.
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.
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.
Defines the clang::Preprocessor interface.
ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, VerifyICEDiagnoser &Diagnoser, bool AllowFold=true)
VerifyIntegerConstantExpression - Verifies that an expression is an ICE, and reports the appropriate ...
OpenMPClauseKind
OpenMP clauses.
StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskyield'.
DeclContext * getDeclContext()
bool isFloatingType() const
static FloatingLiteral * Create(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L)
static OMPReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr * > Privates, ArrayRef< Expr * > LHSExprs, ArrayRef< Expr * > RHSExprs, ArrayRef< Expr * > ReductionOps)
Creates clause with a list of variables VL.
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()
static OMPOrderedDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isExceptionVariable() const
Determine whether this variable is the exception variable in a C++ catch statememt or an Objective-C ...
bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer...
static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, ArrayRef< OMPClause * > Clauses, ArrayRef< OpenMPDirectiveKind > AllowedNameModifiers)
OMPClause * ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, ArrayRef< unsigned > Arguments, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, ArrayRef< SourceLocation > ArgumentsLoc, SourceLocation DelimLoc, SourceLocation EndLoc)
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep)
Creates clause with a list of variables VL and a linear step Step.
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
OMPClause * ActOnOpenMPNumTasksClause(Expr *NumTasks, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_tasks' clause.
This represents 'collapse' clause in the '#pragma omp ...' directive.
static OMPTargetDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
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 OMPTaskLoopDirective * 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.
TypeSourceInfo * getTypeSourceInfo() const
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
DefaultDataSharingAttributes
Default data sharing attributes, which can be applied to directive.
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1...
OMPClause * ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'device' clause.
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.
SmallVector< Expr *, 4 > PrivateCounters
PrivateCounters Loop counters.
This represents 'num_teams' clause in the '#pragma omp ...' directive.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
static Expr * getOrderedNumberExpr(ArrayRef< OMPClause * > Clauses)
This captures a statement into a function.
SmallVector< Expr *, 4 > Counters
Counters Loop counters.
Encodes a location in the source.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
This represents 'hint' clause in the '#pragma omp ...' directive.
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.
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
getCXXOverloadedOperator - If this name is the name of an overloadable operator in C++ (e...
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
isLocalVarDecl - Returns true for local variable declarations other than parameters.
void setReferenced(bool R=true)
OpenMPDirectiveKind
OpenMP directives.
IdentifierTable & getIdentifierTable()
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
std::string getAsString() const
getAsString - Retrieve the human-readable string for this name.
QualType withConst() const
StmtResult ActOnCapturedRegionEnd(Stmt *S)
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
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
isIntegerConstantExpr - Return true if this expression is a valid integer constant expression...
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.
ThreadStorageClassSpecifier getTSCSpec() const
OMPClause * ActOnOpenMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'seq_cst' clause.
bool isTypeDependent() const
isTypeDependent - Determines whether this expression is type-dependent (C++ [temp.dep.expr]), which means that its type could change from one template instantiation to the next.
const T * castAs() const
Member-template castAs<specific type>.
SourceLocation getBeginLoc() const
static OMPForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
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
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
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
bool isDynamicClass() const
StmtResult ActOnOpenMPTaskLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop' after parsing of the associated statement.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
OMPClause * ActOnOpenMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'simd' clause.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
static Expr * getCollapseNumberExpr(ArrayRef< OMPClause * > Clauses)
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 OMPTaskDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
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.
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
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.
OpenMPScheduleClauseModifier
OpenMP modifiers for 'schedule' clause.
This represents 'device' clause in the '#pragma omp ...' directive.
SourceLocation getLocStart() const LLVM_READONLY
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
SmallVector< Expr *, 4 > Inits
Expressions for loop counters inits for CodeGen.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
static bool CheckOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, 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...
void ActOnCapturedRegionError()
static std::string getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, ArrayRef< unsigned > Exclude=llvm::None)
bool isInvalidDecl() const
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.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language...
This represents clause 'linear' in the '#pragma omp ...' directives.
SourceLocation getLocStart() const LLVM_READONLY
static bool checkGrainsizeNumTasksClauses(Sema &S, ArrayRef< OMPClause * > Clauses)
DeclarationNameInfo getDirectiveName() const
Return name of the directive.
bool IsOpenMPCapturedByRef(VarDecl *VD, const sema::CapturedRegionScopeInfo *RSI)
Return true if the provided declaration VD should be captured by reference in the provided scope RSI...
StmtResult ActOnOpenMPTaskgroupDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskgroup'.
detail::InMemoryDirectory::const_iterator E
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
bool isOpenMPThreadPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of threadprivate clauses like 'threadprivate', 'copyin' or 'copyprivate'.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
bool IsOpenMPCapturedVar(VarDecl *VD)
Check if the specified variable is used in one of the private clauses (private, firstprivate, lastprivate, reduction etc.) in OpenMP constructs.
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.
NamedDecl * getCorrectionDecl() const
Gets the pointer to the declaration of the typo correction.
StmtResult ActOnOpenMPTaskLoopSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< VarDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop simd' after parsing of the associated statement...
Not an overloaded operator.
Expr * getSafelen() const
Return safe iteration space distance.
Complex values, per C99 6.2.5p11.
bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a distribute directive.
const T * getAs() const
Member-template getAs<specific type>'.
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)
isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true if 'D' is in Scope 'S'...
bool isOpenMPTargetDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target-kind directive.
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...
Base for LValueReferenceType and RValueReferenceType.
bool isNRVOVariable() const
Determine whether this local variable can be used with the named return value optimization (NRVO)...
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
InitializationStyle getInitStyle() const
The style of initialization for this declaration.
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.
QualType getPointeeType() const
bool isTLSSupported() const
Whether the target supports thread-local storage.
bool isCXXForRangeDecl() const
Determine whether this variable is the for-range-declaration in a C++0x for-range statement...
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
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 getVariableArrayType(QualType EltTy, Expr *NumElts, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals, SourceRange Brackets) const
Return a non-unique reference to the type for a variable array of the specified element type...
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)
This represents 'num_tasks' clause in the '#pragma omp ...' directive.
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.
Privates[]
Gets the list of initial values for linear variables.
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
void addHiddenDecl(Decl *D)
Add the declaration D to this context without modifying any lookup tables.
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.
OMPClause * ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'thread_limit' clause.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
static OMPSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
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.
static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, Expr *NumIterations, Sema &SemaRef, Scope *S)
static VarDecl * buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, StringRef Name, const AttrVec *Attrs=nullptr)
Build a variable declaration for OpenMP loop iteration variable.
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.
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...
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)
Retrieve the overloaded operator kind that corresponds to the given binary opcode.
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
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)
static bool checkSimdlenSafelenValues(Sema &S, const Expr *Simdlen, const Expr *Safelen)
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...
NamedDecl - This represents a decl with a name.
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)
bool isArithmeticType() const
OMPClause * ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc, SourceLocation LParenLoc=SourceLocation(), Expr *NumForLoops=nullptr)
Called on well-formed 'ordered' clause.
Directive - Abstract class representing a parsed verify directive.
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 ':'.
static unsigned CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, 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).
This represents '#pragma omp threadprivate ...' directive.
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)
static OMPParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
bool hasLocalStorage() const
hasLocalStorage - Returns true if a variable with function scope is a non-static local variable...
Helper class that creates diagnostics with optional template instantiation stacks.
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
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.