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"
44 using namespace clang;
45 using namespace llvm::omp;
58 enum DefaultDataSharingAttributes {
63 DSA_firstprivate = 1 << 3,
73 unsigned Modifier = 0;
74 const Expr *RefExpr =
nullptr;
77 bool AppliedToPointee =
false;
78 DSAVarData() =
default;
82 bool AppliedToPointee)
83 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
84 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
85 AppliedToPointee(AppliedToPointee) {}
87 using OperatorOffsetTy =
89 using DoacrossDependMapTy =
90 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
92 enum class UsesAllocatorsDeclKind {
104 unsigned Modifier = 0;
107 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
111 bool AppliedToPointee =
false;
113 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
114 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
115 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
116 using LoopControlVariablesMapTy =
117 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
120 struct MappedExprComponentTy {
124 using MappedExprComponentsTy =
125 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
126 using CriticalsWithHintsTy =
127 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
128 struct ReductionData {
129 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
131 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
132 ReductionData() =
default;
139 ReductionOp = RefExpr;
142 using DeclReductionMapTy =
143 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
144 struct DefaultmapInfo {
148 DefaultmapInfo() =
default;
150 : ImplicitBehavior(M), SLoc(Loc) {}
153 struct SharingMapTy {
154 DeclSAMapTy SharingMap;
155 DeclReductionMapTy ReductionMap;
156 UsedRefMapTy AlignedMap;
157 UsedRefMapTy NontemporalMap;
158 MappedExprComponentsTy MappedExprComponents;
159 LoopControlVariablesMapTy LCVMap;
160 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
165 Scope *CurScope =
nullptr;
171 DoacrossDependMapTy DoacrossDepends;
176 unsigned AssociatedLoops = 1;
177 bool HasMutipleLoops =
false;
178 const Decl *PossiblyLoopCounter =
nullptr;
179 bool NowaitRegion =
false;
180 bool UntiedRegion =
false;
181 bool CancelRegion =
false;
182 bool LoopStart =
false;
183 bool BodyComplete =
false;
188 Expr *TaskgroupReductionRef =
nullptr;
197 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
199 Expr *DeclareMapperVar =
nullptr;
202 :
Directive(DKind), DirectiveName(Name), CurScope(CurScope),
204 SharingMapTy() =
default;
210 DeclSAMapTy Threadprivates;
217 bool ForceCapturing =
false;
220 bool ForceCaptureByReferenceInTargetExecutable =
false;
221 CriticalsWithHintsTy Criticals;
222 unsigned IgnoredStackElements = 0;
226 using const_iterator = StackTy::const_reverse_iterator;
227 const_iterator begin()
const {
228 return Stack.empty() ? const_iterator()
229 : Stack.back().first.rbegin() + IgnoredStackElements;
231 const_iterator end()
const {
232 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
234 using iterator = StackTy::reverse_iterator;
236 return Stack.empty() ? iterator()
237 : Stack.back().first.rbegin() + IgnoredStackElements;
240 return Stack.empty() ? iterator() : Stack.back().first.rend();
245 bool isStackEmpty()
const {
246 return Stack.empty() ||
247 Stack.back().second != CurrentNonCapturingFunctionScope ||
248 Stack.back().first.size() <= IgnoredStackElements;
250 size_t getStackSize()
const {
251 return isStackEmpty() ? 0
252 : Stack.back().first.size() - IgnoredStackElements;
255 SharingMapTy *getTopOfStackOrNull() {
256 size_t Size = getStackSize();
259 return &Stack.back().first[
Size - 1];
261 const SharingMapTy *getTopOfStackOrNull()
const {
262 return const_cast<DSAStackTy &
>(*this).getTopOfStackOrNull();
264 SharingMapTy &getTopOfStack() {
265 assert(!isStackEmpty() &&
"no current directive");
266 return *getTopOfStackOrNull();
268 const SharingMapTy &getTopOfStack()
const {
269 return const_cast<DSAStackTy &
>(*this).getTopOfStack();
272 SharingMapTy *getSecondOnStackOrNull() {
273 size_t Size = getStackSize();
276 return &Stack.back().first[
Size - 2];
278 const SharingMapTy *getSecondOnStackOrNull()
const {
279 return const_cast<DSAStackTy &
>(*this).getSecondOnStackOrNull();
288 SharingMapTy &getStackElemAtLevel(
unsigned Level) {
289 assert(
Level < getStackSize() &&
"no such stack element");
290 return Stack.back().first[
Level];
292 const SharingMapTy &getStackElemAtLevel(
unsigned Level)
const {
293 return const_cast<DSAStackTy &
>(*this).getStackElemAtLevel(
Level);
296 DSAVarData getDSA(const_iterator &Iter,
ValueDecl *D)
const;
299 bool isOpenMPLocal(
VarDecl *D, const_iterator Iter)
const;
312 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
321 explicit DSAStackTy(
Sema &S) : SemaRef(S) {}
324 void setOMPAllocatorHandleT(
QualType Ty) { OMPAllocatorHandleT = Ty; }
326 QualType getOMPAllocatorHandleT()
const {
return OMPAllocatorHandleT; }
328 void setOMPAlloctraitT(
QualType Ty) { OMPAlloctraitT = Ty; }
330 QualType getOMPAlloctraitT()
const {
return OMPAlloctraitT; }
332 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
334 OMPPredefinedAllocators[AllocatorKind] = Allocator;
337 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind)
const {
338 return OMPPredefinedAllocators[AllocatorKind];
341 void setOMPDependT(
QualType Ty) { OMPDependT = Ty; }
343 QualType getOMPDependT()
const {
return OMPDependT; }
346 void setOMPEventHandleT(
QualType Ty) { OMPEventHandleT = Ty; }
348 QualType getOMPEventHandleT()
const {
return OMPEventHandleT; }
350 bool isClauseParsingMode()
const {
return ClauseKindMode != OMPC_unknown; }
352 assert(isClauseParsingMode() &&
"Must be in clause parsing mode.");
353 return ClauseKindMode;
357 bool isBodyComplete()
const {
358 const SharingMapTy *Top = getTopOfStackOrNull();
359 return Top && Top->BodyComplete;
361 void setBodyComplete() { getTopOfStack().BodyComplete =
true; }
363 bool isForceVarCapturing()
const {
return ForceCapturing; }
364 void setForceVarCapturing(
bool V) { ForceCapturing =
V; }
366 void setForceCaptureByReferenceInTargetExecutable(
bool V) {
367 ForceCaptureByReferenceInTargetExecutable =
V;
369 bool isForceCaptureByReferenceInTargetExecutable()
const {
370 return ForceCaptureByReferenceInTargetExecutable;
375 assert(!IgnoredStackElements &&
376 "cannot change stack while ignoring elements");
378 Stack.back().second != CurrentNonCapturingFunctionScope)
379 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
380 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
381 Stack.back().first.back().DefaultAttrLoc = Loc;
385 assert(!IgnoredStackElements &&
386 "cannot change stack while ignoring elements");
387 assert(!Stack.back().first.empty() &&
388 "Data-sharing attributes stack is empty!");
389 Stack.back().first.pop_back();
394 class ParentDirectiveScope {
399 ParentDirectiveScope(DSAStackTy &Self,
bool Activate)
400 : Self(Self), Active(
false) {
404 ~ParentDirectiveScope() { disable(); }
407 --Self.IgnoredStackElements;
413 ++Self.IgnoredStackElements;
422 "Expected loop-based directive.");
423 getTopOfStack().LoopStart =
true;
428 "Expected loop-based directive.");
429 getTopOfStack().LoopStart =
false;
432 bool isLoopStarted()
const {
434 "Expected loop-based directive.");
435 return !getTopOfStack().LoopStart;
438 void resetPossibleLoopCounter(
const Decl *D =
nullptr) {
439 getTopOfStack().PossiblyLoopCounter = D ? D->getCanonicalDecl() : D;
442 const Decl *getPossiblyLoopCunter()
const {
443 return getTopOfStack().PossiblyLoopCounter;
446 void pushFunction() {
447 assert(!IgnoredStackElements &&
448 "cannot change stack while ignoring elements");
450 assert(!isa<CapturingScopeInfo>(CurFnScope));
451 CurrentNonCapturingFunctionScope = CurFnScope;
455 assert(!IgnoredStackElements &&
456 "cannot change stack while ignoring elements");
457 if (!Stack.empty() && Stack.back().second == OldFSI) {
458 assert(Stack.back().first.empty());
461 CurrentNonCapturingFunctionScope =
nullptr;
463 if (!isa<CapturingScopeInfo>(FSI)) {
464 CurrentNonCapturingFunctionScope = FSI;
473 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
475 auto I = Criticals.find(Name.getAsString());
476 if (I != Criticals.end())
495 const LCDeclInfo isLoopControlVariable(
const ValueDecl *D)
const;
500 const LCDeclInfo isParentLoopControlVariable(
const ValueDecl *D)
const;
505 const LCDeclInfo isLoopControlVariable(
const ValueDecl *D,
506 unsigned Level)
const;
509 const ValueDecl *getParentLoopControlVariable(
unsigned I)
const;
512 void markDeclAsUsedInScanDirective(
ValueDecl *D) {
513 if (SharingMapTy *Stack = getSecondOnStackOrNull())
514 Stack->UsedInScanDirective.insert(D);
518 bool isUsedInScanDirective(
ValueDecl *D)
const {
519 if (
const SharingMapTy *Stack = getTopOfStackOrNull())
520 return Stack->UsedInScanDirective.contains(D);
526 DeclRefExpr *PrivateCopy =
nullptr,
unsigned Modifier = 0,
527 bool AppliedToPointee =
false);
536 const Expr *ReductionRef);
542 Expr *&TaskgroupDescriptor)
const;
547 const Expr *&ReductionRef,
548 Expr *&TaskgroupDescriptor)
const;
551 Expr *getTaskgroupReductionRef()
const {
552 assert((getTopOfStack().
Directive == OMPD_taskgroup ||
556 "taskgroup reference expression requested for non taskgroup or "
557 "parallel/worksharing directive.");
558 return getTopOfStack().TaskgroupReductionRef;
562 bool isTaskgroupReductionRef(
const ValueDecl *VD,
unsigned Level)
const {
563 return getStackElemAtLevel(
Level).TaskgroupReductionRef &&
564 cast<DeclRefExpr>(getStackElemAtLevel(
Level).TaskgroupReductionRef)
570 const DSAVarData getTopDSA(
ValueDecl *D,
bool FromParent);
572 const DSAVarData getImplicitDSA(
ValueDecl *D,
bool FromParent)
const;
574 const DSAVarData getImplicitDSA(
ValueDecl *D,
unsigned Level)
const;
582 bool FromParent)
const;
590 bool FromParent)
const;
597 unsigned Level,
bool NotLastprivate =
false)
const;
601 bool hasExplicitDirective(
603 unsigned Level)
const;
607 const llvm::function_ref<
bool(
610 bool FromParent)
const;
614 const SharingMapTy *Top = getTopOfStackOrNull();
615 return Top ? Top->Directive : OMPD_unknown;
619 assert(!isStackEmpty() &&
"No directive at specified level.");
620 return getStackElemAtLevel(
Level).Directive;
624 unsigned OpenMPCaptureLevel)
const {
627 return CaptureRegions[OpenMPCaptureLevel];
631 const SharingMapTy *
Parent = getSecondOnStackOrNull();
636 void addRequiresDecl(
OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); }
639 template <
typename ClauseType>
bool hasRequiresDeclWithClause()
const {
642 return isa<ClauseType>(C);
650 bool IsDuplicate =
false;
653 for (
const OMPClause *CPrev : D->clauselists()) {
654 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
655 SemaRef.
Diag(CNew->getBeginLoc(),
656 diag::err_omp_requires_clause_redeclaration)
657 << getOpenMPClauseName(CNew->getClauseKind());
658 SemaRef.
Diag(CPrev->getBeginLoc(),
659 diag::note_omp_requires_previous_clause)
660 << getOpenMPClauseName(CPrev->getClauseKind());
671 TargetLocations.push_back(LocStart);
677 AtomicLocation = Loc;
682 SourceLocation getAtomicDirectiveLoc()
const {
return AtomicLocation; }
686 return TargetLocations;
691 getTopOfStack().DefaultAttr = DSA_none;
692 getTopOfStack().DefaultAttrLoc = Loc;
696 getTopOfStack().DefaultAttr = DSA_shared;
697 getTopOfStack().DefaultAttrLoc = Loc;
701 getTopOfStack().DefaultAttr = DSA_private;
702 getTopOfStack().DefaultAttrLoc = Loc;
706 getTopOfStack().DefaultAttr = DSA_firstprivate;
707 getTopOfStack().DefaultAttrLoc = Loc;
712 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[
Kind];
713 DMI.ImplicitBehavior = M;
719 return getTopOfStack()
720 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
723 .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
726 .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
728 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
733 return ConstructTraits;
738 ConstructTraits.append(Traits.begin(), Traits.end());
740 for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits)) {
741 llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val();
742 assert(Top == Trait &&
"Something left a trait on the stack!");
748 DefaultDataSharingAttributes getDefaultDSA(
unsigned Level)
const {
749 return getStackSize() <=
Level ? DSA_unspecified
750 : getStackElemAtLevel(
Level).DefaultAttr;
752 DefaultDataSharingAttributes getDefaultDSA()
const {
753 return isStackEmpty() ? DSA_unspecified : getTopOfStack().DefaultAttr;
756 return isStackEmpty() ?
SourceLocation() : getTopOfStack().DefaultAttrLoc;
760 return isStackEmpty()
762 : getTopOfStack().DefaultmapMap[
Kind].ImplicitBehavior;
765 getDefaultmapModifierAtLevel(
unsigned Level,
767 return getStackElemAtLevel(
Level).DefaultmapMap[
Kind].ImplicitBehavior;
769 bool isDefaultmapCapturedByRef(
unsigned Level,
772 getDefaultmapModifierAtLevel(
Level,
Kind);
773 if (
Kind == OMPC_DEFAULTMAP_scalar ||
Kind == OMPC_DEFAULTMAP_pointer) {
774 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
775 (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
776 (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
777 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
784 case OMPC_DEFAULTMAP_scalar:
785 case OMPC_DEFAULTMAP_pointer:
787 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
788 (M == OMPC_DEFAULTMAP_MODIFIER_default);
789 case OMPC_DEFAULTMAP_aggregate:
790 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
794 llvm_unreachable(
"Unexpected OpenMPDefaultmapClauseKind enum");
796 bool mustBeFirstprivateAtLevel(
unsigned Level,
799 getDefaultmapModifierAtLevel(
Level,
Kind);
800 return mustBeFirstprivateBase(M,
Kind);
804 return mustBeFirstprivateBase(M,
Kind);
808 bool isThreadPrivate(
VarDecl *D) {
809 const DSAVarData DVar = getTopDSA(D,
false);
814 void setOrderedRegion(
bool IsOrdered,
const Expr *Param,
817 getTopOfStack().OrderedRegion.emplace(Param, Clause);
819 getTopOfStack().OrderedRegion.reset();
823 bool isOrderedRegion()
const {
824 if (
const SharingMapTy *Top = getTopOfStackOrNull())
825 return Top->OrderedRegion.hasValue();
829 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam()
const {
830 if (
const SharingMapTy *Top = getTopOfStackOrNull())
831 if (Top->OrderedRegion.hasValue())
832 return Top->OrderedRegion.getValue();
833 return std::make_pair(
nullptr,
nullptr);
837 bool isParentOrderedRegion()
const {
838 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
839 return Parent->OrderedRegion.hasValue();
843 std::pair<const Expr *, OMPOrderedClause *>
844 getParentOrderedRegionParam()
const {
845 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
846 if (
Parent->OrderedRegion.hasValue())
847 return Parent->OrderedRegion.getValue();
848 return std::make_pair(
nullptr,
nullptr);
851 void setNowaitRegion(
bool IsNowait =
true) {
852 getTopOfStack().NowaitRegion = IsNowait;
856 bool isParentNowaitRegion()
const {
857 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
858 return Parent->NowaitRegion;
862 void setUntiedRegion(
bool IsUntied =
true) {
863 getTopOfStack().UntiedRegion = IsUntied;
866 bool isUntiedRegion()
const {
867 const SharingMapTy *Top = getTopOfStackOrNull();
868 return Top ? Top->UntiedRegion :
false;
871 void setParentCancelRegion(
bool Cancel =
true) {
872 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
873 Parent->CancelRegion |= Cancel;
876 bool isCancelRegion()
const {
877 const SharingMapTy *Top = getTopOfStackOrNull();
878 return Top ? Top->CancelRegion :
false;
883 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
884 Parent->PrevScanLocation = Loc;
887 bool doesParentHasScanDirective()
const {
888 const SharingMapTy *Top = getSecondOnStackOrNull();
889 return Top ? Top->PrevScanLocation.isValid() :
false;
893 const SharingMapTy *Top = getSecondOnStackOrNull();
898 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
899 Parent->PrevOrderedLocation = Loc;
902 bool doesParentHasOrderedDirective()
const {
903 const SharingMapTy *Top = getSecondOnStackOrNull();
904 return Top ? Top->PrevOrderedLocation.isValid() :
false;
908 const SharingMapTy *Top = getSecondOnStackOrNull();
913 void setAssociatedLoops(
unsigned Val) {
914 getTopOfStack().AssociatedLoops = Val;
916 getTopOfStack().HasMutipleLoops =
true;
919 unsigned getAssociatedLoops()
const {
920 const SharingMapTy *Top = getTopOfStackOrNull();
921 return Top ? Top->AssociatedLoops : 0;
924 bool hasMutipleLoops()
const {
925 const SharingMapTy *Top = getTopOfStackOrNull();
926 return Top ? Top->HasMutipleLoops :
false;
932 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
933 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
936 bool hasInnerTeamsRegion()
const {
937 return getInnerTeamsRegionLoc().
isValid();
941 const SharingMapTy *Top = getTopOfStackOrNull();
945 Scope *getCurScope()
const {
946 const SharingMapTy *Top = getTopOfStackOrNull();
947 return Top ? Top->CurScope :
nullptr;
949 void setContext(
DeclContext *DC) { getTopOfStack().Context = DC; }
951 const SharingMapTy *Top = getTopOfStackOrNull();
957 bool checkMappableExprComponentListsForDecl(
958 const ValueDecl *VD,
bool CurrentRegionOnly,
959 const llvm::function_ref<
971 if (CurrentRegionOnly)
976 for (; SI != SE; ++SI) {
977 auto MI = SI->MappedExprComponents.find(VD);
978 if (MI != SI->MappedExprComponents.end())
980 MI->second.Components)
981 if (Check(L, MI->second.Kind))
989 bool checkMappableExprComponentListsForDeclAtLevel(
991 const llvm::function_ref<
995 if (getStackSize() <=
Level)
998 const SharingMapTy &StackElem = getStackElemAtLevel(
Level);
999 auto MI = StackElem.MappedExprComponents.find(VD);
1000 if (MI != StackElem.MappedExprComponents.end())
1002 MI->second.Components)
1003 if (Check(L, MI->second.Kind))
1010 void addMappableExpressionComponents(
1014 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
1016 MEC.Components.resize(MEC.Components.size() + 1);
1017 MEC.Components.back().append(Components.begin(), Components.end());
1018 MEC.Kind = WhereFoundClauseKind;
1021 unsigned getNestingLevel()
const {
1022 assert(!isStackEmpty());
1023 return getStackSize() - 1;
1026 const OperatorOffsetTy &OpsOffs) {
1027 SharingMapTy *
Parent = getSecondOnStackOrNull();
1029 Parent->DoacrossDepends.try_emplace(C, OpsOffs);
1031 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
1032 getDoacrossDependClauses()
const {
1033 const SharingMapTy &StackElem = getTopOfStack();
1035 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
1036 return llvm::make_range(Ref.begin(), Ref.end());
1038 return llvm::make_range(StackElem.DoacrossDepends.end(),
1039 StackElem.DoacrossDepends.end());
1043 void addMappedClassesQualTypes(
QualType QT) {
1044 SharingMapTy &StackElem = getTopOfStack();
1045 StackElem.MappedClassesQualTypes.insert(QT);
1049 bool isClassPreviouslyMapped(
QualType QT)
const {
1050 const SharingMapTy &StackElem = getTopOfStack();
1051 return StackElem.MappedClassesQualTypes.contains(QT);
1055 void addToParentTargetRegionLinkGlobals(
DeclRefExpr *E) {
1056 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1057 E->
getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1058 "Expected declare target link global.");
1059 for (
auto &Elem : *
this) {
1061 Elem.DeclareTargetLinkVarDecls.push_back(E);
1071 "Expected target executable directive.");
1072 return getTopOfStack().DeclareTargetLinkVarDecls;
1076 void addInnerAllocatorExpr(
Expr *E) {
1077 getTopOfStack().InnerUsedAllocators.push_back(E);
1081 return getTopOfStack().InnerUsedAllocators;
1085 void addImplicitTaskFirstprivate(
unsigned Level,
Decl *D) {
1086 getStackElemAtLevel(
Level).ImplicitTaskFirstprivates.insert(D);
1089 bool isImplicitTaskFirstprivate(
Decl *D)
const {
1090 return getTopOfStack().ImplicitTaskFirstprivates.contains(D);
1094 void addUsesAllocatorsDecl(
const Decl *D, UsesAllocatorsDeclKind
Kind) {
1095 getTopOfStack().UsesAllocatorsDecls.try_emplace(D,
Kind);
1100 const Decl *D)
const {
1101 const SharingMapTy &StackElem = getTopOfStack();
1102 auto I = StackElem.UsesAllocatorsDecls.find(D);
1103 if (I == StackElem.UsesAllocatorsDecls.end())
1105 return I->getSecond();
1108 const SharingMapTy &StackElem = getTopOfStack();
1109 auto I = StackElem.UsesAllocatorsDecls.find(D);
1110 if (I == StackElem.UsesAllocatorsDecls.end())
1112 return I->getSecond();
1115 void addDeclareMapperVarRef(
Expr *Ref) {
1116 SharingMapTy &StackElem = getTopOfStack();
1117 StackElem.DeclareMapperVar = Ref;
1119 const Expr *getDeclareMapperVarRef()
const {
1120 const SharingMapTy *Top = getTopOfStackOrNull();
1121 return Top ? Top->DeclareMapperVar :
nullptr;
1131 DKind == OMPD_unknown;
1137 if (
const auto *FE = dyn_cast<FullExpr>(E))
1138 E = FE->getSubExpr();
1140 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1141 E = MTE->getSubExpr();
1143 while (
const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1144 E = Binder->getSubExpr();
1146 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1147 E = ICE->getSubExprAsWritten();
1156 if (
const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1157 if (
const auto *ME = dyn_cast<MemberExpr>(
getExprAsWritten(CED->getInit())))
1158 D = ME->getMemberDecl();
1159 const auto *VD = dyn_cast<VarDecl>(D);
1160 const auto *FD = dyn_cast<FieldDecl>(D);
1161 if (VD !=
nullptr) {
1166 FD = FD->getCanonicalDecl();
1177 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1180 auto *VD = dyn_cast<VarDecl>(D);
1181 const auto *FD = dyn_cast<FieldDecl>(D);
1183 if (Iter == end()) {
1189 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1190 DVar.CKind = OMPC_shared;
1196 if (VD && VD->hasGlobalStorage())
1197 DVar.CKind = OMPC_shared;
1201 DVar.CKind = OMPC_shared;
1210 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1211 (VD->getStorageClass() ==
SC_Auto || VD->getStorageClass() ==
SC_None)) {
1212 DVar.CKind = OMPC_private;
1216 DVar.DKind = Iter->Directive;
1219 if (Iter->SharingMap.count(D)) {
1220 const DSAInfo &Data = Iter->SharingMap.lookup(D);
1221 DVar.RefExpr = Data.RefExpr.getPointer();
1222 DVar.PrivateCopy = Data.PrivateCopy;
1223 DVar.CKind = Data.Attributes;
1224 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1225 DVar.Modifier = Data.Modifier;
1226 DVar.AppliedToPointee = Data.AppliedToPointee;
1234 switch (Iter->DefaultAttr) {
1236 DVar.CKind = OMPC_shared;
1237 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1241 case DSA_firstprivate:
1242 if (VD && VD->getStorageDuration() ==
SD_Static &&
1244 DVar.CKind = OMPC_unknown;
1246 DVar.CKind = OMPC_firstprivate;
1248 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1254 if (VD && VD->getStorageDuration() ==
SD_Static &&
1256 DVar.CKind = OMPC_unknown;
1258 DVar.CKind = OMPC_private;
1260 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1262 case DSA_unspecified:
1267 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1271 DVar.CKind = OMPC_shared;
1281 DSAVarData DVarTemp;
1282 const_iterator I = Iter, E = end();
1290 DVarTemp = getDSA(I, D);
1291 if (DVarTemp.CKind != OMPC_shared) {
1292 DVar.RefExpr =
nullptr;
1293 DVar.CKind = OMPC_firstprivate;
1296 }
while (I != E && !isImplicitTaskingRegion(I->Directive));
1298 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1307 return getDSA(++Iter, D);
1310 const Expr *DSAStackTy::addUniqueAligned(
const ValueDecl *D,
1311 const Expr *NewDE) {
1312 assert(!isStackEmpty() &&
"Data sharing attributes stack is empty");
1314 SharingMapTy &StackElem = getTopOfStack();
1315 auto It = StackElem.AlignedMap.find(D);
1316 if (It == StackElem.AlignedMap.end()) {
1317 assert(NewDE &&
"Unexpected nullptr expr to be added into aligned map");
1318 StackElem.AlignedMap[D] = NewDE;
1321 assert(It->second &&
"Unexpected nullptr expr in the aligned map");
1325 const Expr *DSAStackTy::addUniqueNontemporal(
const ValueDecl *D,
1326 const Expr *NewDE) {
1327 assert(!isStackEmpty() &&
"Data sharing attributes stack is empty");
1329 SharingMapTy &StackElem = getTopOfStack();
1330 auto It = StackElem.NontemporalMap.find(D);
1331 if (It == StackElem.NontemporalMap.end()) {
1332 assert(NewDE &&
"Unexpected nullptr expr to be added into aligned map");
1333 StackElem.NontemporalMap[D] = NewDE;
1336 assert(It->second &&
"Unexpected nullptr expr in the aligned map");
1341 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1343 SharingMapTy &StackElem = getTopOfStack();
1344 StackElem.LCVMap.try_emplace(
1345 D, LCDeclInfo(StackElem.LCVMap.size() + 1,
Capture));
1348 const DSAStackTy::LCDeclInfo
1349 DSAStackTy::isLoopControlVariable(
const ValueDecl *D)
const {
1350 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1352 const SharingMapTy &StackElem = getTopOfStack();
1353 auto It = StackElem.LCVMap.find(D);
1354 if (It != StackElem.LCVMap.end())
1356 return {0,
nullptr};
1359 const DSAStackTy::LCDeclInfo
1360 DSAStackTy::isLoopControlVariable(
const ValueDecl *D,
unsigned Level)
const {
1361 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1363 for (
unsigned I =
Level + 1; I > 0; --I) {
1364 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1365 auto It = StackElem.LCVMap.find(D);
1366 if (It != StackElem.LCVMap.end())
1369 return {0,
nullptr};
1372 const DSAStackTy::LCDeclInfo
1373 DSAStackTy::isParentLoopControlVariable(
const ValueDecl *D)
const {
1374 const SharingMapTy *
Parent = getSecondOnStackOrNull();
1375 assert(
Parent &&
"Data-sharing attributes stack is empty");
1377 auto It =
Parent->LCVMap.find(D);
1378 if (It !=
Parent->LCVMap.end())
1380 return {0,
nullptr};
1383 const ValueDecl *DSAStackTy::getParentLoopControlVariable(
unsigned I)
const {
1384 const SharingMapTy *
Parent = getSecondOnStackOrNull();
1385 assert(
Parent &&
"Data-sharing attributes stack is empty");
1386 if (
Parent->LCVMap.size() < I)
1388 for (
const auto &Pair :
Parent->LCVMap)
1389 if (Pair.second.first == I)
1396 bool AppliedToPointee) {
1398 if (A == OMPC_threadprivate) {
1399 DSAInfo &Data = Threadprivates[D];
1400 Data.Attributes = A;
1401 Data.RefExpr.setPointer(E);
1402 Data.PrivateCopy =
nullptr;
1403 Data.Modifier = Modifier;
1405 DSAInfo &Data = getTopOfStack().SharingMap[D];
1406 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
1407 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1408 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1409 (isLoopControlVariable(D).first && A == OMPC_private));
1410 Data.Modifier = Modifier;
1411 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1412 Data.RefExpr.setInt(
true);
1415 const bool IsLastprivate =
1416 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1417 Data.Attributes = A;
1418 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1419 Data.PrivateCopy = PrivateCopy;
1420 Data.AppliedToPointee = AppliedToPointee;
1422 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->
getDecl()];
1423 Data.Modifier = Modifier;
1424 Data.Attributes = A;
1425 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1426 Data.PrivateCopy =
nullptr;
1427 Data.AppliedToPointee = AppliedToPointee;
1434 StringRef Name,
const AttrVec *Attrs =
nullptr,
1449 OMPReferencedVarAttr::CreateImplicit(SemaRef.
Context, OrigRef));
1456 bool RefersToCapture =
false) {
1467 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1469 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1470 "Additional reduction info may be specified only for reduction items.");
1471 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1472 assert(ReductionData.ReductionRange.isInvalid() &&
1473 (getTopOfStack().
Directive == OMPD_taskgroup ||
1477 "Additional reduction info may be specified only once for reduction "
1479 ReductionData.set(BOK, SR);
1480 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1481 if (!TaskgroupReductionRef) {
1484 TaskgroupReductionRef =
1490 const Expr *ReductionRef) {
1492 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1494 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1495 "Additional reduction info may be specified only for reduction items.");
1496 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1497 assert(ReductionData.ReductionRange.isInvalid() &&
1498 (getTopOfStack().
Directive == OMPD_taskgroup ||
1502 "Additional reduction info may be specified only once for reduction "
1504 ReductionData.set(ReductionRef, SR);
1505 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1506 if (!TaskgroupReductionRef) {
1509 TaskgroupReductionRef =
1514 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1516 Expr *&TaskgroupDescriptor)
const {
1518 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty.");
1519 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1520 const DSAInfo &Data = I->SharingMap.lookup(D);
1521 if (Data.Attributes != OMPC_reduction ||
1522 Data.Modifier != OMPC_REDUCTION_task)
1524 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1525 if (!ReductionData.ReductionOp ||
1526 ReductionData.ReductionOp.is<
const Expr *>())
1527 return DSAVarData();
1528 SR = ReductionData.ReductionRange;
1529 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1530 assert(I->TaskgroupReductionRef &&
"taskgroup reduction reference "
1531 "expression for the descriptor is not "
1533 TaskgroupDescriptor = I->TaskgroupReductionRef;
1534 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1535 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1538 return DSAVarData();
1541 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1543 Expr *&TaskgroupDescriptor)
const {
1545 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty.");
1546 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1547 const DSAInfo &Data = I->SharingMap.lookup(D);
1548 if (Data.Attributes != OMPC_reduction ||
1549 Data.Modifier != OMPC_REDUCTION_task)
1551 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1552 if (!ReductionData.ReductionOp ||
1553 !ReductionData.ReductionOp.is<
const Expr *>())
1554 return DSAVarData();
1555 SR = ReductionData.ReductionRange;
1556 ReductionRef = ReductionData.ReductionOp.get<
const Expr *>();
1557 assert(I->TaskgroupReductionRef &&
"taskgroup reduction reference "
1558 "expression for the descriptor is not "
1560 TaskgroupDescriptor = I->TaskgroupReductionRef;
1561 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1562 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1565 return DSAVarData();
1568 bool DSAStackTy::isOpenMPLocal(
VarDecl *D, const_iterator I)
const {
1570 for (const_iterator E = end(); I != E; ++I) {
1571 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1575 Scope *CurScope = getCurScope();
1576 while (CurScope && CurScope != TopScope && !CurScope->
isDeclScope(D))
1578 return CurScope != TopScope;
1581 if (I->Context == DC)
1590 bool AcceptIfMutable =
true,
1591 bool *IsClassType =
nullptr) {
1593 Type =
Type.getNonReferenceType().getCanonicalType();
1594 bool IsConstant =
Type.isConstant(Context);
1599 if (
const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1601 RD = CTD->getTemplatedDecl();
1604 return IsConstant && !(SemaRef.
getLangOpts().CPlusPlus && RD &&
1611 bool AcceptIfMutable =
true,
1612 bool ListItemNotVar =
false) {
1616 unsigned Diag = ListItemNotVar ? diag::err_omp_const_list_item
1617 : IsClassType ? diag::err_omp_const_not_mutable_variable
1618 : diag::err_omp_const_variable;
1619 SemaRef.
Diag(ELoc,
Diag) << getOpenMPClauseName(CKind);
1620 if (!ListItemNotVar && D) {
1621 const VarDecl *VD = dyn_cast<VarDecl>(D);
1625 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1633 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(
ValueDecl *D,
1638 auto *VD = dyn_cast<VarDecl>(D);
1639 auto TI = Threadprivates.find(D);
1640 if (TI != Threadprivates.end()) {
1641 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1642 DVar.CKind = OMPC_threadprivate;
1643 DVar.Modifier = TI->getSecond().Modifier;
1646 if (VD && VD->
hasAttr<OMPThreadPrivateDeclAttr>()) {
1649 VD->
getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1650 DVar.CKind = OMPC_threadprivate;
1651 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1658 !(VD->
hasAttr<OMPThreadPrivateDeclAttr>() &&
1662 VD->
hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1665 DVar.CKind = OMPC_threadprivate;
1666 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1670 VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1671 !isLoopControlVariable(D).first) {
1672 const_iterator IterTarget =
1673 std::find_if(begin(), end(), [](
const SharingMapTy &Data) {
1676 if (IterTarget != end()) {
1677 const_iterator ParentIterTarget = IterTarget + 1;
1678 for (const_iterator Iter = begin(); Iter != ParentIterTarget; ++Iter) {
1679 if (isOpenMPLocal(VD, Iter)) {
1683 DVar.CKind = OMPC_threadprivate;
1687 if (!isClauseParsingMode() || IterTarget != begin()) {
1688 auto DSAIter = IterTarget->SharingMap.find(D);
1689 if (DSAIter != IterTarget->SharingMap.end() &&
1691 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1692 DVar.CKind = OMPC_threadprivate;
1695 const_iterator
End = end();
1701 IterTarget->ConstructLoc);
1702 DVar.CKind = OMPC_threadprivate;
1720 if (VD && VD->isStaticDataMember()) {
1722 const_iterator I = begin();
1723 const_iterator EndI = end();
1724 if (FromParent && I != EndI)
1727 auto It = I->SharingMap.find(D);
1728 if (It != I->SharingMap.end()) {
1729 const DSAInfo &Data = It->getSecond();
1730 DVar.RefExpr = Data.RefExpr.getPointer();
1731 DVar.PrivateCopy = Data.PrivateCopy;
1732 DVar.CKind = Data.Attributes;
1733 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1734 DVar.DKind = I->Directive;
1735 DVar.Modifier = Data.Modifier;
1736 DVar.AppliedToPointee = Data.AppliedToPointee;
1741 DVar.CKind = OMPC_shared;
1748 if (SemaRef.
LangOpts.OpenMP <= 31) {
1756 DSAVarData DVarTemp = hasInnermostDSA(
1759 return C == OMPC_firstprivate ||
C == OMPC_shared;
1761 MatchesAlways, FromParent);
1762 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1765 DVar.CKind = OMPC_shared;
1772 const_iterator I = begin();
1773 const_iterator EndI = end();
1774 if (FromParent && I != EndI)
1778 auto It = I->SharingMap.find(D);
1779 if (It != I->SharingMap.end()) {
1780 const DSAInfo &Data = It->getSecond();
1781 DVar.RefExpr = Data.RefExpr.getPointer();
1782 DVar.PrivateCopy = Data.PrivateCopy;
1783 DVar.CKind = Data.Attributes;
1784 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1785 DVar.DKind = I->Directive;
1786 DVar.Modifier = Data.Modifier;
1787 DVar.AppliedToPointee = Data.AppliedToPointee;
1793 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(
ValueDecl *D,
1794 bool FromParent)
const {
1795 if (isStackEmpty()) {
1797 return getDSA(I, D);
1800 const_iterator StartI = begin();
1801 const_iterator EndI = end();
1802 if (FromParent && StartI != EndI)
1804 return getDSA(StartI, D);
1807 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(
ValueDecl *D,
1808 unsigned Level)
const {
1809 if (getStackSize() <=
Level)
1810 return DSAVarData();
1812 const_iterator StartI = std::next(begin(), getStackSize() - 1 -
Level);
1813 return getDSA(StartI, D);
1816 const DSAStackTy::DSAVarData
1820 bool FromParent)
const {
1824 const_iterator I = begin();
1825 const_iterator EndI = end();
1826 if (FromParent && I != EndI)
1828 for (; I != EndI; ++I) {
1829 if (!DPred(I->Directive) &&
1830 !isImplicitOrExplicitTaskingRegion(I->Directive))
1832 const_iterator NewI = I;
1833 DSAVarData DVar = getDSA(NewI, D);
1834 if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee))
1840 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1843 bool FromParent)
const {
1847 const_iterator StartI = begin();
1848 const_iterator EndI = end();
1849 if (FromParent && StartI != EndI)
1851 if (StartI == EndI || !DPred(StartI->Directive))
1853 const_iterator NewI = StartI;
1854 DSAVarData DVar = getDSA(NewI, D);
1855 return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1860 bool DSAStackTy::hasExplicitDSA(
1863 unsigned Level,
bool NotLastprivate)
const {
1864 if (getStackSize() <=
Level)
1867 const SharingMapTy &StackElem = getStackElemAtLevel(
Level);
1868 auto I = StackElem.SharingMap.find(D);
1869 if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1870 CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1871 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1874 auto LI = StackElem.LCVMap.find(D);
1875 if (LI != StackElem.LCVMap.end())
1876 return CPred(OMPC_private,
false);
1880 bool DSAStackTy::hasExplicitDirective(
1882 unsigned Level)
const {
1883 if (getStackSize() <=
Level)
1885 const SharingMapTy &StackElem = getStackElemAtLevel(
Level);
1886 return DPred(StackElem.Directive);
1889 bool DSAStackTy::hasDirective(
1893 bool FromParent)
const {
1895 size_t Skip = FromParent ? 2 : 1;
1896 for (const_iterator I = begin() +
std::min(Skip, getStackSize()), E = end();
1898 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1904 void Sema::InitDataSharingAttributesStack() {
1905 VarDataSharingAttributesStack =
new DSAStackTy(*
this);
1908 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1910 void Sema::pushOpenMPFunctionRegion() {
DSAStack->pushFunction(); }
1918 "Expected OpenMP device compilation.");
1924 enum class FunctionEmissionStatus {
1934 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1935 "Expected OpenMP device compilation.");
1941 case FunctionEmissionStatus::Emitted:
1942 Kind = SemaDiagnosticBuilder::K_Immediate;
1953 ? SemaDiagnosticBuilder::K_Deferred
1954 : SemaDiagnosticBuilder::K_Immediate;
1956 case FunctionEmissionStatus::TemplateDiscarded:
1957 case FunctionEmissionStatus::OMPDiscarded:
1958 Kind = SemaDiagnosticBuilder::K_Nop;
1960 case FunctionEmissionStatus::CUDADiscarded:
1961 llvm_unreachable(
"CUDADiscarded unexpected in OpenMP device compilation");
1972 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
1973 "Expected OpenMP host compilation.");
1979 case FunctionEmissionStatus::Emitted:
1980 Kind = SemaDiagnosticBuilder::K_Immediate;
1983 Kind = SemaDiagnosticBuilder::K_Deferred;
1985 case FunctionEmissionStatus::TemplateDiscarded:
1986 case FunctionEmissionStatus::OMPDiscarded:
1987 case FunctionEmissionStatus::CUDADiscarded:
1988 Kind = SemaDiagnosticBuilder::K_Nop;
1998 if (LO.OpenMP <= 45) {
2000 return OMPC_DEFAULTMAP_scalar;
2001 return OMPC_DEFAULTMAP_aggregate;
2004 return OMPC_DEFAULTMAP_pointer;
2006 return OMPC_DEFAULTMAP_scalar;
2007 return OMPC_DEFAULTMAP_aggregate;
2011 unsigned OpenMPCaptureLevel)
const {
2012 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
2015 bool IsByRef =
true;
2021 bool IsVariableUsedInMapClause =
false;
2083 bool IsVariableAssociatedWithSection =
false;
2085 DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2087 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection,
2094 if (WhereFoundClauseKind != OMPC_map)
2097 auto EI = MapExprComponents.rbegin();
2098 auto EE = MapExprComponents.rend();
2100 assert(EI != EE &&
"Invalid map expression!");
2102 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2103 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2109 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
2110 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
2111 isa<MemberExpr>(EI->getAssociatedExpression()) ||
2112 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) {
2113 IsVariableAssociatedWithSection =
true;
2122 if (IsVariableUsedInMapClause) {
2125 IsByRef = !(Ty->
isPointerType() && IsVariableAssociatedWithSection);
2130 IsByRef = (
DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2133 DSAStack->isDefaultmapCapturedByRef(
2138 return K == OMPC_reduction && !AppliedToPointee;
2146 ((IsVariableUsedInMapClause &&
2152 return K == OMPC_firstprivate ||
2153 (K == OMPC_reduction && AppliedToPointee);
2159 !(isa<OMPCapturedExprDecl>(D) && !D->
hasAttr<OMPCaptureNoInitAttr>() &&
2160 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2163 !((
DSAStack->getDefaultDSA() == DSA_firstprivate ||
2164 DSAStack->getDefaultDSA() == DSA_private) &&
2185 unsigned Sema::getOpenMPNestingLevel()
const {
2186 assert(getLangOpts().OpenMP);
2187 return DSAStack->getNestingLevel();
2197 !
DSAStack->isClauseParsingMode()) ||
2208 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
2211 auto *VD = dyn_cast<VarDecl>(D);
2213 if (VD && VD->isConstexpr())
2220 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2226 if (VD && !VD->hasLocalStorage() &&
2227 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2228 if (isInOpenMPTargetExecutionDirective()) {
2229 DSAStackTy::DSAVarData DVarTop =
2231 if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr)
2236 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2240 llvm::reverse(FunctionScopes),
2241 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2242 if (!isa<CapturingScopeInfo>(FSI))
2244 if (
auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2250 assert(CSI &&
"Failed to find CapturedRegionScopeInfo");
2257 if (isInOpenMPDeclareTargetContext()) {
2260 if (LangOpts.OpenMP <= 45 &&
2261 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2262 checkDeclIsAllowedInOpenMPTarget(
nullptr, VD);
2267 if (CheckScopeInfo) {
2268 bool OpenMPFound =
false;
2269 for (
unsigned I = StopAt + 1; I > 0; --I) {
2271 if (!isa<CapturingScopeInfo>(FSI))
2273 if (
auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2283 if (
DSAStack->getCurrentDirective() != OMPD_unknown &&
2284 (!
DSAStack->isClauseParsingMode() ||
2285 DSAStack->getParentDirective() != OMPD_unknown)) {
2286 auto &&Info =
DSAStack->isLoopControlVariable(D);
2288 (VD && VD->hasLocalStorage() &&
2289 isImplicitOrExplicitTaskingRegion(
DSAStack->getCurrentDirective())) ||
2290 (VD &&
DSAStack->isForceVarCapturing()))
2291 return VD ? VD : Info.second;
2292 DSAStackTy::DSAVarData DVarTop =
2294 if (DVarTop.CKind != OMPC_unknown &&
isOpenMPPrivate(DVarTop.CKind) &&
2295 (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2296 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2302 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2310 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2311 ((
DSAStack->getDefaultDSA() != DSA_none &&
2312 DSAStack->getDefaultDSA() != DSA_private &&
2313 DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2314 DVarTop.CKind == OMPC_shared))
2316 if (DVarPrivate.CKind != OMPC_unknown ||
2317 (VD && (
DSAStack->getDefaultDSA() == DSA_none ||
2318 DSAStack->getDefaultDSA() == DSA_private ||
2319 DSAStack->getDefaultDSA() == DSA_firstprivate)))
2320 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2325 void Sema::adjustOpenMPTargetScopeIndex(
unsigned &FunctionScopesIndex,
2326 unsigned Level)
const {
2327 FunctionScopesIndex -= getOpenMPCaptureLevels(
DSAStack->getDirective(
Level));
2331 assert(LangOpts.OpenMP &&
"OpenMP must be enabled.");
2337 assert(LangOpts.OpenMP &&
"OpenMP must be enabled.");
2339 DSAStack->resetPossibleLoopCounter();
2345 unsigned CapLevel)
const {
2346 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
2348 bool IsTriviallyCopyable =
2358 (IsTriviallyCopyable ||
2364 return OMPC_firstprivate;
2365 DSAStackTy::DSAVarData DVar =
DSAStack->getImplicitDSA(D,
Level);
2366 if (DVar.CKind != OMPC_shared &&
2367 !
DSAStack->isLoopControlVariable(D,
Level).first && !DVar.RefExpr) {
2369 return OMPC_firstprivate;
2375 DSAStack->resetPossibleLoopCounter(D);
2377 return OMPC_private;
2380 DSAStack->isLoopControlVariable(D).first) &&
2385 return OMPC_private;
2387 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
2393 return OMPC_private;
2399 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2400 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2401 return OMPC_private;
2405 (
DSAStack->isClauseParsingMode() &&
2406 DSAStack->getClauseParsingMode() == OMPC_private) ||
2411 return K == OMPD_taskgroup ||
2412 ((isOpenMPParallelDirective(K) ||
2413 isOpenMPWorksharingDirective(K)) &&
2414 !isOpenMPSimdDirective(K));
2424 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
2427 for (
unsigned I =
DSAStack->getNestingLevel() + 1; I >
Level; --I) {
2428 const unsigned NewLevel = I - 1;
2432 if (isOpenMPPrivate(K) && !AppliedToPointee) {
2440 if (
DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2450 if (
DSAStack->mustBeFirstprivateAtLevel(
2452 OMPC = OMPC_firstprivate;
2456 if (OMPC != OMPC_unknown)
2457 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context,
unsigned(OMPC)));
2461 unsigned CaptureLevel)
const {
2462 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
2467 const auto *VD = dyn_cast<VarDecl>(D);
2468 return VD && !VD->hasLocalStorage() &&
2471 Regions[CaptureLevel] != OMPD_task;
2475 unsigned CaptureLevel)
const {
2476 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
2479 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
2480 if (!VD->hasLocalStorage()) {
2483 DSAStackTy::DSAVarData TopDVar =
2485 unsigned NumLevels =
2490 return (NumLevels == CaptureLevel + 1 &&
2491 (TopDVar.CKind != OMPC_shared ||
2492 DSAStack->getDefaultDSA() == DSA_firstprivate));
2495 DSAStackTy::DSAVarData DVar =
DSAStack->getImplicitDSA(D,
Level);
2496 if (DVar.CKind != OMPC_shared)
2498 }
while (
Level > 0);
2504 void Sema::DestroyDataSharingAttributesStack() {
delete DSAStack; }
2508 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2513 "Not in OpenMP declare variant scope!");
2515 OMPDeclareVariantScopes.pop_back();
2521 assert(
LangOpts.OpenMP &&
"Expected OpenMP compilation mode.");
2526 (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host))
2529 if (!
LangOpts.OpenMPIsDevice && DevTy &&
2530 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2533 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2534 if (
LangOpts.OpenMPIsDevice && DevTy &&
2535 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2537 StringRef HostDevTy =
2539 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2540 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2541 diag::note_omp_marked_device_type_here)
2545 if (!
LangOpts.OpenMPIsDevice && !
LangOpts.OpenMPOffloadMandatory && DevTy &&
2546 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2549 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2550 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2551 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2552 diag::note_omp_marked_device_type_here)
2560 DSAStack->push(DKind, DirName, CurScope, Loc);
2570 DSAStack->setClauseParsingMode(OMPC_unknown);
2574 static std::pair<ValueDecl *, bool>
2576 SourceRange &ERange,
bool AllowArraySection =
false);
2581 bool InscanFound =
false;
2588 if (C->getClauseKind() != OMPC_reduction)
2590 auto *RC = cast<OMPReductionClause>(C);
2591 if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2593 InscanLoc = RC->getModifierLoc();
2596 if (RC->getModifier() == OMPC_REDUCTION_task) {
2606 S.
Diag(RC->getModifierLoc(),
2607 diag::err_omp_reduction_task_not_parallel_or_worksharing);
2613 if (C->getClauseKind() != OMPC_reduction)
2615 auto *RC = cast<OMPReductionClause>(C);
2616 if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2619 : RC->getModifierLoc(),
2620 diag::err_omp_inscan_reduction_expected);
2621 S.
Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2624 for (
Expr *Ref : RC->varlists()) {
2625 assert(Ref &&
"NULL expr in OpenMP nontemporal clause.");
2628 Expr *SimpleRefExpr = Ref;
2635 S.
Diag(Ref->getExprLoc(),
2636 diag::err_omp_reduction_not_inclusive_exclusive)
2637 << Ref->getSourceRange();
2651 const DSAStackTy::DSAVarData &DVar,
2652 bool IsLoopIterVar =
false);
2660 if (
const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2662 if (
auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2664 for (
Expr *DE : Clause->varlists()) {
2665 if (DE->isValueDependent() || DE->isTypeDependent()) {
2666 PrivateCopies.push_back(
nullptr);
2669 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2670 auto *VD = cast<VarDecl>(DRE->getDecl());
2672 const DSAStackTy::DSAVarData DVar =
2674 if (DVar.CKind == OMPC_lastprivate) {
2681 *
this, DE->getExprLoc(),
Type.getUnqualifiedType(),
2685 PrivateCopies.push_back(
nullptr);
2689 *
this, VDPrivate, DE->
getType(), DE->getExprLoc()));
2693 PrivateCopies.push_back(
nullptr);
2696 Clause->setPrivateCopies(PrivateCopies);
2700 if (
auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2702 for (
Expr *RefExpr : Clause->varlists()) {
2703 assert(RefExpr &&
"NULL expr in OpenMP nontemporal clause.");
2706 Expr *SimpleRefExpr = RefExpr;
2710 PrivateRefs.push_back(RefExpr);
2715 const DSAStackTy::DSAVarData DVar =
2717 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2720 Clause->setPrivateRefs(PrivateRefs);
2723 if (
auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2724 for (
unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2730 if (!VD || !isa<VarDecl>(VD))
2732 DSAStackTy::DSAVarData DVar =
2738 Expr *MapExpr =
nullptr;
2740 DSAStack->checkMappableExprComponentListsForDecl(
2746 auto MI = MapExprComponents.rbegin();
2747 auto ME = MapExprComponents.rend();
2749 MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2750 VD->getCanonicalDecl()) {
2751 MapExpr = MI->getAssociatedExpression();
2756 Diag(D.Allocator->getExprLoc(),
2757 diag::err_omp_allocator_used_in_clauses)
2762 Diag(MapExpr->getExprLoc(), diag::note_used_here)
2763 << MapExpr->getSourceRange();
2776 DiscardCleanupsInEvaluationContext();
2777 PopExpressionEvaluationContext();
2781 Expr *NumIterations,
Sema &SemaRef,
2782 Scope *S, DSAStackTy *Stack);
2791 explicit VarDeclFilterCCC(
Sema &S) : SemaRef(S) {}
2794 if (
const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2795 return VD->hasGlobalStorage() &&
2802 std::unique_ptr<CorrectionCandidateCallback>
clone()
override {
2803 return std::make_unique<VarDeclFilterCCC>(*
this);
2812 explicit VarOrFuncDeclFilterCCC(
Sema &S) : SemaRef(S) {}
2815 if (ND && ((isa<VarDecl>(ND) && ND->
getKind() == Decl::Var) ||
2816 isa<FunctionDecl>(ND))) {
2823 std::unique_ptr<CorrectionCandidateCallback>
clone()
override {
2824 return std::make_unique<VarOrFuncDeclFilterCCC>(*
this);
2842 VarDeclFilterCCC CCC(*
this);
2848 ? diag::err_undeclared_var_use_suggest
2849 : diag::err_omp_expected_var_arg_suggest)
2851 VD = Corrected.getCorrectionDeclAs<
VarDecl>();
2853 Diag(
Id.getLoc(), Lookup.
empty() ? diag::err_undeclared_var_use
2854 : diag::err_omp_expected_var_arg)
2859 Diag(
Id.getLoc(), diag::err_omp_expected_var_arg) <<
Id.getName();
2868 Diag(
Id.getLoc(), diag::err_omp_global_var_arg)
2873 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2885 Diag(
Id.getLoc(), diag::err_omp_var_scope)
2886 << getOpenMPDirectiveName(
Kind) << VD;
2890 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2900 Diag(
Id.getLoc(), diag::err_omp_var_scope)
2901 << getOpenMPDirectiveName(
Kind) << VD;
2905 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2916 Diag(
Id.getLoc(), diag::err_omp_var_scope)
2917 << getOpenMPDirectiveName(
Kind) << VD;
2921 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2930 Diag(
Id.getLoc(), diag::err_omp_var_scope)
2931 << getOpenMPDirectiveName(
Kind) << VD;
2935 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2943 if (
Kind == OMPD_threadprivate && VD->
isUsed() &&
2945 Diag(
Id.getLoc(), diag::err_omp_var_used)
2946 << getOpenMPDirectiveName(
Kind) << VD;
2968 class LocalVarRefChecker final
2974 if (
const auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
2975 if (VD->hasLocalStorage()) {
2977 diag::err_omp_local_var_in_threadprivate_init)
2979 SemaRef.Diag(VD->
getLocation(), diag::note_defined_here)
2986 bool VisitStmt(
const Stmt *S) {
2987 for (
const Stmt *Child : S->children()) {
2988 if (Child && Visit(Child))
2993 explicit LocalVarRefChecker(
Sema &SemaRef) : SemaRef(SemaRef) {}
3000 for (
Expr *RefExpr : VarList) {
3001 auto *DE = cast<DeclRefExpr>(RefExpr);
3002 auto *VD = cast<VarDecl>(DE->getDecl());
3019 diag::err_omp_threadprivate_incomplete_type)) {
3026 Diag(ILoc, diag::err_omp_ref_type_arg)
3027 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->
getType();
3031 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3039 !(VD->
hasAttr<OMPThreadPrivateDeclAttr>() &&
3043 !VD->isLocalVarDecl())) {
3044 Diag(ILoc, diag::err_omp_var_thread_local)
3049 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3056 if (
const Expr *Init = VD->getAnyInitializer()) {
3057 LocalVarRefChecker Checker(*
this);
3058 if (Checker.Visit(Init))
3062 Vars.push_back(RefExpr);
3063 DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3064 VD->
addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3067 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3070 if (!Vars.empty()) {
3078 static OMPAllocateDeclAttr::AllocatorTypeTy
3081 return OMPAllocateDeclAttr::OMPNullMemAlloc;
3082 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3083 Allocator->isInstantiationDependent() ||
3084 Allocator->containsUnexpandedParameterPack())
3085 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3086 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3087 const Expr *AE = Allocator->IgnoreParenImpCasts();
3088 for (
int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3089 auto AllocatorKind =
static_cast<OMPAllocateDeclAttr::AllocatorTypeTy
>(I);
3090 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3091 llvm::FoldingSetNodeID AEId, DAEId;
3094 if (AEId == DAEId) {
3095 AllocatorKindRes = AllocatorKind;
3099 return AllocatorKindRes;
3104 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
Expr *Allocator) {
3105 if (!VD->
hasAttr<OMPAllocateDeclAttr>())
3107 const auto *A = VD->
getAttr<OMPAllocateDeclAttr>();
3108 Expr *PrevAllocator = A->getAllocator();
3109 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3111 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3112 if (AllocatorsMatch &&
3113 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3114 Allocator && PrevAllocator) {
3115 const Expr *AE = Allocator->IgnoreParenImpCasts();
3117 llvm::FoldingSetNodeID AEId, PAEId;
3120 AllocatorsMatch = AEId == PAEId;
3122 if (!AllocatorsMatch) {
3124 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3128 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3130 PrevAllocator->printPretty(PrevAllocatorStream,
nullptr,
3134 Allocator ? Allocator->getExprLoc() : RefExpr->
getExprLoc();
3136 Allocator ? Allocator->getSourceRange() : RefExpr->
getSourceRange();
3138 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3140 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3141 S.
Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3142 << (Allocator ? 1 : 0) << AllocatorStream.str()
3143 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3145 S.
Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3146 << PrevAllocatorRange;
3154 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3156 if (VD->
hasAttr<OMPAllocateDeclAttr>())
3165 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3166 Allocator->isInstantiationDependent() ||
3167 Allocator->containsUnexpandedParameterPack()))
3169 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.
Context, AllocatorKind,
3170 Allocator, Alignment, SR);
3173 ML->DeclarationMarkedOpenMPAllocate(VD, A);
3180 assert(Clauses.size() <= 2 &&
"Expected at most two clauses.");
3181 Expr *Alignment =
nullptr;
3182 Expr *Allocator =
nullptr;
3183 if (Clauses.empty()) {
3190 targetDiag(Loc, diag::err_expected_allocator_clause);
3193 if (
const auto *AC = dyn_cast<OMPAllocatorClause>(C))
3194 Allocator = AC->getAllocator();
3195 else if (
const auto *AC = dyn_cast<OMPAlignClause>(C))
3196 Alignment = AC->getAlignment();
3198 llvm_unreachable(
"Unexpected clause on allocate directive");
3200 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3203 for (
Expr *RefExpr : VarList) {
3204 auto *DE = cast<DeclRefExpr>(RefExpr);
3205 auto *VD = cast<VarDecl>(DE->getDecl());
3209 VD->
hasAttr<OMPThreadPrivateDeclAttr>() ||
3211 !VD->isLocalVarDecl()))
3217 AllocatorKind, Allocator))
3224 if (Allocator && VD->hasGlobalStorage()) {
3225 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3226 Diag(Allocator->getExprLoc(),
3227 diag::err_omp_expected_predefined_allocator)
3228 << Allocator->getSourceRange();
3229 bool IsDecl = VD->isThisDeclarationADefinition(
Context) ==
3232 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3238 Vars.push_back(RefExpr);
3257 Diag(Loc, diag::err_omp_invalid_scope) <<
"requires";
3271 bool SkippedClauses) {
3272 if (!SkippedClauses && Assumptions.empty())
3273 Diag(Loc, diag::err_omp_no_clause_for_directive)
3274 << llvm::omp::getAllAssumeClauseOptions()
3275 << llvm::omp::getOpenMPDirectiveName(DKind);
3277 auto *AA = AssumptionAttr::Create(
Context, llvm::join(Assumptions,
","), Loc);
3278 if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3279 OMPAssumeScoped.push_back(AA);
3284 if (Assumptions.empty())
3287 assert(DKind == llvm::omp::Directive::OMPD_assumes &&
3288 "Unexpected omp assumption directive!");
3289 OMPAssumeGlobal.push_back(AA);
3297 while (Ctx->getLexicalParent())
3299 DeclContexts.push_back(Ctx);
3300 while (!DeclContexts.empty()) {
3302 for (
auto *SubDC : DC->
decls()) {
3303 if (SubDC->isInvalidDecl())
3305 if (
auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3306 DeclContexts.push_back(CTD->getTemplatedDecl());
3307 llvm::append_range(DeclContexts, CTD->specializations());
3310 if (
auto *DC = dyn_cast<DeclContext>(SubDC))
3311 DeclContexts.push_back(DC);
3312 if (
auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3322 OMPAssumeScoped.pop_back();
3331 DSAStack->getEncounteredTargetLocs();
3333 if (!TargetLocations.empty() || !AtomicLoc.
isInvalid()) {
3334 for (
const OMPClause *CNew : ClauseList) {
3336 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3337 isa<OMPUnifiedAddressClause>(CNew) ||
3338 isa<OMPReverseOffloadClause>(CNew) ||
3339 isa<OMPDynamicAllocatorsClause>(CNew)) {
3340 Diag(Loc, diag::err_omp_directive_before_requires)
3341 <<
"target" << getOpenMPClauseName(CNew->getClauseKind());
3343 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3347 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3348 Diag(Loc, diag::err_omp_directive_before_requires)
3349 <<
"atomic" << getOpenMPClauseName(CNew->getClauseKind());
3350 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3356 if (!
DSAStack->hasDuplicateRequiresClause(ClauseList))
3364 const DSAStackTy::DSAVarData &DVar,
3365 bool IsLoopIterVar) {
3367 SemaRef.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3368 << getOpenMPClauseName(DVar.CKind);
3372 PDSA_StaticMemberShared,
3373 PDSA_StaticLocalVarShared,
3374 PDSA_LoopIterVarPrivate,
3375 PDSA_LoopIterVarLinear,
3376 PDSA_LoopIterVarLastprivate,
3377 PDSA_ConstVarShared,
3378 PDSA_GlobalVarShared,
3379 PDSA_TaskVarFirstprivate,
3380 PDSA_LocalVarPrivate,
3382 } Reason = PDSA_Implicit;
3383 bool ReportHint =
false;
3385 auto *VD = dyn_cast<VarDecl>(D);
3386 if (IsLoopIterVar) {
3387 if (DVar.CKind == OMPC_private)
3388 Reason = PDSA_LoopIterVarPrivate;
3389 else if (DVar.CKind == OMPC_lastprivate)
3390 Reason = PDSA_LoopIterVarLastprivate;
3392 Reason = PDSA_LoopIterVarLinear;
3394 DVar.CKind == OMPC_firstprivate) {
3395 Reason = PDSA_TaskVarFirstprivate;
3396 ReportLoc = DVar.ImplicitDSALoc;
3397 }
else if (VD && VD->isStaticLocal())
3398 Reason = PDSA_StaticLocalVarShared;
3399 else if (VD && VD->isStaticDataMember())
3400 Reason = PDSA_StaticMemberShared;
3401 else if (VD && VD->isFileVarDecl())
3402 Reason = PDSA_GlobalVarShared;
3404 Reason = PDSA_ConstVarShared;
3405 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3407 Reason = PDSA_LocalVarPrivate;
3409 if (Reason != PDSA_Implicit) {
3410 SemaRef.
Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3411 << Reason << ReportHint
3412 << getOpenMPDirectiveName(Stack->getCurrentDirective());
3413 }
else if (DVar.ImplicitDSALoc.isValid()) {
3414 SemaRef.
Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3415 << getOpenMPClauseName(DVar.CKind);
3421 bool IsAggregateOrDeclareTarget) {
3424 case OMPC_DEFAULTMAP_MODIFIER_alloc:
3425 Kind = OMPC_MAP_alloc;
3427 case OMPC_DEFAULTMAP_MODIFIER_to:
3430 case OMPC_DEFAULTMAP_MODIFIER_from:
3431 Kind = OMPC_MAP_from;
3433 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3434 Kind = OMPC_MAP_tofrom;
3436 case OMPC_DEFAULTMAP_MODIFIER_present:
3442 Kind = OMPC_MAP_alloc;
3444 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3446 llvm_unreachable(
"Unexpected defaultmap implicit behavior");
3447 case OMPC_DEFAULTMAP_MODIFIER_none:
3448 case OMPC_DEFAULTMAP_MODIFIER_default:
3453 if (IsAggregateOrDeclareTarget) {
3454 Kind = OMPC_MAP_tofrom;
3457 llvm_unreachable(
"Unexpected defaultmap implicit behavior");
3464 class DSAAttrChecker final :
public StmtVisitor<DSAAttrChecker, void> {
3467 bool ErrorFound =
false;
3468 bool TryCaptureCXXThisMembers =
false;
3470 const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
3475 ImplicitMapModifier[DefaultmapKindNum];
3477 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3481 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3483 if (S->getDirectiveKind() == OMPD_atomic ||
3484 S->getDirectiveKind() == OMPD_critical ||
3485 S->getDirectiveKind() == OMPD_section ||
3486 S->getDirectiveKind() == OMPD_master ||
3487 S->getDirectiveKind() == OMPD_masked ||
3489 Visit(S->getAssociatedStmt());
3492 visitSubCaptures(S->getInnermostCapturedStmt());
3495 if (TryCaptureCXXThisMembers ||
3497 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3499 return C.capturesThis();
3501 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3502 TryCaptureCXXThisMembers =
true;
3503 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3504 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3511 if (
auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3512 for (
Expr *Ref : FC->varlists())
3524 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
3527 !Stack->getTopDSA(VD,
false).RefExpr)) {
3528 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3529 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3530 Visit(CED->getInit());
3533 }
else if (VD->
isImplicit() || isa<OMPCapturedExprDecl>(VD))
3540 !Stack->isImplicitTaskFirstprivate(VD))
3543 if (Stack->isUsesAllocatorsDecl(VD).hasValue())
3546 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD,
false);
3548 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3553 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3556 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3557 !Stack->isImplicitTaskFirstprivate(VD))
3566 if (DVar.CKind == OMPC_unknown &&
3567 (Stack->getDefaultDSA() == DSA_none ||
3568 Stack->getDefaultDSA() == DSA_private ||
3569 Stack->getDefaultDSA() == DSA_firstprivate) &&
3570 isImplicitOrExplicitTaskingRegion(DKind) &&
3571 VarsWithInheritedDSA.count(VD) == 0) {
3572 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3573 if (!InheritedDSA && (Stack->getDefaultDSA() == DSA_firstprivate ||
3574 Stack->getDefaultDSA() == DSA_private)) {
3575 DSAStackTy::DSAVarData DVar =
3576 Stack->getImplicitDSA(VD,
false);
3577 InheritedDSA = DVar.CKind == OMPC_unknown;
3580 VarsWithInheritedDSA[VD] = E;
3581 if (Stack->getDefaultDSA() == DSA_none)
3596 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3597 OMPC_DEFAULTMAP_MODIFIER_none;
3598 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3599 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3603 if (!Stack->checkMappableExprComponentListsForDecl(
3608 auto MI = MapExprComponents.rbegin();
3609 auto ME = MapExprComponents.rend();
3610 return MI != ME && MI->getAssociatedDeclaration() == VD;
3612 VarsWithInheritedDSA[VD] = E;
3618 bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3619 OMPC_DEFAULTMAP_MODIFIER_present;
3620 if (IsModifierPresent) {
3621 if (llvm::find(ImplicitMapModifier[ClauseKind],
3622 OMPC_MAP_MODIFIER_present) ==
3623 std::end(ImplicitMapModifier[ClauseKind])) {
3624 ImplicitMapModifier[ClauseKind].push_back(
3625 OMPC_MAP_MODIFIER_present);
3631 !Stack->isLoopControlVariable(VD).first) {
3632 if (!Stack->checkMappableExprComponentListsForDecl(
3637 if (SemaRef.LangOpts.OpenMP >= 50)
3638 return !StackComponents.empty();
3641 return StackComponents.size() == 1 ||
3643 std::next(StackComponents.rbegin()),
3644 StackComponents.rend(),
3645 [](const OMPClauseMappableExprCommon::
3646 MappableComponent &MC) {
3647 return MC.getAssociatedDeclaration() ==
3649 (isa<OMPArraySectionExpr>(
3650 MC.getAssociatedExpression()) ||
3651 isa<OMPArrayShapingExpr>(
3652 MC.getAssociatedExpression()) ||
3653 isa<ArraySubscriptExpr>(
3654 MC.getAssociatedExpression()));
3657 bool IsFirstprivate =
false;
3659 if (
const auto *RD =
3661 IsFirstprivate = RD->isLambda();
3663 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3664 if (IsFirstprivate) {
3665 ImplicitFirstprivate.emplace_back(E);
3668 Stack->getDefaultmapModifier(ClauseKind);
3670 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3671 ImplicitMap[ClauseKind][
Kind].emplace_back(E);
3681 DVar = Stack->hasInnermostDSA(
3684 return C == OMPC_reduction && !AppliedToPointee;
3693 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
3699 DVar = Stack->getImplicitDSA(VD,
false);
3701 (((Stack->getDefaultDSA() == DSA_firstprivate &&
3702 DVar.CKind == OMPC_firstprivate) ||
3703 (Stack->getDefaultDSA() == DSA_private &&
3704 DVar.CKind == OMPC_private)) &&
3706 !Stack->isLoopControlVariable(VD).first) {
3707 if (Stack->getDefaultDSA() == DSA_private)
3708 ImplicitPrivate.push_back(E);
3710 ImplicitFirstprivate.push_back(E);
3717 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3718 Stack->addToParentTargetRegionLinkGlobals(E);
3732 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD,
false);
3735 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3739 !Stack->isLoopControlVariable(FD).first &&
3740 !Stack->checkMappableExprComponentListsForDecl(
3745 return isa<CXXThisExpr>(
3747 StackComponents.back().getAssociatedExpression())
3754 if (FD->isBitField())
3759 if (Stack->isClassPreviouslyMapped(TE->getType()))
3763 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3768 ImplicitMap[ClauseKind][
Kind].emplace_back(E);
3777 DVar = Stack->hasInnermostDSA(
3780 return C == OMPC_reduction && !AppliedToPointee;
3789 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
3795 DVar = Stack->getImplicitDSA(FD,
false);
3797 !Stack->isLoopControlVariable(FD).first) {
3802 if (DVar.CKind != OMPC_unknown)
3803 ImplicitFirstprivate.push_back(E);
3810 Stack->getCurrentDirective(),
3813 const auto *VD = cast<ValueDecl>(
3814 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3815 if (!Stack->checkMappableExprComponentListsForDecl(
3821 auto CCI = CurComponents.rbegin();
3822 auto CCE = CurComponents.rend();
3823 for (const auto &SC : llvm::reverse(StackComponents)) {
3825 if (CCI->getAssociatedExpression()->getStmtClass() !=
3826 SC.getAssociatedExpression()->getStmtClass())
3827 if (!((isa<OMPArraySectionExpr>(
3828 SC.getAssociatedExpression()) ||
3829 isa<OMPArrayShapingExpr>(
3830 SC.getAssociatedExpression())) &&
3831 isa<ArraySubscriptExpr>(
3832 CCI->getAssociatedExpression())))
3835 const Decl *CCD = CCI->getAssociatedDeclaration();
3836 const Decl *SCD = SC.getAssociatedDeclaration();
3837 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3838 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3841 std::advance(CCI, 1);
3849 }
else if (!TryCaptureCXXThisMembers) {
3857 if (isa_and_nonnull<OMPPrivateClause>(C))
3863 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3866 for (
Stmt *CC :
C->children()) {
3873 VisitSubCaptures(S);
3882 for (
Stmt *C : S->arguments()) {
3889 if (
Expr *Callee = S->getCallee())
3890 if (
auto *CE = dyn_cast<MemberExpr>(
Callee->IgnoreParenImpCasts()))
3891 Visit(CE->getBase());
3893 void VisitStmt(
Stmt *S) {
3894 for (
Stmt *C : S->children()) {
3905 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3907 VarDecl *VD = Cap.getCapturedVar();
3911 Stack->checkMappableExprComponentListsForDecl(
3918 Cap.getLocation(),
true);
3922 bool isErrorFound()
const {
return ErrorFound; }
3924 return ImplicitFirstprivate;
3929 return ImplicitMap[DK][MK];
3933 return ImplicitMapModifier[
Kind];
3936 return VarsWithInheritedDSA;
3940 : Stack(S), SemaRef(SemaRef), ErrorFound(
false), CS(CS) {
3955 Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target);
3957 Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams);
3959 Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel);
3961 Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for);
3963 Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd);
3964 Stack->handleConstructTrait(Traits, ScopeEntry);
3970 case OMPD_parallel_for:
3971 case OMPD_parallel_for_simd:
3972 case OMPD_parallel_sections:
3973 case OMPD_parallel_master:
3974 case OMPD_parallel_loop:
3976 case OMPD_teams_distribute:
3977 case OMPD_teams_distribute_simd: {
3982 std::make_pair(
".global_tid.", KmpInt32PtrTy),
3983 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
3984 std::make_pair(StringRef(),
QualType())
3990 case OMPD_target_teams:
3991 case OMPD_target_parallel:
3992 case OMPD_target_parallel_for:
3993 case OMPD_target_parallel_for_simd:
3994 case OMPD_target_teams_loop:
3995 case OMPD_target_parallel_loop:
3996 case OMPD_target_teams_distribute:
3997 case OMPD_target_teams_distribute_simd: {
4007 std::make_pair(
".global_tid.", KmpInt32Ty),
4008 std::make_pair(
".part_id.", KmpInt32PtrTy),
4009 std::make_pair(
".privates.", VoidPtrTy),
4014 std::make_pair(StringRef(),
QualType())
4021 AlwaysInlineAttr::CreateImplicit(
4023 AlwaysInlineAttr::Keyword_forceinline));
4025 std::make_pair(StringRef(),
QualType())
4031 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4032 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4033 std::make_pair(StringRef(),
QualType())
4038 ParamsTeamsOrParallel, 2);
4042 case OMPD_target_simd: {
4052 std::make_pair(
".global_tid.", KmpInt32Ty),
4053 std::make_pair(
".part_id.", KmpInt32PtrTy),
4054 std::make_pair(
".privates.", VoidPtrTy),
4059 std::make_pair(StringRef(),
QualType())
4066 AlwaysInlineAttr::CreateImplicit(
4068 AlwaysInlineAttr::Keyword_forceinline));
4070 std::make_pair(StringRef(),
QualType()),
4090 case OMPD_taskgroup:
4091 case OMPD_distribute:
4092 case OMPD_distribute_simd:
4094 case OMPD_target_data:
4095 case OMPD_dispatch: {
4097 std::make_pair(StringRef(),
QualType())
4113 std::make_pair(
".global_tid.", KmpInt32Ty),
4114 std::make_pair(
".part_id.", KmpInt32PtrTy),
4115 std::make_pair(
".privates.", VoidPtrTy),
4120 std::make_pair(StringRef(),
QualType())
4127 AlwaysInlineAttr::CreateImplicit(
4129 AlwaysInlineAttr::Keyword_forceinline));
4133 case OMPD_taskloop_simd:
4134 case OMPD_master_taskloop:
4135 case OMPD_master_taskloop_simd: {
4153 std::make_pair(
".global_tid.", KmpInt32Ty),
4154 std::make_pair(
".part_id.", KmpInt32PtrTy),
4155 std::make_pair(
".privates.", VoidPtrTy),
4160 std::make_pair(
".lb.", KmpUInt64Ty),
4161 std::make_pair(
".ub.", KmpUInt64Ty),
4162 std::make_pair(
".st.", KmpInt64Ty),
4163 std::make_pair(
".liter.", KmpInt32Ty),
4164 std::make_pair(
".reductions.", VoidPtrTy),
4165 std::make_pair(StringRef(),
QualType())
4172 AlwaysInlineAttr::CreateImplicit(
4174 AlwaysInlineAttr::Keyword_forceinline));
4177 case OMPD_parallel_master_taskloop:
4178 case OMPD_parallel_master_taskloop_simd: {
4192 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4193 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4194 std::make_pair(StringRef(),
QualType())
4204 std::make_pair(
".global_tid.", KmpInt32Ty),
4205 std::make_pair(
".part_id.", KmpInt32PtrTy),
4206 std::make_pair(
".privates.", VoidPtrTy),
4211 std::make_pair(
".lb.", KmpUInt64Ty),
4212 std::make_pair(
".ub.", KmpUInt64Ty),
4213 std::make_pair(
".st.", KmpInt64Ty),
4214 std::make_pair(
".liter.", KmpInt32Ty),
4215 std::make_pair(
".reductions.", VoidPtrTy),
4216 std::make_pair(StringRef(),
QualType())
4223 AlwaysInlineAttr::CreateImplicit(
4225 AlwaysInlineAttr::Keyword_forceinline));
4228 case OMPD_distribute_parallel_for_simd:
4229 case OMPD_distribute_parallel_for: {
4234 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4235 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4238 std::make_pair(StringRef(),
QualType())
4244 case OMPD_target_teams_distribute_parallel_for:
4245 case OMPD_target_teams_distribute_parallel_for_simd: {
4256 std::make_pair(
".global_tid.", KmpInt32Ty),
4257 std::make_pair(
".part_id.", KmpInt32PtrTy),
4258 std::make_pair(
".privates.", VoidPtrTy),
4263 std::make_pair(StringRef(),
QualType())
4270 AlwaysInlineAttr::CreateImplicit(
4272 AlwaysInlineAttr::Keyword_forceinline));
4274 std::make_pair(StringRef(),
QualType())
4281 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4282 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4283 std::make_pair(StringRef(),
QualType())
4290 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4291 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4294 std::make_pair(StringRef(),
QualType())
4303 case OMPD_teams_loop: {
4309 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4310 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4311 std::make_pair(StringRef(),
QualType())
4319 case OMPD_teams_distribute_parallel_for:
4320 case OMPD_teams_distribute_parallel_for_simd: {
4326 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4327 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4328 std::make_pair(StringRef(),
QualType())
4335 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4336 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4339 std::make_pair(StringRef(),
QualType())
4347 case OMPD_target_update:
4348 case OMPD_target_enter_data:
4349 case OMPD_target_exit_data: {
4359 std::make_pair(
".global_tid.", KmpInt32Ty),
4360 std::make_pair(
".part_id.", KmpInt32PtrTy),
4361 std::make_pair(
".privates.", VoidPtrTy),
4366 std::make_pair(StringRef(),
QualType())
4373 AlwaysInlineAttr::CreateImplicit(
4375 AlwaysInlineAttr::Keyword_forceinline));
4378 case OMPD_threadprivate:
4380 case OMPD_taskyield:
4383 case OMPD_cancellation_point:
4388 case OMPD_declare_reduction:
4389 case OMPD_declare_mapper:
4390 case OMPD_declare_simd:
4391 case OMPD_declare_target:
4392 case OMPD_end_declare_target:
4394 case OMPD_declare_variant:
4395 case OMPD_begin_declare_variant:
4396 case OMPD_end_declare_variant:
4397 case OMPD_metadirective:
4398 llvm_unreachable(
"OpenMP Directive is not allowed");
4401 llvm_unreachable(
"Unknown OpenMP directive");
4407 int Sema::getNumberOfConstructScopes(
unsigned Level)
const {
4414 return CaptureRegions.size();
4418 Expr *CaptureExpr,
bool WithInit,
4419 bool AsExpression) {
4420 assert(CaptureExpr);
4426 Ty = C.getLValueReferenceType(Ty);
4428 Ty = C.getPointerType(Ty);
4440 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4451 CD = cast<OMPCapturedExprDecl>(VD);
4488 class 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 VarDecl *, FieldDecl *> Captures;
4526 RD->getCaptureFields(Captures, ThisCapture);
4529 VarDecl *VD = LC.getCapturedVar();
4534 }
else if (LC.getCaptureKind() ==
LCK_This) {
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)
4582 if (
DSAStack->getCurrentDirective() == OMPD_atomic ||
4583 DSAStack->getCurrentDirective() == OMPD_critical ||
4584 DSAStack->getCurrentDirective() == OMPD_section ||
4585 DSAStack->getCurrentDirective() == OMPD_master ||
4586 DSAStack->getCurrentDirective() == OMPD_masked)
4589 bool ErrorFound =
false;
4590 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4591 *
this, ErrorFound,
DSAStack->getCurrentDirective());
4592 if (!S.isUsable()) {
4610 auto *IRC = cast<OMPInReductionClause>(Clause);
4611 for (
Expr *E : IRC->taskgroup_descriptors())
4623 if (
auto *E = cast_or_null<Expr>(VarRef)) {
4627 DSAStack->setForceVarCapturing(
false);
4629 DSAStack->getCurrentDirective())) {
4630 assert(CaptureRegions.empty() &&
4631 "No captured regions in loop transformation directives.");
4632 }
else if (CaptureRegions.size() > 1 ||
4633 CaptureRegions.back() != OMPD_unknown) {
4637 if (
Expr *E = C->getPostUpdateExpr())
4642 SC = cast<OMPScheduleClause>(Clause);
4644 OC = cast<OMPOrderedClause>(Clause);
4646 LCs.push_back(cast<OMPLinearClause>(Clause));
4657 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4662 diag::err_omp_simple_clause_incompatible_with_ordered)
4663 << getOpenMPClauseName(OMPC_schedule)
4665 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4676 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4685 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
4692 unsigned CompletedRegions = 0;
4697 if (ThisCaptureRegion != OMPD_unknown) {
4705 if (CaptureRegion == ThisCaptureRegion ||
4706 CaptureRegion == OMPD_unknown) {
4707 if (
auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4708 for (
Decl *D : DS->decls())
4714 if (ThisCaptureRegion == OMPD_target) {
4718 if (
const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4719 for (
unsigned I = 0,
End = UAC->getNumberOfAllocators(); I <
End;
4729 if (ThisCaptureRegion == OMPD_parallel) {
4733 if (
auto *RC = dyn_cast<OMPReductionClause>(C)) {
4734 if (RC->getModifier() != OMPC_REDUCTION_inscan)
4736 for (
Expr *E : RC->copy_array_temps())
4739 if (
auto *AC = dyn_cast<OMPAlignedClause>(C)) {
4740 for (
Expr *E : AC->varlists())
4745 if (++CompletedRegions == CaptureRegions.size())
4756 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4759 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4760 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4763 SemaRef.
Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4764 << getOpenMPDirectiveName(CancelRegion);
4774 if (Stack->getCurScope()) {
4777 bool NestingProhibited =
false;
4778 bool CloseNesting =
true;
4779 bool OrphanSeen =
false;
4782 ShouldBeInParallelRegion,
4783 ShouldBeInOrderedRegion,
4784 ShouldBeInTargetRegion,
4785 ShouldBeInTeamsRegion,
4786 ShouldBeInLoopSimdRegion,
4787 } Recommend = NoRecommend;
4789 ((SemaRef.
LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4790 (SemaRef.
LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4791 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4792 CurrentRegion != OMPD_scan))) {
4805 SemaRef.
Diag(StartLoc, (CurrentRegion != OMPD_simd)
4806 ? diag::err_omp_prohibited_region_simd
4807 : diag::warn_omp_nesting_simd)
4808 << (SemaRef.
LangOpts.OpenMP >= 50 ? 1 : 0);
4809 return CurrentRegion != OMPD_simd;
4811 if (ParentRegion == OMPD_atomic) {
4814 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4817 if (CurrentRegion == OMPD_section) {
4822 if (ParentRegion != OMPD_sections &&
4823 ParentRegion != OMPD_parallel_sections) {
4824 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4825 << (ParentRegion != OMPD_unknown)
4826 << getOpenMPDirectiveName(ParentRegion);
4834 if (ParentRegion == OMPD_unknown &&
4836 CurrentRegion != OMPD_cancellation_point &&
4837 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4839 if (CurrentRegion == OMPD_cancellation_point ||
4840 CurrentRegion == OMPD_cancel) {
4853 !((CancelRegion == OMPD_parallel &&
4854 (ParentRegion == OMPD_parallel ||
4855 ParentRegion == OMPD_target_parallel)) ||
4856 (CancelRegion == OMPD_for &&
4857 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4858 ParentRegion == OMPD_target_parallel_for ||
4859 ParentRegion == OMPD_distribute_parallel_for ||
4860 ParentRegion == OMPD_teams_distribute_parallel_for ||
4861 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4862 (CancelRegion == OMPD_taskgroup &&
4863 (ParentRegion == OMPD_task ||
4865 (ParentRegion == OMPD_taskloop ||
4866 ParentRegion == OMPD_master_taskloop ||
4867 ParentRegion == OMPD_parallel_master_taskloop)))) ||
4868 (CancelRegion == OMPD_sections &&
4869 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4870 ParentRegion == OMPD_parallel_sections)));
4871 OrphanSeen = ParentRegion == OMPD_unknown;
4872 }
else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
4879 }
else if (CurrentRegion == OMPD_critical && CurrentName.
getName()) {
4885 bool DeadLock = Stack->hasDirective(
4889 if (K == OMPD_critical && DNI.
getName() == CurrentName.
getName()) {
4890 PreviousCriticalLoc = Loc;
4897 SemaRef.
Diag(StartLoc,
4898 diag::err_omp_prohibited_region_critical_same_name)
4900 if (PreviousCriticalLoc.
isValid())
4901 SemaRef.
Diag(PreviousCriticalLoc,
4902 diag::note_omp_previous_critical_region);
4905 }
else if (CurrentRegion == OMPD_barrier) {
4913 ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
4914 ParentRegion == OMPD_parallel_master ||
4915 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
4927 ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
4928 ParentRegion == OMPD_parallel_master ||
4929 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
4930 Recommend = ShouldBeInParallelRegion;
4931 }
else if (CurrentRegion == OMPD_ordered) {
4940 NestingProhibited = ParentRegion == OMPD_critical ||
4943 Stack->isParentOrderedRegion());
4944 Recommend = ShouldBeInOrderedRegion;
4950 (SemaRef.
LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4951 (SemaRef.
LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4952 ParentRegion != OMPD_target);
4953 OrphanSeen = ParentRegion == OMPD_unknown;
4954 Recommend = ShouldBeInTargetRegion;
4955 }
else if (CurrentRegion == OMPD_scan) {
4961 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
4962 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
4963 ParentRegion != OMPD_parallel_for_simd);
4964 OrphanSeen = ParentRegion == OMPD_unknown;
4965 Recommend = ShouldBeInLoopSimdRegion;
4967 if (!NestingProhibited &&
4970 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4980 CurrentRegion != OMPD_loop;
4981 Recommend = ShouldBeInParallelRegion;
4983 if (!NestingProhibited && CurrentRegion == OMPD_loop) {
4988 NestingProhibited = BindKind == OMPC_BIND_teams &&
4989 ParentRegion != OMPD_teams &&
4990 ParentRegion != OMPD_target_teams;
4991 Recommend = ShouldBeInTeamsRegion;
4993 if (!NestingProhibited &&
4999 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
5000 Recommend = ShouldBeInTeamsRegion;
5002 if (!NestingProhibited &&
5009 NestingProhibited = Stack->hasDirective(
5013 OffendingRegion = K;
5019 CloseNesting =
false;
5021 if (NestingProhibited) {
5023 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_device_directive)
5024 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
5026 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region)
5027 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
5028 << Recommend << getOpenMPDirectiveName(CurrentRegion);
5043 bool ErrorFound =
false;
5044 unsigned NamedModifiersNumber = 0;
5045 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
5046 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
5049 if (
const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
5053 if (FoundNameModifiers[CurNM]) {
5054 S.
Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
5055 << getOpenMPDirectiveName(
Kind) << getOpenMPClauseName(OMPC_if)
5056 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
5058 }
else if (CurNM != OMPD_unknown) {
5059 NameModifierLoc.push_back(IC->getNameModifierLoc());
5060 ++NamedModifiersNumber;
5062 FoundNameModifiers[CurNM] = IC;
5063 if (CurNM == OMPD_unknown)
5069 if (!llvm::is_contained(AllowedNameModifiers, CurNM)) {
5070 S.
Diag(IC->getNameModifierLoc(),
5071 diag::err_omp_wrong_if_directive_name_modifier)
5072 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(
Kind);
5079 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
5080 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
5081 S.
Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
5082 diag::err_omp_no_more_if_clause);
5086 unsigned AllowedCnt = 0;
5087 unsigned TotalAllowedNum =
5088 AllowedNameModifiers.size() - NamedModifiersNumber;
5089 for (
unsigned Cnt = 0,
End = AllowedNameModifiers.size(); Cnt <
End;
5092 if (!FoundNameModifiers[NM]) {
5094 Values += getOpenMPDirectiveName(NM);
5096 if (AllowedCnt + 2 == TotalAllowedNum)
5098 else if (AllowedCnt + 1 != TotalAllowedNum)
5103 S.
Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
5104 diag::err_omp_unnamed_if_clause)
5105 << (TotalAllowedNum > 1) << Values;
5108 S.
Diag(Loc, diag::note_omp_previous_named_if_clause);
5118 bool AllowArraySection) {
5121 return std::make_pair(
nullptr,
true);
5133 } IsArrayExpr = NoArrayExpr;
5134 if (AllowArraySection) {
5135 if (
auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
5136 Expr *
Base = ASE->getBase()->IgnoreParenImpCasts();
5137 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base))
5138 Base = TempASE->getBase()->IgnoreParenImpCasts();
5140 IsArrayExpr = ArraySubscript;
5141 }
else if (
auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
5142 Expr *
Base = OASE->getBase()->IgnoreParenImpCasts();
5143 while (
auto *TempOASE = dyn_cast<OMPArraySectionExpr>(
Base))
5144 Base = TempOASE->getBase()->IgnoreParenImpCasts();
5145 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base))
5146 Base = TempASE->getBase()->IgnoreParenImpCasts();
5148 IsArrayExpr = OMPArraySection;
5154 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5155 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
5156 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
5158 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
5159 !isa<FieldDecl>(ME->getMemberDecl()))) {
5160 if (IsArrayExpr != NoArrayExpr) {
5161 S.
Diag(ELoc, diag::err_omp_expected_base_var_name)
5162 << IsArrayExpr << ERange;
5166 ? diag::err_omp_expected_var_name_member_expr_or_array_item
5167 : diag::err_omp_expected_var_name_member_expr)
5170 return std::make_pair(
nullptr,
false);
5172 return std::make_pair(
5179 class AllocatorChecker final :
public ConstStmtVisitor<AllocatorChecker, bool> {
5180 DSAStackTy *S =
nullptr;
5184 return S->isUsesAllocatorsDecl(E->
getDecl())
5186 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5187 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5189 bool VisitStmt(
const Stmt *S) {
5190 for (
const Stmt *Child : S->children()) {
5191 if (Child && Visit(Child))
5196 explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5203 "Expected non-dependent context.");
5204 auto AllocateRange =
5207 auto PrivateRange = llvm::make_filter_range(Clauses, [](
const OMPClause *C) {
5212 if (
Cl->getClauseKind() == OMPC_private) {
5213 auto *PC = cast<OMPPrivateClause>(
Cl);
5214 I = PC->private_copies().begin();
5215 It = PC->varlist_begin();
5216 Et = PC->varlist_end();
5217 }
else if (
Cl->getClauseKind() == OMPC_firstprivate) {
5218 auto *PC = cast<OMPFirstprivateClause>(
Cl);
5219 I = PC->private_copies().begin();
5220 It = PC->varlist_begin();
5221 Et = PC->varlist_end();
5222 }
else if (
Cl->getClauseKind() == OMPC_lastprivate) {
5223 auto *PC = cast<OMPLastprivateClause>(
Cl);
5224 I = PC->private_copies().begin();
5225 It = PC->varlist_begin();
5226 Et = PC->varlist_end();
5227 }
else if (
Cl->getClauseKind() == OMPC_linear) {
5228 auto *PC = cast<OMPLinearClause>(
Cl);
5229 I = PC->privates().begin();
5230 It = PC->varlist_begin();
5231 Et = PC->varlist_end();
5232 }
else if (
Cl->getClauseKind() == OMPC_reduction) {
5233 auto *PC = cast<OMPReductionClause>(
Cl);
5234 I = PC->privates().begin();
5235 It = PC->varlist_begin();
5236 Et = PC->varlist_end();
5237 }
else if (
Cl->getClauseKind() == OMPC_task_reduction) {
5238 auto *PC = cast<OMPTaskReductionClause>(
Cl);
5239 I = PC->privates().begin();
5240 It = PC->varlist_begin();
5241 Et = PC->varlist_end();
5242 }
else if (
Cl->getClauseKind() == OMPC_in_reduction) {
5243 auto *PC = cast<OMPInReductionClause>(
Cl);
5244 I = PC->privates().begin();
5245 It = PC->varlist_begin();
5246 Et = PC->varlist_end();
5248 llvm_unreachable(
"Expected private clause.");
5250 for (
Expr *E : llvm::make_range(It, Et)) {
5257 Expr *SimpleRefExpr = E;
5260 DeclToCopy.try_emplace(Res.first,
5261 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5266 auto *AC = cast<OMPAllocateClause>(C);
5270 AC->getAllocator()) {
5271 Expr *Allocator = AC->getAllocator();
5277 AllocatorChecker Checker(Stack);
5278 if (Checker.Visit(Allocator))
5279 S.
Diag(Allocator->getExprLoc(),
5280 diag::err_omp_allocator_not_in_uses_allocators)
5281 << Allocator->getSourceRange();
5283 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5289 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5292 S.
Diag(AC->getAllocator()->getExprLoc(),
5293 diag::warn_omp_allocate_thread_on_task_target_directive)
5294 << getOpenMPDirectiveName(Stack->getCurrentDirective());
5296 for (
Expr *E : AC->varlists()) {
5299 Expr *SimpleRefExpr = E;
5302 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD,
false);
5305 diag::err_omp_expected_private_copy_for_allocate);
5308 VarDecl *PrivateVD = DeclToCopy[VD];
5310 AllocatorKind, AC->getAllocator()))
5313 Expr *Alignment =
nullptr;
5330 CaptureVars(
Sema &Actions) : BaseTransform(Actions) {}
5332 bool AlwaysRebuild() {
return true; }
5345 BodyStmts.push_back(NewDeclStmt);
5383 DistParam, LogicalTy,
VK_LValue, {},
nullptr,
nullptr, {},
nullptr);
5394 auto BuildVarRef = [&](
VarDecl *VD) {
5407 Actions.
BuildBinOp(
nullptr, {}, BO_LT, BuildVarRef(NewStep),
Zero));
5411 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5415 nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep)));
5419 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5423 Actions.
BuildUnaryOp(
nullptr, {}, UO_Minus, BuildVarRef(NewStep)));
5425 Actions.
BuildBinOp(
nullptr, {}, BO_Div, BackwardRange, NegIncAmount));
5429 {}, {}, IsNegStep, BackwardDist, ForwardDist));
5431 assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) &&
5432 "Expected one of these relational operators");
5439 nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5443 if (Rel == BO_GE || Rel == BO_GT)
5445 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5448 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5454 if (Rel == BO_LE || Rel == BO_GE) {
5465 Expr *Divisor = BuildVarRef(NewStep);
5466 if (Rel == BO_GE || Rel == BO_GT)
5469 Expr *DivisorMinusOne =
5472 Actions.
BuildBinOp(
nullptr, {}, BO_Add, Range, DivisorMinusOne));
5474 Actions.
BuildBinOp(
nullptr, {}, BO_Div, RangeRoundUp, Divisor));
5484 Actions.
getCurScope(), {}, BO_Assign, DistRef, Dist));
5485 BodyStmts.push_back(ResultAssign);
5490 return cast<CapturedStmt>(
5517 {
"Logical", LogicalTy},
5528 assert(!Invalid &&
"Expecting capture-by-value to work.");
5533 auto *CS = cast<CapturedDecl>(Actions.
CurContext);
5537 TargetParam, LoopVarTy,
VK_LValue, {},
nullptr,
nullptr, {},
nullptr);
5540 IndvarParam, LogicalTy,
VK_LValue, {},
nullptr,
nullptr, {},
nullptr);
5543 CaptureVars Recap(Actions);
5548 Actions.
BuildBinOp(
nullptr, {}, BO_Mul, NewStep, LogicalRef));
5563 BO_Assign, TargetRef, Advanced));
5565 return cast<CapturedStmt>(
5576 if (
auto *For = dyn_cast<ForStmt>(AStmt)) {
5577 Stmt *Init = For->getInit();
5578 if (
auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) {
5580 LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl());
5581 }
else if (
auto *LCAssign = dyn_cast<BinaryOperator>(Init)) {
5583 assert(LCAssign->getOpcode() == BO_Assign &&
5584 "init part must be a loop variable assignment");
5585 auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS());
5586 LIVDecl = cast<VarDecl>(CounterRef->getDecl());
5588 llvm_unreachable(
"Cannot determine loop variable");
5591 Cond = For->getCond();
5592 Inc = For->getInc();
5593 }
else if (
auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) {
5594 DeclStmt *BeginStmt = RangeFor->getBeginStmt();
5596 LUVDecl = RangeFor->getLoopVariable();
5598 Cond = RangeFor->getCond();
5599 Inc = RangeFor->getInc();
5601 llvm_unreachable(
"unhandled kind of loop");
5610 if (
auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) {
5611 LHS = CondBinExpr->getLHS();
5612 RHS = CondBinExpr->getRHS();
5613 CondRel = CondBinExpr->getOpcode();
5614 }
else if (
auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) {
5615 assert(CondCXXOp->getNumArgs() == 2 &&
"Comparison should have 2 operands");
5616 LHS = CondCXXOp->getArg(0);
5617 RHS = CondCXXOp->getArg(1);
5618 switch (CondCXXOp->getOperator()) {
5619 case OO_ExclaimEqual:
5631 case OO_GreaterEqual: