34 using namespace clang;
50 class DSAStackTy final {
52 struct DSAVarData final {
55 Expr *RefExpr =
nullptr;
64 struct DSAInfo final {
68 llvm::PointerIntPair<Expr *, 1, bool> RefExpr;
71 typedef llvm::DenseMap<ValueDecl *, DSAInfo> DeclSAMapTy;
72 typedef llvm::DenseMap<ValueDecl *, Expr *> AlignedMapTy;
73 typedef std::pair<unsigned, VarDecl *> LCDeclInfo;
74 typedef llvm::DenseMap<ValueDecl *, LCDeclInfo> LoopControlVariablesMapTy;
75 typedef llvm::DenseMap<
77 MappedExprComponentsTy;
78 typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>>
80 typedef llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>
83 struct SharingMapTy final {
84 DeclSAMapTy SharingMap;
85 AlignedMapTy AlignedMap;
86 MappedExprComponentsTy MappedExprComponents;
87 LoopControlVariablesMapTy LCVMap;
92 Scope *CurScope =
nullptr;
97 DoacrossDependMapTy DoacrossDepends;
101 llvm::PointerIntPair<Expr *, 1, bool> OrderedRegion;
102 bool NowaitRegion =
false;
103 bool CancelRegion =
false;
104 unsigned AssociatedLoops = 1;
108 :
Directive(DKind), DirectiveName(Name), CurScope(CurScope),
121 bool ForceCapturing =
false;
122 CriticalsWithHintsTy Criticals;
126 DSAVarData getDSA(StackTy::reverse_iterator& Iter,
ValueDecl *D);
129 bool isOpenMPLocal(
VarDecl *D, StackTy::reverse_iterator Iter);
132 explicit DSAStackTy(
Sema &
S) :
Stack(1), SemaRef(S) {}
134 bool isClauseParsingMode()
const {
return ClauseKindMode !=
OMPC_unknown; }
137 bool isForceVarCapturing()
const {
return ForceCapturing; }
138 void setForceVarCapturing(
bool V) { ForceCapturing = V; }
142 Stack.push_back(SharingMapTy(DKind, DirName, CurScope, Loc));
143 Stack.back().DefaultAttrLoc = Loc;
147 assert(
Stack.size() > 1 &&
"Data-sharing attributes stack is empty!");
154 const std::pair<OMPCriticalDirective *, llvm::APSInt>
157 if (
I != Criticals.end())
159 return std::make_pair(
nullptr, llvm::APSInt());
172 LCDeclInfo isLoopControlVariable(
ValueDecl *D);
177 LCDeclInfo isParentLoopControlVariable(
ValueDecl *D);
180 ValueDecl *getParentLoopControlVariable(
unsigned I);
188 DSAVarData getTopDSA(
ValueDecl *D,
bool FromParent);
190 DSAVarData getImplicitDSA(
ValueDecl *D,
bool FromParent);
211 unsigned Level,
bool NotLastprivate =
false);
215 bool hasExplicitDirective(
227 return Stack.back().Directive;
231 if (
Stack.size() > 2)
238 Stack.back().DefaultAttr = DSA_none;
239 Stack.back().DefaultAttrLoc = Loc;
243 Stack.back().DefaultAttr = DSA_shared;
244 Stack.back().DefaultAttrLoc = Loc;
248 return Stack.back().DefaultAttr;
251 return Stack.back().DefaultAttrLoc;
255 bool isThreadPrivate(
VarDecl *D) {
256 DSAVarData DVar = getTopDSA(D,
false);
261 void setOrderedRegion(
bool IsOrdered,
Expr *Param) {
262 Stack.back().OrderedRegion.setInt(IsOrdered);
263 Stack.back().OrderedRegion.setPointer(Param);
267 bool isParentOrderedRegion()
const {
268 if (
Stack.size() > 2)
269 return Stack[
Stack.size() - 2].OrderedRegion.getInt();
273 Expr *getParentOrderedRegionParam()
const {
274 if (
Stack.size() > 2)
275 return Stack[
Stack.size() - 2].OrderedRegion.getPointer();
279 void setNowaitRegion(
bool IsNowait =
true) {
280 Stack.back().NowaitRegion = IsNowait;
284 bool isParentNowaitRegion()
const {
285 if (
Stack.size() > 2)
290 void setParentCancelRegion(
bool Cancel =
true) {
291 if (
Stack.size() > 2)
293 Stack[
Stack.size() - 2].CancelRegion || Cancel;
296 bool isCancelRegion()
const {
297 return Stack.back().CancelRegion;
301 void setAssociatedLoops(
unsigned Val) {
Stack.back().AssociatedLoops = Val; }
303 unsigned getAssociatedLoops()
const {
return Stack.back().AssociatedLoops; }
308 if (
Stack.size() > 2)
309 Stack[
Stack.size() - 2].InnerTeamsRegionLoc = TeamsRegionLoc;
312 bool hasInnerTeamsRegion()
const {
313 return getInnerTeamsRegionLoc().
isValid();
317 if (
Stack.size() > 1)
318 return Stack.back().InnerTeamsRegionLoc;
322 Scope *getCurScope()
const {
return Stack.back().CurScope; }
323 Scope *getCurScope() {
return Stack.back().CurScope; }
328 bool checkMappableExprComponentListsForDecl(
330 const llvm::function_ref<
bool(
332 auto SI =
Stack.rbegin();
333 auto SE =
Stack.rend();
338 if (CurrentRegionOnly) {
344 for (; SI != SE; ++SI) {
345 auto MI = SI->MappedExprComponents.find(VD);
346 if (MI != SI->MappedExprComponents.end())
347 for (
auto &L : MI->second)
356 void addMappableExpressionComponents(
359 assert(
Stack.size() > 1 &&
360 "Not expecting to retrieve components from a empty stack!");
361 auto &MEC =
Stack.back().MappedExprComponents[VD];
363 MEC.resize(MEC.size() + 1);
364 MEC.back().append(Components.begin(), Components.end());
367 unsigned getNestingLevel()
const {
368 assert(
Stack.size() > 1);
369 return Stack.size() - 2;
371 void addDoacrossDependClause(
OMPDependClause *C, OperatorOffsetTy &OpsOffs) {
372 assert(
Stack.size() > 2);
374 Stack[
Stack.size() - 2].DoacrossDepends.insert({C, OpsOffs});
376 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
377 getDoacrossDependClauses()
const {
378 assert(
Stack.size() > 1);
380 auto &Ref =
Stack[
Stack.size() - 1].DoacrossDepends;
381 return llvm::make_range(Ref.begin(), Ref.end());
383 return llvm::make_range(
Stack[0].DoacrossDepends.end(),
384 Stack[0].DoacrossDepends.end());
394 auto *VD = dyn_cast<
VarDecl>(D);
397 VD = VD->getCanonicalDecl();
401 FD = FD->getCanonicalDecl();
407 DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator& Iter,
410 auto *VD = dyn_cast<
VarDecl>(D);
413 if (Iter == std::prev(
Stack.rend())) {
419 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D))
420 DVar.CKind = OMPC_shared;
426 if (VD && VD->hasGlobalStorage())
427 DVar.CKind = OMPC_shared;
431 DVar.CKind = OMPC_shared;
436 DVar.DKind = Iter->Directive;
441 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
442 (VD->getStorageClass() ==
SC_Auto || VD->getStorageClass() ==
SC_None)) {
443 DVar.CKind = OMPC_private;
449 if (Iter->SharingMap.count(D)) {
450 DVar.RefExpr = Iter->SharingMap[D].RefExpr.getPointer();
451 DVar.PrivateCopy = Iter->SharingMap[D].PrivateCopy;
452 DVar.CKind = Iter->SharingMap[D].Attributes;
453 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
461 switch (Iter->DefaultAttr) {
463 DVar.CKind = OMPC_shared;
464 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
468 case DSA_unspecified:
473 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
476 DVar.CKind = OMPC_shared;
487 for (StackTy::reverse_iterator
I = std::next(Iter), EE =
Stack.rend();
494 DVarTemp = getDSA(
I, D);
495 if (DVarTemp.CKind != OMPC_shared) {
496 DVar.RefExpr =
nullptr;
497 DVar.CKind = OMPC_firstprivate;
500 if (isParallelOrTaskRegion(
I->Directive))
504 (DVarTemp.CKind ==
OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
513 return getDSA(++Iter, D);
517 assert(
Stack.size() > 1 &&
"Data sharing attributes stack is empty");
519 auto It =
Stack.back().AlignedMap.find(D);
520 if (It ==
Stack.back().AlignedMap.end()) {
521 assert(NewDE &&
"Unexpected nullptr expr to be added into aligned map");
522 Stack.back().AlignedMap[D] = NewDE;
525 assert(It->second &&
"Unexpected nullptr expr in the aligned map");
532 assert(
Stack.size() > 1 &&
"Data-sharing attributes stack is empty");
534 Stack.back().LCVMap.insert(
535 std::make_pair(D, LCDeclInfo(
Stack.back().LCVMap.size() + 1, Capture)));
538 DSAStackTy::LCDeclInfo DSAStackTy::isLoopControlVariable(
ValueDecl *D) {
539 assert(
Stack.size() > 1 &&
"Data-sharing attributes stack is empty");
541 return Stack.back().LCVMap.count(D) > 0 ?
Stack.back().LCVMap[D]
542 : LCDeclInfo(0,
nullptr);
545 DSAStackTy::LCDeclInfo DSAStackTy::isParentLoopControlVariable(
ValueDecl *D) {
546 assert(
Stack.size() > 2 &&
"Data-sharing attributes stack is empty");
548 return Stack[
Stack.size() - 2].LCVMap.count(D) > 0
550 : LCDeclInfo(0,
nullptr);
553 ValueDecl *DSAStackTy::getParentLoopControlVariable(
unsigned I) {
554 assert(
Stack.size() > 2 &&
"Data-sharing attributes stack is empty");
557 for (
auto &Pair :
Stack[
Stack.size() - 2].LCVMap) {
558 if (Pair.second.first == I)
568 auto &Data =
Stack[0].SharingMap[D];
570 Data.RefExpr.setPointer(E);
571 Data.PrivateCopy =
nullptr;
573 assert(
Stack.size() > 1 &&
"Data-sharing attributes stack is empty");
574 auto &Data =
Stack.back().SharingMap[D];
575 assert(Data.Attributes ==
OMPC_unknown || (A == Data.Attributes) ||
576 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
577 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
578 (isLoopControlVariable(D).first && A == OMPC_private));
579 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
580 Data.RefExpr.setInt(
true);
583 const bool IsLastprivate =
584 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
586 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
587 Data.PrivateCopy = PrivateCopy;
589 auto &Data =
Stack.back().SharingMap[PrivateCopy->
getDecl()];
591 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
592 Data.PrivateCopy =
nullptr;
597 bool DSAStackTy::isOpenMPLocal(
VarDecl *D, StackTy::reverse_iterator Iter) {
599 if (
Stack.size() > 2) {
600 reverse_iterator I = Iter, E = std::prev(
Stack.rend());
601 Scope *TopScope =
nullptr;
602 while (I != E && !isParallelOrTaskRegion(I->Directive)) {
607 TopScope = I->CurScope ? I->CurScope->getParent() :
nullptr;
608 Scope *CurScope = getCurScope();
609 while (CurScope != TopScope && !CurScope->
isDeclScope(D)) {
612 return CurScope != TopScope;
619 StringRef Name,
const AttrVec *Attrs =
nullptr) {
636 bool RefersToCapture =
false) {
644 DSAStackTy::DSAVarData DSAStackTy::getTopDSA(
ValueDecl *D,
bool FromParent) {
651 auto *VD = dyn_cast<
VarDecl>(D);
653 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
654 SemaRef.getLangOpts().OpenMPUseTLS &&
655 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
657 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
662 if (
Stack[0].SharingMap.count(D)) {
663 DVar.RefExpr =
Stack[0].SharingMap[D].RefExpr.getPointer();
668 if (
Stack.size() == 1) {
681 if (VD && VD->isStaticDataMember()) {
682 DSAVarData DVarTemp = hasDSA(D,
isOpenMPPrivate, MatchesAlways, FromParent);
686 DVar.CKind = OMPC_shared;
691 bool IsConstant = Type.
isConstant(SemaRef.getASTContext());
692 Type = SemaRef.getASTContext().getBaseElementType(Type);
699 if (
auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
700 if (
auto *CTD = CTSD->getSpecializedTemplate())
701 RD = CTD->getTemplatedDecl();
703 !(SemaRef.getLangOpts().CPlusPlus && RD && RD->
hasDefinition() &&
707 DSAVarData DVarTemp = hasDSA(
709 MatchesAlways, FromParent);
710 if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
713 DVar.CKind = OMPC_shared;
719 auto StartI = std::next(
Stack.rbegin());
720 auto EndI = std::prev(
Stack.rend());
721 if (FromParent && StartI != EndI) {
722 StartI = std::next(StartI);
724 auto I = std::prev(StartI);
725 if (I->SharingMap.count(D)) {
726 DVar.RefExpr = I->SharingMap[D].RefExpr.getPointer();
727 DVar.PrivateCopy = I->SharingMap[D].PrivateCopy;
728 DVar.CKind = I->SharingMap[D].Attributes;
729 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
735 DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(
ValueDecl *D,
738 auto StartI =
Stack.rbegin();
739 auto EndI = std::prev(
Stack.rend());
740 if (FromParent && StartI != EndI) {
741 StartI = std::next(StartI);
743 return getDSA(StartI, D);
746 DSAStackTy::DSAVarData
752 auto StartI = std::next(
Stack.rbegin());
753 auto EndI =
Stack.rend();
754 if (FromParent && StartI != EndI) {
755 StartI = std::next(StartI);
757 for (
auto I = StartI, EE = EndI; I != EE; ++
I) {
758 if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive))
760 DSAVarData DVar = getDSA(I, D);
761 if (CPred(DVar.CKind))
767 DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
772 auto StartI = std::next(
Stack.rbegin());
773 auto EndI =
Stack.rend();
774 if (FromParent && StartI != EndI) {
775 StartI = std::next(StartI);
777 for (
auto I = StartI, EE = EndI; I != EE; ++
I) {
778 if (!DPred(I->Directive))
780 DSAVarData DVar = getDSA(I, D);
781 if (CPred(DVar.CKind))
788 bool DSAStackTy::hasExplicitDSA(
790 unsigned Level,
bool NotLastprivate) {
791 if (CPred(ClauseKindMode))
794 auto StartI = std::next(
Stack.begin());
795 auto EndI =
Stack.end();
798 std::advance(StartI, Level);
799 return (StartI->SharingMap.count(D) > 0) &&
800 StartI->SharingMap[D].RefExpr.getPointer() &&
801 CPred(StartI->SharingMap[D].Attributes) &&
802 (!NotLastprivate || !StartI->SharingMap[D].RefExpr.getInt());
805 bool DSAStackTy::hasExplicitDirective(
808 auto StartI = std::next(
Stack.begin());
809 auto EndI =
Stack.end();
812 std::advance(StartI, Level);
813 return DPred(StartI->Directive);
816 bool DSAStackTy::hasDirective(
822 if (
Stack.size() < 2)
824 auto StartI = std::next(
Stack.rbegin());
825 auto EndI = std::prev(
Stack.rend());
826 if (FromParent && StartI != EndI) {
827 StartI = std::next(StartI);
829 for (
auto I = StartI, EE = EndI; I != EE; ++
I) {
830 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
836 void Sema::InitDataSharingAttributesStack() {
837 VarDataSharingAttributesStack =
new DSAStackTy(*
this);
840 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
843 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
907 if (Ty->isReferenceType())
913 bool IsVariableUsedInMapClause =
false;
914 bool IsVariableAssociatedWithSection =
false;
916 DSAStack->checkMappableExprComponentListsForDecl(
921 auto EI = MapExprComponents.rbegin();
922 auto EE = MapExprComponents.rend();
924 assert(EI != EE &&
"Invalid map expression!");
926 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
927 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
933 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
934 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
935 isa<MemberExpr>(EI->getAssociatedExpression())) {
936 IsVariableAssociatedWithSection =
true;
945 if (IsVariableUsedInMapClause) {
948 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
951 IsByRef = !Ty->isScalarType();
955 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
956 IsByRef = !
DSAStack->hasExplicitDSA(
966 (Ctx.getTypeSizeInChars(Ty) >
967 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
968 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
975 unsigned Sema::getOpenMPNestingLevel()
const {
981 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
991 auto *VD = dyn_cast<
VarDecl>(D);
992 if (VD && !VD->hasLocalStorage()) {
993 if (
DSAStack->getCurrentDirective() == OMPD_target &&
1006 (!
DSAStack->isClauseParsingMode() ||
1008 auto &&Info =
DSAStack->isLoopControlVariable(D);
1010 (VD && VD->hasLocalStorage() &&
1011 isParallelOrTaskRegion(
DSAStack->getCurrentDirective())) ||
1012 (VD &&
DSAStack->isForceVarCapturing()))
1013 return VD ? VD : Info.second;
1014 auto DVarPrivate =
DSAStack->getTopDSA(D,
DSAStack->isClauseParsingMode());
1016 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1021 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1026 bool Sema::isOpenMPPrivateDecl(
ValueDecl *D,
unsigned Level) {
1027 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
1033 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
1036 auto *VD = dyn_cast<
VarDecl>(D);
1037 return VD && !VD->hasLocalStorage() &&
1042 void Sema::DestroyDataSharingAttributesStack() {
delete DSAStack; }
1047 DSAStack->push(DKind, DirName, CurScope, Loc);
1065 if (
auto D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
1066 for (
auto *C : D->clauses()) {
1067 if (
auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
1069 for (
auto *DE : Clause->varlists()) {
1070 if (DE->isValueDependent() || DE->isTypeDependent()) {
1071 PrivateCopies.push_back(
nullptr);
1074 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
1075 VarDecl *VD = cast<VarDecl>(DRE->getDecl());
1076 QualType Type = VD->getType().getNonReferenceType();
1077 auto DVar =
DSAStack->getTopDSA(VD,
false);
1078 if (DVar.CKind == OMPC_lastprivate) {
1085 *
this, DE->getExprLoc(), Type.getUnqualifiedType(),
1086 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() :
nullptr);
1088 if (VDPrivate->isInvalidDecl())
1091 *
this, VDPrivate, DE->getType(), DE->getExprLoc()));
1095 PrivateCopies.push_back(
nullptr);
1099 if (PrivateCopies.size() == Clause->varlist_size())
1100 Clause->setPrivateCopies(PrivateCopies);
1111 Expr *NumIterations,
Sema &SemaRef,
1121 explicit VarDeclFilterCCC(
Sema &
S) : SemaRef(S) {}
1122 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1124 if (
VarDecl *VD = dyn_cast_or_null<VarDecl>(ND)) {
1125 return VD->hasGlobalStorage() &&
1126 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1127 SemaRef.getCurScope());
1138 explicit VarOrFuncDeclFilterCCC(
Sema &
S) : SemaRef(S) {}
1139 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1141 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) {
1142 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1143 SemaRef.getCurScope());
1167 ? diag::err_undeclared_var_use_suggest
1168 : diag::err_omp_expected_var_arg_suggest)
1170 VD = Corrected.getCorrectionDeclAs<
VarDecl>();
1173 : diag::err_omp_expected_var_arg)
1189 Diag(Id.
getLoc(), diag::err_omp_global_var_arg)
1193 Diag(VD->getLocation(),
1194 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1200 NamedDecl *ND = cast<NamedDecl>(CanonicalVD);
1204 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
1210 Diag(VD->getLocation(),
1211 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1225 Diag(VD->getLocation(),
1226 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1234 if (CanonicalVD->getDeclContext()->isNamespace() &&
1241 Diag(VD->getLocation(),
1242 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1255 Diag(VD->getLocation(),
1256 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1264 if (VD->isUsed() && !
DSAStack->isThreadPrivate(VD)) {
1288 class LocalVarRefChecker :
public ConstStmtVisitor<LocalVarRefChecker, bool> {
1293 if (
auto VD = dyn_cast<VarDecl>(E->
getDecl())) {
1294 if (VD->hasLocalStorage()) {
1296 diag::err_omp_local_var_in_threadprivate_init)
1297 << E->getSourceRange();
1298 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
1299 << VD << VD->getSourceRange();
1305 bool VisitStmt(
const Stmt *
S) {
1306 for (
auto Child : S->children()) {
1307 if (Child && Visit(Child))
1312 explicit LocalVarRefChecker(
Sema &SemaRef) : SemaRef(SemaRef) {}
1319 for (
auto &RefExpr : VarList) {
1325 VD->setReferenced();
1338 diag::err_omp_threadprivate_incomplete_type)) {
1344 if (VD->getType()->isReferenceType()) {
1345 Diag(ILoc, diag::err_omp_ref_type_arg)
1349 Diag(VD->getLocation(),
1350 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1358 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1361 (VD->getStorageClass() ==
SC_Register && VD->hasAttr<AsmLabelAttr>() &&
1362 !VD->isLocalVarDecl())) {
1363 Diag(ILoc, diag::err_omp_var_thread_local)
1367 Diag(VD->getLocation(),
1368 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1375 if (
auto Init = VD->getAnyInitializer()) {
1376 LocalVarRefChecker Checker(*
this);
1377 if (Checker.Visit(Init))
1381 Vars.push_back(RefExpr);
1383 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
1386 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
1389 if (!Vars.empty()) {
1398 const ValueDecl *D, DSAStackTy::DSAVarData DVar,
1399 bool IsLoopIterVar =
false) {
1401 SemaRef.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
1406 PDSA_StaticMemberShared,
1407 PDSA_StaticLocalVarShared,
1408 PDSA_LoopIterVarPrivate,
1409 PDSA_LoopIterVarLinear,
1410 PDSA_LoopIterVarLastprivate,
1411 PDSA_ConstVarShared,
1412 PDSA_GlobalVarShared,
1413 PDSA_TaskVarFirstprivate,
1414 PDSA_LocalVarPrivate,
1416 } Reason = PDSA_Implicit;
1417 bool ReportHint =
false;
1418 auto ReportLoc = D->getLocation();
1419 auto *VD = dyn_cast<
VarDecl>(D);
1420 if (IsLoopIterVar) {
1421 if (DVar.CKind == OMPC_private)
1422 Reason = PDSA_LoopIterVarPrivate;
1423 else if (DVar.CKind == OMPC_lastprivate)
1424 Reason = PDSA_LoopIterVarLastprivate;
1426 Reason = PDSA_LoopIterVarLinear;
1428 DVar.CKind == OMPC_firstprivate) {
1429 Reason = PDSA_TaskVarFirstprivate;
1430 ReportLoc = DVar.ImplicitDSALoc;
1431 }
else if (VD && VD->isStaticLocal())
1432 Reason = PDSA_StaticLocalVarShared;
1433 else if (VD && VD->isStaticDataMember())
1434 Reason = PDSA_StaticMemberShared;
1435 else if (VD && VD->isFileVarDecl())
1436 Reason = PDSA_GlobalVarShared;
1438 Reason = PDSA_ConstVarShared;
1439 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
1441 Reason = PDSA_LocalVarPrivate;
1443 if (Reason != PDSA_Implicit) {
1444 SemaRef.
Diag(ReportLoc, diag::note_omp_predetermined_dsa)
1445 << Reason << ReportHint
1447 }
else if (DVar.ImplicitDSALoc.isValid()) {
1448 SemaRef.
Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
1454 class DSAAttrChecker :
public StmtVisitor<DSAAttrChecker, void> {
1460 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA;
1467 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
1469 if (VD->isLocalVarDecl() && !CS->capturesVariable(VD))
1472 auto DVar =
Stack->getTopDSA(VD,
false);
1474 if (DVar.RefExpr)
return;
1477 auto DKind =
Stack->getCurrentDirective();
1483 isParallelOrTaskRegion(DKind) &&
1484 VarsWithInheritedDSA.count(VD) == 0) {
1485 VarsWithInheritedDSA[VD] =
E;
1493 DVar =
Stack->hasInnermostDSA(
1502 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
1508 DVar =
Stack->getImplicitDSA(VD,
false);
1510 !
Stack->isLoopControlVariable(VD).first)
1511 ImplicitFirstprivate.push_back(E);
1520 auto DVar =
Stack->getTopDSA(FD,
false);
1527 auto DKind =
Stack->getCurrentDirective();
1532 DVar =
Stack->hasInnermostDSA(
1542 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
1548 DVar =
Stack->getImplicitDSA(FD,
false);
1550 !
Stack->isLoopControlVariable(FD).first)
1551 ImplicitFirstprivate.push_back(E);
1556 for (
auto *C : S->
clauses()) {
1559 if (C && (!isa<OMPFirstprivateClause>(C) || C->getLocStart().isValid()))
1560 for (
auto *CC : C->children()) {
1566 void VisitStmt(
Stmt *S) {
1567 for (
auto *C : S->children()) {
1568 if (C && !isa<OMPExecutableDirective>(C))
1573 bool isErrorFound() {
return ErrorFound; }
1574 ArrayRef<Expr *> getImplicitFirstprivate() {
return ImplicitFirstprivate; }
1575 llvm::DenseMap<ValueDecl *, Expr *> &getVarsWithInheritedDSA() {
1576 return VarsWithInheritedDSA;
1580 :
Stack(S), SemaRef(SemaRef), ErrorFound(
false), CS(CS) {}
1587 case OMPD_parallel_for:
1588 case OMPD_parallel_for_simd:
1589 case OMPD_parallel_sections:
1595 std::make_pair(
".global_tid.", KmpInt32PtrTy),
1596 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
1597 std::make_pair(StringRef(),
QualType())
1611 case OMPD_taskgroup:
1612 case OMPD_distribute:
1615 case OMPD_target_data:
1617 case OMPD_target_parallel:
1618 case OMPD_target_parallel_for:
1619 case OMPD_target_parallel_for_simd: {
1621 std::make_pair(StringRef(),
QualType())
1634 std::make_pair(
".global_tid.", KmpInt32Ty),
1637 std::make_pair(
".copy_fn.",
1640 std::make_pair(StringRef(),
QualType())
1647 AlwaysInlineAttr::CreateImplicit(
1652 case OMPD_taskloop_simd: {
1664 std::make_pair(
".global_tid.", KmpInt32Ty),
1666 std::make_pair(
".privates.",
1672 std::make_pair(
".lb.", KmpUInt64Ty),
1673 std::make_pair(
".ub.", KmpUInt64Ty), std::make_pair(
".st.", KmpInt64Ty),
1674 std::make_pair(
".liter.", KmpInt32Ty),
1675 std::make_pair(StringRef(),
QualType())
1682 AlwaysInlineAttr::CreateImplicit(
1686 case OMPD_distribute_parallel_for_simd:
1687 case OMPD_distribute_simd:
1688 case OMPD_distribute_parallel_for: {
1693 std::make_pair(
".global_tid.", KmpInt32PtrTy),
1694 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
1697 std::make_pair(StringRef(),
QualType())
1703 case OMPD_threadprivate:
1704 case OMPD_taskyield:
1707 case OMPD_cancellation_point:
1710 case OMPD_target_enter_data:
1711 case OMPD_target_exit_data:
1712 case OMPD_declare_reduction:
1713 case OMPD_declare_simd:
1714 case OMPD_declare_target:
1715 case OMPD_end_declare_target:
1716 case OMPD_target_update:
1717 llvm_unreachable(
"OpenMP Directive is not allowed");
1719 llvm_unreachable(
"Unknown OpenMP directive");
1724 Expr *CaptureExpr,
bool WithInit,
1725 bool AsExpression) {
1726 assert(CaptureExpr);
1745 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C,
SourceRange()));
1756 CD = cast<OMPCapturedExprDecl>(VD);
1768 CaptureExpr,
true,
true);
1793 for (
auto *Clause : Clauses) {
1795 Clause->getClauseKind() == OMPC_copyprivate ||
1798 Clause->getClauseKind() == OMPC_copyin)) {
1799 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
1801 for (
auto *VarRef : Clause->children()) {
1802 if (
auto *E = cast_or_null<Expr>(VarRef)) {
1806 DSAStack->setForceVarCapturing(
false);
1807 }
else if (isParallelOrTaskRegion(
DSAStack->getCurrentDirective())) {
1812 if (
auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
1813 for (
auto *D : DS->decls())
1818 if (
auto *E = C->getPostUpdateExpr())
1822 if (Clause->getClauseKind() == OMPC_schedule)
1823 SC = cast<OMPScheduleClause>(Clause);
1824 else if (Clause->getClauseKind() == OMPC_ordered)
1825 OC = cast<OMPOrderedClause>(Clause);
1826 else if (Clause->getClauseKind() == OMPC_linear)
1827 LCs.push_back(cast<OMPLinearClause>(Clause));
1829 bool ErrorFound =
false;
1836 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
1841 diag::err_omp_schedule_nonmonotonic_ordered)
1846 for (
auto *C : LCs) {
1847 Diag(C->getLocStart(), diag::err_omp_linear_ordered)
3101 if (Stack->getCurScope()) {
3102 auto ParentRegion = Stack->getParentDirective();
3103 auto OffendingRegion = ParentRegion;
3104 bool NestingProhibited =
false;
3105 bool CloseNesting =
true;
3108 ShouldBeInParallelRegion,
3109 ShouldBeInOrderedRegion,
3110 ShouldBeInTargetRegion,
3111 ShouldBeInTeamsRegion
3112 } Recommend = NoRecommend;
3122 SemaRef.
Diag(StartLoc, (CurrentRegion != OMPD_simd)
3123 ? diag::err_omp_prohibited_region_simd
3124 : diag::warn_omp_nesting_simd);
3125 return CurrentRegion != OMPD_simd;
3127 if (ParentRegion == OMPD_atomic) {
3130 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
3133 if (CurrentRegion == OMPD_section) {
3138 if (ParentRegion != OMPD_sections &&
3139 ParentRegion != OMPD_parallel_sections) {
3140 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_section_directive)
3151 if (CurrentRegion == OMPD_cancellation_point ||
3152 CurrentRegion == OMPD_cancel) {
3165 !((CancelRegion == OMPD_parallel &&
3166 (ParentRegion == OMPD_parallel ||
3167 ParentRegion == OMPD_target_parallel)) ||
3168 (CancelRegion == OMPD_for &&
3169 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
3170 ParentRegion == OMPD_target_parallel_for)) ||
3171 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
3172 (CancelRegion == OMPD_sections &&
3173 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
3174 ParentRegion == OMPD_parallel_sections)));
3175 }
else if (CurrentRegion == OMPD_master) {
3181 }
else if (CurrentRegion == OMPD_critical && CurrentName.
getName()) {
3188 Stack->hasDirective([CurrentName, &PreviousCriticalLoc](
3193 if (K == OMPD_critical &&
3195 PreviousCriticalLoc = Loc;
3202 SemaRef.
Diag(StartLoc,
3203 diag::err_omp_prohibited_region_critical_same_name)
3205 if (PreviousCriticalLoc.
isValid())
3206 SemaRef.
Diag(PreviousCriticalLoc,
3207 diag::note_omp_previous_critical_region);
3210 }
else if (CurrentRegion == OMPD_barrier) {
3216 ParentRegion == OMPD_master ||
3217 ParentRegion == OMPD_critical ||
3218 ParentRegion == OMPD_ordered;
3226 ParentRegion == OMPD_master ||
3227 ParentRegion == OMPD_critical ||
3228 ParentRegion == OMPD_ordered;
3229 Recommend = ShouldBeInParallelRegion;
3230 }
else if (CurrentRegion == OMPD_ordered) {
3239 NestingProhibited = ParentRegion == OMPD_critical ||
3242 Stack->isParentOrderedRegion());
3243 Recommend = ShouldBeInOrderedRegion;
3248 NestingProhibited = ParentRegion != OMPD_target;
3249 Recommend = ShouldBeInTargetRegion;
3250 Stack->setParentTeamsRegionLoc(Stack->getConstructLoc());
3259 Recommend = ShouldBeInParallelRegion;
3266 Recommend = ShouldBeInTeamsRegion;
3268 if (!NestingProhibited &&
3275 NestingProhibited = Stack->hasDirective(
3279 OffendingRegion = K;
3285 CloseNesting =
false;
3287 if (NestingProhibited) {
3288 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region)
3300 bool ErrorFound =
false;
3301 unsigned NamedModifiersNumber = 0;
3305 for (
const auto *C : Clauses) {
3306 if (
const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
3310 if (FoundNameModifiers[CurNM]) {
3311 S.
Diag(C->getLocStart(), diag::err_omp_more_one_clause)
3316 NameModifierLoc.push_back(IC->getNameModifierLoc());
3317 ++NamedModifiersNumber;
3319 FoundNameModifiers[CurNM] = IC;
3326 bool MatchFound =
false;
3327 for (
auto NM : AllowedNameModifiers) {
3334 S.
Diag(IC->getNameModifierLoc(),
3335 diag::err_omp_wrong_if_directive_name_modifier)
3343 if (FoundNameModifiers[
OMPD_unknown] && NamedModifiersNumber > 0) {
3344 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
3346 diag::err_omp_no_more_if_clause);
3349 std::string Sep(
", ");
3350 unsigned AllowedCnt = 0;
3351 unsigned TotalAllowedNum =
3352 AllowedNameModifiers.size() - NamedModifiersNumber;
3353 for (
unsigned Cnt = 0,
End = AllowedNameModifiers.size(); Cnt <
End;
3356 if (!FoundNameModifiers[NM]) {
3360 if (AllowedCnt + 2 == TotalAllowedNum)
3362 else if (AllowedCnt + 1 != TotalAllowedNum)
3368 diag::err_omp_unnamed_if_clause)
3369 << (TotalAllowedNum > 1) << Values;
3371 for (
auto Loc : NameModifierLoc) {
3372 S.
Diag(Loc, diag::note_omp_previous_named_if_clause);
3389 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA;
3390 bool ErrorFound =
false;
3391 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
3393 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
3396 DSAAttrChecker DSAChecker(
DSAStack, *
this, cast<CapturedStmt>(AStmt));
3397 DSAChecker.Visit(cast<CapturedStmt>(AStmt)->getCapturedStmt());
3398 if (DSAChecker.isErrorFound())
3401 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
3403 if (!DSAChecker.getImplicitFirstprivate().empty()) {
3407 ClausesWithImplicit.push_back(Implicit);
3408 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
3409 DSAChecker.getImplicitFirstprivate().size();
3420 AllowedNameModifiers.push_back(OMPD_parallel);
3424 VarsWithInheritedDSA);
3428 VarsWithInheritedDSA);
3432 EndLoc, VarsWithInheritedDSA);
3439 assert(ClausesWithImplicit.empty() &&
3440 "No clauses are allowed for 'omp section' directive");
3448 assert(ClausesWithImplicit.empty() &&
3449 "No clauses are allowed for 'omp master' directive");
3456 case OMPD_parallel_for:
3458 EndLoc, VarsWithInheritedDSA);
3459 AllowedNameModifiers.push_back(OMPD_parallel);
3461 case OMPD_parallel_for_simd:
3463 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3464 AllowedNameModifiers.push_back(OMPD_parallel);
3466 case OMPD_parallel_sections:
3469 AllowedNameModifiers.push_back(OMPD_parallel);
3474 AllowedNameModifiers.push_back(OMPD_task);
3476 case OMPD_taskyield:
3477 assert(ClausesWithImplicit.empty() &&
3478 "No clauses are allowed for 'omp taskyield' directive");
3479 assert(AStmt ==
nullptr &&
3480 "No associated statement allowed for 'omp taskyield' directive");
3484 assert(ClausesWithImplicit.empty() &&
3485 "No clauses are allowed for 'omp barrier' directive");
3486 assert(AStmt ==
nullptr &&
3487 "No associated statement allowed for 'omp barrier' directive");
3491 assert(ClausesWithImplicit.empty() &&
3492 "No clauses are allowed for 'omp taskwait' directive");
3493 assert(AStmt ==
nullptr &&
3494 "No associated statement allowed for 'omp taskwait' directive");
3497 case OMPD_taskgroup:
3498 assert(ClausesWithImplicit.empty() &&
3499 "No clauses are allowed for 'omp taskgroup' directive");
3503 assert(AStmt ==
nullptr &&
3504 "No associated statement allowed for 'omp flush' directive");
3522 AllowedNameModifiers.push_back(OMPD_target);
3524 case OMPD_target_parallel:
3527 AllowedNameModifiers.push_back(OMPD_target);
3528 AllowedNameModifiers.push_back(OMPD_parallel);
3530 case OMPD_target_parallel_for:
3532 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3533 AllowedNameModifiers.push_back(OMPD_target);
3534 AllowedNameModifiers.push_back(OMPD_parallel);
3536 case OMPD_cancellation_point:
3537 assert(ClausesWithImplicit.empty() &&
3538 "No clauses are allowed for 'omp cancellation point' directive");
3539 assert(AStmt ==
nullptr &&
"No associated statement allowed for 'omp "
3540 "cancellation point' directive");
3544 assert(AStmt ==
nullptr &&
3545 "No associated statement allowed for 'omp cancel' directive");
3548 AllowedNameModifiers.push_back(OMPD_cancel);
3550 case OMPD_target_data:
3553 AllowedNameModifiers.push_back(OMPD_target_data);
3555 case OMPD_target_enter_data:
3558 AllowedNameModifiers.push_back(OMPD_target_enter_data);
3560 case OMPD_target_exit_data:
3563 AllowedNameModifiers.push_back(OMPD_target_exit_data);
3567 EndLoc, VarsWithInheritedDSA);
3568 AllowedNameModifiers.push_back(OMPD_taskloop);
3570 case OMPD_taskloop_simd:
3572 EndLoc, VarsWithInheritedDSA);
3573 AllowedNameModifiers.push_back(OMPD_taskloop);
3575 case OMPD_distribute:
3577 EndLoc, VarsWithInheritedDSA);
3579 case OMPD_target_update:
3580 assert(!AStmt &&
"Statement is not allowed for target update");
3583 AllowedNameModifiers.push_back(OMPD_target_update);
3585 case OMPD_distribute_parallel_for:
3587 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3588 AllowedNameModifiers.push_back(OMPD_parallel);
3590 case OMPD_distribute_parallel_for_simd:
3592 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3593 AllowedNameModifiers.push_back(OMPD_parallel);
3595 case OMPD_distribute_simd:
3597 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3599 case OMPD_target_parallel_for_simd:
3601 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3602 AllowedNameModifiers.push_back(OMPD_target);
3603 AllowedNameModifiers.push_back(OMPD_parallel);
3605 case OMPD_declare_target:
3606 case OMPD_end_declare_target:
3607 case OMPD_threadprivate:
3608 case OMPD_declare_reduction:
3609 case OMPD_declare_simd:
3610 llvm_unreachable(
"OpenMP Directive is not allowed");
3612 llvm_unreachable(
"Unknown OpenMP directive");
3615 for (
auto P : VarsWithInheritedDSA) {
3616 Diag(
P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
3617 <<
P.first <<
P.second->getSourceRange();
3619 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
3621 if (!AllowedNameModifiers.empty())
3622 ErrorFound =
checkIfClauses(*
this, Kind, Clauses, AllowedNameModifiers) ||
3635 assert(Aligneds.size() == Alignments.size());
3636 assert(Linears.size() == LinModifiers.size());
3637 assert(Linears.size() == Steps.size());
3638 if (!DG || DG.
get().isNull())
3641 if (!DG.
get().isSingleDecl()) {
3642 Diag(SR.
getBegin(), diag::err_omp_single_decl_in_declare_simd);
3645 auto *ADecl = DG.
get().getSingleDecl();
3646 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
3647 ADecl = FTD->getTemplatedDecl();
3651 Diag(ADecl->getLocation(), diag::err_omp_function_expected);
3660 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
3667 llvm::DenseMap<Decl *, Expr *> UniformedArgs;
3668 Expr *UniformedLinearThis =
nullptr;
3669 for (
auto *E : Uniforms) {
3671 if (
auto *DRE = dyn_cast<DeclRefExpr>(E))
3672 if (
auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
3673 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3674 FD->getParamDecl(PVD->getFunctionScopeIndex())
3676 UniformedArgs.insert(std::make_pair(PVD->getCanonicalDecl(),
E));
3679 if (isa<CXXThisExpr>(E)) {
3680 UniformedLinearThis =
E;
3684 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3694 llvm::DenseMap<Decl *, Expr *> AlignedArgs;
3695 Expr *AlignedThis =
nullptr;
3696 for (
auto *E : Aligneds) {
3698 if (
auto *DRE = dyn_cast<DeclRefExpr>(E))
3699 if (
auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3700 auto *CanonPVD = PVD->getCanonicalDecl();
3701 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3702 FD->getParamDecl(PVD->getFunctionScopeIndex())
3706 if (AlignedArgs.count(CanonPVD) > 0) {
3708 << 1 << E->getSourceRange();
3709 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
3710 diag::note_omp_explicit_dsa)
3714 AlignedArgs[CanonPVD] =
E;
3716 .getNonReferenceType()
3717 .getUnqualifiedType()
3718 .getCanonicalType();
3721 Diag(E->
getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
3722 << QTy <<
getLangOpts().CPlusPlus << E->getSourceRange();
3723 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
3728 if (isa<CXXThisExpr>(E)) {
3731 << 2 << E->getSourceRange();
3739 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3746 for (
auto *E : Alignments) {
3749 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
3750 NewAligns.push_back(Align.
get());
3761 llvm::DenseMap<Decl *, Expr *> LinearArgs;
3762 const bool IsUniformedThis = UniformedLinearThis !=
nullptr;
3763 auto MI = LinModifiers.begin();
3764 for (
auto *E : Linears) {
3768 if (
auto *DRE = dyn_cast<DeclRefExpr>(E))
3769 if (
auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3770 auto *CanonPVD = PVD->getCanonicalDecl();
3771 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3772 FD->getParamDecl(PVD->getFunctionScopeIndex())
3776 if (LinearArgs.count(CanonPVD) > 0) {
3780 Diag(LinearArgs[CanonPVD]->getExprLoc(),
3781 diag::note_omp_explicit_dsa)
3786 if (UniformedArgs.count(CanonPVD) > 0) {
3790 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
3791 diag::note_omp_explicit_dsa)
3795 LinearArgs[CanonPVD] =
E;
3801 PVD->getOriginalType());
3805 if (isa<CXXThisExpr>(E)) {
3806 if (UniformedLinearThis) {
3810 << E->getSourceRange();
3811 Diag(UniformedLinearThis->
getExprLoc(), diag::note_omp_explicit_dsa)
3816 UniformedLinearThis =
E;
3825 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3828 Expr *NewStep =
nullptr;
3830 for (
auto *E : Steps) {
3832 if (Step == E || !E) {
3833 NewSteps.push_back(E ? NewStep :
nullptr);
3837 if (
auto *DRE = dyn_cast<DeclRefExpr>(Step))
3838 if (
auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3839 auto *CanonPVD = PVD->getCanonicalDecl();
3840 if (UniformedArgs.count(CanonPVD) == 0) {
3842 << Step->getSourceRange();
3846 CanonPVD->getType()->hasIntegerRepresentation())
3847 NewSteps.push_back(Step);
3850 << Step->getSourceRange();
3863 NewSteps.push_back(NewStep);
3865 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
3867 Uniforms.size(),
const_cast<Expr **
>(Aligneds.data()), Aligneds.size(),
3868 const_cast<Expr **
>(NewAligns.data()), NewAligns.size(),
3869 const_cast<Expr **
>(Linears.data()), Linears.size(),
3870 const_cast<unsigned *
>(LinModifiers.data()), LinModifiers.size(),
3871 NewSteps.data(), NewSteps.size(), SR);
3872 ADecl->addAttr(NewAttr);
3901 class OpenMPIterationSpaceChecker {
3917 Expr *LCRef =
nullptr;
3929 bool TestIsLessOp =
false;
3931 bool TestIsStrictOp =
false;
3933 bool SubtractStep =
false;
3937 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
3940 bool CheckInit(
Stmt *S,
bool EmitDiags =
true);
3943 bool CheckCond(
Expr *S);
3946 bool CheckInc(
Expr *S);
3948 ValueDecl *GetLoopDecl()
const {
return LCDecl; }
3950 Expr *GetLoopDeclRefExpr()
const {
return LCRef; }
3952 SourceRange GetInitSrcRange()
const {
return InitSrcRange; }
3954 SourceRange GetConditionSrcRange()
const {
return ConditionSrcRange; }
3956 SourceRange GetIncrementSrcRange()
const {
return IncrementSrcRange; }
3958 bool ShouldSubtractStep()
const {
return SubtractStep; }
3961 BuildNumIterations(
Scope *S,
const bool LimitedType,
3962 llvm::MapVector<Expr *, DeclRefExpr *> &Captures)
const;
3965 llvm::MapVector<Expr *, DeclRefExpr *> &Captures)
const;
3967 DeclRefExpr *BuildCounterVar(llvm::MapVector<Expr *, DeclRefExpr *> &Captures,
3968 DSAStackTy &DSA)
const;
3971 Expr *BuildPrivateCounterVar()
const;
3975 Expr *BuildCounterStep()
const;
3977 bool Dependent()
const;
3982 bool CheckIncRHS(
Expr *RHS);
3989 bool SetStep(
Expr *NewStep,
bool Subtract);
3992 bool OpenMPIterationSpaceChecker::Dependent()
const {
3994 assert(!LB && !UB && !
Step);
3997 return LCDecl->getType()->isDependentType() ||
3998 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
3999 (
Step &&
Step->isValueDependent());
4002 static Expr *getExprAsWritten(
Expr *E) {
4003 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(E))
4004 E = ExprTemp->getSubExpr();
4006 if (
auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
4007 E = MTE->GetTemporaryExpr();
4009 while (
auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
4010 E = Binder->getSubExpr();
4012 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E))
4013 E = ICE->getSubExprAsWritten();
4017 bool OpenMPIterationSpaceChecker::SetLCDeclAndLB(
ValueDecl *NewLCDecl,
4021 assert(LCDecl ==
nullptr && LB ==
nullptr && LCRef ==
nullptr &&
4022 UB ==
nullptr &&
Step ==
nullptr && !TestIsLessOp && !TestIsStrictOp);
4023 if (!NewLCDecl || !NewLB)
4026 LCRef = NewLCRefExpr;
4027 if (
auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
4029 if ((Ctor->isCopyOrMoveConstructor() ||
4030 Ctor->isConvertingConstructor(
false)) &&
4031 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
4037 bool OpenMPIterationSpaceChecker::SetUB(
Expr *NewUB,
bool LessOp,
bool StrictOp,
4040 assert(LCDecl !=
nullptr && LB !=
nullptr && UB ==
nullptr &&
4041 Step ==
nullptr && !TestIsLessOp && !TestIsStrictOp);
4045 TestIsLessOp = LessOp;
4046 TestIsStrictOp = StrictOp;
4047 ConditionSrcRange = SR;
4052 bool OpenMPIterationSpaceChecker::SetStep(
Expr *NewStep,
bool Subtract) {
4054 assert(LCDecl !=
nullptr && LB !=
nullptr &&
Step ==
nullptr);
4061 SemaRef.PerformOpenMPImplicitIntegerConversion(StepLoc, NewStep);
4064 NewStep = Val.
get();
4081 IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
4083 IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
4084 bool IsConstZero = IsConstant && !Result.getBoolValue();
4085 if (UB && (IsConstZero ||
4086 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
4087 : (IsConstPos || (IsUnsigned && !Subtract))))) {
4089 diag::err_omp_loop_incr_not_compatible)
4090 << LCDecl << TestIsLessOp << NewStep->getSourceRange();
4091 SemaRef.Diag(ConditionLoc,
4092 diag::note_omp_loop_cond_requres_compatible_incr)
4093 << TestIsLessOp << ConditionSrcRange;
4096 if (TestIsLessOp == Subtract) {
4097 NewStep = SemaRef.CreateBuiltinUnaryOp(NewStep->
getExprLoc(), UO_Minus,
4099 Subtract = !Subtract;
4104 SubtractStep = Subtract;
4108 bool OpenMPIterationSpaceChecker::CheckInit(
Stmt *S,
bool EmitDiags) {
4119 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
4123 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
4124 if (!ExprTemp->cleanupsHaveSideEffects())
4125 S = ExprTemp->getSubExpr();
4127 InitSrcRange = S->getSourceRange();
4128 if (
Expr *E = dyn_cast<Expr>(S))
4130 if (
auto BO = dyn_cast<BinaryOperator>(S)) {
4131 if (BO->getOpcode() == BO_Assign) {
4133 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
4134 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
4135 if (
auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
4136 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4137 return SetLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS());
4139 if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
4140 if (ME->isArrow() &&
4141 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
4142 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4145 }
else if (
auto DS = dyn_cast<DeclStmt>(S)) {
4146 if (DS->isSingleDecl()) {
4147 if (
auto Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
4148 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
4151 SemaRef.Diag(S->getLocStart(),
4152 diag::ext_omp_loop_not_canonical_init)
4153 << S->getSourceRange();
4154 return SetLCDeclAndLB(Var,
nullptr, Var->getInit());
4158 }
else if (
auto CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4159 if (CE->getOperator() == OO_Equal) {
4160 auto *LHS = CE->getArg(0);
4161 if (
auto DRE = dyn_cast<DeclRefExpr>(LHS)) {
4162 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
4163 if (
auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
4164 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4165 return SetLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1));
4167 if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
4168 if (ME->isArrow() &&
4169 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
4170 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4175 if (Dependent() || SemaRef.CurContext->isDependentContext())
4178 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init)
4179 << S->getSourceRange();
4189 E = getExprAsWritten(E);
4190 if (
auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
4192 if ((Ctor->isCopyOrMoveConstructor() ||
4193 Ctor->isConvertingConstructor(
false)) &&
4194 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
4196 if (
auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
4197 if (
auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
4198 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
4199 if (
auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
4204 if (
auto *ME = dyn_cast_or_null<MemberExpr>(E))
4205 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
4210 bool OpenMPIterationSpaceChecker::CheckCond(
Expr *S) {
4218 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl;
4221 S = getExprAsWritten(S);
4223 if (
auto BO = dyn_cast<BinaryOperator>(S)) {
4224 if (BO->isRelationalOp()) {
4225 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
4226 return SetUB(BO->getRHS(),
4227 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
4228 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
4229 BO->getSourceRange(), BO->getOperatorLoc());
4230 if (GetInitLCDecl(BO->getRHS()) == LCDecl)
4231 return SetUB(BO->getLHS(),
4232 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
4233 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
4234 BO->getSourceRange(), BO->getOperatorLoc());
4236 }
else if (
auto CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4237 if (CE->getNumArgs() == 2) {
4238 auto Op = CE->getOperator();
4241 case OO_GreaterEqual:
4244 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
4245 return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
4246 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
4247 CE->getOperatorLoc());
4248 if (GetInitLCDecl(CE->getArg(1)) == LCDecl)
4249 return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
4250 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
4251 CE->getOperatorLoc());
4258 if (Dependent() || SemaRef.CurContext->isDependentContext())
4260 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
4261 << S->getSourceRange() << LCDecl;
4265 bool OpenMPIterationSpaceChecker::CheckIncRHS(
Expr *RHS) {
4272 if (
auto BO = dyn_cast<BinaryOperator>(RHS)) {
4273 if (BO->isAdditiveOp()) {
4274 bool IsAdd = BO->getOpcode() == BO_Add;
4275 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
4276 return SetStep(BO->getRHS(), !IsAdd);
4277 if (IsAdd && GetInitLCDecl(BO->getRHS()) == LCDecl)
4278 return SetStep(BO->getLHS(),
false);
4280 }
else if (
auto CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
4281 bool IsAdd = CE->getOperator() == OO_Plus;
4282 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
4283 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
4284 return SetStep(CE->getArg(1), !IsAdd);
4285 if (IsAdd && GetInitLCDecl(CE->getArg(1)) == LCDecl)
4286 return SetStep(CE->getArg(0),
false);
4289 if (Dependent() || SemaRef.CurContext->isDependentContext())
4291 SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr)
4292 << RHS->getSourceRange() << LCDecl;
4296 bool OpenMPIterationSpaceChecker::CheckInc(
Expr *S) {
4311 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
4314 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
4315 if (!ExprTemp->cleanupsHaveSideEffects())
4316 S = ExprTemp->getSubExpr();
4318 IncrementSrcRange = S->getSourceRange();
4320 if (
auto UO = dyn_cast<UnaryOperator>(S)) {
4321 if (UO->isIncrementDecrementOp() &&
4322 GetInitLCDecl(UO->getSubExpr()) == LCDecl)
4324 SemaRef.ActOnIntegerConstant(UO->getLocStart(),
4325 (UO->isDecrementOp() ? -1 : 1)).get(),
4327 }
else if (
auto BO = dyn_cast<BinaryOperator>(S)) {
4328 switch (BO->getOpcode()) {
4331 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
4332 return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
4335 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
4336 return CheckIncRHS(BO->getRHS());
4341 }
else if (
auto CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4342 switch (CE->getOperator()) {
4345 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
4347 SemaRef.ActOnIntegerConstant(
4349 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)).
get(),
4354 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
4355 return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
4358 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
4359 return CheckIncRHS(CE->getArg(1));
4365 if (Dependent() || SemaRef.CurContext->isDependentContext())
4367 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr)
4368 << S->getSourceRange() << LCDecl;
4373 tryBuildCapture(
Sema &SemaRef,
Expr *Capture,
4374 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4381 auto I = Captures.find(Capture);
4382 if (I != Captures.end())
4386 Captures[Capture] = Ref;
4391 Expr *OpenMPIterationSpaceChecker::BuildNumIterations(
4392 Scope *S,
const bool LimitedType,
4393 llvm::MapVector<Expr *, DeclRefExpr *> &Captures)
const {
4395 auto VarType = LCDecl->getType().getNonReferenceType();
4396 if (VarType->isIntegerType() || VarType->isPointerType() ||
4399 auto *UBExpr = TestIsLessOp ? UB : LB;
4400 auto *LBExpr = TestIsLessOp ? LB : UB;
4401 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
4402 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
4403 if (!Upper || !Lower)
4406 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
4408 if (!Diff.
isUsable() && VarType->getAsCXXRecordDecl()) {
4411 SemaRef.
Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx)
4412 << Upper->getSourceRange() << Lower->getSourceRange();
4423 S, DefaultLoc, BO_Sub, Diff.
get(),
4429 auto NewStep = tryBuildCapture(SemaRef,
Step, Captures);
4430 if (!NewStep.isUsable())
4432 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Add, Diff.
get(), NewStep.get());
4442 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Div, Diff.
get(), NewStep.get());
4449 bool UseVarType = VarType->hasIntegerRepresentation() &&
4453 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
4454 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
4456 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
4465 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
4466 if (NewSize != C.getTypeSize(Type)) {
4467 if (NewSize < C.getTypeSize(Type)) {
4468 assert(NewSize == 64 &&
"incorrect loop var size");
4469 SemaRef.
Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
4470 << InitSrcRange << ConditionSrcRange;
4472 QualType NewType = C.getIntTypeForBitwidth(
4474 C.getTypeSize(Type) < NewSize);
4487 Expr *OpenMPIterationSpaceChecker::BuildPreCond(
4489 llvm::MapVector<Expr *, DeclRefExpr *> &Captures)
const {
4494 auto NewLB = tryBuildCapture(SemaRef, LB, Captures);
4495 auto NewUB = tryBuildCapture(SemaRef, UB, Captures);
4496 if (!NewLB.isUsable() || !NewUB.isUsable())
4500 S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
4501 : (TestIsStrictOp ? BO_GT : BO_GE),
4502 NewLB.get(), NewUB.get());
4503 if (CondExpr.isUsable()) {
4512 return CondExpr.isUsable() ? CondExpr.get() : Cond;
4516 DeclRefExpr *OpenMPIterationSpaceChecker::BuildCounterVar(
4517 llvm::MapVector<Expr *, DeclRefExpr *> &Captures, DSAStackTy &DSA)
const {
4518 auto *VD = dyn_cast<
VarDecl>(LCDecl);
4523 DSAStackTy::DSAVarData Data = DSA.getTopDSA(LCDecl,
false);
4527 Captures.insert(std::make_pair(LCRef, Ref));
4534 Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar()
const {
4535 if (LCDecl && !LCDecl->isInvalidDecl()) {
4536 auto Type = LCDecl->getType().getNonReferenceType();
4538 buildVarDecl(SemaRef, DefaultLoc, Type, LCDecl->getName(),
4539 LCDecl->hasAttrs() ? &LCDecl->getAttrs() :
nullptr);
4540 if (PrivateVar->isInvalidDecl())
4551 Expr *OpenMPIterationSpaceChecker::BuildCounterStep()
const {
return Step; }
4554 struct LoopIterationSpace final {
4556 Expr *PreCond =
nullptr;
4559 Expr *NumIterations =
nullptr;
4561 Expr *CounterVar =
nullptr;
4563 Expr *PrivateCounterVar =
nullptr;
4565 Expr *CounterInit =
nullptr;
4568 Expr *CounterStep =
nullptr;
4570 bool Subtract =
false;
4582 assert(
getLangOpts().OpenMP &&
"OpenMP is not active.");
4583 assert(Init &&
"Expected loop in canonical form.");
4584 unsigned AssociatedLoops =
DSAStack->getAssociatedLoops();
4585 if (AssociatedLoops > 0 &&
4587 OpenMPIterationSpaceChecker ISC(*
this, ForLoc);
4588 if (!ISC.CheckInit(Init,
false)) {
4589 if (
auto *D = ISC.GetLoopDecl()) {
4590 auto *VD = dyn_cast<
VarDecl>(D);
4595 auto *Ref =
buildCapture(*
this, D, ISC.GetLoopDeclRefExpr(),
4597 VD = cast<VarDecl>(Ref->getDecl());
4600 DSAStack->addLoopControlVariable(D, VD);
4603 DSAStack->setAssociatedLoops(AssociatedLoops - 1);
4611 unsigned CurrentNestedLoopCount,
unsigned NestedLoopCount,
4612 Expr *CollapseLoopCountExpr,
Expr *OrderedLoopCountExpr,
4613 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA,
4614 LoopIterationSpace &ResultIterSpace,
4615 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4618 auto For = dyn_cast_or_null<ForStmt>(
S);
4620 SemaRef.
Diag(S->getLocStart(), diag::err_omp_not_for)
4621 << (CollapseLoopCountExpr !=
nullptr || OrderedLoopCountExpr !=
nullptr)
4623 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
4624 if (NestedLoopCount > 1) {
4625 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
4626 SemaRef.
Diag(DSA.getConstructLoc(),
4627 diag::note_omp_collapse_ordered_expr)
4628 << 2 << CollapseLoopCountExpr->getSourceRange()
4629 << OrderedLoopCountExpr->getSourceRange();
4630 else if (CollapseLoopCountExpr)
4632 diag::note_omp_collapse_ordered_expr)
4633 << 0 << CollapseLoopCountExpr->getSourceRange();
4636 diag::note_omp_collapse_ordered_expr)
4637 << 1 << OrderedLoopCountExpr->getSourceRange();
4641 assert(For->getBody());
4643 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
4646 auto Init = For->getInit();
4647 if (ISC.CheckInit(Init))
4650 bool HasErrors =
false;
4653 if (
auto *LCDecl = ISC.GetLoopDecl()) {
4654 auto *LoopDeclRefExpr = ISC.GetLoopDeclRefExpr();
4662 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
4663 !VarType->isPointerType() &&
4664 !(SemaRef.
getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
4665 SemaRef.
Diag(Init->getLocStart(), diag::err_omp_loop_variable_type)
4679 VarsWithImplicitDSA.erase(LCDecl);
4689 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl,
false);
4692 auto PredeterminedCKind =
4694 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
4697 DVar.CKind != PredeterminedCKind) ||
4701 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
4702 (DVar.CKind != OMPC_private || DVar.RefExpr !=
nullptr)) {
4703 SemaRef.
Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa)
4706 if (DVar.RefExpr ==
nullptr)
4707 DVar.CKind = PredeterminedCKind;
4710 }
else if (LoopDeclRefExpr !=
nullptr) {
4719 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind);
4725 HasErrors |= ISC.CheckCond(For->getCond());
4728 HasErrors |= ISC.CheckInc(For->getInc());
4735 ResultIterSpace.PreCond =
4736 ISC.BuildPreCond(DSA.getCurScope(), For->getCond(), Captures);
4737 ResultIterSpace.NumIterations = ISC.BuildNumIterations(
4742 ResultIterSpace.CounterVar = ISC.BuildCounterVar(Captures, DSA);
4743 ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar();
4744 ResultIterSpace.CounterInit = ISC.BuildCounterInit();
4745 ResultIterSpace.CounterStep = ISC.BuildCounterStep();
4746 ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange();
4747 ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange();
4748 ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange();
4749 ResultIterSpace.Subtract = ISC.ShouldSubtractStep();
4751 HasErrors |= (ResultIterSpace.PreCond ==
nullptr ||
4752 ResultIterSpace.NumIterations ==
nullptr ||
4753 ResultIterSpace.CounterVar ==
nullptr ||
4754 ResultIterSpace.PrivateCounterVar ==
nullptr ||
4755 ResultIterSpace.CounterInit ==
nullptr ||
4756 ResultIterSpace.CounterStep ==
nullptr);
4765 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4767 auto NewStart = tryBuildCapture(SemaRef, Start.
get(), Captures);
4768 if (!NewStart.isUsable())
4775 if (!NewStart.isUsable())
4780 SemaRef.
BuildBinOp(S, Loc, BO_Assign, VarRef.
get(), NewStart.get());
4789 llvm::MapVector<Expr *, DeclRefExpr *> *Captures =
nullptr) {
4798 NewStep = tryBuildCapture(SemaRef, Step.
get(), *Captures);
4810 NewStart = tryBuildCapture(SemaRef, Start.
get(), *Captures);
4826 SemaRef.
BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
4827 VarRef.
get(), SavedUpdate.
get());
4838 Update = SemaRef.
BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
4839 NewStart.
get(), SavedUpdate.
get());
4851 Update = SemaRef.
BuildBinOp(S, Loc, BO_Assign, VarRef.
get(), Update.
get());
4864 unsigned HasBits = C.getTypeSize(OldType);
4865 if (HasBits >= Bits)
4868 QualType NewType = C.getIntTypeForBitwidth(Bits,
true);
4880 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
4886 SmallVectorImpl<Decl *> &PreInits) {
4887 if (!PreInits.empty()) {
4897 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4898 if (!Captures.empty()) {
4900 for (
auto &Pair : Captures)
4901 PreInits.push_back(Pair.second->getDecl());
4909 Expr *PostUpdate =
nullptr;
4910 if (!PostUpdates.empty()) {
4911 for (
auto *E : PostUpdates) {
4917 PostUpdate = PostUpdate
4932 Expr *OrderedLoopCountExpr,
Stmt *AStmt,
Sema &SemaRef,
4934 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA,
4936 unsigned NestedLoopCount = 1;
4937 if (CollapseLoopCountExpr) {
4941 NestedLoopCount = Result.getLimitedValue();
4943 if (OrderedLoopCountExpr) {
4947 if (Result.getLimitedValue() < NestedLoopCount) {
4949 diag::err_omp_wrong_ordered_loop_count)
4950 << OrderedLoopCountExpr->getSourceRange();
4952 diag::note_collapse_loop_count)
4953 << CollapseLoopCountExpr->getSourceRange();
4955 NestedLoopCount = Result.getLimitedValue();
4960 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
4962 IterSpaces.resize(NestedLoopCount);
4963 Stmt *CurStmt = AStmt->IgnoreContainers(
true);
4964 for (
unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
4966 NestedLoopCount, CollapseLoopCountExpr,
4967 OrderedLoopCountExpr, VarsWithImplicitDSA,
4968 IterSpaces[Cnt], Captures))
4975 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
4978 Built.
clear( NestedLoopCount);
4981 return NestedLoopCount;
5014 auto PreCond =
ExprResult(IterSpaces[0].PreCond);
5015 auto N0 = IterSpaces[0].NumIterations;
5018 N0->IgnoreImpCasts(), N0->getType(),
5024 N0->IgnoreImpCasts(), N0->getType(),
5029 if (!LastIteration32.
isUsable() || !LastIteration64.isUsable())
5030 return NestedLoopCount;
5033 bool AllCountsNeedLessThan32Bits = C.
getTypeSize(N0->getType()) < 32;
5035 Scope *CurScope = DSA.getCurScope();
5036 for (
unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
5037 if (PreCond.isUsable()) {
5039 PreCond.get(), IterSpaces[Cnt].PreCond);
5041 auto N = IterSpaces[Cnt].NumIterations;
5042 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
5050 if (LastIteration64.isUsable())
5062 C.getTypeSize(LastIteration32.
get()->
getType()) == 32 &&
5063 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
5067 LastIteration64.get(), SemaRef)))
5068 LastIteration = LastIteration32;
5100 tryBuildCapture(SemaRef, LastIteration.
get(), Captures);
5101 LastIteration = SaveRef;
5114 ExprResult LB, UB, IL, ST, EUB, PrevLB, PrevUB;
5142 buildVarDecl(SemaRef, InitLoc, StrideVType,
".omp.stride");
5151 UB.
get(), LastIteration.
get());
5153 InitLoc, InitLoc, IsUBGreater.
get(), LastIteration.
get(), UB.
get());
5154 EUB = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, UB.
get(),
5163 auto *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
5167 assert(CD->getNumParams() >= 4 &&
5168 "Unexpected number of parameters in loop combined directive");
5172 auto *PrevLBDecl = CD->getParam(2);
5173 auto *PrevUBDecl = CD->getParam(3);
5195 Init = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, IV.
get(), RHS);
5206 NumIterations.
get());
5215 Inc = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, IV.
get(), Inc.
get());
5248 bool HasErrors =
false;
5249 Built.
Counters.resize(NestedLoopCount);
5250 Built.
Inits.resize(NestedLoopCount);
5251 Built.
Updates.resize(NestedLoopCount);
5252 Built.
Finals.resize(NestedLoopCount);
5257 for (
int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
5258 LoopIterationSpace &IS = IterSpaces[Cnt];
5268 assert((Cnt == (
int)NestedLoopCount - 1) &&
5269 "unusable div expected on first iteration only");
5273 Iter = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.
get(),
5281 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
5283 IS.CounterVar->getExprLoc(),
5286 IS.CounterInit, Captures);
5287 if (!Init.isUsable()) {
5292 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
5293 IS.CounterStep, IS.Subtract, &Captures);
5301 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
5302 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures);
5311 Div = IS.NumIterations;
5313 Div = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.
get(),
5318 Div = tryBuildCapture(SemaRef, Div.
get(), Captures);
5323 LoopMultipliers.push_back(Div.
get());
5330 Built.
Counters[Cnt] = IS.CounterVar;
5332 Built.
Inits[Cnt] = Init.get();
5347 Built.
PreCond = PreCond.get();
5352 Built.
LB = LB.
get();
5353 Built.
UB = UB.
get();
5354 Built.
IL = IL.
get();
5355 Built.
ST = ST.
get();
5357 Built.
NLB = NextLB.
get();
5358 Built.
NUB = NextUB.
get();
5364 for (
auto Pair : DSA.getDoacrossDependClauses()) {
5365 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
5366 Pair.first->setCounterValue(CounterVal);
5368 if (NestedLoopCount != Pair.second.size() ||
5369 NestedLoopCount != LoopMultipliers.size() + 1) {
5371 Pair.first->setCounterValue(CounterVal);
5374 assert(Pair.first->getDependencyKind() == OMPC_DEPEND_sink);
5375 auto I = Pair.second.rbegin();
5376 auto IS = IterSpaces.rbegin();
5377 auto ILM = LoopMultipliers.rbegin();
5378 Expr *UpCounterVal = CounterVal;
5379 Expr *Multiplier =
nullptr;
5380 for (
int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
5382 assert(IS->CounterStep);
5383 Expr *NormalizedOffset =
5385 .
BuildBinOp(CurScope, I->first->getExprLoc(), BO_Div,
5386 I->first, IS->CounterStep)
5391 .
BuildBinOp(CurScope, I->first->getExprLoc(), BO_Mul,
5392 NormalizedOffset, Multiplier)
5395 assert(I->second == OO_Plus || I->second == OO_Minus);
5398 SemaRef.
BuildBinOp(CurScope, I->first->getExprLoc(), BOK,
5399 UpCounterVal, NormalizedOffset).
get();
5406 Pair.first->setCounterValue(UpCounterVal);
5410 return NestedLoopCount;
5414 auto CollapseClauses =
5415 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
5416 if (CollapseClauses.begin() != CollapseClauses.end())
5417 return (*CollapseClauses.begin())->getNumForLoops();
5422 auto OrderedClauses =
5423 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
5424 if (OrderedClauses.begin() != OrderedClauses.end())
5425 return (*OrderedClauses.begin())->getNumForLoops();
5434 for (
auto *Clause : Clauses) {
5435 if (Clause->getClauseKind() == OMPC_safelen)
5436 Safelen = cast<OMPSafelenClause>(Clause);
5437 else if (Clause->getClauseKind() == OMPC_simdlen)
5438 Simdlen = cast<OMPSimdlenClause>(Clause);
5439 if (Safelen && Simdlen)
5443 if (Simdlen && Safelen) {
5444 llvm::APSInt SimdlenRes, SafelenRes;
5447 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
5448 SimdlenLength->isInstantiationDependent() ||
5449 SimdlenLength->containsUnexpandedParameterPack())
5451 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
5452 SafelenLength->isInstantiationDependent() ||
5453 SafelenLength->containsUnexpandedParameterPack())
5456 SafelenLength->EvaluateAsInt(SafelenRes, S.
Context);
5461 if (SimdlenRes > SafelenRes) {
5462 S.
Diag(SimdlenLength->getExprLoc(),
5463 diag::err_omp_wrong_simdlen_safelen_values)
5464 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
5474 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5478 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5484 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
5485 if (NestedLoopCount == 0)
5489 "omp simd loop exprs were not built");
5493 for (
auto C : Clauses) {
5494 if (
auto LC = dyn_cast<OMPLinearClause>(C))
5513 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5517 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5523 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
5524 if (NestedLoopCount == 0)
5528 "omp for loop exprs were not built");
5532 for (
auto C : Clauses) {
5533 if (
auto LC = dyn_cast<OMPLinearClause>(C))
5543 Clauses, AStmt, B,
DSAStack->isCancelRegion());
5549 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5553 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5557 unsigned NestedLoopCount =
5560 VarsWithImplicitDSA, B);
5561 if (NestedLoopCount == 0)
5565 "omp for simd loop exprs were not built");
5569 for (
auto C : Clauses) {
5570 if (
auto LC = dyn_cast<OMPLinearClause>(C))
5593 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5594 auto BaseStmt = AStmt;
5595 while (
CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5596 BaseStmt = CS->getCapturedStmt();
5597 if (
auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5598 auto S = C->children();
5599 if (S.begin() == S.end())
5603 for (
Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5604 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5606 Diag(SectionStmt->getLocStart(),
5607 diag::err_omp_sections_substmt_not_section);
5610 cast<OMPSectionDirective>(SectionStmt)
5611 ->setHasCancel(
DSAStack->isCancelRegion());
5614 Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt);
5630 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5646 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5654 for (
auto *Clause : Clauses) {
5655 if (Clause->getClauseKind() == OMPC_nowait)
5657 else if (Clause->getClauseKind() == OMPC_copyprivate)
5658 Copyprivate = Clause;
5659 if (Copyprivate && Nowait) {
5661 diag::err_omp_single_copyprivate_with_nowait);
5676 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5689 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5691 bool ErrorFound =
false;
5694 bool DependentHint =
false;
5695 for (
auto *C : Clauses) {
5696 if (C->getClauseKind() == OMPC_hint) {
5698 Diag(C->getLocStart(), diag::err_omp_hint_clause_no_name);
5701 Expr *E = cast<OMPHintClause>(C)->getHint();
5704 DependentHint =
true;
5707 HintLoc = C->getLocStart();
5713 auto Pair =
DSAStack->getCriticalWithHint(DirName);
5714 if (Pair.first && DirName.
getName() && !DependentHint) {
5715 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
5716 Diag(StartLoc, diag::err_omp_critical_with_hint);
5718 Diag(HintLoc, diag::note_omp_critical_hint_here)
5719 << 0 << Hint.toString(10,
false);
5721 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
5722 if (
auto *C = Pair.first->getSingleClause<
OMPHintClause>()) {
5723 Diag(C->getLocStart(), diag::note_omp_critical_hint_here)
5725 << C->getHint()->EvaluateKnownConstInt(
Context).toString(
5728 Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1;
5736 if (!Pair.first && DirName.
getName() && !DependentHint)
5737 DSAStack->addCriticalWithHint(Dir, Hint);
5744 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5759 unsigned NestedLoopCount =
5762 VarsWithImplicitDSA, B);
5763 if (NestedLoopCount == 0)
5767 "omp parallel for loop exprs were not built");
5771 for (
auto C : Clauses) {
5772 if (
auto LC = dyn_cast<OMPLinearClause>(C))
5782 NestedLoopCount, Clauses, AStmt, B,
5789 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5804 unsigned NestedLoopCount =
5807 VarsWithImplicitDSA, B);
5808 if (NestedLoopCount == 0)
5813 for (
auto C : Clauses) {
5814 if (
auto LC = dyn_cast<OMPLinearClause>(C))
5827 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
5837 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5838 auto BaseStmt = AStmt;
5839 while (
CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5840 BaseStmt = CS->getCapturedStmt();
5841 if (
auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5842 auto S = C->children();
5843 if (S.begin() == S.end())
5847 for (
Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5848 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5850 Diag(SectionStmt->getLocStart(),
5851 diag::err_omp_parallel_sections_substmt_not_section);
5854 cast<OMPSectionDirective>(SectionStmt)
5855 ->setHasCancel(
DSAStack->isCancelRegion());
5858 Diag(AStmt->getLocStart(),
5859 diag::err_omp_parallel_sections_not_compound_stmt);
5866 Context, StartLoc, EndLoc, Clauses, AStmt,
DSAStack->isCancelRegion());
5910 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5920 assert(Clauses.size() <= 1 &&
"Extra clauses in flush directive");
5929 OMPClause *DependSourceClause =
nullptr;
5931 bool ErrorFound =
false;
5934 for (
auto *C : Clauses) {
5935 if (
auto *DC = dyn_cast<OMPDependClause>(C)) {
5937 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
5938 if (DependSourceClause) {
5939 Diag(C->getLocStart(), diag::err_omp_more_one_clause)
5944 DependSourceClause = C;
5945 if (DependSinkClause) {
5946 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5950 }
else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
5951 if (DependSourceClause) {
5952 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5956 DependSinkClause = C;
5958 }
else if (C->getClauseKind() == OMPC_threads)
5959 TC = cast<OMPThreadsClause>(C);
5960 else if (C->getClauseKind() == OMPC_simd)
5961 SC = cast<OMPSIMDClause>(C);
5963 if (!ErrorFound && !SC &&
5968 Diag(StartLoc, diag::err_omp_prohibited_region_simd);
5970 }
else if (DependFound && (TC || SC)) {
5971 Diag(DependFound->
getLocStart(), diag::err_omp_depend_clause_thread_simd)
5974 }
else if (DependFound && !
DSAStack->getParentOrderedRegionParam()) {
5976 diag::err_omp_ordered_directive_without_param);
5978 }
else if (TC || Clauses.empty()) {
5979 if (
auto *Param =
DSAStack->getParentOrderedRegionParam()) {
5981 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
5983 Diag(Param->getLocStart(), diag::note_omp_ordered_param);
5987 if ((!AStmt && !DependFound) || ErrorFound)
5991 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6002 class OpenMPAtomicUpdateChecker {
6004 enum ExprAnalysisErrorCode {
6008 NotABinaryOrUnaryExpression,
6010 NotAnUnaryIncDecExpression,
6016 NotABinaryExpression,
6022 NotAnUpdateExpression,
6040 bool IsXLHSInRHSPart;
6045 bool IsPostfixUpdate;
6048 OpenMPAtomicUpdateChecker(
Sema &SemaRef)
6049 : SemaRef(SemaRef),
X(nullptr), E(nullptr), UpdateExpr(nullptr),
6050 IsXLHSInRHSPart(
false), Op(BO_PtrMemD), IsPostfixUpdate(
false) {}
6058 bool checkStatement(
Stmt *S,
unsigned DiagId = 0,
unsigned NoteId = 0);
6060 Expr *getX()
const {
return X; }
6062 Expr *getExpr()
const {
return E; }
6066 Expr *getUpdateExpr()
const {
return UpdateExpr; }
6069 bool isXLHSInRHSPart()
const {
return IsXLHSInRHSPart; }
6073 bool isPostfixUpdate()
const {
return IsPostfixUpdate; }
6076 bool checkBinaryOperation(
BinaryOperator *AtomicBinOp,
unsigned DiagId = 0,
6077 unsigned NoteId = 0);
6081 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
6083 ExprAnalysisErrorCode ErrorFound = NoError;
6089 if (AtomicBinOp->
getOpcode() == BO_Assign) {
6091 if (
auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
6093 if (AtomicInnerBinOp->isMultiplicativeOp() ||
6094 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
6095 AtomicInnerBinOp->isBitwiseOp()) {
6096 Op = AtomicInnerBinOp->getOpcode();
6097 OpLoc = AtomicInnerBinOp->getOperatorLoc();
6098 auto *LHS = AtomicInnerBinOp->getLHS();
6099 auto *RHS = AtomicInnerBinOp->getRHS();
6100 llvm::FoldingSetNodeID XId, LHSId, RHSId;
6103 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.
getASTContext(),
6109 IsXLHSInRHSPart =
true;
6110 }
else if (XId == RHSId) {
6112 IsXLHSInRHSPart =
false;
6114 ErrorLoc = AtomicInnerBinOp->getExprLoc();
6115 ErrorRange = AtomicInnerBinOp->getSourceRange();
6116 NoteLoc =
X->getExprLoc();
6117 NoteRange =
X->getSourceRange();
6118 ErrorFound = NotAnUpdateExpression;
6121 ErrorLoc = AtomicInnerBinOp->getExprLoc();
6122 ErrorRange = AtomicInnerBinOp->getSourceRange();
6123 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
6125 ErrorFound = NotABinaryOperator;
6129 NoteRange = ErrorRange = AtomicBinOp->
getRHS()->getSourceRange();
6130 ErrorFound = NotABinaryExpression;
6134 ErrorRange = AtomicBinOp->getSourceRange();
6137 ErrorFound = NotAnAssignmentOp;
6139 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
6140 SemaRef.
Diag(ErrorLoc, DiagId) << ErrorRange;
6141 SemaRef.
Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
6144 E =
X = UpdateExpr =
nullptr;
6145 return ErrorFound != NoError;
6148 bool OpenMPAtomicUpdateChecker::checkStatement(
Stmt *S,
unsigned DiagId,
6150 ExprAnalysisErrorCode ErrorFound = NoError;
6161 if (
auto *AtomicBody = dyn_cast<Expr>(S)) {
6162 AtomicBody = AtomicBody->IgnoreParenImpCasts();
6163 if (AtomicBody->getType()->isScalarType() ||
6164 AtomicBody->isInstantiationDependent()) {
6165 if (
auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
6166 AtomicBody->IgnoreParenImpCasts())) {
6169 AtomicCompAssignOp->getOpcode());
6170 OpLoc = AtomicCompAssignOp->getOperatorLoc();
6171 E = AtomicCompAssignOp->getRHS();
6172 X = AtomicCompAssignOp->getLHS();
6173 IsXLHSInRHSPart =
true;
6174 }
else if (
auto *AtomicBinOp = dyn_cast<BinaryOperator>(
6175 AtomicBody->IgnoreParenImpCasts())) {
6177 if(checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
6179 }
else if (
auto *AtomicUnaryOp =
6180 dyn_cast<UnaryOperator>(AtomicBody->IgnoreParenImpCasts())) {
6182 if (AtomicUnaryOp->isIncrementDecrementOp()) {
6183 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
6184 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
6185 OpLoc = AtomicUnaryOp->getOperatorLoc();
6186 X = AtomicUnaryOp->getSubExpr();
6188 IsXLHSInRHSPart =
true;
6190 ErrorFound = NotAnUnaryIncDecExpression;
6191 ErrorLoc = AtomicUnaryOp->getExprLoc();
6192 ErrorRange = AtomicUnaryOp->getSourceRange();
6193 NoteLoc = AtomicUnaryOp->getOperatorLoc();
6196 }
else if (!AtomicBody->isInstantiationDependent()) {
6197 ErrorFound = NotABinaryOrUnaryExpression;
6198 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
6199 NoteRange = ErrorRange = AtomicBody->getSourceRange();
6202 ErrorFound = NotAScalarType;
6203 NoteLoc = ErrorLoc = AtomicBody->getLocStart();
6204 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
6207 ErrorFound = NotAnExpression;
6208 NoteLoc = ErrorLoc = S->getLocStart();
6209 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
6211 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
6212 SemaRef.
Diag(ErrorLoc, DiagId) << ErrorRange;
6213 SemaRef.
Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
6216 E =
X = UpdateExpr =
nullptr;
6217 if (ErrorFound == NoError && E &&
X) {
6227 IsXLHSInRHSPart ? OVEExpr : OVEX);
6228 if (Update.isInvalid())
6232 if (Update.isInvalid())
6234 UpdateExpr = Update.
get();
6236 return ErrorFound != NoError;
6246 auto CS = cast<CapturedStmt>(AStmt);
6254 for (
auto *C : Clauses) {
6255 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
6256 C->getClauseKind() == OMPC_update ||
6257 C->getClauseKind() == OMPC_capture) {
6259 Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses)
6261 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
6264 AtomicKind = C->getClauseKind();
6265 AtomicKindLoc = C->getLocStart();
6270 auto Body = CS->getCapturedStmt();
6271 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Body))
6272 Body = EWC->getSubExpr();
6278 bool IsXLHSInRHSPart =
false;
6279 bool IsPostfixUpdate =
false;
6302 if (AtomicKind == OMPC_read) {
6309 } ErrorFound = NoError;
6314 if (
auto AtomicBody = dyn_cast<Expr>(Body)) {
6317 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
6323 auto NotLValueExpr = X->
isLValue() ? V :
X;
6324 ErrorFound = NotAnLValue;
6326 ErrorRange = AtomicBinOp->getSourceRange();
6327 NoteLoc = NotLValueExpr->getExprLoc();
6328 NoteRange = NotLValueExpr->getSourceRange();
6332 auto NotScalarExpr =
6336 ErrorFound = NotAScalarType;
6338 ErrorRange = AtomicBinOp->getSourceRange();
6339 NoteLoc = NotScalarExpr->getExprLoc();
6340 NoteRange = NotScalarExpr->getSourceRange();
6342 }
else if (!AtomicBody->isInstantiationDependent()) {
6343 ErrorFound = NotAnAssignmentOp;
6344 ErrorLoc = AtomicBody->getExprLoc();
6345 ErrorRange = AtomicBody->getSourceRange();
6347 : AtomicBody->getExprLoc();
6348 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6349 : AtomicBody->getSourceRange();
6352 ErrorFound = NotAnExpression;
6353 NoteLoc = ErrorLoc = Body->getLocStart();
6354 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
6356 if (ErrorFound != NoError) {
6357 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
6359 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6364 }
else if (AtomicKind == OMPC_write) {
6371 } ErrorFound = NoError;
6376 if (
auto AtomicBody = dyn_cast<Expr>(Body)) {
6379 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
6380 X = AtomicBinOp->
getLHS();
6381 E = AtomicBinOp->
getRHS();
6385 ErrorFound = NotAnLValue;
6387 ErrorRange = AtomicBinOp->getSourceRange();
6389 NoteRange = X->getSourceRange();
6393 auto NotScalarExpr =
6397 ErrorFound = NotAScalarType;
6399 ErrorRange = AtomicBinOp->getSourceRange();
6400 NoteLoc = NotScalarExpr->getExprLoc();
6401 NoteRange = NotScalarExpr->getSourceRange();
6403 }
else if (!AtomicBody->isInstantiationDependent()) {
6404 ErrorFound = NotAnAssignmentOp;
6405 ErrorLoc = AtomicBody->getExprLoc();
6406 ErrorRange = AtomicBody->getSourceRange();
6408 : AtomicBody->getExprLoc();
6409 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6410 : AtomicBody->getSourceRange();
6413 ErrorFound = NotAnExpression;
6414 NoteLoc = ErrorLoc = Body->getLocStart();
6415 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
6417 if (ErrorFound != NoError) {
6418 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
6420 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6425 }
else if (AtomicKind == OMPC_update || AtomicKind ==
OMPC_unknown) {
6434 OpenMPAtomicUpdateChecker Checker(*
this);
6435 if (Checker.checkStatement(
6436 Body, (AtomicKind == OMPC_update)
6437 ? diag::err_omp_atomic_update_not_expression_statement
6438 : diag::err_omp_atomic_not_expression_statement,
6439 diag::note_omp_atomic_update))
6442 E = Checker.getExpr();
6444 UE = Checker.getUpdateExpr();
6445 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6447 }
else if (AtomicKind == OMPC_capture) {
6450 NotACompoundStatement,
6451 NotTwoSubstatements,
6452 NotASpecificExpression,
6454 } ErrorFound = NoError;
6457 if (
auto *AtomicBody = dyn_cast<Expr>(Body)) {
6468 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
6469 V = AtomicBinOp->
getLHS();
6471 OpenMPAtomicUpdateChecker Checker(*
this);
6472 if (Checker.checkStatement(
6473 Body, diag::err_omp_atomic_capture_not_expression_statement,
6474 diag::note_omp_atomic_update))
6476 E = Checker.getExpr();
6478 UE = Checker.getUpdateExpr();
6479 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6480 IsPostfixUpdate = Checker.isPostfixUpdate();
6481 }
else if (!AtomicBody->isInstantiationDependent()) {
6482 ErrorLoc = AtomicBody->getExprLoc();
6483 ErrorRange = AtomicBody->getSourceRange();
6485 : AtomicBody->getExprLoc();
6486 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6487 : AtomicBody->getSourceRange();
6488 ErrorFound = NotAnAssignmentOp;
6490 if (ErrorFound != NoError) {
6491 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
6493 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6496 UE = V = E = X =
nullptr;
6515 if (
auto *CS = dyn_cast<CompoundStmt>(Body)) {
6517 if (CS->size() == 2) {
6518 auto *First = CS->body_front();
6519 auto *Second = CS->body_back();
6520 if (
auto *EWC = dyn_cast<ExprWithCleanups>(First))
6522 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Second))
6525 OpenMPAtomicUpdateChecker Checker(*
this);
6526 bool IsUpdateExprFound = !Checker.checkStatement(Second);
6528 if (IsUpdateExprFound) {
6530 IsUpdateExprFound = BinOp && BinOp->
getOpcode() == BO_Assign;
6542 llvm::FoldingSetNodeID XId, PossibleXId;
6543 Checker.getX()->Profile(XId,
Context,
true);
6544 PossibleX->Profile(PossibleXId,
Context,
true);
6545 IsUpdateExprFound = XId == PossibleXId;
6546 if (IsUpdateExprFound) {
6549 E = Checker.getExpr();
6550 UE = Checker.getUpdateExpr();
6551 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6552 IsPostfixUpdate =
true;
6555 if (!IsUpdateExprFound) {
6556 IsUpdateExprFound = !Checker.checkStatement(First);
6558 if (IsUpdateExprFound) {
6560 IsUpdateExprFound = BinOp && BinOp->
getOpcode() == BO_Assign;
6572 llvm::FoldingSetNodeID XId, PossibleXId;
6573 Checker.getX()->Profile(XId,
Context,
true);
6574 PossibleX->Profile(PossibleXId,
Context,
true);
6575 IsUpdateExprFound = XId == PossibleXId;
6576 if (IsUpdateExprFound) {
6579 E = Checker.getExpr();
6580 UE = Checker.getUpdateExpr();
6581 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6582 IsPostfixUpdate =
false;
6586 if (!IsUpdateExprFound) {
6588 auto *FirstExpr = dyn_cast<
Expr>(First);
6589 auto *SecondExpr = dyn_cast<
Expr>(Second);
6590 if (!FirstExpr || !SecondExpr ||
6591 !(FirstExpr->isInstantiationDependent() ||
6592 SecondExpr->isInstantiationDependent())) {
6594 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
6595 ErrorFound = NotAnAssignmentOp;
6596 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
6597 : First->getLocStart();
6598 NoteRange = ErrorRange = FirstBinOp
6599 ? FirstBinOp->getSourceRange()
6603 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
6604 ErrorFound = NotAnAssignmentOp;
6605 NoteLoc = ErrorLoc = SecondBinOp
6606 ? SecondBinOp->getOperatorLoc()
6607 : Second->getLocStart();
6608 NoteRange = ErrorRange =
6609 SecondBinOp ? SecondBinOp->getSourceRange()
6612 auto *PossibleXRHSInFirst =
6613 FirstBinOp->getRHS()->IgnoreParenImpCasts();
6614 auto *PossibleXLHSInSecond =
6615 SecondBinOp->getLHS()->IgnoreParenImpCasts();
6616 llvm::FoldingSetNodeID X1Id, X2Id;
6617 PossibleXRHSInFirst->Profile(X1Id,
Context,
6619 PossibleXLHSInSecond->Profile(X2Id,
Context,
6621 IsUpdateExprFound = X1Id == X2Id;
6622 if (IsUpdateExprFound) {
6623 V = FirstBinOp->getLHS();
6624 X = SecondBinOp->getLHS();
6625 E = SecondBinOp->getRHS();
6627 IsXLHSInRHSPart =
false;
6628 IsPostfixUpdate =
true;
6630 ErrorFound = NotASpecificExpression;
6631 ErrorLoc = FirstBinOp->getExprLoc();
6632 ErrorRange = FirstBinOp->getSourceRange();
6633 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
6634 NoteRange = SecondBinOp->getRHS()->getSourceRange();
6641 NoteLoc = ErrorLoc = Body->getLocStart();
6642 NoteRange = ErrorRange =
6643 SourceRange(Body->getLocStart(), Body->getLocStart());
6644 ErrorFound = NotTwoSubstatements;
6647 NoteLoc = ErrorLoc = Body->getLocStart();
6648 NoteRange = ErrorRange =
6649 SourceRange(Body->getLocStart(), Body->getLocStart());
6650 ErrorFound = NotACompoundStatement;
6652 if (ErrorFound != NoError) {
6653 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
6655 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6658 UE = V = E = X =
nullptr;
6666 X, V, E, UE, IsXLHSInRHSPart,
6689 if (
DSAStack->hasInnerTeamsRegion()) {
6690 auto S = AStmt->IgnoreContainers(
true);
6691 bool OMPTeamsFound =
true;
6692 if (
auto *CS = dyn_cast<CompoundStmt>(S)) {
6693 auto I = CS->body_begin();
6694 while (I != CS->body_end()) {
6697 OMPTeamsFound =
false;
6702 assert(I != CS->body_end() &&
"Not found statement");
6708 if (!OMPTeamsFound) {
6709 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
6711 diag::note_omp_nested_teams_construct_here);
6712 Diag(S->getLocStart(), diag::note_omp_nested_statement_here)
6713 << isa<OMPExecutableDirective>(S);
6747 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6762 unsigned NestedLoopCount =
6765 VarsWithImplicitDSA, B);
6766 if (NestedLoopCount == 0)
6770 "omp target parallel for loop exprs were not built");
6774 for (
auto C : Clauses) {
6775 if (
auto LC = dyn_cast<OMPLinearClause>(C))
6785 NestedLoopCount, Clauses, AStmt,
6793 if (*I !=
nullptr && (*I)->getClauseKind() == OMPC_map) {
6808 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6813 Diag(StartLoc, diag::err_omp_no_map_for_directive) <<
6831 Diag(StartLoc, diag::err_omp_no_map_for_directive)
6847 Diag(StartLoc, diag::err_omp_no_map_for_directive)
6858 bool seenMotionClause =
false;
6859 for (
auto *C : Clauses) {
6860 if (C->getClauseKind() == OMPC_to || C->getClauseKind() == OMPC_from)
6861 seenMotionClause =
true;
6863 if (!seenMotionClause) {
6864 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
6893 if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for &&
6894 CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) {
6895 Diag(StartLoc, diag::err_omp_wrong_cancel_region)
6899 if (
DSAStack->isParentNowaitRegion()) {
6900 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
6903 if (
DSAStack->isParentOrderedRegion()) {
6904 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
6915 if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for &&
6916 CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) {
6917 Diag(StartLoc, diag::err_omp_wrong_cancel_region)
6921 if (
DSAStack->isParentNowaitRegion()) {
6922 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
6925 if (
DSAStack->isParentOrderedRegion()) {
6926 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
6929 DSAStack->setParentCancelRegion(
true);
6937 bool ErrorFound =
false;
6938 for (
auto *C : Clauses) {
6939 if (C->getClauseKind() == OMPC_grainsize ||
6940 C->getClauseKind() == OMPC_num_tasks) {
6943 else if (PrevClause->
getClauseKind() != C->getClauseKind()) {
6944 S.
Diag(C->getLocStart(),
6945 diag::err_omp_grainsize_num_tasks_mutually_exclusive)
6949 diag::note_omp_previous_grainsize_num_tasks)
6961 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6965 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6969 unsigned NestedLoopCount =
6972 VarsWithImplicitDSA, B);
6973 if (NestedLoopCount == 0)
6977 "omp for loop exprs were not built");
6987 NestedLoopCount, Clauses, AStmt, B);
6993 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6997 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
7001 unsigned NestedLoopCount =
7004 VarsWithImplicitDSA, B);
7005 if (NestedLoopCount == 0)
7009 "omp for loop exprs were not built");
7013 for (
auto C : Clauses) {
7014 if (
auto LC = dyn_cast<OMPLinearClause>(C))
7030 NestedLoopCount, Clauses, AStmt, B);
7036 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7040 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
7044 unsigned NestedLoopCount =
7047 *
this, *
DSAStack, VarsWithImplicitDSA, B);
7048 if (NestedLoopCount == 0)
7052 "omp for loop exprs were not built");
7056 NestedLoopCount, Clauses, AStmt, B);
7062 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7080 VarsWithImplicitDSA, B);
7081 if (NestedLoopCount == 0)
7085 "omp for loop exprs were not built");
7089 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7095 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7113 VarsWithImplicitDSA, B);
7114 if (NestedLoopCount == 0)
7118 "omp for loop exprs were not built");
7125 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7131 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7146 unsigned NestedLoopCount =
7149 *
this, *
DSAStack, VarsWithImplicitDSA, B);
7150 if (NestedLoopCount == 0)
7154 "omp for loop exprs were not built");
7161 NestedLoopCount, Clauses, AStmt, B);
7167 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7185 VarsWithImplicitDSA, B);
7186 if (NestedLoopCount == 0)
7190 "omp target parallel for simd loop exprs were not built");
7194 for (
auto C : Clauses) {
7195 if (
auto LC = dyn_cast<OMPLinearClause>(C))
7207 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7219 case OMPC_num_threads:
7237 case OMPC_num_teams:
7240 case OMPC_thread_limit:
7246 case OMPC_grainsize:
7249 case OMPC_num_tasks:
7257 case OMPC_proc_bind:
7260 case OMPC_firstprivate:
7261 case OMPC_lastprivate:
7263 case OMPC_reduction:
7267 case OMPC_copyprivate:
7270 case OMPC_mergeable:
7283 case OMPC_dist_schedule:
7284 case OMPC_defaultmap:
7289 case OMPC_use_device_ptr:
7290 case OMPC_is_device_ptr:
7291 llvm_unreachable(
"Clause is not allowed.");
7302 Expr *ValExpr = Condition;
7314 NameModifierLoc, ColonLoc, EndLoc);
7321 Expr *ValExpr = Condition;
7341 IntConvertDiagnoser()
7345 return S.
Diag(Loc, diag::err_omp_not_integral) << T;
7349 return S.
Diag(Loc, diag::err_omp_incomplete_type) << T;
7354 return S.
Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
7358 return S.
Diag(Conv->getLocation(), diag::note_omp_conversion_here)
7363 return S.
Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
7367 return S.
Diag(Conv->getLocation(), diag::note_omp_conversion_here)
7372 llvm_unreachable(
"conversion functions are permitted");
7380 bool StrictlyPositive) {
7389 ValExpr = Value.
get();
7393 Result.isSigned() &&
7394 !((!StrictlyPositive && Result.isNonNegative()) ||
7395 (StrictlyPositive && Result.isStrictlyPositive()))) {
7396 SemaRef.
Diag(Loc, diag::err_omp_negative_expression_in_clause)
7398 << ValExpr->getSourceRange();
7409 Expr *ValExpr = NumThreads;
7423 bool StrictlyPositive) {
7433 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
7434 (!StrictlyPositive && !Result.isNonNegative())) {
7435 Diag(E->
getExprLoc(), diag::err_omp_negative_expression_in_clause)
7437 << E->getSourceRange();
7440 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
7442 << E->getSourceRange();
7445 if (CKind == OMPC_collapse &&
DSAStack->getAssociatedLoops() == 1)
7446 DSAStack->setAssociatedLoops(Result.getExtValue());
7447 else if (CKind == OMPC_ordered)
7448 DSAStack->setAssociatedLoops(Result.getExtValue());
7458 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
7471 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
7488 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
7498 Expr *NumForLoops) {
7504 if (NumForLoops && LParenLoc.
isValid()) {
7506 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
7509 NumForLoops = NumForLoopsResult.
get();
7511 NumForLoops =
nullptr;
7512 DSAStack->setOrderedRegion(
true, NumForLoops);
7525 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
7527 case OMPC_proc_bind:
7529 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
7534 case OMPC_num_threads:
7540 case OMPC_firstprivate:
7541 case OMPC_lastprivate:
7543 case OMPC_reduction:
7547 case OMPC_copyprivate:
7551 case OMPC_mergeable:
7564 case OMPC_num_teams:
7565 case OMPC_thread_limit:
7567 case OMPC_grainsize:
7569 case OMPC_num_tasks:
7571 case OMPC_dist_schedule:
7572 case OMPC_defaultmap:
7577 case OMPC_use_device_ptr:
7578 case OMPC_is_device_ptr:
7579 llvm_unreachable(
"Clause is not allowed.");
7588 unsigned Bound = Last >= 2 ? Last - 2 : 0;
7589 unsigned Skipped = Exclude.size();
7590 auto S = Exclude.begin(), E = Exclude.end();
7591 for (
unsigned i = First; i <
Last; ++i) {
7592 if (std::find(S, E, i) != E) {
7599 if (i == Bound - Skipped)
7601 else if (i != Bound + 1 - Skipped)
7614 "OMPC_DEFAULT_unknown not greater than 0");
7615 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
7622 case OMPC_DEFAULT_none:
7623 DSAStack->setDefaultDSANone(KindKwLoc);
7625 case OMPC_DEFAULT_shared:
7626 DSAStack->setDefaultDSAShared(KindKwLoc);
7629 llvm_unreachable(
"Clause kind is not allowed.");
7642 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
7660 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
7661 assert(Argument.size() == NumberOfElements &&
7662 ArgumentLoc.size() == NumberOfElements);
7664 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
7665 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
7666 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
7667 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
7668 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
7671 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
7673 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
7676 case OMPC_dist_schedule:
7678 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
7679 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
7681 case OMPC_defaultmap:
7684 static_cast<OpenMPDefaultmapClauseModifier>(Argument[
Modifier]),
7685 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
7686 StartLoc, LParenLoc, ArgumentLoc[Modifier],
7687 ArgumentLoc[DefaultmapKind], EndLoc);
7690 case OMPC_num_threads:
7695 case OMPC_proc_bind:
7697 case OMPC_firstprivate:
7698 case OMPC_lastprivate:
7700 case OMPC_reduction:
7704 case OMPC_copyprivate:
7708 case OMPC_mergeable:
7721 case OMPC_num_teams:
7722 case OMPC_thread_limit:
7724 case OMPC_grainsize:
7726 case OMPC_num_tasks:
7732 case OMPC_use_device_ptr:
7733 case OMPC_is_device_ptr:
7734 llvm_unreachable(
"Clause is not allowed.");
7745 Excluded.push_back(M2);
7746 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
7747 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
7748 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
7749 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
7750 S.
Diag(M1Loc, diag::err_omp_unexpected_clause_value)
7773 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
7774 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
7775 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
7776 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
7777 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
7793 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
7800 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
7801 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
7802 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
7803 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
7804 diag::err_omp_schedule_nonmonotonic_static);
7807 Expr *ValExpr = ChunkSize;
7808 Stmt *HelperValStmt =
nullptr;
7819 ValExpr = Val.
get();
7826 if (Result.isSigned() && !Result.isStrictlyPositive()) {
7827 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
7828 <<
"schedule" << 1 << ChunkSize->getSourceRange();
7831 }
else if (isParallelOrTaskRegion(
DSAStack->getCurrentDirective()) &&
7833 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
7834 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
7842 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
7859 case OMPC_mergeable:
7888 case OMPC_num_threads:
7894 case OMPC_firstprivate:
7895 case OMPC_lastprivate:
7897 case OMPC_reduction:
7901 case OMPC_copyprivate:
7903 case OMPC_proc_bind:
7909 case OMPC_num_teams:
7910 case OMPC_thread_limit:
7912 case OMPC_grainsize:
7913 case OMPC_num_tasks:
7915 case OMPC_dist_schedule:
7916 case OMPC_defaultmap:
7921 case OMPC_use_device_ptr:
7922 case OMPC_is_device_ptr:
7923 llvm_unreachable(
"Clause is not allowed.");
7997 case OMPC_firstprivate:
8000 case OMPC_lastprivate:
8006 case OMPC_reduction:
8008 EndLoc, ReductionIdScopeSpec, ReductionId);
8012 LinKind, DepLinMapLoc, ColonLoc, EndLoc);
8021 case OMPC_copyprivate:
8029 StartLoc, LParenLoc, EndLoc);
8033 DepLinMapLoc, ColonLoc, VarList, StartLoc,
8042 case OMPC_use_device_ptr:
8045 case OMPC_is_device_ptr:
8050 case OMPC_num_threads:
8055 case OMPC_proc_bind:
8060 case OMPC_mergeable:
8070 case OMPC_num_teams:
8071 case OMPC_thread_limit:
8073 case OMPC_grainsize:
8075 case OMPC_num_tasks:
8077 case OMPC_dist_schedule:
8078 case OMPC_defaultmap:
8081 llvm_unreachable(
"Clause is not allowed.");
8105 static std::pair<ValueDecl *, bool>
8107 SourceRange &ERange,
bool AllowArraySection =
false) {
8110 return std::make_pair(
nullptr,
true);
8122 } IsArrayExpr = NoArrayExpr;
8123 if (AllowArraySection) {
8124 if (
auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
8125 auto *
Base = ASE->getBase()->IgnoreParenImpCasts();
8126 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base))
8127 Base = TempASE->getBase()->IgnoreParenImpCasts();
8129 IsArrayExpr = ArraySubscript;
8130 }
else if (
auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
8131 auto *
Base = OASE->getBase()->IgnoreParenImpCasts();
8132 while (
auto *TempOASE = dyn_cast<OMPArraySectionExpr>(
Base))
8133 Base = TempOASE->getBase()->IgnoreParenImpCasts();
8134 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base))
8135 Base = TempASE->getBase()->IgnoreParenImpCasts();
8137 IsArrayExpr = OMPArraySection;
8141 ERange = RefExpr->getSourceRange();
8143 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
8144 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
8145 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
8147 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
8148 !isa<FieldDecl>(ME->getMemberDecl()))) {
8149 if (IsArrayExpr != NoArrayExpr)
8150 S.
Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
8155 ? diag::err_omp_expected_var_name_member_expr_or_array_item
8156 : diag::err_omp_expected_var_name_member_expr)
8159 return std::make_pair(
nullptr,
false);
8161 return std::make_pair(DE ? DE->getDecl() : ME->getMemberDecl(),
false);
8170 for (
auto &RefExpr : VarList) {
8171 assert(RefExpr &&
"NULL expr in OpenMP private clause.");
8174 Expr *SimpleRefExpr = RefExpr;
8178 Vars.push_back(RefExpr);
8179 PrivateCopies.push_back(
nullptr);
8186 auto *VD = dyn_cast<
VarDecl>(D);
8202 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
8203 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_private) {
8213 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
8219 Diag(D->getLocation(),
8220 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
8228 if (
DSAStack->getCurrentDirective() == OMPD_target) {
8229 if (
DSAStack->checkMappableExprComponentListsForDecl(
8232 ->
bool {
return true; })) {
8233 Diag(ELoc, diag::err_omp_variable_in_map_and_dsa)
8252 D->hasAttrs() ? &D->getAttrs() :
nullptr);
8254 if (VDPrivate->isInvalidDecl())
8257 *
this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
8262 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
8264 ? RefExpr->IgnoreParens()
8266 PrivateCopies.push_back(VDPrivateRefExpr);
8277 class DiagsUninitializedSeveretyRAII {
8286 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
8288 Diags.
setSeverity( diag::warn_uninit_self_reference_in_init,
8292 ~DiagsUninitializedSeveretyRAII() {
8307 bool IsImplicitClause =
8309 auto ImplicitClauseLoc =
DSAStack->getConstructLoc();
8311 for (
auto &RefExpr : VarList) {
8312 assert(RefExpr &&
"NULL expr in OpenMP firstprivate clause.");
8315 Expr *SimpleRefExpr = RefExpr;
8319 Vars.push_back(RefExpr);
8320 PrivateCopies.push_back(
nullptr);
8321 Inits.push_back(
nullptr);
8327 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
8329 auto *VD = dyn_cast<
VarDecl>(D);
8335 diag::err_omp_firstprivate_incomplete_type))
8346 DSAStackTy::DSAVarData TopDVar;
8347 if (!IsImplicitClause) {
8348 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
8350 bool IsConstant = ElemType.isConstant(
Context);
8355 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
8356 DVar.CKind != OMPC_lastprivate && DVar.RefExpr) {
8357 Diag(ELoc, diag::err_omp_wrong_dsa)
8375 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
8376 DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_shared) {
8377 Diag(ELoc, diag::err_omp_wrong_dsa)
8392 DVar =
DSAStack->getImplicitDSA(D,
true);
8393 if (DVar.CKind != OMPC_shared &&
8396 Diag(ELoc, diag::err_omp_required_access)
8422 if (DVar.CKind == OMPC_reduction &&
8425 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
8445 if (CurrDir == OMPD_distribute) {
8453 Diag(ELoc, diag::err_omp_firstprivate_distribute_private_teams);
8463 if (DVar.CKind == OMPC_reduction &&
8465 Diag(ELoc, diag::err_omp_firstprivate_distribute_in_teams_reduction);
8469 DVar =
DSAStack->getTopDSA(D,
false);
8470 if (DVar.CKind == OMPC_lastprivate) {
8471 Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute);
8479 if (CurrDir == OMPD_target) {
8480 if (
DSAStack->checkMappableExprComponentListsForDecl(
8483 ->
bool {
return true; })) {
8484 Diag(ELoc, diag::err_omp_variable_in_map_and_dsa)
8496 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
8502 Diag(D->getLocation(),
8503 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
8510 D->hasAttrs() ? &D->getAttrs() :
nullptr);
8516 Expr *VDInitRefExpr =
nullptr;
8524 ElemType = ElemType.getUnqualifiedType();
8525 auto *VDInitTemp =
buildVarDecl(*
this, RefExpr->getExprLoc(), ElemType,
8526 ".firstprivate.temp");
8534 VDPrivate->setInvalidDecl();
8536 VDPrivate->setInit(Result.
getAs<
Expr>());
8540 auto *VDInit =
buildVarDecl(*
this, RefExpr->getExprLoc(), Type,
8541 ".firstprivate.temp");
8543 RefExpr->getExprLoc());
8548 if (VDPrivate->isInvalidDecl()) {
8549 if (IsImplicitClause) {
8550 Diag(RefExpr->getExprLoc(),
8551 diag::note_omp_task_predetermined_firstprivate_here);
8557 *
this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
8558 RefExpr->getExprLoc());
8561 if (TopDVar.CKind == OMPC_lastprivate)
8562 Ref = TopDVar.PrivateCopy;
8566 ExprCaptures.push_back(Ref->getDecl());
8569 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
8571 ? RefExpr->IgnoreParens()
8573 PrivateCopies.push_back(VDPrivateRefExpr);
8574 Inits.push_back(VDInitRefExpr);
8581 Vars, PrivateCopies,
Inits,
8595 for (
auto &RefExpr : VarList) {
8596 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
8599 Expr *SimpleRefExpr = RefExpr;
8603 Vars.push_back(RefExpr);
8604 SrcExprs.push_back(
nullptr);
8605 DstExprs.push_back(
nullptr);
8606 AssignmentOps.push_back(
nullptr);
8613 auto *VD = dyn_cast<
VarDecl>(D);
8619 diag::err_omp_lastprivate_incomplete_type))
8628 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
8629 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
8630 DVar.CKind != OMPC_firstprivate &&
8631 (DVar.CKind != OMPC_private || DVar.RefExpr !=
nullptr)) {
8632 Diag(ELoc, diag::err_omp_wrong_dsa)
8646 DSAStackTy::DSAVarData TopDVar = DVar;
8649 DVar =
DSAStack->getImplicitDSA(D,
true);
8650 if (DVar.CKind != OMPC_shared) {
8651 Diag(ELoc, diag::err_omp_required_access)
8662 if (CurrDir == OMPD_distribute) {
8663 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
8664 if (DVar.CKind == OMPC_firstprivate) {
8665 Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute);
8682 D->hasAttrs() ? &D->getAttrs() :
nullptr);
8683 auto *PseudoSrcExpr =
8687 D->hasAttrs() ? &D->getAttrs() :
nullptr);
8691 auto AssignmentOp =
BuildBinOp(
nullptr, ELoc, BO_Assign,
8692 PseudoDstExpr, PseudoSrcExpr);
8693 if (AssignmentOp.isInvalid())
8697 if (AssignmentOp.isInvalid())
8702 if (TopDVar.CKind == OMPC_firstprivate)
8703 Ref = TopDVar.PrivateCopy;
8707 ExprCaptures.push_back(Ref->
getDecl());
8709 if (TopDVar.CKind == OMPC_firstprivate ||
8711 Ref->
getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
8720 ExprPostUpdates.push_back(
8724 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
8726 ? RefExpr->IgnoreParens()
8728 SrcExprs.push_back(PseudoSrcExpr);
8729 DstExprs.push_back(PseudoDstExpr);
8730 AssignmentOps.push_back(AssignmentOp.get());
8737 Vars, SrcExprs, DstExprs, AssignmentOps,
8747 for (
auto &RefExpr : VarList) {
8748 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
8751 Expr *SimpleRefExpr = RefExpr;
8755 Vars.push_back(RefExpr);
8761 auto *VD = dyn_cast<
VarDecl>(D);
8769 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
8770 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_shared &&
8781 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
8783 ? RefExpr->IgnoreParens()
8794 class DSARefChecker :
public StmtVisitor<DSARefChecker, bool> {
8800 DSAStackTy::DSAVarData DVar =
Stack->getTopDSA(VD,
false);
8801 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
8805 DSAStackTy::DSAVarData DVarPrivate =
Stack->hasDSA(
8814 bool VisitStmt(
Stmt *S) {
8815 for (
auto Child : S->children()) {
8816 if (Child && Visit(Child))
8821 explicit DSARefChecker(DSAStackTy *S) :
Stack(S) {}
8828 class TransformExprToCaptures :
public TreeTransform<TransformExprToCaptures> {
8835 : BaseTransform(SemaRef),
Field(FieldDecl), CapturedExpr(nullptr) {}
8841 return CapturedExpr;
8843 return BaseTransform::TransformMemberExpr(E);
8845 DeclRefExpr *getCapturedExpr() {
return CapturedExpr; }
8849 template <
typename T>
8851 const llvm::function_ref<T(
ValueDecl *)> &Gen) {
8852 for (
auto &Set : Lookups) {
8853 for (
auto *D : Set) {
8854 if (
auto Res = Gen(cast<ValueDecl>(D)))
8880 Lookups.back().append(Lookup.
begin(), Lookup.
end());
8883 }
else if (
auto *ULE =
8884 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
8886 Decl *PrevD =
nullptr;
8887 for(
auto *D : ULE->decls()) {
8890 else if (
auto *DRD = cast<OMPDeclareReductionDecl>(D))
8891 Lookups.back().addDecl(DRD);
8897 filterLookupForUDR<bool>(Lookups, [](
ValueDecl *D) ->
bool {
8898 return !D->isInvalidDecl() &&
8904 for (
auto &Set : Lookups) {
8905 ResSet.
append(Set.begin(), Set.end());
8907 ResSet.
addDecl(Set[Set.size() - 1]);
8912 true,
true, ResSet.
begin(), ResSet.
end());
8914 if (
auto *VD = filterLookupForUDR<ValueDecl *>(
8916 if (!D->isInvalidDecl() &&
8922 if (
auto *VD = filterLookupForUDR<ValueDecl *>(
8924 if (!D->isInvalidDecl() &&
8944 if (ReductionIdScopeSpec.
isSet()) {
8945 SemaRef.
Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range;
8956 auto DN = ReductionId.
getName();
8994 case OO_Array_Delete:
9003 case OO_GreaterEqual:
9008 case OO_PercentEqual:
9013 case OO_GreaterGreater:
9014 case OO_LessLessEqual:
9015 case OO_GreaterGreaterEqual:
9017 case OO_ExclaimEqual:
9025 case OO_Conditional:
9028 llvm_unreachable(
"Unexpected reduction identifier");
9030 if (
auto II = DN.getAsIdentifierInfo()) {
9031 if (II->isStr(
"max"))
9033 else if (II->isStr(
"min"))
9039 if (ReductionIdScopeSpec.
isValid())
9050 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
9051 bool FirstIter =
true;
9052 for (
auto RefExpr : VarList) {
9053 assert(RefExpr &&
"nullptr expr in OpenMP reduction clause.");
9061 if (!FirstIter && IR != ER)
9066 Expr *SimpleRefExpr = RefExpr;
9071 Vars.push_back(RefExpr);
9072 Privates.push_back(
nullptr);
9073 LHSs.push_back(
nullptr);
9074 RHSs.push_back(
nullptr);
9080 *
this, ELoc, ERange,
DSAStack->getCurScope(), ReductionIdScopeSpec,
9081 ReductionId, Type, BasePath, IR == ER ?
nullptr : *IR);
9083 (DeclareReductionRef.
isUnset() ||
9084 isa<UnresolvedLookupExpr>(DeclareReductionRef.
get())))
9085 ReductionOps.push_back(DeclareReductionRef.
get());
9087 ReductionOps.push_back(
nullptr);
9097 Type = ASE->getType().getNonReferenceType();
9100 if (
auto *ATy = BaseType->getAsArrayTypeUnsafe())
9101 Type = ATy->getElementType();
9107 auto *VD = dyn_cast<
VarDecl>(D);
9113 diag::err_omp_reduction_incomplete_type))
9119 Diag(ELoc, diag::err_omp_const_reduction_list_item)
9121 if (!ASE && !OASE) {
9122 bool IsDecl = !VD ||
9123 VD->isThisDeclarationADefinition(
Context) ==
9125 Diag(D->getLocation(),
9126 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9134 if (!ASE && !OASE && VD) {
9135 VarDecl *VDDef = VD->getDefinition();
9138 if (Check.Visit(VDDef->
getInit())) {
9139 Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange;
9140 Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
9157 DSAStackTy::DSAVarData DVar;
9158 DVar =
DSAStack->getTopDSA(D,
false);
9159 if (DVar.CKind == OMPC_reduction) {
9160 Diag(ELoc, diag::err_omp_once_referenced)
9163 Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
9165 Diag(ELoc, diag::err_omp_wrong_dsa)
9179 DVar =
DSAStack->getImplicitDSA(D,
true);
9180 if (DVar.CKind != OMPC_shared) {
9181 Diag(ELoc, diag::err_omp_required_access)
9193 *
this, ELoc, ERange,
DSAStack->getCurScope(), ReductionIdScopeSpec,
9194 ReductionId, Type, BasePath, IR == ER ?
nullptr : *IR);
9198 (DeclareReductionRef.
isUnset() ||
9199 isa<UnresolvedLookupExpr>(DeclareReductionRef.
get()))) {
9200 Vars.push_back(RefExpr);
9201 Privates.push_back(
nullptr);
9202 LHSs.push_back(
nullptr);
9203 RHSs.push_back(
nullptr);
9204 ReductionOps.push_back(DeclareReductionRef.
get());
9207 if (BOK == BO_Comma && DeclareReductionRef.
isUnset()) {
9209 Diag(ReductionId.getLocStart(),
9210 diag::err_omp_unknown_reduction_identifier)
9211 << Type << ReductionIdRange;
9223 if (DeclareReductionRef.
isUnset()) {
9224 if ((BOK == BO_GT || BOK == BO_LT) &&
9225 !(Type->isScalarType() ||
9226 (
getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
9227 Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
9229 if (!ASE && !OASE) {
9230 bool IsDecl = !VD ||
9231 VD->isThisDeclarationADefinition(
Context) ==
9233 Diag(D->getLocation(),
9234 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9239 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
9240 !
getLangOpts().CPlusPlus && Type->isFloatingType()) {
9241 Diag(ELoc, diag::err_omp_clause_floating_type_arg);
9242 if (!ASE && !OASE) {
9243 bool IsDecl = !VD ||
9244 VD->isThisDeclarationADefinition(
Context) ==
9246 Diag(D->getLocation(),
9247 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9254 Type = Type.getNonLValueExprType(
Context).getUnqualifiedType();
9255 auto *LHSVD =
buildVarDecl(*
this, ELoc, Type,
".reduction.lhs",
9256 D->hasAttrs() ? &D->getAttrs() :
nullptr);
9258 D->hasAttrs() ? &D->getAttrs() :
nullptr);
9259 auto PrivateTy = Type;
9272 }
else if (!ASE && !OASE &&
9277 D->hasAttrs() ? &D->getAttrs() :
nullptr);
9279 Expr *Init =
nullptr;
9282 if (DeclareReductionRef.
isUsable()) {
9284 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
9285 if (DRD->getInitializer()) {
9287 RHSVD->setInit(DRDRef);
9297 if (Type->isScalarType() || Type->isAnyComplexType())
9302 if (Type->isScalarType() || Type->isAnyComplexType()) {
9311 Type = ComplexTy->getElementType();
9312 if (Type->isRealFloatingType()) {
9313 llvm::APFloat InitValue =
9318 }
else if (Type->isScalarType()) {
9321 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
9338 if (Type->isIntegerType() || Type->isPointerType()) {
9343 llvm::APInt InitValue =
9345 ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
9346 : llvm::APInt::getMinValue(Size)
9347 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
9348 : llvm::APInt::getMaxValue(Size);
9350 if (Type->isPointerType()) {
9359 }
else if (Type->isRealFloatingType()) {
9360 llvm::APFloat InitValue = llvm::APFloat::getLargest(
9390 llvm_unreachable(
"Unexpected reduction operation");
9393 if (Init && DeclareReductionRef.
isUnset()) {
9398 if (RHSVD->isInvalidDecl())
9400 if (!RHSVD->hasInit() && DeclareReductionRef.
isUnset()) {
9401 Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type
9402 << ReductionIdRange;
9406 Diag(D->getLocation(),
9407 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9413 PrivateVD->setInit(RHSVD->getInit());
9414 PrivateVD->setInitStyle(RHSVD->getInitStyle());
9417 if (DeclareReductionRef.
isUsable()) {
9422 if (!BasePath.empty()) {
9426 CK_UncheckedDerivedToBase, LHS.get(),
9427 &BasePath, LHS.get()->getValueKind());
9429 CK_UncheckedDerivedToBase, RHS.get(),
9430 &BasePath, RHS.get()->getValueKind());
9433 QualType Params[] = {PtrRedTy, PtrRedTy};
9443 ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE);
9445 if (BOK != BO_LT && BOK != BO_GT) {
9448 BO_Assign, LHSDRE, ReductionOp.
get());
9455 BO_Assign, LHSDRE, ConditionalOp);
9467 TransformExprToCaptures RebuildToCapture(*
this, D);
9469 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).
get();
9470 Ref = RebuildToCapture.getCapturedExpr();
9476 ExprCaptures.push_back(Ref->
getDecl());
9477 if (Ref->
getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
9483 SimpleRefExpr, RefRes.
get());
9486 ExprPostUpdates.push_back(
9491 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
9492 Vars.push_back(VarsExpr);
9493 Privates.push_back(PrivateDRE);
9494 LHSs.push_back(LHSDRE);
9495 RHSs.push_back(RHSDRE);
9496 ReductionOps.push_back(ReductionOp.
get());
9503 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars,
9511 if ((!
LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
9513 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) <<
LangOpts.CPlusPlus;
9522 auto *VD = dyn_cast_or_null<VarDecl>(D);
9526 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
9528 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
9536 Diag(ELoc, diag::err_omp_const_variable)
9542 Diag(D->getLocation(),
9543 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9552 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(
Context) &&
9553 !Ty->isPointerType())) {
9554 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
9559 Diag(D->getLocation(),
9560 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9578 LinKind = OMPC_LINEAR_val;
9579 for (
auto &RefExpr : VarList) {
9580 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
9583 Expr *SimpleRefExpr = RefExpr;
9588 Vars.push_back(RefExpr);
9589 Privates.push_back(
nullptr);
9590 Inits.push_back(
nullptr);
9597 auto *VD = dyn_cast<
VarDecl>(D);
9603 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
9617 D->hasAttrs() ? &D->getAttrs() :
nullptr);
9626 ExprCaptures.push_back(Ref->
getDecl());
9627 if (Ref->
getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
9633 SimpleRefExpr, RefRes.
get());
9636 ExprPostUpdates.push_back(
9641 if (LinKind == OMPC_LINEAR_uval)
9642 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
9644 InitExpr = VD ? SimpleRefExpr : Ref;
9649 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
9651 ? RefExpr->IgnoreParens()
9653 Privates.push_back(PrivateRef);
9654 Inits.push_back(InitRef);
9661 Expr *CalcStepExpr =
nullptr;
9669 StepExpr = Val.
get();
9677 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
9684 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
9685 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
9686 << (Vars.size() > 1);
9687 if (!IsConstant && CalcStep.isUsable()) {
9690 CalcStepExpr = CalcStep.get();
9695 ColonLoc, EndLoc, Vars, Privates, Inits,
9696 StepExpr, CalcStepExpr,
9702 Expr *NumIterations,
Sema &SemaRef,
9711 if (Step ==
nullptr)
9713 else if (CalcStep) {
9714 Step = cast<BinaryOperator>(
CalcStep)->getLHS();
9716 bool HasErrors =
false;
9717 auto CurInit = Clause.inits().begin();
9718 auto CurPrivate = Clause.privates().begin();
9719 auto LinKind = Clause.getModifier();
9720 for (
auto &RefExpr : Clause.
varlists()) {
9723 Expr *SimpleRefExpr = RefExpr;
9727 if (Res.second || !D) {
9728 Updates.push_back(
nullptr);
9729 Finals.push_back(
nullptr);
9733 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) {
9734 D = cast<MemberExpr>(CED->getInit()->IgnoreParenImpCasts())
9737 auto &&Info = Stack->isLoopControlVariable(D);
9738 Expr *InitExpr = *CurInit;
9741 auto DE = cast<DeclRefExpr>(SimpleRefExpr);
9743 if (LinKind == OMPC_LINEAR_uval)
9744 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
9748 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
9756 InitExpr, IV,
Step,
false);
9758 Update = *CurPrivate;
9766 InitExpr, NumIterations,
Step,
9769 Final = *CurPrivate;
9773 if (!Update.isUsable() || !Final.
isUsable()) {
9774 Updates.push_back(
nullptr);
9775 Finals.push_back(
nullptr);
9778 Updates.push_back(Update.get());
9779 Finals.push_back(Final.
get());
9784 Clause.setUpdates(Updates);
9785 Clause.setFinals(Finals);
9794 for (
auto &RefExpr : VarList) {
9795 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
9798 Expr *SimpleRefExpr = RefExpr;
9803 Vars.push_back(RefExpr);
9810 auto *VD = dyn_cast<
VarDecl>(D);
9818 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
9823 Diag(D->getLocation(),
9824 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9831 if (
Expr *PrevRef =
DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
9832 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange;
9833 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
9842 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
9851 if (Alignment !=
nullptr) {
9853 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
9856 Alignment = AlignResult.
get();
9862 EndLoc, Vars, Alignment);
9873 for (
auto &RefExpr : VarList) {
9874 assert(RefExpr &&
"NULL expr in OpenMP copyin clause.");
9875 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
9877 Vars.push_back(RefExpr);
9878 SrcExprs.push_back(
nullptr);
9879 DstExprs.push_back(
nullptr);
9880 AssignmentOps.push_back(
nullptr);
9890 if (!DE || !isa<VarDecl>(DE->
getDecl())) {
9891 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
9892 << 0 << RefExpr->getSourceRange();
9897 VarDecl *VD = cast<VarDecl>(D);
9900 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
9903 SrcExprs.push_back(
nullptr);
9904 DstExprs.push_back(
nullptr);
9905 AssignmentOps.push_back(
nullptr);
9911 if (!
DSAStack->isThreadPrivate(VD)) {
9912 Diag(ELoc, diag::err_omp_required_access)
9925 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() :
nullptr);
9927 *
this, SrcVD, ElemType.getUnqualifiedType(), DE->
getExprLoc());
9930 VD->hasAttrs() ? &VD->getAttrs() :
nullptr);
9931 auto *PseudoDstExpr =
9936 PseudoDstExpr, PseudoSrcExpr);
9937 if (AssignmentOp.isInvalid())
9941 if (AssignmentOp.isInvalid())
9944 DSAStack->addDSA(VD, DE, OMPC_copyin);
9946 SrcExprs.push_back(PseudoSrcExpr);
9947 DstExprs.push_back(PseudoDstExpr);
9948 AssignmentOps.push_back(AssignmentOp.get());
9955 SrcExprs, DstExprs, AssignmentOps);
9966 for (
auto &RefExpr : VarList) {
9967 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
9970 Expr *SimpleRefExpr = RefExpr;
9975 Vars.push_back(RefExpr);
9976 SrcExprs.push_back(
nullptr);
9977 DstExprs.push_back(
nullptr);
9978 AssignmentOps.push_back(
nullptr);
9985 auto *VD = dyn_cast<
VarDecl>(D);
9990 if (!VD || !
DSAStack->isThreadPrivate(VD)) {
9991 auto DVar =
DSAStack->getTopDSA(D,
false);
9992 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
9994 Diag(ELoc, diag::err_omp_wrong_dsa)
10005 DVar =
DSAStack->getImplicitDSA(D,
false);
10006 if (DVar.CKind == OMPC_shared) {
10007 Diag(ELoc, diag::err_omp_required_access)
10009 <<
"threadprivate or private in the enclosing context";
10018 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
10024 Diag(D->getLocation(),
10025 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10035 .getUnqualifiedType();
10037 buildVarDecl(*
this, RefExpr->getLocStart(), Type,
".copyprivate.src",
10038 D->hasAttrs() ? &D->getAttrs() :
nullptr);
10041 buildVarDecl(*
this, RefExpr->getLocStart(), Type,
".copyprivate.dst",
10042 D->hasAttrs() ? &D->getAttrs() :
nullptr);
10043 auto *PseudoDstExpr =
10046 PseudoDstExpr, PseudoSrcExpr);
10047 if (AssignmentOp.isInvalid())
10051 if (AssignmentOp.isInvalid())
10058 VD ? RefExpr->IgnoreParens()
10060 SrcExprs.push_back(PseudoSrcExpr);
10061 DstExprs.push_back(PseudoDstExpr);
10062 AssignmentOps.push_back(AssignmentOp.get());
10069 Vars, SrcExprs, DstExprs, AssignmentOps);
10076 if (VarList.empty())
10087 if (
DSAStack->getCurrentDirective() == OMPD_ordered &&
10088 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
10089 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
10093 if (
DSAStack->getCurrentDirective() != OMPD_ordered &&
10095 DepKind == OMPC_DEPEND_sink)) {
10096 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
10097 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
10105 llvm::APSInt DepCounter(32);
10106 llvm::APSInt TotalDepCount(32);
10107 if (DepKind == OMPC_DEPEND_sink) {
10108 if (
auto *OrderedCountExpr =
DSAStack->getParentOrderedRegionParam()) {
10109 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(
Context);
10110 TotalDepCount.setIsUnsigned(
true);
10113 if ((DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) ||
10114 DSAStack->getParentOrderedRegionParam()) {
10115 for (
auto &RefExpr : VarList) {
10116 assert(RefExpr &&
"NULL expr in OpenMP shared clause.");
10117 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
10119 Vars.push_back(RefExpr);
10124 auto *SimpleExpr = RefExpr->IgnoreParenCasts();
10125 if (DepKind == OMPC_DEPEND_sink) {
10126 if (DepCounter >= TotalDepCount) {
10127 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
10141 Vars.push_back(RefExpr);
10144 SimpleExpr = SimpleExpr->IgnoreImplicit();
10147 Expr *LHS = SimpleExpr;
10148 Expr *RHS =
nullptr;
10149 if (
auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
10151 OOLoc = BO->getOperatorLoc();
10154 }
else if (
auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
10155 OOK = OCE->getOperator();
10156 OOLoc = OCE->getOperatorLoc();
10159 }
else if (
auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
10160 OOK = MCE->getMethodDecl()
10163 .getCXXOverloadedOperator();
10164 OOLoc = MCE->getCallee()->getExprLoc();
10174 Vars.push_back(RefExpr);
10180 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK !=
OO_None)) {
10181 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
10185 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
10186 RHS, OMPC_depend,
false);
10191 DSAStack->getParentOrderedRegionParam() &&
10192 DepCounter !=
DSAStack->isParentLoopControlVariable(D).first) {
10193 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
10194 <<
DSAStack->getParentLoopControlVariable(
10195 DepCounter.getZExtValue());
10198 OpsOffs.push_back({RHS, OOK});
10207 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
10208 (!ASE && !DE && !OASE) || (DE && !isa<VarDecl>(DE->getDecl())) ||
10212 .getNonReferenceType()
10213 ->isPointerType() &&
10214 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
10215 Diag(ELoc, diag::err_omp_expected_var_name_member_expr_or_array_item)
10216 << 0 << RefExpr->getSourceRange();
10220 Vars.push_back(RefExpr->IgnoreParenImpCasts());
10224 TotalDepCount > VarList.size() &&
10225 DSAStack->getParentOrderedRegionParam()) {
10226 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
10227 <<
DSAStack->getParentLoopControlVariable(VarList.size() + 1);
10229 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
10234 DepKind, DepLoc, ColonLoc, Vars);
10235 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source)
10236 DSAStack->addDoacrossDependClause(C, OpsOffs);
10243 Expr *ValExpr = Device;
10256 if (!RD || RD->isInvalidDecl())
10259 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
10260 if (
auto *CTD = CTSD->getSpecializedTemplate())
10261 RD = CTD->getTemplatedDecl();
10264 SemaRef.
Diag(Loc, diag::err_omp_not_mappable_type) << QTy;
10265 SemaRef.
Diag(RD->getLocation(), diag::note_omp_polymorphic_in_target);
10269 bool IsCorrect =
true;
10270 for (
auto *I : DC->decls()) {
10272 if (
auto *MD = dyn_cast<CXXMethodDecl>(I)) {
10273 if (MD->isStatic()) {
10274 SemaRef.
Diag(Loc, diag::err_omp_not_mappable_type) << QTy;
10275 SemaRef.
Diag(MD->getLocation(),
10276 diag::note_omp_static_member_in_target);
10279 }
else if (
auto *VD = dyn_cast<VarDecl>(I)) {
10280 if (VD->isStaticDataMember()) {
10281 SemaRef.
Diag(Loc, diag::err_omp_not_mappable_type) << QTy;
10282 SemaRef.
Diag(VD->getLocation(),
10283 diag::note_omp_static_member_in_target);
10290 for (
auto &I : RD->
bases()) {
10292 I.getType()->getAsCXXRecordDecl()))
10302 SemaRef.
Diag(SL, diag::err_incomplete_type) << QTy << SR;
10304 }
else if (
CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(ND)) {
10305 if (!RD->isInvalidDecl() &&
10323 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) {
10324 if (
auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
10325 return ATy->getSize().getSExtValue() != 1;
10330 assert(OASE &&
"Expecting array section if not an array subscript.");
10331 auto *LowerBound = OASE->getLowerBound();
10332 auto *
Length = OASE->getLength();
10337 llvm::APSInt ConstLowerBound;
10338 if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.
getASTContext()))
10340 if (ConstLowerBound.getSExtValue())
10359 llvm::APSInt ConstLength;
10363 return CATy->
getSize().getSExtValue() != ConstLength.getSExtValue();
10376 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid()))
10379 assert(OASE &&
"Expecting array section if not an array subscript.");
10380 auto *
Length = OASE->getLength();
10386 if (
auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
10387 return ATy->getSize().getSExtValue() != 1;
10393 llvm::APSInt ConstLength;
10397 return ConstLength.getSExtValue() != 1;
10430 Expr *RelevantExpr =
nullptr;
10449 bool AllowUnitySizeArraySection =
true;
10450 bool AllowWholeSizeArraySection =
true;
10452 while (!RelevantExpr) {
10455 if (
auto *CurE = dyn_cast<DeclRefExpr>(E)) {
10456 if (!isa<VarDecl>(CurE->getDecl()))
10459 RelevantExpr = CurE;
10463 AllowUnitySizeArraySection =
false;
10464 AllowWholeSizeArraySection =
false;
10468 CurE, CurE->getDecl()));
10472 if (
auto *CurE = dyn_cast<MemberExpr>(E)) {
10473 auto *BaseE = CurE->getBase()->IgnoreParenImpCasts();
10475 if (isa<CXXThisExpr>(BaseE))
10477 RelevantExpr = CurE;
10481 if (!isa<FieldDecl>(CurE->getMemberDecl())) {
10482 SemaRef.
Diag(ELoc, diag::err_omp_expected_access_to_data_field)
10483 << CurE->getSourceRange();
10487 auto *FD = cast<FieldDecl>(CurE->getMemberDecl());
10492 if (FD->isBitField()) {
10493 SemaRef.
Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
10501 QualType CurType = BaseE->getType().getNonReferenceType();
10508 if (RT->isUnionType()) {
10509 SemaRef.
Diag(ELoc, diag::err_omp_union_type_not_allowed)
10510 << CurE->getSourceRange();
10521 AllowUnitySizeArraySection =
false;
10522 AllowWholeSizeArraySection =
false;
10525 CurComponents.push_back(
10530 if (
auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) {
10534 SemaRef.
Diag(ELoc, diag::err_omp_expected_base_var_name)
10535 << 0 << CurE->getSourceRange();
10544 AllowWholeSizeArraySection =
false;
10547 CurComponents.push_back(
10552 if (
auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) {
10561 if (CurType->isReferenceType())
10566 if (!IsPointer && !CurType->isArrayType()) {
10567 SemaRef.
Diag(ELoc, diag::err_omp_expected_base_var_name)
10568 << 0 << CurE->getSourceRange();
10577 if (AllowWholeSizeArraySection && AllowUnitySizeArraySection) {
10583 if (NotWhole || IsPointer)
10584 AllowWholeSizeArraySection =
false;
10585 }
else if ((AllowUnitySizeArraySection && NotUnity) ||
10586 (AllowWholeSizeArraySection && NotWhole)) {
10590 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
10591 << CurE->getSourceRange();
10596 CurComponents.push_back(
10603 diag::err_omp_expected_named_var_member_or_array_expression)
10608 return RelevantExpr;
10615 bool CurrentRegionOnly,
10626 assert(!CurComponents.empty() &&
"Map clause expression with no components!");
10627 assert(CurComponents.back().getAssociatedDeclaration() == VD &&
10628 "Map clause expression with unexpected base!");
10631 bool IsEnclosedByDataEnvironmentExpr =
false;
10632 const Expr *EnclosingExpr =
nullptr;
10634 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
10635 VD, CurrentRegionOnly,
10637 StackComponents) ->
bool {
10639 assert(!StackComponents.empty() &&
10640 "Map clause expression with no components!");
10641 assert(StackComponents.back().getAssociatedDeclaration() == VD &&
10642 "Map clause expression with unexpected base!");
10645 auto *RE = StackComponents.front().getAssociatedExpression();
10651 auto CI = CurComponents.rbegin();
10652 auto CE = CurComponents.rend();
10653 auto SI = StackComponents.rbegin();
10654 auto SE = StackComponents.rend();
10655 for (; CI != CE && SI != SE; ++CI, ++SI) {
10660 if (CurrentRegionOnly &&
10661 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
10662 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
10663 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
10664 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
10665 SemaRef.
Diag(CI->getAssociatedExpression()->getExprLoc(),
10666 diag::err_omp_multiple_array_items_in_map_clause)
10667 << CI->getAssociatedExpression()->getSourceRange();
10668 SemaRef.
Diag(SI->getAssociatedExpression()->getExprLoc(),
10669 diag::note_used_here)
10670 << SI->getAssociatedExpression()->getSourceRange();
10675 if (CI->getAssociatedExpression()->getStmtClass() !=
10676 SI->getAssociatedExpression()->getStmtClass())
10680 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
10690 if (CI == CE && SI == SE) {
10691 if (CurrentRegionOnly) {
10692 if (CKind == OMPC_map)
10693 SemaRef.
Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
10695 assert(CKind == OMPC_to || CKind == OMPC_from);
10696 SemaRef.
Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
10699 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
10700 << RE->getSourceRange();
10705 IsEnclosedByDataEnvironmentExpr =
true;
10711 std::prev(CI)->getAssociatedDeclaration()->getType();
10713 std::prev(CI)->getAssociatedExpression()->getExprLoc();
10732 if (CI == CE || SI == SE) {
10735 diag::err_omp_pointer_mapped_along_with_derived_section)
10738 assert(CI != CE && SI != SE);
10739 SemaRef.
Diag(DerivedLoc, diag::err_omp_same_pointer_derreferenced)
10742 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
10743 << RE->getSourceRange();
10752 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
10753 if (CKind == OMPC_map)
10754 SemaRef.
Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
10756 assert(CKind == OMPC_to || CKind == OMPC_from);
10757 SemaRef.
Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
10760 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
10761 << RE->getSourceRange();
10767 if (!CurrentRegionOnly && SI != SE)
10768 EnclosingExpr = RE;
10772 IsEnclosedByDataEnvironmentExpr |=
10773 (!CurrentRegionOnly && CI != CE && SI == SE);
10778 if (CurrentRegionOnly)
10792 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
10794 diag::err_omp_original_storage_is_shared_and_does_not_contain)
10797 << EnclosingExpr->getSourceRange();
10807 struct MappableVarListInfo final {
10820 VarComponents.reserve(VarList.size());
10821 VarBaseDeclarations.reserve(VarList.size());
10836 bool IsMapTypeImplicit =
false) {
10838 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
10839 "Unexpected clause kind with mappable expressions!");
10847 for (
auto &RE : MVLI.VarList) {
10848 assert(RE &&
"Null expr in omp to/from/map clause");
10851 auto *VE = RE->IgnoreParenLValueCasts();
10853 if (VE->isValueDependent() || VE->isTypeDependent() ||
10854 VE->isInstantiationDependent() ||
10855 VE->containsUnexpandedParameterPack()) {
10858 MVLI.ProcessedVarList.push_back(RE);
10862 auto *SimpleExpr = RE->IgnoreParenCasts();
10864 if (!RE->IgnoreParenImpCasts()->isLValue()) {
10866 diag::err_omp_expected_named_var_member_or_array_expression)
10867 << RE->getSourceRange();
10881 assert(!CurComponents.empty() &&
10882 "Invalid mappable expression information.");
10887 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
10888 assert(CurDeclaration &&
"Null decl on map clause.");
10890 CurDeclaration->isCanonicalDecl() &&
10891 "Expecting components to have associated only canonical declarations.");
10893 auto *VD = dyn_cast<
VarDecl>(CurDeclaration);
10894 auto *FD = dyn_cast<
FieldDecl>(CurDeclaration);
10896 assert((VD || FD) &&
"Only variables or fields are expected here!");
10903 if (VD && DSAS->isThreadPrivate(VD)) {
10904 auto DVar = DSAS->getTopDSA(VD,
false);
10905 SemaRef.
Diag(ELoc, diag::err_omp_threadprivate_in_clause)
10920 true, CurComponents, CKind))
10922 if (CKind == OMPC_map &&
10924 false, CurComponents, CKind))
10931 QualType Type = CurDeclaration->getType().getNonReferenceType();
10941 if (CKind == OMPC_map) {
10947 if (DKind == OMPD_target_enter_data &&
10948 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
10949 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
10950 << (IsMapTypeImplicit ? 1 : 0)
10960 if (DKind == OMPD_target_exit_data &&
10961 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
10962 MapType == OMPC_MAP_delete)) {
10963 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
10964 << (IsMapTypeImplicit ? 1 : 0)
10973 if (DKind == OMPD_target && VD) {
10974 auto DVar = DSAS->getTopDSA(VD,
false);
10976 SemaRef.
Diag(ELoc, diag::err_omp_variable_in_map_and_dsa)
10986 MVLI.ProcessedVarList.push_back(RE);
10990 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents);
10995 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
10996 MVLI.VarComponents.back().append(CurComponents.begin(),
10997 CurComponents.end());
10998 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ?
nullptr
11009 MappableVarListInfo MVLI(VarList);
11011 MapType, IsMapTypeImplicit);
11016 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
11017 MVLI.VarComponents, MapTypeModifier, MapType,
11018 IsMapTypeImplicit, MapLoc);
11026 if (ReductionType.isNull())
11033 if (ReductionType.hasQualifiers()) {
11034 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
11038 if (ReductionType->isFunctionType()) {
11039 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
11042 if (ReductionType->isReferenceType()) {
11043 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
11046 if (ReductionType->isArrayType()) {
11047 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
11050 return ReductionType;
11055 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
11058 Decls.reserve(ReductionTypes.size());
11066 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
11068 bool InCompoundScope =
true;
11069 if (S !=
nullptr) {
11078 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
11080 while (Filter.hasNext()) {
11081 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
11082 if (InCompoundScope) {
11083 auto I = UsedAsPrevious.find(PrevDecl);
11084 if (I == UsedAsPrevious.end())
11085 UsedAsPrevious[PrevDecl] =
false;
11086 if (
auto *D = PrevDecl->getPrevDeclInScope())
11087 UsedAsPrevious[D] =
true;
11089 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
11090 PrevDecl->getLocation();
11093 if (InCompoundScope) {
11094 for (
auto &PrevData : UsedAsPrevious) {
11095 if (!PrevData.second) {
11096 PrevDRD = PrevData.first;
11101 }
else if (PrevDeclInScope !=
nullptr) {
11102 auto *PrevDRDInScope = PrevDRD =
11103 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
11105 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
11106 PrevDRDInScope->getLocation();
11108 }
while (PrevDRDInScope !=
nullptr);
11110 for (
auto &TyData : ReductionTypes) {
11111 auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
11112 bool Invalid =
false;
11113 if (I != PreviousRedeclTypes.end()) {
11114 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
11116 Diag(I->second, diag::note_previous_definition);
11119 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
11121 Name, TyData.first, PrevDRD);
11123 DRD->setAccess(AS);
11124 Decls.push_back(DRD);
11126 DRD->setInvalidDecl();
11136 auto *DRD = cast<OMPDeclareReductionDecl>(D);
11150 QualType ReductionType = DRD->getType();
11158 buildVarDecl(*
this, D->getLocation(), ReductionType,
"omp_in");
11166 buildVarDecl(*
this, D->getLocation(), ReductionType,
"omp_out");
11167 if (S !=
nullptr) {
11171 DRD->addDecl(OmpInParm);
11172 DRD->addDecl(OmpOutParm);
11177 auto *DRD = cast<OMPDeclareReductionDecl>(D);
11184 if (Combiner !=
nullptr)
11185 DRD->setCombiner(Combiner);
11187 DRD->setInvalidDecl();
11191 auto *DRD = cast<OMPDeclareReductionDecl>(D);
11204 QualType ReductionType = DRD->getType();
11211 auto *OmpPrivParm =
11212 buildVarDecl(*
this, D->getLocation(), ReductionType,
"omp_priv");
11219 auto *OmpOrigParm =
11220 buildVarDecl(*
this, D->getLocation(), ReductionType,
"omp_orig");
11221 if (S !=
nullptr) {
11225 DRD->addDecl(OmpPrivParm);
11226 DRD->addDecl(OmpOrigParm);
11231 Expr *Initializer) {
11232 auto *DRD = cast<OMPDeclareReductionDecl>(D);
11239 if (Initializer !=
nullptr)
11240 DRD->setInitializer(Initializer);
11242 DRD->setInvalidDecl();
11247 for (
auto *D : DeclReductions.
get()) {
11249 auto *DRD = cast<OMPDeclareReductionDecl>(D);
11253 D->setInvalidDecl();
11255 return DeclReductions;
11262 Expr *ValExpr = NumTeams;
11277 Expr *ValExpr = ThreadLimit;
11293 Expr *ValExpr = Priority;
11308 Expr *ValExpr = Grainsize;
11324 Expr *ValExpr = NumTasks;
11342 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
11354 std::string Values;
11358 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
11362 Expr *ValExpr = ChunkSize;
11363 Stmt *HelperValStmt =
nullptr;
11374 ValExpr = Val.
get();
11381 if (Result.isSigned() && !Result.isStrictlyPositive()) {
11382 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
11383 <<
"dist_schedule" << ChunkSize->getSourceRange();
11386 }
else if (isParallelOrTaskRegion(
DSAStack->getCurrentDirective()) &&
11388 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
11389 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
11397 Kind, ValExpr, HelperValStmt);
11405 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
11406 Kind != OMPC_DEFAULTMAP_scalar) {
11410 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
11412 OMPC_DEFAULTMAP_MODIFIER_tofrom);
11416 OMPC_DEFAULTMAP_scalar);
11420 Diag(Loc, diag::err_omp_unexpected_clause_value)
11434 Diag(Loc, diag::err_omp_region_not_file_context);
11437 if (IsInOpenMPDeclareTargetContext) {
11438 Diag(Loc, diag::err_omp_enclosed_declare_target);
11442 IsInOpenMPDeclareTargetContext =
true;
11447 assert(IsInOpenMPDeclareTargetContext &&
11448 "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
11450 IsInOpenMPDeclareTargetContext =
false;
11456 OMPDeclareTargetDeclAttr::MapTypeTy MT,
11468 llvm::make_unique<VarOrFuncDeclFilterCCC>(*
this),
11481 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) {
11482 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
11485 if (!ND->hasAttr<OMPDeclareTargetDeclAttr>()) {
11486 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
Context, MT);
11489 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
11491 }
else if (ND->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() != MT) {
11492 Diag(Id.
getLoc(), diag::err_omp_declare_target_to_and_link)
11503 Decl *LD =
nullptr;
11504 if (isa<TagDecl>(D)) {
11506 }
else if (isa<VarDecl>(D)) {
11511 if (cast<VarDecl>(D)->isImplicit()) {
11512 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
11513 SemaRef.
Context, OMPDeclareTargetDeclAttr::MT_To);
11516 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
11520 }
else if (isa<FunctionDecl>(D)) {
11522 if (cast<FunctionDecl>(D)->hasBody(FD))
11529 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
11530 SemaRef.
Context, OMPDeclareTargetDeclAttr::MT_To);
11533 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
11539 if (LD && !LD->hasAttr<OMPDeclareTargetDeclAttr>() &&
11540 (isa<VarDecl>(LD) || isa<FunctionDecl>(LD))) {
11542 if (LD->isOutOfLine()) {
11543 SemaRef.
Diag(LD->getLocation(), diag::warn_omp_not_in_target_context);
11544 SemaRef.
Diag(SL, diag::note_used_here) << SR;
11548 if (isa<FunctionDecl>(DC) &&
11549 cast<FunctionDecl>(DC)->hasAttr<OMPDeclareTargetDeclAttr>())
11557 SemaRef.
Diag(LD->getLocation(), diag::warn_omp_not_in_target_context);
11558 SemaRef.
Diag(SL, diag::note_used_here) << SR;
11561 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
11562 SemaRef.
Context, OMPDeclareTargetDeclAttr::MT_To);
11565 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
11572 if (VD->hasAttr<OMPDeclareTargetDeclAttr>())
11580 if (!D || D->isInvalidDecl())
11582 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
11585 if (
VarDecl *VD = dyn_cast<VarDecl>(D)) {
11586 if (
DSAStack->isThreadPrivate(VD)) {
11587 Diag(SL, diag::err_omp_threadprivate_in_target);
11592 if (
ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
11598 if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD)) {
11599 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
11600 Context, OMPDeclareTargetDeclAttr::MT_To);
11603 ML->DeclarationMarkedOpenMPDeclareTarget(VD, A);
11610 if (!D->hasAttr<OMPDeclareTargetDeclAttr>() &&
11611 (isa<VarDecl>(D) || isa<FunctionDecl>(D))) {
11612 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
11613 Context, OMPDeclareTargetDeclAttr::MT_To);
11616 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
11627 MappableVarListInfo MVLI(VarList);
11629 if (MVLI.ProcessedVarList.empty())
11633 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
11634 MVLI.VarComponents);
11641 MappableVarListInfo MVLI(VarList);
11643 if (MVLI.ProcessedVarList.empty())
11647 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
11648 MVLI.VarComponents);
11656 for (
auto &RefExpr : VarList) {
11657 assert(RefExpr &&
"NULL expr in OpenMP use_device_ptr clause.");
11660 Expr *SimpleRefExpr = RefExpr;
11664 Vars.push_back(RefExpr);
11673 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
11674 << 0 << RefExpr->getSourceRange();
11677 Vars.push_back(RefExpr->IgnoreParens());
11692 for (
auto &RefExpr : VarList) {
11693 assert(RefExpr &&
"NULL expr in OpenMP use_device_ptr clause.");
11696 Expr *SimpleRefExpr = RefExpr;
11700 Vars.push_back(RefExpr);
11710 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
11711 << 0 << RefExpr->getSourceRange();
11714 Vars.push_back(RefExpr->IgnoreParens());
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.
OMPClause * ActOnOpenMPReductionClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions=llvm::None)
Called on well-formed 'reduction' clause.
Expr * NLB
Update of LowerBound for statically sheduled 'omp for' loops.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
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.
QualType getCurrentThisType()
Try to retrieve the type of the 'this' pointer.
StmtResult ActOnOpenMPForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for' after parsing of the associated statement.
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.
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, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
ExprResult ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id)
Called on correct id-expression from the '#pragma omp threadprivate'.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
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.
static OMPDistributeSimdDirective * 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.
static OMPToClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
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.
StmtResult ActOnOpenMPTargetParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel for simd' after parsing of the associated statemen...
StmtResult ActOnOpenMPTargetEnterDataDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target enter data' after parsing of the associated statement...
bool ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc)
Called on the start of target region i.e. '#pragma omp declare target'.
A (possibly-)qualified type.
void ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
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)
OMPClause * ActOnOpenMPUseDevicePtrClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'use_device_ptr' clause.
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.
static OMPDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
void EndOpenMPDSABlock(Stmt *CurDirective)
Called on end of data sharing attribute block.
DeclGroupPtrTy ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, ArrayRef< Expr * > Uniforms, ArrayRef< Expr * > Aligneds, ArrayRef< Expr * > Alignments, ArrayRef< Expr * > Linears, ArrayRef< unsigned > LinModifiers, ArrayRef< Expr * > Steps, SourceRange SR)
Called on well-formed '#pragma omp declare simd' after parsing of the associated method/function.
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.
OpenMPDefaultmapClauseKind
OpenMP attributes for 'defaultmap' clause.
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
const LangOptions & getLangOpts() const
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false)
Perform unqualified name lookup starting from a given scope.
static UnresolvedLookupExpr * Create(const ASTContext &C, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool ADL, bool Overloaded, UnresolvedSetIterator Begin, UnresolvedSetIterator End)
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...
static OMPClauseWithPreInit * get(OMPClause *C)
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
Filter makeFilter()
Create a filter for this result set.
bool isExternCContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
SourceLocation getEndLoc() const
getEndLoc - Retrieve the location of the last token.
static bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, QualType QTy)
FullExprArg MakeFullExpr(Expr *Arg)
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).
StmtResult ActOnOpenMPTeamsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp teams' after parsing of the associated statement.
static OMPTargetUpdateDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive with a list of Clauses.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
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.
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 isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level)
Check if the specified variable is captured by 'target' directive.
StmtResult ActOnOpenMPForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for simd' after parsing of the associated statement.
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
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type...
This represents 'priority' clause in the '#pragma omp ...' directive.
bool isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target data offload 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.
bool CheckOpenMPLinearDecl(ValueDecl *D, SourceLocation ELoc, OpenMPLinearClauseKind LinKind, QualType Type)
Checks that the specified declaration matches requirements for the linear decls.
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
static OMPDeclareReductionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, QualType T, OMPDeclareReductionDecl *PrevDeclInScope)
Create declare reduction node.
const Expr * getInit() const
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
A container of type source information.
This represents 'update' clause in the '#pragma omp atomic' directive.
Wrapper for void* pointer.
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, SourceLocation LinLoc)
Checks correctness of linear modifiers.
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 ActOnOpenMPTargetUpdateDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target update'.
Represents a C++ constructor within a class.
static std::pair< ValueDecl *, bool > getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, SourceRange &ERange, bool AllowArraySection=false)
OpenMPDefaultmapClauseModifier
OpenMP modifiers for 'defaultmap' clause.
float __ovld __cnfn distance(float p0, float p1)
Returns the distance between p0 and p1.
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.
const llvm::APInt & getSize() const
StmtResult ActOnOpenMPParallelDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel' after parsing of the associated statement.
Expr * PrevLB
PreviousLowerBound - local variable passed to runtime in the enclosing schedule or null if that does ...
Retains information about a function, method, or block that is currently being parsed.
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.
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.
Extra information about a function prototype.
This represents 'defaultmap' clause in the '#pragma omp ...' directive.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
static OMPTargetParallelForSimdDirective * 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 hasGlobalStorage() const
Returns true for all variables that do not have local storage.
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'.
static OMPDistributeParallelForDirective * 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 containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
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()
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.
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveStart(Scope *S, DeclContext *DC, DeclarationName Name, ArrayRef< std::pair< QualType, SourceLocation >> ReductionTypes, AccessSpecifier AS, Decl *PrevDeclInScope=nullptr)
Called on start of '#pragma omp declare reduction'.
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, AssignmentAction Action, bool AllowExplicit=false)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType...
StmtResult ActOnOpenMPTaskLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop' after parsing of the associated statement.
Expr * IgnoreImpCasts() LLVM_READONLY
IgnoreImpCasts - Skip past any implicit casts which might surround this expression.
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.
static OMPCapturedExprDecl * Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, QualType T)
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.
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
void setHasOMPDeclareReductionCombiner()
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
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 IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base)
Determine whether the type Derived is a C++ class that is derived from the type Base.
bool isReferenceType() const
bool isOpenMPTaskingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of tasking directives - task, taskloop or taksloop simd...
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
bool isAnyPointerType() const
OMPClause * ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'if' clause.
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
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.
SourceLocation getExprLoc() const LLVM_READONLY
bool isTranslationUnit() const
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 OMPTargetExitDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive with a list of Clauses.
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.
static bool CheckOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA, LoopIterationSpace &ResultIterSpace, llvm::MapVector< Expr *, DeclRefExpr * > &Captures)
Called on a for stmt to check and extract its iteration space for further processing (such as collaps...
ExprResult DefaultFunctionArrayConversion(Expr *E, bool Diagnose=true)
DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4).
void PopExpressionEvaluationContext()
This represents '#pragma omp critical' directive.
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
void EndOpenMPClause()
End analysis of clauses.
OMPClause * ActOnOpenMPSharedClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'shared' clause.
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.
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.
OpenMPDistScheduleClauseKind
OpenMP attributes for 'dist_schedule' clause.
static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack, const ValueDecl *D, DSAStackTy::DSAVarData DVar, bool IsLoopIterVar=false)
OMPClause * ActOnOpenMPIsDevicePtrClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'is_device_ptr' clause.
SourceLocation getFirstScheduleModifierLoc() const
Get the first modifier location.
static OMPTargetParallelForDirective * 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.
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.
bool IsOpenMPCapturedByRef(ValueDecl *D, unsigned Level)
Return true if the provided declaration VD should be captured by reference.
const TargetInfo & getTargetInfo() const
void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer)
Finish current declare reduction construct initializer.
StmtResult ActOnOpenMPTargetParallelDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target parallel' after parsing of the associated statement...
void ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
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.
static ValueDecl * getCanonicalDecl(ValueDecl *D)
OMPClause * ActOnOpenMPFromClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'from' clause.
static DeclRefExpr * buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, SourceLocation Loc, bool RefersToCapture=false)
static ExprResult buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, Scope *S, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, QualType Ty, CXXCastPath &BasePath, Expr *UnresolvedReduction)
Concrete class used by the front-end to report problems and issues.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
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]).
Look up the name of an OpenMP user-defined reduction operation.
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...
OMPClause * ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'map' clause.
This represents 'final' clause in the '#pragma omp ...' directive.
This represents 'mergeable' clause in the '#pragma omp ...' directive.
bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target code offload 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.
void append(iterator I, iterator E)
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...
static unsigned CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA, OMPLoopDirective::HelperExprs &Built)
Called on a for stmt to check itself and nested loops (if any).
static DeclRefExpr * buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, bool WithInit)
bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a worksharing directive.
static OMPTargetEnterDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive with a list of Clauses.
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.
detail::InMemoryDirectory::const_iterator I
static T filterLookupForUDR(SmallVectorImpl< UnresolvedSet< 8 >> &Lookups, const llvm::function_ref< T(ValueDecl *)> &Gen)
OMPClause * ActOnOpenMPSafelenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'safelen' clause.
void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var)
Mark a variable referenced, and check whether it is odr-used (C++ [basic.def.odr]p2, C99 6.9p3).
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.
The lookup results will be used for redeclaration of a name, if an entity by that name already exists...
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.
static const Decl * getDefinition(const Decl *D)
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.
static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, Expr *NumIterations, Sema &SemaRef, Scope *S, DSAStackTy *Stack)
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.
bool isOpenMPPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of private clauses like 'private', 'firstprivate', 'reduction' etc.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat)
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.
sema::FunctionScopeInfo * getEnclosingFunction() const
bool isMoreQualifiedThan(QualType Other) const
Determine whether this type is more qualified than the other given type, requiring exact equality for...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
static OMPTargetDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static OMPIsDevicePtrClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
This represents implicit clause 'depend' for the '#pragma omp task' directive.
static OMPFlushClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
Allows QualTypes to be sorted and hence used in maps and sets.
const Type * getTypePtrOrNull() const
This represents 'proc_bind' clause in the '#pragma omp ...' directive.
This represents 'capture' clause in the '#pragma omp atomic' directive.
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Expr - This represents one expression.
void StartOpenMPClause(OpenMPClauseKind K)
Start analysis of clauses.
Allow any unmodeled side effect.
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
bool isDeclScope(Decl *D)
isDeclScope - Return true if this is the scope that the specified decl is declared in...
bool isAnyComplexType() const
void ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner)
Finish current declare reduction construct initializer.
void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath)
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)
OMPDeclareReductionDecl * getPrevDeclInScope()
Get reference to previous declare reduction construct in the same scope with the same name...
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'.
void PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP=nullptr, const Decl *D=nullptr, const BlockExpr *blkExpr=nullptr)
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, ValueDecl *VD)
OMPClause * ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc)
Called on well-formed 'defaultmap' clause.
static FloatingLiteral * Create(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L)
bool RequireCompleteType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
bool builtAll()
Check if all the expressions are built (does not check the worksharing ones).
This represents 'ordered' clause in the '#pragma omp ...' directive.
void DiscardCleanupsInEvaluationContext()
Expr * PrevUB
PreviousUpperBound - local variable passed to runtime in the enclosing schedule or null if that does ...
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...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
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)
StmtResult ActOnOpenMPTargetParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel for' after parsing of the associated statement...
StmtResult ActOnOpenMPParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for simd' after parsing of the associated statement...
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
DiagnosticsEngine & getDiagnostics() const
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.
void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext=true)
Add this decl to the scope shadowed decl chains.
static Expr * buildPostUpdate(Sema &S, ArrayRef< Expr * > PostUpdates)
Build postupdate expression for the given list of postupdates expressions.
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.
StmtResult ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute parallel for simd' after parsing of the associated stat...
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.
StmtResult ActOnOpenMPDistributeParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute parallel for' after parsing of the associated statement...
VarDecl * getCanonicalDecl() override
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.
void checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D)
Check declaration inside target region.
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 bool CheckArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
Return true if it can be proven that the provided array expression (array section or array subscript)...
static Expr * getOrderedNumberExpr(ArrayRef< OMPClause * > Clauses)
This captures a statement into a function.
SmallVector< Expr *, 4 > Counters
Counters Loop counters.
static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, llvm::MapVector< Expr *, DeclRefExpr * > *Captures=nullptr)
Build 'VarRef = Start + Iter * Step'.
static OMPFirstprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PrivateVL, ArrayRef< Expr * > InitVL, Stmt *PreInit)
Creates clause with a list of variables VL.
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.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
StmtResult ActOnOpenMPTaskDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp task' after parsing of the associated statement.
This represents '#pragma omp declare reduction ...' directive.
OMPClause * ActOnOpenMPPrivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'private' clause.
bool isConstant(const ASTContext &Ctx) const
Pseudo declaration for capturing expressions.
StmtResult ActOnOpenMPDistributeSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute simd' after parsing of the associated statement...
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.
VarDecl * IsOpenMPCapturedDecl(ValueDecl *D)
Check if the specified variable is used in one of the private clauses (private, firstprivate, lastprivate, reduction etc.) in OpenMP constructs.
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...
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.
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, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
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 getSuppressAllDiagnostics() const
OMPClause * ActOnOpenMPToClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'to' clause.
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
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
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
StmtResult ActOnCapturedRegionEnd(Stmt *S)
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
StmtResult ActOnOpenMPParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for' after parsing of the associated statement.
StmtResult ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancellation point'.
OpenMPLinearClauseKind Modifier
Modifier of 'linear' clause.
ExprResult DefaultLvalueConversion(Expr *E)
C-style initialization with assignment.
This file defines OpenMP nodes for declarative directives.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
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.
static OMPFromClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
bool isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of the composite or combined directives that need loop ...
void addDecl(NamedDecl *D)
Describes the kind of initialization being performed, along with location information for tokens rela...
This declaration is only a declaration.
OMPClause * ActOnOpenMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'seq_cst' clause.
SourceLocation getBegin() const
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
static void checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, MappableVarListInfo &MVLI, SourceLocation StartLoc, OpenMPMapClauseKind MapType=OMPC_MAP_unknown, bool IsMapTypeImplicit=false)
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 isExternCXXContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
bool isDynamicClass() const
OMPClause * ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'dist_schedule' clause.
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)
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.
void diagnoseTypo(const TypoCorrection &Correction, const PartialDiagnostic &TypoDiag, bool ErrorRecovery=true)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T-> getSizeExpr()))
OMPClause * ActOnOpenMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_threads' clause.
static ExprResult BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, llvm::MapVector< Expr *, DeclRefExpr * > &Captures)
Build 'VarRef = Start.
static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls)
static Stmt * buildPreInits(ASTContext &Context, SmallVectorImpl< Decl * > &PreInits)
Build preinits statement for the given declarations.
OpenMPScheduleClauseModifier
OpenMP modifiers for 'schedule' clause.
This represents 'device' clause in the '#pragma omp ...' directive.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
StmtResult ActOnOpenMPDistributeDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute' after parsing of the associated statement.
SmallVector< Expr *, 4 > Inits
Expressions for loop counters inits for CodeGen.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
void ActOnCapturedRegionError()
static std::string getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, ArrayRef< unsigned > Exclude=llvm::None)
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.
DeclarationName - The name of a declaration.
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
static OMPCapturedExprDecl * buildCaptureDecl(Sema &S, IdentifierInfo *Id, Expr *CaptureExpr, bool WithInit, bool AsExpression)
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...
void PushDeclContext(Scope *S, DeclContext *DC)
Set the current declaration context until it gets popped.
This represents clause 'linear' in the '#pragma omp ...' directives.
static bool checkGrainsizeNumTasksClauses(Sema &S, ArrayRef< OMPClause * > Clauses)
DeclarationNameInfo getDirectiveName() const
Return name of the directive.
StmtResult ActOnOpenMPTaskgroupDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskgroup'.
detail::InMemoryDirectory::const_iterator E
bool isAmbiguous(CanQualType BaseType)
Determine whether the path from the most-derived type to the given base type is ambiguous (i...
static Expr * CheckMapClauseExpressionBase(Sema &SemaRef, Expr *E, OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, OpenMPClauseKind CKind)
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd(Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid)
Called at the end of '#pragma omp declare reduction'.
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
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...
static bool CheckArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
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...
ExprResult IgnoredValueConversions(Expr *E)
IgnoredValueConversions - Given that an expression's result is syntactically ignored, perform any conversions that are required.
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.
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
NamedDecl * getCorrectionDecl() const
Gets the pointer to the declaration of the typo correction.
Not an overloaded operator.
Expr * getSafelen() const
Return safe iteration space distance.
void ActOnFinishOpenMPDeclareTargetDirective()
Called at the end of target region i.e. '#pragme omp end declare target'.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
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)
static OMPLastprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
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'...
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.
static bool checkSimdlenSafelenSpecified(Sema &S, const ArrayRef< OMPClause * > Clauses)
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, TypeResult ParsedType)
Check if the specified type is allowed to be used in 'omp declare reduction' construct.
ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *InputExpr)
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)
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
OMPThreadPrivateDecl * CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef< Expr * > VarList)
Builds a new OpenMPThreadPrivateDecl and checks its correctness.
QualType getPointeeType() const
bool isTLSSupported() const
Whether the target supports thread-local storage.
static OMPUseDevicePtrClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
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).
Call-style initialization (C++98)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
static OMPTaskyieldDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
StmtResult ActOnOpenMPSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp simd' after parsing of the associated statement.
void setSuppressAllDiagnostics(bool Val=true)
Suppress all diagnostics, to silence the front end when we know that we don't want any more diagnosti...
Expr * UB
UpperBound - local variable passed to runtime.
static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, Sema &SemaRef, Decl *D)
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)
void ActOnOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id, OMPDeclareTargetDeclAttr::MapTypeTy MT, NamedDeclSetType &SameDirectiveDecls)
Called on correct id-expression from the '#pragma omp declare target'.
Represents a C++ struct/union/class.
This represents 'num_tasks' clause in the '#pragma omp ...' directive.
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
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.
static bool HasMapClause(ArrayRef< OMPClause * > Clauses)
Check for existence of a map clause in the list of clauses.
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, QualType Derived, const CXXBasePath &Path, unsigned DiagID, bool ForceCheck=false, bool ForceUnprivileged=false)
Checks access for a hierarchy conversion.
bool isOverloadableType() const
Determines whether this is a type for which one can define an overloaded operator.
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 OMPMapClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists, OpenMPMapClauseKind TypeModifier, OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc)
Creates clause with a list of variables VL.
static OMPSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
Defines the clang::TargetInfo interface.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
static OMPTaskgroupDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt)
Creates directive.
This represents 'dist_schedule' clause in the '#pragma omp ...' directive.
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, bool IsMapTypeImplicit, SourceLocation DepLinMapLoc)
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.
Stmt * PreInits
Init statement for all captured expressions.
bool isValid() const
A scope specifier is present, and it refers to a real scope.
A reference to a declared variable, function, enum, etc.
bool isSet() const
Deprecated.
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.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
static OMPTargetParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
SmallVector< CompoundScopeInfo, 4 > CompoundScopes
The stack of currently active compound stamement scopes in the function.
An l-value expression is a reference to an object with independent storage.
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.
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...
ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E, bool IsConstexpr=false)
CheckBooleanCondition - Diagnose problems involving the use of the given expression as a boolean cond...
NamedDecl - This represents a decl with a name.
static bool CheckMapConflicts(Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, Expr *E, bool CurrentRegionOnly, OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, OpenMPClauseKind CKind)
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.
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)
static OMPClauseWithPostUpdate * get(OMPClause *C)
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.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Describes an entity that is being initialized.
StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef< OMPClause * > Clauses)
End of OpenMP region.
SourceLocation ColonLoc
Location of ':'.
This represents '#pragma omp threadprivate ...' directive.
Represents the canonical version of C arrays with a specified constant size.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
void clear()
Clears out any current state.
void PushFunctionScope()
Enter a new function scope.
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Attr - This represents one attribute.
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).
Helper class that creates diagnostics with optional template instantiation stacks.
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, ExprObjectKind OK, SourceLocation Loc)
StmtResult ActOnOpenMPTaskLoopSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop simd' after parsing of the associated statement...
StmtResult ActOnOpenMPTargetExitDataDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target exit data' after parsing of the associated statement...
void FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S, bool ConsiderLinkage, bool AllowInlineNamespace)
Filters out lookup results that don't fall within the given scope as determined by isDeclInScope...
bool isPointerType() const