35#include "llvm/ADT/IndexedMap.h"
36#include "llvm/ADT/PointerEmbeddedInt.h"
37#include "llvm/ADT/STLExtras.h"
38#include "llvm/ADT/SmallSet.h"
39#include "llvm/ADT/StringExtras.h"
40#include "llvm/Frontend/OpenMP/OMPAssume.h"
41#include "llvm/Frontend/OpenMP/OMPConstants.h"
46using namespace llvm::omp;
59enum DefaultDataSharingAttributes {
64 DSA_firstprivate = 1 << 3,
74 unsigned Modifier = 0;
75 const Expr *RefExpr =
nullptr;
78 bool AppliedToPointee =
false;
79 DSAVarData() =
default;
83 bool AppliedToPointee)
84 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
85 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
86 AppliedToPointee(AppliedToPointee) {}
88 using OperatorOffsetTy =
90 using DoacrossDependMapTy =
91 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
93 enum class UsesAllocatorsDeclKind {
105 unsigned Modifier = 0;
108 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
112 bool AppliedToPointee =
false;
114 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
115 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
116 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
117 using LoopControlVariablesMapTy =
118 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
121 struct MappedExprComponentTy {
125 using MappedExprComponentsTy =
126 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
127 using CriticalsWithHintsTy =
128 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
129 struct ReductionData {
130 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
132 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
133 ReductionData() =
default;
140 ReductionOp = RefExpr;
143 using DeclReductionMapTy =
144 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
145 struct DefaultmapInfo {
149 DefaultmapInfo() =
default;
151 : ImplicitBehavior(M), SLoc(Loc) {}
154 struct SharingMapTy {
155 DeclSAMapTy SharingMap;
156 DeclReductionMapTy ReductionMap;
157 UsedRefMapTy AlignedMap;
158 UsedRefMapTy NontemporalMap;
159 MappedExprComponentsTy MappedExprComponents;
160 LoopControlVariablesMapTy LCVMap;
161 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
166 Scope *CurScope =
nullptr;
172 DoacrossDependMapTy DoacrossDepends;
176 std::optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
177 bool RegionHasOrderConcurrent =
false;
178 unsigned AssociatedLoops = 1;
179 bool HasMutipleLoops =
false;
180 const Decl *PossiblyLoopCounter =
nullptr;
181 bool NowaitRegion =
false;
182 bool UntiedRegion =
false;
183 bool CancelRegion =
false;
184 bool LoopStart =
false;
185 bool BodyComplete =
false;
190 Expr *TaskgroupReductionRef =
nullptr;
199 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
203 struct ImplicitDefaultFDInfoTy {
207 size_t StackLevel = 0;
210 ImplicitDefaultFDInfoTy(
const FieldDecl *FD,
size_t StackLevel,
212 : FD(FD), StackLevel(StackLevel), VD(VD) {}
216 ImplicitDefaultFirstprivateFDs;
217 Expr *DeclareMapperVar =
nullptr;
221 :
Directive(DKind), DirectiveName(Name), CurScope(CurScope),
223 SharingMapTy() =
default;
229 DeclSAMapTy Threadprivates;
236 bool ForceCapturing =
false;
239 bool ForceCaptureByReferenceInTargetExecutable =
false;
240 CriticalsWithHintsTy Criticals;
241 unsigned IgnoredStackElements = 0;
245 using const_iterator = StackTy::const_reverse_iterator;
246 const_iterator begin()
const {
247 return Stack.empty() ? const_iterator()
248 : Stack.back().first.rbegin() + IgnoredStackElements;
250 const_iterator end()
const {
251 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
253 using iterator = StackTy::reverse_iterator;
255 return Stack.empty() ? iterator()
256 : Stack.back().first.rbegin() + IgnoredStackElements;
259 return Stack.empty() ? iterator() : Stack.back().first.rend();
264 bool isStackEmpty()
const {
265 return Stack.empty() ||
266 Stack.back().second != CurrentNonCapturingFunctionScope ||
267 Stack.back().first.size() <= IgnoredStackElements;
269 size_t getStackSize()
const {
270 return isStackEmpty() ? 0
271 : Stack.back().first.size() - IgnoredStackElements;
274 SharingMapTy *getTopOfStackOrNull() {
275 size_t Size = getStackSize();
278 return &Stack.back().first[
Size - 1];
280 const SharingMapTy *getTopOfStackOrNull()
const {
281 return const_cast<DSAStackTy &
>(*this).getTopOfStackOrNull();
283 SharingMapTy &getTopOfStack() {
284 assert(!isStackEmpty() &&
"no current directive");
285 return *getTopOfStackOrNull();
287 const SharingMapTy &getTopOfStack()
const {
288 return const_cast<DSAStackTy &
>(*this).getTopOfStack();
291 SharingMapTy *getSecondOnStackOrNull() {
292 size_t Size = getStackSize();
295 return &Stack.back().first[
Size - 2];
297 const SharingMapTy *getSecondOnStackOrNull()
const {
298 return const_cast<DSAStackTy &
>(*this).getSecondOnStackOrNull();
307 SharingMapTy &getStackElemAtLevel(
unsigned Level) {
308 assert(Level < getStackSize() &&
"no such stack element");
309 return Stack.back().first[
Level];
311 const SharingMapTy &getStackElemAtLevel(
unsigned Level)
const {
312 return const_cast<DSAStackTy &
>(*this).getStackElemAtLevel(Level);
315 DSAVarData getDSA(const_iterator &Iter,
ValueDecl *D)
const;
318 bool isOpenMPLocal(
VarDecl *D, const_iterator Iter)
const;
331 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
340 explicit DSAStackTy(
Sema &S) : SemaRef(S) {}
343 void setOMPAllocatorHandleT(
QualType Ty) { OMPAllocatorHandleT = Ty; }
345 QualType getOMPAllocatorHandleT()
const {
return OMPAllocatorHandleT; }
347 void setOMPAlloctraitT(
QualType Ty) { OMPAlloctraitT = Ty; }
349 QualType getOMPAlloctraitT()
const {
return OMPAlloctraitT; }
351 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
353 OMPPredefinedAllocators[AllocatorKind] = Allocator;
356 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind)
const {
357 return OMPPredefinedAllocators[AllocatorKind];
360 void setOMPDependT(
QualType Ty) { OMPDependT = Ty; }
362 QualType getOMPDependT()
const {
return OMPDependT; }
365 void setOMPEventHandleT(
QualType Ty) { OMPEventHandleT = Ty; }
367 QualType getOMPEventHandleT()
const {
return OMPEventHandleT; }
369 bool isClauseParsingMode()
const {
return ClauseKindMode != OMPC_unknown; }
371 assert(isClauseParsingMode() &&
"Must be in clause parsing mode.");
372 return ClauseKindMode;
376 bool isBodyComplete()
const {
377 const SharingMapTy *Top = getTopOfStackOrNull();
378 return Top && Top->BodyComplete;
380 void setBodyComplete() { getTopOfStack().BodyComplete =
true; }
382 bool isForceVarCapturing()
const {
return ForceCapturing; }
383 void setForceVarCapturing(
bool V) { ForceCapturing =
V; }
385 void setForceCaptureByReferenceInTargetExecutable(
bool V) {
386 ForceCaptureByReferenceInTargetExecutable =
V;
388 bool isForceCaptureByReferenceInTargetExecutable()
const {
389 return ForceCaptureByReferenceInTargetExecutable;
394 assert(!IgnoredStackElements &&
395 "cannot change stack while ignoring elements");
397 Stack.back().second != CurrentNonCapturingFunctionScope)
398 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
399 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
400 Stack.back().first.back().DefaultAttrLoc = Loc;
404 assert(!IgnoredStackElements &&
405 "cannot change stack while ignoring elements");
406 assert(!Stack.back().first.empty() &&
407 "Data-sharing attributes stack is empty!");
408 Stack.back().first.pop_back();
413 class ParentDirectiveScope {
418 ParentDirectiveScope(DSAStackTy &Self,
bool Activate)
419 : Self(Self), Active(
false) {
423 ~ParentDirectiveScope() { disable(); }
426 --Self.IgnoredStackElements;
432 ++Self.IgnoredStackElements;
441 "Expected loop-based directive.");
442 getTopOfStack().LoopStart =
true;
447 "Expected loop-based directive.");
448 getTopOfStack().LoopStart =
false;
451 bool isLoopStarted()
const {
453 "Expected loop-based directive.");
454 return !getTopOfStack().LoopStart;
457 void resetPossibleLoopCounter(
const Decl *D =
nullptr) {
458 getTopOfStack().PossiblyLoopCounter = D ? D->getCanonicalDecl() : D;
461 const Decl *getPossiblyLoopCunter()
const {
462 return getTopOfStack().PossiblyLoopCounter;
465 void pushFunction() {
466 assert(!IgnoredStackElements &&
467 "cannot change stack while ignoring elements");
469 assert(!isa<CapturingScopeInfo>(CurFnScope));
470 CurrentNonCapturingFunctionScope = CurFnScope;
474 assert(!IgnoredStackElements &&
475 "cannot change stack while ignoring elements");
476 if (!Stack.empty() && Stack.back().second == OldFSI) {
477 assert(Stack.back().first.empty());
480 CurrentNonCapturingFunctionScope =
nullptr;
482 if (!isa<CapturingScopeInfo>(FSI)) {
483 CurrentNonCapturingFunctionScope = FSI;
492 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
494 auto I = Criticals.find(Name.getAsString());
495 if (I != Criticals.end())
497 return std::make_pair(
nullptr, llvm::APSInt());
514 const LCDeclInfo isLoopControlVariable(
const ValueDecl *D)
const;
519 const LCDeclInfo isParentLoopControlVariable(
const ValueDecl *D)
const;
524 const LCDeclInfo isLoopControlVariable(
const ValueDecl *D,
525 unsigned Level)
const;
528 const ValueDecl *getParentLoopControlVariable(
unsigned I)
const;
531 void markDeclAsUsedInScanDirective(
ValueDecl *D) {
532 if (SharingMapTy *Stack = getSecondOnStackOrNull())
533 Stack->UsedInScanDirective.insert(D);
537 bool isUsedInScanDirective(
ValueDecl *D)
const {
538 if (
const SharingMapTy *Stack = getTopOfStackOrNull())
539 return Stack->UsedInScanDirective.contains(D);
545 DeclRefExpr *PrivateCopy =
nullptr,
unsigned Modifier = 0,
546 bool AppliedToPointee =
false);
555 const Expr *ReductionRef);
561 Expr *&TaskgroupDescriptor)
const;
566 const Expr *&ReductionRef,
567 Expr *&TaskgroupDescriptor)
const;
570 Expr *getTaskgroupReductionRef()
const {
571 assert((getTopOfStack().
Directive == OMPD_taskgroup ||
575 "taskgroup reference expression requested for non taskgroup or "
576 "parallel/worksharing directive.");
577 return getTopOfStack().TaskgroupReductionRef;
581 bool isTaskgroupReductionRef(
const ValueDecl *VD,
unsigned Level)
const {
582 return getStackElemAtLevel(Level).TaskgroupReductionRef &&
583 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
589 const DSAVarData getTopDSA(
ValueDecl *D,
bool FromParent);
591 const DSAVarData getImplicitDSA(
ValueDecl *D,
bool FromParent)
const;
593 const DSAVarData getImplicitDSA(
ValueDecl *D,
unsigned Level)
const;
600 DefaultDataSharingAttributes)>
603 bool FromParent)
const;
611 bool FromParent)
const;
618 unsigned Level,
bool NotLastprivate =
false)
const;
622 bool hasExplicitDirective(
624 unsigned Level)
const;
628 const llvm::function_ref<
bool(
631 bool FromParent)
const;
635 const SharingMapTy *Top = getTopOfStackOrNull();
636 return Top ? Top->Directive : OMPD_unknown;
640 assert(!isStackEmpty() &&
"No directive at specified level.");
641 return getStackElemAtLevel(Level).Directive;
645 unsigned OpenMPCaptureLevel)
const {
648 return CaptureRegions[OpenMPCaptureLevel];
652 const SharingMapTy *
Parent = getSecondOnStackOrNull();
657 void addRequiresDecl(
OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); }
660 template <
typename ClauseType>
bool hasRequiresDeclWithClause()
const {
663 return isa<ClauseType>(C);
671 bool IsDuplicate =
false;
674 for (
const OMPClause *CPrev : D->clauselists()) {
675 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
676 SemaRef.
Diag(CNew->getBeginLoc(),
677 diag::err_omp_requires_clause_redeclaration)
678 << getOpenMPClauseName(CNew->getClauseKind());
679 SemaRef.
Diag(CPrev->getBeginLoc(),
680 diag::note_omp_requires_previous_clause)
681 << getOpenMPClauseName(CPrev->getClauseKind());
692 TargetLocations.push_back(LocStart);
698 AtomicLocation = Loc;
703 SourceLocation getAtomicDirectiveLoc()
const {
return AtomicLocation; }
707 return TargetLocations;
712 getTopOfStack().DefaultAttr = DSA_none;
713 getTopOfStack().DefaultAttrLoc = Loc;
717 getTopOfStack().DefaultAttr = DSA_shared;
718 getTopOfStack().DefaultAttrLoc = Loc;
722 getTopOfStack().DefaultAttr = DSA_private;
723 getTopOfStack().DefaultAttrLoc = Loc;
727 getTopOfStack().DefaultAttr = DSA_firstprivate;
728 getTopOfStack().DefaultAttrLoc = Loc;
733 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[
Kind];
734 DMI.ImplicitBehavior = M;
740 return getTopOfStack()
741 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
744 .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
747 .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
749 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
754 return ConstructTraits;
759 ConstructTraits.append(Traits.begin(), Traits.end());
761 for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits)) {
762 llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val();
763 assert(Top == Trait &&
"Something left a trait on the stack!");
769 DefaultDataSharingAttributes getDefaultDSA(
unsigned Level)
const {
770 return getStackSize() <=
Level ? DSA_unspecified
771 : getStackElemAtLevel(Level).DefaultAttr;
773 DefaultDataSharingAttributes getDefaultDSA()
const {
774 return isStackEmpty() ? DSA_unspecified : getTopOfStack().DefaultAttr;
777 return isStackEmpty() ?
SourceLocation() : getTopOfStack().DefaultAttrLoc;
781 return isStackEmpty()
783 : getTopOfStack().DefaultmapMap[
Kind].ImplicitBehavior;
786 getDefaultmapModifierAtLevel(
unsigned Level,
788 return getStackElemAtLevel(Level).DefaultmapMap[
Kind].ImplicitBehavior;
790 bool isDefaultmapCapturedByRef(
unsigned Level,
793 getDefaultmapModifierAtLevel(Level, Kind);
794 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
795 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
796 (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
797 (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
798 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
805 case OMPC_DEFAULTMAP_scalar:
806 case OMPC_DEFAULTMAP_pointer:
808 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
809 (M == OMPC_DEFAULTMAP_MODIFIER_default);
810 case OMPC_DEFAULTMAP_aggregate:
811 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
815 llvm_unreachable(
"Unexpected OpenMPDefaultmapClauseKind enum");
817 bool mustBeFirstprivateAtLevel(
unsigned Level,
820 getDefaultmapModifierAtLevel(Level, Kind);
821 return mustBeFirstprivateBase(M, Kind);
825 return mustBeFirstprivateBase(M, Kind);
829 bool isThreadPrivate(
VarDecl *D) {
830 const DSAVarData DVar = getTopDSA(D,
false);
835 void setOrderedRegion(
bool IsOrdered,
const Expr *Param,
838 getTopOfStack().OrderedRegion.emplace(Param, Clause);
840 getTopOfStack().OrderedRegion.reset();
844 bool isOrderedRegion()
const {
845 if (
const SharingMapTy *Top = getTopOfStackOrNull())
846 return Top->OrderedRegion.has_value();
850 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam()
const {
851 if (
const SharingMapTy *Top = getTopOfStackOrNull())
852 if (Top->OrderedRegion)
853 return *Top->OrderedRegion;
854 return std::make_pair(
nullptr,
nullptr);
858 bool isParentOrderedRegion()
const {
859 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
860 return Parent->OrderedRegion.has_value();
864 std::pair<const Expr *, OMPOrderedClause *>
865 getParentOrderedRegionParam()
const {
866 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
867 if (
Parent->OrderedRegion)
868 return *
Parent->OrderedRegion;
869 return std::make_pair(
nullptr,
nullptr);
872 void setRegionHasOrderConcurrent(
bool HasOrderConcurrent) {
873 getTopOfStack().RegionHasOrderConcurrent = HasOrderConcurrent;
877 bool isParentOrderConcurrent()
const {
878 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
879 return Parent->RegionHasOrderConcurrent;
883 void setNowaitRegion(
bool IsNowait =
true) {
884 getTopOfStack().NowaitRegion = IsNowait;
888 bool isParentNowaitRegion()
const {
889 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
890 return Parent->NowaitRegion;
894 void setUntiedRegion(
bool IsUntied =
true) {
895 getTopOfStack().UntiedRegion = IsUntied;
898 bool isUntiedRegion()
const {
899 const SharingMapTy *Top = getTopOfStackOrNull();
900 return Top ? Top->UntiedRegion :
false;
903 void setParentCancelRegion(
bool Cancel =
true) {
904 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
905 Parent->CancelRegion |= Cancel;
908 bool isCancelRegion()
const {
909 const SharingMapTy *Top = getTopOfStackOrNull();
910 return Top ? Top->CancelRegion :
false;
915 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
916 Parent->PrevScanLocation = Loc;
919 bool doesParentHasScanDirective()
const {
920 const SharingMapTy *Top = getSecondOnStackOrNull();
921 return Top ? Top->PrevScanLocation.isValid() :
false;
925 const SharingMapTy *Top = getSecondOnStackOrNull();
930 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
931 Parent->PrevOrderedLocation = Loc;
934 bool doesParentHasOrderedDirective()
const {
935 const SharingMapTy *Top = getSecondOnStackOrNull();
936 return Top ? Top->PrevOrderedLocation.isValid() :
false;
940 const SharingMapTy *Top = getSecondOnStackOrNull();
945 void setAssociatedLoops(
unsigned Val) {
946 getTopOfStack().AssociatedLoops = Val;
948 getTopOfStack().HasMutipleLoops =
true;
951 unsigned getAssociatedLoops()
const {
952 const SharingMapTy *Top = getTopOfStackOrNull();
953 return Top ? Top->AssociatedLoops : 0;
956 bool hasMutipleLoops()
const {
957 const SharingMapTy *Top = getTopOfStackOrNull();
958 return Top ? Top->HasMutipleLoops :
false;
964 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
965 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
968 bool hasInnerTeamsRegion()
const {
969 return getInnerTeamsRegionLoc().
isValid();
973 const SharingMapTy *Top = getTopOfStackOrNull();
977 Scope *getCurScope()
const {
978 const SharingMapTy *Top = getTopOfStackOrNull();
979 return Top ? Top->CurScope :
nullptr;
981 void setContext(
DeclContext *DC) { getTopOfStack().Context = DC; }
983 const SharingMapTy *Top = getTopOfStackOrNull();
989 bool checkMappableExprComponentListsForDecl(
990 const ValueDecl *VD,
bool CurrentRegionOnly,
991 const llvm::function_ref<
1003 if (CurrentRegionOnly)
1006 std::advance(SI, 1);
1008 for (; SI != SE; ++SI) {
1009 auto MI = SI->MappedExprComponents.find(VD);
1010 if (MI != SI->MappedExprComponents.end())
1012 MI->second.Components)
1013 if (Check(L, MI->second.Kind))
1021 bool checkMappableExprComponentListsForDeclAtLevel(
1023 const llvm::function_ref<
1027 if (getStackSize() <= Level)
1030 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1031 auto MI = StackElem.MappedExprComponents.find(VD);
1032 if (MI != StackElem.MappedExprComponents.end())
1034 MI->second.Components)
1035 if (Check(L, MI->second.Kind))
1042 void addMappableExpressionComponents(
1046 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
1048 MEC.Components.resize(MEC.Components.size() + 1);
1049 MEC.Components.back().append(Components.begin(), Components.end());
1050 MEC.Kind = WhereFoundClauseKind;
1053 unsigned getNestingLevel()
const {
1054 assert(!isStackEmpty());
1055 return getStackSize() - 1;
1058 const OperatorOffsetTy &OpsOffs) {
1059 SharingMapTy *
Parent = getSecondOnStackOrNull();
1061 Parent->DoacrossDepends.try_emplace(
C, OpsOffs);
1063 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
1064 getDoacrossDependClauses()
const {
1065 const SharingMapTy &StackElem = getTopOfStack();
1067 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
1068 return llvm::make_range(Ref.begin(), Ref.end());
1070 return llvm::make_range(StackElem.DoacrossDepends.end(),
1071 StackElem.DoacrossDepends.end());
1075 void addMappedClassesQualTypes(
QualType QT) {
1076 SharingMapTy &StackElem = getTopOfStack();
1077 StackElem.MappedClassesQualTypes.insert(QT);
1081 bool isClassPreviouslyMapped(
QualType QT)
const {
1082 const SharingMapTy &StackElem = getTopOfStack();
1083 return StackElem.MappedClassesQualTypes.contains(QT);
1087 void addToParentTargetRegionLinkGlobals(
DeclRefExpr *E) {
1088 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1089 E->
getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1090 "Expected declare target link global.");
1091 for (
auto &Elem : *
this) {
1093 Elem.DeclareTargetLinkVarDecls.push_back(E);
1103 "Expected target executable directive.");
1104 return getTopOfStack().DeclareTargetLinkVarDecls;
1108 void addInnerAllocatorExpr(
Expr *E) {
1109 getTopOfStack().InnerUsedAllocators.push_back(E);
1113 return getTopOfStack().InnerUsedAllocators;
1117 void addImplicitTaskFirstprivate(
unsigned Level,
Decl *D) {
1118 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1121 bool isImplicitTaskFirstprivate(
Decl *D)
const {
1122 return getTopOfStack().ImplicitTaskFirstprivates.contains(D);
1126 void addUsesAllocatorsDecl(
const Decl *D, UsesAllocatorsDeclKind Kind) {
1127 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1131 std::optional<UsesAllocatorsDeclKind>
1132 isUsesAllocatorsDecl(
unsigned Level,
const Decl *D)
const {
1133 const SharingMapTy &StackElem = getTopOfStack();
1134 auto I = StackElem.UsesAllocatorsDecls.find(D);
1135 if (I == StackElem.UsesAllocatorsDecls.end())
1136 return std::nullopt;
1137 return I->getSecond();
1139 std::optional<UsesAllocatorsDeclKind>
1140 isUsesAllocatorsDecl(
const Decl *D)
const {
1141 const SharingMapTy &StackElem = getTopOfStack();
1142 auto I = StackElem.UsesAllocatorsDecls.find(D);
1143 if (I == StackElem.UsesAllocatorsDecls.end())
1144 return std::nullopt;
1145 return I->getSecond();
1148 void addDeclareMapperVarRef(
Expr *Ref) {
1149 SharingMapTy &StackElem = getTopOfStack();
1150 StackElem.DeclareMapperVar = Ref;
1152 const Expr *getDeclareMapperVarRef()
const {
1153 const SharingMapTy *Top = getTopOfStackOrNull();
1154 return Top ? Top->DeclareMapperVar :
nullptr;
1158 void addIteratorVarDecl(
VarDecl *VD) {
1159 SharingMapTy &StackElem = getTopOfStack();
1163 bool isIteratorVarDecl(
const VarDecl *VD)
const {
1164 const SharingMapTy *Top = getTopOfStackOrNull();
1168 return llvm::any_of(Top->IteratorVarDecls, [VD](
const VarDecl *IteratorVD) {
1169 return IteratorVD == VD->getCanonicalDecl();
1174 const_iterator I = begin();
1175 const_iterator EndI = end();
1176 size_t StackLevel = getStackSize();
1177 for (; I != EndI; ++I) {
1178 if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1182 assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1185 for (
const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1186 if (IFD.FD == FD && IFD.StackLevel == StackLevel)
1191 bool isImplicitDefaultFirstprivateFD(
VarDecl *VD)
const {
1192 const_iterator I = begin();
1193 const_iterator EndI = end();
1194 for (; I != EndI; ++I)
1195 if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1199 for (
const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1206 iterator I = begin();
1207 const_iterator EndI = end();
1208 size_t StackLevel = getStackSize();
1209 for (; I != EndI; ++I) {
1210 if (I->DefaultAttr == DSA_private || I->DefaultAttr == DSA_firstprivate) {
1211 I->ImplicitDefaultFirstprivateFDs.emplace_back(FD, StackLevel, VD);
1216 assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1226 DKind == OMPD_unknown;
1232 if (
const auto *FE = dyn_cast<FullExpr>(E))
1233 E = FE->getSubExpr();
1235 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1236 E = MTE->getSubExpr();
1238 while (
const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1239 E = Binder->getSubExpr();
1241 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1242 E = ICE->getSubExprAsWritten();
1251 if (
const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1252 if (
const auto *ME = dyn_cast<MemberExpr>(
getExprAsWritten(CED->getInit())))
1253 D = ME->getMemberDecl();
1254 const auto *VD = dyn_cast<VarDecl>(D);
1255 const auto *FD = dyn_cast<FieldDecl>(D);
1256 if (VD !=
nullptr) {
1272DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1275 auto *VD = dyn_cast<VarDecl>(D);
1276 const auto *FD = dyn_cast<FieldDecl>(D);
1278 if (Iter == end()) {
1285 DVar.CKind = OMPC_shared;
1292 DVar.CKind = OMPC_shared;
1296 DVar.CKind = OMPC_shared;
1307 DVar.CKind = OMPC_private;
1311 DVar.DKind = Iter->Directive;
1314 if (Iter->SharingMap.count(D)) {
1315 const DSAInfo &
Data = Iter->SharingMap.lookup(D);
1316 DVar.RefExpr =
Data.RefExpr.getPointer();
1317 DVar.PrivateCopy =
Data.PrivateCopy;
1318 DVar.CKind =
Data.Attributes;
1319 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1320 DVar.Modifier =
Data.Modifier;
1321 DVar.AppliedToPointee =
Data.AppliedToPointee;
1329 switch (Iter->DefaultAttr) {
1331 DVar.CKind = OMPC_shared;
1332 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1336 case DSA_firstprivate:
1339 DVar.CKind = OMPC_unknown;
1341 DVar.CKind = OMPC_firstprivate;
1343 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1351 DVar.CKind = OMPC_unknown;
1353 DVar.CKind = OMPC_private;
1355 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1357 case DSA_unspecified:
1362 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1366 DVar.CKind = OMPC_shared;
1376 DSAVarData DVarTemp;
1377 const_iterator I = Iter, E = end();
1385 DVarTemp = getDSA(I, D);
1386 if (DVarTemp.CKind != OMPC_shared) {
1387 DVar.RefExpr =
nullptr;
1388 DVar.CKind = OMPC_firstprivate;
1391 }
while (I != E && !isImplicitTaskingRegion(I->Directive));
1393 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1402 return getDSA(++Iter, D);
1406 const Expr *NewDE) {
1407 assert(!isStackEmpty() &&
"Data sharing attributes stack is empty");
1409 SharingMapTy &StackElem = getTopOfStack();
1410 auto It = StackElem.AlignedMap.find(D);
1411 if (It == StackElem.AlignedMap.end()) {
1412 assert(NewDE &&
"Unexpected nullptr expr to be added into aligned map");
1413 StackElem.AlignedMap[D] = NewDE;
1416 assert(It->second &&
"Unexpected nullptr expr in the aligned map");
1420const Expr *DSAStackTy::addUniqueNontemporal(
const ValueDecl *D,
1421 const Expr *NewDE) {
1422 assert(!isStackEmpty() &&
"Data sharing attributes stack is empty");
1424 SharingMapTy &StackElem = getTopOfStack();
1425 auto It = StackElem.NontemporalMap.find(D);
1426 if (It == StackElem.NontemporalMap.end()) {
1427 assert(NewDE &&
"Unexpected nullptr expr to be added into aligned map");
1428 StackElem.NontemporalMap[D] = NewDE;
1431 assert(It->second &&
"Unexpected nullptr expr in the aligned map");
1436 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1438 SharingMapTy &StackElem = getTopOfStack();
1439 StackElem.LCVMap.try_emplace(
1440 D, LCDeclInfo(StackElem.LCVMap.size() + 1,
Capture));
1443const DSAStackTy::LCDeclInfo
1444DSAStackTy::isLoopControlVariable(
const ValueDecl *D)
const {
1445 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1447 const SharingMapTy &StackElem = getTopOfStack();
1448 auto It = StackElem.LCVMap.find(D);
1449 if (It != StackElem.LCVMap.end())
1451 return {0,
nullptr};
1454const DSAStackTy::LCDeclInfo
1455DSAStackTy::isLoopControlVariable(
const ValueDecl *D,
unsigned Level)
const {
1456 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1458 for (
unsigned I = Level + 1; I > 0; --I) {
1459 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1460 auto It = StackElem.LCVMap.find(D);
1461 if (It != StackElem.LCVMap.end())
1464 return {0,
nullptr};
1467const DSAStackTy::LCDeclInfo
1468DSAStackTy::isParentLoopControlVariable(
const ValueDecl *D)
const {
1469 const SharingMapTy *
Parent = getSecondOnStackOrNull();
1470 assert(
Parent &&
"Data-sharing attributes stack is empty");
1472 auto It =
Parent->LCVMap.find(D);
1473 if (It !=
Parent->LCVMap.end())
1475 return {0,
nullptr};
1478const ValueDecl *DSAStackTy::getParentLoopControlVariable(
unsigned I)
const {
1479 const SharingMapTy *
Parent = getSecondOnStackOrNull();
1480 assert(
Parent &&
"Data-sharing attributes stack is empty");
1481 if (
Parent->LCVMap.size() < I)
1483 for (
const auto &Pair :
Parent->LCVMap)
1484 if (Pair.second.first == I)
1491 bool AppliedToPointee) {
1493 if (A == OMPC_threadprivate) {
1494 DSAInfo &
Data = Threadprivates[D];
1495 Data.Attributes = A;
1496 Data.RefExpr.setPointer(E);
1497 Data.PrivateCopy =
nullptr;
1498 Data.Modifier = Modifier;
1500 DSAInfo &
Data = getTopOfStack().SharingMap[D];
1501 assert(
Data.Attributes == OMPC_unknown || (A ==
Data.Attributes) ||
1502 (A == OMPC_firstprivate &&
Data.Attributes == OMPC_lastprivate) ||
1503 (A == OMPC_lastprivate &&
Data.Attributes == OMPC_firstprivate) ||
1504 (isLoopControlVariable(D).first && A == OMPC_private));
1505 Data.Modifier = Modifier;
1506 if (A == OMPC_lastprivate &&
Data.Attributes == OMPC_firstprivate) {
1507 Data.RefExpr.setInt(
true);
1510 const bool IsLastprivate =
1511 A == OMPC_lastprivate ||
Data.Attributes == OMPC_lastprivate;
1512 Data.Attributes = A;
1513 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1514 Data.PrivateCopy = PrivateCopy;
1515 Data.AppliedToPointee = AppliedToPointee;
1517 DSAInfo &
Data = getTopOfStack().SharingMap[PrivateCopy->
getDecl()];
1518 Data.Modifier = Modifier;
1519 Data.Attributes = A;
1520 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1521 Data.PrivateCopy =
nullptr;
1522 Data.AppliedToPointee = AppliedToPointee;
1529 StringRef Name,
const AttrVec *Attrs =
nullptr,
1544 OMPReferencedVarAttr::CreateImplicit(SemaRef.
Context, OrigRef));
1551 bool RefersToCapture =
false) {
1562 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1564 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1565 "Additional reduction info may be specified only for reduction items.");
1566 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1567 assert(ReductionData.ReductionRange.isInvalid() &&
1568 (getTopOfStack().
Directive == OMPD_taskgroup ||
1572 "Additional reduction info may be specified only once for reduction "
1574 ReductionData.set(BOK, SR);
1575 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1576 if (!TaskgroupReductionRef) {
1579 TaskgroupReductionRef =
1585 const Expr *ReductionRef) {
1587 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1589 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1590 "Additional reduction info may be specified only for reduction items.");
1591 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1592 assert(ReductionData.ReductionRange.isInvalid() &&
1593 (getTopOfStack().
Directive == OMPD_taskgroup ||
1597 "Additional reduction info may be specified only once for reduction "
1599 ReductionData.set(ReductionRef, SR);
1600 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1601 if (!TaskgroupReductionRef) {
1604 TaskgroupReductionRef =
1609const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1611 Expr *&TaskgroupDescriptor)
const {
1613 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty.");
1614 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1615 const DSAInfo &
Data = I->SharingMap.lookup(D);
1616 if (
Data.Attributes != OMPC_reduction ||
1617 Data.Modifier != OMPC_REDUCTION_task)
1619 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1620 if (!ReductionData.ReductionOp ||
1621 ReductionData.ReductionOp.is<
const Expr *>())
1622 return DSAVarData();
1623 SR = ReductionData.ReductionRange;
1624 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1625 assert(I->TaskgroupReductionRef &&
"taskgroup reduction reference "
1626 "expression for the descriptor is not "
1628 TaskgroupDescriptor = I->TaskgroupReductionRef;
1629 return DSAVarData(I->Directive, OMPC_reduction,
Data.RefExpr.getPointer(),
1630 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1633 return DSAVarData();
1636const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1638 Expr *&TaskgroupDescriptor)
const {
1640 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty.");
1641 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1642 const DSAInfo &
Data = I->SharingMap.lookup(D);
1643 if (
Data.Attributes != OMPC_reduction ||
1644 Data.Modifier != OMPC_REDUCTION_task)
1646 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1647 if (!ReductionData.ReductionOp ||
1648 !ReductionData.ReductionOp.is<
const Expr *>())
1649 return DSAVarData();
1650 SR = ReductionData.ReductionRange;
1651 ReductionRef = ReductionData.ReductionOp.get<
const Expr *>();
1652 assert(I->TaskgroupReductionRef &&
"taskgroup reduction reference "
1653 "expression for the descriptor is not "
1655 TaskgroupDescriptor = I->TaskgroupReductionRef;
1656 return DSAVarData(I->Directive, OMPC_reduction,
Data.RefExpr.getPointer(),
1657 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1660 return DSAVarData();
1663bool DSAStackTy::isOpenMPLocal(
VarDecl *D, const_iterator I)
const {
1665 for (const_iterator E = end(); I != E; ++I) {
1666 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1670 Scope *CurScope = getCurScope();
1671 while (CurScope && CurScope != TopScope && !CurScope->
isDeclScope(D))
1673 return CurScope != TopScope;
1676 if (I->Context == DC)
1685 bool AcceptIfMutable =
true,
1686 bool *IsClassType =
nullptr) {
1688 Type =
Type.getNonReferenceType().getCanonicalType();
1689 bool IsConstant =
Type.isConstant(Context);
1694 if (
const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1696 RD = CTD->getTemplatedDecl();
1699 return IsConstant && !(SemaRef.
getLangOpts().CPlusPlus && RD &&
1706 bool AcceptIfMutable =
true,
1707 bool ListItemNotVar =
false) {
1711 unsigned Diag = ListItemNotVar ? diag::err_omp_const_list_item
1712 : IsClassType ? diag::err_omp_const_not_mutable_variable
1713 : diag::err_omp_const_variable;
1714 SemaRef.
Diag(ELoc,
Diag) << getOpenMPClauseName(CKind);
1715 if (!ListItemNotVar && D) {
1716 const VarDecl *VD = dyn_cast<VarDecl>(D);
1720 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1728const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(
ValueDecl *D,
1733 auto *VD = dyn_cast<VarDecl>(D);
1734 auto TI = Threadprivates.find(D);
1735 if (TI != Threadprivates.end()) {
1736 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1737 DVar.CKind = OMPC_threadprivate;
1738 DVar.Modifier = TI->getSecond().Modifier;
1741 if (VD && VD->
hasAttr<OMPThreadPrivateDeclAttr>()) {
1744 VD->
getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1745 DVar.CKind = OMPC_threadprivate;
1746 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1753 !(VD->
hasAttr<OMPThreadPrivateDeclAttr>() &&
1760 DVar.CKind = OMPC_threadprivate;
1761 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1766 !isLoopControlVariable(D).first) {
1767 const_iterator IterTarget =
1768 std::find_if(begin(), end(), [](
const SharingMapTy &
Data) {
1771 if (IterTarget != end()) {
1772 const_iterator ParentIterTarget = IterTarget + 1;
1773 for (const_iterator Iter = begin(); Iter != ParentIterTarget; ++Iter) {
1774 if (isOpenMPLocal(VD, Iter)) {
1778 DVar.CKind = OMPC_threadprivate;
1782 if (!isClauseParsingMode() || IterTarget != begin()) {
1783 auto DSAIter = IterTarget->SharingMap.find(D);
1784 if (DSAIter != IterTarget->SharingMap.end() &&
1786 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1787 DVar.CKind = OMPC_threadprivate;
1790 const_iterator End = end();
1792 std::distance(ParentIterTarget, End),
1796 IterTarget->ConstructLoc);
1797 DVar.CKind = OMPC_threadprivate;
1817 const_iterator I = begin();
1818 const_iterator EndI = end();
1819 if (FromParent && I != EndI)
1822 auto It = I->SharingMap.find(D);
1823 if (It != I->SharingMap.end()) {
1824 const DSAInfo &
Data = It->getSecond();
1825 DVar.RefExpr =
Data.RefExpr.getPointer();
1826 DVar.PrivateCopy =
Data.PrivateCopy;
1827 DVar.CKind =
Data.Attributes;
1828 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1829 DVar.DKind = I->Directive;
1830 DVar.Modifier =
Data.Modifier;
1831 DVar.AppliedToPointee =
Data.AppliedToPointee;
1836 DVar.CKind = OMPC_shared;
1843 if (SemaRef.
LangOpts.OpenMP <= 31) {
1851 DSAVarData DVarTemp = hasInnermostDSA(
1854 return C == OMPC_firstprivate ||
C == OMPC_shared;
1856 MatchesAlways, FromParent);
1857 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1860 DVar.CKind = OMPC_shared;
1867 const_iterator I = begin();
1868 const_iterator EndI = end();
1869 if (FromParent && I != EndI)
1873 auto It = I->SharingMap.find(D);
1874 if (It != I->SharingMap.end()) {
1875 const DSAInfo &
Data = It->getSecond();
1876 DVar.RefExpr =
Data.RefExpr.getPointer();
1877 DVar.PrivateCopy =
Data.PrivateCopy;
1878 DVar.CKind =
Data.Attributes;
1879 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1880 DVar.DKind = I->Directive;
1881 DVar.Modifier =
Data.Modifier;
1882 DVar.AppliedToPointee =
Data.AppliedToPointee;
1888const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(
ValueDecl *D,
1889 bool FromParent)
const {
1890 if (isStackEmpty()) {
1892 return getDSA(I, D);
1895 const_iterator StartI = begin();
1896 const_iterator EndI = end();
1897 if (FromParent && StartI != EndI)
1899 return getDSA(StartI, D);
1902const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(
ValueDecl *D,
1903 unsigned Level)
const {
1904 if (getStackSize() <= Level)
1905 return DSAVarData();
1907 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1908 return getDSA(StartI, D);
1911const DSAStackTy::DSAVarData
1914 DefaultDataSharingAttributes)>
1917 bool FromParent)
const {
1921 const_iterator I = begin();
1922 const_iterator EndI = end();
1923 if (FromParent && I != EndI)
1925 for (; I != EndI; ++I) {
1926 if (!DPred(I->Directive) &&
1927 !isImplicitOrExplicitTaskingRegion(I->Directive))
1929 const_iterator NewI = I;
1930 DSAVarData DVar = getDSA(NewI, D);
1931 if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee, I->DefaultAttr))
1937const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1940 bool FromParent)
const {
1944 const_iterator StartI = begin();
1945 const_iterator EndI = end();
1946 if (FromParent && StartI != EndI)
1948 if (StartI == EndI || !DPred(StartI->Directive))
1950 const_iterator NewI = StartI;
1951 DSAVarData DVar = getDSA(NewI, D);
1952 return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1957bool DSAStackTy::hasExplicitDSA(
1960 unsigned Level,
bool NotLastprivate)
const {
1961 if (getStackSize() <= Level)
1964 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1965 auto I = StackElem.SharingMap.find(D);
1966 if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1967 CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1968 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1971 auto LI = StackElem.LCVMap.find(D);
1972 if (LI != StackElem.LCVMap.end())
1973 return CPred(OMPC_private,
false);
1977bool DSAStackTy::hasExplicitDirective(
1979 unsigned Level)
const {
1980 if (getStackSize() <= Level)
1982 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1983 return DPred(StackElem.Directive);
1986bool DSAStackTy::hasDirective(
1990 bool FromParent)
const {
1992 size_t Skip = FromParent ? 2 : 1;
1993 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1995 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
2001void Sema::InitDataSharingAttributesStack() {
2002 VarDataSharingAttributesStack =
new DSAStackTy(*
this);
2005#define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
2007void Sema::pushOpenMPFunctionRegion() {
DSAStack->pushFunction(); }
2015 "Expected OpenMP device compilation.");
2021enum class FunctionEmissionStatus {
2032 "Expected OpenMP device compilation.");
2058 llvm_unreachable(
"CUDADiscarded unexpected in OpenMP device compilation");
2070 "Expected OpenMP host compilation.");
2095 if (LO.OpenMP <= 45) {
2097 return OMPC_DEFAULTMAP_scalar;
2098 return OMPC_DEFAULTMAP_aggregate;
2101 return OMPC_DEFAULTMAP_pointer;
2103 return OMPC_DEFAULTMAP_scalar;
2104 return OMPC_DEFAULTMAP_aggregate;
2108 unsigned OpenMPCaptureLevel)
const {
2109 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
2112 bool IsByRef =
true;
2118 bool IsVariableUsedInMapClause =
false;
2180 bool IsVariableAssociatedWithSection =
false;
2182 DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2184 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection,
2191 if (WhereFoundClauseKind != OMPC_map &&
2192 WhereFoundClauseKind != OMPC_has_device_addr)
2195 auto EI = MapExprComponents.rbegin();
2196 auto EE = MapExprComponents.rend();
2198 assert(EI != EE &&
"Invalid map expression!");
2200 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2201 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2206 auto Last = std::prev(EE);
2208 dyn_cast<UnaryOperator>(
Last->getAssociatedExpression());
2209 if ((UO && UO->getOpcode() == UO_Deref) ||
2210 isa<ArraySubscriptExpr>(
Last->getAssociatedExpression()) ||
2211 isa<OMPArraySectionExpr>(
Last->getAssociatedExpression()) ||
2212 isa<MemberExpr>(EI->getAssociatedExpression()) ||
2213 isa<OMPArrayShapingExpr>(
Last->getAssociatedExpression())) {
2214 IsVariableAssociatedWithSection =
true;
2223 if (IsVariableUsedInMapClause) {
2226 IsByRef = !(Ty->
isPointerType() && IsVariableAssociatedWithSection);
2231 IsByRef = (
DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2234 DSAStack->isDefaultmapCapturedByRef(
2239 return K == OMPC_reduction && !AppliedToPointee;
2247 ((IsVariableUsedInMapClause &&
2248 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2253 return K == OMPC_firstprivate ||
2254 (K == OMPC_reduction && AppliedToPointee);
2257 DSAStack->isUsesAllocatorsDecl(Level, D))) &&
2260 !(isa<OMPCapturedExprDecl>(D) && !D->
hasAttr<OMPCaptureNoInitAttr>() &&
2261 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2264 !((
DSAStack->getDefaultDSA() == DSA_firstprivate ||
2265 DSAStack->getDefaultDSA() == DSA_private) &&
2269 !
DSAStack->isLoopControlVariable(D, Level).first);
2286unsigned Sema::getOpenMPNestingLevel()
const {
2288 return DSAStack->getNestingLevel();
2298 !
DSAStack->isClauseParsingMode()) ||
2309 if (!dyn_cast<FieldDecl>(D))
2311 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2314 DefaultDataSharingAttributes DefaultAttr) {
2316 (DefaultAttr == DSA_firstprivate || DefaultAttr == DSA_private);
2320 if (DVarPrivate.CKind != OMPC_unknown)
2326 Expr *CaptureExpr,
bool WithInit,
2332 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
2335 auto *VD = dyn_cast<VarDecl>(D);
2344 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2353 DSAStackTy::DSAVarData DVarTop =
2355 if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr)
2360 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2366 if (!isa<CapturingScopeInfo>(FSI))
2368 if (
auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2374 assert(CSI &&
"Failed to find CapturedRegionScopeInfo");
2385 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2391 if (CheckScopeInfo) {
2392 bool OpenMPFound =
false;
2393 for (
unsigned I = StopAt + 1; I > 0; --I) {
2395 if (!isa<CapturingScopeInfo>(FSI))
2397 if (
auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2407 if (
DSAStack->getCurrentDirective() != OMPD_unknown &&
2408 (!
DSAStack->isClauseParsingMode() ||
2409 DSAStack->getParentDirective() != OMPD_unknown)) {
2410 auto &&Info =
DSAStack->isLoopControlVariable(D);
2413 isImplicitOrExplicitTaskingRegion(
DSAStack->getCurrentDirective())) ||
2414 (VD &&
DSAStack->isForceVarCapturing()))
2415 return VD ? VD : Info.second;
2416 DSAStackTy::DSAVarData DVarTop =
2418 if (DVarTop.CKind != OMPC_unknown &&
isOpenMPPrivate(DVarTop.CKind) &&
2420 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2426 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2434 if (VD && !VD->
hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2435 ((
DSAStack->getDefaultDSA() != DSA_none &&
2436 DSAStack->getDefaultDSA() != DSA_private &&
2437 DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2438 DVarTop.CKind == OMPC_shared))
2440 auto *FD = dyn_cast<FieldDecl>(D);
2441 if (DVarPrivate.CKind != OMPC_unknown && !VD && FD &&
2442 !DVarPrivate.PrivateCopy) {
2443 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2446 DefaultDataSharingAttributes DefaultAttr) {
2448 (DefaultAttr == DSA_firstprivate ||
2449 DefaultAttr == DSA_private);
2453 if (DVarPrivate.CKind == OMPC_unknown)
2471 *
this, FD->
getIdentifier(), ME, DVarPrivate.CKind != OMPC_private,
2475 VD = cast<VarDecl>(VDPrivateRefExpr->
getDecl());
2476 DSAStack->addImplicitDefaultFirstprivateFD(FD, VD);
2479 if (DVarPrivate.CKind != OMPC_unknown ||
2480 (VD && (
DSAStack->getDefaultDSA() == DSA_none ||
2481 DSAStack->getDefaultDSA() == DSA_private ||
2482 DSAStack->getDefaultDSA() == DSA_firstprivate)))
2483 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2488void Sema::adjustOpenMPTargetScopeIndex(
unsigned &FunctionScopesIndex,
2489 unsigned Level)
const {
2494 assert(
LangOpts.OpenMP &&
"OpenMP must be enabled.");
2500 assert(
LangOpts.OpenMP &&
"OpenMP must be enabled.");
2502 DSAStack->resetPossibleLoopCounter();
2508 unsigned CapLevel)
const {
2509 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
2510 if (
DSAStack->getCurrentDirective() != OMPD_unknown &&
2511 (!
DSAStack->isClauseParsingMode() ||
2512 DSAStack->getParentDirective() != OMPD_unknown)) {
2513 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2516 DefaultDataSharingAttributes DefaultAttr) {
2518 DefaultAttr == DSA_private;
2522 if (DVarPrivate.CKind == OMPC_private && isa<OMPCapturedExprDecl>(D) &&
2523 DSAStack->isImplicitDefaultFirstprivateFD(cast<VarDecl>(D)) &&
2524 !
DSAStack->isLoopControlVariable(D).first)
2525 return OMPC_private;
2528 bool IsTriviallyCopyable =
2538 (IsTriviallyCopyable ||
2544 return OMPC_firstprivate;
2545 DSAStackTy::DSAVarData DVar =
DSAStack->getImplicitDSA(D, Level);
2546 if (DVar.CKind != OMPC_shared &&
2547 !
DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2548 DSAStack->addImplicitTaskFirstprivate(Level, D);
2549 return OMPC_firstprivate;
2555 DSAStack->resetPossibleLoopCounter(D);
2557 return OMPC_private;
2560 DSAStack->isLoopControlVariable(D).first) &&
2565 return OMPC_private;
2567 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
2573 return OMPC_private;
2578 DSAStack->isUsesAllocatorsDecl(Level, D).value_or(
2579 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2580 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2581 return OMPC_private;
2585 (
DSAStack->isClauseParsingMode() &&
2586 DSAStack->getClauseParsingMode() == OMPC_private) ||
2591 return K == OMPD_taskgroup ||
2592 ((isOpenMPParallelDirective(K) ||
2593 isOpenMPWorksharingDirective(K)) &&
2594 !isOpenMPSimdDirective(K));
2597 DSAStack->isTaskgroupReductionRef(D, Level)))
2604 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
2607 for (
unsigned I =
DSAStack->getNestingLevel() + 1; I > Level; --I) {
2608 const unsigned NewLevel = I - 1;
2612 if (isOpenMPPrivate(K) && !AppliedToPointee) {
2620 if (
DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2630 if (
DSAStack->mustBeFirstprivateAtLevel(
2632 OMPC = OMPC_firstprivate;
2636 if (OMPC != OMPC_unknown)
2637 FD->
addAttr(OMPCaptureKindAttr::CreateImplicit(Context,
unsigned(OMPC)));
2641 unsigned CaptureLevel)
const {
2642 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
2647 const auto *VD = dyn_cast<VarDecl>(D);
2651 Regions[CaptureLevel] != OMPD_task;
2655 unsigned CaptureLevel)
const {
2656 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
2659 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
2663 DSAStackTy::DSAVarData TopDVar =
2665 unsigned NumLevels =
2670 return (NumLevels == CaptureLevel + 1 &&
2671 (TopDVar.CKind != OMPC_shared ||
2672 DSAStack->getDefaultDSA() == DSA_firstprivate));
2675 DSAStackTy::DSAVarData DVar =
DSAStack->getImplicitDSA(D, Level);
2676 if (DVar.CKind != OMPC_shared)
2678 }
while (Level > 0);
2684void Sema::DestroyDataSharingAttributesStack() {
delete DSAStack; }
2688 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2693 "Not in OpenMP declare variant scope!");
2695 OMPDeclareVariantScopes.pop_back();
2701 assert(
LangOpts.OpenMP &&
"Expected OpenMP compilation mode.");
2702 std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2706 (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host))
2709 if (!
LangOpts.OpenMPIsDevice && DevTy &&
2710 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2713 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2714 if (
LangOpts.OpenMPIsDevice && DevTy &&
2715 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2717 StringRef HostDevTy =
2719 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2720 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2721 diag::note_omp_marked_device_type_here)
2725 if (!
LangOpts.OpenMPIsDevice && !
LangOpts.OpenMPOffloadMandatory && DevTy &&
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)
2758 DSAStack->push(DKind, DirName, CurScope, Loc);
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->varlists()) {
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);
2859 if (
const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2861 if (
auto *Clause = dyn_cast<OMPLastprivateClause>(
C)) {
2863 for (
Expr *DE : Clause->varlists()) {
2864 if (DE->isValueDependent() || DE->isTypeDependent()) {
2865 PrivateCopies.push_back(
nullptr);
2868 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2869 auto *VD = cast<VarDecl>(DRE->getDecl());
2871 const DSAStackTy::DSAVarData DVar =
2873 if (DVar.CKind == OMPC_lastprivate) {
2880 *
this, DE->getExprLoc(),
Type.getUnqualifiedType(),
2884 PrivateCopies.push_back(
nullptr);
2888 *
this, VDPrivate, DE->
getType(), DE->getExprLoc()));
2892 PrivateCopies.push_back(
nullptr);
2895 Clause->setPrivateCopies(PrivateCopies);
2899 if (
auto *Clause = dyn_cast<OMPNontemporalClause>(
C)) {
2901 for (
Expr *RefExpr : Clause->varlists()) {
2902 assert(RefExpr &&
"NULL expr in OpenMP nontemporal clause.");
2905 Expr *SimpleRefExpr = RefExpr;
2909 PrivateRefs.push_back(RefExpr);
2914 const DSAStackTy::DSAVarData DVar =
2916 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2919 Clause->setPrivateRefs(PrivateRefs);
2922 if (
auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(
C)) {
2923 for (
unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2929 if (!VD || !isa<VarDecl>(VD))
2931 DSAStackTy::DSAVarData DVar =
2937 Expr *MapExpr =
nullptr;
2939 DSAStack->checkMappableExprComponentListsForDecl(
2945 auto MI = MapExprComponents.rbegin();
2946 auto ME = MapExprComponents.rend();
2948 MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2949 VD->getCanonicalDecl()) {
2950 MapExpr = MI->getAssociatedExpression();
2955 Diag(D.Allocator->getExprLoc(),
2956 diag::err_omp_allocator_used_in_clauses)
2961 Diag(MapExpr->getExprLoc(), diag::note_used_here)
2962 << MapExpr->getSourceRange();
2975 DiscardCleanupsInEvaluationContext();
2976 PopExpressionEvaluationContext();
2980 Expr *NumIterations,
Sema &SemaRef,
2981 Scope *S, DSAStackTy *Stack);
2990 explicit VarDeclFilterCCC(
Sema &S) : SemaRef(S) {}
2991 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
2993 if (
const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
3001 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
3002 return std::make_unique<VarDeclFilterCCC>(*
this);
3011 explicit VarOrFuncDeclFilterCCC(
Sema &S) : SemaRef(S) {}
3012 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
3014 if (ND && ((isa<VarDecl>(ND) && ND->
getKind() == Decl::Var) ||
3015 isa<FunctionDecl>(ND))) {
3022 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
3023 return std::make_unique<VarOrFuncDeclFilterCCC>(*
this);
3041 VarDeclFilterCCC CCC(*
this);
3047 ? diag::err_undeclared_var_use_suggest
3048 : diag::err_omp_expected_var_arg_suggest)
3050 VD = Corrected.getCorrectionDeclAs<
VarDecl>();
3052 Diag(
Id.getLoc(), Lookup.
empty() ? diag::err_undeclared_var_use
3053 : diag::err_omp_expected_var_arg)
3058 Diag(
Id.getLoc(), diag::err_omp_expected_var_arg) <<
Id.getName();
3067 Diag(
Id.getLoc(), diag::err_omp_global_var_arg)
3072 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3084 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3085 << getOpenMPDirectiveName(Kind) << VD;
3089 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3099 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3100 << getOpenMPDirectiveName(Kind) << VD;
3104 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3115 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3116 << getOpenMPDirectiveName(Kind) << VD;
3120 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3129 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3130 << getOpenMPDirectiveName(Kind) << VD;
3134 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3142 if (Kind == OMPD_threadprivate && VD->
isUsed() &&
3144 Diag(
Id.getLoc(), diag::err_omp_var_used)
3145 << getOpenMPDirectiveName(Kind) << VD;
3167class LocalVarRefChecker final
3173 if (
const auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
3176 diag::err_omp_local_var_in_threadprivate_init)
3178 SemaRef.Diag(VD->
getLocation(), diag::note_defined_here)
3185 bool VisitStmt(
const Stmt *S) {
3186 for (
const Stmt *Child : S->children()) {
3187 if (Child && Visit(Child))
3192 explicit LocalVarRefChecker(
Sema &SemaRef) : SemaRef(SemaRef) {}
3199 for (
Expr *RefExpr : VarList) {
3200 auto *DE = cast<DeclRefExpr>(RefExpr);
3201 auto *VD = cast<VarDecl>(DE->getDecl());
3218 diag::err_omp_threadprivate_incomplete_type)) {
3225 Diag(ILoc, diag::err_omp_ref_type_arg)
3226 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->
getType();
3230 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3238 !(VD->
hasAttr<OMPThreadPrivateDeclAttr>() &&
3243 Diag(ILoc, diag::err_omp_var_thread_local)
3248 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3256 LocalVarRefChecker Checker(*
this);
3257 if (Checker.Visit(Init))
3261 Vars.push_back(RefExpr);
3262 DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3263 VD->
addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3266 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3269 if (!Vars.empty()) {
3277static OMPAllocateDeclAttr::AllocatorTypeTy
3280 return OMPAllocateDeclAttr::OMPNullMemAlloc;
3281 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3282 Allocator->isInstantiationDependent() ||
3283 Allocator->containsUnexpandedParameterPack())
3284 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3285 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3286 llvm::FoldingSetNodeID AEId;
3287 const Expr *AE = Allocator->IgnoreParenImpCasts();
3289 for (
int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3290 auto AllocatorKind =
static_cast<OMPAllocateDeclAttr::AllocatorTypeTy
>(I);
3291 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3292 llvm::FoldingSetNodeID DAEId;
3295 if (AEId == DAEId) {
3296 AllocatorKindRes = AllocatorKind;
3300 return AllocatorKindRes;
3305 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
Expr *Allocator) {
3306 if (!VD->
hasAttr<OMPAllocateDeclAttr>())
3308 const auto *A = VD->
getAttr<OMPAllocateDeclAttr>();
3309 Expr *PrevAllocator = A->getAllocator();
3310 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3312 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3313 if (AllocatorsMatch &&
3314 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3315 Allocator && PrevAllocator) {
3316 const Expr *AE = Allocator->IgnoreParenImpCasts();
3318 llvm::FoldingSetNodeID AEId, PAEId;
3321 AllocatorsMatch = AEId == PAEId;
3323 if (!AllocatorsMatch) {
3325 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3329 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3331 PrevAllocator->printPretty(PrevAllocatorStream,
nullptr,
3335 Allocator ? Allocator->getExprLoc() : RefExpr->
getExprLoc();
3337 Allocator ? Allocator->getSourceRange() : RefExpr->
getSourceRange();
3339 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3341 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3342 S.
Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3343 << (Allocator ? 1 : 0) << AllocatorStream.str()
3344 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3346 S.
Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3347 << PrevAllocatorRange;
3355 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3357 if (VD->
hasAttr<OMPAllocateDeclAttr>())
3366 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3367 Allocator->isInstantiationDependent() ||
3368 Allocator->containsUnexpandedParameterPack()))
3370 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.
Context, AllocatorKind,
3371 Allocator, Alignment, SR);
3374 ML->DeclarationMarkedOpenMPAllocate(VD, A);
3381 assert(Clauses.size() <= 2 &&
"Expected at most two clauses.");
3382 Expr *Alignment =
nullptr;
3383 Expr *Allocator =
nullptr;
3384 if (Clauses.empty()) {
3391 targetDiag(Loc, diag::err_expected_allocator_clause);
3394 if (
const auto *AC = dyn_cast<OMPAllocatorClause>(
C))
3395 Allocator = AC->getAllocator();
3396 else if (
const auto *AC = dyn_cast<OMPAlignClause>(
C))
3397 Alignment = AC->getAlignment();
3399 llvm_unreachable(
"Unexpected clause on allocate directive");
3401 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3404 for (
Expr *RefExpr : VarList) {
3405 auto *DE = cast<DeclRefExpr>(RefExpr);
3406 auto *VD = cast<VarDecl>(DE->getDecl());
3410 VD->
hasAttr<OMPThreadPrivateDeclAttr>() ||
3418 AllocatorKind, Allocator))
3426 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3427 Diag(Allocator->getExprLoc(),
3428 diag::err_omp_expected_predefined_allocator)
3429 << Allocator->getSourceRange();
3433 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3439 Vars.push_back(RefExpr);
3458 Diag(Loc, diag::err_omp_invalid_scope) <<
"requires";
3472 bool SkippedClauses) {
3473 if (!SkippedClauses && Assumptions.empty())
3474 Diag(Loc, diag::err_omp_no_clause_for_directive)
3475 << llvm::omp::getAllAssumeClauseOptions()
3476 << llvm::omp::getOpenMPDirectiveName(DKind);
3478 auto *AA = AssumptionAttr::Create(
Context, llvm::join(Assumptions,
","), Loc);
3479 if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3480 OMPAssumeScoped.push_back(AA);
3485 if (Assumptions.empty())
3488 assert(DKind == llvm::omp::Directive::OMPD_assumes &&
3489 "Unexpected omp assumption directive!");
3490 OMPAssumeGlobal.push_back(AA);
3498 while (Ctx->getLexicalParent())
3500 DeclContexts.push_back(Ctx);
3501 while (!DeclContexts.empty()) {
3503 for (
auto *SubDC : DC->
decls()) {
3504 if (SubDC->isInvalidDecl())
3506 if (
auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3507 DeclContexts.push_back(CTD->getTemplatedDecl());
3508 llvm::append_range(DeclContexts, CTD->specializations());
3511 if (
auto *DC = dyn_cast<DeclContext>(SubDC))
3512 DeclContexts.push_back(DC);
3513 if (
auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3523 OMPAssumeScoped.pop_back();
3532 DSAStack->getEncounteredTargetLocs();
3534 if (!TargetLocations.empty() || !AtomicLoc.
isInvalid()) {
3535 for (
const OMPClause *CNew : ClauseList) {
3537 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3538 isa<OMPUnifiedAddressClause>(CNew) ||
3539 isa<OMPReverseOffloadClause>(CNew) ||
3540 isa<OMPDynamicAllocatorsClause>(CNew)) {
3541 Diag(Loc, diag::err_omp_directive_before_requires)
3542 <<
"target" << getOpenMPClauseName(CNew->getClauseKind());
3544 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3548 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3549 Diag(Loc, diag::err_omp_directive_before_requires)
3550 <<
"atomic" << getOpenMPClauseName(CNew->getClauseKind());
3551 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3557 if (!
DSAStack->hasDuplicateRequiresClause(ClauseList))
3565 const DSAStackTy::DSAVarData &DVar,
3566 bool IsLoopIterVar) {
3568 SemaRef.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3569 << getOpenMPClauseName(DVar.CKind);
3573 PDSA_StaticMemberShared,
3574 PDSA_StaticLocalVarShared,
3575 PDSA_LoopIterVarPrivate,
3576 PDSA_LoopIterVarLinear,
3577 PDSA_LoopIterVarLastprivate,
3578 PDSA_ConstVarShared,
3579 PDSA_GlobalVarShared,
3580 PDSA_TaskVarFirstprivate,
3581 PDSA_LocalVarPrivate,
3583 } Reason = PDSA_Implicit;
3584 bool ReportHint =
false;
3586 auto *VD = dyn_cast<VarDecl>(D);
3587 if (IsLoopIterVar) {
3588 if (DVar.CKind == OMPC_private)
3589 Reason = PDSA_LoopIterVarPrivate;
3590 else if (DVar.CKind == OMPC_lastprivate)
3591 Reason = PDSA_LoopIterVarLastprivate;
3593 Reason = PDSA_LoopIterVarLinear;
3595 DVar.CKind == OMPC_firstprivate) {
3596 Reason = PDSA_TaskVarFirstprivate;
3597 ReportLoc = DVar.ImplicitDSALoc;
3599 Reason = PDSA_StaticLocalVarShared;
3601 Reason = PDSA_StaticMemberShared;
3603 Reason = PDSA_GlobalVarShared;
3605 Reason = PDSA_ConstVarShared;
3606 else if (VD && VD->
isLocalVarDecl() && DVar.CKind == OMPC_private) {
3608 Reason = PDSA_LocalVarPrivate;
3610 if (Reason != PDSA_Implicit) {
3611 SemaRef.
Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3612 << Reason << ReportHint
3613 << getOpenMPDirectiveName(Stack->getCurrentDirective());
3614 }
else if (DVar.ImplicitDSALoc.isValid()) {
3615 SemaRef.
Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3616 << getOpenMPClauseName(DVar.CKind);
3622 bool IsAggregateOrDeclareTarget) {
3625 case OMPC_DEFAULTMAP_MODIFIER_alloc:
3626 Kind = OMPC_MAP_alloc;
3628 case OMPC_DEFAULTMAP_MODIFIER_to:
3631 case OMPC_DEFAULTMAP_MODIFIER_from:
3632 Kind = OMPC_MAP_from;
3634 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3635 Kind = OMPC_MAP_tofrom;
3637 case OMPC_DEFAULTMAP_MODIFIER_present:
3643 Kind = OMPC_MAP_alloc;
3645 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3647 llvm_unreachable(
"Unexpected defaultmap implicit behavior");
3648 case OMPC_DEFAULTMAP_MODIFIER_none:
3649 case OMPC_DEFAULTMAP_MODIFIER_default:
3654 if (IsAggregateOrDeclareTarget) {
3655 Kind = OMPC_MAP_tofrom;
3658 llvm_unreachable(
"Unexpected defaultmap implicit behavior");
3665class DSAAttrChecker final :
public StmtVisitor<DSAAttrChecker, void> {
3668 bool ErrorFound =
false;
3669 bool TryCaptureCXXThisMembers =
false;
3671 const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
3676 ImplicitMapModifier[DefaultmapKindNum];
3678 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3682 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3684 if (S->getDirectiveKind() == OMPD_atomic ||
3685 S->getDirectiveKind() == OMPD_critical ||
3686 S->getDirectiveKind() == OMPD_section ||
3687 S->getDirectiveKind() == OMPD_master ||
3688 S->getDirectiveKind() == OMPD_masked ||
3690 Visit(S->getAssociatedStmt());
3693 visitSubCaptures(S->getInnermostCapturedStmt());
3696 if (TryCaptureCXXThisMembers ||
3698 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3700 return C.capturesThis();
3702 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3703 TryCaptureCXXThisMembers =
true;
3704 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3705 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3712 if (
auto *FC = dyn_cast<OMPFirstprivateClause>(
C)) {
3713 for (
Expr *Ref : FC->varlists())
3725 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
3728 !Stack->getTopDSA(VD,
false).RefExpr &&
3729 !Stack->isImplicitDefaultFirstprivateFD(VD))) {
3730 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3731 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3732 Visit(CED->getInit());
3735 }
else if (VD->
isImplicit() || isa<OMPCapturedExprDecl>(VD))
3738 if (!Stack->isImplicitDefaultFirstprivateFD(VD))
3743 !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3744 !Stack->isImplicitTaskFirstprivate(VD))
3747 if (Stack->isUsesAllocatorsDecl(VD))
3750 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD,
false);
3752 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3756 std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3757 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3760 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3761 !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3762 !Stack->isImplicitTaskFirstprivate(VD))
3771 if (DVar.CKind == OMPC_unknown &&
3772 (Stack->getDefaultDSA() == DSA_none ||
3773 Stack->getDefaultDSA() == DSA_private ||
3774 Stack->getDefaultDSA() == DSA_firstprivate) &&
3775 isImplicitOrExplicitTaskingRegion(DKind) &&
3776 VarsWithInheritedDSA.count(VD) == 0) {
3777 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3778 if (!InheritedDSA && (Stack->getDefaultDSA() == DSA_firstprivate ||
3779 Stack->getDefaultDSA() == DSA_private)) {
3780 DSAStackTy::DSAVarData DVar =
3781 Stack->getImplicitDSA(VD,
false);
3782 InheritedDSA = DVar.CKind == OMPC_unknown;
3785 VarsWithInheritedDSA[VD] = E;
3786 if (Stack->getDefaultDSA() == DSA_none)
3801 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3802 OMPC_DEFAULTMAP_MODIFIER_none;
3803 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3804 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3808 if (!Stack->checkMappableExprComponentListsForDecl(
3813 auto MI = MapExprComponents.rbegin();
3814 auto ME = MapExprComponents.rend();
3815 return MI != ME && MI->getAssociatedDeclaration() == VD;
3817 VarsWithInheritedDSA[VD] = E;
3823 bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3824 OMPC_DEFAULTMAP_MODIFIER_present;
3825 if (IsModifierPresent) {
3826 if (!llvm::is_contained(ImplicitMapModifier[ClauseKind],
3827 OMPC_MAP_MODIFIER_present)) {
3828 ImplicitMapModifier[ClauseKind].push_back(
3829 OMPC_MAP_MODIFIER_present);
3835 !Stack->isLoopControlVariable(VD).first) {
3836 if (!Stack->checkMappableExprComponentListsForDecl(
3841 if (SemaRef.LangOpts.OpenMP >= 50)
3842 return !StackComponents.empty();
3845 return StackComponents.size() == 1 ||
3847 llvm::drop_begin(llvm::reverse(StackComponents)),
3848 [](const OMPClauseMappableExprCommon::
3849 MappableComponent &MC) {
3850 return MC.getAssociatedDeclaration() ==
3852 (isa<OMPArraySectionExpr>(
3853 MC.getAssociatedExpression()) ||
3854 isa<OMPArrayShapingExpr>(
3855 MC.getAssociatedExpression()) ||
3856 isa<ArraySubscriptExpr>(
3857 MC.getAssociatedExpression()));
3860 bool IsFirstprivate =
false;
3862 if (
const auto *RD =
3864 IsFirstprivate = RD->isLambda();
3866 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3867 if (IsFirstprivate) {
3868 ImplicitFirstprivate.emplace_back(E);
3871 Stack->getDefaultmapModifier(ClauseKind);
3873 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3874 ImplicitMap[ClauseKind][
Kind].emplace_back(E);
3884 DVar = Stack->hasInnermostDSA(
3887 return C == OMPC_reduction && !AppliedToPointee;
3896 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
3902 DVar = Stack->getImplicitDSA(VD,
false);
3904 (((Stack->getDefaultDSA() == DSA_firstprivate &&
3905 DVar.CKind == OMPC_firstprivate) ||
3906 (Stack->getDefaultDSA() == DSA_private &&
3907 DVar.CKind == OMPC_private)) &&
3909 !Stack->isLoopControlVariable(VD).first) {
3910 if (Stack->getDefaultDSA() == DSA_private)
3911 ImplicitPrivate.push_back(E);
3913 ImplicitFirstprivate.push_back(E);
3920 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3921 Stack->addToParentTargetRegionLinkGlobals(E);
3935 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD,
false);
3938 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3942 !Stack->isLoopControlVariable(FD).first &&
3943 !Stack->checkMappableExprComponentListsForDecl(
3948 return isa<CXXThisExpr>(
3950 StackComponents.back().getAssociatedExpression())
3962 if (Stack->isClassPreviouslyMapped(TE->getType()))
3966 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3971 ImplicitMap[ClauseKind][
Kind].emplace_back(E);
3980 DVar = Stack->hasInnermostDSA(
3983 return C == OMPC_reduction && !AppliedToPointee;
3992 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
3998 DVar = Stack->getImplicitDSA(FD,
false);
4000 !Stack->isLoopControlVariable(FD).first) {
4005 if (DVar.CKind != OMPC_unknown)
4006 ImplicitFirstprivate.push_back(E);
4013 Stack->getCurrentDirective(),
4016 const auto *VD = cast<ValueDecl>(
4017 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
4018 if (!Stack->checkMappableExprComponentListsForDecl(
4024 auto CCI = CurComponents.rbegin();
4025 auto CCE = CurComponents.rend();
4026 for (const auto &SC : llvm::reverse(StackComponents)) {
4028 if (CCI->getAssociatedExpression()->getStmtClass() !=
4029 SC.getAssociatedExpression()->getStmtClass())
4030 if (!((isa<OMPArraySectionExpr>(
4031 SC.getAssociatedExpression()) ||
4032 isa<OMPArrayShapingExpr>(
4033 SC.getAssociatedExpression())) &&
4034 isa<ArraySubscriptExpr>(
4035 CCI->getAssociatedExpression())))
4038 const Decl *CCD = CCI->getAssociatedDeclaration();
4039 const Decl *SCD = SC.getAssociatedDeclaration();
4040 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
4041 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
4044 std::advance(CCI, 1);
4052 }
else if (!TryCaptureCXXThisMembers) {
4060 if (isa_and_nonnull<OMPPrivateClause>(
C))
4066 if (
C && !((isa<OMPFirstprivateClause>(
C) || isa<OMPMapClause>(
C)) &&
4069 for (
Stmt *CC :
C->children()) {
4076 VisitSubCaptures(S);
4085 for (
Stmt *
C : S->arguments()) {
4092 if (
Expr *Callee = S->getCallee()) {
4093 auto *CI =
Callee->IgnoreParenImpCasts();
4094 if (
auto *CE = dyn_cast<MemberExpr>(CI))
4095 Visit(CE->getBase());
4096 else if (
auto *CE = dyn_cast<DeclRefExpr>(CI))
4100 void VisitStmt(
Stmt *S) {
4101 for (
Stmt *
C : S->children()) {
4112 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
4114 VarDecl *VD = Cap.getCapturedVar();
4118 Stack->checkMappableExprComponentListsForDecl(
4125 Cap.getLocation(),
true);
4129 bool isErrorFound()
const {
return ErrorFound; }
4131 return ImplicitFirstprivate;
4136 return ImplicitMap[DK][MK];
4140 return ImplicitMapModifier[
Kind];
4143 return VarsWithInheritedDSA;
4147 : Stack(S), SemaRef(SemaRef), ErrorFound(
false), CS(CS) {
4162 Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target);
4164 Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams);
4166 Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel);
4168 Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for);
4170 Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd);
4171 Stack->handleConstructTrait(Traits, ScopeEntry);
4177 case OMPD_parallel_for:
4178 case OMPD_parallel_for_simd:
4179 case OMPD_parallel_sections:
4180 case OMPD_parallel_master:
4181 case OMPD_parallel_masked:
4182 case OMPD_parallel_loop:
4184 case OMPD_teams_distribute:
4185 case OMPD_teams_distribute_simd: {
4190 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4191 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4192 std::make_pair(StringRef(),
QualType())
4198 case OMPD_target_teams:
4199 case OMPD_target_parallel:
4200 case OMPD_target_parallel_for:
4201 case OMPD_target_parallel_for_simd:
4202 case OMPD_target_teams_loop:
4203 case OMPD_target_parallel_loop:
4204 case OMPD_target_teams_distribute:
4205 case OMPD_target_teams_distribute_simd: {
4215 std::make_pair(
".global_tid.", KmpInt32Ty),
4216 std::make_pair(
".part_id.", KmpInt32PtrTy),
4217 std::make_pair(
".privates.", VoidPtrTy),
4222 std::make_pair(StringRef(),
QualType())
4229 AlwaysInlineAttr::CreateImplicit(
4231 AlwaysInlineAttr::Keyword_forceinline));
4233 std::make_pair(StringRef(),
QualType())
4239 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4240 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4241 std::make_pair(StringRef(),
QualType())
4246 ParamsTeamsOrParallel, 2);
4250 case OMPD_target_simd: {
4260 std::make_pair(
".global_tid.", KmpInt32Ty),
4261 std::make_pair(
".part_id.", KmpInt32PtrTy),
4262 std::make_pair(
".privates.", VoidPtrTy),
4267 std::make_pair(StringRef(),
QualType())
4274 AlwaysInlineAttr::CreateImplicit(
4276 AlwaysInlineAttr::Keyword_forceinline));
4278 std::make_pair(StringRef(),
QualType()),
4298 case OMPD_taskgroup:
4299 case OMPD_distribute:
4300 case OMPD_distribute_simd:
4302 case OMPD_target_data:
4303 case OMPD_dispatch: {
4305 std::make_pair(StringRef(),
QualType())
4321 std::make_pair(
".global_tid.", KmpInt32Ty),
4322 std::make_pair(
".part_id.", KmpInt32PtrTy),
4323 std::make_pair(
".privates.", VoidPtrTy),
4328 std::make_pair(StringRef(),
QualType())
4335 AlwaysInlineAttr::CreateImplicit(
4337 AlwaysInlineAttr::Keyword_forceinline));
4341 case OMPD_taskloop_simd:
4342 case OMPD_master_taskloop:
4343 case OMPD_masked_taskloop:
4344 case OMPD_masked_taskloop_simd:
4345 case OMPD_master_taskloop_simd: {
4363 std::make_pair(
".global_tid.", KmpInt32Ty),
4364 std::make_pair(
".part_id.", KmpInt32PtrTy),
4365 std::make_pair(
".privates.", VoidPtrTy),
4370 std::make_pair(
".lb.", KmpUInt64Ty),
4371 std::make_pair(
".ub.", KmpUInt64Ty),
4372 std::make_pair(
".st.", KmpInt64Ty),
4373 std::make_pair(
".liter.", KmpInt32Ty),
4374 std::make_pair(
".reductions.", VoidPtrTy),
4375 std::make_pair(StringRef(),
QualType())
4382 AlwaysInlineAttr::CreateImplicit(
4384 AlwaysInlineAttr::Keyword_forceinline));
4387 case OMPD_parallel_masked_taskloop:
4388 case OMPD_parallel_masked_taskloop_simd:
4389 case OMPD_parallel_master_taskloop:
4390 case OMPD_parallel_master_taskloop_simd: {
4404 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4405 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4406 std::make_pair(StringRef(),
QualType())
4416 std::make_pair(
".global_tid.", KmpInt32Ty),
4417 std::make_pair(
".part_id.", KmpInt32PtrTy),
4418 std::make_pair(
".privates.", VoidPtrTy),
4423 std::make_pair(
".lb.", KmpUInt64Ty),
4424 std::make_pair(
".ub.", KmpUInt64Ty),
4425 std::make_pair(
".st.", KmpInt64Ty),
4426 std::make_pair(
".liter.", KmpInt32Ty),
4427 std::make_pair(
".reductions.", VoidPtrTy),
4428 std::make_pair(StringRef(),
QualType())
4435 AlwaysInlineAttr::CreateImplicit(
4437 AlwaysInlineAttr::Keyword_forceinline));
4440 case OMPD_distribute_parallel_for_simd:
4441 case OMPD_distribute_parallel_for: {
4446 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4447 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4450 std::make_pair(StringRef(),
QualType())
4456 case OMPD_target_teams_distribute_parallel_for:
4457 case OMPD_target_teams_distribute_parallel_for_simd: {
4468 std::make_pair(
".global_tid.", KmpInt32Ty),
4469 std::make_pair(
".part_id.", KmpInt32PtrTy),
4470 std::make_pair(
".privates.", VoidPtrTy),
4475 std::make_pair(StringRef(),
QualType())
4482 AlwaysInlineAttr::CreateImplicit(
4484 AlwaysInlineAttr::Keyword_forceinline));
4486 std::make_pair(StringRef(),
QualType())
4493 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4494 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4495 std::make_pair(StringRef(),
QualType())
4502 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4503 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4506 std::make_pair(StringRef(),
QualType())
4515 case OMPD_teams_loop: {
4521 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4522 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4523 std::make_pair(StringRef(),
QualType())
4531 case OMPD_teams_distribute_parallel_for:
4532 case OMPD_teams_distribute_parallel_for_simd: {
4538 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4539 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4540 std::make_pair(StringRef(),
QualType())
4547 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4548 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4551 std::make_pair(StringRef(),
QualType())
4559 case OMPD_target_update:
4560 case OMPD_target_enter_data:
4561 case OMPD_target_exit_data: {
4571 std::make_pair(
".global_tid.", KmpInt32Ty),
4572 std::make_pair(
".part_id.", KmpInt32PtrTy),
4573 std::make_pair(
".privates.", VoidPtrTy),
4578 std::make_pair(StringRef(),
QualType())
4585 AlwaysInlineAttr::CreateImplicit(
4587 AlwaysInlineAttr::Keyword_forceinline));
4590 case OMPD_threadprivate:
4592 case OMPD_taskyield:
4596 case OMPD_cancellation_point:
4601 case OMPD_declare_reduction:
4602 case OMPD_declare_mapper:
4603 case OMPD_declare_simd:
4604 case OMPD_declare_target:
4605 case OMPD_end_declare_target:
4607 case OMPD_declare_variant:
4608 case OMPD_begin_declare_variant:
4609 case OMPD_end_declare_variant:
4610 case OMPD_metadirective:
4611 llvm_unreachable(
"OpenMP Directive is not allowed");
4614 llvm_unreachable(
"Unknown OpenMP directive");
4620int Sema::getNumberOfConstructScopes(
unsigned Level)
const {
4627 return CaptureRegions.size();
4631 Expr *CaptureExpr,
bool WithInit,
4633 bool AsExpression) {
4634 assert(CaptureExpr);
4640 Ty =
C.getLValueReferenceType(Ty);
4642 Ty =
C.getPointerType(Ty);
4654 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(
C));
4665 CD = cast<OMPCapturedExprDecl>(VD);
4704class CaptureRegionUnwinderRAII {
4711 CaptureRegionUnwinderRAII(
Sema &S,
bool &ErrorFound,
4713 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4714 ~CaptureRegionUnwinderRAII() {
4717 while (--ThisCaptureLevel >= 0)
4730 DSAStack->getCurrentDirective()))) {
4732 if (
const auto *RD =
Type.getCanonicalType()
4733 .getNonReferenceType()
4735 bool SavedForceCaptureByReferenceInTargetExecutable =
4736 DSAStack->isForceCaptureByReferenceInTargetExecutable();
4737 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4739 if (RD->isLambda()) {
4740 llvm::DenseMap<const ValueDecl *, FieldDecl *> Captures;
4742 RD->getCaptureFields(Captures, ThisCapture);
4745 VarDecl *VD = cast<VarDecl>(LC.getCapturedVar());
4750 }
else if (LC.getCaptureKind() ==
LCK_This) {
4758 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4759 SavedForceCaptureByReferenceInTargetExecutable);
4769 for (
const OMPClause *Clause : Clauses) {
4771 Ordered = cast<OMPOrderedClause>(Clause);
4773 Order = cast<OMPOrderClause>(Clause);
4774 if (Order->
getKind() != OMPC_ORDER_concurrent)
4777 if (Ordered && Order)
4781 if (Ordered && Order) {
4783 diag::err_omp_simple_clause_incompatible_with_ordered)
4784 << getOpenMPClauseName(OMPC_order)
4798 if (
DSAStack->getCurrentDirective() == OMPD_atomic ||
4799 DSAStack->getCurrentDirective() == OMPD_critical ||
4800 DSAStack->getCurrentDirective() == OMPD_section ||
4801 DSAStack->getCurrentDirective() == OMPD_master ||
4802 DSAStack->getCurrentDirective() == OMPD_masked)
4805 bool ErrorFound =
false;
4806 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4807 *
this, ErrorFound,
DSAStack->getCurrentDirective());
4808 if (!S.isUsable()) {
4823 DSAStack->getCurrentDirective() == OMPD_target) &&
4827 auto *IRC = cast<OMPInReductionClause>(Clause);
4828 for (
Expr *E : IRC->taskgroup_descriptors())
4840 if (
auto *E = cast_or_null<Expr>(VarRef)) {
4844 DSAStack->setForceVarCapturing(
false);
4846 DSAStack->getCurrentDirective())) {
4847 assert(CaptureRegions.empty() &&
4848 "No captured regions in loop transformation directives.");
4849 }
else if (CaptureRegions.size() > 1 ||
4850 CaptureRegions.back() != OMPD_unknown) {
4854 if (
Expr *E =
C->getPostUpdateExpr())
4859 SC = cast<OMPScheduleClause>(Clause);
4861 OC = cast<OMPOrderedClause>(Clause);
4863 LCs.push_back(cast<OMPLinearClause>(Clause));
4874 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4879 diag::err_omp_simple_clause_incompatible_with_ordered)
4880 << getOpenMPClauseName(OMPC_schedule)
4882 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4893 Diag(
C->getBeginLoc(), diag::err_omp_linear_ordered)
4902 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
4909 unsigned CompletedRegions = 0;
4914 if (ThisCaptureRegion != OMPD_unknown) {
4922 if (CaptureRegion == ThisCaptureRegion ||
4923 CaptureRegion == OMPD_unknown) {
4924 if (
auto *DS = cast_or_null<DeclStmt>(
C->getPreInitStmt())) {
4925 for (
Decl *D : DS->decls())
4931 if (ThisCaptureRegion == OMPD_target) {
4935 if (
const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(
C)) {
4936 for (
unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4946 if (ThisCaptureRegion == OMPD_parallel) {
4950 if (
auto *RC = dyn_cast<OMPReductionClause>(
C)) {
4951 if (RC->getModifier() != OMPC_REDUCTION_inscan)
4953 for (
Expr *E : RC->copy_array_temps())
4956 if (
auto *AC = dyn_cast<OMPAlignedClause>(
C)) {
4957 for (
Expr *E : AC->varlists())
4962 if (++CompletedRegions == CaptureRegions.size())
4973 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4976 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4977 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4980 SemaRef.
Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4981 << getOpenMPDirectiveName(CancelRegion);
4991 if (Stack->getCurScope()) {
4994 bool NestingProhibited =
false;
4995 bool CloseNesting =
true;
4996 bool OrphanSeen =
false;
4999 ShouldBeInParallelRegion,
5000 ShouldBeInOrderedRegion,
5001 ShouldBeInTargetRegion,
5002 ShouldBeInTeamsRegion,
5003 ShouldBeInLoopSimdRegion,
5004 } Recommend = NoRecommend;
5005 if (SemaRef.
LangOpts.OpenMP >= 51 && Stack->isParentOrderConcurrent() &&
5006 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_loop &&
5007 CurrentRegion != OMPD_parallel &&
5009 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_order)
5010 << getOpenMPDirectiveName(CurrentRegion);
5014 ((SemaRef.
LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
5015 (SemaRef.
LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
5016 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
5017 CurrentRegion != OMPD_scan))) {
5030 SemaRef.
Diag(StartLoc, (CurrentRegion != OMPD_simd)
5031 ? diag::err_omp_prohibited_region_simd
5032 : diag::warn_omp_nesting_simd)
5033 << (SemaRef.
LangOpts.OpenMP >= 50 ? 1 : 0);
5034 return CurrentRegion != OMPD_simd;
5036 if (ParentRegion == OMPD_atomic) {
5039 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
5042 if (CurrentRegion == OMPD_section) {
5047 if (ParentRegion != OMPD_sections &&
5048 ParentRegion != OMPD_parallel_sections) {
5049 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_section_directive)
5050 << (ParentRegion != OMPD_unknown)
5051 << getOpenMPDirectiveName(ParentRegion);
5059 if (ParentRegion == OMPD_unknown &&
5061 CurrentRegion != OMPD_cancellation_point &&
5062 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
5064 if (CurrentRegion == OMPD_cancellation_point ||
5065 CurrentRegion == OMPD_cancel) {
5078 !((CancelRegion == OMPD_parallel &&
5079 (ParentRegion == OMPD_parallel ||
5080 ParentRegion == OMPD_target_parallel)) ||
5081 (CancelRegion == OMPD_for &&
5082 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
5083 ParentRegion == OMPD_target_parallel_for ||
5084 ParentRegion == OMPD_distribute_parallel_for ||
5085 ParentRegion == OMPD_teams_distribute_parallel_for ||
5086 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
5087 (CancelRegion == OMPD_taskgroup &&
5088 (ParentRegion == OMPD_task ||
5090 (ParentRegion == OMPD_taskloop ||
5091 ParentRegion == OMPD_master_taskloop ||
5092 ParentRegion == OMPD_masked_taskloop ||
5093 ParentRegion == OMPD_parallel_masked_taskloop ||
5094 ParentRegion == OMPD_parallel_master_taskloop)))) ||
5095 (CancelRegion == OMPD_sections &&
5096 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
5097 ParentRegion == OMPD_parallel_sections)));
5098 OrphanSeen = ParentRegion == OMPD_unknown;
5099 }
else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
5106 }
else if (CurrentRegion == OMPD_critical && CurrentName.
getName()) {
5112 bool DeadLock = Stack->hasDirective(
5116 if (K == OMPD_critical && DNI.
getName() == CurrentName.
getName()) {
5117 PreviousCriticalLoc = Loc;
5124 SemaRef.
Diag(StartLoc,
5125 diag::err_omp_prohibited_region_critical_same_name)
5127 if (PreviousCriticalLoc.
isValid())
5128 SemaRef.
Diag(PreviousCriticalLoc,
5129 diag::note_omp_previous_critical_region);
5132 }
else if (CurrentRegion == OMPD_barrier) {
5140 ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5141 ParentRegion == OMPD_parallel_master ||
5142 ParentRegion == OMPD_parallel_masked ||
5143 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5155 ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5156 ParentRegion == OMPD_parallel_master ||
5157 ParentRegion == OMPD_parallel_masked ||
5158 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5159 Recommend = ShouldBeInParallelRegion;
5160 }
else if (CurrentRegion == OMPD_ordered) {
5169 NestingProhibited = ParentRegion == OMPD_critical ||
5172 Stack->isParentOrderedRegion());
5173 Recommend = ShouldBeInOrderedRegion;
5179 (SemaRef.
LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
5180 (SemaRef.
LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
5181 ParentRegion != OMPD_target);
5182 OrphanSeen = ParentRegion == OMPD_unknown;
5183 Recommend = ShouldBeInTargetRegion;
5184 }
else if (CurrentRegion == OMPD_scan) {
5190 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
5191 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
5192 ParentRegion != OMPD_parallel_for_simd);
5193 OrphanSeen = ParentRegion == OMPD_unknown;
5194 Recommend = ShouldBeInLoopSimdRegion;
5196 if (!NestingProhibited &&
5199 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
5211 CurrentRegion != OMPD_loop &&
5213 CurrentRegion == OMPD_atomic);
5214 Recommend = ShouldBeInParallelRegion;
5216 if (!NestingProhibited && CurrentRegion == OMPD_loop) {
5221 NestingProhibited = BindKind == OMPC_BIND_teams &&
5222 ParentRegion != OMPD_teams &&
5223 ParentRegion != OMPD_target_teams;
5224 Recommend = ShouldBeInTeamsRegion;
5226 if (!NestingProhibited &&
5232 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
5233 Recommend = ShouldBeInTeamsRegion;
5235 if (!NestingProhibited &&
5242 NestingProhibited = Stack->hasDirective(
5246 OffendingRegion = K;
5252 CloseNesting =
false;
5254 if (NestingProhibited) {
5256 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_device_directive)
5257 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
5259 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region)
5260 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
5261 << Recommend << getOpenMPDirectiveName(CurrentRegion);