39#include "llvm/ADT/IndexedMap.h"
40#include "llvm/ADT/PointerEmbeddedInt.h"
41#include "llvm/ADT/STLExtras.h"
42#include "llvm/ADT/Sequence.h"
43#include "llvm/ADT/SetVector.h"
44#include "llvm/ADT/SmallSet.h"
45#include "llvm/ADT/StringExtras.h"
46#include "llvm/Frontend/OpenMP/OMPAssume.h"
47#include "llvm/Frontend/OpenMP/OMPConstants.h"
48#include "llvm/IR/Assumptions.h"
52using namespace llvm::omp;
65enum DefaultDataSharingAttributes {
70 DSA_firstprivate = 1 << 3,
80 unsigned Modifier = 0;
81 const Expr *RefExpr =
nullptr;
84 bool AppliedToPointee =
false;
85 DSAVarData() =
default;
89 bool AppliedToPointee)
90 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
91 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
92 AppliedToPointee(AppliedToPointee) {}
94 using OperatorOffsetTy =
96 using DoacrossClauseMapTy = llvm::DenseMap<OMPClause *, OperatorOffsetTy>;
98 enum class UsesAllocatorsDeclKind {
102 UserDefinedAllocator,
110 unsigned Modifier = 0;
113 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
117 bool AppliedToPointee =
false;
119 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
120 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
121 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
122 using LoopControlVariablesMapTy =
123 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
126 struct MappedExprComponentTy {
130 using MappedExprComponentsTy =
131 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
132 using CriticalsWithHintsTy =
133 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
134 struct ReductionData {
135 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
137 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
138 ReductionData() =
default;
145 ReductionOp = RefExpr;
148 using DeclReductionMapTy =
149 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
150 struct DefaultmapInfo {
154 DefaultmapInfo() =
default;
156 : ImplicitBehavior(M), SLoc(
Loc) {}
159 struct SharingMapTy {
160 DeclSAMapTy SharingMap;
161 DeclReductionMapTy ReductionMap;
162 UsedRefMapTy AlignedMap;
163 UsedRefMapTy NontemporalMap;
164 MappedExprComponentsTy MappedExprComponents;
165 LoopControlVariablesMapTy LCVMap;
166 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
171 Scope *CurScope =
nullptr;
177 DoacrossClauseMapTy DoacrossDepends;
181 std::optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
182 bool RegionHasOrderConcurrent =
false;
183 unsigned AssociatedLoops = 1;
184 bool HasMutipleLoops =
false;
185 const Decl *PossiblyLoopCounter =
nullptr;
186 bool NowaitRegion =
false;
187 bool UntiedRegion =
false;
188 bool CancelRegion =
false;
189 bool LoopStart =
false;
190 bool BodyComplete =
false;
195 Expr *TaskgroupReductionRef =
nullptr;
196 llvm::DenseSet<QualType> MappedClassesQualTypes;
198 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates;
203 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective;
204 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
208 struct ImplicitDefaultFDInfoTy {
212 size_t StackLevel = 0;
215 ImplicitDefaultFDInfoTy(
const FieldDecl *FD,
size_t StackLevel,
217 : FD(FD), StackLevel(StackLevel), VD(VD) {}
221 ImplicitDefaultFirstprivateFDs;
222 Expr *DeclareMapperVar =
nullptr;
226 :
Directive(DKind), DirectiveName(Name), CurScope(CurScope),
228 SharingMapTy() =
default;
234 DeclSAMapTy Threadprivates;
241 bool ForceCapturing =
false;
244 bool ForceCaptureByReferenceInTargetExecutable =
false;
245 CriticalsWithHintsTy Criticals;
246 unsigned IgnoredStackElements = 0;
250 using const_iterator = StackTy::const_reverse_iterator;
251 const_iterator begin()
const {
252 return Stack.empty() ? const_iterator()
253 : Stack.back().first.rbegin() + IgnoredStackElements;
255 const_iterator end()
const {
256 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
258 using iterator = StackTy::reverse_iterator;
260 return Stack.empty() ? iterator()
261 : Stack.back().first.rbegin() + IgnoredStackElements;
264 return Stack.empty() ? iterator() : Stack.back().first.rend();
269 bool isStackEmpty()
const {
270 return Stack.empty() ||
271 Stack.back().second != CurrentNonCapturingFunctionScope ||
272 Stack.back().first.size() <= IgnoredStackElements;
274 size_t getStackSize()
const {
275 return isStackEmpty() ? 0
276 : Stack.back().first.size() - IgnoredStackElements;
279 SharingMapTy *getTopOfStackOrNull() {
280 size_t Size = getStackSize();
283 return &Stack.back().first[
Size - 1];
285 const SharingMapTy *getTopOfStackOrNull()
const {
286 return const_cast<DSAStackTy &
>(*this).getTopOfStackOrNull();
288 SharingMapTy &getTopOfStack() {
289 assert(!isStackEmpty() &&
"no current directive");
290 return *getTopOfStackOrNull();
292 const SharingMapTy &getTopOfStack()
const {
293 return const_cast<DSAStackTy &
>(*this).getTopOfStack();
296 SharingMapTy *getSecondOnStackOrNull() {
297 size_t Size = getStackSize();
300 return &Stack.back().first[
Size - 2];
302 const SharingMapTy *getSecondOnStackOrNull()
const {
303 return const_cast<DSAStackTy &
>(*this).getSecondOnStackOrNull();
312 SharingMapTy &getStackElemAtLevel(
unsigned Level) {
313 assert(Level < getStackSize() &&
"no such stack element");
314 return Stack.back().first[
Level];
316 const SharingMapTy &getStackElemAtLevel(
unsigned Level)
const {
317 return const_cast<DSAStackTy &
>(*this).getStackElemAtLevel(Level);
323 bool isOpenMPLocal(
VarDecl *
D, const_iterator
Iter)
const;
336 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
345 explicit DSAStackTy(
Sema &S) : SemaRef(S) {}
348 void setOMPAllocatorHandleT(
QualType Ty) { OMPAllocatorHandleT = Ty; }
350 QualType getOMPAllocatorHandleT()
const {
return OMPAllocatorHandleT; }
352 void setOMPAlloctraitT(
QualType Ty) { OMPAlloctraitT = Ty; }
354 QualType getOMPAlloctraitT()
const {
return OMPAlloctraitT; }
356 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
358 OMPPredefinedAllocators[AllocatorKind] = Allocator;
361 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind)
const {
362 return OMPPredefinedAllocators[AllocatorKind];
365 void setOMPDependT(
QualType Ty) { OMPDependT = Ty; }
367 QualType getOMPDependT()
const {
return OMPDependT; }
370 void setOMPEventHandleT(
QualType Ty) { OMPEventHandleT = Ty; }
372 QualType getOMPEventHandleT()
const {
return OMPEventHandleT; }
374 bool isClauseParsingMode()
const {
return ClauseKindMode != OMPC_unknown; }
376 assert(isClauseParsingMode() &&
"Must be in clause parsing mode.");
377 return ClauseKindMode;
381 bool isBodyComplete()
const {
382 const SharingMapTy *Top = getTopOfStackOrNull();
383 return Top && Top->BodyComplete;
385 void setBodyComplete() { getTopOfStack().BodyComplete =
true; }
387 bool isForceVarCapturing()
const {
return ForceCapturing; }
388 void setForceVarCapturing(
bool V) { ForceCapturing =
V; }
390 void setForceCaptureByReferenceInTargetExecutable(
bool V) {
391 ForceCaptureByReferenceInTargetExecutable =
V;
393 bool isForceCaptureByReferenceInTargetExecutable()
const {
394 return ForceCaptureByReferenceInTargetExecutable;
399 assert(!IgnoredStackElements &&
400 "cannot change stack while ignoring elements");
402 Stack.back().second != CurrentNonCapturingFunctionScope)
403 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
404 Stack.back().first.emplace_back(DKind, DirName, CurScope,
Loc);
405 Stack.back().first.back().DefaultAttrLoc =
Loc;
409 assert(!IgnoredStackElements &&
410 "cannot change stack while ignoring elements");
411 assert(!Stack.back().first.empty() &&
412 "Data-sharing attributes stack is empty!");
413 Stack.back().first.pop_back();
418 class ParentDirectiveScope {
423 ParentDirectiveScope(DSAStackTy &Self,
bool Activate)
424 : Self(Self), Active(
false) {
428 ~ParentDirectiveScope() { disable(); }
431 --Self.IgnoredStackElements;
437 ++Self.IgnoredStackElements;
446 "Expected loop-based directive.");
447 getTopOfStack().LoopStart =
true;
452 "Expected loop-based directive.");
453 getTopOfStack().LoopStart =
false;
456 bool isLoopStarted()
const {
458 "Expected loop-based directive.");
459 return !getTopOfStack().LoopStart;
462 void resetPossibleLoopCounter(
const Decl *
D =
nullptr) {
466 const Decl *getPossiblyLoopCounter()
const {
467 return getTopOfStack().PossiblyLoopCounter;
470 void pushFunction() {
471 assert(!IgnoredStackElements &&
472 "cannot change stack while ignoring elements");
474 assert(!isa<CapturingScopeInfo>(CurFnScope));
475 CurrentNonCapturingFunctionScope = CurFnScope;
479 assert(!IgnoredStackElements &&
480 "cannot change stack while ignoring elements");
481 if (!Stack.empty() && Stack.back().second == OldFSI) {
482 assert(Stack.back().first.empty());
485 CurrentNonCapturingFunctionScope =
nullptr;
487 if (!isa<CapturingScopeInfo>(FSI)) {
488 CurrentNonCapturingFunctionScope = FSI;
495 Criticals.try_emplace(
D->getDirectiveName().getAsString(),
D, Hint);
497 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
499 auto I = Criticals.find(Name.getAsString());
500 if (I != Criticals.end())
502 return std::make_pair(
nullptr, llvm::APSInt());
519 const LCDeclInfo isLoopControlVariable(
const ValueDecl *
D)
const;
524 const LCDeclInfo isParentLoopControlVariable(
const ValueDecl *
D)
const;
529 const LCDeclInfo isLoopControlVariable(
const ValueDecl *
D,
530 unsigned Level)
const;
533 const ValueDecl *getParentLoopControlVariable(
unsigned I)
const;
536 void markDeclAsUsedInScanDirective(
ValueDecl *
D) {
537 if (SharingMapTy *Stack = getSecondOnStackOrNull())
538 Stack->UsedInScanDirective.insert(
D);
542 bool isUsedInScanDirective(
ValueDecl *
D)
const {
543 if (
const SharingMapTy *Stack = getTopOfStackOrNull())
544 return Stack->UsedInScanDirective.contains(
D);
550 DeclRefExpr *PrivateCopy =
nullptr,
unsigned Modifier = 0,
551 bool AppliedToPointee =
false);
560 const Expr *ReductionRef);
566 Expr *&TaskgroupDescriptor)
const;
571 const Expr *&ReductionRef,
572 Expr *&TaskgroupDescriptor)
const;
575 Expr *getTaskgroupReductionRef()
const {
576 assert((getTopOfStack().
Directive == OMPD_taskgroup ||
580 "taskgroup reference expression requested for non taskgroup or "
581 "parallel/worksharing directive.");
582 return getTopOfStack().TaskgroupReductionRef;
586 bool isTaskgroupReductionRef(
const ValueDecl *VD,
unsigned Level)
const {
587 return getStackElemAtLevel(Level).TaskgroupReductionRef &&
588 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
594 const DSAVarData getTopDSA(
ValueDecl *
D,
bool FromParent);
596 const DSAVarData getImplicitDSA(
ValueDecl *
D,
bool FromParent)
const;
598 const DSAVarData getImplicitDSA(
ValueDecl *
D,
unsigned Level)
const;
605 DefaultDataSharingAttributes)>
608 bool FromParent)
const;
616 bool FromParent)
const;
623 unsigned Level,
bool NotLastprivate =
false)
const;
627 bool hasExplicitDirective(
629 unsigned Level)
const;
633 const llvm::function_ref<
bool(
636 bool FromParent)
const;
640 const SharingMapTy *Top = getTopOfStackOrNull();
641 return Top ? Top->Directive : OMPD_unknown;
645 assert(!isStackEmpty() &&
"No directive at specified level.");
646 return getStackElemAtLevel(Level).Directive;
650 unsigned OpenMPCaptureLevel)
const {
653 return CaptureRegions[OpenMPCaptureLevel];
657 const SharingMapTy *
Parent = getSecondOnStackOrNull();
662 void addRequiresDecl(
OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); }
665 template <
typename ClauseType>
bool hasRequiresDeclWithClause()
const {
667 return llvm::any_of(
D->clauselists(), [](
const OMPClause *
C) {
668 return isa<ClauseType>(C);
676 bool IsDuplicate =
false;
679 for (
const OMPClause *CPrev :
D->clauselists()) {
680 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
681 SemaRef.
Diag(CNew->getBeginLoc(),
682 diag::err_omp_requires_clause_redeclaration)
683 << getOpenMPClauseName(CNew->getClauseKind());
684 SemaRef.
Diag(CPrev->getBeginLoc(),
685 diag::note_omp_requires_previous_clause)
686 << getOpenMPClauseName(CPrev->getClauseKind());
697 TargetLocations.push_back(LocStart);
703 AtomicLocation =
Loc;
708 SourceLocation getAtomicDirectiveLoc()
const {
return AtomicLocation; }
712 return TargetLocations;
717 getTopOfStack().DefaultAttr = DSA_none;
718 getTopOfStack().DefaultAttrLoc =
Loc;
722 getTopOfStack().DefaultAttr = DSA_shared;
723 getTopOfStack().DefaultAttrLoc =
Loc;
727 getTopOfStack().DefaultAttr = DSA_private;
728 getTopOfStack().DefaultAttrLoc =
Loc;
732 getTopOfStack().DefaultAttr = DSA_firstprivate;
733 getTopOfStack().DefaultAttrLoc =
Loc;
738 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[
Kind];
739 DMI.ImplicitBehavior = M;
745 return getTopOfStack()
746 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
749 .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
752 .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
754 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
759 return ConstructTraits;
764 ConstructTraits.append(Traits.begin(), Traits.end());
766 for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits)) {
767 llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val();
768 assert(Top == Trait &&
"Something left a trait on the stack!");
774 DefaultDataSharingAttributes getDefaultDSA(
unsigned Level)
const {
775 return getStackSize() <=
Level ? DSA_unspecified
776 : getStackElemAtLevel(Level).DefaultAttr;
778 DefaultDataSharingAttributes getDefaultDSA()
const {
779 return isStackEmpty() ? DSA_unspecified : getTopOfStack().DefaultAttr;
782 return isStackEmpty() ?
SourceLocation() : getTopOfStack().DefaultAttrLoc;
786 return isStackEmpty()
788 : getTopOfStack().DefaultmapMap[
Kind].ImplicitBehavior;
791 getDefaultmapModifierAtLevel(
unsigned Level,
793 return getStackElemAtLevel(Level).DefaultmapMap[
Kind].ImplicitBehavior;
795 bool isDefaultmapCapturedByRef(
unsigned Level,
798 getDefaultmapModifierAtLevel(Level, Kind);
799 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
800 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
801 (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
802 (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
803 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom) ||
804 (M == OMPC_DEFAULTMAP_MODIFIER_present);
811 case OMPC_DEFAULTMAP_scalar:
812 case OMPC_DEFAULTMAP_pointer:
814 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
815 (M == OMPC_DEFAULTMAP_MODIFIER_default);
816 case OMPC_DEFAULTMAP_aggregate:
817 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
821 llvm_unreachable(
"Unexpected OpenMPDefaultmapClauseKind enum");
823 bool mustBeFirstprivateAtLevel(
unsigned Level,
826 getDefaultmapModifierAtLevel(Level, Kind);
827 return mustBeFirstprivateBase(M, Kind);
831 return mustBeFirstprivateBase(M, Kind);
836 const DSAVarData DVar = getTopDSA(
D,
false);
841 void setOrderedRegion(
bool IsOrdered,
const Expr *Param,
844 getTopOfStack().OrderedRegion.emplace(Param, Clause);
846 getTopOfStack().OrderedRegion.reset();
850 bool isOrderedRegion()
const {
851 if (
const SharingMapTy *Top = getTopOfStackOrNull())
852 return Top->OrderedRegion.has_value();
856 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam()
const {
857 if (
const SharingMapTy *Top = getTopOfStackOrNull())
858 if (Top->OrderedRegion)
859 return *Top->OrderedRegion;
860 return std::make_pair(
nullptr,
nullptr);
864 bool isParentOrderedRegion()
const {
865 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
866 return Parent->OrderedRegion.has_value();
870 std::pair<const Expr *, OMPOrderedClause *>
871 getParentOrderedRegionParam()
const {
872 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
873 if (
Parent->OrderedRegion)
874 return *
Parent->OrderedRegion;
875 return std::make_pair(
nullptr,
nullptr);
878 void setRegionHasOrderConcurrent(
bool HasOrderConcurrent) {
879 getTopOfStack().RegionHasOrderConcurrent = HasOrderConcurrent;
883 bool isParentOrderConcurrent()
const {
884 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
885 return Parent->RegionHasOrderConcurrent;
889 void setNowaitRegion(
bool IsNowait =
true) {
890 getTopOfStack().NowaitRegion = IsNowait;
894 bool isParentNowaitRegion()
const {
895 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
896 return Parent->NowaitRegion;
900 void setUntiedRegion(
bool IsUntied =
true) {
901 getTopOfStack().UntiedRegion = IsUntied;
904 bool isUntiedRegion()
const {
905 const SharingMapTy *Top = getTopOfStackOrNull();
906 return Top ? Top->UntiedRegion :
false;
909 void setParentCancelRegion(
bool Cancel =
true) {
910 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
911 Parent->CancelRegion |= Cancel;
914 bool isCancelRegion()
const {
915 const SharingMapTy *Top = getTopOfStackOrNull();
916 return Top ? Top->CancelRegion :
false;
921 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
925 bool doesParentHasScanDirective()
const {
926 const SharingMapTy *Top = getSecondOnStackOrNull();
927 return Top ? Top->PrevScanLocation.isValid() :
false;
931 const SharingMapTy *Top = getSecondOnStackOrNull();
936 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
940 bool doesParentHasOrderedDirective()
const {
941 const SharingMapTy *Top = getSecondOnStackOrNull();
942 return Top ? Top->PrevOrderedLocation.isValid() :
false;
946 const SharingMapTy *Top = getSecondOnStackOrNull();
951 void setAssociatedLoops(
unsigned Val) {
952 getTopOfStack().AssociatedLoops = Val;
954 getTopOfStack().HasMutipleLoops =
true;
957 unsigned getAssociatedLoops()
const {
958 const SharingMapTy *Top = getTopOfStackOrNull();
959 return Top ? Top->AssociatedLoops : 0;
962 bool hasMutipleLoops()
const {
963 const SharingMapTy *Top = getTopOfStackOrNull();
964 return Top ? Top->HasMutipleLoops :
false;
970 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
971 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
974 bool hasInnerTeamsRegion()
const {
975 return getInnerTeamsRegionLoc().
isValid();
979 const SharingMapTy *Top = getTopOfStackOrNull();
983 Scope *getCurScope()
const {
984 const SharingMapTy *Top = getTopOfStackOrNull();
985 return Top ? Top->CurScope :
nullptr;
987 void setContext(
DeclContext *DC) { getTopOfStack().Context = DC; }
989 const SharingMapTy *Top = getTopOfStackOrNull();
995 bool checkMappableExprComponentListsForDecl(
996 const ValueDecl *VD,
bool CurrentRegionOnly,
997 const llvm::function_ref<
1009 if (CurrentRegionOnly)
1012 std::advance(SI, 1);
1014 for (; SI != SE; ++SI) {
1015 auto MI = SI->MappedExprComponents.find(VD);
1016 if (MI != SI->MappedExprComponents.end())
1018 MI->second.Components)
1019 if (Check(L, MI->second.Kind))
1027 bool checkMappableExprComponentListsForDeclAtLevel(
1029 const llvm::function_ref<
1033 if (getStackSize() <= Level)
1036 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1037 auto MI = StackElem.MappedExprComponents.find(VD);
1038 if (MI != StackElem.MappedExprComponents.end())
1040 MI->second.Components)
1041 if (Check(L, MI->second.Kind))
1048 void addMappableExpressionComponents(
1052 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
1054 MEC.Components.resize(MEC.Components.size() + 1);
1055 MEC.Components.back().append(Components.begin(), Components.end());
1056 MEC.Kind = WhereFoundClauseKind;
1059 unsigned getNestingLevel()
const {
1060 assert(!isStackEmpty());
1061 return getStackSize() - 1;
1063 void addDoacrossDependClause(
OMPClause *
C,
const OperatorOffsetTy &OpsOffs) {
1064 SharingMapTy *
Parent = getSecondOnStackOrNull();
1066 Parent->DoacrossDepends.try_emplace(
C, OpsOffs);
1068 llvm::iterator_range<DoacrossClauseMapTy::const_iterator>
1069 getDoacrossDependClauses()
const {
1070 const SharingMapTy &StackElem = getTopOfStack();
1072 const DoacrossClauseMapTy &Ref = StackElem.DoacrossDepends;
1073 return llvm::make_range(Ref.begin(), Ref.end());
1075 return llvm::make_range(StackElem.DoacrossDepends.end(),
1076 StackElem.DoacrossDepends.end());
1080 void addMappedClassesQualTypes(
QualType QT) {
1081 SharingMapTy &StackElem = getTopOfStack();
1082 StackElem.MappedClassesQualTypes.insert(QT);
1086 bool isClassPreviouslyMapped(
QualType QT)
const {
1087 const SharingMapTy &StackElem = getTopOfStack();
1088 return StackElem.MappedClassesQualTypes.contains(QT);
1092 void addToParentTargetRegionLinkGlobals(
DeclRefExpr *
E) {
1093 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1094 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1095 "Expected declare target link global.");
1096 for (
auto &Elem : *
this) {
1098 Elem.DeclareTargetLinkVarDecls.push_back(
E);
1108 "Expected target executable directive.");
1109 return getTopOfStack().DeclareTargetLinkVarDecls;
1113 void addInnerAllocatorExpr(
Expr *
E) {
1114 getTopOfStack().InnerUsedAllocators.push_back(
E);
1118 return getTopOfStack().InnerUsedAllocators;
1122 void addImplicitTaskFirstprivate(
unsigned Level,
Decl *
D) {
1123 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(
D);
1126 bool isImplicitTaskFirstprivate(
Decl *
D)
const {
1127 return getTopOfStack().ImplicitTaskFirstprivates.contains(
D);
1131 void addUsesAllocatorsDecl(
const Decl *
D, UsesAllocatorsDeclKind Kind) {
1132 getTopOfStack().UsesAllocatorsDecls.try_emplace(
D, Kind);
1136 std::optional<UsesAllocatorsDeclKind>
1137 isUsesAllocatorsDecl(
unsigned Level,
const Decl *
D)
const {
1138 const SharingMapTy &StackElem = getTopOfStack();
1139 auto I = StackElem.UsesAllocatorsDecls.find(
D);
1140 if (I == StackElem.UsesAllocatorsDecls.end())
1141 return std::nullopt;
1142 return I->getSecond();
1144 std::optional<UsesAllocatorsDeclKind>
1145 isUsesAllocatorsDecl(
const Decl *
D)
const {
1146 const SharingMapTy &StackElem = getTopOfStack();
1147 auto I = StackElem.UsesAllocatorsDecls.find(
D);
1148 if (I == StackElem.UsesAllocatorsDecls.end())
1149 return std::nullopt;
1150 return I->getSecond();
1153 void addDeclareMapperVarRef(
Expr *Ref) {
1154 SharingMapTy &StackElem = getTopOfStack();
1155 StackElem.DeclareMapperVar = Ref;
1157 const Expr *getDeclareMapperVarRef()
const {
1158 const SharingMapTy *Top = getTopOfStackOrNull();
1159 return Top ? Top->DeclareMapperVar :
nullptr;
1163 void addIteratorVarDecl(
VarDecl *VD) {
1164 SharingMapTy &StackElem = getTopOfStack();
1168 bool isIteratorVarDecl(
const VarDecl *VD)
const {
1169 const SharingMapTy *Top = getTopOfStackOrNull();
1177 const_iterator I = begin();
1178 const_iterator EndI = end();
1179 size_t StackLevel = getStackSize();
1180 for (; I != EndI; ++I) {
1181 if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1185 assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1188 for (
const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1189 if (IFD.FD == FD && IFD.StackLevel == StackLevel)
1194 bool isImplicitDefaultFirstprivateFD(
VarDecl *VD)
const {
1195 const_iterator I = begin();
1196 const_iterator EndI = end();
1197 for (; I != EndI; ++I)
1198 if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1202 for (
const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1209 iterator I = begin();
1210 const_iterator EndI = end();
1211 size_t StackLevel = getStackSize();
1212 for (; I != EndI; ++I) {
1213 if (I->DefaultAttr == DSA_private || I->DefaultAttr == DSA_firstprivate) {
1214 I->ImplicitDefaultFirstprivateFDs.emplace_back(FD, StackLevel, VD);
1219 assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1229 DKind == OMPD_unknown;
1235 if (
const auto *FE = dyn_cast<FullExpr>(
E))
1236 E = FE->getSubExpr();
1238 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(
E))
1239 E = MTE->getSubExpr();
1241 while (
const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(
E))
1242 E = Binder->getSubExpr();
1244 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(
E))
1245 E = ICE->getSubExprAsWritten();
1254 if (
const auto *CED = dyn_cast<OMPCapturedExprDecl>(
D))
1255 if (
const auto *ME = dyn_cast<MemberExpr>(
getExprAsWritten(CED->getInit())))
1256 D = ME->getMemberDecl();
1267DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &
Iter,
1270 auto *VD = dyn_cast<VarDecl>(
D);
1271 const auto *FD = dyn_cast<FieldDecl>(
D);
1273 if (
Iter == end()) {
1280 DVar.CKind = OMPC_shared;
1287 DVar.CKind = OMPC_shared;
1291 DVar.CKind = OMPC_shared;
1302 DVar.CKind = OMPC_private;
1306 DVar.DKind =
Iter->Directive;
1309 if (
Iter->SharingMap.count(
D)) {
1310 const DSAInfo &
Data =
Iter->SharingMap.lookup(
D);
1311 DVar.RefExpr =
Data.RefExpr.getPointer();
1312 DVar.PrivateCopy =
Data.PrivateCopy;
1313 DVar.CKind =
Data.Attributes;
1314 DVar.ImplicitDSALoc =
Iter->DefaultAttrLoc;
1315 DVar.Modifier =
Data.Modifier;
1316 DVar.AppliedToPointee =
Data.AppliedToPointee;
1324 switch (
Iter->DefaultAttr) {
1326 DVar.CKind = OMPC_shared;
1327 DVar.ImplicitDSALoc =
Iter->DefaultAttrLoc;
1331 case DSA_firstprivate:
1334 DVar.CKind = OMPC_unknown;
1336 DVar.CKind = OMPC_firstprivate;
1338 DVar.ImplicitDSALoc =
Iter->DefaultAttrLoc;
1346 DVar.CKind = OMPC_unknown;
1348 DVar.CKind = OMPC_private;
1350 DVar.ImplicitDSALoc =
Iter->DefaultAttrLoc;
1352 case DSA_unspecified:
1357 DVar.ImplicitDSALoc =
Iter->DefaultAttrLoc;
1361 DVar.CKind = OMPC_shared;
1371 DSAVarData DVarTemp;
1372 const_iterator I =
Iter,
E = end();
1380 DVarTemp = getDSA(I,
D);
1381 if (DVarTemp.CKind != OMPC_shared) {
1382 DVar.RefExpr =
nullptr;
1383 DVar.CKind = OMPC_firstprivate;
1386 }
while (I !=
E && !isImplicitTaskingRegion(I->Directive));
1388 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1397 return getDSA(++
Iter,
D);
1401 const Expr *NewDE) {
1402 assert(!isStackEmpty() &&
"Data sharing attributes stack is empty");
1404 SharingMapTy &StackElem = getTopOfStack();
1405 auto [It, Inserted] = StackElem.AlignedMap.try_emplace(
D, NewDE);
1407 assert(NewDE &&
"Unexpected nullptr expr to be added into aligned map");
1410 assert(It->second &&
"Unexpected nullptr expr in the aligned map");
1415 const Expr *NewDE) {
1416 assert(!isStackEmpty() &&
"Data sharing attributes stack is empty");
1418 SharingMapTy &StackElem = getTopOfStack();
1419 auto [It, Inserted] = StackElem.NontemporalMap.try_emplace(
D, NewDE);
1421 assert(NewDE &&
"Unexpected nullptr expr to be added into aligned map");
1424 assert(It->second &&
"Unexpected nullptr expr in the aligned map");
1429 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1431 SharingMapTy &StackElem = getTopOfStack();
1432 StackElem.LCVMap.try_emplace(
1433 D, LCDeclInfo(StackElem.LCVMap.size() + 1,
Capture));
1436const DSAStackTy::LCDeclInfo
1437DSAStackTy::isLoopControlVariable(
const ValueDecl *
D)
const {
1438 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1440 const SharingMapTy &StackElem = getTopOfStack();
1441 auto It = StackElem.LCVMap.find(
D);
1442 if (It != StackElem.LCVMap.end())
1444 return {0,
nullptr};
1447const DSAStackTy::LCDeclInfo
1448DSAStackTy::isLoopControlVariable(
const ValueDecl *
D,
unsigned Level)
const {
1449 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1451 for (
unsigned I = Level + 1; I > 0; --I) {
1452 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1453 auto It = StackElem.LCVMap.find(
D);
1454 if (It != StackElem.LCVMap.end())
1457 return {0,
nullptr};
1460const DSAStackTy::LCDeclInfo
1461DSAStackTy::isParentLoopControlVariable(
const ValueDecl *
D)
const {
1462 const SharingMapTy *
Parent = getSecondOnStackOrNull();
1463 assert(
Parent &&
"Data-sharing attributes stack is empty");
1465 auto It =
Parent->LCVMap.find(
D);
1466 if (It !=
Parent->LCVMap.end())
1468 return {0,
nullptr};
1471const ValueDecl *DSAStackTy::getParentLoopControlVariable(
unsigned I)
const {
1472 const SharingMapTy *
Parent = getSecondOnStackOrNull();
1473 assert(
Parent &&
"Data-sharing attributes stack is empty");
1474 if (
Parent->LCVMap.size() < I)
1476 for (
const auto &Pair :
Parent->LCVMap)
1477 if (Pair.second.first == I)
1484 bool AppliedToPointee) {
1486 if (A == OMPC_threadprivate) {
1487 DSAInfo &
Data = Threadprivates[
D];
1488 Data.Attributes = A;
1489 Data.RefExpr.setPointer(
E);
1490 Data.PrivateCopy =
nullptr;
1491 Data.Modifier = Modifier;
1493 DSAInfo &
Data = getTopOfStack().SharingMap[
D];
1494 assert(
Data.Attributes == OMPC_unknown || (A ==
Data.Attributes) ||
1495 (A == OMPC_firstprivate &&
Data.Attributes == OMPC_lastprivate) ||
1496 (A == OMPC_lastprivate &&
Data.Attributes == OMPC_firstprivate) ||
1497 (isLoopControlVariable(
D).first && A == OMPC_private));
1498 Data.Modifier = Modifier;
1499 if (A == OMPC_lastprivate &&
Data.Attributes == OMPC_firstprivate) {
1500 Data.RefExpr.setInt(
true);
1503 const bool IsLastprivate =
1504 A == OMPC_lastprivate ||
Data.Attributes == OMPC_lastprivate;
1505 Data.Attributes = A;
1506 Data.RefExpr.setPointerAndInt(
E, IsLastprivate);
1507 Data.PrivateCopy = PrivateCopy;
1508 Data.AppliedToPointee = AppliedToPointee;
1510 DSAInfo &
Data = getTopOfStack().SharingMap[PrivateCopy->
getDecl()];
1511 Data.Modifier = Modifier;
1512 Data.Attributes = A;
1513 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1514 Data.PrivateCopy =
nullptr;
1515 Data.AppliedToPointee = AppliedToPointee;
1522 StringRef Name,
const AttrVec *Attrs =
nullptr,
1537 OMPReferencedVarAttr::CreateImplicit(SemaRef.
Context, OrigRef));
1544 bool RefersToCapture =
false) {
1555 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1557 getTopOfStack().SharingMap[
D].Attributes == OMPC_reduction &&
1558 "Additional reduction info may be specified only for reduction items.");
1559 ReductionData &ReductionData = getTopOfStack().ReductionMap[
D];
1560 assert(ReductionData.ReductionRange.isInvalid() &&
1561 (getTopOfStack().
Directive == OMPD_taskgroup ||
1565 "Additional reduction info may be specified only once for reduction "
1567 ReductionData.set(BOK, SR);
1568 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1569 if (!TaskgroupReductionRef) {
1572 TaskgroupReductionRef =
1578 const Expr *ReductionRef) {
1580 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1582 getTopOfStack().SharingMap[
D].Attributes == OMPC_reduction &&
1583 "Additional reduction info may be specified only for reduction items.");
1584 ReductionData &ReductionData = getTopOfStack().ReductionMap[
D];
1585 assert(ReductionData.ReductionRange.isInvalid() &&
1586 (getTopOfStack().
Directive == OMPD_taskgroup ||
1590 "Additional reduction info may be specified only once for reduction "
1592 ReductionData.set(ReductionRef, SR);
1593 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1594 if (!TaskgroupReductionRef) {
1597 TaskgroupReductionRef =
1602const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1604 Expr *&TaskgroupDescriptor)
const {
1606 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty.");
1607 for (const_iterator I = begin() + 1,
E = end(); I !=
E; ++I) {
1608 const DSAInfo &
Data = I->SharingMap.lookup(
D);
1609 if (
Data.Attributes != OMPC_reduction ||
1610 Data.Modifier != OMPC_REDUCTION_task)
1612 const ReductionData &ReductionData = I->ReductionMap.lookup(
D);
1613 if (!ReductionData.ReductionOp ||
1614 isa<const Expr *>(ReductionData.ReductionOp))
1615 return DSAVarData();
1616 SR = ReductionData.ReductionRange;
1617 BOK = cast<ReductionData::BOKPtrType>(ReductionData.ReductionOp);
1618 assert(I->TaskgroupReductionRef &&
"taskgroup reduction reference "
1619 "expression for the descriptor is not "
1621 TaskgroupDescriptor = I->TaskgroupReductionRef;
1622 return DSAVarData(I->Directive, OMPC_reduction,
Data.RefExpr.getPointer(),
1623 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1626 return DSAVarData();
1629const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1631 Expr *&TaskgroupDescriptor)
const {
1633 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty.");
1634 for (const_iterator I = begin() + 1,
E = end(); I !=
E; ++I) {
1635 const DSAInfo &
Data = I->SharingMap.lookup(
D);
1636 if (
Data.Attributes != OMPC_reduction ||
1637 Data.Modifier != OMPC_REDUCTION_task)
1639 const ReductionData &ReductionData = I->ReductionMap.lookup(
D);
1640 if (!ReductionData.ReductionOp ||
1641 !isa<const Expr *>(ReductionData.ReductionOp))
1642 return DSAVarData();
1643 SR = ReductionData.ReductionRange;
1644 ReductionRef = cast<const Expr *>(ReductionData.ReductionOp);
1645 assert(I->TaskgroupReductionRef &&
"taskgroup reduction reference "
1646 "expression for the descriptor is not "
1648 TaskgroupDescriptor = I->TaskgroupReductionRef;
1649 return DSAVarData(I->Directive, OMPC_reduction,
Data.RefExpr.getPointer(),
1650 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1653 return DSAVarData();
1656bool DSAStackTy::isOpenMPLocal(
VarDecl *
D, const_iterator I)
const {
1658 for (const_iterator
E = end(); I !=
E; ++I) {
1659 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1663 Scope *CurScope = getCurScope();
1664 while (CurScope && CurScope != TopScope && !CurScope->
isDeclScope(
D))
1666 return CurScope != TopScope;
1669 if (I->Context == DC)
1678 bool AcceptIfMutable =
true,
1679 bool *IsClassType =
nullptr) {
1681 Type =
Type.getNonReferenceType().getCanonicalType();
1682 bool IsConstant =
Type.isConstant(Context);
1687 if (
const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1689 RD = CTD->getTemplatedDecl();
1692 return IsConstant && !(SemaRef.
getLangOpts().CPlusPlus && RD &&
1699 bool AcceptIfMutable =
true,
1700 bool ListItemNotVar =
false) {
1704 unsigned Diag = ListItemNotVar ? diag::err_omp_const_list_item
1705 : IsClassType ? diag::err_omp_const_not_mutable_variable
1706 : diag::err_omp_const_variable;
1707 SemaRef.
Diag(ELoc,
Diag) << getOpenMPClauseName(CKind);
1708 if (!ListItemNotVar &&
D) {
1709 const VarDecl *VD = dyn_cast<VarDecl>(
D);
1713 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1721const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(
ValueDecl *
D,
1726 auto *VD = dyn_cast<VarDecl>(
D);
1727 auto TI = Threadprivates.find(
D);
1728 if (TI != Threadprivates.end()) {
1729 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1730 DVar.CKind = OMPC_threadprivate;
1731 DVar.Modifier = TI->getSecond().Modifier;
1734 if (VD && VD->
hasAttr<OMPThreadPrivateDeclAttr>()) {
1736 SemaRef, VD,
D->getType().getNonReferenceType(),
1737 VD->
getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1738 DVar.CKind = OMPC_threadprivate;
1739 addDSA(
D, DVar.RefExpr, OMPC_threadprivate);
1746 !(VD->
hasAttr<OMPThreadPrivateDeclAttr>() &&
1752 SemaRef, VD,
D->getType().getNonReferenceType(),
D->
getLocation());
1753 DVar.CKind = OMPC_threadprivate;
1754 addDSA(
D, DVar.RefExpr, OMPC_threadprivate);
1759 !isLoopControlVariable(
D).first) {
1760 const_iterator IterTarget =
1761 std::find_if(begin(), end(), [](
const SharingMapTy &
Data) {
1764 if (IterTarget != end()) {
1765 const_iterator ParentIterTarget = IterTarget + 1;
1766 for (const_iterator
Iter = begin();
Iter != ParentIterTarget; ++
Iter) {
1767 if (isOpenMPLocal(VD,
Iter)) {
1771 DVar.CKind = OMPC_threadprivate;
1775 if (!isClauseParsingMode() || IterTarget != begin()) {
1776 auto DSAIter = IterTarget->SharingMap.find(
D);
1777 if (DSAIter != IterTarget->SharingMap.end() &&
1779 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1780 DVar.CKind = OMPC_threadprivate;
1783 const_iterator End = end();
1785 D, std::distance(ParentIterTarget, End),
1789 IterTarget->ConstructLoc);
1790 DVar.CKind = OMPC_threadprivate;
1810 const_iterator I = begin();
1811 const_iterator EndI = end();
1812 if (FromParent && I != EndI)
1815 auto It = I->SharingMap.find(
D);
1816 if (It != I->SharingMap.end()) {
1817 const DSAInfo &
Data = It->getSecond();
1818 DVar.RefExpr =
Data.RefExpr.getPointer();
1819 DVar.PrivateCopy =
Data.PrivateCopy;
1820 DVar.CKind =
Data.Attributes;
1821 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1822 DVar.DKind = I->Directive;
1823 DVar.Modifier =
Data.Modifier;
1824 DVar.AppliedToPointee =
Data.AppliedToPointee;
1829 DVar.CKind = OMPC_shared;
1836 if (SemaRef.
LangOpts.OpenMP <= 31) {
1844 DSAVarData DVarTemp = hasInnermostDSA(
1847 return C == OMPC_firstprivate ||
C == OMPC_shared;
1849 MatchesAlways, FromParent);
1850 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1853 DVar.CKind = OMPC_shared;
1860 const_iterator I = begin();
1861 const_iterator EndI = end();
1862 if (FromParent && I != EndI)
1866 auto It = I->SharingMap.find(
D);
1867 if (It != I->SharingMap.end()) {
1868 const DSAInfo &
Data = It->getSecond();
1869 DVar.RefExpr =
Data.RefExpr.getPointer();
1870 DVar.PrivateCopy =
Data.PrivateCopy;
1871 DVar.CKind =
Data.Attributes;
1872 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1873 DVar.DKind = I->Directive;
1874 DVar.Modifier =
Data.Modifier;
1875 DVar.AppliedToPointee =
Data.AppliedToPointee;
1881const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(
ValueDecl *
D,
1882 bool FromParent)
const {
1883 if (isStackEmpty()) {
1885 return getDSA(I,
D);
1888 const_iterator StartI = begin();
1889 const_iterator EndI = end();
1890 if (FromParent && StartI != EndI)
1892 return getDSA(StartI,
D);
1895const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(
ValueDecl *
D,
1896 unsigned Level)
const {
1897 if (getStackSize() <= Level)
1898 return DSAVarData();
1900 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1901 return getDSA(StartI,
D);
1904const DSAStackTy::DSAVarData
1907 DefaultDataSharingAttributes)>
1910 bool FromParent)
const {
1914 const_iterator I = begin();
1915 const_iterator EndI = end();
1916 if (FromParent && I != EndI)
1918 for (; I != EndI; ++I) {
1919 if (!DPred(I->Directive) &&
1920 !isImplicitOrExplicitTaskingRegion(I->Directive))
1922 const_iterator NewI = I;
1923 DSAVarData DVar = getDSA(NewI,
D);
1924 if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee, I->DefaultAttr))
1930const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1933 bool FromParent)
const {
1937 const_iterator StartI = begin();
1938 const_iterator EndI = end();
1939 if (FromParent && StartI != EndI)
1941 if (StartI == EndI || !DPred(StartI->Directive))
1943 const_iterator NewI = StartI;
1944 DSAVarData DVar = getDSA(NewI,
D);
1945 return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1950bool DSAStackTy::hasExplicitDSA(
1953 unsigned Level,
bool NotLastprivate)
const {
1954 if (getStackSize() <= Level)
1957 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1958 auto I = StackElem.SharingMap.find(
D);
1959 if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1960 CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1961 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1964 auto LI = StackElem.LCVMap.find(
D);
1965 if (LI != StackElem.LCVMap.end())
1966 return CPred(OMPC_private,
false);
1970bool DSAStackTy::hasExplicitDirective(
1972 unsigned Level)
const {
1973 if (getStackSize() <= Level)
1975 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1976 return DPred(StackElem.Directive);
1979bool DSAStackTy::hasDirective(
1983 bool FromParent)
const {
1985 size_t Skip = FromParent ? 2 : 1;
1986 for (const_iterator I = begin() + std::min(
Skip, getStackSize()),
E = end();
1988 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1994void SemaOpenMP::InitDataSharingAttributesStack() {
1995 VarDataSharingAttributesStack =
new DSAStackTy(
SemaRef);
1998#define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
2000void SemaOpenMP::pushOpenMPFunctionRegion() {
DSAStack->pushFunction(); }
2008 "Expected OpenMP device compilation.");
2014enum class FunctionEmissionStatus {
2025 "Expected OpenMP device compilation.");
2027 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
2032 Kind = SemaDiagnosticBuilder::K_Immediate;
2043 ? SemaDiagnosticBuilder::K_Deferred
2044 : SemaDiagnosticBuilder::K_Immediate;
2048 Kind = SemaDiagnosticBuilder::K_Nop;
2051 llvm_unreachable(
"CUDADiscarded unexpected in OpenMP device compilation");
2063 "Expected OpenMP host compilation.");
2065 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
2070 Kind = SemaDiagnosticBuilder::K_Immediate;
2073 Kind = SemaDiagnosticBuilder::K_Deferred;
2078 Kind = SemaDiagnosticBuilder::K_Nop;
2088 if (LO.OpenMP <= 45) {
2090 return OMPC_DEFAULTMAP_scalar;
2091 return OMPC_DEFAULTMAP_aggregate;
2094 return OMPC_DEFAULTMAP_pointer;
2096 return OMPC_DEFAULTMAP_scalar;
2097 return OMPC_DEFAULTMAP_aggregate;
2101 unsigned OpenMPCaptureLevel)
const {
2102 assert(
getLangOpts().OpenMP &&
"OpenMP is not allowed");
2105 bool IsByRef =
true;
2111 bool IsVariableUsedInMapClause =
false;
2173 bool IsVariableAssociatedWithSection =
false;
2175 DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2177 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection,
2184 if (WhereFoundClauseKind != OMPC_map &&
2185 WhereFoundClauseKind != OMPC_has_device_addr)
2188 auto EI = MapExprComponents.rbegin();
2189 auto EE = MapExprComponents.rend();
2191 assert(EI != EE &&
"Invalid map expression!");
2193 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2194 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() ==
D;
2199 auto Last = std::prev(EE);
2201 dyn_cast<UnaryOperator>(
Last->getAssociatedExpression());
2202 if ((UO && UO->getOpcode() == UO_Deref) ||
2203 isa<ArraySubscriptExpr>(
Last->getAssociatedExpression()) ||
2204 isa<ArraySectionExpr>(
Last->getAssociatedExpression()) ||
2205 isa<MemberExpr>(EI->getAssociatedExpression()) ||
2206 isa<OMPArrayShapingExpr>(
Last->getAssociatedExpression())) {
2207 IsVariableAssociatedWithSection =
true;
2216 if (IsVariableUsedInMapClause) {
2219 IsByRef = !(Ty->
isPointerType() && IsVariableAssociatedWithSection);
2224 IsByRef = (
DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2227 DSAStack->isDefaultmapCapturedByRef(
2232 return K == OMPC_reduction && !AppliedToPointee;
2240 ((IsVariableUsedInMapClause &&
2241 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2246 return K == OMPC_firstprivate ||
2247 (K == OMPC_reduction && AppliedToPointee);
2250 DSAStack->isUsesAllocatorsDecl(Level,
D))) &&
2253 !(isa<OMPCapturedExprDecl>(
D) && !
D->
hasAttr<OMPCaptureNoInitAttr>() &&
2254 !cast<OMPCapturedExprDecl>(
D)->getInit()->isGLValue()) &&
2257 !((
DSAStack->getDefaultDSA() == DSA_firstprivate ||
2258 DSAStack->getDefaultDSA() == DSA_private) &&
2262 !
DSAStack->isLoopControlVariable(
D, Level).first);
2279unsigned SemaOpenMP::getOpenMPNestingLevel()
const {
2281 return DSAStack->getNestingLevel();
2291 !
DSAStack->isClauseParsingMode()) ||
2302 if (!dyn_cast<FieldDecl>(
D))
2304 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2307 DefaultDataSharingAttributes DefaultAttr) {
2309 (DefaultAttr == DSA_firstprivate || DefaultAttr == DSA_private);
2313 if (DVarPrivate.CKind != OMPC_unknown)
2319 Expr *CaptureExpr,
bool WithInit,
2325 assert(
getLangOpts().OpenMP &&
"OpenMP is not allowed");
2328 auto *VD = dyn_cast<VarDecl>(
D);
2337 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2347 DSAStackTy::DSAVarData DVarTop =
2349 if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr)
2354 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2361 if (!isa<CapturingScopeInfo>(FSI))
2363 if (
auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2369 assert(CSI &&
"Failed to find CapturedRegionScopeInfo");
2380 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2386 if (CheckScopeInfo) {
2387 bool OpenMPFound =
false;
2388 for (
unsigned I = StopAt + 1; I > 0; --I) {
2390 if (!isa<CapturingScopeInfo>(FSI))
2392 if (
auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2402 if (
DSAStack->getCurrentDirective() != OMPD_unknown &&
2403 (!
DSAStack->isClauseParsingMode() ||
2404 DSAStack->getParentDirective() != OMPD_unknown)) {
2405 auto &&Info =
DSAStack->isLoopControlVariable(
D);
2408 isImplicitOrExplicitTaskingRegion(
DSAStack->getCurrentDirective())) ||
2409 (VD &&
DSAStack->isForceVarCapturing()))
2410 return VD ? VD : Info.second;
2411 DSAStackTy::DSAVarData DVarTop =
2413 if (DVarTop.CKind != OMPC_unknown &&
isOpenMPPrivate(DVarTop.CKind) &&
2415 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2421 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2429 if (VD && !VD->
hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2430 ((
DSAStack->getDefaultDSA() != DSA_none &&
2431 DSAStack->getDefaultDSA() != DSA_private &&
2432 DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2433 DVarTop.CKind == OMPC_shared))
2435 auto *FD = dyn_cast<FieldDecl>(
D);
2436 if (DVarPrivate.CKind != OMPC_unknown && !VD && FD &&
2437 !DVarPrivate.PrivateCopy) {
2438 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2441 DefaultDataSharingAttributes DefaultAttr) {
2443 (DefaultAttr == DSA_firstprivate ||
2444 DefaultAttr == DSA_private);
2448 if (DVarPrivate.CKind == OMPC_unknown)
2471 VD = cast<VarDecl>(VDPrivateRefExpr->
getDecl());
2472 DSAStack->addImplicitDefaultFirstprivateFD(FD, VD);
2475 if (DVarPrivate.CKind != OMPC_unknown ||
2476 (VD && (
DSAStack->getDefaultDSA() == DSA_none ||
2477 DSAStack->getDefaultDSA() == DSA_private ||
2478 DSAStack->getDefaultDSA() == DSA_firstprivate)))
2479 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2484void SemaOpenMP::adjustOpenMPTargetScopeIndex(
unsigned &FunctionScopesIndex,
2485 unsigned Level)
const {
2490 assert(
getLangOpts().OpenMP &&
"OpenMP must be enabled.");
2496 assert(
getLangOpts().OpenMP &&
"OpenMP must be enabled.");
2498 DSAStack->resetPossibleLoopCounter();
2504 unsigned CapLevel)
const {
2505 assert(
getLangOpts().OpenMP &&
"OpenMP is not allowed");
2506 if (
DSAStack->getCurrentDirective() != OMPD_unknown &&
2507 (!
DSAStack->isClauseParsingMode() ||
2508 DSAStack->getParentDirective() != OMPD_unknown)) {
2509 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2512 DefaultDataSharingAttributes DefaultAttr) {
2514 DefaultAttr == DSA_private;
2518 if (DVarPrivate.CKind == OMPC_private && isa<OMPCapturedExprDecl>(
D) &&
2519 DSAStack->isImplicitDefaultFirstprivateFD(cast<VarDecl>(
D)) &&
2520 !
DSAStack->isLoopControlVariable(
D).first)
2521 return OMPC_private;
2524 bool IsTriviallyCopyable =
2525 D->getType().getNonReferenceType().isTriviallyCopyableType(
2528 .getNonReferenceType()
2530 ->getAsCXXRecordDecl();
2535 (IsTriviallyCopyable ||
2541 return OMPC_firstprivate;
2542 DSAStackTy::DSAVarData DVar =
DSAStack->getImplicitDSA(
D, Level);
2543 if (DVar.CKind != OMPC_shared &&
2544 !
DSAStack->isLoopControlVariable(
D, Level).first && !DVar.RefExpr) {
2545 DSAStack->addImplicitTaskFirstprivate(Level,
D);
2546 return OMPC_firstprivate;
2555 return OMPC_private;
2558 DSAStack->isLoopControlVariable(
D).first) &&
2563 return OMPC_private;
2565 if (
const auto *VD = dyn_cast<VarDecl>(
D)) {
2571 return OMPC_private;
2576 DSAStack->isUsesAllocatorsDecl(Level,
D).value_or(
2577 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2578 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2579 return OMPC_private;
2583 (
DSAStack->isClauseParsingMode() &&
2584 DSAStack->getClauseParsingMode() == OMPC_private) ||
2589 return K == OMPD_taskgroup ||
2590 ((isOpenMPParallelDirective(K) ||
2591 isOpenMPWorksharingDirective(K)) &&
2592 !isOpenMPSimdDirective(K));
2595 DSAStack->isTaskgroupReductionRef(
D, Level)))
2602 assert(
getLangOpts().OpenMP &&
"OpenMP is not allowed");
2605 for (
unsigned I =
DSAStack->getNestingLevel() + 1; I > Level; --I) {
2606 const unsigned NewLevel = I - 1;
2610 if (isOpenMPPrivate(K) && !AppliedToPointee) {
2618 if (
DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2628 if (
DSAStack->mustBeFirstprivateAtLevel(
2630 OMPC = OMPC_firstprivate;
2634 if (OMPC != OMPC_unknown)
2636 OMPCaptureKindAttr::CreateImplicit(getASTContext(),
unsigned(OMPC)));
2640 unsigned CaptureLevel)
const {
2641 assert(
getLangOpts().OpenMP &&
"OpenMP is not allowed");
2646 const auto *VD = dyn_cast<VarDecl>(
D);
2650 Regions[CaptureLevel] != OMPD_task;
2654 unsigned CaptureLevel)
const {
2655 assert(
getLangOpts().OpenMP &&
"OpenMP is not allowed");
2658 if (
const auto *VD = dyn_cast<VarDecl>(
D)) {
2662 DSAStackTy::DSAVarData TopDVar =
2664 unsigned NumLevels =
2669 return (NumLevels == CaptureLevel + 1 &&
2670 (TopDVar.CKind != OMPC_shared ||
2671 DSAStack->getDefaultDSA() == DSA_firstprivate));
2674 DSAStackTy::DSAVarData DVar =
DSAStack->getImplicitDSA(
D, Level);
2675 if (DVar.CKind != OMPC_shared)
2677 }
while (Level > 0);
2683void SemaOpenMP::DestroyDataSharingAttributesStack() {
delete DSAStack; }
2687 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2692 "Not in OpenMP declare variant scope!");
2694 OMPDeclareVariantScopes.pop_back();
2700 assert(
getLangOpts().OpenMP &&
"Expected OpenMP compilation mode.");
2701 std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2705 (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host))
2708 if (!
getLangOpts().OpenMPIsTargetDevice && DevTy &&
2709 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2712 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2713 if (
getLangOpts().OpenMPIsTargetDevice && DevTy &&
2714 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2716 StringRef HostDevTy =
2718 Diag(
Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2719 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2720 diag::note_omp_marked_device_type_here)
2726 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2730 for (OMPDeclareVariantAttr *A :
2731 Callee->specific_attrs<OMPDeclareVariantAttr>()) {
2732 auto *DeclRefVariant = cast<DeclRefExpr>(A->getVariantFuncRef());
2733 auto *VariantFD = cast<FunctionDecl>(DeclRefVariant->getDecl());
2734 std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2735 OMPDeclareTargetDeclAttr::getDeviceType(
2736 VariantFD->getMostRecentDecl());
2737 if (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2743 Callee->hasAttr<OMPDeclareVariantAttr>() && HasHostAttr(Callee))
2747 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2748 Diag(
Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2749 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2750 diag::note_omp_marked_device_type_here)
2768 DSAStack->setClauseParsingMode(OMPC_unknown);
2772static std::pair<ValueDecl *, bool>
2774 SourceRange &ERange,
bool AllowArraySection =
false,
2775 StringRef DiagType =
"");
2780 bool InscanFound =
false;
2787 if (
C->getClauseKind() != OMPC_reduction)
2789 auto *RC = cast<OMPReductionClause>(
C);
2790 if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2792 InscanLoc = RC->getModifierLoc();
2795 if (RC->getModifier() == OMPC_REDUCTION_task) {
2805 S.
Diag(RC->getModifierLoc(),
2806 diag::err_omp_reduction_task_not_parallel_or_worksharing);
2812 if (
C->getClauseKind() != OMPC_reduction)
2814 auto *RC = cast<OMPReductionClause>(
C);
2815 if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2818 : RC->getModifierLoc(),
2819 diag::err_omp_inscan_reduction_expected);
2820 S.
Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2823 for (
Expr *Ref : RC->varlist()) {
2824 assert(Ref &&
"NULL expr in OpenMP nontemporal clause.");
2827 Expr *SimpleRefExpr = Ref;
2834 S.
Diag(Ref->getExprLoc(),
2835 diag::err_omp_reduction_not_inclusive_exclusive)
2836 << Ref->getSourceRange();
2850 const DSAStackTy::DSAVarData &DVar,
2851 bool IsLoopIterVar =
false);
2862 for (
Expr *DE : Clause->varlist()) {
2863 if (DE->isValueDependent() || DE->isTypeDependent()) {
2864 PrivateCopies.push_back(
nullptr);
2867 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2868 auto *VD = cast<VarDecl>(DRE->getDecl());
2870 const DSAStackTy::DSAVarData DVar =
2872 if (DVar.CKind != OMPC_lastprivate) {
2875 PrivateCopies.push_back(
nullptr);
2888 PrivateCopies.push_back(
nullptr);
2894 Clause->setPrivateCopies(PrivateCopies);
2900 for (
Expr *RefExpr : Clause->varlist()) {
2901 assert(RefExpr &&
"NULL expr in OpenMP nontemporal clause.");
2904 Expr *SimpleRefExpr = RefExpr;
2908 PrivateRefs.push_back(RefExpr);
2913 const DSAStackTy::DSAVarData DVar =
2915 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2918 Clause->setPrivateRefs(PrivateRefs);
2922 for (
unsigned I = 0,
E = Clause->getNumberOfAllocators(); I <
E; ++I) {
2924 auto *DRE = dyn_cast<DeclRefExpr>(
D.Allocator->IgnoreParenImpCasts());
2928 if (!VD || !isa<VarDecl>(VD))
2930 DSAStackTy::DSAVarData DVar =
2936 Expr *MapExpr =
nullptr;
2938 DSAStack->checkMappableExprComponentListsForDecl(
2944 auto MI = MapExprComponents.rbegin();
2945 auto ME = MapExprComponents.rend();
2947 MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2948 VD->getCanonicalDecl()) {
2949 MapExpr = MI->getAssociatedExpression();
2954 Diag(
D.Allocator->getExprLoc(), diag::err_omp_allocator_used_in_clauses)
2959 Diag(MapExpr->getExprLoc(), diag::note_used_here)
2960 << MapExpr->getSourceRange();
2965 if (
const auto *
D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2967 if (
auto *Clause = dyn_cast<OMPLastprivateClause>(
C)) {
2968 FinalizeLastprivate(Clause);
2969 }
else if (
auto *Clause = dyn_cast<OMPNontemporalClause>(
C)) {
2970 FinalizeNontemporal(Clause);
2971 }
else if (
auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(
C)) {
2972 FinalizeAllocators(Clause);
2987 Expr *NumIterations,
Sema &SemaRef,
2988 Scope *S, DSAStackTy *Stack);
2992 DSAStackTy *Stack) {
2994 "loop exprs were not built");
3001 auto *LC = dyn_cast<OMPLinearClause>(
C);
3020 explicit VarDeclFilterCCC(
Sema &S) : SemaRef(S) {}
3021 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
3023 if (
const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
3031 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
3032 return std::make_unique<VarDeclFilterCCC>(*
this);
3041 explicit VarOrFuncDeclFilterCCC(
Sema &S) : SemaRef(S) {}
3042 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
3044 if (ND && ((isa<VarDecl>(ND) && ND->
getKind() == Decl::Var) ||
3045 isa<FunctionDecl>(ND))) {
3052 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
3053 return std::make_unique<VarOrFuncDeclFilterCCC>(*
this);
3074 VarDeclFilterCCC CCC(
SemaRef);
3081 : diag::err_omp_expected_var_arg_suggest)
3083 VD = Corrected.getCorrectionDeclAs<
VarDecl>();
3085 Diag(
Id.getLoc(), Lookup.
empty() ? diag::err_undeclared_var_use
3086 : diag::err_omp_expected_var_arg)
3091 Diag(
Id.getLoc(), diag::err_omp_expected_var_arg) <<
Id.getName();
3100 Diag(
Id.getLoc(), diag::err_omp_global_var_arg)
3105 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3117 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3118 << getOpenMPDirectiveName(Kind) << VD;
3122 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3132 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3133 << getOpenMPDirectiveName(Kind) << VD;
3137 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3149 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3150 << getOpenMPDirectiveName(Kind) << VD;
3154 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3163 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3164 << getOpenMPDirectiveName(Kind) << VD;
3168 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3176 if (Kind == OMPD_threadprivate && VD->
isUsed() &&
3178 Diag(
Id.getLoc(), diag::err_omp_var_used)
3179 << getOpenMPDirectiveName(Kind) << VD;
3201class LocalVarRefChecker final
3207 if (
const auto *VD = dyn_cast<VarDecl>(
E->getDecl())) {
3210 diag::err_omp_local_var_in_threadprivate_init)
3212 SemaRef.Diag(VD->
getLocation(), diag::note_defined_here)
3219 bool VisitStmt(
const Stmt *S) {
3220 for (
const Stmt *Child : S->children()) {
3221 if (Child && Visit(Child))
3226 explicit LocalVarRefChecker(
Sema &SemaRef) : SemaRef(SemaRef) {}
3235 for (
Expr *RefExpr : VarList) {
3236 auto *DE = cast<DeclRefExpr>(RefExpr);
3237 auto *VD = cast<VarDecl>(DE->getDecl());
3254 ILoc, VD->
getType(), diag::err_omp_threadprivate_incomplete_type)) {
3261 Diag(ILoc, diag::err_omp_ref_type_arg)
3262 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->
getType();
3266 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3274 !(VD->
hasAttr<OMPThreadPrivateDeclAttr>() &&
3279 Diag(ILoc, diag::err_omp_var_thread_local)
3284 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3292 LocalVarRefChecker Checker(
SemaRef);
3293 if (Checker.Visit(
Init))
3297 Vars.push_back(RefExpr);
3298 DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3299 VD->
addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3302 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3305 if (!Vars.empty()) {
3313static OMPAllocateDeclAttr::AllocatorTypeTy
3316 return OMPAllocateDeclAttr::OMPNullMemAlloc;
3317 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3318 Allocator->isInstantiationDependent() ||
3319 Allocator->containsUnexpandedParameterPack())
3320 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3321 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3322 llvm::FoldingSetNodeID AEId;
3323 const Expr *AE = Allocator->IgnoreParenImpCasts();
3325 for (
int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3326 auto AllocatorKind =
static_cast<OMPAllocateDeclAttr::AllocatorTypeTy
>(I);
3327 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3328 llvm::FoldingSetNodeID DAEId;
3331 if (AEId == DAEId) {
3332 AllocatorKindRes = AllocatorKind;
3336 return AllocatorKindRes;
3341 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
Expr *Allocator) {
3342 if (!VD->
hasAttr<OMPAllocateDeclAttr>())
3344 const auto *A = VD->
getAttr<OMPAllocateDeclAttr>();
3345 Expr *PrevAllocator = A->getAllocator();
3346 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3348 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3349 if (AllocatorsMatch &&
3350 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3351 Allocator && PrevAllocator) {
3352 const Expr *AE = Allocator->IgnoreParenImpCasts();
3354 llvm::FoldingSetNodeID AEId, PAEId;
3357 AllocatorsMatch = AEId == PAEId;
3359 if (!AllocatorsMatch) {
3361 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3365 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3367 PrevAllocator->printPretty(PrevAllocatorStream,
nullptr,
3371 Allocator ? Allocator->getExprLoc() : RefExpr->
getExprLoc();
3373 Allocator ? Allocator->getSourceRange() : RefExpr->
getSourceRange();
3375 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3377 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3378 S.
Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3379 << (Allocator ? 1 : 0) << AllocatorStream.str()
3380 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3382 S.
Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3383 << PrevAllocatorRange;
3391 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3393 if (VD->
hasAttr<OMPAllocateDeclAttr>())
3402 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3403 Allocator->isInstantiationDependent() ||
3404 Allocator->containsUnexpandedParameterPack()))
3406 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.
Context, AllocatorKind,
3407 Allocator, Alignment, SR);
3410 ML->DeclarationMarkedOpenMPAllocate(VD, A);
3416 assert(Clauses.size() <= 2 &&
"Expected at most two clauses.");
3417 Expr *Alignment =
nullptr;
3418 Expr *Allocator =
nullptr;
3419 if (Clauses.empty()) {
3429 if (
const auto *AC = dyn_cast<OMPAllocatorClause>(
C))
3430 Allocator = AC->getAllocator();
3431 else if (
const auto *AC = dyn_cast<OMPAlignClause>(
C))
3432 Alignment = AC->getAlignment();
3434 llvm_unreachable(
"Unexpected clause on allocate directive");
3436 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3439 for (
Expr *RefExpr : VarList) {
3440 auto *DE = cast<DeclRefExpr>(RefExpr);
3441 auto *VD = cast<VarDecl>(DE->getDecl());
3445 VD->
hasAttr<OMPThreadPrivateDeclAttr>() ||
3453 AllocatorKind, Allocator))
3461 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3462 Diag(Allocator->getExprLoc(),
3463 diag::err_omp_expected_predefined_allocator)
3464 << Allocator->getSourceRange();
3468 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3474 Vars.push_back(RefExpr);
3493 Diag(
Loc, diag::err_omp_invalid_scope) <<
"requires";
3507 bool SkippedClauses) {
3508 if (!SkippedClauses && Assumptions.empty())
3509 Diag(
Loc, diag::err_omp_no_clause_for_directive)
3510 << llvm::omp::getAllAssumeClauseOptions()
3511 << llvm::omp::getOpenMPDirectiveName(DKind);
3515 if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3516 OMPAssumeScoped.push_back(AA);
3521 if (Assumptions.empty())
3524 assert(DKind == llvm::omp::Directive::OMPD_assumes &&
3525 "Unexpected omp assumption directive!");
3526 OMPAssumeGlobal.push_back(AA);
3534 while (Ctx->getLexicalParent())
3536 DeclContexts.push_back(Ctx);
3537 while (!DeclContexts.empty()) {
3539 for (
auto *SubDC : DC->
decls()) {
3540 if (SubDC->isInvalidDecl())
3542 if (
auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3543 DeclContexts.push_back(CTD->getTemplatedDecl());
3544 llvm::append_range(DeclContexts, CTD->specializations());
3547 if (
auto *DC = dyn_cast<DeclContext>(SubDC))
3548 DeclContexts.push_back(DC);
3549 if (
auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3559 OMPAssumeScoped.pop_back();
3580 DSAStack->getEncounteredTargetLocs();
3582 if (!TargetLocations.empty() || !AtomicLoc.
isInvalid()) {
3583 for (
const OMPClause *CNew : ClauseList) {
3585 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3586 isa<OMPUnifiedAddressClause>(CNew) ||
3587 isa<OMPReverseOffloadClause>(CNew) ||
3588 isa<OMPDynamicAllocatorsClause>(CNew)) {
3589 Diag(
Loc, diag::err_omp_directive_before_requires)
3590 <<
"target" << getOpenMPClauseName(CNew->getClauseKind());
3592 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3596 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3597 Diag(
Loc, diag::err_omp_directive_before_requires)
3598 <<
"atomic" << getOpenMPClauseName(CNew->getClauseKind());
3599 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3605 if (!
DSAStack->hasDuplicateRequiresClause(ClauseList))
3613 const DSAStackTy::DSAVarData &DVar,
3614 bool IsLoopIterVar) {
3616 SemaRef.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3617 << getOpenMPClauseName(DVar.CKind);
3621 PDSA_StaticMemberShared,
3622 PDSA_StaticLocalVarShared,
3623 PDSA_LoopIterVarPrivate,
3624 PDSA_LoopIterVarLinear,
3625 PDSA_LoopIterVarLastprivate,
3626 PDSA_ConstVarShared,
3627 PDSA_GlobalVarShared,
3628 PDSA_TaskVarFirstprivate,
3629 PDSA_LocalVarPrivate,
3631 } Reason = PDSA_Implicit;
3632 bool ReportHint =
false;
3634 auto *VD = dyn_cast<VarDecl>(
D);
3635 if (IsLoopIterVar) {
3636 if (DVar.CKind == OMPC_private)
3637 Reason = PDSA_LoopIterVarPrivate;
3638 else if (DVar.CKind == OMPC_lastprivate)
3639 Reason = PDSA_LoopIterVarLastprivate;
3641 Reason = PDSA_LoopIterVarLinear;
3643 DVar.CKind == OMPC_firstprivate) {
3644 Reason = PDSA_TaskVarFirstprivate;
3645 ReportLoc = DVar.ImplicitDSALoc;
3647 Reason = PDSA_StaticLocalVarShared;
3649 Reason = PDSA_StaticMemberShared;
3651 Reason = PDSA_GlobalVarShared;
3653 Reason = PDSA_ConstVarShared;
3654 else if (VD && VD->
isLocalVarDecl() && DVar.CKind == OMPC_private) {
3656 Reason = PDSA_LocalVarPrivate;
3658 if (Reason != PDSA_Implicit) {
3659 SemaRef.
Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3660 << Reason << ReportHint
3661 << getOpenMPDirectiveName(Stack->getCurrentDirective());
3662 }
else if (DVar.ImplicitDSALoc.isValid()) {
3663 SemaRef.
Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3664 << getOpenMPClauseName(DVar.CKind);
3670 bool IsAggregateOrDeclareTarget) {
3673 case OMPC_DEFAULTMAP_MODIFIER_alloc:
3674 Kind = OMPC_MAP_alloc;
3676 case OMPC_DEFAULTMAP_MODIFIER_to:
3679 case OMPC_DEFAULTMAP_MODIFIER_from:
3680 Kind = OMPC_MAP_from;
3682 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3683 Kind = OMPC_MAP_tofrom;
3685 case OMPC_DEFAULTMAP_MODIFIER_present:
3691 Kind = OMPC_MAP_alloc;
3693 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3695 llvm_unreachable(
"Unexpected defaultmap implicit behavior");
3696 case OMPC_DEFAULTMAP_MODIFIER_none:
3697 case OMPC_DEFAULTMAP_MODIFIER_default:
3702 if (IsAggregateOrDeclareTarget) {
3703 Kind = OMPC_MAP_tofrom;
3706 llvm_unreachable(
"Unexpected defaultmap implicit behavior");
3713struct VariableImplicitInfo {
3717 llvm::SetVector<Expr *> Privates;
3718 llvm::SetVector<Expr *> Firstprivates;
3719 llvm::SetVector<Expr *> Mappings[DefaultmapKindNum][MapKindNum];
3721 MapModifiers[DefaultmapKindNum];
3724class DSAAttrChecker final :
public StmtVisitor<DSAAttrChecker, void> {
3728 bool ErrorFound =
false;
3729 bool TryCaptureCXXThisMembers =
false;
3732 VariableImplicitInfo ImpInfo;
3734 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3738 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3740 if (S->getDirectiveKind() == OMPD_atomic ||
3741 S->getDirectiveKind() == OMPD_critical ||
3742 S->getDirectiveKind() == OMPD_section ||
3743 S->getDirectiveKind() == OMPD_master ||
3744 S->getDirectiveKind() == OMPD_masked ||
3745 S->getDirectiveKind() == OMPD_scope ||
3746 S->getDirectiveKind() == OMPD_assume ||
3748 Visit(S->getAssociatedStmt());
3751 visitSubCaptures(S->getInnermostCapturedStmt());
3754 if (TryCaptureCXXThisMembers ||
3756 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3758 return C.capturesThis();
3760 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3761 TryCaptureCXXThisMembers =
true;
3762 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3763 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3770 if (
auto *FC = dyn_cast<OMPFirstprivateClause>(
C)) {
3771 for (
Expr *Ref : FC->varlist())
3784 if (
auto *VD = dyn_cast<VarDecl>(
E->getDecl())) {
3787 !Stack->getTopDSA(VD,
false).RefExpr &&
3788 !Stack->isImplicitDefaultFirstprivateFD(VD))) {
3789 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3790 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3791 Visit(CED->getInit());
3794 }
else if (VD->
isImplicit() || isa<OMPCapturedExprDecl>(VD))
3797 if (!Stack->isImplicitDefaultFirstprivateFD(VD))
3802 !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3803 !Stack->isImplicitTaskFirstprivate(VD))
3806 if (Stack->isUsesAllocatorsDecl(VD))
3809 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD,
false);
3811 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3815 std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3816 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3819 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3820 !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3821 !Stack->isImplicitTaskFirstprivate(VD))
3829 if (DVar.CKind == OMPC_unknown &&
3830 (Stack->getDefaultDSA() == DSA_none ||
3831 Stack->getDefaultDSA() == DSA_private ||
3832 Stack->getDefaultDSA() == DSA_firstprivate) &&
3833 isImplicitOrExplicitTaskingRegion(DKind) &&
3834 VarsWithInheritedDSA.count(VD) == 0) {
3835 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3836 if (!InheritedDSA && (Stack->getDefaultDSA() == DSA_firstprivate ||
3837 Stack->getDefaultDSA() == DSA_private)) {
3838 DSAStackTy::DSAVarData DVar =
3839 Stack->getImplicitDSA(VD,
false);
3840 InheritedDSA = DVar.CKind == OMPC_unknown;
3843 VarsWithInheritedDSA[VD] =
E;
3844 if (Stack->getDefaultDSA() == DSA_none)
3859 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3860 OMPC_DEFAULTMAP_MODIFIER_none;
3861 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3862 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3866 if (!Stack->checkMappableExprComponentListsForDecl(
3871 auto MI = MapExprComponents.rbegin();
3872 auto ME = MapExprComponents.rend();
3873 return MI != ME && MI->getAssociatedDeclaration() == VD;
3875 VarsWithInheritedDSA[VD] =
E;
3881 bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3882 OMPC_DEFAULTMAP_MODIFIER_present;
3883 if (IsModifierPresent) {
3884 if (!llvm::is_contained(ImpInfo.MapModifiers[ClauseKind],
3885 OMPC_MAP_MODIFIER_present)) {
3886 ImpInfo.MapModifiers[ClauseKind].push_back(
3887 OMPC_MAP_MODIFIER_present);
3893 !Stack->isLoopControlVariable(VD).first) {
3894 if (!Stack->checkMappableExprComponentListsForDecl(
3899 if (SemaRef.LangOpts.OpenMP >= 50)
3900 return !StackComponents.empty();
3903 return StackComponents.size() == 1 ||
3905 llvm::drop_begin(llvm::reverse(StackComponents)),
3906 [](const OMPClauseMappableExprCommon::
3907 MappableComponent &MC) {
3908 return MC.getAssociatedDeclaration() ==
3910 (isa<ArraySectionExpr>(
3911 MC.getAssociatedExpression()) ||
3912 isa<OMPArrayShapingExpr>(
3913 MC.getAssociatedExpression()) ||
3914 isa<ArraySubscriptExpr>(
3915 MC.getAssociatedExpression()));
3918 bool IsFirstprivate =
false;
3920 if (
const auto *RD =
3922 IsFirstprivate = RD->isLambda();
3924 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3925 if (IsFirstprivate) {
3926 ImpInfo.Firstprivates.insert(
E);
3929 Stack->getDefaultmapModifier(ClauseKind);
3931 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3932 ImpInfo.Mappings[ClauseKind][
Kind].insert(
E);
3942 DVar = Stack->hasInnermostDSA(
3945 return C == OMPC_reduction && !AppliedToPointee;
3954 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
3960 DVar = Stack->getImplicitDSA(VD,
false);
3962 (((Stack->getDefaultDSA() == DSA_firstprivate &&
3963 DVar.CKind == OMPC_firstprivate) ||
3964 (Stack->getDefaultDSA() == DSA_private &&
3965 DVar.CKind == OMPC_private)) &&
3967 !Stack->isLoopControlVariable(VD).first) {
3968 if (Stack->getDefaultDSA() == DSA_private)
3969 ImpInfo.Privates.insert(
E);
3971 ImpInfo.Firstprivates.insert(
E);
3978 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3979 Stack->addToParentTargetRegionLinkGlobals(
E);
3988 auto *FD = dyn_cast<FieldDecl>(
E->getMemberDecl());
3992 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD,
false);
3995 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3999 !Stack->isLoopControlVariable(FD).first &&
4000 !Stack->checkMappableExprComponentListsForDecl(
4005 return isa<CXXThisExpr>(
4007 StackComponents.back().getAssociatedExpression())
4019 if (Stack->isClassPreviouslyMapped(TE->getType()))
4023 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
4028 ImpInfo.Mappings[ClauseKind][
Kind].insert(
E);
4037 DVar = Stack->hasInnermostDSA(
4040 return C == OMPC_reduction && !AppliedToPointee;
4049 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
4055 DVar = Stack->getImplicitDSA(FD,
false);
4057 !Stack->isLoopControlVariable(FD).first) {
4062 if (DVar.CKind != OMPC_unknown)
4063 ImpInfo.Firstprivates.insert(
E);
4072 const auto *VD = cast<ValueDecl>(
4073 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
4074 if (!Stack->checkMappableExprComponentListsForDecl(
4080 auto CCI = CurComponents.rbegin();
4081 auto CCE = CurComponents.rend();
4082 for (const auto &SC : llvm::reverse(StackComponents)) {
4084 if (CCI->getAssociatedExpression()->getStmtClass() !=
4085 SC.getAssociatedExpression()->getStmtClass())
4086 if (!((isa<ArraySectionExpr>(
4087 SC.getAssociatedExpression()) ||
4088 isa<OMPArrayShapingExpr>(
4089 SC.getAssociatedExpression())) &&
4090 isa<ArraySubscriptExpr>(
4091 CCI->getAssociatedExpression())))
4094 const Decl *CCD = CCI->getAssociatedDeclaration();
4095 const Decl *SCD = SC.getAssociatedDeclaration();
4096 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
4097 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
4100 std::advance(CCI, 1);
4106 Visit(
E->getBase());
4108 }
else if (!TryCaptureCXXThisMembers) {
4109 Visit(
E->getBase());
4116 if (isa_and_nonnull<OMPPrivateClause>(
C))
4122 if (
C && !((isa<OMPFirstprivateClause>(
C) || isa<OMPMapClause>(
C)) &&
4124 for (
Stmt *CC :
C->children()) {
4131 VisitSubCaptures(S);
4140 for (
Stmt *
C : S->arguments()) {
4147 if (
Expr *Callee = S->getCallee()) {
4148 auto *CI =
Callee->IgnoreParenImpCasts();
4149 if (
auto *CE = dyn_cast<MemberExpr>(CI))
4150 Visit(CE->getBase());
4151 else if (
auto *CE = dyn_cast<DeclRefExpr>(CI))
4155 void VisitStmt(
Stmt *S) {
4156 for (
Stmt *
C : S->children()) {
4167 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
4169 VarDecl *VD = Cap.getCapturedVar();
4173 Stack->checkMappableExprComponentListsForDecl(
4180 Cap.getLocation(),
true);
4184 bool isErrorFound()
const {
return ErrorFound; }
4185 const VariableImplicitInfo &getImplicitInfo()
const {
return ImpInfo; }
4187 return VarsWithInheritedDSA;
4191 : Stack(S), SemaRef(SemaRef), ErrorFound(
false), CS(CS) {
4192 DKind = S->getCurrentDirective();
4207 Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target);
4209 Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams);
4211 Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel);
4213 Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for);
4215 Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd);
4216 Stack->handleConstructTrait(Traits, ScopeEntry);
4227 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4228 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4230 if (LoopBoundSharing) {
4232 Params.push_back(std::make_pair(
".previous.lb.", KmpSizeTy));
4233 Params.push_back(std::make_pair(
".previous.ub.", KmpSizeTy));
4237 Params.push_back(std::make_pair(StringRef(),
QualType()));
4258 std::make_pair(
".global_tid.", KmpInt32Ty),
4259 std::make_pair(
".part_id.", KmpInt32PtrTy),
4260 std::make_pair(
".privates.", VoidPtrTy),
4265 std::make_pair(StringRef(),
QualType())
4276 Params.push_back(std::make_pair(StringRef(
"dyn_ptr"), VoidPtrTy));
4279 Params.push_back(std::make_pair(StringRef(),
QualType()));
4286 std::make_pair(StringRef(),
QualType())
4308 std::make_pair(
".global_tid.", KmpInt32Ty),
4309 std::make_pair(
".part_id.", KmpInt32PtrTy),
4310 std::make_pair(
".privates.", VoidPtrTy),
4315 std::make_pair(
".lb.", KmpUInt64Ty),
4316 std::make_pair(
".ub.", KmpUInt64Ty),
4317 std::make_pair(
".st.", KmpInt64Ty),
4318 std::make_pair(
".liter.", KmpInt32Ty),
4319 std::make_pair(
".reductions.", VoidPtrTy),
4320 std::make_pair(StringRef(),
QualType())
4333 CSI->TheCapturedDecl->addAttr(AlwaysInlineAttr::CreateImplicit(
4334 SemaRef.
getASTContext(), {}, AlwaysInlineAttr::Keyword_forceinline));
4337 for (
auto [Level, RKind] : llvm::enumerate(Regions)) {
4372 case OMPD_metadirective:
4375 llvm_unreachable(
"Unexpected capture region");
4391 case OMPD_interchange:
4404int SemaOpenMP::getNumberOfConstructScopes(
unsigned Level)
const {
4411 return CaptureRegions.size();
4415 Expr *CaptureExpr,
bool WithInit,
4417 bool AsExpression) {
4418 assert(CaptureExpr);
4424 Ty =
C.getLValueReferenceType(Ty);
4426 Ty =
C.getPointerType(Ty);
4438 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(
C));
4449 CD = cast<OMPCapturedExprDecl>(VD);
4488class CaptureRegionUnwinderRAII {
4495 CaptureRegionUnwinderRAII(
Sema &S,
bool &ErrorFound,
4497 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4498 ~CaptureRegionUnwinderRAII() {
4501 while (--ThisCaptureLevel >= 0)
4514 DSAStack->getCurrentDirective()))) {
4516 if (
const auto *RD =
Type.getCanonicalType()
4517 .getNonReferenceType()
4519 bool SavedForceCaptureByReferenceInTargetExecutable =
4520 DSAStack->isForceCaptureByReferenceInTargetExecutable();
4521 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4523 if (RD->isLambda()) {
4524 llvm::DenseMap<const ValueDecl *, FieldDecl *> Captures;
4526 RD->getCaptureFields(Captures, ThisCapture);
4529 VarDecl *VD = cast<VarDecl>(LC.getCapturedVar());
4534 }
else if (LC.getCaptureKind() ==
LCK_This) {
4537 ThisTy, ThisCapture->
getType()))
4542 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4543 SavedForceCaptureByReferenceInTargetExecutable);
4553 for (
const OMPClause *Clause : Clauses) {
4555 Ordered = cast<OMPOrderedClause>(Clause);
4557 Order = cast<OMPOrderClause>(Clause);
4558 if (Order->
getKind() != OMPC_ORDER_concurrent)
4561 if (Ordered && Order)
4565 if (Ordered && Order) {
4567 diag::err_omp_simple_clause_incompatible_with_ordered)
4568 << getOpenMPClauseName(OMPC_order)
4585 bool ErrorFound =
false;
4586 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4588 if (!S.isUsable()) {
4603 DSAStack->getCurrentDirective() == OMPD_target) &&
4607 auto *IRC = cast<OMPInReductionClause>(Clause);
4608 for (
Expr *
E : IRC->taskgroup_descriptors())
4620 if (
auto *
E = cast_or_null<Expr>(VarRef)) {
4624 DSAStack->setForceVarCapturing(
false);
4625 }
else if (CaptureRegions.size() > 1 ||
4626 CaptureRegions.back() != OMPD_unknown) {
4630 if (
Expr *
E =
C->getPostUpdateExpr())
4635 SC = cast<OMPScheduleClause>(Clause);
4637 OC = cast<OMPOrderedClause>(Clause);
4639 LCs.push_back(cast<OMPLinearClause>(Clause));
4650 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4655 diag::err_omp_simple_clause_incompatible_with_ordered)
4656 << getOpenMPClauseName(OMPC_schedule)
4658 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4669 Diag(
C->getBeginLoc(), diag::err_omp_linear_ordered)
4678 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
4685 unsigned CompletedRegions = 0;
4690 if (ThisCaptureRegion != OMPD_unknown) {
4698 if (CaptureRegion == ThisCaptureRegion ||
4699 CaptureRegion == OMPD_unknown) {
4700 if (
auto *DS = cast_or_null<DeclStmt>(
C->getPreInitStmt())) {
4701 for (
Decl *
D : DS->decls())
4708 if (ThisCaptureRegion == OMPD_target) {
4712 if (
const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(
C)) {
4713 for (
unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4716 if (
Expr *
E =
D.AllocatorTraits)
4723 if (ThisCaptureRegion == OMPD_parallel) {
4727 if (
auto *RC = dyn_cast<OMPReductionClause>(
C)) {
4728 if (RC->getModifier() != OMPC_REDUCTION_inscan)
4730 for (
Expr *
E : RC->copy_array_temps())
4734 if (
auto *AC = dyn_cast<OMPAlignedClause>(
C)) {
4735 for (
Expr *
E : AC->varlist())
4740 if (++CompletedRegions == CaptureRegions.size())
4751 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4754 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4755 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4758 SemaRef.
Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4759 << getOpenMPDirectiveName(CancelRegion);
4769 if (!Stack->getCurScope())
4774 bool NestingProhibited =
false;
4775 bool CloseNesting =
true;
4776 bool OrphanSeen =
false;
4779 ShouldBeInParallelRegion,
4780 ShouldBeInOrderedRegion,
4781 ShouldBeInTargetRegion,
4782 ShouldBeInTeamsRegion,
4783 ShouldBeInLoopSimdRegion,
4784 } Recommend = NoRecommend;
4788 getLeafOrCompositeConstructs(ParentRegion, LeafOrComposite);
4791 if (SemaRef.
LangOpts.OpenMP >= 51 && Stack->isParentOrderConcurrent() &&
4792 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_loop &&
4793 CurrentRegion != OMPD_parallel &&
4795 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_order)
4796 << getOpenMPDirectiveName(CurrentRegion);
4800 ((SemaRef.
LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4801 (SemaRef.
LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4802 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4803 CurrentRegion != OMPD_scan))) {
4816 SemaRef.
Diag(StartLoc, (CurrentRegion != OMPD_simd)
4817 ? diag::err_omp_prohibited_region_simd
4818 : diag::warn_omp_nesting_simd)
4819 << (SemaRef.
LangOpts.OpenMP >= 50 ? 1 : 0);
4820 return CurrentRegion != OMPD_simd;
4822 if (EnclosingConstruct == OMPD_atomic) {
4825 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4828 if (CurrentRegion == OMPD_section) {
4833 if (EnclosingConstruct != OMPD_sections) {
4834 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4835 << (ParentRegion != OMPD_unknown)
4836 << getOpenMPDirectiveName(ParentRegion);
4844 if (ParentRegion == OMPD_unknown &&
4846 CurrentRegion != OMPD_cancellation_point &&
4847 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4851 if (SemaRef.
LangOpts.OpenMP >= 50 && CurrentRegion == OMPD_loop &&
4852 (BindKind == OMPC_BIND_parallel || BindKind == OMPC_BIND_teams) &&
4854 EnclosingConstruct == OMPD_loop)) {
4855 int ErrorMsgNumber = (BindKind == OMPC_BIND_parallel) ? 1 : 4;
4856 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region)
4857 <<
true << getOpenMPDirectiveName(ParentRegion) << ErrorMsgNumber
4858 << getOpenMPDirectiveName(CurrentRegion);
4861 if (CurrentRegion == OMPD_cancellation_point ||
4862 CurrentRegion == OMPD_cancel) {
4875 if (CancelRegion == OMPD_taskgroup) {
4876 NestingProhibited = EnclosingConstruct != OMPD_task &&
4878 EnclosingConstruct != OMPD_taskloop);
4879 }
else if (CancelRegion == OMPD_sections) {
4880 NestingProhibited = EnclosingConstruct != OMPD_section &&
4881 EnclosingConstruct != OMPD_sections;
4883 NestingProhibited = CancelRegion != Leafs.back();
4885 OrphanSeen = ParentRegion == OMPD_unknown;
4886 }
else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
4893 }
else if (CurrentRegion == OMPD_critical && CurrentName.
getName()) {
4899 bool DeadLock = Stack->hasDirective(
4903 if (K == OMPD_critical && DNI.
getName() == CurrentName.
getName()) {
4904 PreviousCriticalLoc = Loc;
4911 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_critical_same_name)
4913 if (PreviousCriticalLoc.
isValid())
4914 SemaRef.
Diag(PreviousCriticalLoc,
4915 diag::note_omp_previous_critical_region);
4918 }
else if (CurrentRegion == OMPD_barrier || CurrentRegion == OMPD_scope) {
4928 llvm::is_contained({OMPD_masked, OMPD_master,
4929 OMPD_critical, OMPD_ordered},
4930 EnclosingConstruct);
4941 llvm::is_contained({OMPD_masked, OMPD_master,
4942 OMPD_critical, OMPD_ordered},
4943 EnclosingConstruct);
4944 Recommend = ShouldBeInParallelRegion;
4945 }
else if (CurrentRegion == OMPD_ordered) {
4954 NestingProhibited = EnclosingConstruct == OMPD_critical ||
4957 Stack->isParentOrderedRegion());
4958 Recommend = ShouldBeInOrderedRegion;
4964 (SemaRef.
LangOpts.OpenMP <= 45 && EnclosingConstruct != OMPD_target) ||
4965 (SemaRef.
LangOpts.OpenMP >= 50 && EnclosingConstruct != OMPD_unknown &&
4966 EnclosingConstruct != OMPD_target);
4967 OrphanSeen = ParentRegion == OMPD_unknown;
4968 Recommend = ShouldBeInTargetRegion;
4969 }
else if (CurrentRegion == OMPD_scan) {
4970 if (SemaRef.
LangOpts.OpenMP >= 50) {
4975 NestingProhibited = !llvm::is_contained(
4976 {OMPD_for, OMPD_simd, OMPD_for_simd}, EnclosingConstruct);
4978 NestingProhibited =
true;
4980 OrphanSeen = ParentRegion == OMPD_unknown;
4981 Recommend = ShouldBeInLoopSimdRegion;
4985 EnclosingConstruct == OMPD_teams) {
4997 CurrentRegion != OMPD_loop &&
4999 CurrentRegion == OMPD_atomic);
5000 Recommend = ShouldBeInParallelRegion;
5002 if (!NestingProhibited && CurrentRegion == OMPD_loop) {
5008 BindKind == OMPC_BIND_teams && EnclosingConstruct != OMPD_teams;
5009 Recommend = ShouldBeInTeamsRegion;
5015 NestingProhibited = EnclosingConstruct != OMPD_teams;
5016 Recommend = ShouldBeInTeamsRegion;
5018 if (!NestingProhibited &&
5025 NestingProhibited = Stack->hasDirective(
5029 OffendingRegion = K;
5035 CloseNesting =
false;
5037 if (NestingProhibited) {
5039 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_device_directive)
5040 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
5042 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region)
5043 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
5044 << Recommend << getOpenMPDirectiveName(CurrentRegion);
5058 bool ErrorFound =
false;
5059 unsigned NamedModifiersNumber = 0;
5060 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
5061 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
5064 if (
const auto *IC = dyn_cast_or_null<OMPIfClause>(
C)) {
5068 if (FoundNameModifiers[CurNM]) {
5069 S.
Diag(
C->getBeginLoc(), diag::err_omp_more_one_clause)
5070 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
5071 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
5073 }
else if (CurNM != OMPD_unknown) {
5074 NameModifierLoc.push_back(IC->getNameModifierLoc());
5075 ++NamedModifiersNumber;
5077 FoundNameModifiers[CurNM] = IC;
5078 if (CurNM == OMPD_unknown)
5084 if (!llvm::is_contained(AllowedNameModifiers, CurNM)) {
5085 S.
Diag(IC->getNameModifierLoc(),
5086 diag::err_omp_wrong_if_directive_name_modifier)
5087 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
5094 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
5095 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
5096 S.
Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
5097 diag::err_omp_no_more_if_clause);
5100 std::string Sep(
", ");
5101 unsigned AllowedCnt = 0;
5102 unsigned TotalAllowedNum =
5103 AllowedNameModifiers.size() - NamedModifiersNumber;
5104 for (
unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
5107 if (!FoundNameModifiers[NM]) {
5109 Values += getOpenMPDirectiveName(NM);
5111 if (AllowedCnt + 2 == TotalAllowedNum)
5113 else if (AllowedCnt + 1 != TotalAllowedNum)
5118 S.
Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
5119 diag::err_omp_unnamed_if_clause)
5120 << (TotalAllowedNum > 1) << Values;
5123 S.
Diag(
Loc, diag::note_omp_previous_named_if_clause);