37#include "llvm/ADT/IndexedMap.h"
38#include "llvm/ADT/PointerEmbeddedInt.h"
39#include "llvm/ADT/STLExtras.h"
40#include "llvm/ADT/SmallSet.h"
41#include "llvm/ADT/StringExtras.h"
42#include "llvm/Frontend/OpenMP/OMPAssume.h"
43#include "llvm/Frontend/OpenMP/OMPConstants.h"
48using namespace llvm::omp;
61enum DefaultDataSharingAttributes {
66 DSA_firstprivate = 1 << 3,
76 unsigned Modifier = 0;
77 const Expr *RefExpr =
nullptr;
80 bool AppliedToPointee =
false;
81 DSAVarData() =
default;
85 bool AppliedToPointee)
86 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
87 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
88 AppliedToPointee(AppliedToPointee) {}
90 using OperatorOffsetTy =
92 using DoacrossClauseMapTy = llvm::DenseMap<OMPClause *, OperatorOffsetTy>;
94 enum class UsesAllocatorsDeclKind {
106 unsigned Modifier = 0;
109 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
113 bool AppliedToPointee =
false;
115 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
116 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
117 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
118 using LoopControlVariablesMapTy =
119 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
122 struct MappedExprComponentTy {
126 using MappedExprComponentsTy =
127 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
128 using CriticalsWithHintsTy =
129 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
130 struct ReductionData {
131 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
133 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
134 ReductionData() =
default;
141 ReductionOp = RefExpr;
144 using DeclReductionMapTy =
145 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
146 struct DefaultmapInfo {
150 DefaultmapInfo() =
default;
152 : ImplicitBehavior(M), SLoc(Loc) {}
155 struct SharingMapTy {
156 DeclSAMapTy SharingMap;
157 DeclReductionMapTy ReductionMap;
158 UsedRefMapTy AlignedMap;
159 UsedRefMapTy NontemporalMap;
160 MappedExprComponentsTy MappedExprComponents;
161 LoopControlVariablesMapTy LCVMap;
162 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
171 Scope *CurScope =
nullptr;
177 DoacrossClauseMapTy DoacrossDepends;
181 std::optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
182 bool RegionHasOrderConcurrent =
false;
183 unsigned AssociatedLoops = 1;
184 bool HasMutipleLoops =
false;
185 const Decl *PossiblyLoopCounter =
nullptr;
186 bool NowaitRegion =
false;
187 bool UntiedRegion =
false;
188 bool CancelRegion =
false;
189 bool LoopStart =
false;
190 bool BodyComplete =
false;
195 Expr *TaskgroupReductionRef =
nullptr;
204 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
208 struct ImplicitDefaultFDInfoTy {
212 size_t StackLevel = 0;
215 ImplicitDefaultFDInfoTy(
const FieldDecl *FD,
size_t StackLevel,
217 : FD(FD), StackLevel(StackLevel), VD(VD) {}
221 ImplicitDefaultFirstprivateFDs;
222 Expr *DeclareMapperVar =
nullptr;
226 :
Directive(DKind), DirectiveName(Name), CurScope(CurScope),
228 SharingMapTy() =
default;
234 DeclSAMapTy Threadprivates;
241 bool ForceCapturing =
false;
244 bool ForceCaptureByReferenceInTargetExecutable =
false;
245 CriticalsWithHintsTy Criticals;
246 unsigned IgnoredStackElements = 0;
250 using const_iterator = StackTy::const_reverse_iterator;
251 const_iterator begin()
const {
252 return Stack.empty() ? const_iterator()
253 : Stack.back().first.rbegin() + IgnoredStackElements;
255 const_iterator end()
const {
256 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
258 using iterator = StackTy::reverse_iterator;
260 return Stack.empty() ? iterator()
261 : Stack.back().first.rbegin() + IgnoredStackElements;
264 return Stack.empty() ? iterator() : Stack.back().first.rend();
269 bool isStackEmpty()
const {
270 return Stack.empty() ||
271 Stack.back().second != CurrentNonCapturingFunctionScope ||
272 Stack.back().first.size() <= IgnoredStackElements;
274 size_t getStackSize()
const {
275 return isStackEmpty() ? 0
276 : Stack.back().first.size() - IgnoredStackElements;
279 SharingMapTy *getTopOfStackOrNull() {
280 size_t Size = getStackSize();
283 return &Stack.back().first[
Size - 1];
285 const SharingMapTy *getTopOfStackOrNull()
const {
286 return const_cast<DSAStackTy &
>(*this).getTopOfStackOrNull();
288 SharingMapTy &getTopOfStack() {
289 assert(!isStackEmpty() &&
"no current directive");
290 return *getTopOfStackOrNull();
292 const SharingMapTy &getTopOfStack()
const {
293 return const_cast<DSAStackTy &
>(*this).getTopOfStack();
296 SharingMapTy *getSecondOnStackOrNull() {
297 size_t Size = getStackSize();
300 return &Stack.back().first[
Size - 2];
302 const SharingMapTy *getSecondOnStackOrNull()
const {
303 return const_cast<DSAStackTy &
>(*this).getSecondOnStackOrNull();
312 SharingMapTy &getStackElemAtLevel(
unsigned Level) {
313 assert(Level < getStackSize() &&
"no such stack element");
314 return Stack.back().first[
Level];
316 const SharingMapTy &getStackElemAtLevel(
unsigned Level)
const {
317 return const_cast<DSAStackTy &
>(*this).getStackElemAtLevel(Level);
323 bool isOpenMPLocal(
VarDecl *D, const_iterator
Iter)
const;
336 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
345 explicit DSAStackTy(
Sema &S) : SemaRef(S) {}
348 void setOMPAllocatorHandleT(
QualType Ty) { OMPAllocatorHandleT = Ty; }
350 QualType getOMPAllocatorHandleT()
const {
return OMPAllocatorHandleT; }
352 void setOMPAlloctraitT(
QualType Ty) { OMPAlloctraitT = Ty; }
354 QualType getOMPAlloctraitT()
const {
return OMPAlloctraitT; }
356 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
358 OMPPredefinedAllocators[AllocatorKind] = Allocator;
361 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind)
const {
362 return OMPPredefinedAllocators[AllocatorKind];
365 void setOMPDependT(
QualType Ty) { OMPDependT = Ty; }
367 QualType getOMPDependT()
const {
return OMPDependT; }
370 void setOMPEventHandleT(
QualType Ty) { OMPEventHandleT = Ty; }
372 QualType getOMPEventHandleT()
const {
return OMPEventHandleT; }
374 bool isClauseParsingMode()
const {
return ClauseKindMode != OMPC_unknown; }
376 assert(isClauseParsingMode() &&
"Must be in clause parsing mode.");
377 return ClauseKindMode;
381 bool isBodyComplete()
const {
382 const SharingMapTy *Top = getTopOfStackOrNull();
383 return Top && Top->BodyComplete;
385 void setBodyComplete() { getTopOfStack().BodyComplete =
true; }
387 bool isForceVarCapturing()
const {
return ForceCapturing; }
388 void setForceVarCapturing(
bool V) { ForceCapturing =
V; }
390 void setForceCaptureByReferenceInTargetExecutable(
bool V) {
391 ForceCaptureByReferenceInTargetExecutable =
V;
393 bool isForceCaptureByReferenceInTargetExecutable()
const {
394 return ForceCaptureByReferenceInTargetExecutable;
399 assert(!IgnoredStackElements &&
400 "cannot change stack while ignoring elements");
402 Stack.back().second != CurrentNonCapturingFunctionScope)
403 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
404 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
405 Stack.back().first.back().DefaultAttrLoc = Loc;
409 assert(!IgnoredStackElements &&
410 "cannot change stack while ignoring elements");
411 assert(!Stack.back().first.empty() &&
412 "Data-sharing attributes stack is empty!");
413 Stack.back().first.pop_back();
418 class ParentDirectiveScope {
423 ParentDirectiveScope(DSAStackTy &Self,
bool Activate)
428 ~ParentDirectiveScope() { disable(); }
431 --
Self.IgnoredStackElements;
437 ++
Self.IgnoredStackElements;
446 "Expected loop-based directive.");
447 getTopOfStack().LoopStart =
true;
452 "Expected loop-based directive.");
453 getTopOfStack().LoopStart =
false;
456 bool isLoopStarted()
const {
458 "Expected loop-based directive.");
459 return !getTopOfStack().LoopStart;
462 void resetPossibleLoopCounter(
const Decl *D =
nullptr) {
463 getTopOfStack().PossiblyLoopCounter = D ? D->getCanonicalDecl() : D;
466 const Decl *getPossiblyLoopCunter()
const {
467 return getTopOfStack().PossiblyLoopCounter;
470 void pushFunction() {
471 assert(!IgnoredStackElements &&
472 "cannot change stack while ignoring elements");
474 assert(!isa<CapturingScopeInfo>(CurFnScope));
475 CurrentNonCapturingFunctionScope = CurFnScope;
479 assert(!IgnoredStackElements &&
480 "cannot change stack while ignoring elements");
481 if (!Stack.empty() && Stack.back().second == OldFSI) {
482 assert(Stack.back().first.empty());
485 CurrentNonCapturingFunctionScope =
nullptr;
487 if (!isa<CapturingScopeInfo>(FSI)) {
488 CurrentNonCapturingFunctionScope = FSI;
497 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
499 auto I = Criticals.find(Name.getAsString());
500 if (I != Criticals.end())
502 return std::make_pair(
nullptr, llvm::APSInt());
519 const LCDeclInfo isLoopControlVariable(
const ValueDecl *D)
const;
524 const LCDeclInfo isParentLoopControlVariable(
const ValueDecl *D)
const;
529 const LCDeclInfo isLoopControlVariable(
const ValueDecl *D,
530 unsigned Level)
const;
533 const ValueDecl *getParentLoopControlVariable(
unsigned I)
const;
536 void markDeclAsUsedInScanDirective(
ValueDecl *D) {
537 if (SharingMapTy *Stack = getSecondOnStackOrNull())
538 Stack->UsedInScanDirective.insert(D);
542 bool isUsedInScanDirective(
ValueDecl *D)
const {
543 if (
const SharingMapTy *Stack = getTopOfStackOrNull())
544 return Stack->UsedInScanDirective.contains(D);
550 DeclRefExpr *PrivateCopy =
nullptr,
unsigned Modifier = 0,
551 bool AppliedToPointee =
false);
560 const Expr *ReductionRef);
566 Expr *&TaskgroupDescriptor)
const;
571 const Expr *&ReductionRef,
572 Expr *&TaskgroupDescriptor)
const;
575 Expr *getTaskgroupReductionRef()
const {
576 assert((getTopOfStack().
Directive == OMPD_taskgroup ||
580 "taskgroup reference expression requested for non taskgroup or "
581 "parallel/worksharing directive.");
582 return getTopOfStack().TaskgroupReductionRef;
586 bool isTaskgroupReductionRef(
const ValueDecl *VD,
unsigned Level)
const {
587 return getStackElemAtLevel(Level).TaskgroupReductionRef &&
588 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
594 const DSAVarData getTopDSA(
ValueDecl *D,
bool FromParent);
596 const DSAVarData getImplicitDSA(
ValueDecl *D,
bool FromParent)
const;
598 const DSAVarData getImplicitDSA(
ValueDecl *D,
unsigned Level)
const;
605 DefaultDataSharingAttributes)>
608 bool FromParent)
const;
616 bool FromParent)
const;
623 unsigned Level,
bool NotLastprivate =
false)
const;
627 bool hasExplicitDirective(
629 unsigned Level)
const;
633 const llvm::function_ref<
bool(
636 bool FromParent)
const;
640 const SharingMapTy *Top = getTopOfStackOrNull();
641 return Top ? Top->Directive : OMPD_unknown;
644 const SharingMapTy *Top = getTopOfStackOrNull();
645 return Top ? Top->MappedDirective : OMPD_unknown;
648 SharingMapTy *Top = getTopOfStackOrNull();
650 "Before calling setCurrentDirective Top of Stack not to be NULL.");
652 Top->Directive = NewDK;
655 SharingMapTy *Top = getTopOfStackOrNull();
657 "Before calling setMappedDirective Top of Stack not to be NULL.");
659 Top->MappedDirective = NewDK;
663 assert(!isStackEmpty() &&
"No directive at specified level.");
664 return getStackElemAtLevel(Level).Directive;
668 unsigned OpenMPCaptureLevel)
const {
671 return CaptureRegions[OpenMPCaptureLevel];
675 const SharingMapTy *
Parent = getSecondOnStackOrNull();
680 void addRequiresDecl(
OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); }
683 template <
typename ClauseType>
bool hasRequiresDeclWithClause()
const {
686 return isa<ClauseType>(C);
694 bool IsDuplicate =
false;
697 for (
const OMPClause *CPrev : D->clauselists()) {
698 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
699 SemaRef.
Diag(CNew->getBeginLoc(),
700 diag::err_omp_requires_clause_redeclaration)
701 << getOpenMPClauseName(CNew->getClauseKind());
702 SemaRef.
Diag(CPrev->getBeginLoc(),
703 diag::note_omp_requires_previous_clause)
704 << getOpenMPClauseName(CPrev->getClauseKind());
715 TargetLocations.push_back(LocStart);
721 AtomicLocation = Loc;
726 SourceLocation getAtomicDirectiveLoc()
const {
return AtomicLocation; }
730 return TargetLocations;
735 getTopOfStack().DefaultAttr = DSA_none;
736 getTopOfStack().DefaultAttrLoc = Loc;
740 getTopOfStack().DefaultAttr = DSA_shared;
741 getTopOfStack().DefaultAttrLoc = Loc;
745 getTopOfStack().DefaultAttr = DSA_private;
746 getTopOfStack().DefaultAttrLoc = Loc;
750 getTopOfStack().DefaultAttr = DSA_firstprivate;
751 getTopOfStack().DefaultAttrLoc = Loc;
756 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[
Kind];
757 DMI.ImplicitBehavior = M;
763 return getTopOfStack()
764 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
767 .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
770 .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
772 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
777 return ConstructTraits;
782 ConstructTraits.append(Traits.begin(), Traits.end());
784 for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits)) {
785 llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val();
786 assert(Top == Trait &&
"Something left a trait on the stack!");
792 DefaultDataSharingAttributes getDefaultDSA(
unsigned Level)
const {
793 return getStackSize() <=
Level ? DSA_unspecified
794 : getStackElemAtLevel(Level).DefaultAttr;
796 DefaultDataSharingAttributes getDefaultDSA()
const {
797 return isStackEmpty() ? DSA_unspecified : getTopOfStack().DefaultAttr;
800 return isStackEmpty() ?
SourceLocation() : getTopOfStack().DefaultAttrLoc;
804 return isStackEmpty()
806 : getTopOfStack().DefaultmapMap[
Kind].ImplicitBehavior;
809 getDefaultmapModifierAtLevel(
unsigned Level,
811 return getStackElemAtLevel(Level).DefaultmapMap[
Kind].ImplicitBehavior;
813 bool isDefaultmapCapturedByRef(
unsigned Level,
816 getDefaultmapModifierAtLevel(Level, Kind);
817 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
818 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
819 (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
820 (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
821 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
828 case OMPC_DEFAULTMAP_scalar:
829 case OMPC_DEFAULTMAP_pointer:
831 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
832 (M == OMPC_DEFAULTMAP_MODIFIER_default);
833 case OMPC_DEFAULTMAP_aggregate:
834 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
838 llvm_unreachable(
"Unexpected OpenMPDefaultmapClauseKind enum");
840 bool mustBeFirstprivateAtLevel(
unsigned Level,
843 getDefaultmapModifierAtLevel(Level, Kind);
844 return mustBeFirstprivateBase(M, Kind);
848 return mustBeFirstprivateBase(M, Kind);
852 bool isThreadPrivate(
VarDecl *D) {
853 const DSAVarData DVar = getTopDSA(D,
false);
858 void setOrderedRegion(
bool IsOrdered,
const Expr *Param,
861 getTopOfStack().OrderedRegion.emplace(Param, Clause);
863 getTopOfStack().OrderedRegion.reset();
867 bool isOrderedRegion()
const {
868 if (
const SharingMapTy *Top = getTopOfStackOrNull())
869 return Top->OrderedRegion.has_value();
873 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam()
const {
874 if (
const SharingMapTy *Top = getTopOfStackOrNull())
875 if (Top->OrderedRegion)
876 return *Top->OrderedRegion;
877 return std::make_pair(
nullptr,
nullptr);
881 bool isParentOrderedRegion()
const {
882 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
883 return Parent->OrderedRegion.has_value();
887 std::pair<const Expr *, OMPOrderedClause *>
888 getParentOrderedRegionParam()
const {
889 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
890 if (
Parent->OrderedRegion)
891 return *
Parent->OrderedRegion;
892 return std::make_pair(
nullptr,
nullptr);
895 void setRegionHasOrderConcurrent(
bool HasOrderConcurrent) {
896 getTopOfStack().RegionHasOrderConcurrent = HasOrderConcurrent;
900 bool isParentOrderConcurrent()
const {
901 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
902 return Parent->RegionHasOrderConcurrent;
906 void setNowaitRegion(
bool IsNowait =
true) {
907 getTopOfStack().NowaitRegion = IsNowait;
911 bool isParentNowaitRegion()
const {
912 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
913 return Parent->NowaitRegion;
917 void setUntiedRegion(
bool IsUntied =
true) {
918 getTopOfStack().UntiedRegion = IsUntied;
921 bool isUntiedRegion()
const {
922 const SharingMapTy *Top = getTopOfStackOrNull();
923 return Top ? Top->UntiedRegion :
false;
926 void setParentCancelRegion(
bool Cancel =
true) {
927 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
928 Parent->CancelRegion |= Cancel;
931 bool isCancelRegion()
const {
932 const SharingMapTy *Top = getTopOfStackOrNull();
933 return Top ? Top->CancelRegion :
false;
938 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
939 Parent->PrevScanLocation = Loc;
942 bool doesParentHasScanDirective()
const {
943 const SharingMapTy *Top = getSecondOnStackOrNull();
944 return Top ? Top->PrevScanLocation.isValid() :
false;
948 const SharingMapTy *Top = getSecondOnStackOrNull();
953 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
954 Parent->PrevOrderedLocation = Loc;
957 bool doesParentHasOrderedDirective()
const {
958 const SharingMapTy *Top = getSecondOnStackOrNull();
959 return Top ? Top->PrevOrderedLocation.isValid() :
false;
963 const SharingMapTy *Top = getSecondOnStackOrNull();
968 void setAssociatedLoops(
unsigned Val) {
969 getTopOfStack().AssociatedLoops = Val;
971 getTopOfStack().HasMutipleLoops =
true;
974 unsigned getAssociatedLoops()
const {
975 const SharingMapTy *Top = getTopOfStackOrNull();
976 return Top ? Top->AssociatedLoops : 0;
979 bool hasMutipleLoops()
const {
980 const SharingMapTy *Top = getTopOfStackOrNull();
981 return Top ? Top->HasMutipleLoops :
false;
987 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
988 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
991 bool hasInnerTeamsRegion()
const {
992 return getInnerTeamsRegionLoc().
isValid();
996 const SharingMapTy *Top = getTopOfStackOrNull();
1000 Scope *getCurScope()
const {
1001 const SharingMapTy *Top = getTopOfStackOrNull();
1002 return Top ? Top->CurScope :
nullptr;
1004 void setContext(
DeclContext *DC) { getTopOfStack().Context = DC; }
1006 const SharingMapTy *Top = getTopOfStackOrNull();
1012 bool checkMappableExprComponentListsForDecl(
1013 const ValueDecl *VD,
bool CurrentRegionOnly,
1014 const llvm::function_ref<
1026 if (CurrentRegionOnly)
1029 std::advance(SI, 1);
1031 for (; SI != SE; ++SI) {
1032 auto MI = SI->MappedExprComponents.find(VD);
1033 if (MI != SI->MappedExprComponents.end())
1035 MI->second.Components)
1036 if (Check(L, MI->second.Kind))
1044 bool checkMappableExprComponentListsForDeclAtLevel(
1046 const llvm::function_ref<
1050 if (getStackSize() <= Level)
1053 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1054 auto MI = StackElem.MappedExprComponents.find(VD);
1055 if (MI != StackElem.MappedExprComponents.end())
1057 MI->second.Components)
1058 if (Check(L, MI->second.Kind))
1065 void addMappableExpressionComponents(
1069 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
1071 MEC.Components.resize(MEC.Components.size() + 1);
1072 MEC.Components.back().append(Components.begin(), Components.end());
1073 MEC.Kind = WhereFoundClauseKind;
1076 unsigned getNestingLevel()
const {
1077 assert(!isStackEmpty());
1078 return getStackSize() - 1;
1080 void addDoacrossDependClause(
OMPClause *
C,
const OperatorOffsetTy &OpsOffs) {
1081 SharingMapTy *
Parent = getSecondOnStackOrNull();
1083 Parent->DoacrossDepends.try_emplace(
C, OpsOffs);
1085 llvm::iterator_range<DoacrossClauseMapTy::const_iterator>
1086 getDoacrossDependClauses()
const {
1087 const SharingMapTy &StackElem = getTopOfStack();
1089 const DoacrossClauseMapTy &Ref = StackElem.DoacrossDepends;
1090 return llvm::make_range(Ref.begin(), Ref.end());
1092 return llvm::make_range(StackElem.DoacrossDepends.end(),
1093 StackElem.DoacrossDepends.end());
1097 void addMappedClassesQualTypes(
QualType QT) {
1098 SharingMapTy &StackElem = getTopOfStack();
1099 StackElem.MappedClassesQualTypes.insert(QT);
1103 bool isClassPreviouslyMapped(
QualType QT)
const {
1104 const SharingMapTy &StackElem = getTopOfStack();
1105 return StackElem.MappedClassesQualTypes.contains(QT);
1109 void addToParentTargetRegionLinkGlobals(
DeclRefExpr *E) {
1110 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1111 E->
getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1112 "Expected declare target link global.");
1113 for (
auto &Elem : *
this) {
1115 Elem.DeclareTargetLinkVarDecls.push_back(E);
1125 "Expected target executable directive.");
1126 return getTopOfStack().DeclareTargetLinkVarDecls;
1130 void addInnerAllocatorExpr(
Expr *E) {
1131 getTopOfStack().InnerUsedAllocators.push_back(E);
1135 return getTopOfStack().InnerUsedAllocators;
1139 void addImplicitTaskFirstprivate(
unsigned Level,
Decl *D) {
1140 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1143 bool isImplicitTaskFirstprivate(
Decl *D)
const {
1144 return getTopOfStack().ImplicitTaskFirstprivates.contains(D);
1148 void addUsesAllocatorsDecl(
const Decl *D, UsesAllocatorsDeclKind Kind) {
1149 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1153 std::optional<UsesAllocatorsDeclKind>
1154 isUsesAllocatorsDecl(
unsigned Level,
const Decl *D)
const {
1155 const SharingMapTy &StackElem = getTopOfStack();
1156 auto I = StackElem.UsesAllocatorsDecls.find(D);
1157 if (I == StackElem.UsesAllocatorsDecls.end())
1158 return std::nullopt;
1159 return I->getSecond();
1161 std::optional<UsesAllocatorsDeclKind>
1162 isUsesAllocatorsDecl(
const Decl *D)
const {
1163 const SharingMapTy &StackElem = getTopOfStack();
1164 auto I = StackElem.UsesAllocatorsDecls.find(D);
1165 if (I == StackElem.UsesAllocatorsDecls.end())
1166 return std::nullopt;
1167 return I->getSecond();
1170 void addDeclareMapperVarRef(
Expr *Ref) {
1171 SharingMapTy &StackElem = getTopOfStack();
1172 StackElem.DeclareMapperVar = Ref;
1174 const Expr *getDeclareMapperVarRef()
const {
1175 const SharingMapTy *Top = getTopOfStackOrNull();
1176 return Top ? Top->DeclareMapperVar :
nullptr;
1180 void addIteratorVarDecl(
VarDecl *VD) {
1181 SharingMapTy &StackElem = getTopOfStack();
1185 bool isIteratorVarDecl(
const VarDecl *VD)
const {
1186 const SharingMapTy *Top = getTopOfStackOrNull();
1194 const_iterator I = begin();
1195 const_iterator EndI = end();
1196 size_t StackLevel = getStackSize();
1197 for (; I != EndI; ++I) {
1198 if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1202 assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1205 for (
const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1206 if (IFD.FD == FD && IFD.StackLevel == StackLevel)
1211 bool isImplicitDefaultFirstprivateFD(
VarDecl *VD)
const {
1212 const_iterator I = begin();
1213 const_iterator EndI = end();
1214 for (; I != EndI; ++I)
1215 if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1219 for (
const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1226 iterator I = begin();
1227 const_iterator EndI = end();
1228 size_t StackLevel = getStackSize();
1229 for (; I != EndI; ++I) {
1230 if (I->DefaultAttr == DSA_private || I->DefaultAttr == DSA_firstprivate) {
1231 I->ImplicitDefaultFirstprivateFDs.emplace_back(FD, StackLevel, VD);
1236 assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1246 DKind == OMPD_unknown;
1252 if (
const auto *FE = dyn_cast<FullExpr>(E))
1253 E = FE->getSubExpr();
1255 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1256 E = MTE->getSubExpr();
1258 while (
const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1259 E = Binder->getSubExpr();
1261 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1262 E = ICE->getSubExprAsWritten();
1271 if (
const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1272 if (
const auto *ME = dyn_cast<MemberExpr>(
getExprAsWritten(CED->getInit())))
1273 D = ME->getMemberDecl();
1274 const auto *VD = dyn_cast<VarDecl>(D);
1275 const auto *FD = dyn_cast<FieldDecl>(D);
1276 if (VD !=
nullptr) {
1292DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &
Iter,
1295 auto *VD = dyn_cast<VarDecl>(D);
1296 const auto *FD = dyn_cast<FieldDecl>(D);
1298 if (
Iter == end()) {
1305 DVar.CKind = OMPC_shared;
1312 DVar.CKind = OMPC_shared;
1316 DVar.CKind = OMPC_shared;
1327 DVar.CKind = OMPC_private;
1331 DVar.DKind =
Iter->Directive;
1334 if (
Iter->SharingMap.count(D)) {
1335 const DSAInfo &
Data =
Iter->SharingMap.lookup(D);
1336 DVar.RefExpr =
Data.RefExpr.getPointer();
1337 DVar.PrivateCopy =
Data.PrivateCopy;
1338 DVar.CKind =
Data.Attributes;
1339 DVar.ImplicitDSALoc =
Iter->DefaultAttrLoc;
1340 DVar.Modifier =
Data.Modifier;
1341 DVar.AppliedToPointee =
Data.AppliedToPointee;
1349 switch (
Iter->DefaultAttr) {
1351 DVar.CKind = OMPC_shared;
1352 DVar.ImplicitDSALoc =
Iter->DefaultAttrLoc;
1356 case DSA_firstprivate:
1359 DVar.CKind = OMPC_unknown;
1361 DVar.CKind = OMPC_firstprivate;
1363 DVar.ImplicitDSALoc =
Iter->DefaultAttrLoc;
1371 DVar.CKind = OMPC_unknown;
1373 DVar.CKind = OMPC_private;
1375 DVar.ImplicitDSALoc =
Iter->DefaultAttrLoc;
1377 case DSA_unspecified:
1382 DVar.ImplicitDSALoc =
Iter->DefaultAttrLoc;
1386 DVar.CKind = OMPC_shared;
1396 DSAVarData DVarTemp;
1397 const_iterator I =
Iter, E = end();
1405 DVarTemp = getDSA(I, D);
1406 if (DVarTemp.CKind != OMPC_shared) {
1407 DVar.RefExpr =
nullptr;
1408 DVar.CKind = OMPC_firstprivate;
1411 }
while (I != E && !isImplicitTaskingRegion(I->Directive));
1413 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1422 return getDSA(++
Iter, D);
1426 const Expr *NewDE) {
1427 assert(!isStackEmpty() &&
"Data sharing attributes stack is empty");
1429 SharingMapTy &StackElem = getTopOfStack();
1430 auto It = StackElem.AlignedMap.find(D);
1431 if (It == StackElem.AlignedMap.end()) {
1432 assert(NewDE &&
"Unexpected nullptr expr to be added into aligned map");
1433 StackElem.AlignedMap[D] = NewDE;
1436 assert(It->second &&
"Unexpected nullptr expr in the aligned map");
1440const Expr *DSAStackTy::addUniqueNontemporal(
const ValueDecl *D,
1441 const Expr *NewDE) {
1442 assert(!isStackEmpty() &&
"Data sharing attributes stack is empty");
1444 SharingMapTy &StackElem = getTopOfStack();
1445 auto It = StackElem.NontemporalMap.find(D);
1446 if (It == StackElem.NontemporalMap.end()) {
1447 assert(NewDE &&
"Unexpected nullptr expr to be added into aligned map");
1448 StackElem.NontemporalMap[D] = NewDE;
1451 assert(It->second &&
"Unexpected nullptr expr in the aligned map");
1456 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1458 SharingMapTy &StackElem = getTopOfStack();
1459 StackElem.LCVMap.try_emplace(
1460 D, LCDeclInfo(StackElem.LCVMap.size() + 1,
Capture));
1463const DSAStackTy::LCDeclInfo
1464DSAStackTy::isLoopControlVariable(
const ValueDecl *D)
const {
1465 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1467 const SharingMapTy &StackElem = getTopOfStack();
1468 auto It = StackElem.LCVMap.find(D);
1469 if (It != StackElem.LCVMap.end())
1471 return {0,
nullptr};
1474const DSAStackTy::LCDeclInfo
1475DSAStackTy::isLoopControlVariable(
const ValueDecl *D,
unsigned Level)
const {
1476 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1478 for (
unsigned I = Level + 1; I > 0; --I) {
1479 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1480 auto It = StackElem.LCVMap.find(D);
1481 if (It != StackElem.LCVMap.end())
1484 return {0,
nullptr};
1487const DSAStackTy::LCDeclInfo
1488DSAStackTy::isParentLoopControlVariable(
const ValueDecl *D)
const {
1489 const SharingMapTy *
Parent = getSecondOnStackOrNull();
1490 assert(
Parent &&
"Data-sharing attributes stack is empty");
1492 auto It =
Parent->LCVMap.find(D);
1493 if (It !=
Parent->LCVMap.end())
1495 return {0,
nullptr};
1498const ValueDecl *DSAStackTy::getParentLoopControlVariable(
unsigned I)
const {
1499 const SharingMapTy *
Parent = getSecondOnStackOrNull();
1500 assert(
Parent &&
"Data-sharing attributes stack is empty");
1501 if (
Parent->LCVMap.size() < I)
1503 for (
const auto &Pair :
Parent->LCVMap)
1504 if (Pair.second.first == I)
1511 bool AppliedToPointee) {
1513 if (A == OMPC_threadprivate) {
1514 DSAInfo &
Data = Threadprivates[D];
1515 Data.Attributes = A;
1516 Data.RefExpr.setPointer(E);
1517 Data.PrivateCopy =
nullptr;
1518 Data.Modifier = Modifier;
1520 DSAInfo &
Data = getTopOfStack().SharingMap[D];
1521 assert(
Data.Attributes == OMPC_unknown || (A ==
Data.Attributes) ||
1522 (A == OMPC_firstprivate &&
Data.Attributes == OMPC_lastprivate) ||
1523 (A == OMPC_lastprivate &&
Data.Attributes == OMPC_firstprivate) ||
1524 (isLoopControlVariable(D).first && A == OMPC_private));
1525 Data.Modifier = Modifier;
1526 if (A == OMPC_lastprivate &&
Data.Attributes == OMPC_firstprivate) {
1527 Data.RefExpr.setInt(
true);
1530 const bool IsLastprivate =
1531 A == OMPC_lastprivate ||
Data.Attributes == OMPC_lastprivate;
1532 Data.Attributes = A;
1533 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1534 Data.PrivateCopy = PrivateCopy;
1535 Data.AppliedToPointee = AppliedToPointee;
1537 DSAInfo &
Data = getTopOfStack().SharingMap[PrivateCopy->
getDecl()];
1538 Data.Modifier = Modifier;
1539 Data.Attributes = A;
1540 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1541 Data.PrivateCopy =
nullptr;
1542 Data.AppliedToPointee = AppliedToPointee;
1549 StringRef Name,
const AttrVec *Attrs =
nullptr,
1564 OMPReferencedVarAttr::CreateImplicit(SemaRef.
Context, OrigRef));
1571 bool RefersToCapture =
false) {
1582 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1584 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1585 "Additional reduction info may be specified only for reduction items.");
1586 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1587 assert(ReductionData.ReductionRange.isInvalid() &&
1588 (getTopOfStack().
Directive == OMPD_taskgroup ||
1592 "Additional reduction info may be specified only once for reduction "
1594 ReductionData.set(BOK, SR);
1595 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1596 if (!TaskgroupReductionRef) {
1599 TaskgroupReductionRef =
1605 const Expr *ReductionRef) {
1607 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1609 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1610 "Additional reduction info may be specified only for reduction items.");
1611 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1612 assert(ReductionData.ReductionRange.isInvalid() &&
1613 (getTopOfStack().
Directive == OMPD_taskgroup ||
1617 "Additional reduction info may be specified only once for reduction "
1619 ReductionData.set(ReductionRef, SR);
1620 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1621 if (!TaskgroupReductionRef) {
1624 TaskgroupReductionRef =
1629const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1631 Expr *&TaskgroupDescriptor)
const {
1633 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty.");
1634 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1635 const DSAInfo &
Data = I->SharingMap.lookup(D);
1636 if (
Data.Attributes != OMPC_reduction ||
1637 Data.Modifier != OMPC_REDUCTION_task)
1639 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1640 if (!ReductionData.ReductionOp ||
1641 ReductionData.ReductionOp.is<
const Expr *>())
1642 return DSAVarData();
1643 SR = ReductionData.ReductionRange;
1644 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1645 assert(I->TaskgroupReductionRef &&
"taskgroup reduction reference "
1646 "expression for the descriptor is not "
1648 TaskgroupDescriptor = I->TaskgroupReductionRef;
1649 return DSAVarData(I->Directive, OMPC_reduction,
Data.RefExpr.getPointer(),
1650 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1653 return DSAVarData();
1656const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1658 Expr *&TaskgroupDescriptor)
const {
1660 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty.");
1661 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1662 const DSAInfo &
Data = I->SharingMap.lookup(D);
1663 if (
Data.Attributes != OMPC_reduction ||
1664 Data.Modifier != OMPC_REDUCTION_task)
1666 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1667 if (!ReductionData.ReductionOp ||
1668 !ReductionData.ReductionOp.is<
const Expr *>())
1669 return DSAVarData();
1670 SR = ReductionData.ReductionRange;
1671 ReductionRef = ReductionData.ReductionOp.get<
const Expr *>();
1672 assert(I->TaskgroupReductionRef &&
"taskgroup reduction reference "
1673 "expression for the descriptor is not "
1675 TaskgroupDescriptor = I->TaskgroupReductionRef;
1676 return DSAVarData(I->Directive, OMPC_reduction,
Data.RefExpr.getPointer(),
1677 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1680 return DSAVarData();
1683bool DSAStackTy::isOpenMPLocal(
VarDecl *D, const_iterator I)
const {
1685 for (const_iterator E = end(); I != E; ++I) {
1686 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1690 Scope *CurScope = getCurScope();
1691 while (CurScope && CurScope != TopScope && !CurScope->
isDeclScope(D))
1693 return CurScope != TopScope;
1696 if (I->Context == DC)
1705 bool AcceptIfMutable =
true,
1706 bool *IsClassType =
nullptr) {
1708 Type =
Type.getNonReferenceType().getCanonicalType();
1709 bool IsConstant =
Type.isConstant(Context);
1714 if (
const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1716 RD = CTD->getTemplatedDecl();
1719 return IsConstant && !(SemaRef.
getLangOpts().CPlusPlus && RD &&
1726 bool AcceptIfMutable =
true,
1727 bool ListItemNotVar =
false) {
1731 unsigned Diag = ListItemNotVar ? diag::err_omp_const_list_item
1732 : IsClassType ? diag::err_omp_const_not_mutable_variable
1733 : diag::err_omp_const_variable;
1734 SemaRef.
Diag(ELoc,
Diag) << getOpenMPClauseName(CKind);
1735 if (!ListItemNotVar && D) {
1736 const VarDecl *VD = dyn_cast<VarDecl>(D);
1740 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1748const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(
ValueDecl *D,
1753 auto *VD = dyn_cast<VarDecl>(D);
1754 auto TI = Threadprivates.find(D);
1755 if (TI != Threadprivates.end()) {
1756 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1757 DVar.CKind = OMPC_threadprivate;
1758 DVar.Modifier = TI->getSecond().Modifier;
1761 if (VD && VD->
hasAttr<OMPThreadPrivateDeclAttr>()) {
1764 VD->
getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1765 DVar.CKind = OMPC_threadprivate;
1766 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1773 !(VD->
hasAttr<OMPThreadPrivateDeclAttr>() &&
1780 DVar.CKind = OMPC_threadprivate;
1781 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1786 !isLoopControlVariable(D).first) {
1787 const_iterator IterTarget =
1788 std::find_if(begin(), end(), [](
const SharingMapTy &
Data) {
1791 if (IterTarget != end()) {
1792 const_iterator ParentIterTarget = IterTarget + 1;
1793 for (const_iterator
Iter = begin();
Iter != ParentIterTarget; ++
Iter) {
1794 if (isOpenMPLocal(VD,
Iter)) {
1798 DVar.CKind = OMPC_threadprivate;
1802 if (!isClauseParsingMode() || IterTarget != begin()) {
1803 auto DSAIter = IterTarget->SharingMap.find(D);
1804 if (DSAIter != IterTarget->SharingMap.end() &&
1806 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1807 DVar.CKind = OMPC_threadprivate;
1810 const_iterator End = end();
1812 std::distance(ParentIterTarget, End),
1816 IterTarget->ConstructLoc);
1817 DVar.CKind = OMPC_threadprivate;
1837 const_iterator I = begin();
1838 const_iterator EndI = end();
1839 if (FromParent && I != EndI)
1842 auto It = I->SharingMap.find(D);
1843 if (It != I->SharingMap.end()) {
1844 const DSAInfo &
Data = It->getSecond();
1845 DVar.RefExpr =
Data.RefExpr.getPointer();
1846 DVar.PrivateCopy =
Data.PrivateCopy;
1847 DVar.CKind =
Data.Attributes;
1848 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1849 DVar.DKind = I->Directive;
1850 DVar.Modifier =
Data.Modifier;
1851 DVar.AppliedToPointee =
Data.AppliedToPointee;
1856 DVar.CKind = OMPC_shared;
1863 if (SemaRef.
LangOpts.OpenMP <= 31) {
1871 DSAVarData DVarTemp = hasInnermostDSA(
1874 return C == OMPC_firstprivate ||
C == OMPC_shared;
1876 MatchesAlways, FromParent);
1877 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1880 DVar.CKind = OMPC_shared;
1887 const_iterator I = begin();
1888 const_iterator EndI = end();
1889 if (FromParent && I != EndI)
1893 auto It = I->SharingMap.find(D);
1894 if (It != I->SharingMap.end()) {
1895 const DSAInfo &
Data = It->getSecond();
1896 DVar.RefExpr =
Data.RefExpr.getPointer();
1897 DVar.PrivateCopy =
Data.PrivateCopy;
1898 DVar.CKind =
Data.Attributes;
1899 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1900 DVar.DKind = I->Directive;
1901 DVar.Modifier =
Data.Modifier;
1902 DVar.AppliedToPointee =
Data.AppliedToPointee;
1908const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(
ValueDecl *D,
1909 bool FromParent)
const {
1910 if (isStackEmpty()) {
1912 return getDSA(I, D);
1915 const_iterator StartI = begin();
1916 const_iterator EndI = end();
1917 if (FromParent && StartI != EndI)
1919 return getDSA(StartI, D);
1922const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(
ValueDecl *D,
1923 unsigned Level)
const {
1924 if (getStackSize() <= Level)
1925 return DSAVarData();
1927 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1928 return getDSA(StartI, D);
1931const DSAStackTy::DSAVarData
1934 DefaultDataSharingAttributes)>
1937 bool FromParent)
const {
1941 const_iterator I = begin();
1942 const_iterator EndI = end();
1943 if (FromParent && I != EndI)
1945 for (; I != EndI; ++I) {
1946 if (!DPred(I->Directive) &&
1947 !isImplicitOrExplicitTaskingRegion(I->Directive))
1949 const_iterator NewI = I;
1950 DSAVarData DVar = getDSA(NewI, D);
1951 if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee, I->DefaultAttr))
1957const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1960 bool FromParent)
const {
1964 const_iterator StartI = begin();
1965 const_iterator EndI = end();
1966 if (FromParent && StartI != EndI)
1968 if (StartI == EndI || !DPred(StartI->Directive))
1970 const_iterator NewI = StartI;
1971 DSAVarData DVar = getDSA(NewI, D);
1972 return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1977bool DSAStackTy::hasExplicitDSA(
1980 unsigned Level,
bool NotLastprivate)
const {
1981 if (getStackSize() <= Level)
1984 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1985 auto I = StackElem.SharingMap.find(D);
1986 if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1987 CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1988 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1991 auto LI = StackElem.LCVMap.find(D);
1992 if (LI != StackElem.LCVMap.end())
1993 return CPred(OMPC_private,
false);
1997bool DSAStackTy::hasExplicitDirective(
1999 unsigned Level)
const {
2000 if (getStackSize() <= Level)
2002 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
2003 return DPred(StackElem.Directive);
2006bool DSAStackTy::hasDirective(
2010 bool FromParent)
const {
2012 size_t Skip = FromParent ? 2 : 1;
2013 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
2015 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
2021void Sema::InitDataSharingAttributesStack() {
2022 VarDataSharingAttributesStack =
new DSAStackTy(*
this);
2025#define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
2027void Sema::pushOpenMPFunctionRegion() {
DSAStack->pushFunction(); }
2035 "Expected OpenMP device compilation.");
2041enum class FunctionEmissionStatus {
2052 "Expected OpenMP device compilation.");
2078 llvm_unreachable(
"CUDADiscarded unexpected in OpenMP device compilation");
2090 "Expected OpenMP host compilation.");
2115 if (LO.OpenMP <= 45) {
2117 return OMPC_DEFAULTMAP_scalar;
2118 return OMPC_DEFAULTMAP_aggregate;
2121 return OMPC_DEFAULTMAP_pointer;
2123 return OMPC_DEFAULTMAP_scalar;
2124 return OMPC_DEFAULTMAP_aggregate;
2128 unsigned OpenMPCaptureLevel)
const {
2129 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
2132 bool IsByRef =
true;
2138 bool IsVariableUsedInMapClause =
false;
2200 bool IsVariableAssociatedWithSection =
false;
2202 DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2204 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection,
2211 if (WhereFoundClauseKind != OMPC_map &&
2212 WhereFoundClauseKind != OMPC_has_device_addr)
2215 auto EI = MapExprComponents.rbegin();
2216 auto EE = MapExprComponents.rend();
2218 assert(EI != EE &&
"Invalid map expression!");
2220 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2221 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2226 auto Last = std::prev(EE);
2228 dyn_cast<UnaryOperator>(
Last->getAssociatedExpression());
2229 if ((UO && UO->getOpcode() == UO_Deref) ||
2230 isa<ArraySubscriptExpr>(
Last->getAssociatedExpression()) ||
2231 isa<OMPArraySectionExpr>(
Last->getAssociatedExpression()) ||
2232 isa<MemberExpr>(EI->getAssociatedExpression()) ||
2233 isa<OMPArrayShapingExpr>(
Last->getAssociatedExpression())) {
2234 IsVariableAssociatedWithSection =
true;
2243 if (IsVariableUsedInMapClause) {
2246 IsByRef = !(Ty->
isPointerType() && IsVariableAssociatedWithSection);
2251 IsByRef = (
DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2254 DSAStack->isDefaultmapCapturedByRef(
2259 return K == OMPC_reduction && !AppliedToPointee;
2267 ((IsVariableUsedInMapClause &&
2268 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2273 return K == OMPC_firstprivate ||
2274 (K == OMPC_reduction && AppliedToPointee);
2277 DSAStack->isUsesAllocatorsDecl(Level, D))) &&
2280 !(isa<OMPCapturedExprDecl>(D) && !D->
hasAttr<OMPCaptureNoInitAttr>() &&
2281 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2284 !((
DSAStack->getDefaultDSA() == DSA_firstprivate ||
2285 DSAStack->getDefaultDSA() == DSA_private) &&
2289 !
DSAStack->isLoopControlVariable(D, Level).first);
2306unsigned Sema::getOpenMPNestingLevel()
const {
2308 return DSAStack->getNestingLevel();
2318 !
DSAStack->isClauseParsingMode()) ||
2329 if (!dyn_cast<FieldDecl>(D))
2331 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2334 DefaultDataSharingAttributes DefaultAttr) {
2336 (DefaultAttr == DSA_firstprivate || DefaultAttr == DSA_private);
2340 if (DVarPrivate.CKind != OMPC_unknown)
2346 Expr *CaptureExpr,
bool WithInit,
2352 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
2355 auto *VD = dyn_cast<VarDecl>(D);
2364 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2373 DSAStackTy::DSAVarData DVarTop =
2375 if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr)
2380 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2386 if (!isa<CapturingScopeInfo>(FSI))
2388 if (
auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2394 assert(CSI &&
"Failed to find CapturedRegionScopeInfo");
2405 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2411 if (CheckScopeInfo) {
2412 bool OpenMPFound =
false;
2413 for (
unsigned I = StopAt + 1; I > 0; --I) {
2415 if (!isa<CapturingScopeInfo>(FSI))
2417 if (
auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2427 if (
DSAStack->getCurrentDirective() != OMPD_unknown &&
2428 (!
DSAStack->isClauseParsingMode() ||
2429 DSAStack->getParentDirective() != OMPD_unknown)) {
2430 auto &&Info =
DSAStack->isLoopControlVariable(D);
2433 isImplicitOrExplicitTaskingRegion(
DSAStack->getCurrentDirective())) ||
2434 (VD &&
DSAStack->isForceVarCapturing()))
2435 return VD ? VD : Info.second;
2436 DSAStackTy::DSAVarData DVarTop =
2438 if (DVarTop.CKind != OMPC_unknown &&
isOpenMPPrivate(DVarTop.CKind) &&
2440 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2446 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2454 if (VD && !VD->
hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2455 ((
DSAStack->getDefaultDSA() != DSA_none &&
2456 DSAStack->getDefaultDSA() != DSA_private &&
2457 DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2458 DVarTop.CKind == OMPC_shared))
2460 auto *FD = dyn_cast<FieldDecl>(D);
2461 if (DVarPrivate.CKind != OMPC_unknown && !VD && FD &&
2462 !DVarPrivate.PrivateCopy) {
2463 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2466 DefaultDataSharingAttributes DefaultAttr) {
2468 (DefaultAttr == DSA_firstprivate ||
2469 DefaultAttr == DSA_private);
2473 if (DVarPrivate.CKind == OMPC_unknown)
2491 *
this, FD->
getIdentifier(), ME, DVarPrivate.CKind != OMPC_private,
2495 VD = cast<VarDecl>(VDPrivateRefExpr->
getDecl());
2496 DSAStack->addImplicitDefaultFirstprivateFD(FD, VD);
2499 if (DVarPrivate.CKind != OMPC_unknown ||
2500 (VD && (
DSAStack->getDefaultDSA() == DSA_none ||
2501 DSAStack->getDefaultDSA() == DSA_private ||
2502 DSAStack->getDefaultDSA() == DSA_firstprivate)))
2503 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2508void Sema::adjustOpenMPTargetScopeIndex(
unsigned &FunctionScopesIndex,
2509 unsigned Level)
const {
2514 assert(
LangOpts.OpenMP &&
"OpenMP must be enabled.");
2520 assert(
LangOpts.OpenMP &&
"OpenMP must be enabled.");
2522 DSAStack->resetPossibleLoopCounter();
2528 unsigned CapLevel)
const {
2529 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
2530 if (
DSAStack->getCurrentDirective() != OMPD_unknown &&
2531 (!
DSAStack->isClauseParsingMode() ||
2532 DSAStack->getParentDirective() != OMPD_unknown)) {
2533 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2536 DefaultDataSharingAttributes DefaultAttr) {
2538 DefaultAttr == DSA_private;
2542 if (DVarPrivate.CKind == OMPC_private && isa<OMPCapturedExprDecl>(D) &&
2543 DSAStack->isImplicitDefaultFirstprivateFD(cast<VarDecl>(D)) &&
2544 !
DSAStack->isLoopControlVariable(D).first)
2545 return OMPC_private;
2548 bool IsTriviallyCopyable =
2558 (IsTriviallyCopyable ||
2564 return OMPC_firstprivate;
2565 DSAStackTy::DSAVarData DVar =
DSAStack->getImplicitDSA(D, Level);
2566 if (DVar.CKind != OMPC_shared &&
2567 !
DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2568 DSAStack->addImplicitTaskFirstprivate(Level, D);
2569 return OMPC_firstprivate;
2576 DSAStack->resetPossibleLoopCounter(D);
2578 return OMPC_private;
2581 DSAStack->isLoopControlVariable(D).first) &&
2586 return OMPC_private;
2588 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
2594 return OMPC_private;
2599 DSAStack->isUsesAllocatorsDecl(Level, D).value_or(
2600 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2601 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2602 return OMPC_private;
2606 (
DSAStack->isClauseParsingMode() &&
2607 DSAStack->getClauseParsingMode() == OMPC_private) ||
2612 return K == OMPD_taskgroup ||
2613 ((isOpenMPParallelDirective(K) ||
2614 isOpenMPWorksharingDirective(K)) &&
2615 !isOpenMPSimdDirective(K));
2618 DSAStack->isTaskgroupReductionRef(D, Level)))
2625 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
2628 for (
unsigned I =
DSAStack->getNestingLevel() + 1; I > Level; --I) {
2629 const unsigned NewLevel = I - 1;
2633 if (isOpenMPPrivate(K) && !AppliedToPointee) {
2641 if (
DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2651 if (
DSAStack->mustBeFirstprivateAtLevel(
2653 OMPC = OMPC_firstprivate;
2657 if (OMPC != OMPC_unknown)
2658 FD->
addAttr(OMPCaptureKindAttr::CreateImplicit(Context,
unsigned(OMPC)));
2662 unsigned CaptureLevel)
const {
2663 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
2668 const auto *VD = dyn_cast<VarDecl>(D);
2672 Regions[CaptureLevel] != OMPD_task;
2676 unsigned CaptureLevel)
const {
2677 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
2680 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
2684 DSAStackTy::DSAVarData TopDVar =
2686 unsigned NumLevels =
2691 return (NumLevels == CaptureLevel + 1 &&
2692 (TopDVar.CKind != OMPC_shared ||
2693 DSAStack->getDefaultDSA() == DSA_firstprivate));
2696 DSAStackTy::DSAVarData DVar =
DSAStack->getImplicitDSA(D, Level);
2697 if (DVar.CKind != OMPC_shared)
2699 }
while (Level > 0);
2705void Sema::DestroyDataSharingAttributesStack() {
delete DSAStack; }
2709 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2714 "Not in OpenMP declare variant scope!");
2716 OMPDeclareVariantScopes.pop_back();
2722 assert(
LangOpts.OpenMP &&
"Expected OpenMP compilation mode.");
2723 std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2726 if (
LangOpts.OpenMPIsTargetDevice &&
2727 (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host))
2730 if (!
LangOpts.OpenMPIsTargetDevice && DevTy &&
2731 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2734 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2735 if (
LangOpts.OpenMPIsTargetDevice && DevTy &&
2736 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2738 StringRef HostDevTy =
2740 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2741 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2742 diag::note_omp_marked_device_type_here)
2747 DevTy && *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2751 for (OMPDeclareVariantAttr *A :
2752 Callee->specific_attrs<OMPDeclareVariantAttr>()) {
2753 auto *DeclRefVariant = cast<DeclRefExpr>(A->getVariantFuncRef());
2754 auto *VariantFD = cast<FunctionDecl>(DeclRefVariant->getDecl());
2755 std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2756 OMPDeclareTargetDeclAttr::getDeviceType(
2757 VariantFD->getMostRecentDecl());
2758 if (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2764 Callee->hasAttr<OMPDeclareVariantAttr>() && HasHostAttr(Callee))
2768 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2769 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2770 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2771 diag::note_omp_marked_device_type_here)
2779 DSAStack->push(DKind, DirName, CurScope, Loc);
2789 DSAStack->setClauseParsingMode(OMPC_unknown);
2793static std::pair<ValueDecl *, bool>
2795 SourceRange &ERange,
bool AllowArraySection =
false,
2796 StringRef DiagType =
"");
2801 bool InscanFound =
false;
2808 if (
C->getClauseKind() != OMPC_reduction)
2810 auto *RC = cast<OMPReductionClause>(
C);
2811 if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2813 InscanLoc = RC->getModifierLoc();
2816 if (RC->getModifier() == OMPC_REDUCTION_task) {
2826 S.
Diag(RC->getModifierLoc(),
2827 diag::err_omp_reduction_task_not_parallel_or_worksharing);
2833 if (
C->getClauseKind() != OMPC_reduction)
2835 auto *RC = cast<OMPReductionClause>(
C);
2836 if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2839 : RC->getModifierLoc(),
2840 diag::err_omp_inscan_reduction_expected);
2841 S.
Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2844 for (
Expr *Ref : RC->varlists()) {
2845 assert(Ref &&
"NULL expr in OpenMP nontemporal clause.");
2848 Expr *SimpleRefExpr = Ref;
2855 S.
Diag(Ref->getExprLoc(),
2856 diag::err_omp_reduction_not_inclusive_exclusive)
2857 << Ref->getSourceRange();
2871 const DSAStackTy::DSAVarData &DVar,
2872 bool IsLoopIterVar =
false);
2880 if (
const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2882 if (
auto *Clause = dyn_cast<OMPLastprivateClause>(
C)) {
2884 for (
Expr *DE : Clause->varlists()) {
2885 if (DE->isValueDependent() || DE->isTypeDependent()) {
2886 PrivateCopies.push_back(
nullptr);
2889 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2890 auto *VD = cast<VarDecl>(DRE->getDecl());
2892 const DSAStackTy::DSAVarData DVar =
2894 if (DVar.CKind == OMPC_lastprivate) {
2901 *
this, DE->getExprLoc(),
Type.getUnqualifiedType(),
2905 PrivateCopies.push_back(
nullptr);
2909 *
this, VDPrivate, DE->
getType(), DE->getExprLoc()));
2913 PrivateCopies.push_back(
nullptr);
2916 Clause->setPrivateCopies(PrivateCopies);
2920 if (
auto *Clause = dyn_cast<OMPNontemporalClause>(
C)) {
2922 for (
Expr *RefExpr : Clause->varlists()) {
2923 assert(RefExpr &&
"NULL expr in OpenMP nontemporal clause.");
2926 Expr *SimpleRefExpr = RefExpr;
2930 PrivateRefs.push_back(RefExpr);
2935 const DSAStackTy::DSAVarData DVar =
2937 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2940 Clause->setPrivateRefs(PrivateRefs);
2943 if (
auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(
C)) {
2944 for (
unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2950 if (!VD || !isa<VarDecl>(VD))
2952 DSAStackTy::DSAVarData DVar =
2958 Expr *MapExpr =
nullptr;
2960 DSAStack->checkMappableExprComponentListsForDecl(
2966 auto MI = MapExprComponents.rbegin();
2967 auto ME = MapExprComponents.rend();
2969 MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2970 VD->getCanonicalDecl()) {
2971 MapExpr = MI->getAssociatedExpression();
2976 Diag(D.Allocator->getExprLoc(),
2977 diag::err_omp_allocator_used_in_clauses)
2982 Diag(MapExpr->getExprLoc(), diag::note_used_here)
2983 << MapExpr->getSourceRange();
2996 DiscardCleanupsInEvaluationContext();
2997 PopExpressionEvaluationContext();
3001 Expr *NumIterations,
Sema &SemaRef,
3002 Scope *S, DSAStackTy *Stack);
3011 explicit VarDeclFilterCCC(
Sema &S) : SemaRef(S) {}
3012 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
3014 if (
const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
3022 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
3023 return std::make_unique<VarDeclFilterCCC>(*
this);
3032 explicit VarOrFuncDeclFilterCCC(
Sema &S) : SemaRef(S) {}
3033 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
3035 if (ND && ((isa<VarDecl>(ND) && ND->
getKind() == Decl::Var) ||
3036 isa<FunctionDecl>(ND))) {
3043 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
3044 return std::make_unique<VarOrFuncDeclFilterCCC>(*
this);
3062 VarDeclFilterCCC CCC(*
this);
3068 ? diag::err_undeclared_var_use_suggest
3069 : diag::err_omp_expected_var_arg_suggest)
3071 VD = Corrected.getCorrectionDeclAs<
VarDecl>();
3073 Diag(
Id.getLoc(), Lookup.
empty() ? diag::err_undeclared_var_use
3074 : diag::err_omp_expected_var_arg)
3079 Diag(
Id.getLoc(), diag::err_omp_expected_var_arg) <<
Id.getName();
3088 Diag(
Id.getLoc(), diag::err_omp_global_var_arg)
3093 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3105 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3106 << getOpenMPDirectiveName(Kind) << VD;
3110 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3120 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3121 << getOpenMPDirectiveName(Kind) << VD;
3125 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3136 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3137 << getOpenMPDirectiveName(Kind) << VD;
3141 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3150 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3151 << getOpenMPDirectiveName(Kind) << VD;
3155 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3163 if (Kind == OMPD_threadprivate && VD->
isUsed() &&
3165 Diag(
Id.getLoc(), diag::err_omp_var_used)
3166 << getOpenMPDirectiveName(Kind) << VD;
3188class LocalVarRefChecker final
3194 if (
const auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
3197 diag::err_omp_local_var_in_threadprivate_init)
3199 SemaRef.Diag(VD->
getLocation(), diag::note_defined_here)
3206 bool VisitStmt(
const Stmt *S) {
3207 for (
const Stmt *Child : S->children()) {
3208 if (Child && Visit(Child))
3213 explicit LocalVarRefChecker(
Sema &SemaRef) : SemaRef(SemaRef) {}
3220 for (
Expr *RefExpr : VarList) {
3221 auto *DE = cast<DeclRefExpr>(RefExpr);
3222 auto *VD = cast<VarDecl>(DE->getDecl());
3239 diag::err_omp_threadprivate_incomplete_type)) {
3246 Diag(ILoc, diag::err_omp_ref_type_arg)
3247 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->
getType();
3251 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3259 !(VD->
hasAttr<OMPThreadPrivateDeclAttr>() &&
3264 Diag(ILoc, diag::err_omp_var_thread_local)
3269 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3277 LocalVarRefChecker Checker(*
this);
3278 if (Checker.Visit(
Init))
3282 Vars.push_back(RefExpr);
3283 DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3284 VD->
addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3287 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3290 if (!Vars.empty()) {
3298static OMPAllocateDeclAttr::AllocatorTypeTy
3301 return OMPAllocateDeclAttr::OMPNullMemAlloc;
3302 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3303 Allocator->isInstantiationDependent() ||
3304 Allocator->containsUnexpandedParameterPack())
3305 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3306 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3307 llvm::FoldingSetNodeID AEId;
3308 const Expr *AE = Allocator->IgnoreParenImpCasts();
3310 for (
int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3311 auto AllocatorKind =
static_cast<OMPAllocateDeclAttr::AllocatorTypeTy
>(I);
3312 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3313 llvm::FoldingSetNodeID DAEId;
3316 if (AEId == DAEId) {
3317 AllocatorKindRes = AllocatorKind;
3321 return AllocatorKindRes;
3326 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
Expr *Allocator) {
3327 if (!VD->
hasAttr<OMPAllocateDeclAttr>())
3329 const auto *A = VD->
getAttr<OMPAllocateDeclAttr>();
3330 Expr *PrevAllocator = A->getAllocator();
3331 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3333 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3334 if (AllocatorsMatch &&
3335 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3336 Allocator && PrevAllocator) {
3337 const Expr *AE = Allocator->IgnoreParenImpCasts();
3339 llvm::FoldingSetNodeID AEId, PAEId;
3342 AllocatorsMatch = AEId == PAEId;
3344 if (!AllocatorsMatch) {
3346 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3350 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3352 PrevAllocator->printPretty(PrevAllocatorStream,
nullptr,
3356 Allocator ? Allocator->getExprLoc() : RefExpr->
getExprLoc();
3358 Allocator ? Allocator->getSourceRange() : RefExpr->
getSourceRange();
3360 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3362 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3363 S.
Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3364 << (Allocator ? 1 : 0) << AllocatorStream.str()
3365 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3367 S.
Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3368 << PrevAllocatorRange;
3376 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3378 if (VD->
hasAttr<OMPAllocateDeclAttr>())
3387 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3388 Allocator->isInstantiationDependent() ||
3389 Allocator->containsUnexpandedParameterPack()))
3391 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.
Context, AllocatorKind,
3392 Allocator, Alignment, SR);
3395 ML->DeclarationMarkedOpenMPAllocate(VD, A);
3402 assert(Clauses.size() <= 2 &&
"Expected at most two clauses.");
3403 Expr *Alignment =
nullptr;
3404 Expr *Allocator =
nullptr;
3405 if (Clauses.empty()) {
3410 if (
LangOpts.OpenMPIsTargetDevice &&
3412 targetDiag(Loc, diag::err_expected_allocator_clause);
3415 if (
const auto *AC = dyn_cast<OMPAllocatorClause>(
C))
3416 Allocator = AC->getAllocator();
3417 else if (
const auto *AC = dyn_cast<OMPAlignClause>(
C))
3418 Alignment = AC->getAlignment();
3420 llvm_unreachable(
"Unexpected clause on allocate directive");
3422 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3425 for (
Expr *RefExpr : VarList) {
3426 auto *DE = cast<DeclRefExpr>(RefExpr);
3427 auto *VD = cast<VarDecl>(DE->getDecl());
3431 VD->
hasAttr<OMPThreadPrivateDeclAttr>() ||
3439 AllocatorKind, Allocator))
3447 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3448 Diag(Allocator->getExprLoc(),
3449 diag::err_omp_expected_predefined_allocator)
3450 << Allocator->getSourceRange();
3454 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3460 Vars.push_back(RefExpr);
3479 Diag(Loc, diag::err_omp_invalid_scope) <<
"requires";
3493 bool SkippedClauses) {
3494 if (!SkippedClauses && Assumptions.empty())
3495 Diag(Loc, diag::err_omp_no_clause_for_directive)
3496 << llvm::omp::getAllAssumeClauseOptions()
3497 << llvm::omp::getOpenMPDirectiveName(DKind);
3499 auto *AA = OMPAssumeAttr::Create(
Context, llvm::join(Assumptions,
","), Loc);
3500 if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3501 OMPAssumeScoped.push_back(AA);
3506 if (Assumptions.empty())
3509 assert(DKind == llvm::omp::Directive::OMPD_assumes &&
3510 "Unexpected omp assumption directive!");
3511 OMPAssumeGlobal.push_back(AA);
3519 while (Ctx->getLexicalParent())
3521 DeclContexts.push_back(Ctx);
3522 while (!DeclContexts.empty()) {
3524 for (
auto *SubDC : DC->
decls()) {
3525 if (SubDC->isInvalidDecl())
3527 if (
auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3528 DeclContexts.push_back(CTD->getTemplatedDecl());
3529 llvm::append_range(DeclContexts, CTD->specializations());
3532 if (
auto *DC = dyn_cast<DeclContext>(SubDC))
3533 DeclContexts.push_back(DC);
3534 if (
auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3544 OMPAssumeScoped.pop_back();
3553 DSAStack->getEncounteredTargetLocs();
3555 if (!TargetLocations.empty() || !AtomicLoc.
isInvalid()) {
3556 for (
const OMPClause *CNew : ClauseList) {
3558 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3559 isa<OMPUnifiedAddressClause>(CNew) ||
3560 isa<OMPReverseOffloadClause>(CNew) ||
3561 isa<OMPDynamicAllocatorsClause>(CNew)) {
3562 Diag(Loc, diag::err_omp_directive_before_requires)
3563 <<
"target" << getOpenMPClauseName(CNew->getClauseKind());
3565 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3569 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3570 Diag(Loc, diag::err_omp_directive_before_requires)
3571 <<
"atomic" << getOpenMPClauseName(CNew->getClauseKind());
3572 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3578 if (!
DSAStack->hasDuplicateRequiresClause(ClauseList))
3586 const DSAStackTy::DSAVarData &DVar,
3587 bool IsLoopIterVar) {
3589 SemaRef.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3590 << getOpenMPClauseName(DVar.CKind);
3594 PDSA_StaticMemberShared,
3595 PDSA_StaticLocalVarShared,
3596 PDSA_LoopIterVarPrivate,
3597 PDSA_LoopIterVarLinear,
3598 PDSA_LoopIterVarLastprivate,
3599 PDSA_ConstVarShared,
3600 PDSA_GlobalVarShared,
3601 PDSA_TaskVarFirstprivate,
3602 PDSA_LocalVarPrivate,
3604 } Reason = PDSA_Implicit;
3605 bool ReportHint =
false;
3607 auto *VD = dyn_cast<VarDecl>(D);
3608 if (IsLoopIterVar) {
3609 if (DVar.CKind == OMPC_private)
3610 Reason = PDSA_LoopIterVarPrivate;
3611 else if (DVar.CKind == OMPC_lastprivate)
3612 Reason = PDSA_LoopIterVarLastprivate;
3614 Reason = PDSA_LoopIterVarLinear;
3616 DVar.CKind == OMPC_firstprivate) {
3617 Reason = PDSA_TaskVarFirstprivate;
3618 ReportLoc = DVar.ImplicitDSALoc;
3620 Reason = PDSA_StaticLocalVarShared;
3622 Reason = PDSA_StaticMemberShared;
3624 Reason = PDSA_GlobalVarShared;
3626 Reason = PDSA_ConstVarShared;
3627 else if (VD && VD->
isLocalVarDecl() && DVar.CKind == OMPC_private) {
3629 Reason = PDSA_LocalVarPrivate;
3631 if (Reason != PDSA_Implicit) {
3632 SemaRef.
Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3633 << Reason << ReportHint
3634 << getOpenMPDirectiveName(Stack->getCurrentDirective());
3635 }
else if (DVar.ImplicitDSALoc.isValid()) {
3636 SemaRef.
Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3637 << getOpenMPClauseName(DVar.CKind);
3643 bool IsAggregateOrDeclareTarget) {
3646 case OMPC_DEFAULTMAP_MODIFIER_alloc:
3647 Kind = OMPC_MAP_alloc;
3649 case OMPC_DEFAULTMAP_MODIFIER_to:
3652 case OMPC_DEFAULTMAP_MODIFIER_from:
3653 Kind = OMPC_MAP_from;
3655 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3656 Kind = OMPC_MAP_tofrom;
3658 case OMPC_DEFAULTMAP_MODIFIER_present:
3664 Kind = OMPC_MAP_alloc;
3666 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3668 llvm_unreachable(
"Unexpected defaultmap implicit behavior");
3669 case OMPC_DEFAULTMAP_MODIFIER_none:
3670 case OMPC_DEFAULTMAP_MODIFIER_default:
3675 if (IsAggregateOrDeclareTarget) {
3676 Kind = OMPC_MAP_tofrom;
3679 llvm_unreachable(
"Unexpected defaultmap implicit behavior");
3686class DSAAttrChecker final :
public StmtVisitor<DSAAttrChecker, void> {
3689 bool ErrorFound =
false;
3690 bool TryCaptureCXXThisMembers =
false;
3697 ImplicitMapModifier[DefaultmapKindNum];
3699 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3703 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3705 if (S->getDirectiveKind() == OMPD_atomic ||
3706 S->getDirectiveKind() == OMPD_critical ||
3707 S->getDirectiveKind() == OMPD_section ||
3708 S->getDirectiveKind() == OMPD_master ||
3709 S->getDirectiveKind() == OMPD_masked ||
3710 S->getDirectiveKind() == OMPD_scope ||
3712 Visit(S->getAssociatedStmt());
3715 visitSubCaptures(S->getInnermostCapturedStmt());
3718 if (TryCaptureCXXThisMembers ||
3720 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3722 return C.capturesThis();
3724 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3725 TryCaptureCXXThisMembers =
true;
3726 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3727 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3734 if (
auto *FC = dyn_cast<OMPFirstprivateClause>(
C)) {
3735 for (
Expr *Ref : FC->varlists())
3747 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
3750 !Stack->getTopDSA(VD,
false).RefExpr &&
3751 !Stack->isImplicitDefaultFirstprivateFD(VD))) {
3752 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3753 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3754 Visit(CED->getInit());
3757 }
else if (VD->
isImplicit() || isa<OMPCapturedExprDecl>(VD))
3760 if (!Stack->isImplicitDefaultFirstprivateFD(VD))
3765 !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3766 !Stack->isImplicitTaskFirstprivate(VD))
3769 if (Stack->isUsesAllocatorsDecl(VD))
3772 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD,
false);
3774 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3778 std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3779 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3782 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3783 !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3784 !Stack->isImplicitTaskFirstprivate(VD))
3793 if (DVar.CKind == OMPC_unknown &&
3794 (Stack->getDefaultDSA() == DSA_none ||
3795 Stack->getDefaultDSA() == DSA_private ||
3796 Stack->getDefaultDSA() == DSA_firstprivate) &&
3797 isImplicitOrExplicitTaskingRegion(DKind) &&
3798 VarsWithInheritedDSA.count(VD) == 0) {
3799 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3800 if (!InheritedDSA && (Stack->getDefaultDSA() == DSA_firstprivate ||
3801 Stack->getDefaultDSA() == DSA_private)) {
3802 DSAStackTy::DSAVarData DVar =
3803 Stack->getImplicitDSA(VD,
false);
3804 InheritedDSA = DVar.CKind == OMPC_unknown;
3807 VarsWithInheritedDSA[VD] = E;
3808 if (Stack->getDefaultDSA() == DSA_none)
3823 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3824 OMPC_DEFAULTMAP_MODIFIER_none;
3825 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3826 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3830 if (!Stack->checkMappableExprComponentListsForDecl(
3835 auto MI = MapExprComponents.rbegin();
3836 auto ME = MapExprComponents.rend();
3837 return MI != ME && MI->getAssociatedDeclaration() == VD;
3839 VarsWithInheritedDSA[VD] = E;
3845 bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3846 OMPC_DEFAULTMAP_MODIFIER_present;
3847 if (IsModifierPresent) {
3848 if (!llvm::is_contained(ImplicitMapModifier[ClauseKind],
3849 OMPC_MAP_MODIFIER_present)) {
3850 ImplicitMapModifier[ClauseKind].push_back(
3851 OMPC_MAP_MODIFIER_present);
3857 !Stack->isLoopControlVariable(VD).first) {
3858 if (!Stack->checkMappableExprComponentListsForDecl(
3863 if (SemaRef.LangOpts.OpenMP >= 50)
3864 return !StackComponents.empty();
3867 return StackComponents.size() == 1 ||
3869 llvm::drop_begin(llvm::reverse(StackComponents)),
3870 [](const OMPClauseMappableExprCommon::
3871 MappableComponent &MC) {
3872 return MC.getAssociatedDeclaration() ==
3874 (isa<OMPArraySectionExpr>(
3875 MC.getAssociatedExpression()) ||
3876 isa<OMPArrayShapingExpr>(
3877 MC.getAssociatedExpression()) ||
3878 isa<ArraySubscriptExpr>(
3879 MC.getAssociatedExpression()));
3882 bool IsFirstprivate =
false;
3884 if (
const auto *RD =
3886 IsFirstprivate = RD->isLambda();
3888 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3889 if (IsFirstprivate) {
3890 ImplicitFirstprivate.emplace_back(E);
3893 Stack->getDefaultmapModifier(ClauseKind);
3895 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3896 ImplicitMap[ClauseKind][
Kind].emplace_back(E);
3906 DVar = Stack->hasInnermostDSA(
3909 return C == OMPC_reduction && !AppliedToPointee;
3918 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
3924 DVar = Stack->getImplicitDSA(VD,
false);
3926 (((Stack->getDefaultDSA() == DSA_firstprivate &&
3927 DVar.CKind == OMPC_firstprivate) ||
3928 (Stack->getDefaultDSA() == DSA_private &&
3929 DVar.CKind == OMPC_private)) &&
3931 !Stack->isLoopControlVariable(VD).first) {
3932 if (Stack->getDefaultDSA() == DSA_private)
3933 ImplicitPrivate.push_back(E);
3935 ImplicitFirstprivate.push_back(E);
3942 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3943 Stack->addToParentTargetRegionLinkGlobals(E);
3957 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD,
false);
3960 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3964 !Stack->isLoopControlVariable(FD).first &&
3965 !Stack->checkMappableExprComponentListsForDecl(
3970 return isa<CXXThisExpr>(
3972 StackComponents.back().getAssociatedExpression())
3984 if (Stack->isClassPreviouslyMapped(TE->getType()))
3988 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3993 ImplicitMap[ClauseKind][
Kind].emplace_back(E);
4002 DVar = Stack->hasInnermostDSA(
4005 return C == OMPC_reduction && !AppliedToPointee;
4014 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
4020 DVar = Stack->getImplicitDSA(FD,
false);
4022 !Stack->isLoopControlVariable(FD).first) {
4027 if (DVar.CKind != OMPC_unknown)
4028 ImplicitFirstprivate.push_back(E);
4035 Stack->getCurrentDirective(),
4038 const auto *VD = cast<ValueDecl>(
4039 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
4040 if (!Stack->checkMappableExprComponentListsForDecl(
4046 auto CCI = CurComponents.rbegin();
4047 auto CCE = CurComponents.rend();
4048 for (const auto &SC : llvm::reverse(StackComponents)) {
4050 if (CCI->getAssociatedExpression()->getStmtClass() !=
4051 SC.getAssociatedExpression()->getStmtClass())
4052 if (!((isa<OMPArraySectionExpr>(
4053 SC.getAssociatedExpression()) ||
4054 isa<OMPArrayShapingExpr>(
4055 SC.getAssociatedExpression())) &&
4056 isa<ArraySubscriptExpr>(
4057 CCI->getAssociatedExpression())))
4060 const Decl *CCD = CCI->getAssociatedDeclaration();
4061 const Decl *SCD = SC.getAssociatedDeclaration();
4062 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
4063 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
4066 std::advance(CCI, 1);
4074 }
else if (!TryCaptureCXXThisMembers) {
4082 if (isa_and_nonnull<OMPPrivateClause>(
C))
4088 if (
C && !((isa<OMPFirstprivateClause>(
C) || isa<OMPMapClause>(
C)) &&
4091 for (
Stmt *CC :
C->children()) {
4098 VisitSubCaptures(S);
4107 for (
Stmt *
C : S->arguments()) {
4114 if (
Expr *Callee = S->getCallee()) {
4115 auto *CI =
Callee->IgnoreParenImpCasts();
4116 if (
auto *CE = dyn_cast<MemberExpr>(CI))
4117 Visit(CE->getBase());
4118 else if (
auto *CE = dyn_cast<DeclRefExpr>(CI))
4122 void VisitStmt(
Stmt *S) {
4123 for (
Stmt *
C : S->children()) {
4134 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
4136 VarDecl *VD = Cap.getCapturedVar();
4140 Stack->checkMappableExprComponentListsForDecl(
4147 Cap.getLocation(),
true);
4151 bool isErrorFound()
const {
return ErrorFound; }
4153 return ImplicitFirstprivate;
4158 return ImplicitMap[DK][MK];
4162 return ImplicitMapModifier[
Kind];
4165 return VarsWithInheritedDSA;
4169 : Stack(S), SemaRef(SemaRef), ErrorFound(
false), CS(CS) {
4184 Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target);
4186 Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams);
4188 Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel);
4190 Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for);
4192 Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd);
4193 Stack->handleConstructTrait(Traits, ScopeEntry);
4199 case OMPD_parallel_for:
4200 case OMPD_parallel_for_simd:
4201 case OMPD_parallel_sections:
4202 case OMPD_parallel_master:
4203 case OMPD_parallel_masked:
4204 case OMPD_parallel_loop:
4206 case OMPD_teams_distribute:
4207 case OMPD_teams_distribute_simd: {
4212 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4213 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4214 std::make_pair(StringRef(),
QualType())
4220 case OMPD_target_teams:
4221 case OMPD_target_parallel:
4222 case OMPD_target_parallel_for:
4223 case OMPD_target_parallel_for_simd:
4224 case OMPD_target_parallel_loop:
4225 case OMPD_target_teams_distribute:
4226 case OMPD_target_teams_distribute_simd: {
4236 std::make_pair(
".global_tid.", KmpInt32Ty),
4237 std::make_pair(
".part_id.", KmpInt32PtrTy),
4238 std::make_pair(
".privates.", VoidPtrTy),
4243 std::make_pair(StringRef(),
QualType())
4250 AlwaysInlineAttr::CreateImplicit(
4251 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4254 ParamsTarget.push_back(std::make_pair(StringRef(
"dyn_ptr"), VoidPtrTy));
4255 ParamsTarget.push_back(
4256 std::make_pair(StringRef(),
QualType()));
4262 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4263 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4264 std::make_pair(StringRef(),
QualType())
4269 ParamsTeamsOrParallel, 2);
4273 case OMPD_target_simd: {
4283 std::make_pair(
".global_tid.", KmpInt32Ty),
4284 std::make_pair(
".part_id.", KmpInt32PtrTy),
4285 std::make_pair(
".privates.", VoidPtrTy),
4290 std::make_pair(StringRef(),
QualType())
4297 AlwaysInlineAttr::CreateImplicit(
4298 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4301 ParamsTarget.push_back(std::make_pair(StringRef(
"dyn_ptr"), VoidPtrTy));
4302 ParamsTarget.push_back(
4303 std::make_pair(StringRef(),
QualType()));
4325 case OMPD_taskgroup:
4326 case OMPD_distribute:
4327 case OMPD_distribute_simd:
4330 case OMPD_target_data:
4331 case OMPD_dispatch: {
4333 std::make_pair(StringRef(),
QualType())
4349 std::make_pair(
".global_tid.", KmpInt32Ty),
4350 std::make_pair(
".part_id.", KmpInt32PtrTy),
4351 std::make_pair(
".privates.", VoidPtrTy),
4356 std::make_pair(StringRef(),
QualType())
4363 AlwaysInlineAttr::CreateImplicit(
4364 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4368 case OMPD_taskloop_simd:
4369 case OMPD_master_taskloop:
4370 case OMPD_masked_taskloop:
4371 case OMPD_masked_taskloop_simd:
4372 case OMPD_master_taskloop_simd: {
4390 std::make_pair(
".global_tid.", KmpInt32Ty),
4391 std::make_pair(
".part_id.", KmpInt32PtrTy),
4392 std::make_pair(
".privates.", VoidPtrTy),
4397 std::make_pair(
".lb.", KmpUInt64Ty),
4398 std::make_pair(
".ub.", KmpUInt64Ty),
4399 std::make_pair(
".st.", KmpInt64Ty),
4400 std::make_pair(
".liter.", KmpInt32Ty),
4401 std::make_pair(
".reductions.", VoidPtrTy),
4402 std::make_pair(StringRef(),
QualType())
4409 AlwaysInlineAttr::CreateImplicit(
4410 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4413 case OMPD_parallel_masked_taskloop:
4414 case OMPD_parallel_masked_taskloop_simd:
4415 case OMPD_parallel_master_taskloop:
4416 case OMPD_parallel_master_taskloop_simd: {
4430 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4431 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4432 std::make_pair(StringRef(),
QualType())
4442 std::make_pair(
".global_tid.", KmpInt32Ty),
4443 std::make_pair(
".part_id.", KmpInt32PtrTy),
4444 std::make_pair(
".privates.", VoidPtrTy),
4449 std::make_pair(
".lb.", KmpUInt64Ty),
4450 std::make_pair(
".ub.", KmpUInt64Ty),
4451 std::make_pair(
".st.", KmpInt64Ty),
4452 std::make_pair(
".liter.", KmpInt32Ty),
4453 std::make_pair(
".reductions.", VoidPtrTy),
4454 std::make_pair(StringRef(),
QualType())
4461 AlwaysInlineAttr::CreateImplicit(
4462 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4465 case OMPD_distribute_parallel_for_simd:
4466 case OMPD_distribute_parallel_for: {
4471 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4472 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4475 std::make_pair(StringRef(),
QualType())
4481 case OMPD_target_teams_loop:
4482 case OMPD_target_teams_distribute_parallel_for:
4483 case OMPD_target_teams_distribute_parallel_for_simd: {
4494 std::make_pair(
".global_tid.", KmpInt32Ty),
4495 std::make_pair(
".part_id.", KmpInt32PtrTy),
4496 std::make_pair(
".privates.", VoidPtrTy),
4501 std::make_pair(StringRef(),
QualType())
4508 AlwaysInlineAttr::CreateImplicit(
4509 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4512 ParamsTarget.push_back(std::make_pair(StringRef(
"dyn_ptr"), VoidPtrTy));
4513 ParamsTarget.push_back(
4514 std::make_pair(StringRef(),
QualType()));
4520 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4521 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4522 std::make_pair(StringRef(),
QualType())
4529 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4530 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4533 std::make_pair(StringRef(),
QualType())
4542 case OMPD_teams_loop:
4543 case OMPD_teams_distribute_parallel_for:
4544 case OMPD_teams_distribute_parallel_for_simd: {
4550 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4551 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4552 std::make_pair(StringRef(),
QualType())
4559 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4560 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4563 std::make_pair(StringRef(),
QualType())
4571 case OMPD_target_update:
4572 case OMPD_target_enter_data:
4573 case OMPD_target_exit_data: {
4583 std::make_pair(
".global_tid.", KmpInt32Ty),
4584 std::make_pair(
".part_id.", KmpInt32PtrTy),
4585 std::make_pair(
".privates.", VoidPtrTy),
4590 std::make_pair(StringRef(),
QualType())
4597 AlwaysInlineAttr::CreateImplicit(
4598 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4601 case OMPD_threadprivate:
4603 case OMPD_taskyield:
4607 case OMPD_cancellation_point:
4612 case OMPD_declare_reduction:
4613 case OMPD_declare_mapper:
4614 case OMPD_declare_simd:
4615 case OMPD_declare_target:
4616 case OMPD_end_declare_target:
4618 case OMPD_declare_variant:
4619 case OMPD_begin_declare_variant:
4620 case OMPD_end_declare_variant:
4621 case OMPD_metadirective:
4622 llvm_unreachable(
"OpenMP Directive is not allowed");
4625 llvm_unreachable(
"Unknown OpenMP directive");
4631int Sema::getNumberOfConstructScopes(
unsigned Level)
const {
4638 return CaptureRegions.size();
4642 Expr *CaptureExpr,
bool WithInit,
4644 bool AsExpression) {
4645 assert(CaptureExpr);
4651 Ty =
C.getLValueReferenceType(Ty);
4653 Ty =
C.getPointerType(Ty);
4665 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(
C));
4676 CD = cast<OMPCapturedExprDecl>(VD);
4715class CaptureRegionUnwinderRAII {
4722 CaptureRegionUnwinderRAII(
Sema &S,
bool &ErrorFound,
4724 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4725 ~CaptureRegionUnwinderRAII() {
4728 while (--ThisCaptureLevel >= 0)
4741 DSAStack->getCurrentDirective()))) {
4743 if (
const auto *RD =
Type.getCanonicalType()
4744 .getNonReferenceType()
4746 bool SavedForceCaptureByReferenceInTargetExecutable =
4747 DSAStack->isForceCaptureByReferenceInTargetExecutable();
4748 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4750 if (RD->isLambda()) {
4751 llvm::DenseMap<const ValueDecl *, FieldDecl *> Captures;
4753 RD->getCaptureFields(Captures, ThisCapture);
4756 VarDecl *VD = cast<VarDecl>(LC.getCapturedVar());
4761 }
else if (LC.getCaptureKind() ==
LCK_This) {
4769 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4770 SavedForceCaptureByReferenceInTargetExecutable);
4780 for (
const OMPClause *Clause : Clauses) {
4782 Ordered = cast<OMPOrderedClause>(Clause);
4784 Order = cast<OMPOrderClause>(Clause);
4785 if (Order->
getKind() != OMPC_ORDER_concurrent)
4788 if (Ordered && Order)
4792 if (Ordered && Order) {
4794 diag::err_omp_simple_clause_incompatible_with_ordered)
4795 << getOpenMPClauseName(OMPC_order)
4809 if (
DSAStack->getCurrentDirective() == OMPD_atomic ||
4810 DSAStack->getCurrentDirective() == OMPD_critical ||
4811 DSAStack->getCurrentDirective() == OMPD_section ||
4812 DSAStack->getCurrentDirective() == OMPD_master ||
4813 DSAStack->getCurrentDirective() == OMPD_masked)
4816 bool ErrorFound =
false;
4817 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4818 *
this, ErrorFound,
DSAStack->getCurrentDirective());
4819 if (!S.isUsable()) {
4834 DSAStack->getCurrentDirective() == OMPD_target) &&
4838 auto *IRC = cast<OMPInReductionClause>(Clause);
4839 for (
Expr *E : IRC->taskgroup_descriptors())
4851 if (
auto *E = cast_or_null<Expr>(VarRef)) {
4855 DSAStack->setForceVarCapturing(
false);
4857 DSAStack->getCurrentDirective())) {
4858 assert(CaptureRegions.empty() &&
4859 "No captured regions in loop transformation directives.");
4860 }
else if (CaptureRegions.size() > 1 ||
4861 CaptureRegions.back() != OMPD_unknown) {
4865 if (
Expr *E =
C->getPostUpdateExpr())
4870 SC = cast<OMPScheduleClause>(Clause);
4872 OC = cast<OMPOrderedClause>(Clause);
4874 LCs.push_back(cast<OMPLinearClause>(Clause));
4885 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4890 diag::err_omp_simple_clause_incompatible_with_ordered)
4891 << getOpenMPClauseName(OMPC_schedule)
4893 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4904 Diag(
C->getBeginLoc(), diag::err_omp_linear_ordered)
4913 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
4920 unsigned CompletedRegions = 0;
4925 if (ThisCaptureRegion != OMPD_unknown) {
4933 if (CaptureRegion == ThisCaptureRegion ||
4934 CaptureRegion == OMPD_unknown) {
4935 if (
auto *DS = cast_or_null<DeclStmt>(
C->getPreInitStmt())) {
4936 for (
Decl *D : DS->decls())
4942 if (ThisCaptureRegion == OMPD_target) {
4946 if (
const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(
C)) {
4947 for (
unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4957 if (ThisCaptureRegion == OMPD_parallel) {
4961 if (
auto *RC = dyn_cast<OMPReductionClause>(
C)) {
4962 if (RC->getModifier() != OMPC_REDUCTION_inscan)
4964 for (
Expr *E : RC->copy_array_temps())
4968 if (
auto *AC = dyn_cast<OMPAlignedClause>(
C)) {
4969 for (
Expr *E : AC->varlists())
4974 if (++CompletedRegions == CaptureRegions.size())
4985 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4988 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4989 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4992 SemaRef.
Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4993 << getOpenMPDirectiveName(CancelRegion);
5003 if (Stack->getCurScope()) {
5006 bool NestingProhibited =
false;
5007 bool CloseNesting =
true;
5008 bool OrphanSeen =
false;
5011 ShouldBeInParallelRegion,
5012 ShouldBeInOrderedRegion,
5013 ShouldBeInTargetRegion,
5014 ShouldBeInTeamsRegion,
5015 ShouldBeInLoopSimdRegion,
5016 } Recommend = NoRecommend;
5017 if (SemaRef.
LangOpts.OpenMP >= 51 && Stack->isParentOrderConcurrent() &&
5018 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_loop &&
5019 CurrentRegion != OMPD_parallel &&
5021 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_order)
5022 << getOpenMPDirectiveName(CurrentRegion);
5026 ((SemaRef.
LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
5027 (SemaRef.
LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
5028 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
5029 CurrentRegion != OMPD_scan))) {
5042 SemaRef.
Diag(StartLoc, (CurrentRegion != OMPD_simd)
5043 ? diag::err_omp_prohibited_region_simd
5044 : diag::warn_omp_nesting_simd)
5045 << (SemaRef.
LangOpts.OpenMP >= 50 ? 1 : 0);
5046 return CurrentRegion != OMPD_simd;
5048 if (ParentRegion == OMPD_atomic) {
5051 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
5054 if (CurrentRegion == OMPD_section) {
5059 if (ParentRegion != OMPD_sections &&
5060 ParentRegion != OMPD_parallel_sections) {
5061 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_section_directive)
5062 << (ParentRegion != OMPD_unknown)
5063 << getOpenMPDirectiveName(ParentRegion);
5071 if (ParentRegion == OMPD_unknown &&
5073 CurrentRegion != OMPD_cancellation_point &&
5074 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
5078 if (SemaRef.
LangOpts.OpenMP >= 50 && CurrentRegion == OMPD_loop &&
5079 (BindKind == OMPC_BIND_parallel || BindKind == OMPC_BIND_teams) &&
5081 ParentRegion == OMPD_loop)) {
5082 int ErrorMsgNumber = (BindKind == OMPC_BIND_parallel) ? 1 : 4;
5083 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region)
5084 <<
true << getOpenMPDirectiveName(ParentRegion) << ErrorMsgNumber
5085 << getOpenMPDirectiveName(CurrentRegion);
5088 if (CurrentRegion == OMPD_cancellation_point ||
5089 CurrentRegion == OMPD_cancel) {
5102 !((CancelRegion == OMPD_parallel &&
5103 (ParentRegion == OMPD_parallel ||
5104 ParentRegion == OMPD_target_parallel)) ||
5105 (CancelRegion == OMPD_for &&
5106 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
5107 ParentRegion == OMPD_target_parallel_for ||
5108 ParentRegion == OMPD_distribute_parallel_for ||
5109 ParentRegion == OMPD_teams_distribute_parallel_for ||
5110 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
5111 (CancelRegion == OMPD_taskgroup &&
5112 (ParentRegion == OMPD_task ||
5114 (ParentRegion == OMPD_taskloop ||
5115 ParentRegion == OMPD_master_taskloop ||
5116 ParentRegion == OMPD_masked_taskloop ||
5117 ParentRegion == OMPD_parallel_masked_taskloop ||
5118 ParentRegion == OMPD_parallel_master_taskloop)))) ||
5119 (CancelRegion == OMPD_sections &&
5120 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
5121 ParentRegion == OMPD_parallel_sections)));
5122 OrphanSeen = ParentRegion == OMPD_unknown;
5123 }
else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
5130 }
else if (CurrentRegion == OMPD_critical && CurrentName.
getName()) {
5136 bool DeadLock = Stack->hasDirective(
5140 if (K == OMPD_critical && DNI.
getName() == CurrentName.
getName()) {
5141 PreviousCriticalLoc = Loc;
5148 SemaRef.
Diag(StartLoc,
5149 diag::err_omp_prohibited_region_critical_same_name)
5151 if (PreviousCriticalLoc.
isValid())
5152 SemaRef.
Diag(PreviousCriticalLoc,
5153 diag::note_omp_previous_critical_region);
5156 }
else if (CurrentRegion == OMPD_barrier || CurrentRegion == OMPD_scope) {
5167 ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5168 ParentRegion == OMPD_parallel_master ||
5169 ParentRegion == OMPD_parallel_masked ||
5170 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5182 ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5183 ParentRegion == OMPD_parallel_master ||
5184 ParentRegion == OMPD_parallel_masked ||
5185 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5186 Recommend = ShouldBeInParallelRegion;
5187 }
else if (CurrentRegion == OMPD_ordered) {
5196 NestingProhibited = ParentRegion == OMPD_critical ||
5199 Stack->isParentOrderedRegion());
5200 Recommend = ShouldBeInOrderedRegion;
5206 (SemaRef.
LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
5207 (SemaRef.
LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
5208 ParentRegion != OMPD_target);
5209 OrphanSeen = ParentRegion == OMPD_unknown;
5210 Recommend = ShouldBeInTargetRegion;
5211 }
else if (CurrentRegion == OMPD_scan) {
5217 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
5218 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
5219 ParentRegion != OMPD_parallel_for_simd);
5220 OrphanSeen = ParentRegion == OMPD_unknown;
5221 Recommend = ShouldBeInLoopSimdRegion;
5223 if (!NestingProhibited &&
5226 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
5238 CurrentRegion != OMPD_loop &&
5240 CurrentRegion == OMPD_atomic);
5241 Recommend = ShouldBeInParallelRegion;
5243 if (!NestingProhibited && CurrentRegion == OMPD_loop) {
5248 NestingProhibited = BindKind == OMPC_BIND_teams &&
5249 ParentRegion != OMPD_teams &&
5250 ParentRegion != OMPD_target_teams;
5251 Recommend = ShouldBeInTeamsRegion;
5253 if (!NestingProhibited &&
5259 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
5260 Recommend = ShouldBeInTeamsRegion;
5262 if (!NestingProhibited &&
5269 NestingProhibited = Stack->hasDirective(
5273 OffendingRegion = K;
5279 CloseNesting =
false;
5281 if (NestingProhibited) {
5283 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_device_directive)
5284 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
5286 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region)
5287 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
5288 << Recommend << getOpenMPDirectiveName(CurrentRegion);
5303 bool ErrorFound =
false;
5304 unsigned NamedModifiersNumber = 0;
5305 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
5306 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
5309 if (
const auto *IC = dyn_cast_or_null<OMPIfClause>(
C)) {
5313 if (FoundNameModifiers[CurNM]) {
5314 S.
Diag(
C->getBeginLoc(), diag::err_omp_more_one_clause)
5315 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
5316 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
5318 }
else if (CurNM != OMPD_unknown) {
5319 NameModifierLoc.push_back(IC->getNameModifierLoc());
5320 ++NamedModifiersNumber;
5322 FoundNameModifiers[CurNM] = IC;
5323 if (CurNM == OMPD_unknown)
5329 if (!llvm::is_contained(AllowedNameModifiers, CurNM)) {
5330 S.
Diag(IC->getNameModifierLoc(),
5331 diag::err_omp_wrong_if_directive_name_modifier)
5332 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
5339 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
5340 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
5341 S.
Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
5342 diag::err_omp_no_more_if_clause);
5345 std::string Sep(
", ");
5346 unsigned AllowedCnt = 0;
5347 unsigned TotalAllowedNum =
5348 AllowedNameModifiers.size() - NamedModifiersNumber;
5349 for (
unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
5352 if (!FoundNameModifiers[NM]) {
5354 Values += getOpenMPDirectiveName(NM);
5356 if (AllowedCnt + 2 == TotalAllowedNum)
5358 else if (AllowedCnt + 1 != TotalAllowedNum)
5363 S.
Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
5364 diag::err_omp_unnamed_if_clause)
5365 << (TotalAllowedNum > 1) << Values;
5368 S.
Diag(Loc, diag::note_omp_previous_named_if_clause);
5378 bool AllowArraySection,
5379 StringRef DiagType) {
5382 return std::make_pair(
nullptr,
true);
5394 } IsArrayExpr = NoArrayExpr;
5395 if (AllowArraySection) {
5396 if (
auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
5397 Expr *
Base = ASE->getBase()->IgnoreParenImpCasts();
5398 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base))
5399 Base = TempASE->getBase()->IgnoreParenImpCasts();
5401 IsArrayExpr = ArraySubscript;
5402 }
else if (
auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
5403 Expr *
Base = OASE->getBase()->IgnoreParenImpCasts();
5404 while (
auto *TempOASE = dyn_cast<OMPArraySectionExpr>(
Base))
5405 Base = TempOASE->getBase()->IgnoreParenImpCasts();
5406 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base))
5407 Base = TempASE->getBase()->IgnoreParenImpCasts();
5409 IsArrayExpr = OMPArraySection;
5415 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5416 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
5417 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
5419 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
5420 !isa<FieldDecl>(ME->getMemberDecl()))) {
5421 if (IsArrayExpr != NoArrayExpr) {
5422 S.
Diag(ELoc, diag::err_omp_expected_base_var_name)
5423 << IsArrayExpr << ERange;
5424 }
else if (!DiagType.empty()) {
5428 S.
Diag(ELoc, diag::err_omp_expected_var_name_member_expr_with_type)
5429 << DiagSelect << DiagType << ERange;
5433 ? diag::err_omp_expected_var_name_member_expr_or_array_item
5434 : diag::err_omp_expected_var_name_member_expr)
5437 return std::make_pair(
nullptr,
false);
5439 return std::make_pair(
5446class AllocatorChecker final :
public ConstStmtVisitor<AllocatorChecker, bool> {
5447 DSAStackTy *S =
nullptr;
5451 return S->isUsesAllocatorsDecl(E->
getDecl())
5452 .value_or(DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5453 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5455 bool VisitStmt(
const Stmt *S) {
5456 for (
const Stmt *Child : S->children()) {
5457 if (Child && Visit(Child))
5462 explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5469 "Expected non-dependent context.");
5470 auto AllocateRange =
5473 auto PrivateRange = llvm::make_filter_range(Clauses, [](
const OMPClause *
C) {
5478 if (
Cl->getClauseKind() == OMPC_private) {
5479 auto *PC = cast<OMPPrivateClause>(
Cl);
5480 I = PC->private_copies().begin();
5481 It = PC->varlist_begin();
5482 Et = PC->varlist_end();
5483 }
else if (
Cl->getClauseKind() == OMPC_firstprivate) {
5484 auto *PC = cast<OMPFirstprivateClause>(
Cl);
5485 I = PC->private_copies().begin();
5486 It = PC->varlist_begin();
5487 Et = PC->varlist_end();
5488 }
else if (
Cl->getClauseKind() == OMPC_lastprivate) {
5489 auto *PC = cast<OMPLastprivateClause>(
Cl);
5490 I = PC->private_copies().begin();
5491 It = PC->varlist_begin();
5492 Et = PC->varlist_end();
5493 }
else if (
Cl->getClauseKind() == OMPC_linear) {
5494 auto *PC = cast<OMPLinearClause>(
Cl);
5495 I = PC->privates().begin();
5496 It = PC->varlist_begin();
5497 Et = PC->varlist_end();
5498 }
else if (
Cl->getClauseKind() == OMPC_reduction) {
5499 auto *PC = cast<OMPReductionClause>(
Cl);
5500 I = PC->privates().begin();
5501 It = PC->varlist_begin();
5502 Et = PC->varlist_end();
5503 }
else if (
Cl->getClauseKind() == OMPC_task_reduction) {
5504 auto *PC = cast<OMPTaskReductionClause>(
Cl);
5505 I = PC->privates().begin();
5506 It = PC->varlist_begin();
5507 Et = PC->varlist_end();
5508 }
else if (
Cl->getClauseKind() == OMPC_in_reduction) {
5509 auto *PC = cast<OMPInReductionClause>(
Cl);
5510 I = PC->privates().begin();
5511 It = PC->varlist_begin();
5512 Et = PC->varlist_end();
5514 llvm_unreachable(
"Expected private clause.");
5516 for (
Expr *E : llvm::make_range(It, Et)) {
5523 Expr *SimpleRefExpr = E;
5526 DeclToCopy.try_emplace(Res.first,
5527 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5532 auto *AC = cast<OMPAllocateClause>(
C);
5536 AC->getAllocator()) {
5537 Expr *Allocator = AC->getAllocator();
5543 AllocatorChecker Checker(Stack);
5544 if (Checker.Visit(Allocator))
5545 S.
Diag(Allocator->getExprLoc(),
5546 diag::err_omp_allocator_not_in_uses_allocators)
5547 << Allocator->getSourceRange();
5549 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5555 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5558 S.
Diag(AC->getAllocator()->getExprLoc(),
5559 diag::warn_omp_allocate_thread_on_task_target_directive)
5560 << getOpenMPDirectiveName(Stack->getCurrentDirective());
5562 for (
Expr *E : AC->varlists()) {
5565 Expr *SimpleRefExpr = E;
5568 DSAStackTy::DSAVarData
Data = Stack->getTopDSA(VD,
false);
5571 diag::err_omp_expected_private_copy_for_allocate);
5574 VarDecl *PrivateVD = DeclToCopy[VD];
5576 AllocatorKind, AC->getAllocator()))
5579 Expr *Alignment =
nullptr;
5596 CaptureVars(
Sema &Actions) : BaseTransform(Actions) {}
5598 bool AlwaysRebuild() {
return true; }
5611 BodyStmts.push_back(NewDeclStmt);
5649 DistParam, LogicalTy,
VK_LValue, {},
nullptr,
nullptr, {},
nullptr);
5660 auto BuildVarRef = [&](
VarDecl *VD) {
5665 Ctx, llvm::APInt(Ctx.
getIntWidth(LogicalTy), 0), LogicalTy, {});
5667 Ctx, llvm::APInt(Ctx.
getIntWidth(LogicalTy), 1), LogicalTy, {});
5673 Actions.
BuildBinOp(
nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero));
5677 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5681 nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep)));
5685 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5689 Actions.
BuildUnaryOp(
nullptr, {}, UO_Minus, BuildVarRef(NewStep)));
5691 Actions.
BuildBinOp(
nullptr, {}, BO_Div, BackwardRange, NegIncAmount));
5695 {}, {}, IsNegStep, BackwardDist, ForwardDist));
5697 assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) &&
5698 "Expected one of these relational operators");
5705 nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5709 if (Rel == BO_GE || Rel == BO_GT)
5711 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5714 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5720 if (Rel == BO_LE || Rel == BO_GE) {
5732 Expr *Divisor = BuildVarRef(NewStep);
5733 if (Rel == BO_GE || Rel == BO_GT)
5736 Expr *DivisorMinusOne =
5739 Actions.
BuildBinOp(
nullptr, {}, BO_Add, Range, DivisorMinusOne));
5741 Actions.
BuildBinOp(
nullptr, {}, BO_Div, RangeRoundUp, Divisor));
5751 Actions.
getCurScope(), {}, BO_Assign, DistRef, Dist));
5752 BodyStmts.push_back(ResultAssign);
5757 return cast<CapturedStmt>(
5784 {
"Logical", LogicalTy},
5795 assert(!
Invalid &&
"Expecting capture-by-value to work.");
5800 auto *CS = cast<CapturedDecl>(Actions.
CurContext);
5804 TargetParam, LoopVarTy,
VK_LValue, {},
nullptr,
nullptr, {},
nullptr);
5807 IndvarParam, LogicalTy,
VK_LValue, {},
nullptr,
nullptr, {},
nullptr);
5810 CaptureVars Recap(Actions);
5815 Actions.
BuildBinOp(
nullptr, {}, BO_Mul, NewStep, LogicalRef));
5830 BO_Assign, TargetRef, Advanced));
5832 return cast<CapturedStmt>(
5843 if (
auto *For = dyn_cast<ForStmt>(AStmt)) {
5845 if (
auto *LCVarDeclStmt = dyn_cast<DeclStmt>(
Init)) {
5847 LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl());
5848 }
else if (
auto *LCAssign = dyn_cast<BinaryOperator>(
Init)) {
5850 assert(LCAssign->getOpcode() == BO_Assign &&
5851 "init part must be a loop variable assignment");
5852 auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS());
5853 LIVDecl = cast<VarDecl>(CounterRef->getDecl());
5855 llvm_unreachable(
"Cannot determine loop variable");
5858 Cond = For->getCond();
5859 Inc = For->getInc();
5860 }
else if (
auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) {
5861 DeclStmt *BeginStmt = RangeFor->getBeginStmt();
5863 LUVDecl = RangeFor->getLoopVariable();
5865 Cond = RangeFor->getCond();
5866 Inc = RangeFor->getInc();
5868 llvm_unreachable(
"unhandled kind of loop");
5877 if (
auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) {
5878 LHS = CondBinExpr->getLHS();
5879 RHS = CondBinExpr->getRHS();
5880 CondRel = CondBinExpr->getOpcode();
5881 }
else if (
auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) {
5882 assert(CondCXXOp->getNumArgs() == 2 &&
"Comparison should have 2 operands");
5883 LHS = CondCXXOp->getArg(0);
5884 RHS = CondCXXOp->getArg(1);
5885 switch (CondCXXOp->getOperator()) {
5886 case OO_ExclaimEqual:
5898 case OO_GreaterEqual:
5902 llvm_unreachable(
"unexpected iterator operator");
5905 llvm_unreachable(
"unexpected loop condition");
5909 cast<DeclRefExpr>(LHS->
IgnoreImplicit())->getDecl() != LIVDecl) {
5910 std::swap(LHS, RHS);
5927 if (
auto *IncUn = dyn_cast<UnaryOperator>(Inc)) {
5929 switch (IncUn->getOpcode()) {
5939 llvm_unreachable(
"unhandled unary increment operator");
5942 Ctx, llvm::APInt(Ctx.
getIntWidth(LogicalTy), Direction), LogicalTy, {});
5943 }
else if (
auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
5944 if (IncBin->getOpcode() == BO_AddAssign) {
5945 Step = IncBin->getRHS();
5946 }
else if (IncBin->getOpcode() == BO_SubAssign) {
5950 llvm_unreachable(
"unhandled binary increment operator");
5951 }
else if (
auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) {
5952 switch (CondCXXOp->getOperator()) {
5955 Ctx, llvm::APInt(Ctx.
getIntWidth(LogicalTy), 1), LogicalTy, {});
5959 Ctx, llvm::APInt(Ctx.
getIntWidth(LogicalTy), -1), LogicalTy, {});
5962 Step = CondCXXOp->getArg(1);
5966 BuildUnaryOp(
nullptr, {}, UO_Minus, CondCXXOp->getArg(1)));
5969 llvm_unreachable(
"unhandled overloaded increment operator");
5972 llvm_unreachable(
"unknown increment expression");
5977 *
this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt));
5979 {},
nullptr,
nullptr, {},
nullptr);
5981 LoopVarFunc, LVRef);
5986 if (isa<ForStmt>(AStmt) || isa<CXXForRangeStmt>(AStmt))
5993 "Loop transformation directive expected");
5994 return LoopTransform;
6001 Expr *UnresolvedMapper);
6013 for (
int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) {
6014 auto *
C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
6018 auto *MI =
C->mapperlist_begin();
6019 for (
auto I =
C->varlist_begin(), End =
C->varlist_end(); I != End;
6039 ElemType = ATy->getElementType();
6042 CanonType = ElemType;
6047 1, {CanonType,
nullptr});
6048 llvm::DenseMap<const Type *, Expr *>
Visited;
6051 while (!Types.empty()) {
6054 std::tie(BaseType, CurFD) = Types.pop_back_val();
6055 while (ParentChain.back().second == 0)
6056 ParentChain.pop_back();
6057 --ParentChain.back().second;
6073 S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
6084 Expr *BaseExpr = OE;
6085 for (
const auto &
P : ParentChain) {
6103 SubExprs.push_back(BaseExpr);
6107 bool FirstIter =
true;
6117 ParentChain.emplace_back(CurFD, 1);
6119 ++ParentChain.back().second;
6121 Types.emplace_back(FieldTy, FD);
6125 if (SubExprs.empty())
6130 nullptr,
C->getMapTypeModifiers(),
C->getMapTypeModifiersLoc(),
6131 MapperIdScopeSpec, MapperId,
C->getMapType(),
6134 Clauses.push_back(NewClause);
6147 bool UseClausesWithoutBind =
false;
6150 if (
getLangOpts().OpenMP >= 50 && Kind == OMPD_loop) {
6157 BindKind = OMPC_BIND_thread;
6159 if (ParentDirective == OMPD_unknown) {
6161 diag::err_omp_bind_required_on_loop);
6162 }
else if (ParentDirective == OMPD_parallel ||
6163 ParentDirective == OMPD_target_parallel) {
6164 BindKind = OMPC_BIND_parallel;
6165 }
else if (ParentDirective == OMPD_teams ||
6166 ParentDirective == OMPD_target_teams) {
6167 BindKind = OMPC_BIND_teams;
6174 UseClausesWithoutBind =
true;
6179 if (BindKind == OMPC_BIND_teams &&
6180 C->getClauseKind() == llvm::omp::Clause::OMPC_reduction)
6182 diag::err_omp_loop_reduction_clause);
6186 if (
C->getClauseKind() != llvm::omp::Clause::OMPC_bind)
6187 ClausesWithoutBind.push_back(
C);
6191 case OMPC_BIND_parallel:
6193 DSAStack->setCurrentDirective(OMPD_for);
6194 DSAStack->setMappedDirective(OMPD_loop);
6195 PrevMappedDirective = OMPD_loop;
6197 case OMPC_BIND_teams:
6198 Kind = OMPD_distribute;
6199 DSAStack->setCurrentDirective(OMPD_distribute);
6200 DSAStack->setMappedDirective(OMPD_loop);
6201 PrevMappedDirective = OMPD_loop;
6203 case OMPC_BIND_thread:
6205 DSAStack->setCurrentDirective(OMPD_simd);
6206 DSAStack->setMappedDirective(OMPD_loop);
6207 PrevMappedDirective = OMPD_loop;
6212 }
else if (PrevMappedDirective == OMPD_loop) {
6221 DSAStack->setMappedDirective(OMPD_loop);
6224 return UseClausesWithoutBind;
6235 bool UseClausesWithoutBind =
false;
6238 OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses))
6239 BindKind = BC->getBindKind();
6244 if (Kind == OMPD_loop || PrevMappedDirective == OMPD_loop) {
6245 UseClausesWithoutBind = mapLoopConstruct(
6246 ClausesWithoutBind, Clauses, BindKind, Kind, PrevMappedDirective,
6247 StartLoc, EndLoc, DirName, CancelRegion);
6254 BindKind, StartLoc)) {
6261 Diag(StartLoc, diag::warn_hip_omp_target_directives);
6265 bool ErrorFound =
false;
6266 if (
getLangOpts().OpenMP >= 50 && UseClausesWithoutBind) {
6267 ClausesWithImplicit.append(ClausesWithoutBind.begin(),
6268 ClausesWithoutBind.end());
6270 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
6273 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master &&
6275 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6278 DSAAttrChecker DSAChecker(
DSAStack, *
this, cast<CapturedStmt>(AStmt));
6281 while (--ThisCaptureLevel >= 0)
6282 S = cast<CapturedStmt>(S)->getCapturedStmt();
6283 DSAChecker.Visit(S);
6287 auto *CS = cast<CapturedStmt>(AStmt);
6291 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
6293 DSAChecker.visitSubCaptures(CS);
6295 if (DSAChecker.isErrorFound())
6298 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
6301 DSAChecker.getImplicitFirstprivate().begin(),
6302 DSAChecker.getImplicitFirstprivate().end());
6304 DSAChecker.getImplicitPrivate().begin(),
6305 DSAChecker.getImplicitPrivate().end());
6309 ImplicitMapModifiers[DefaultmapKindNum];
6311 ImplicitMapModifiersLoc[DefaultmapKindNum];
6315 if (
auto *DMC = dyn_cast<OMPDefaultmapClause>(
C))
6316 if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
6317 PresentModifierLocs[DMC->getDefaultmapKind()] =
6318 DMC->getDefaultmapModifierLoc();
6320 for (
unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
6322 for (
unsigned I = 0; I < OMPC_MAP_delete; ++I) {
6325 ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
6328 DSAChecker.getImplicitMapModifier(Kind);
6329 ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
6330 ImplicitModifier.end());
6331 std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
6332 ImplicitModifier.size(), PresentModifierLocs[VC]);
6336 if (
auto *IRC = dyn_cast<OMPInReductionClause>(
C)) {
6337 for (
Expr *E : IRC->taskgroup_descriptors())
6339 ImplicitFirstprivates.emplace_back(E);
6344 if (
auto *DC = dyn_cast<OMPDetachClause>(
C))
6345 ImplicitFirstprivates.push_back(DC->getEventHandler());
6347 if (!ImplicitFirstprivates.empty()) {
6351 ClausesWithImplicit.push_back(Implicit);
6352 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
6353 ImplicitFirstprivates.size();
6358 if (!ImplicitPrivates.empty()) {
6362 ClausesWithImplicit.push_back(Implicit);
6363 ErrorFound = cast<OMPPrivateClause>(Implicit)->varlist_size() !=
6364 ImplicitPrivates.size();
6373 if (
getLangOpts().OpenMP >= 50 && Kind != OMPD_target &&
6377 if (
auto *RC = dyn_cast<OMPReductionClause>(
C))
6378 for (
Expr *E : RC->varlists())
6380 ImplicitExprs.emplace_back(E);
6382 if (!ImplicitExprs.empty()) {
6388 MapperIdScopeSpec, MapperId, OMPC_MAP_tofrom,
6391 ClausesWithImplicit.emplace_back(Implicit);
6394 for (
unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
6395 int ClauseKindCnt = -1;
6398 if (ImplicitMap.empty())
6404 nullptr, ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
6405 MapperIdScopeSpec, MapperId, Kind,
true,
6408 ClausesWithImplicit.emplace_back(Implicit);
6409 ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
6420 ClausesWithImplicit);
6428 AllowedNameModifiers.push_back(OMPD_parallel);
6432 VarsWithInheritedDSA);
6434 AllowedNameModifiers.push_back(OMPD_simd);
6446 VarsWithInheritedDSA);
6450 EndLoc, VarsWithInheritedDSA);
6452 AllowedNameModifiers.push_back(OMPD_simd);
6459 assert(ClausesWithImplicit.empty() &&
6460 "No clauses are allowed for 'omp section' directive");
6468 assert(ClausesWithImplicit.empty() &&
6469 "No clauses are allowed for 'omp master' directive");
6480 case OMPD_parallel_for:
6482 EndLoc, VarsWithInheritedDSA);
6483 AllowedNameModifiers.push_back(OMPD_parallel);
6485 case OMPD_parallel_for_simd:
6487 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6488 AllowedNameModifiers.push_back(OMPD_parallel);
6490 AllowedNameModifiers.push_back(OMPD_simd);
6496 case OMPD_parallel_master:
6499 AllowedNameModifiers.push_back(OMPD_parallel);
6501 case OMPD_parallel_masked:
6504 AllowedNameModifiers.push_back(OMPD_parallel);
6506 case OMPD_parallel_sections:
6509 AllowedNameModifiers.push_back(OMPD_parallel);
6514 AllowedNameModifiers.push_back(OMPD_task);
6516 case OMPD_taskyield:
6517 assert(ClausesWithImplicit.empty() &&
6518 "No clauses are allowed for 'omp taskyield' directive");
6519 assert(AStmt ==
nullptr &&
6520 "No associated statement allowed for 'omp taskyield' directive");
6524 assert(AStmt ==
nullptr &&
6525 "No associated statement allowed for 'omp error' directive");
6529 assert(ClausesWithImplicit.empty() &&
6530 "No clauses are allowed for 'omp barrier' directive");
6531 assert(AStmt ==
nullptr &&
6532 "No associated statement allowed for 'omp barrier' directive");
6536 assert(AStmt ==
nullptr &&
6537 "No associated statement allowed for 'omp taskwait' directive");
6540 case OMPD_taskgroup:
6545 assert(AStmt ==
nullptr &&
6546 "No associated statement allowed for 'omp flush' directive");
6550 assert(AStmt ==
nullptr &&
6551 "No associated statement allowed for 'omp depobj' directive");
6555 assert(AStmt ==
nullptr &&
6556 "No associated statement allowed for 'omp scan' directive");
6574 AllowedNameModifiers.push_back(OMPD_target);
6576 case OMPD_target_parallel:
6579 AllowedNameModifiers.push_back(OMPD_target);
6580 AllowedNameModifiers.push_back(OMPD_parallel);
6582 case OMPD_target_parallel_for:
6584 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6585 AllowedNameModifiers.push_back(OMPD_target);
6586 AllowedNameModifiers.push_back(OMPD_parallel);
6588 case OMPD_cancellation_point:
6589 assert(ClausesWithImplicit.empty() &&
6590 "No clauses are allowed for 'omp cancellation point' directive");
6591 assert(AStmt ==
nullptr &&
"No associated statement allowed for 'omp "
6592 "cancellation point' directive");
6596 assert(AStmt ==
nullptr &&
6597 "No associated statement allowed for 'omp cancel' directive");
6600 AllowedNameModifiers.push_back(OMPD_cancel);
6602 case OMPD_target_data:
6605 AllowedNameModifiers.push_back(OMPD_target_data);
6607 case OMPD_target_enter_data:
6610 AllowedNameModifiers.push_back(OMPD_target_enter_data);
6612 case OMPD_target_exit_data:
6615 AllowedNameModifiers.push_back(OMPD_target_exit_data);
6619 EndLoc, VarsWithInheritedDSA);
6620 AllowedNameModifiers.push_back(OMPD_taskloop);
6622 case OMPD_taskloop_simd:
6624 EndLoc, VarsWithInheritedDSA);
6625 AllowedNameModifiers.push_back(OMPD_taskloop);
6627 AllowedNameModifiers.push_back(OMPD_simd);
6629 case OMPD_master_taskloop:
6631 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6632 AllowedNameModifiers.push_back(OMPD_taskloop);
6634 case OMPD_masked_taskloop:
6636 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6637 AllowedNameModifiers.push_back(OMPD_taskloop);
6639 case OMPD_master_taskloop_simd:
6641 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6642 AllowedNameModifiers.push_back(OMPD_taskloop);
6644 AllowedNameModifiers.push_back(OMPD_simd);
6646 case OMPD_masked_taskloop_simd:
6648 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6650 AllowedNameModifiers.push_back(OMPD_taskloop);
6651 AllowedNameModifiers.push_back(OMPD_simd);
6654 case OMPD_parallel_master_taskloop:
6656 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6657 AllowedNameModifiers.push_back(OMPD_taskloop);
6658 AllowedNameModifiers.push_back(OMPD_parallel);
6660 case OMPD_parallel_masked_taskloop:
6662 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6664 AllowedNameModifiers.push_back(OMPD_taskloop);
6665 AllowedNameModifiers.push_back(OMPD_parallel);
6668 case OMPD_parallel_master_taskloop_simd:
6670 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6671 AllowedNameModifiers.push_back(OMPD_taskloop);
6672 AllowedNameModifiers.push_back(OMPD_parallel);
6674 AllowedNameModifiers.push_back(OMPD_simd);
6676 case OMPD_parallel_masked_taskloop_simd:
6678 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6680 AllowedNameModifiers.push_back(OMPD_taskloop);
6681 AllowedNameModifiers.push_back(OMPD_parallel);
6682 AllowedNameModifiers.push_back(OMPD_simd);
6685 case OMPD_distribute:
6687 EndLoc, VarsWithInheritedDSA);
6689 case OMPD_target_update:
6692 AllowedNameModifiers.push_back(OMPD_target_update);
6694 case OMPD_distribute_parallel_for:
6696 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6697 AllowedNameModifiers.push_back(OMPD_parallel);
6699 case OMPD_distribute_parallel_for_simd:
6701 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6702 AllowedNameModifiers.push_back(OMPD_parallel);
6704 AllowedNameModifiers.push_back(OMPD_simd);
6706 case OMPD_distribute_simd:
6708 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6710 AllowedNameModifiers.push_back(OMPD_simd);
6712 case OMPD_target_parallel_for_simd:
6714 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6715 AllowedNameModifiers.push_back(OMPD_target);
6716 AllowedNameModifiers.push_back(OMPD_parallel);
6718 AllowedNameModifiers.push_back(OMPD_simd);
6720 case OMPD_target_simd:
6722 EndLoc, VarsWithInheritedDSA);
6723 AllowedNameModifiers.push_back(OMPD_target);
6725 AllowedNameModifiers.push_back(OMPD_simd);
6727 case OMPD_teams_distribute:
6729 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6731 case OMPD_teams_distribute_simd:
6733 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6735 AllowedNameModifiers.push_back(OMPD_simd);
6737 case OMPD_teams_distribute_parallel_for_simd:
6739 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6740 AllowedNameModifiers.push_back(OMPD_parallel);
6742 AllowedNameModifiers.push_back(OMPD_simd);
6744 case OMPD_teams_distribute_parallel_for:
6746 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6747 AllowedNameModifiers.push_back(OMPD_parallel);
6749 case OMPD_target_teams:
6752 AllowedNameModifiers.push_back(OMPD_target);
6754 case OMPD_target_teams_distribute:
6756 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6757 AllowedNameModifiers.push_back(OMPD_target);
6759 case OMPD_target_teams_distribute_parallel_for:
6761 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6762 AllowedNameModifiers.push_back(OMPD_target);
6763 AllowedNameModifiers.push_back(OMPD_parallel);
6765 case OMPD_target_teams_distribute_parallel_for_simd:
6767 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6768 AllowedNameModifiers.push_back(OMPD_target);
6769 AllowedNameModifiers.push_back(OMPD_parallel);
6771 AllowedNameModifiers.push_back(OMPD_simd);
6773 case OMPD_target_teams_distribute_simd:
6775 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6776 AllowedNameModifiers.push_back(OMPD_target);
6778 AllowedNameModifiers.push_back(OMPD_simd);
6781 assert(AStmt ==
nullptr &&
6782 "No associated statement allowed for 'omp interop' directive");
6791 EndLoc, VarsWithInheritedDSA);
6793 case OMPD_teams_loop:
6795 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6797 case OMPD_target_teams_loop:
6799 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6800 AllowedNameModifiers.push_back(OMPD_target);
6802 case OMPD_parallel_loop:
6804 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6806 case OMPD_target_parallel_loop:
6808 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6810 case OMPD_declare_target:
6811 case OMPD_end_declare_target:
6812 case OMPD_threadprivate:
6814 case OMPD_declare_reduction:
6815 case OMPD_declare_mapper:
6816 case OMPD_declare_simd:
6818 case OMPD_declare_variant:
6819 case OMPD_begin_declare_variant:
6820 case OMPD_end_declare_variant:
6821 llvm_unreachable(
"OpenMP Directive is not allowed");
6824 llvm_unreachable(
"Unknown OpenMP directive");
6827 ErrorFound = Res.
isInvalid() || ErrorFound;
6831 if (
DSAStack->getDefaultDSA() == DSA_none ||
6832 DSAStack->getDefaultDSA() == DSA_private ||
6833 DSAStack->getDefaultDSA() == DSA_firstprivate) {
6834 DSAAttrChecker DSAChecker(
DSAStack, *
this,
nullptr);
6836 switch (
C->getClauseKind()) {
6837 case OMPC_num_threads:
6838 case OMPC_dist_schedule:
6845 cast<OMPIfClause>(
C)->getNameModifier() != OMPD_target)
6849 cast<OMPIfClause>(
C)->getNameModifier() != OMPD_parallel)
6855 case OMPC_grainsize:
6856 case OMPC_num_tasks:
6859 case OMPC_novariants:
6860 case OMPC_nocontext:
6867 case OMPC_num_teams:
6868 case OMPC_thread_limit:
6875 case OMPC_proc_bind:
6877 case OMPC_firstprivate:
6878 case OMPC_lastprivate:
6880 case OMPC_reduction:
6881 case OMPC_task_reduction:
6882 case OMPC_in_reduction:
6886 case OMPC_copyprivate:
6889 case OMPC_mergeable:
6906 case OMPC_defaultmap:
6909 case OMPC_use_device_ptr:
6910 case OMPC_use_device_addr:
6911 case OMPC_is_device_ptr:
6912 case OMPC_has_device_addr:
6913 case OMPC_nontemporal:
6916 case OMPC_inclusive:
6917 case OMPC_exclusive:
6918 case OMPC_uses_allocators:
6923 case OMPC_allocator:
6926 case OMPC_threadprivate:
6929 case OMPC_unified_address:
6930 case OMPC_unified_shared_memory:
6931 case OMPC_reverse_offload:
6932 case OMPC_dynamic_allocators:
6933 case OMPC_atomic_default_mem_order:
6934 case OMPC_device_type:
6941 llvm_unreachable(
"Unexpected clause");
6943 for (
Stmt *CC :
C->children()) {
6945 DSAChecker.Visit(CC);
6948 for (
const auto &
P : DSAChecker.getVarsWithInheritedDSA())
6949 VarsWithInheritedDSA[
P.getFirst()] =
P.getSecond();
6951 for (
const auto &
P : VarsWithInheritedDSA) {
6952 if (
P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(
P.getFirst()))
6955 if (
DSAStack->getDefaultDSA() == DSA_none ||
6956 DSAStack->getDefaultDSA() == DSA_private ||
6957 DSAStack->getDefaultDSA() == DSA_firstprivate) {
6958 Diag(
P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
6959 <<
P.first <<
P.second->getSourceRange();
6960 Diag(
DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
6962 Diag(
P.second->getExprLoc(),
6963 diag::err_omp_defaultmap_no_attr_for_variable)
6964 <<
P.first <<
P.second->getSourceRange();
6966 diag::note_omp_defaultmap_attr_none);
6970 if (!AllowedNameModifiers.empty())
6971 ErrorFound =
checkIfClauses(*
this, Kind, Clauses, AllowedNameModifiers) ||
6984 DSAStack->addTargetDirLocation(StartLoc);
6995 assert(Aligneds.size() == Alignments.size());
6996 assert(Linears.size() == LinModifiers.size());
6997 assert(Linears.size() == Steps.size());
6998 if (!DG || DG.
get().isNull())
7001 const int SimdId = 0;
7002 if (!DG.
get().isSingleDecl()) {
7003 Diag(SR.
getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
7007 Decl *ADecl = DG.
get().getSingleDecl();
7008 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
7009 ADecl = FTD->getTemplatedDecl();
7011 auto *FD = dyn_cast<FunctionDecl>(ADecl);
7013 Diag(ADecl->
getLocation(), diag::err_omp_function_expected) << SimdId;
7029 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
7030 const Expr *UniformedLinearThis =
nullptr;
7031 for (
const Expr *E : Uniforms) {
7033 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
7034 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
7035 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7036 FD->getParamDecl(PVD->getFunctionScopeIndex())
7038 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
7041 if (isa<CXXThisExpr>(E)) {
7042 UniformedLinearThis = E;
7046 << FD->
getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
7056 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
7057 const Expr *AlignedThis =
nullptr;
7058 for (
const Expr *E : Aligneds) {
7060 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
7061 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7063 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7064 FD->getParamDecl(PVD->getFunctionScopeIndex())
7068 if (AlignedArgs.count(CanonPVD) > 0) {
7070 << 1 << getOpenMPClauseName(OMPC_aligned)
7072 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
7073 diag::note_omp_explicit_dsa)
7074 << getOpenMPClauseName(OMPC_aligned);
7077 AlignedArgs[CanonPVD] = E;
7079 .getNonReferenceType()
7080 .getUnqualifiedType()
7081 .getCanonicalType();
7084 Diag(E->
getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
7086 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
7091 if (isa<CXXThisExpr>(E)) {
7094 << 2 << getOpenMPClauseName(OMPC_aligned) << E->
getSourceRange();
7096 << getOpenMPClauseName(OMPC_aligned);
7102 << FD->
getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
7109 for (
Expr *E : Alignments) {
7113 NewAligns.push_back(Align.
get());
7124 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
7125 const bool IsUniformedThis = UniformedLinearThis !=
nullptr;
7126 auto MI = LinModifiers.begin();
7127 for (
const Expr *E : Linears) {
7131 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
7132 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7134 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7135 FD->getParamDecl(PVD->getFunctionScopeIndex())
7139 if (LinearArgs.count(CanonPVD) > 0) {
7141 << getOpenMPClauseName(OMPC_linear)
7143 Diag(LinearArgs[CanonPVD]->getExprLoc(),
7144 diag::note_omp_explicit_dsa)
7145 << getOpenMPClauseName(OMPC_linear);
7149 if (UniformedArgs.count(CanonPVD) > 0) {
7151 << getOpenMPClauseName(OMPC_linear)
7153 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
7154 diag::note_omp_explicit_dsa)
7155 << getOpenMPClauseName(OMPC_uniform);
7158 LinearArgs[CanonPVD] = E;
7164 PVD->getOriginalType(),
7169 if (isa<CXXThisExpr>(E)) {
7170 if (UniformedLinearThis) {
7172 << getOpenMPClauseName(OMPC_linear)
7173 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
7175 Diag(UniformedLinearThis->
getExprLoc(), diag::note_omp_explicit_dsa)
7176 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
7180 UniformedLinearThis = E;
7189 << FD->
getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
7191 Expr *Step =
nullptr;
7192 Expr *NewStep =
nullptr;
7194 for (
Expr *E : Steps) {
7196 if (Step == E || !E) {
7197 NewSteps.push_back(E ? NewStep :
nullptr);
7201 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Step))
7202 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7204 if (UniformedArgs.count(CanonPVD) == 0) {
7211 NewSteps.push_back(Step);
7228 NewSteps.push_back(NewStep);
7230 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
7232 Uniforms.size(),
const_cast<Expr **
>(Aligneds.data()), Aligneds.size(),
7233 const_cast<Expr **
>(NewAligns.data()), NewAligns.size(),
7234 const_cast<Expr **
>(Linears.data()), Linears.size(),
7235 const_cast<unsigned *
>(LinModifiers.data()), LinModifiers.size(),
7236 NewSteps.data(), NewSteps.size(), SR);
7244 "Expected function type with prototype.");
7246 "Expected function with type with no prototype.");
7248 "Expected function with prototype.");
7256 Param->setScopeInfo(0, Params.size());
7257 Param->setImplicit();
7258 Params.push_back(Param);
7261 FD->setParams(Params);
7268 if (
auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7269 FD = UTemplDecl->getTemplatedDecl();
7271 FD = cast<FunctionDecl>(D);
7272 assert(FD &&
"Expected a function declaration!");
7278 for (OMPAssumeAttr *AA : OMPAssumeScoped)
7281 for (OMPAssumeAttr *AA : OMPAssumeGlobal)
7285Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(
OMPTraitInfo &TI)
7286 : TI(&TI), NameSuffix(TI.getMangledName()) {}
7294 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7297 bool IsTemplated = !TemplateParamLists.empty();
7299 !DVScope.TI->isExtensionActive(
7300 llvm::omp::TraitProperty::implementation_extension_allow_templates))
7316 for (
auto *Candidate : Lookup) {
7317 auto *CandidateDecl = Candidate->getUnderlyingDecl();
7319 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) {
7320 auto *FTD = cast<FunctionTemplateDecl>(CandidateDecl);
7321 if (FTD->getTemplateParameters()->size() == TemplateParamLists.size())
7322 UDecl = FTD->getTemplatedDecl();
7323 }
else if (!IsTemplated)
7324 UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
7338 FType, UDeclTy,
false,
7345 Bases.push_back(UDecl);
7348 bool UseImplicitBase = !DVScope.TI->isExtensionActive(
7349 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
7351 if (Bases.empty() && UseImplicitBase) {
7355 if (
auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
7356 Bases.push_back(BaseTemplD->getTemplatedDecl());
7358 Bases.push_back(cast<FunctionDecl>(BaseD));
7361 std::string MangledName;
7364 MangledName += DVScope.NameSuffix;
7379 if (
auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7380 FD = UTemplDecl->getTemplatedDecl();
7382 FD = cast<FunctionDecl>(D);
7389 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7390 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
7391 Context, VariantFuncRef, DVScope.TI,
7396 BaseFD->addAttr(OMPDeclareVariantA);
7414 CalleeFnDecl->
getName().starts_with_insensitive(
"omp_")) {
7417 Diag(LParenLoc, diag::err_omp_unexpected_call_to_omp_runtime_api);
7420 if (!CalleeFnDecl->
hasAttr<OMPDeclareVariantAttr>())
7424 std::function<void(StringRef)> DiagUnknownTrait = [
this,
7425 CE](StringRef ISATrait) {
7438 while (CalleeFnDecl) {
7439 for (OMPDeclareVariantAttr *A :
7441 Expr *VariantRef = A->getVariantFuncRef();
7443 VariantMatchInfo VMI;
7446 if (!isVariantApplicableInContext(VMI, OMPCtx,
7450 VMIs.push_back(VMI);
7451 Exprs.push_back(VariantRef);
7459 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
7462 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
7463 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
7479 if (
auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
7480 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
7482 Context, MemberCall->getImplicitObjectArgument(),
7484 MemberCall->getValueKind(), MemberCall->getObjectKind());
7489 if (
CallExpr *NCE = dyn_cast<CallExpr>(NewCall.
get())) {
7490 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
7492 CalleeFnType, NewCalleeFnDecl->
getType(),
7503 VMIs.erase(VMIs.begin() + BestIdx);
7504 Exprs.erase(Exprs.begin() + BestIdx);
7505 }
while (!VMIs.empty());
7512std::optional<std::pair<FunctionDecl *, Expr *>>
7515 unsigned NumAppendArgs,
7517 if (!DG || DG.
get().isNull())
7518 return std::nullopt;
7520 const int VariantId = 1;
7522 if (!DG.
get().isSingleDecl()) {
7523 Diag(SR.
getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
7525 return std::nullopt;
7527 Decl *ADecl = DG.
get().getSingleDecl();
7528 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
7529 ADecl = FTD->getTemplatedDecl();
7532 auto *FD = dyn_cast<FunctionDecl>(ADecl);
7536 return std::nullopt;
7539 auto &&HasMultiVersionAttributes = [](
const FunctionDecl *FD) {
7542 return FD->isMultiVersion() || FD->
hasAttr<TargetAttr>();
7545 if (HasMultiVersionAttributes(FD)) {
7546 Diag(FD->
getLocation(), diag::err_omp_declare_variant_incompat_attributes)
7548 return std::nullopt;
7553 Diag(SR.
getBegin(), diag::warn_omp_declare_variant_after_used)
7558 if (!FD->isThisDeclarationADefinition() && FD->isDefined(
Definition) &&
7560 Diag(SR.
getBegin(), diag::warn_omp_declare_variant_after_emitted)
7565 Diag(SR.
getBegin(), diag::err_omp_function_expected) << VariantId;
7566 return std::nullopt;
7569 auto ShouldDelayChecks = [](
Expr *&E,
bool) {
7575 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef,
false) ||
7577 return std::make_pair(FD, VariantRef);
7580 auto HandleNonConstantScoresAndConditions = [
this](
Expr *&E,
7581 bool IsScore) ->
bool {
7587 Diag(E->
getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
7595 diag::err_omp_declare_variant_user_condition_not_constant)
7601 return std::nullopt;
7604 if (NumAppendArgs) {
7607 Diag(FD->
getLocation(), diag::err_omp_declare_variant_prototype_required)
7609 return std::nullopt;
7618 TD = dyn_cast_or_null<TypeDecl>(ND);
7621 Diag(SR.
getBegin(), diag::err_omp_interop_type_not_found) << SR;
7622 return std::nullopt;
7625 if (PTy->isVariadic()) {
7626 Diag(FD->
getLocation(), diag::err_omp_append_args_with_varargs) << SR;
7627 return std::nullopt;
7630 Params.append(PTy->param_type_begin(), PTy->param_type_end());
7631 Params.insert(Params.end(), NumAppendArgs, InteropType);
7633 PTy->getExtProtoInfo());
7641 auto *Method = dyn_cast<CXXMethodDecl>(FD);
7642 if (Method && !Method->isStatic()) {
7643 const Type *ClassType =
7657 return std::nullopt;
7659 VariantRef = ER.
get();
7667 false, AllowedExplicit::None,
7673 diag::err_omp_declare_variant_incompat_types)
7675 << ((Method && !Method->isStatic()) ? FnPtrType : FD->
getType())
7677 return std::nullopt;
7682 return std::nullopt;
7685 if (Method && !Method->isStatic()) {
7686 Expr *PossibleAddrOfVariantRef = VariantRefCast.
get();
7687 if (
auto *UO = dyn_cast<UnaryOperator>(
7689 VariantRefCast = UO->getSubExpr();
7698 return std::nullopt;
7706 return std::nullopt;
7708 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
7712 return std::nullopt;
7717 diag::err_omp_declare_variant_same_base_function)
7719 return std::nullopt;
7728 diag::err_omp_declare_variant_incompat_types)
7729 << NewFD->getType() << FD->
getType() << (NumAppendArgs ? 1 : 0)
7731 return std::nullopt;
7736 else if (NewFD->getType()->isFunctionNoProtoType())
7742 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
7744 diag::warn_omp_declare_variant_marked_as_declare_variant)
7747 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->
getRange();
7748 Diag(SR.
getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
7749 return std::nullopt;
7752 enum DoesntSupport {
7761 if (
const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
7762 if (CXXFD->isVirtual()) {
7765 return std::nullopt;
7768 if (isa<CXXConstructorDecl>(FD)) {
7771 return std::nullopt;
7774 if (isa<CXXDestructorDecl>(FD)) {
7777 return std::nullopt;
7781 if (FD->isDeleted()) {
7784 return std::nullopt;
7787 if (FD->isDefaulted()) {
7790 return std::nullopt;
7793 if (FD->isConstexpr()) {
7795 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
7796 return std::nullopt;
7806 PDiag(diag::err_omp_declare_variant_doesnt_support)),
7808 PDiag(diag::err_omp_declare_variant_diff)
7812 return std::nullopt;
7813 return std::make_pair(FD, cast<Expr>(DRE));
7829 llvm::append_range(AllAdjustArgs, AdjustArgsNothing);
7830 llvm::append_range(AllAdjustArgs, AdjustArgsNeedDevicePtr);
7832 if (!AllAdjustArgs.empty() || !AppendArgs.empty()) {
7833 VariantMatchInfo VMI;
7835 if (!llvm::is_contained(
7836 VMI.ConstructTraits,
7837 llvm::omp::TraitProperty::construct_dispatch_dispatch)) {
7838 if (!AllAdjustArgs.empty())
7839 Diag(AdjustArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7840 << getOpenMPClauseName(OMPC_adjust_args);
7841 if (!AppendArgs.empty())
7842 Diag(AppendArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7843 << getOpenMPClauseName(OMPC_append_args);
7853 for (
Expr *E : AllAdjustArgs) {
7855 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
7856 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7858 if (FD->
getNumParams() > PVD->getFunctionScopeIndex() &&
7862 if (!AdjustVars.insert(CanonPVD).second) {
7863 Diag(DRE->getLocation(), diag::err_omp_adjust_arg_multiple_clauses)
7872 Diag(E->
getExprLoc(), diag::err_omp_param_or_this_in_clause) << FD << 0;
7876 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
7877 Context, VariantRef, &TI,
const_cast<Expr **
>(AdjustArgsNothing.data()),
7878 AdjustArgsNothing.size(),
7879 const_cast<Expr **
>(AdjustArgsNeedDevicePtr.data()),
7880 AdjustArgsNeedDevicePtr.size(),
7881 const_cast<OMPInteropInfo *
>(AppendArgs.data()), AppendArgs.size(), SR);
7892 auto *CS = cast<CapturedStmt>(AStmt);
7903 DSAStack->getTaskgroupReductionRef(),
7909struct LoopIterationSpace final {
7912 bool IsStrictCompare =
false;
7914 Expr *PreCond =
nullptr;
7917 Expr *NumIterations =
nullptr;
7919 Expr *CounterVar =
nullptr;
7921 Expr *PrivateCounterVar =
nullptr;
7923 Expr *CounterInit =
nullptr;
7926 Expr *CounterStep =
nullptr;
7928 bool Subtract =
false;
7938 Expr *MinValue =
nullptr;
7942 Expr *MaxValue =
nullptr;
7944 bool IsNonRectangularLB =
false;
7946 bool IsNonRectangularUB =
false;
7949 unsigned LoopDependentIdx = 0;
7953 Expr *FinalCondition =
nullptr;
7959class OpenMPIterationSpaceChecker {
7963 bool SupportsNonRectangular;
7979 Expr *LCRef =
nullptr;
7985 Expr *Step =
nullptr;
7992 std::optional<bool> TestIsLessOp;
7994 bool TestIsStrictOp =
false;
7996 bool SubtractStep =
false;
8001 std::optional<unsigned> InitDependOnLC;
8004 std::optional<unsigned> CondDependOnLC;
8006 std::optional<unsigned> doesDependOnLoopCounter(
const Stmt *S,
8007 bool IsInitializer);
8013 OpenMPIterationSpaceChecker(
Sema &SemaRef,
bool SupportsNonRectangular,
8015 : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular),
8016 Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
8019 bool checkAndSetInit(
Stmt *S,
bool EmitDiags =
true);
8022 bool checkAndSetCond(
Expr *S);
8025 bool checkAndSetInc(
Expr *S);
8027 ValueDecl *getLoopDecl()
const {
return LCDecl; }
8029 Expr *getLoopDeclRefExpr()
const {
return LCRef; }
8031 SourceRange getInitSrcRange()
const {
return InitSrcRange; }
8033 SourceRange getConditionSrcRange()
const {
return ConditionSrcRange; }
8035 SourceRange getIncrementSrcRange()
const {
return IncrementSrcRange; }
8037 bool shouldSubtractStep()
const {
return SubtractStep; }
8039 bool isStrictTestOp()
const {
return TestIsStrictOp; }
8041 Expr *buildNumIterations(
8043 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const;
8047 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const;
8050 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8051 DSAStackTy &DSA)
const;
8054 Expr *buildPrivateCounterVar()
const;
8058 Expr *buildCounterStep()
const;
8062 buildOrderedLoopData(
Scope *S,
Expr *Counter,
8063 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8067 std::pair<Expr *, Expr *> buildMinMaxValues(
8068 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const;
8070 Expr *buildFinalCondition(
Scope *S)
const;
8072 bool dependent()
const;
8074 bool doesInitDependOnLC()
const {
return InitDependOnLC.has_value(); }
8076 bool doesCondDependOnLC()
const {
return CondDependOnLC.has_value(); }
8078 unsigned getLoopDependentIdx()
const {
8079 return InitDependOnLC.value_or(CondDependOnLC.value_or(0));
8085 bool checkAndSetIncRHS(
Expr *RHS);
8090 bool setUB(
Expr *NewUB, std::optional<bool> LessOp,
bool StrictOp,
8093 bool setStep(
Expr *NewStep,
bool Subtract);
8096bool OpenMPIterationSpaceChecker::dependent()
const {
8098 assert(!LB && !UB && !Step);
8106bool OpenMPIterationSpaceChecker::setLCDeclAndLB(
ValueDecl *NewLCDecl,
8108 Expr *NewLB,
bool EmitDiags) {
8110 assert(LCDecl ==
nullptr && LB ==
nullptr && LCRef ==
nullptr &&
8111 UB ==
nullptr && Step ==
nullptr && !TestIsLessOp && !TestIsStrictOp);
8115 LCRef = NewLCRefExpr;
8116 if (
auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
8118 if ((Ctor->isCopyOrMoveConstructor() ||
8119 Ctor->isConvertingConstructor(
false)) &&
8120 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
8124 InitDependOnLC = doesDependOnLoopCounter(LB,
true);
8128bool OpenMPIterationSpaceChecker::setUB(
Expr *NewUB, std::optional<bool> LessOp,
8132 assert(LCDecl !=
nullptr && LB !=
nullptr && UB ==
nullptr &&
8133 Step ==
nullptr && !TestIsLessOp && !TestIsStrictOp);
8138 TestIsLessOp = LessOp;
8139 TestIsStrictOp = StrictOp;
8140 ConditionSrcRange = SR;
8142 CondDependOnLC = doesDependOnLoopCounter(UB,
false);
8146bool OpenMPIterationSpaceChecker::setStep(
Expr *NewStep,
bool Subtract) {
8148 assert(LCDecl !=
nullptr && LB !=
nullptr && Step ==
nullptr);
8158 NewStep = Val.
get();
8171 std::optional<llvm::APSInt>
Result =
8182 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
8183 if (UB && (IsConstZero ||
8184 (*TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
8185 : (IsConstPos || (IsUnsigned && !Subtract))))) {
8187 diag::err_omp_loop_incr_not_compatible)
8189 SemaRef.
Diag(ConditionLoc,
8190 diag::note_omp_loop_cond_requres_compatible_incr)
8191 << *TestIsLessOp << ConditionSrcRange;
8194 if (*TestIsLessOp == Subtract) {
8198 Subtract = !Subtract;
8203 SubtractStep = Subtract;
8210class LoopCounterRefChecker final
8217 bool IsInitializer =
true;
8218 bool SupportsNonRectangular;
8219 unsigned BaseLoopId = 0;
8222 SemaRef.Diag(E->
getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
8223 << (IsInitializer ? 0 : 1);
8226 const auto &&
Data = Stack.isLoopControlVariable(VD);
8232 llvm::raw_svector_ostream OS(Name);
8236 diag::err_omp_wrong_dependency_iterator_type)
8238 SemaRef.Diag(VD->
getLocation(), diag::note_previous_decl) << VD;
8241 if (
Data.first && !SupportsNonRectangular) {
8242 SemaRef.Diag(E->
getExprLoc(), diag::err_omp_invariant_dependency);
8246 (DepDecl || (PrevDepDecl &&
8248 if (!DepDecl && PrevDepDecl)
8249 DepDecl = PrevDepDecl;
8251 llvm::raw_svector_ostream OS(Name);
8255 diag::err_omp_invariant_or_linear_dependency)
8261 BaseLoopId =
Data.first;
8269 if (isa<VarDecl>(VD))
8270 return checkDecl(E, VD);
8276 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
8277 return checkDecl(E, VD);
8281 bool VisitStmt(
const Stmt *S) {
8283 for (
const Stmt *Child : S->children())
8284 Res = (Child && Visit(Child)) || Res;
8287 explicit LoopCounterRefChecker(
Sema &SemaRef, DSAStackTy &Stack,
8288 const ValueDecl *CurLCDecl,
bool IsInitializer,
8290 bool SupportsNonRectangular =
true)
8291 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
8292 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer),
8293 SupportsNonRectangular(SupportsNonRectangular) {}
8294 unsigned getBaseLoopId()
const {
8295 assert(CurLCDecl &&
"Expected loop dependency.");
8299 assert(CurLCDecl &&
"Expected loop dependency.");
8305std::optional<unsigned>
8306OpenMPIterationSpaceChecker::doesDependOnLoopCounter(
const Stmt *S,
8307 bool IsInitializer) {
8309 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
8310 DepDecl, SupportsNonRectangular);
8311 if (LoopStmtChecker.Visit(S)) {
8312 DepDecl = LoopStmtChecker.getDepDecl();
8313 return LoopStmtChecker.getBaseLoopId();
8315 return std::nullopt;
8318bool OpenMPIterationSpaceChecker::checkAndSetInit(
Stmt *S,
bool EmitDiags) {
8329 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
8333 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8334 if (!ExprTemp->cleanupsHaveSideEffects())
8335 S = ExprTemp->getSubExpr();
8337 InitSrcRange = S->getSourceRange();
8338 if (
Expr *E = dyn_cast<Expr>(S))
8340 if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
8341 if (BO->getOpcode() == BO_Assign) {
8343 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8344 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8346 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8348 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
8350 if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
8351 if (ME->isArrow() &&
8352 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8353 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8357 }
else if (
auto *DS = dyn_cast<DeclStmt>(S)) {
8358 if (DS->isSingleDecl()) {
8359 if (
auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
8360 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
8363 SemaRef.Diag(S->getBeginLoc(),
8364 diag::ext_omp_loop_not_canonical_init)
8365 << S->getSourceRange();
8366 return setLCDeclAndLB(
8369 Var->getType().getNonReferenceType(),
8371 Var->getInit(), EmitDiags);
8375 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8376 if (CE->getOperator() == OO_Equal) {
8377 Expr *LHS = CE->getArg(0);
8378 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8379 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8381 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8383 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
8385 if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
8386 if (ME->isArrow() &&
8387 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8388 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8394 if (dependent() || SemaRef.CurContext->isDependentContext())
8397 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
8398 << S->getSourceRange();
8409 if (
const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
8411 if ((Ctor->isCopyOrMoveConstructor() ||
8412 Ctor->isConvertingConstructor(
false)) &&
8413 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
8415 if (
const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
8416 if (
const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
8419 if (
const auto *ME = dyn_cast_or_null<MemberExpr>(E))
8420 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8425bool OpenMPIterationSpaceChecker::checkAndSetCond(
Expr *S) {
8432 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
8434 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
8435 << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
8441 auto &&CheckAndSetCond =
8446 if (getInitLCDecl(LHS) == LCDecl)
8447 return setUB(
const_cast<Expr *
>(RHS),
8449 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8450 if (getInitLCDecl(RHS) == LCDecl)
8451 return setUB(
const_cast<Expr *
>(LHS),
8453 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8454 }
else if (IneqCondIsCanonical && Opcode == BO_NE) {
8455 return setUB(
const_cast<Expr *
>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS),
8459 return std::nullopt;
8461 std::optional<bool> Res;
8462 if (
auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) {
8465 RBO->getOperatorLoc());
8466 }
else if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
8467 Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(),
8468 BO->getSourceRange(), BO->getOperatorLoc());
8469 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8470 if (CE->getNumArgs() == 2) {
8471 Res = CheckAndSetCond(
8473 CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc());
8478 if (dependent() || SemaRef.CurContext->isDependentContext())
8480 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
8481 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
8485bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(
Expr *RHS) {
8492 if (
auto *BO = dyn_cast<BinaryOperator>(RHS)) {
8493 if (BO->isAdditiveOp()) {
8494 bool IsAdd = BO->getOpcode() == BO_Add;
8495 if (getInitLCDecl(BO->getLHS()) == LCDecl)
8496 return setStep(BO->getRHS(), !IsAdd);
8497 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
8498 return setStep(BO->getLHS(),
false);
8500 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
8501 bool IsAdd = CE->getOperator() == OO_Plus;
8502 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
8503 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8504 return setStep(CE->getArg(1), !IsAdd);
8505 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
8506 return setStep(CE->getArg(0),
false);
8509 if (dependent() || SemaRef.CurContext->isDependentContext())
8511 SemaRef.Diag(RHS->
getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8516bool OpenMPIterationSpaceChecker::checkAndSetInc(
Expr *S) {
8531 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
8534 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8535 if (!ExprTemp->cleanupsHaveSideEffects())
8536 S = ExprTemp->getSubExpr();
8538 IncrementSrcRange = S->getSourceRange();
8539 S = S->IgnoreParens();
8540 if (
auto *UO = dyn_cast<UnaryOperator>(S)) {
8541 if (UO->isIncrementDecrementOp() &&
8542 getInitLCDecl(UO->getSubExpr()) == LCDecl)
8543 return setStep(SemaRef
8544 .ActOnIntegerConstant(UO->getBeginLoc(),
8545 (UO->isDecrementOp() ? -1 : 1))
8548 }
else if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
8549 switch (BO->getOpcode()) {
8552 if (getInitLCDecl(BO->getLHS()) == LCDecl)
8553 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
8556 if (getInitLCDecl(BO->getLHS()) == LCDecl)
8557 return checkAndSetIncRHS(BO->getRHS());
8562 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8563 switch (CE->getOperator()) {
8566 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8567 return setStep(SemaRef
8568 .ActOnIntegerConstant(
8570 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
8576 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8577 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
8580 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8581 return checkAndSetIncRHS(CE->getArg(1));
8587 if (dependent() || SemaRef.CurContext->isDependentContext())
8589 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8590 << S->getSourceRange() << LCDecl;
8596 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8597 StringRef Name =
".capture_expr.") {
8604 auto I = Captures.find(
Capture);
8605 if (I != Captures.end())
8618 bool TestIsStrictOp,
bool RoundToStep,
8619 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8620 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures,
".new_step");
8623 llvm::APSInt LRes, SRes;
8624 bool IsLowerConst =
false, IsStepConst =
false;
8625 if (std::optional<llvm::APSInt> Res =
8628 IsLowerConst =
true;
8630 if (std::optional<llvm::APSInt> Res =
8635 bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
8636 ((!TestIsStrictOp && LRes.isNonNegative()) ||
8637 (TestIsStrictOp && LRes.isStrictlyPositive()));
8638 bool NeedToReorganize =
false;
8640 if (!NoNeedToConvert && IsLowerConst &&
8641 (TestIsStrictOp || (RoundToStep && IsStepConst))) {
8642 NoNeedToConvert =
true;
8644 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
8645 ? LRes.getBitWidth()
8646 : SRes.getBitWidth();
8647 LRes = LRes.extend(BW + 1);
8648 LRes.setIsSigned(
true);
8649 SRes = SRes.extend(BW + 1);
8650 SRes.setIsSigned(
true);
8652 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
8653 LRes = LRes.trunc(BW);
8655 if (TestIsStrictOp) {
8656 unsigned BW = LRes.getBitWidth();
8657 LRes = LRes.extend(BW + 1);
8658 LRes.setIsSigned(
true);
8661 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
8663 LRes = LRes.trunc(BW);
8665 NeedToReorganize = NoNeedToConvert;
8668 bool IsUpperConst =
false;
8669 if (std::optional<llvm::APSInt> Res =
8672 IsUpperConst =
true;
8674 if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
8675 (!RoundToStep || IsStepConst)) {
8676 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
8677 : URes.getBitWidth();
8678 LRes = LRes.extend(BW + 1);
8679 LRes.setIsSigned(
true);
8680 URes = URes.extend(BW + 1);
8681 URes.setIsSigned(
true);
8683 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
8684 NeedToReorganize = NoNeedToConvert;
8689 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
8695 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
8698 LowerSize > UpperSize ? LowerSize : UpperSize, 0);
8709 if (!Lower || !Upper || NewStep.
isInvalid())
8715 if (NeedToReorganize) {
8729 S, DefaultLoc, BO_Add, Diff.
get(),
8739 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.
get());
8743 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
8759 S, DefaultLoc, BO_Sub, Diff.
get(),
8779 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Div, Diff.
get(), NewStep.
get());
8787Expr *OpenMPIterationSpaceChecker::buildNumIterations(
8789 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const {
8798 if (InitDependOnLC) {
8799 const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
8800 if (!IS.MinValue || !IS.MaxValue)
8809 IS.CounterVar, MinValue.
get());
8814 SemaRef.
BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.
get(), LBVal);
8829 IS.CounterVar, MaxValue.
get());
8834 SemaRef.
BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.
get(), LBVal);
8843 tryBuildCapture(SemaRef, LBMinVal.
get(), Captures,
".lb_min").get();
8845 tryBuildCapture(SemaRef, LBMaxVal.
get(), Captures,
".lb_max").get();
8846 if (!LBMin || !LBMax)
8850 SemaRef.
BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
8854 tryBuildCapture(SemaRef, MinLessMaxRes.
get(), Captures,
".min_less_max")
8858 if (*TestIsLessOp) {
8862 MinLessMax, LBMin, LBMax);
8865 LBVal = MinLB.
get();
8870 MinLessMax, LBMax, LBMin);
8873 LBVal = MaxLB.
get();
8877 SemaRef.
BuildBinOp(S, DefaultLoc, BO_Assign, IS.CounterVar, LBVal);
8880 LBVal = LBMinVal.
get();
8884 if (CondDependOnLC) {
8885 const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
8886 if (!IS.MinValue || !IS.MaxValue)
8895 IS.CounterVar, MinValue.
get());
8900 SemaRef.
BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.
get(), UBVal);
8915 IS.CounterVar, MaxValue.
get());
8920 SemaRef.
BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.
get(), UBVal);
8929 tryBuildCapture(SemaRef, UBMinVal.
get(), Captures,
".ub_min").get();
8931 tryBuildCapture(SemaRef, UBMaxVal.
get(), Captures,
".ub_max").get();
8932 if (!UBMin || !UBMax)
8936 SemaRef.
BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
8939 Expr *MinGreaterMax = tryBuildCapture(SemaRef, MinGreaterMaxRes.
get(),
8940 Captures,
".min_greater_max")
8944 if (*TestIsLessOp) {
8948 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
8951 UBVal = MaxUB.
get();
8956 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
8959 UBVal = MinUB.
get();
8962 Expr *UBExpr = *TestIsLessOp ? UBVal : LBVal;
8963 Expr *LBExpr = *TestIsLessOp ? LBVal : UBVal;
8964 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures,
".upper").get();
8965 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures,
".lower").get();
8966 if (!Upper || !Lower)
8969 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8970 Step, VarType, TestIsStrictOp,
8979 C.getTypeSize(
Type) >
C.getTypeSize(VarType);
8982 UseVarType ?
C.getTypeSize(VarType) :
C.getTypeSize(
Type);
8985 Type =
C.getIntTypeForBitwidth(NewSize, IsSigned);
8994 unsigned NewSize = (
C.getTypeSize(
Type) > 32) ? 64 : 32;
8995 if (NewSize !=
C.getTypeSize(
Type)) {
8996 if (NewSize <
C.getTypeSize(
Type)) {
8997 assert(NewSize == 64 &&
"incorrect loop var size");
8998 SemaRef.
Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
8999 << InitSrcRange << ConditionSrcRange;
9001 QualType NewType =
C.getIntTypeForBitwidth(
9003 C.getTypeSize(
Type) < NewSize);
9016std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
9017 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const {
9021 return std::make_pair(
nullptr,
nullptr);
9024 Expr *MinExpr =
nullptr;
9025 Expr *MaxExpr =
nullptr;
9026 Expr *LBExpr = *TestIsLessOp ? LB : UB;
9027 Expr *UBExpr = *TestIsLessOp ? UB : LB;
9029 *TestIsLessOp ? InitDependOnLC.has_value() : CondDependOnLC.has_value();
9031 *TestIsLessOp ? CondDependOnLC.has_value() : InitDependOnLC.has_value();
9033 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
9035 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
9036 if (!Upper || !Lower)
9037 return std::make_pair(
nullptr,
nullptr);
9047 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
9048 Step, VarType, TestIsStrictOp,
9051 return std::make_pair(
nullptr,
nullptr);
9057 return std::make_pair(
nullptr,
nullptr);
9059 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures,
".new_step");
9061 return std::make_pair(
nullptr,
nullptr);
9062 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Mul, Diff.
get(), NewStep.
get());
9064 return std::make_pair(
nullptr,
nullptr);
9069 return std::make_pair(
nullptr,
nullptr);
9081 return std::make_pair(
nullptr,
nullptr);
9083 if (*TestIsLessOp) {
9087 S, DefaultLoc, BO_Add,
9091 return std::make_pair(
nullptr,
nullptr);
9096 S, DefaultLoc, BO_Sub,
9100 return std::make_pair(
nullptr,
nullptr);
9109 return std::make_pair(
nullptr,
nullptr);
9114 return std::make_pair(
nullptr,
nullptr);
9117 MaxExpr = Diff.
get();
9119 MinExpr = Diff.
get();
9121 return std::make_pair(MinExpr, MaxExpr);
9124Expr *OpenMPIterationSpaceChecker::buildFinalCondition(
Scope *S)
const {
9125 if (InitDependOnLC || CondDependOnLC)
9130Expr *OpenMPIterationSpaceChecker::buildPreCond(
9132 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const {
9137 if (CondDependOnLC || InitDependOnLC)
9148 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
9149 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
9155 *TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
9156 : (TestIsStrictOp ? BO_GT : BO_GE),
9157 NewLB.
get(), NewUB.
get());
9167 return CondExpr.
isUsable() ? CondExpr.
get() : Cond;
9171DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
9172 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
9173 DSAStackTy &DSA)
const {
9174 auto *VD = dyn_cast<VarDecl>(LCDecl);
9179 const DSAStackTy::DSAVarData
Data =
9180 DSA.getTopDSA(LCDecl,
false);
9184 Captures.insert(std::make_pair(LCRef, Ref));
9187 return cast<DeclRefExpr>(LCRef);
9190Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar()
const {
9196 isa<VarDecl>(LCDecl)
9207Expr *OpenMPIterationSpaceChecker::buildCounterInit()
const {
return LB; }
9210Expr *OpenMPIterationSpaceChecker::buildCounterStep()
const {
return Step; }
9212Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
9214 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
SourceLocation Loc,
9220 assert((OOK == OO_Plus || OOK == OO_Minus) &&
9221 "Expected only + or - operations for depend clauses.");
9233 *TestIsLessOp ? Cnt : tryBuildCapture(SemaRef, LB, Captures).get();
9235 *TestIsLessOp ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt;
9236 if (!Upper || !Lower)
9240 SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
9241 false,
false, Captures);
9250 assert(
getLangOpts().OpenMP &&
"OpenMP is not active.");
9251 assert(
Init &&
"Expected loop in canonical form.");
9252 unsigned AssociatedLoops =
DSAStack->getAssociatedLoops();
9253 if (AssociatedLoops > 0 &&
9256 OpenMPIterationSpaceChecker ISC(*
this,
true,
9258 if (!ISC.checkAndSetInit(
Init,
false)) {
9260 auto *VD = dyn_cast<VarDecl>(D);
9266 PrivateRef =
buildCapture(*
this, D, ISC.getLoopDeclRefExpr(),
9268 VD = cast<VarDecl>(PrivateRef->
getDecl());
9271 DSAStack->addLoopControlVariable(D, VD);
9274 DSAStack->resetPossibleLoopCounter();
9275 if (
auto *Var = dyn_cast_or_null<VarDecl>(LD))
9289 DSAStackTy::DSAVarData DVar =
9293 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
9296 ? (
DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
9299 DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
9300 (
LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
9301 DVar.CKind != OMPC_private))) ||
9303 DKind == OMPD_master_taskloop || DKind == OMPD_masked_taskloop ||
9304 DKind == OMPD_parallel_master_taskloop ||
9305 DKind == OMPD_parallel_masked_taskloop ||
9308 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
9309 (DVar.CKind != OMPC_private || DVar.RefExpr)) {
9310 Diag(
Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
9311 << getOpenMPClauseName(DVar.CKind)
9312 << getOpenMPDirectiveName(DKind)
9313 << getOpenMPClauseName(PredeterminedCKind);
9314 if (DVar.RefExpr ==
nullptr)
9315 DVar.CKind = PredeterminedCKind;
9318 }
else if (LoopDeclRefExpr) {
9323 if (DVar.CKind == OMPC_unknown)
9324 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
9329 DSAStack->setAssociatedLoops(AssociatedLoops - 1);
9335class OMPDoacrossKind {
9338 return C->getDependenceType() == OMPC_DOACROSS_source ||
9339 C->getDependenceType() == OMPC_DOACROSS_source_omp_cur_iteration;
9342 return C->getDependenceType() == OMPC_DOACROSS_sink;
9345 return C->getDependenceType() == OMPC_DOACROSS_sink_omp_cur_iteration;
9353 unsigned CurrentNestedLoopCount,
unsigned NestedLoopCount,
9354 unsigned TotalNestedLoopCount,
Expr *CollapseLoopCountExpr,
9355 Expr *OrderedLoopCountExpr,
9358 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9363 if (
auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S))
9364 S = CanonLoop->getLoopStmt();
9365 auto *For = dyn_cast_or_null<ForStmt>(S);
9366 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
9368 if (!For && (SemaRef.
LangOpts.OpenMP <= 45 || !CXXFor)) {
9370 DSA.getMappedDirective() == OMPD_unknown)
9372 : DSA.getMappedDirective();
9373 SemaRef.
Diag(S->getBeginLoc(), diag::err_omp_not_for)
9374 << (CollapseLoopCountExpr !=
nullptr || OrderedLoopCountExpr !=
nullptr)
9375 << getOpenMPDirectiveName(DK) << TotalNestedLoopCount
9376 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
9377 if (TotalNestedLoopCount > 1) {
9378 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
9379 SemaRef.
Diag(DSA.getConstructLoc(),
9380 diag::note_omp_collapse_ordered_expr)
9383 else if (CollapseLoopCountExpr)
9385 diag::note_omp_collapse_ordered_expr)
9389 diag::note_omp_collapse_ordered_expr)
9394 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
9400 OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA,
9401 For ? For->getForLoc() : CXXFor->getForLoc());
9404 Stmt *
Init = For ? For->getInit() : CXXFor->getBeginStmt();
9405 if (ISC.checkAndSetInit(
Init))
9408 bool HasErrors =
false;
9411 if (
ValueDecl *LCDecl = ISC.getLoopDecl()) {
9421 SemaRef.
Diag(
Init->getBeginLoc(), diag::err_omp_loop_variable_type)
9435 VarsWithImplicitDSA.erase(LCDecl);
9440 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
9443 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
9450 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
9451 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
9452 ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
9453 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
9460 ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
9461 ISC.buildCounterVar(Captures, DSA);
9462 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
9463 ISC.buildPrivateCounterVar();
9464 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
9465 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
9466 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
9467 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
9468 ISC.getConditionSrcRange();
9469 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
9470 ISC.getIncrementSrcRange();
9471 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
9472 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
9473 ISC.isStrictTestOp();
9474 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
9475 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
9476 ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
9477 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
9478 ISC.buildFinalCondition(DSA.getCurScope());
9479 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
9480 ISC.doesInitDependOnLC();
9481 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
9482 ISC.doesCondDependOnLC();
9483 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
9484 ISC.getLoopDependentIdx();
9487 (ResultIterSpaces[CurrentNestedLoopCount].PreCond ==
nullptr ||
9488 ResultIterSpaces[CurrentNestedLoopCount].NumIterations ==
nullptr ||
9489 ResultIterSpaces[CurrentNestedLoopCount].CounterVar ==
nullptr ||
9490 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar ==
nullptr ||
9491 ResultIterSpaces[CurrentNestedLoopCount].CounterInit ==
nullptr ||
9492 ResultIterSpaces[CurrentNestedLoopCount].CounterStep ==
nullptr);
9493 if (!HasErrors && DSA.isOrderedRegion()) {
9494 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
9495 if (CurrentNestedLoopCount <
9496 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
9497 DSA.getOrderedRegionParam().second->setLoopNumIterations(
9498 CurrentNestedLoopCount,
9499 ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
9500 DSA.getOrderedRegionParam().second->setLoopCounter(
9501 CurrentNestedLoopCount,
9502 ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
9505 for (
auto &Pair : DSA.getDoacrossDependClauses()) {
9506 auto *DependC = dyn_cast<OMPDependClause>(Pair.first);
9507 auto *DoacrossC = dyn_cast<OMPDoacrossClause>(Pair.first);
9509 DependC ? DependC->getNumLoops() : DoacrossC->getNumLoops();
9510 if (CurrentNestedLoopCount >= NumLoops) {
9514 if (DependC && DependC->getDependencyKind() == OMPC_DEPEND_sink &&
9515 Pair.second.size() <= CurrentNestedLoopCount) {
9517 DependC->setLoopData(CurrentNestedLoopCount,
nullptr);
9520 OMPDoacrossKind ODK;
9521 if (DoacrossC && ODK.isSink(DoacrossC) &&
9522 Pair.second.size() <= CurrentNestedLoopCount) {
9524 DoacrossC->setLoopData(CurrentNestedLoopCount,
nullptr);
9529 DependC ? DependC->getDependencyLoc() : DoacrossC->getDependenceLoc();
9530 if ((DependC && DependC->getDependencyKind() == OMPC_DEPEND_source) ||
9531 (DoacrossC && ODK.isSource(DoacrossC)))
9532 CntValue = ISC.buildOrderedLoopData(
9534 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9536 else if (DoacrossC && ODK.isSinkIter(DoacrossC)) {
9539 ResultIterSpaces[CurrentNestedLoopCount].CounterVar)
9547 CntValue = ISC.buildOrderedLoopData(
9549 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9550 DepLoc, Inc, clang::OO_Minus);
9552 CntValue = ISC.buildOrderedLoopData(
9554 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9555 DepLoc, Pair.second[CurrentNestedLoopCount].first,
9556 Pair.second[CurrentNestedLoopCount].second);
9558 DependC->setLoopData(CurrentNestedLoopCount, CntValue);
9560 DoacrossC->setLoopData(CurrentNestedLoopCount, CntValue);
9571 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9575 : tryBuildCapture(SemaRef, Start.
get(), Captures);
9596 bool IsNonRectangularLB,
9597 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures =
nullptr) {
9606 NewStep = tryBuildCapture(SemaRef, Step.
get(), *Captures);
9621 if (Captures && !IsNonRectangularLB)
9622 NewStart = tryBuildCapture(SemaRef, Start.
get(), *Captures);
9631 Update.get()->getType()->isOverloadableType()) {
9638 SemaRef.
BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
9639 VarRef.
get(), SavedUpdate.
get());
9650 NewStart.
get(), SavedUpdate.
get());
9674 unsigned HasBits =
C.getTypeSize(OldType);
9675 if (HasBits >= Bits)
9678 QualType NewType =
C.getIntTypeForBitwidth(Bits,
true);
9688 if (std::optional<llvm::APSInt>
Result =
9697 if (!PreInits.empty()) {
9708 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9709 if (!Captures.empty()) {
9711 for (
const auto &Pair : Captures)
9712 PreInits.push_back(Pair.second->getDecl());
9720 Expr *PostUpdate =
nullptr;
9721 if (!PostUpdates.empty()) {
9722 for (
Expr *E : PostUpdates) {
9728 PostUpdate = PostUpdate
9743 Expr *OrderedLoopCountExpr,
Stmt *AStmt,
Sema &SemaRef,
9747 unsigned NestedLoopCount = 1;
9748 bool SupportsNonPerfectlyNested = (SemaRef.
LangOpts.OpenMP >= 50) &&
9751 if (CollapseLoopCountExpr) {
9756 NestedLoopCount =
Result.Val.getInt().getLimitedValue();
9762 unsigned OrderedLoopCount = 1;
9763 if (OrderedLoopCountExpr) {
9770 if (
Result.getLimitedValue() < NestedLoopCount) {
9772 diag::err_omp_wrong_ordered_loop_count)
9775 diag::note_collapse_loop_count)
9778 OrderedLoopCount =
Result.getLimitedValue();
9786 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9787 unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount);
9791 SupportsNonPerfectlyNested, NumLoops,
9792 [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount,
9793 CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA,
9794 &IterSpaces, &Captures](
unsigned Cnt,
Stmt *CurStmt) {
9796 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
9797 NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr,
9798 VarsWithImplicitDSA, IterSpaces, Captures))
9800 if (Cnt > 0 && Cnt >= NestedLoopCount &&
9801 IterSpaces[Cnt].CounterVar) {
9803 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
9804 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
9805 Captures[DRE] = DRE;
9811 Stmt *DependentPreInits = Transform->getPreInits();
9812 if (!DependentPreInits)
9814 for (
Decl *
C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) {
9815 auto *D = cast<VarDecl>(
C);
9817 Transform->getBeginLoc());
9818 Captures[Ref] = Ref;
9823 Built.
clear( NestedLoopCount);
9826 return NestedLoopCount;
9859 auto PreCond =
ExprResult(IterSpaces[0].PreCond);
9860 Expr *N0 = IterSpaces[0].NumIterations;
9864 .PerformImplicitConversion(
9879 return NestedLoopCount;
9882 bool AllCountsNeedLessThan32Bits =
C.getTypeSize(N0->
getType()) < 32;
9884 Scope *CurScope = DSA.getCurScope();
9885 for (
unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
9886 if (PreCond.isUsable()) {
9888 SemaRef.
BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
9889 PreCond.get(), IterSpaces[Cnt].PreCond);
9891 Expr *N = IterSpaces[Cnt].NumIterations;
9893 AllCountsNeedLessThan32Bits &=
C.getTypeSize(N->
getType()) < 32;
9896 CurScope, Loc, BO_Mul, LastIteration32.
get(),
9904 CurScope, Loc, BO_Mul, LastIteration64.
get(),
9914 if (SemaRef.
getLangOpts().OpenMPOptimisticCollapse ||
9916 C.getTypeSize(LastIteration32.
get()->
getType()) == 32 &&
9917 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
9921 LastIteration64.
get(), SemaRef))))
9922 LastIteration = LastIteration32;
9941 LastIteration.
get(),
9953 tryBuildCapture(SemaRef, LastIteration.
get(), Captures);
9954 LastIteration = SaveRef;
9967 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
9996 buildVarDecl(SemaRef, InitLoc, StrideVType,
".omp.stride");
10005 UB.
get(), LastIteration.
get());
10008 LastIteration.
get(), UB.
get());
10009 EUB = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, UB.
get(),
10020 buildVarDecl(SemaRef, InitLoc, VType,
".omp.comb.lb");
10028 buildVarDecl(SemaRef, InitLoc, VType,
".omp.comb.ub");
10034 CurScope, InitLoc, BO_GT, CombUB.
get(), LastIteration.
get());
10037 LastIteration.
get(), CombUB.
get());
10038 CombEUB = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.
get(),
10043 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
10047 "Unexpected number of parameters in loop combined directive");
10088 SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, IV.
get(), CombRHS);
10094 bool UseStrictCompare =
10096 llvm::all_of(IterSpaces, [](
const LoopIterationSpace &LIS) {
10097 return LIS.IsStrictCompare;
10103 if (UseStrictCompare) {
10106 .
BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
10118 UseStrictCompare ? BO_LT : BO_LE, IV.
get(),
10121 NumIterations.
get());
10124 CombDistCond = SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LT, IV.
get(),
10125 NumIterations.
get());
10130 Expr *BoundCombUB = CombUB.
get();
10131 if (UseStrictCompare) {
10135 CurScope, CondLoc, BO_Add, BoundCombUB,
10143 SemaRef.
BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
10144 IV.
get(), BoundCombUB);
10151 if (!Inc.isUsable())
10153 Inc = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, IV.
get(), Inc.get());
10155 if (!Inc.isUsable())
10162 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
10168 NextLB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Add, LB.
get(), ST.
get());
10179 NextUB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Add, UB.
get(), ST.
get());
10195 CombNextLB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.
get(),
10207 CombNextUB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.
get(),
10221 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
10224 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.
get(), BoundUB);
10225 assert(DistCond.
isUsable() &&
"distribute cond expr was not built");
10229 assert(DistInc.
isUsable() &&
"distribute inc expr was not built");
10230 DistInc = SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.
get(),
10234 assert(DistInc.
isUsable() &&
"distribute inc expr was not built");
10245 DistEUBLoc, NewPrevUB.
get());
10250 UB.
get(), NewPrevUB.
get());
10252 DistEUBLoc, DistEUBLoc, IsUBGreater.
get(), NewPrevUB.
get(), UB.
get());
10253 PrevEUB = SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.
get(),
10261 Expr *BoundPrevUB = PrevUB.
get();
10262 if (UseStrictCompare) {
10266 CurScope, CondLoc, BO_Add, BoundPrevUB,
10274 SemaRef.
BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
10275 IV.
get(), BoundPrevUB);
10279 bool HasErrors =
false;
10280 Built.
Counters.resize(NestedLoopCount);
10281 Built.
Inits.resize(NestedLoopCount);
10282 Built.
Updates.resize(NestedLoopCount);
10283 Built.
Finals.resize(NestedLoopCount);
10304 for (
unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
10305 LoopIterationSpace &IS = IterSpaces[Cnt];
10311 for (
unsigned int K = Cnt + 1; K < NestedLoopCount; ++K)
10312 Prod = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.
get(),
10313 IterSpaces[K].NumIterations);
10318 if (Cnt + 1 < NestedLoopCount)
10323 if (!
Iter.isUsable()) {
10332 if (Cnt + 1 < NestedLoopCount)
10337 Acc = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Sub, Acc.
get(), Prod.
get());
10340 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
10342 SemaRef, VD, IS.CounterVar->
getType(), IS.CounterVar->getExprLoc(),
10346 IS.CounterInit, IS.IsNonRectangularLB, Captures);
10347 if (!
Init.isUsable()) {
10352 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
Iter,
10353 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
10354 if (!
Update.isUsable()) {
10362 IS.CounterInit, IS.NumIterations, IS.CounterStep,
10363 IS.Subtract, IS.IsNonRectangularLB, &Captures);
10364 if (!Final.isUsable()) {
10369 if (!
Update.isUsable() || !Final.isUsable()) {
10374 Built.
Counters[Cnt] = IS.CounterVar;
10378 Built.
Finals[Cnt] = Final.get();
10382 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
10401 Built.
PreCond = PreCond.get();
10405 Built.
Inc = Inc.get();
10406 Built.
LB = LB.
get();
10407 Built.
UB = UB.
get();
10408 Built.
IL = IL.
get();
10409 Built.
ST = ST.
get();
10411 Built.
NLB = NextLB.
get();
10412 Built.
NUB = NextUB.
get();
10427 return NestedLoopCount;
10431 auto CollapseClauses =
10432 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
10433 if (CollapseClauses.begin() != CollapseClauses.end())
10434 return (*CollapseClauses.begin())->getNumForLoops();
10439 auto OrderedClauses =
10440 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
10441 if (OrderedClauses.begin() != OrderedClauses.end())
10442 return (*OrderedClauses.begin())->getNumForLoops();
10451 for (
const OMPClause *Clause : Clauses) {
10453 Safelen = cast<OMPSafelenClause>(Clause);
10455 Simdlen = cast<OMPSimdlenClause>(Clause);
10456 if (Safelen && Simdlen)
10460 if (Simdlen && Safelen) {
10474 llvm::APSInt SimdlenRes = SimdlenResult.
Val.
getInt();
10475 llvm::APSInt SafelenRes = SafelenResult.
Val.
getInt();
10480 if (SimdlenRes > SafelenRes) {
10482 diag::err_omp_wrong_simdlen_safelen_values)
10492 DSAStackTy *Stack);
10501 DSAStack->getMappedDirective() == OMPD_loop &&
10515 if (!checkLastPrivateForMappedDirectives(Clauses))
10518 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
10524 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
10525 if (NestedLoopCount == 0)
10529 "omp simd loop exprs were not built");
10534 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
10547 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10549 return SimdDirective;
10559 if (!checkLastPrivateForMappedDirectives(Clauses))
10562 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
10568 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
10569 if (NestedLoopCount == 0)
10573 "omp for loop exprs were not built");
10578 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
10587 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10590 return ForDirective;
10599 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
10603 unsigned NestedLoopCount =
10606 VarsWithImplicitDSA, B);
10607 if (NestedLoopCount == 0)
10611 "omp for simd loop exprs were not built");
10616 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
10629 Clauses, AStmt, B);
10639 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
10640 auto BaseStmt = AStmt;
10641 while (
auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10643 if (
auto *
C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10644 auto S =
C->children();
10645 if (S.begin() == S.end())
10649 for (
Stmt *SectionStmt : llvm::drop_begin(S)) {
10650 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10652 Diag(SectionStmt->getBeginLoc(),
10653 diag::err_omp_sections_substmt_not_section);
10656 cast<OMPSectionDirective>(SectionStmt)
10657 ->setHasCancel(
DSAStack->isCancelRegion());
10660 Diag(AStmt->
getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
10667 DSAStack->getTaskgroupReductionRef(),
10686 if (
auto *CE = dyn_cast<CallExpr>(E))
10687 if (CE->getDirectCallee())
10699 Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt();
10709 Expr *TargetCall =
nullptr;
10711 auto *E = dyn_cast<Expr>(S);
10713 Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10719 if (
auto *BO = dyn_cast<BinaryOperator>(E)) {
10720 if (BO->getOpcode() == BO_Assign)
10723 if (
auto *COCE = dyn_cast<CXXOperatorCallExpr>(E))
10724 if (COCE->getOperator() == OO_Equal)
10744 DSAStackTy *Stack) {
10745 bool ErrorFound =
false;
10747 if (
auto *LPC = dyn_cast<OMPLastprivateClause>(
C)) {
10748 for (
Expr *RefExpr : LPC->varlists()) {
10751 Expr *SimpleRefExpr = RefExpr;
10754 auto &&Info = Stack->isLoopControlVariable(D);
10756 S.
Diag(ELoc, diag::err_omp_lastprivate_loop_var_non_loop_iteration)
10757 << getOpenMPDirectiveName(K);
10779 auto *CS = cast<CapturedStmt>(AStmt);
10791 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
10792 if (NestedLoopCount == 0)
10796 "omp loop exprs were not built");
10800 NestedLoopCount, Clauses, AStmt, B);
10815 auto *CS = cast<CapturedStmt>(AStmt);
10823 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10835 unsigned NestedLoopCount =
10838 VarsWithImplicitDSA, B);
10839 if (NestedLoopCount == 0)
10843 "omp loop exprs were not built");
10846 DSAStack->setParentTeamsRegionLoc(StartLoc);
10849 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10865 auto *CS = cast<CapturedStmt>(AStmt);
10873 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10885 unsigned NestedLoopCount =
10888 VarsWithImplicitDSA, B);
10889 if (NestedLoopCount == 0)
10893 "omp loop exprs were not built");
10898 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10913 auto *CS = cast<CapturedStmt>(AStmt);
10921 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10933 unsigned NestedLoopCount =
10936 VarsWithImplicitDSA, B);
10937 if (NestedLoopCount == 0)
10941 "omp loop exprs were not built");
10946 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10962 auto *CS = cast<CapturedStmt>(AStmt);
10970 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10982 unsigned NestedLoopCount =
10985 VarsWithImplicitDSA, B);
10986 if (NestedLoopCount == 0)
10990 "omp loop exprs were not built");
10995 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11005 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
11012 const OMPClause *Copyprivate =
nullptr;
11013 for (
const OMPClause *Clause : Clauses) {
11017 Copyprivate = Clause;
11018 if (Copyprivate && Nowait) {
11020 diag::err_omp_single_copyprivate_with_nowait);
11058 bool ErrorFound =
false;
11061 bool DependentHint =
false;
11063 if (
C->getClauseKind() == OMPC_hint) {
11065 Diag(
C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
11068 Expr *E = cast<OMPHintClause>(
C)->getHint();
11071 DependentHint =
true;
11074 HintLoc =
C->getBeginLoc();
11080 const auto Pair =
DSAStack->getCriticalWithHint(DirName);
11081 if (Pair.first && DirName.
getName() && !DependentHint) {
11082 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
11083 Diag(StartLoc, diag::err_omp_critical_with_hint);
11085 Diag(HintLoc, diag::note_omp_critical_hint_here)
11086 << 0 <<
toString(Hint, 10,
false);
11088 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
11089 if (
const auto *
C = Pair.first->getSingleClause<
OMPHintClause>()) {
11090 Diag(
C->getBeginLoc(), diag::note_omp_critical_hint_here)
11095 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
11104 if (!Pair.first && DirName.
getName() && !DependentHint)
11105 DSAStack->addCriticalWithHint(Dir, Hint);
11115 auto *CS = cast<CapturedStmt>(AStmt);
11126 unsigned NestedLoopCount =
11129 VarsWithImplicitDSA, B);
11130 if (NestedLoopCount == 0)
11134 "omp parallel for loop exprs were not built");
11139 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
11149 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11159 auto *CS = cast<CapturedStmt>(AStmt);
11170 unsigned NestedLoopCount =
11173 VarsWithImplicitDSA, B);
11174 if (NestedLoopCount == 0)
11180 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
11193 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11203 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
11204 auto *CS = cast<CapturedStmt>(AStmt);
11215 Context, StartLoc, EndLoc, Clauses, AStmt,
11216 DSAStack->getTaskgroupReductionRef());
11226 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
11227 auto *CS = cast<CapturedStmt>(AStmt);
11238 Context, StartLoc, EndLoc, Clauses, AStmt,
11239 DSAStack->getTaskgroupReductionRef());
11249 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
11250 auto BaseStmt = AStmt;
11251 while (
auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
11253 if (
auto *
C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
11254 auto S =
C->children();
11255 if (S.begin() == S.end())
11259 for (
Stmt *SectionStmt : llvm::drop_begin(S)) {
11260 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
11262 Diag(SectionStmt->getBeginLoc(),
11263 diag::err_omp_parallel_sections_substmt_not_section);
11266 cast<OMPSectionDirective>(SectionStmt)
11267 ->setHasCancel(
DSAStack->isCancelRegion());
11271 diag::err_omp_parallel_sections_not_compound_stmt);
11278 Context, StartLoc, EndLoc, Clauses, AStmt,
11287 bool ErrorFound =
false;
11289 if (llvm::is_contained(MutuallyExclusiveClauses,
C->getClauseKind())) {
11293 S.
Diag(
C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
11294 << getOpenMPClauseName(
C->getClauseKind())
11315 {OMPC_detach, OMPC_mergeable}))
11318 auto *CS = cast<CapturedStmt>(AStmt);
11345 bool InExContext) {
11347 OMPExecutableDirective::getSingleClause<OMPAtClause>(Clauses);
11349 if (AtC && !InExContext && AtC->
getAtKind() == OMPC_AT_execution) {
11355 OMPExecutableDirective::getSingleClause<OMPSeverityClause>(Clauses);
11357 OMPExecutableDirective::getSingleClause<OMPMessageClause>(Clauses);
11360 if (!AtC || AtC->
getAtKind() == OMPC_AT_compilation) {
11361 if (SeverityC && SeverityC->
getSeverityKind() == OMPC_SEVERITY_warning)
11363 << (ME ? cast<StringLiteral>(ME)->getString() :
"WARNING");
11365 Diag(StartLoc, diag::err_diagnose_if_succeeded)
11366 << (ME ? cast<StringLiteral>(ME)->getString() :
"ERROR");
11367 if (!SeverityC || SeverityC->
getSeverityKind() != OMPC_SEVERITY_warning)
11377 OMPExecutableDirective::getSingleClause<OMPNowaitClause>(Clauses);
11379 !OMPExecutableDirective::getClausesOfKind<OMPDependClause>(Clauses)
11381 if (NowaitC && !HasDependC) {
11382 Diag(StartLoc, diag::err_omp_nowait_clause_without_depend);
11396 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
11402 DSAStack->getTaskgroupReductionRef());
11411 if (
C->getClauseKind() == OMPC_flush)
11412 FC = cast<OMPFlushClause>(
C);
11419 if (
C->getClauseKind() == OMPC_acq_rel ||
11420 C->getClauseKind() == OMPC_acquire ||
11421 C->getClauseKind() == OMPC_release) {
11422 if (MemOrderKind != OMPC_unknown) {
11423 Diag(
C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
11424 << getOpenMPDirectiveName(OMPD_flush) << 1
11426 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
11427 << getOpenMPClauseName(MemOrderKind);
11429 MemOrderKind =
C->getClauseKind();
11430 MemOrderLoc =
C->getBeginLoc();
11434 if (FC && OrderClause) {
11437 Diag(OrderClause->
getBeginLoc(), diag::note_omp_flush_order_clause_here)
11447 if (Clauses.empty()) {
11448 Diag(StartLoc, diag::err_omp_depobj_expected);
11450 }
else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
11451 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
11455 if (Clauses.size() > 2) {
11456 Diag(Clauses[2]->getBeginLoc(),
11457 diag::err_omp_depobj_single_clause_expected);
11459 }
else if (Clauses.size() < 1) {
11460 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
11470 if (Clauses.size() != 1) {
11471 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
11472 diag::err_omp_scan_single_clause_expected);
11477 Scope *ParentS = S->getParent();
11480 return StmtError(
Diag(StartLoc, diag::err_omp_orphaned_device_directive)
11481 << getOpenMPDirectiveName(OMPD_scan) << 5);
11485 if (
DSAStack->doesParentHasScanDirective()) {
11486 Diag(StartLoc, diag::err_omp_several_directives_in_region) <<
"scan";
11488 diag::note_omp_previous_directive)
11492 DSAStack->setParentHasScanDirective(StartLoc);
11500 const OMPClause *DependFound =
nullptr;
11501 const OMPClause *DependSourceClause =
nullptr;
11502 const OMPClause *DependSinkClause =
nullptr;
11503 const OMPClause *DoacrossFound =
nullptr;
11504 const OMPClause *DoacrossSourceClause =
nullptr;
11505 const OMPClause *DoacrossSinkClause =
nullptr;
11506 bool ErrorFound =
false;
11510 auto DOC = dyn_cast<OMPDoacrossClause>(
C);
11511 auto DC = dyn_cast<OMPDependClause>(
C);
11513 DependFound = DC ?
C :
nullptr;
11514 DoacrossFound = DOC ?
C :
nullptr;
11515 OMPDoacrossKind ODK;
11516 if ((DC && DC->getDependencyKind() == OMPC_DEPEND_source) ||
11517 (DOC && (ODK.isSource(DOC)))) {
11518 if ((DC && DependSourceClause) || (DOC && DoacrossSourceClause)) {
11519 Diag(
C->getBeginLoc(), diag::err_omp_more_one_clause)
11520 << getOpenMPDirectiveName(OMPD_ordered)
11521 << getOpenMPClauseName(DC ? OMPC_depend : OMPC_doacross) << 2;
11525 DependSourceClause =
C;
11527 DoacrossSourceClause =
C;
11529 if ((DC && DependSinkClause) || (DOC && DoacrossSinkClause)) {
11530 Diag(
C->getBeginLoc(), diag::err_omp_sink_and_source_not_allowed)
11531 << (DC ?
"depend" :
"doacross") << 0;
11534 }
else if ((DC && DC->getDependencyKind() == OMPC_DEPEND_sink) ||
11535 (DOC && (ODK.isSink(DOC) || ODK.isSinkIter(DOC)))) {
11536 if (DependSourceClause || DoacrossSourceClause) {
11537 Diag(
C->getBeginLoc(), diag::err_omp_sink_and_source_not_allowed)
11538 << (DC ?
"depend" :
"doacross") << 1;
11542 DependSinkClause =
C;
11544 DoacrossSinkClause =
C;
11546 }
else if (
C->getClauseKind() == OMPC_threads) {
11547 TC = cast<OMPThreadsClause>(
C);
11548 }
else if (
C->getClauseKind() == OMPC_simd) {
11549 SC = cast<OMPSIMDClause>(
C);
11552 if (!ErrorFound && !SC &&
11557 Diag(StartLoc, diag::err_omp_prohibited_region_simd)
11558 << (
LangOpts.OpenMP >= 50 ? 1 : 0);
11560 }
else if ((DependFound || DoacrossFound) && (TC || SC)) {
11563 Diag(Loc, diag::err_omp_depend_clause_thread_simd)
11564 << getOpenMPClauseName(DependFound ? OMPC_depend : OMPC_doacross)
11567 }
else if ((DependFound || DoacrossFound) &&
11568 !
DSAStack->getParentOrderedRegionParam().first) {
11571 Diag(Loc, diag::err_omp_ordered_directive_without_param)
11572 << getOpenMPClauseName(DependFound ? OMPC_depend : OMPC_doacross);
11574 }
else if (TC || Clauses.empty()) {
11575 if (
const Expr *Param =
DSAStack->getParentOrderedRegionParam().first) {
11577 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
11578 << (TC !=
nullptr);
11583 if ((!AStmt && !DependFound && !DoacrossFound) || ErrorFound)
11591 if (!DependFound && !DoacrossFound) {
11592 if (
DSAStack->doesParentHasOrderedDirective()) {
11593 Diag(StartLoc, diag::err_omp_several_directives_in_region) <<
"ordered";
11595 diag::note_omp_previous_directive)
11599 DSAStack->setParentHasOrderedDirective(StartLoc);
11603 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
11614class OpenMPAtomicUpdateChecker {
11616 enum ExprAnalysisErrorCode {
11620 NotABinaryOrUnaryExpression,
11622 NotAnUnaryIncDecExpression,
11628 NotABinaryExpression,
11631 NotABinaryOperator,
11634 NotAnUpdateExpression,
11637 NotAValidExpression,
11655 bool IsXLHSInRHSPart;
11660 bool IsPostfixUpdate;
11663 OpenMPAtomicUpdateChecker(
Sema &SemaRef)
11664 : SemaRef(SemaRef),
X(nullptr), E(nullptr), UpdateExpr(nullptr),
11665 IsXLHSInRHSPart(
false), Op(BO_PtrMemD), IsPostfixUpdate(
false) {}
11673 bool checkStatement(
Stmt *S,
unsigned DiagId = 0,
unsigned NoteId = 0);
11675 Expr *getX()
const {
return X; }
11677 Expr *getExpr()
const {
return E; }
11681 Expr *getUpdateExpr()
const {
return UpdateExpr; }
11684 bool isXLHSInRHSPart()
const {
return IsXLHSInRHSPart; }
11688 bool isPostfixUpdate()
const {
return IsPostfixUpdate; }
11691 bool checkBinaryOperation(
BinaryOperator *AtomicBinOp,
unsigned DiagId = 0,
11692 unsigned NoteId = 0);
11695bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
11696 BinaryOperator *AtomicBinOp,
unsigned DiagId,
unsigned NoteId) {
11697 ExprAnalysisErrorCode ErrorFound = NoError;
11703 if (AtomicBinOp->
getOpcode() == BO_Assign) {
11705 if (
const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
11707 if (AtomicInnerBinOp->isMultiplicativeOp() ||
11708 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
11709 AtomicInnerBinOp->isBitwiseOp()) {
11710 Op = AtomicInnerBinOp->getOpcode();
11711 OpLoc = AtomicInnerBinOp->getOperatorLoc();
11712 Expr *LHS = AtomicInnerBinOp->getLHS();
11713 Expr *RHS = AtomicInnerBinOp->getRHS();
11714 llvm::FoldingSetNodeID XId, LHSId, RHSId;
11721 if (XId == LHSId) {
11723 IsXLHSInRHSPart =
true;
11724 }
else if (XId == RHSId) {
11726 IsXLHSInRHSPart =
false;
11728 ErrorLoc = AtomicInnerBinOp->getExprLoc();
11729 ErrorRange = AtomicInnerBinOp->getSourceRange();
11730 NoteLoc =
X->getExprLoc();
11731 NoteRange =
X->getSourceRange();
11732 ErrorFound = NotAnUpdateExpression;
11735 ErrorLoc = AtomicInnerBinOp->getExprLoc();
11736 ErrorRange = AtomicInnerBinOp->getSourceRange();
11737 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
11739 ErrorFound = NotABinaryOperator;
11744 ErrorFound = NotABinaryExpression;
11751 ErrorFound = NotAnAssignmentOp;
11753 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11754 SemaRef.
Diag(ErrorLoc, DiagId) << ErrorRange;
11755 SemaRef.
Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11759 E =
X = UpdateExpr =
nullptr;
11760 return ErrorFound != NoError;
11763bool OpenMPAtomicUpdateChecker::checkStatement(
Stmt *S,
unsigned DiagId,
11765 ExprAnalysisErrorCode ErrorFound = NoError;
11776 if (
auto *AtomicBody = dyn_cast<Expr>(S)) {
11777 AtomicBody = AtomicBody->IgnoreParenImpCasts();
11778 if (AtomicBody->getType()->isScalarType() ||
11779 AtomicBody->isInstantiationDependent()) {
11780 if (
const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
11781 AtomicBody->IgnoreParenImpCasts())) {
11784 AtomicCompAssignOp->getOpcode());
11785 OpLoc = AtomicCompAssignOp->getOperatorLoc();
11786 E = AtomicCompAssignOp->getRHS();
11787 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
11788 IsXLHSInRHSPart =
true;
11789 }
else if (
auto *AtomicBinOp = dyn_cast<BinaryOperator>(
11790 AtomicBody->IgnoreParenImpCasts())) {
11792 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
11794 }
else if (
const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
11795 AtomicBody->IgnoreParenImpCasts())) {
11797 if (AtomicUnaryOp->isIncrementDecrementOp()) {
11798 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
11799 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
11800 OpLoc = AtomicUnaryOp->getOperatorLoc();
11801 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
11803 IsXLHSInRHSPart =
true;
11805 ErrorFound = NotAnUnaryIncDecExpression;
11806 ErrorLoc = AtomicUnaryOp->getExprLoc();
11807 ErrorRange = AtomicUnaryOp->getSourceRange();
11808 NoteLoc = AtomicUnaryOp->getOperatorLoc();
11811 }
else if (!AtomicBody->isInstantiationDependent()) {
11812 ErrorFound = NotABinaryOrUnaryExpression;
11813 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
11814 NoteRange = ErrorRange = AtomicBody->getSourceRange();
11815 }
else if (AtomicBody->containsErrors()) {
11816 ErrorFound = NotAValidExpression;
11817 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
11818 NoteRange = ErrorRange = AtomicBody->getSourceRange();
11821 ErrorFound = NotAScalarType;
11822 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
11823 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
11826 ErrorFound = NotAnExpression;
11827 NoteLoc = ErrorLoc = S->getBeginLoc();
11828 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
11830 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11831 SemaRef.
Diag(ErrorLoc, DiagId) << ErrorRange;
11832 SemaRef.
Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11836 E =
X = UpdateExpr =
nullptr;
11837 if (ErrorFound == NoError && E &&
X) {
11847 IsXLHSInRHSPart ? OVEExpr : OVEX);
11854 UpdateExpr =
Update.get();
11856 return ErrorFound != NoError;
11860llvm::FoldingSetNodeID getNodeId(
ASTContext &Context,
const Expr *S) {
11861 llvm::FoldingSetNodeID
Id;
11862 S->IgnoreParenImpCasts()->Profile(
Id, Context,
true);
11867bool checkIfTwoExprsAreSame(
ASTContext &Context,
const Expr *LHS,
11869 return getNodeId(Context, LHS) == getNodeId(Context, RHS);
11872class OpenMPAtomicCompareChecker {
11919 struct ErrorInfoTy {
11927 OpenMPAtomicCompareChecker(
Sema &S) : ContextRef(S.getASTContext()) {}
11930 bool checkStmt(
Stmt *S, ErrorInfoTy &ErrorInfo);
11932 Expr *getX()
const {
return X; }
11933 Expr *getE()
const {
return E; }
11934 Expr *getD()
const {
return D; }
11935 Expr *getCond()
const {
return C; }
11936 bool isXBinopExpr()
const {
return IsXBinopExpr; }
11955 bool IsXBinopExpr =
true;
11958 bool checkCondUpdateStmt(
IfStmt *S, ErrorInfoTy &ErrorInfo);
11961 bool checkCondExprStmt(
Stmt *S, ErrorInfoTy &ErrorInfo);
11964 bool checkType(ErrorInfoTy &ErrorInfo)
const;
11966 static bool CheckValue(
const Expr *E, ErrorInfoTy &ErrorInfo,
11967 bool ShouldBeLValue,
bool ShouldBeInteger =
false) {
11971 if (ShouldBeLValue && !E->
isLValue()) {
11972 ErrorInfo.Error = ErrorTy::XNotLValue;
11973 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->
getExprLoc();
11974 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->
getSourceRange();
11980 ErrorInfo.Error = ErrorTy::NotScalar;
11981 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->
getExprLoc();
11982 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->
getSourceRange();
11986 ErrorInfo.Error = ErrorTy::NotInteger;
11987 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->
getExprLoc();
11988 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->
getSourceRange();
11996bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(
IfStmt *S,
11997 ErrorInfoTy &ErrorInfo) {
11998 auto *Then = S->getThen();
11999 if (
auto *CS = dyn_cast<CompoundStmt>(Then)) {
12000 if (CS->body_empty()) {
12001 ErrorInfo.Error = ErrorTy::NoStmt;
12002 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12003 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12006 if (CS->size() > 1) {
12007 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12008 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12009 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12012 Then = CS->body_front();
12015 auto *BO = dyn_cast<BinaryOperator>(Then);
12017 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12018 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
12019 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
12022 if (BO->getOpcode() != BO_Assign) {
12023 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12024 ErrorInfo.ErrorLoc = BO->getExprLoc();
12025 ErrorInfo.NoteLoc = BO->getOperatorLoc();
12026 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12032 auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
12034 ErrorInfo.Error = ErrorTy::NotABinaryOp;
12035 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
12036 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
12040 switch (Cond->getOpcode()) {
12044 if (checkIfTwoExprsAreSame(ContextRef,
X, Cond->getLHS())) {
12045 E = Cond->getRHS();
12046 }
else if (checkIfTwoExprsAreSame(ContextRef,
X, Cond->getRHS())) {
12047 E = Cond->getLHS();
12049 ErrorInfo.Error = ErrorTy::InvalidComparison;
12050 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->
getExprLoc();
12051 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
12059 if (checkIfTwoExprsAreSame(ContextRef,
X, Cond->getLHS()) &&
12060 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
12062 }
else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
12063 checkIfTwoExprsAreSame(ContextRef,
X, Cond->getRHS())) {
12065 IsXBinopExpr =
false;
12067 ErrorInfo.Error = ErrorTy::InvalidComparison;
12068 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->
getExprLoc();
12069 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
12075 ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
12076 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->
getExprLoc();
12077 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
12081 if (S->getElse()) {
12082 ErrorInfo.Error = ErrorTy::UnexpectedElse;
12083 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc();
12084 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getElse()->getSourceRange();
12091bool OpenMPAtomicCompareChecker::checkCondExprStmt(
Stmt *S,
12092 ErrorInfoTy &ErrorInfo) {
12093 auto *BO = dyn_cast<BinaryOperator>(S);
12095 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12096 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12097 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12100 if (BO->getOpcode() != BO_Assign) {
12101 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12102 ErrorInfo.ErrorLoc = BO->getExprLoc();
12103 ErrorInfo.NoteLoc = BO->getOperatorLoc();
12104 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12110 auto *CO = dyn_cast<ConditionalOperator>(BO->getRHS()->IgnoreParenImpCasts());
12112 ErrorInfo.Error = ErrorTy::NotCondOp;
12113 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getRHS()->getExprLoc();
12114 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getRHS()->getSourceRange();
12118 if (!checkIfTwoExprsAreSame(ContextRef,
X, CO->getFalseExpr())) {
12119 ErrorInfo.Error = ErrorTy::WrongFalseExpr;
12120 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getFalseExpr()->getExprLoc();
12121 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12122 CO->getFalseExpr()->getSourceRange();
12126 auto *Cond = dyn_cast<BinaryOperator>(CO->getCond());
12128 ErrorInfo.Error = ErrorTy::NotABinaryOp;
12129 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getCond()->getExprLoc();
12130 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12131 CO->getCond()->getSourceRange();
12135 switch (Cond->getOpcode()) {
12138 D = CO->getTrueExpr();
12139 if (checkIfTwoExprsAreSame(ContextRef,
X, Cond->getLHS())) {
12140 E = Cond->getRHS();
12141 }
else if (checkIfTwoExprsAreSame(ContextRef,
X, Cond->getRHS())) {
12142 E = Cond->getLHS();
12144 ErrorInfo.Error = ErrorTy::InvalidComparison;
12145 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->
getExprLoc();
12146 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
12153 E = CO->getTrueExpr();
12154 if (checkIfTwoExprsAreSame(ContextRef,
X, Cond->getLHS()) &&
12155 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
12157 }
else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
12158 checkIfTwoExprsAreSame(ContextRef,
X, Cond->getRHS())) {
12160 IsXBinopExpr =
false;
12162 ErrorInfo.Error = ErrorTy::InvalidComparison;
12163 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->
getExprLoc();
12164 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
12170 ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
12171 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->
getExprLoc();
12172 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
12179bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo)
const {
12181 assert(
X && E &&
"X and E cannot be nullptr");
12183 if (!CheckValue(
X, ErrorInfo,
true))
12186 if (!CheckValue(E, ErrorInfo,
false))
12189 if (D && !CheckValue(D, ErrorInfo,
false))
12195bool OpenMPAtomicCompareChecker::checkStmt(
12196 Stmt *S, OpenMPAtomicCompareChecker::ErrorInfoTy &ErrorInfo) {
12197 auto *CS = dyn_cast<CompoundStmt>(S);
12199 if (CS->body_empty()) {
12200 ErrorInfo.Error = ErrorTy::NoStmt;
12201 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12202 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12206 if (CS->size() != 1) {
12207 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12208 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12209 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12212 S = CS->body_front();
12217 if (
auto *IS = dyn_cast<IfStmt>(S)) {
12223 Res = checkCondUpdateStmt(IS, ErrorInfo);
12229 Res = checkCondExprStmt(S, ErrorInfo);
12235 return checkType(ErrorInfo);
12238class OpenMPAtomicCompareCaptureChecker final
12239 :
public OpenMPAtomicCompareChecker {
12241 OpenMPAtomicCompareCaptureChecker(
Sema &S) : OpenMPAtomicCompareChecker(S) {}
12243 Expr *getV()
const {
return V; }
12244 Expr *getR()
const {
return R; }
12245 bool isFailOnly()
const {
return IsFailOnly; }
12246 bool isPostfixUpdate()
const {
return IsPostfixUpdate; }
12249 bool checkStmt(
Stmt *S, ErrorInfoTy &ErrorInfo);
12252 bool checkType(ErrorInfoTy &ErrorInfo);
12264 bool checkForm3(
IfStmt *S, ErrorInfoTy &ErrorInfo);
12268 bool checkForm45(
Stmt *S, ErrorInfoTy &ErrorInfo);
12275 bool IsFailOnly =
false;
12277 bool IsPostfixUpdate =
false;
12280bool OpenMPAtomicCompareCaptureChecker::checkType(ErrorInfoTy &ErrorInfo) {
12281 if (!OpenMPAtomicCompareChecker::checkType(ErrorInfo))
12284 if (
V && !CheckValue(
V, ErrorInfo,
true))
12287 if (R && !CheckValue(R, ErrorInfo,
true,
true))
12293bool OpenMPAtomicCompareCaptureChecker::checkForm3(
IfStmt *S,
12294 ErrorInfoTy &ErrorInfo) {
12297 auto *Then = S->getThen();
12298 if (
auto *CS = dyn_cast<CompoundStmt>(Then)) {
12299 if (CS->body_empty()) {
12300 ErrorInfo.Error = ErrorTy::NoStmt;
12301 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12302 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12305 if (CS->size() > 1) {
12306 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12307 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12308 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12311 Then = CS->body_front();
12314 auto *BO = dyn_cast<BinaryOperator>(Then);
12316 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12317 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
12318 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
12321 if (BO->getOpcode() != BO_Assign) {
12322 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12323 ErrorInfo.ErrorLoc = BO->getExprLoc();
12324 ErrorInfo.NoteLoc = BO->getOperatorLoc();
12325 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12332 auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
12334 ErrorInfo.Error = ErrorTy::NotABinaryOp;
12335 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
12336 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
12339 if (Cond->getOpcode() != BO_EQ) {
12340 ErrorInfo.Error = ErrorTy::NotEQ;
12341 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->
getExprLoc();
12342 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
12346 if (checkIfTwoExprsAreSame(ContextRef,
X, Cond->getLHS())) {
12347 E = Cond->getRHS();
12348 }
else if (checkIfTwoExprsAreSame(ContextRef,
X, Cond->getRHS())) {
12349 E = Cond->getLHS();
12351 ErrorInfo.Error = ErrorTy::InvalidComparison;
12352 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->
getExprLoc();
12353 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
12359 if (!S->getElse()) {
12360 ErrorInfo.Error = ErrorTy::NoElse;
12361 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12362 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12366 auto *Else = S->getElse();
12367 if (
auto *CS = dyn_cast<CompoundStmt>(Else)) {
12368 if (CS->body_empty()) {
12369 ErrorInfo.Error = ErrorTy::NoStmt;
12370 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12371 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12374 if (CS->size() > 1) {
12375 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12376 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12377 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12380 Else = CS->body_front();
12383 auto *ElseBO = dyn_cast<BinaryOperator>(Else);
12385 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12386 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
12387 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
12390 if (ElseBO->getOpcode() != BO_Assign) {
12391 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12392 ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
12393 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12394 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12398 if (!checkIfTwoExprsAreSame(ContextRef,
X, ElseBO->getRHS())) {
12399 ErrorInfo.Error = ErrorTy::InvalidAssignment;
12400 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseBO->getRHS()->getExprLoc();
12401 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12402 ElseBO->getRHS()->getSourceRange();
12406 V = ElseBO->getLHS();
12408 return checkType(ErrorInfo);
12411bool OpenMPAtomicCompareCaptureChecker::checkForm45(
Stmt *S,
12412 ErrorInfoTy &ErrorInfo) {
12415 auto *CS = cast<CompoundStmt>(S);
12416 assert(CS->size() == 2 &&
"CompoundStmt size is not expected");
12417 auto *S1 = cast<BinaryOperator>(CS->body_front());
12418 auto *S2 = cast<IfStmt>(CS->body_back());
12419 assert(S1->getOpcode() == BO_Assign &&
"unexpected binary operator");
12421 if (!checkIfTwoExprsAreSame(ContextRef, S1->getLHS(), S2->getCond())) {
12422 ErrorInfo.Error = ErrorTy::InvalidCondition;
12423 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getCond()->getExprLoc();
12424 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S1->getLHS()->getSourceRange();
12430 auto *Then = S2->getThen();
12431 if (
auto *ThenCS = dyn_cast<CompoundStmt>(Then)) {
12432 if (ThenCS->body_empty()) {
12433 ErrorInfo.Error = ErrorTy::NoStmt;
12434 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12435 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12438 if (ThenCS->size() > 1) {
12439 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12440 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12441 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12444 Then = ThenCS->body_front();
12447 auto *ThenBO = dyn_cast<BinaryOperator>(Then);
12449 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12450 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getBeginLoc();
12451 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S2->getSourceRange();
12454 if (ThenBO->getOpcode() != BO_Assign) {
12455 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12456 ErrorInfo.ErrorLoc = ThenBO->getExprLoc();
12457 ErrorInfo.NoteLoc = ThenBO->getOperatorLoc();
12458 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenBO->getSourceRange();
12462 X = ThenBO->getLHS();
12463 D = ThenBO->getRHS();
12465 auto *BO = cast<BinaryOperator>(S1->getRHS()->IgnoreImpCasts());
12466 if (BO->getOpcode() != BO_EQ) {
12467 ErrorInfo.Error = ErrorTy::NotEQ;
12468 ErrorInfo.ErrorLoc = BO->getExprLoc();
12469 ErrorInfo.NoteLoc = BO->getOperatorLoc();
12470 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12476 if (checkIfTwoExprsAreSame(ContextRef,
X, BO->getLHS())) {
12478 }
else if (checkIfTwoExprsAreSame(ContextRef,
X, BO->getRHS())) {
12481 ErrorInfo.Error = ErrorTy::InvalidComparison;
12482 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->
getExprLoc();
12483 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12487 if (S2->getElse()) {
12490 auto *Else = S2->getElse();
12491 if (
auto *ElseCS = dyn_cast<CompoundStmt>(Else)) {
12492 if (ElseCS->body_empty()) {
12493 ErrorInfo.Error = ErrorTy::NoStmt;
12494 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12495 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12498 if (ElseCS->size() > 1) {
12499 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12500 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12501 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12504 Else = ElseCS->body_front();
12507 auto *ElseBO = dyn_cast<BinaryOperator>(Else);
12509 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12510 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
12511 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
12514 if (ElseBO->getOpcode() != BO_Assign) {
12515 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12516 ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
12517 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12518 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12521 if (!checkIfTwoExprsAreSame(ContextRef,
X, ElseBO->getRHS())) {
12522 ErrorInfo.Error = ErrorTy::InvalidAssignment;
12523 ErrorInfo.ErrorLoc = ElseBO->getRHS()->getExprLoc();
12524 ErrorInfo.NoteLoc =
X->getExprLoc();
12525 ErrorInfo.ErrorRange = ElseBO->getRHS()->getSourceRange();
12526 ErrorInfo.NoteRange =
X->getSourceRange();
12530 V = ElseBO->getLHS();
12533 return checkType(ErrorInfo);
12536bool OpenMPAtomicCompareCaptureChecker::checkStmt(
Stmt *S,
12537 ErrorInfoTy &ErrorInfo) {
12539 if (
auto *IS = dyn_cast<IfStmt>(S))
12540 return checkForm3(IS, ErrorInfo);
12542 auto *CS = dyn_cast<CompoundStmt>(S);
12544 ErrorInfo.Error = ErrorTy::NotCompoundStmt;
12545 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12546 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12549 if (CS->body_empty()) {
12550 ErrorInfo.Error = ErrorTy::NoStmt;
12551 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12552 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12557 if (CS->size() == 1) {
12558 auto *IS = dyn_cast<IfStmt>(CS->body_front());
12560 ErrorInfo.Error = ErrorTy::NotIfStmt;
12561 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->body_front()->
getBeginLoc();
12562 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12567 return checkForm3(IS, ErrorInfo);
12568 }
else if (CS->size() == 2) {
12569 auto *S1 = CS->body_front();
12570 auto *S2 = CS->body_back();
12572 Stmt *UpdateStmt =
nullptr;
12573 Stmt *CondUpdateStmt =
nullptr;
12574 Stmt *CondExprStmt =
nullptr;
12576 if (
auto *BO = dyn_cast<BinaryOperator>(S1)) {
12582 if (isa<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) ||
12583 isa<ConditionalOperator>(BO->getRHS()->IgnoreImpCasts())) {
12585 if (isa<IfStmt>(S2))
12586 return checkForm45(CS, ErrorInfo);
12591 IsPostfixUpdate =
true;
12593 if (isa<IfStmt>(S2)) {
12595 CondUpdateStmt = S2;
12604 CondUpdateStmt = S1;
12607 auto CheckCondUpdateStmt = [
this, &ErrorInfo](
Stmt *CUS) {
12608 auto *IS = dyn_cast<IfStmt>(CUS);
12610 ErrorInfo.Error = ErrorTy::NotIfStmt;
12611 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CUS->getBeginLoc();
12612 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CUS->getSourceRange();
12616 return checkCondUpdateStmt(IS, ErrorInfo);
12620 auto CheckUpdateStmt = [
this, &ErrorInfo](
Stmt *US) {
12621 auto *BO = dyn_cast<BinaryOperator>(US);
12623 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12624 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = US->getBeginLoc();
12625 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = US->getSourceRange();
12628 if (BO->getOpcode() != BO_Assign) {
12629 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12630 ErrorInfo.ErrorLoc = BO->getExprLoc();
12631 ErrorInfo.NoteLoc = BO->getOperatorLoc();
12632 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12635 if (!checkIfTwoExprsAreSame(ContextRef, this->X, BO->getRHS())) {
12636 ErrorInfo.Error = ErrorTy::InvalidAssignment;
12637 ErrorInfo.ErrorLoc = BO->getRHS()->getExprLoc();
12639 ErrorInfo.ErrorRange = BO->getRHS()->getSourceRange();
12644 this->
V = BO->getLHS();
12649 if (CondUpdateStmt && !CheckCondUpdateStmt(CondUpdateStmt))
12651 if (CondExprStmt && !checkCondExprStmt(CondExprStmt, ErrorInfo))
12653 if (!CheckUpdateStmt(UpdateStmt))
12656 ErrorInfo.Error = ErrorTy::MoreThanTwoStmts;
12657 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12658 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12662 return checkType(ErrorInfo);
12671 DSAStack->addAtomicDirectiveLoc(StartLoc);
12684 bool MutexClauseEncountered =
false;
12685 llvm::SmallSet<OpenMPClauseKind, 2> EncounteredAtomicKinds;
12687 switch (
C->getClauseKind()) {
12691 MutexClauseEncountered =
true;
12694 case OMPC_compare: {
12695 if (AtomicKind != OMPC_unknown && MutexClauseEncountered) {
12696 Diag(
C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12698 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12699 << getOpenMPClauseName(AtomicKind);
12701 AtomicKind =
C->getClauseKind();
12702 AtomicKindLoc =
C->getBeginLoc();
12703 if (!EncounteredAtomicKinds.insert(
C->getClauseKind()).second) {
12704 Diag(
C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12706 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12707 << getOpenMPClauseName(AtomicKind);
12714 if (!EncounteredAtomicKinds.contains(OMPC_compare)) {
12715 Diag(
C->getBeginLoc(), diag::err_omp_atomic_no_compare)
12716 << getOpenMPClauseName(
C->getClauseKind())
12726 case OMPC_relaxed: {
12727 if (MemOrderKind != OMPC_unknown) {
12728 Diag(
C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
12729 << getOpenMPDirectiveName(OMPD_atomic) << 0
12731 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12732 << getOpenMPClauseName(MemOrderKind);
12734 MemOrderKind =
C->getClauseKind();
12735 MemOrderLoc =
C->getBeginLoc();
12743 llvm_unreachable(
"unknown clause is encountered");
12746 bool IsCompareCapture =
false;
12747 if (EncounteredAtomicKinds.contains(OMPC_compare) &&
12748 EncounteredAtomicKinds.contains(OMPC_capture)) {
12749 IsCompareCapture =
true;
12750 AtomicKind = OMPC_compare;
12759 if ((AtomicKind == OMPC_read &&
12760 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
12761 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
12762 AtomicKind == OMPC_unknown) &&
12763 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
12765 if (AtomicKind == OMPC_unknown)
12767 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
12768 << getOpenMPClauseName(AtomicKind)
12769 << (AtomicKind == OMPC_unknown ? 1 : 0)
12770 << getOpenMPClauseName(MemOrderKind);
12771 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12772 << getOpenMPClauseName(MemOrderKind);
12775 Stmt *Body = AStmt;
12776 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Body))
12777 Body = EWC->getSubExpr();
12782 Expr *UE =
nullptr;
12784 Expr *CE =
nullptr;
12786 bool IsXLHSInRHSPart =
false;
12787 bool IsPostfixUpdate =
false;
12788 bool IsFailOnly =
false;
12811 if (AtomicKind == OMPC_read) {
12818 } ErrorFound = NoError;
12823 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12824 const auto *AtomicBinOp =
12825 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12826 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
12829 if ((
X->isInstantiationDependent() ||
X->getType()->isScalarType()) &&
12830 (
V->isInstantiationDependent() ||
V->getType()->isScalarType())) {
12831 if (!
X->isLValue() || !
V->isLValue()) {
12832 const Expr *NotLValueExpr =
X->isLValue() ?
V :
X;
12833 ErrorFound = NotAnLValue;
12839 }
else if (!
X->isInstantiationDependent() ||
12840 !
V->isInstantiationDependent()) {
12841 const Expr *NotScalarExpr =
12842 (
X->isInstantiationDependent() ||
X->getType()->isScalarType())
12845 ErrorFound = NotAScalarType;
12851 }
else if (!AtomicBody->isInstantiationDependent()) {
12852 ErrorFound = NotAnAssignmentOp;
12853 ErrorLoc = AtomicBody->getExprLoc();
12854 ErrorRange = AtomicBody->getSourceRange();
12856 : AtomicBody->getExprLoc();
12858 : AtomicBody->getSourceRange();
12861 ErrorFound = NotAnExpression;
12863 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
12865 if (ErrorFound != NoError) {
12866 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
12868 Diag(NoteLoc, diag::note_omp_atomic_read_write)
12869 << ErrorFound << NoteRange;
12874 }
else if (AtomicKind == OMPC_write) {
12881 } ErrorFound = NoError;
12886 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12887 const auto *AtomicBinOp =
12888 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12889 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
12891 E = AtomicBinOp->
getRHS();
12892 if ((
X->isInstantiationDependent() ||
X->getType()->isScalarType()) &&
12894 if (!
X->isLValue()) {
12895 ErrorFound = NotAnLValue;
12898 NoteLoc =
X->getExprLoc();
12899 NoteRange =
X->getSourceRange();
12901 }
else if (!
X->isInstantiationDependent() ||
12903 const Expr *NotScalarExpr =
12904 (
X->isInstantiationDependent() ||
X->getType()->isScalarType())
12907 ErrorFound = NotAScalarType;
12913 }
else if (!AtomicBody->isInstantiationDependent()) {
12914 ErrorFound = NotAnAssignmentOp;
12915 ErrorLoc = AtomicBody->getExprLoc();
12916 ErrorRange = AtomicBody->getSourceRange();
12918 : AtomicBody->getExprLoc();
12920 : AtomicBody->getSourceRange();
12923 ErrorFound = NotAnExpression;
12925 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
12927 if (ErrorFound != NoError) {
12928 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
12930 Diag(NoteLoc, diag::note_omp_atomic_read_write)
12931 << ErrorFound << NoteRange;
12936 }
else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
12945 OpenMPAtomicUpdateChecker Checker(*
this);
12946 if (Checker.checkStatement(
12948 (AtomicKind == OMPC_update)
12949 ? diag::err_omp_atomic_update_not_expression_statement
12950 : diag::err_omp_atomic_not_expression_statement,
12951 diag::note_omp_atomic_update))
12954 E = Checker.getExpr();
12955 X = Checker.getX();
12956 UE = Checker.getUpdateExpr();
12957 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12959 }
else if (AtomicKind == OMPC_capture) {
12962 NotACompoundStatement,
12963 NotTwoSubstatements,
12964 NotASpecificExpression,
12966 } ErrorFound = NoError;
12969 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12978 const auto *AtomicBinOp =
12979 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12980 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
12983 OpenMPAtomicUpdateChecker Checker(*
this);
12984 if (Checker.checkStatement(
12985 Body, diag::err_omp_atomic_capture_not_expression_statement,
12986 diag::note_omp_atomic_update))
12988 E = Checker.getExpr();
12989 X = Checker.getX();
12990 UE = Checker.getUpdateExpr();
12991 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12992 IsPostfixUpdate = Checker.isPostfixUpdate();
12993 }
else if (!AtomicBody->isInstantiationDependent()) {
12994 ErrorLoc = AtomicBody->getExprLoc();
12995 ErrorRange = AtomicBody->getSourceRange();
12997 : AtomicBody->getExprLoc();
12999 : AtomicBody->getSourceRange();
13000 ErrorFound = NotAnAssignmentOp;
13002 if (ErrorFound != NoError) {
13003 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
13005 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
13009 UE =
V = E =
X =
nullptr;
13027 if (
auto *CS = dyn_cast<CompoundStmt>(Body)) {
13029 if (CS->size() == 2) {
13031 Stmt *Second = CS->body_back();
13032 if (
auto *EWC = dyn_cast<ExprWithCleanups>(
First))
13033 First = EWC->getSubExpr()->IgnoreParenImpCasts();
13034 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Second))
13035 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
13037 OpenMPAtomicUpdateChecker Checker(*
this);
13038 bool IsUpdateExprFound = !Checker.checkStatement(Second);
13040 if (IsUpdateExprFound) {
13041 BinOp = dyn_cast<BinaryOperator>(
First);
13042 IsUpdateExprFound = BinOp && BinOp->
getOpcode() == BO_Assign;
13054 llvm::FoldingSetNodeID XId, PossibleXId;
13057 IsUpdateExprFound = XId == PossibleXId;
13058 if (IsUpdateExprFound) {
13060 X = Checker.getX();
13061 E = Checker.getExpr();
13062 UE = Checker.getUpdateExpr();
13063 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
13064 IsPostfixUpdate =
true;
13067 if (!IsUpdateExprFound) {
13068 IsUpdateExprFound = !Checker.checkStatement(
First);
13070 if (IsUpdateExprFound) {
13071 BinOp = dyn_cast<BinaryOperator>(Second);
13072 IsUpdateExprFound = BinOp && BinOp->
getOpcode() == BO_Assign;
13084 llvm::FoldingSetNodeID XId, PossibleXId;
13087 IsUpdateExprFound = XId == PossibleXId;
13088 if (IsUpdateExprFound) {
13090 X = Checker.getX();
13091 E = Checker.getExpr();
13092 UE = Checker.getUpdateExpr();
13093 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
13094 IsPostfixUpdate =
false;
13098 if (!IsUpdateExprFound) {
13100 auto *FirstExpr = dyn_cast<Expr>(
First);
13101 auto *SecondExpr = dyn_cast<Expr>(Second);
13102 if (!FirstExpr || !SecondExpr ||
13103 !(FirstExpr->isInstantiationDependent() ||
13104 SecondExpr->isInstantiationDependent())) {
13105 auto *FirstBinOp = dyn_cast<BinaryOperator>(
First);
13106 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
13107 ErrorFound = NotAnAssignmentOp;
13108 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
13109 :
First->getBeginLoc();
13110 NoteRange = ErrorRange = FirstBinOp
13111 ? FirstBinOp->getSourceRange()
13114 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
13115 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
13116 ErrorFound = NotAnAssignmentOp;
13117 NoteLoc = ErrorLoc = SecondBinOp
13118 ? SecondBinOp->getOperatorLoc()
13120 NoteRange = ErrorRange =
13121 SecondBinOp ? SecondBinOp->getSourceRange()
13124 Expr *PossibleXRHSInFirst =
13126 Expr *PossibleXLHSInSecond =
13128 llvm::FoldingSetNodeID X1Id, X2Id;
13133 IsUpdateExprFound = X1Id == X2Id;
13134 if (IsUpdateExprFound) {
13135 V = FirstBinOp->getLHS();
13136 X = SecondBinOp->getLHS();
13137 E = SecondBinOp->getRHS();
13139 IsXLHSInRHSPart =
false;
13140 IsPostfixUpdate =
true;
13142 ErrorFound = NotASpecificExpression;
13143 ErrorLoc = FirstBinOp->getExprLoc();
13144 ErrorRange = FirstBinOp->getSourceRange();
13145 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
13146 NoteRange = SecondBinOp->getRHS()->getSourceRange();
13154 NoteRange = ErrorRange =
13156 ErrorFound = NotTwoSubstatements;
13160 NoteRange = ErrorRange =
13162 ErrorFound = NotACompoundStatement;
13165 if (ErrorFound != NoError) {
13166 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
13168 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
13172 UE =
V = E =
X =
nullptr;
13173 }
else if (AtomicKind == OMPC_compare) {
13174 if (IsCompareCapture) {
13175 OpenMPAtomicCompareCaptureChecker::ErrorInfoTy ErrorInfo;
13176 OpenMPAtomicCompareCaptureChecker Checker(*
this);
13177 if (!Checker.checkStmt(Body, ErrorInfo)) {
13178 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare_capture)
13179 << ErrorInfo.ErrorRange;
13180 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
13181 << ErrorInfo.Error << ErrorInfo.NoteRange;
13184 X = Checker.getX();
13185 E = Checker.getE();
13186 D = Checker.getD();
13187 CE = Checker.getCond();
13188 V = Checker.getV();
13189 R = Checker.getR();
13191 IsXLHSInRHSPart = Checker.isXBinopExpr();
13192 IsFailOnly = Checker.isFailOnly();
13193 IsPostfixUpdate = Checker.isPostfixUpdate();
13195 OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo;
13196 OpenMPAtomicCompareChecker Checker(*
this);
13197 if (!Checker.checkStmt(Body, ErrorInfo)) {
13198 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare)
13199 << ErrorInfo.ErrorRange;
13200 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
13201 << ErrorInfo.Error << ErrorInfo.NoteRange;
13204 X = Checker.getX();
13205 E = Checker.getE();
13206 D = Checker.getD();
13207 CE = Checker.getCond();
13213 auto *It = find_if(Clauses, [](
OMPClause *
C) {
13214 return C->getClauseKind() == llvm::omp::Clause::OMPC_weak;
13216 if (It != Clauses.end()) {
13217 auto *Cond = dyn_cast<BinaryOperator>(CE);
13218 if (Cond->getOpcode() != BO_EQ) {
13219 ErrorInfo.Error = Checker.ErrorTy::NotAnAssignment;
13221 ErrorInfo.NoteLoc = Cond->getOperatorLoc();
13222 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
13224 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_weak_no_equality)
13225 << ErrorInfo.ErrorRange;
13230 IsXLHSInRHSPart = Checker.isXBinopExpr();
13237 Context, StartLoc, EndLoc, Clauses, AStmt,
13238 {
X,
V, R, E, UE, D, CE, IsXLHSInRHSPart, IsPostfixUpdate, IsFailOnly});
13248 auto *CS = cast<CapturedStmt>(AStmt);
13256 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13270 if (
DSAStack->hasInnerTeamsRegion()) {
13272 bool OMPTeamsFound =
true;
13273 if (
const auto *CS = dyn_cast<CompoundStmt>(S)) {
13274 auto I = CS->body_begin();
13275 while (I != CS->body_end()) {
13276 const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
13280 OMPTeamsFound =
false;
13285 assert(I != CS->body_end() &&
"Not found statement");
13288 const auto *OED = dyn_cast<OMPExecutableDirective>(S);
13291 if (!OMPTeamsFound) {
13292 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
13294 diag::note_omp_nested_teams_construct_here);
13295 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
13296 << isa<OMPExecutableDirective>(S);
13313 auto *CS = cast<CapturedStmt>(AStmt);
13321 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13334 Context, StartLoc, EndLoc, Clauses, AStmt,
13344 auto *CS = cast<CapturedStmt>(AStmt);
13352 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13365 unsigned NestedLoopCount =
13368 VarsWithImplicitDSA, B);
13369 if (NestedLoopCount == 0)
13373 "omp target parallel for loop exprs were not built");
13378 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
13388 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13395 return llvm::any_of(
13396 Clauses, [K](
const OMPClause *
C) {
return C->getClauseKind() == K; });
13399template <
typename... Params>
13401 const Params... ClauseTypes) {
13408 if (
auto *TC = dyn_cast<OMPToClause>(
C))
13409 return llvm::all_of(TC->all_decls(), [](
ValueDecl *VD) {
13410 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13411 (VD->isExternallyVisible() &&
13412 VD->getVisibility() != HiddenVisibility);
13414 else if (
auto *FC = dyn_cast<OMPFromClause>(
C))
13415 return llvm::all_of(FC->all_decls(), [](
ValueDecl *VD) {
13416 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13417 (VD->isExternallyVisible() &&
13418 VD->getVisibility() != HiddenVisibility);
13432 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13437 if (!
hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
13441 Expected =
"'map' or 'use_device_ptr'";
13443 Expected =
"'map', 'use_device_ptr', or 'use_device_addr'";
13444 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13445 <<
Expected << getOpenMPDirectiveName(OMPD_target_data);
13462 auto *CS = cast<CapturedStmt>(AStmt);
13470 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13483 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13484 <<
"'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
13499 auto *CS = cast<CapturedStmt>(AStmt);
13507 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13520 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13521 <<
"'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
13536 auto *CS = cast<CapturedStmt>(AStmt);
13544 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13554 if (!
hasClauses(Clauses, OMPC_to, OMPC_from)) {
13555 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
13560 Diag(StartLoc, diag::err_omp_cannot_update_with_internal_linkage);
13576 Diag(StartLoc, diag::warn_hip_omp_target_directives);
13578 auto *CS = cast<CapturedStmt>(AStmt);
13588 DSAStack->setParentTeamsRegionLoc(StartLoc);
13597 if (
DSAStack->isParentNowaitRegion()) {
13598 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
13601 if (
DSAStack->isParentOrderedRegion()) {
13602 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
13613 if (
DSAStack->isParentNowaitRegion()) {
13614 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
13617 if (
DSAStack->isParentOrderedRegion()) {
13618 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
13621 DSAStack->setParentCancelRegion(
true);
13628 const OMPClause *ReductionClause =
nullptr;
13629 const OMPClause *NogroupClause =
nullptr;
13631 if (
C->getClauseKind() == OMPC_reduction) {
13632 ReductionClause =
C;
13637 if (
C->getClauseKind() == OMPC_nogroup) {
13639 if (ReductionClause)
13644 if (ReductionClause && NogroupClause) {
13645 S.
Diag(ReductionClause->
getBeginLoc(), diag::err_omp_reduction_with_nogroup)
13659 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13663 unsigned NestedLoopCount =
13666 VarsWithImplicitDSA, B);
13667 if (NestedLoopCount == 0)
13671 "omp for loop exprs were not built");
13677 {OMPC_grainsize, OMPC_num_tasks}))
13687 NestedLoopCount, Clauses, AStmt, B,
13697 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13701 unsigned NestedLoopCount =
13704 VarsWithImplicitDSA, B);
13705 if (NestedLoopCount == 0)
13709 "omp for loop exprs were not built");
13714 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
13726 {OMPC_grainsize, OMPC_num_tasks}))
13738 NestedLoopCount, Clauses, AStmt, B);
13747 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13751 unsigned NestedLoopCount =
13754 VarsWithImplicitDSA, B);
13755 if (NestedLoopCount == 0)
13759 "omp for loop exprs were not built");
13765 {OMPC_grainsize, OMPC_num_tasks}))
13775 NestedLoopCount, Clauses, AStmt, B,
13785 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13789 unsigned NestedLoopCount =
13792 VarsWithImplicitDSA, B);
13793 if (NestedLoopCount == 0)
13797 "omp for loop exprs were not built");
13803 {OMPC_grainsize, OMPC_num_tasks}))
13813 NestedLoopCount, Clauses, AStmt, B,
13823 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13827 unsigned NestedLoopCount =
13830 VarsWithImplicitDSA, B);
13831 if (NestedLoopCount == 0)
13835 "omp for loop exprs were not built");
13840 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
13852 {OMPC_grainsize, OMPC_num_tasks}))
13864 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13873 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13877 unsigned NestedLoopCount =
13880 VarsWithImplicitDSA, B);
13881 if (NestedLoopCount == 0)
13885 "omp for loop exprs were not built");
13890 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
13902 {OMPC_grainsize, OMPC_num_tasks}))
13914 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13923 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13924 auto *CS = cast<CapturedStmt>(AStmt);
13931 for (
int ThisCaptureLevel =
13933 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13949 VarsWithImplicitDSA, B);
13950 if (NestedLoopCount == 0)
13954 "omp for loop exprs were not built");
13960 {OMPC_grainsize, OMPC_num_tasks}))
13970 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13980 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13981 auto *CS = cast<CapturedStmt>(AStmt);
13988 for (
int ThisCaptureLevel =
13990 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14006 VarsWithImplicitDSA, B);
14007 if (NestedLoopCount == 0)
14011 "omp for loop exprs were not built");
14017 {OMPC_grainsize, OMPC_num_tasks}))
14027 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14037 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
14038 auto *CS = cast<CapturedStmt>(AStmt);
14045 for (
int ThisCaptureLevel =
14047 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14063 VarsWithImplicitDSA, B);
14064 if (NestedLoopCount == 0)
14068 "omp for loop exprs were not built");
14073 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14085 {OMPC_grainsize, OMPC_num_tasks}))
14097 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14106 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
14107 auto *CS = cast<CapturedStmt>(AStmt);
14114 for (
int ThisCaptureLevel =
14116 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14132 VarsWithImplicitDSA, B);
14133 if (NestedLoopCount == 0)
14137 "omp for loop exprs were not built");
14142 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14154 {OMPC_grainsize, OMPC_num_tasks}))
14166 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14175 if (!checkLastPrivateForMappedDirectives(Clauses))
14178 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
14182 unsigned NestedLoopCount =
14185 *
this, *
DSAStack, VarsWithImplicitDSA, B);
14186 if (NestedLoopCount == 0)
14190 "omp for loop exprs were not built");
14194 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14196 return DistributeDirective;
14205 auto *CS = cast<CapturedStmt>(AStmt);
14212 for (
int ThisCaptureLevel =
14214 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14230 VarsWithImplicitDSA, B);
14231 if (NestedLoopCount == 0)
14235 "omp for loop exprs were not built");
14239 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14249 auto *CS = cast<CapturedStmt>(AStmt);
14256 for (
int ThisCaptureLevel =
14258 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14274 VarsWithImplicitDSA, B);
14275 if (NestedLoopCount == 0)
14279 "omp for loop exprs were not built");
14284 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14297 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14306 auto *CS = cast<CapturedStmt>(AStmt);
14314 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14327 unsigned NestedLoopCount =
14329 nullptr , CS, *
this,
14330 *
DSAStack, VarsWithImplicitDSA, B);
14331 if (NestedLoopCount == 0)
14335 "omp for loop exprs were not built");
14340 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14353 NestedLoopCount, Clauses, AStmt, B);
14362 auto *CS = cast<CapturedStmt>(AStmt);
14369 for (
int ThisCaptureLevel =
14371 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14388 if (NestedLoopCount == 0)
14392 "omp target parallel for simd loop exprs were not built");
14397 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14409 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14418 auto *CS = cast<CapturedStmt>(AStmt);
14426 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14439 unsigned NestedLoopCount =
14442 VarsWithImplicitDSA, B);
14443 if (NestedLoopCount == 0)
14447 "omp target simd loop exprs were not built");
14452 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14465 NestedLoopCount, Clauses, AStmt, B);
14474 auto *CS = cast<CapturedStmt>(AStmt);
14482 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14495 unsigned NestedLoopCount =
14497 nullptr , CS, *
this,
14498 *
DSAStack, VarsWithImplicitDSA, B);
14499 if (NestedLoopCount == 0)
14503 "omp teams distribute loop exprs were not built");
14507 DSAStack->setParentTeamsRegionLoc(StartLoc);
14510 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14519 auto *CS = cast<CapturedStmt>(AStmt);
14526 for (
int ThisCaptureLevel =
14528 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14544 VarsWithImplicitDSA, B);
14546 if (NestedLoopCount == 0)
14550 "omp teams distribute simd loop exprs were not built");
14555 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14568 DSAStack->setParentTeamsRegionLoc(StartLoc);
14571 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14580 auto *CS = cast<CapturedStmt>(AStmt);
14588 for (
int ThisCaptureLevel =
14590 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14606 VarsWithImplicitDSA, B);
14608 if (NestedLoopCount == 0)
14612 "omp for loop exprs were not built");
14617 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14630 DSAStack->setParentTeamsRegionLoc(StartLoc);
14633 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14642 auto *CS = cast<CapturedStmt>(AStmt);
14650 for (
int ThisCaptureLevel =
14652 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14668 VarsWithImplicitDSA, B);
14670 if (NestedLoopCount == 0)
14674 "omp for loop exprs were not built");
14678 DSAStack->setParentTeamsRegionLoc(StartLoc);
14681 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14692 auto *CS = cast<CapturedStmt>(AStmt);
14701 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14713 bool HasThreadLimitAndNumTeamsClause =
hasClauses(Clauses, OMPC_num_teams) &&
14715 bool HasBareClause = llvm::any_of(Clauses, [&](
const OMPClause *
C) {
14717 return C->getClauseKind() == OMPC_ompx_bare;
14720 if (HasBareClause && !HasThreadLimitAndNumTeamsClause) {
14735 auto *CS = cast<CapturedStmt>(AStmt);
14742 for (
int ThisCaptureLevel =
14744 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14760 VarsWithImplicitDSA, B);
14761 if (NestedLoopCount == 0)
14765 "omp target teams distribute loop exprs were not built");
14769 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14778 auto *CS = cast<CapturedStmt>(AStmt);
14785 for (
int ThisCaptureLevel =
14787 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14803 VarsWithImplicitDSA, B);
14804 if (NestedLoopCount == 0)
14808 "omp target teams distribute parallel for loop exprs were not built");
14813 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14823 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14833 auto *CS = cast<CapturedStmt>(AStmt);
14841 OMPD_target_teams_distribute_parallel_for_simd);
14842 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14855 unsigned NestedLoopCount =
14858 nullptr , CS, *
this,
14859 *
DSAStack, VarsWithImplicitDSA, B);
14860 if (NestedLoopCount == 0)
14864 "omp target teams distribute parallel for simd loop exprs were not "
14870 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14883 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14892 auto *CS = cast<CapturedStmt>(AStmt);
14899 for (
int ThisCaptureLevel =
14901 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14917 VarsWithImplicitDSA, B);
14918 if (NestedLoopCount == 0)
14922 "omp target teams distribute simd loop exprs were not built");
14927 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14940 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14943bool Sema::checkTransformableLoopNest(
14949 OriginalInits.emplace_back();
14952 [
this, &LoopHelpers, &Body, &OriginalInits, Kind](
unsigned Cnt,
14954 VarsWithInheritedDSAType TmpDSA;
14955 unsigned SingleNumLoops =
14956 checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, *this, *DSAStack,
14957 TmpDSA, LoopHelpers[Cnt]);
14958 if (SingleNumLoops == 0)
14960 assert(SingleNumLoops == 1 &&
"Expect single loop iteration space");
14961 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
14962 OriginalInits.back().push_back(For->getInit());
14963 Body = For->getBody();
14965 assert(isa<CXXForRangeStmt>(CurStmt) &&
14966 "Expected canonical for or range-based for loops.");
14967 auto *CXXFor = cast<CXXForRangeStmt>(CurStmt);
14968 OriginalInits.back().push_back(CXXFor->getBeginStmt());
14969 Body = CXXFor->getBody();
14971 OriginalInits.emplace_back();
14975 Stmt *DependentPreInits;
14976 if (
auto *Dir = dyn_cast<OMPTileDirective>(Transform))
14977 DependentPreInits = Dir->getPreInits();
14978 else if (
auto *Dir = dyn_cast<OMPUnrollDirective>(Transform))
14979 DependentPreInits = Dir->getPreInits();
14981 llvm_unreachable(
"Unhandled loop transformation");
14982 if (!DependentPreInits)
14984 llvm::append_range(OriginalInits.back(),
14985 cast<DeclStmt>(DependentPreInits)->getDeclGroup());
14987 assert(OriginalInits.back().empty() &&
"No preinit after innermost loop");
14988 OriginalInits.pop_back();
14995 auto SizesClauses =
14996 OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses);
14997 if (SizesClauses.empty()) {
15010 Stmt *Body =
nullptr;
15013 if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body,
15020 NumLoops, AStmt,
nullptr,
nullptr);
15027 FloorIndVars.resize(NumLoops);
15028 TileIndVars.resize(NumLoops);
15029 for (
unsigned I = 0; I < NumLoops; ++I) {
15032 assert(LoopHelper.
Counters.size() == 1 &&
15033 "Expect single-dimensional loop iteration space");
15034 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.
Counters.front());
15035 std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
15041 std::string FloorCntName =
15042 (Twine(
".floor_") + llvm::utostr(I) +
".iv." + OrigVarName).str();
15044 buildVarDecl(*
this, {}, CntTy, FloorCntName,
nullptr, OrigCntVar);
15045 FloorIndVars[I] = FloorCntDecl;
15050 std::string TileCntName =
15051 (Twine(
".tile_") + llvm::utostr(I) +
".iv." + OrigVarName).str();
15056 auto *TileCntDecl = cast<VarDecl>(IterVarRef->
getDecl());
15058 TileIndVars[I] = TileCntDecl;
15060 for (
auto &
P : OriginalInits[I]) {
15061 if (
auto *D =
P.dyn_cast<
Decl *>())
15062 PreInits.push_back(D);
15063 else if (
auto *PI = dyn_cast_or_null<DeclStmt>(
P.dyn_cast<
Stmt *>()))
15064 PreInits.append(PI->decl_begin(), PI->decl_end());
15066 if (
auto *PI = cast_or_null<DeclStmt>(LoopHelper.
PreInits))
15067 PreInits.append(PI->decl_begin(), PI->decl_end());
15070 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
15071 if (isa<OMPCapturedExprDecl>(CounterDecl))
15072 PreInits.push_back(CounterDecl);
15077 Stmt *Inner = Body;
15080 for (
int I = NumLoops - 1; I >= 0; --I) {
15083 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.
Counters[0]);
15084 QualType CntTy = OrigCntVar->getType();
15090 OrigCntVar->getExprLoc());
15092 OrigCntVar->getExprLoc());
15097 Decl *CounterDecl = TileIndVars[I];
15100 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
15107 BO_Add, FloorIV, DimTileSize);
15112 NumIterations, EndOfTile.
get());
15117 IsPartialTile.
get(), NumIterations, EndOfTile.
get());
15118 if (!MinTileAndIterSpace.
isUsable())
15121 BO_LT, TileIV, MinTileAndIterSpace.
get());
15145 BodyParts.append(LoopHelper.
Updates.begin(), LoopHelper.
Updates.end());
15146 BodyParts.push_back(Inner);
15148 Inner->getBeginLoc(), Inner->getEndLoc());
15156 for (
int I = NumLoops - 1; I >= 0; --I) {
15157 auto &LoopHelper = LoopHelpers[I];
15158 Expr *NumIterations = LoopHelper.NumIterations;
15159 DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
15173 Decl *CounterDecl = FloorIndVars[I];
15182 BO_LT, FloorIV, NumIterations);
15188 BO_AddAssign, FloorIV, DimTileSize);
15194 IncrStmt.
get(), Inner, LoopHelper.Init->getBeginLoc(),
15195 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15215 OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses);
15217 OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses);
15218 assert(!(FullClause && PartialClause) &&
15219 "mutual exclusivity must have been checked before");
15221 constexpr unsigned NumLoops = 1;
15222 Stmt *Body =
nullptr;
15227 if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers,
15228 Body, OriginalInits))
15231 unsigned NumGeneratedLoops = PartialClause ? 1 : 0;
15236 NumGeneratedLoops,
nullptr,
nullptr);
15245 Diag(AStmt->
getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count);
15247 <<
"#pragma omp unroll full";
15255 if (NumGeneratedLoops == 0)
15257 NumGeneratedLoops,
nullptr,
nullptr);
15303 assert(OriginalInits.size() == 1 &&
15304 "Expecting a single-dimensional loop iteration space");
15305 for (
auto &
P : OriginalInits[0]) {
15306 if (
auto *D =
P.dyn_cast<
Decl *>())
15307 PreInits.push_back(D);
15308 else if (
auto *PI = dyn_cast_or_null<DeclStmt>(
P.dyn_cast<
Stmt *>()))
15309 PreInits.append(PI->decl_begin(), PI->decl_end());
15311 if (
auto *PI = cast_or_null<DeclStmt>(LoopHelper.
PreInits))
15312 PreInits.append(PI->decl_begin(), PI->decl_end());
15315 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
15316 if (isa<OMPCapturedExprDecl>(CounterDecl))
15317 PreInits.push_back(CounterDecl);
15320 auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.
IterationVarRef);
15321 QualType IVTy = IterationVarRef->getType();
15322 assert(LoopHelper.
Counters.size() == 1 &&
15323 "Expecting a single-dimensional loop iteration space");
15324 auto *OrigVar = cast<DeclRefExpr>(LoopHelper.
Counters.front());
15330 Factor = FactorVal->getIntegerConstantExpr(
Context)->getZExtValue();
15331 FactorLoc = FactorVal->getExprLoc();
15336 assert(Factor > 0 &&
"Expected positive unroll factor");
15337 auto MakeFactorExpr = [
this, Factor, IVTy, FactorLoc]() {
15349 std::string OrigVarName = OrigVar->getNameInfo().getAsString();
15350 std::string OuterIVName = (Twine(
".unrolled.iv.") + OrigVarName).str();
15351 std::string InnerIVName = (Twine(
".unroll_inner.iv.") + OrigVarName).str();
15352 std::string InnerTripCountName =
15353 (Twine(
".unroll_inner.tripcount.") + OrigVarName).str();
15357 buildVarDecl(*
this, {}, IVTy, OuterIVName,
nullptr, OrigVar);
15358 auto MakeOuterRef = [
this, OuterIVDecl, IVTy, OrigVarLoc]() {
15364 auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl());
15366 auto MakeInnerRef = [
this, InnerIVDecl, IVTy, OrigVarLoc]() {
15372 CaptureVars CopyTransformer(*
this);
15373 auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() ->
Expr * {
15394 BO_Add, MakeOuterRef(), MakeFactorExpr());
15398 BO_LT, MakeInnerRef(), EndOfTile.
get());
15403 MakeNumIterations());
15408 InnerCond1.
get(), InnerCond2.
get());
15414 UO_PreInc, MakeInnerRef());
15420 InnerBodyStmts.append(LoopHelper.
Updates.begin(), LoopHelper.
Updates.end());
15421 InnerBodyStmts.push_back(Body);
15442 LoopHintAttr *UnrollHintAttr =
15443 LoopHintAttr::CreateImplicit(
Context, LoopHintAttr::UnrollCount,
15444 LoopHintAttr::Numeric, MakeFactorExpr());
15460 MakeNumIterations());
15467 MakeOuterRef(), MakeFactorExpr());
15478 NumGeneratedLoops, OuterFor,
15491 case OMPC_num_threads:
15500 case OMPC_allocator:
15503 case OMPC_collapse:
15509 case OMPC_num_teams:
15512 case OMPC_thread_limit:
15515 case OMPC_priority:
15527 case OMPC_novariants:
15530 case OMPC_nocontext:
15545 case OMPC_ompx_dyn_cgroup_mem:
15548 case OMPC_grainsize:
15549 case OMPC_num_tasks:
15553 case OMPC_proc_bind:
15554 case OMPC_schedule:
15556 case OMPC_firstprivate:
15557 case OMPC_lastprivate:
15559 case OMPC_reduction:
15560 case OMPC_task_reduction:
15561 case OMPC_in_reduction:
15565 case OMPC_copyprivate:
15568 case OMPC_mergeable:
15569 case OMPC_threadprivate:
15571 case OMPC_allocate:
15588 case OMPC_dist_schedule:
15589 case OMPC_defaultmap:
15594 case OMPC_use_device_ptr:
15595 case OMPC_use_device_addr:
15596 case OMPC_is_device_ptr:
15597 case OMPC_unified_address:
15598 case OMPC_unified_shared_memory:
15599 case OMPC_reverse_offload:
15600 case OMPC_dynamic_allocators:
15601 case OMPC_atomic_default_mem_order:
15602 case OMPC_device_type:
15604 case OMPC_nontemporal:
15607 case OMPC_severity:
15609 case OMPC_inclusive:
15610 case OMPC_exclusive:
15611 case OMPC_uses_allocators:
15612 case OMPC_affinity:
15616 llvm_unreachable(
"Clause is not allowed.");
15633 case OMPD_target_parallel_for_simd:
15634 if (OpenMPVersion >= 50 &&
15635 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15636 CaptureRegion = OMPD_parallel;
15640 case OMPD_target_parallel:
15641 case OMPD_target_parallel_for:
15642 case OMPD_target_parallel_loop:
15645 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
15646 CaptureRegion = OMPD_target;
15648 case OMPD_target_teams_distribute_parallel_for_simd:
15649 if (OpenMPVersion >= 50 &&
15650 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15651 CaptureRegion = OMPD_parallel;
15655 case OMPD_target_teams_loop:
15656 case OMPD_target_teams_distribute_parallel_for:
15659 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
15660 CaptureRegion = OMPD_teams;
15662 case OMPD_teams_distribute_parallel_for_simd:
15663 if (OpenMPVersion >= 50 &&
15664 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15665 CaptureRegion = OMPD_parallel;
15669 case OMPD_teams_distribute_parallel_for:
15670 CaptureRegion = OMPD_teams;
15672 case OMPD_target_update:
15673 case OMPD_target_enter_data:
15674 case OMPD_target_exit_data:
15675 CaptureRegion = OMPD_task;
15677 case OMPD_parallel_masked_taskloop:
15678 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
15679 CaptureRegion = OMPD_parallel;
15681 case OMPD_parallel_master_taskloop:
15682 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
15683 CaptureRegion = OMPD_parallel;
15685 case OMPD_parallel_masked_taskloop_simd:
15686 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
15687 NameModifier == OMPD_taskloop) {
15688 CaptureRegion = OMPD_parallel;
15691 if (OpenMPVersion <= 45)
15693 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15694 CaptureRegion = OMPD_taskloop;
15696 case OMPD_parallel_master_taskloop_simd:
15697 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
15698 NameModifier == OMPD_taskloop) {
15699 CaptureRegion = OMPD_parallel;
15702 if (OpenMPVersion <= 45)
15704 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15705 CaptureRegion = OMPD_taskloop;
15707 case OMPD_parallel_for_simd:
15708 if (OpenMPVersion <= 45)
15710 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15711 CaptureRegion = OMPD_parallel;
15713 case OMPD_taskloop_simd:
15714 case OMPD_master_taskloop_simd:
15715 case OMPD_masked_taskloop_simd:
15716 if (OpenMPVersion <= 45)
15718 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15719 CaptureRegion = OMPD_taskloop;
15721 case OMPD_distribute_parallel_for_simd:
15722 if (OpenMPVersion <= 45)
15724 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15725 CaptureRegion = OMPD_parallel;
15727 case OMPD_target_simd:
15728 if (OpenMPVersion >= 50 &&
15729 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
15730 CaptureRegion = OMPD_target;
15732 case OMPD_teams_distribute_simd:
15733 case OMPD_target_teams_distribute_simd:
15734 if (OpenMPVersion >= 50 &&
15735 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
15736 CaptureRegion = OMPD_teams;
15739 case OMPD_parallel:
15740 case OMPD_parallel_master:
15741 case OMPD_parallel_masked:
15742 case OMPD_parallel_sections:
15743 case OMPD_parallel_for:
15744 case OMPD_parallel_loop:
15746 case OMPD_target_teams:
15747 case OMPD_target_teams_distribute:
15748 case OMPD_distribute_parallel_for:
15750 case OMPD_taskloop:
15751 case OMPD_master_taskloop:
15752 case OMPD_masked_taskloop:
15753 case OMPD_target_data:
15755 case OMPD_for_simd:
15756 case OMPD_distribute_simd:
15759 case OMPD_threadprivate:
15760 case OMPD_allocate:
15761 case OMPD_taskyield:
15764 case OMPD_taskwait:
15765 case OMPD_cancellation_point:
15769 case OMPD_declare_reduction:
15770 case OMPD_declare_mapper:
15771 case OMPD_declare_simd:
15772 case OMPD_declare_variant:
15773 case OMPD_begin_declare_variant:
15774 case OMPD_end_declare_variant:
15775 case OMPD_declare_target:
15776 case OMPD_end_declare_target:
15778 case OMPD_teams_loop:
15783 case OMPD_sections:
15788 case OMPD_critical:
15789 case OMPD_taskgroup:
15790 case OMPD_distribute:
15793 case OMPD_teams_distribute:
15794 case OMPD_requires:
15795 case OMPD_metadirective:
15796 llvm_unreachable(
"Unexpected OpenMP directive with if-clause");
15799 llvm_unreachable(
"Unknown OpenMP directive");
15802 case OMPC_num_threads:
15804 case OMPD_target_parallel:
15805 case OMPD_target_parallel_for:
15806 case OMPD_target_parallel_for_simd:
15807 case OMPD_target_parallel_loop:
15808 CaptureRegion = OMPD_target;
15810 case OMPD_teams_distribute_parallel_for:
15811 case OMPD_teams_distribute_parallel_for_simd:
15812 case OMPD_target_teams_distribute_parallel_for:
15813 case OMPD_target_teams_distribute_parallel_for_simd:
15814 CaptureRegion = OMPD_teams;
15816 case OMPD_parallel:
15817 case OMPD_parallel_master:
15818 case OMPD_parallel_masked:
15819 case OMPD_parallel_sections:
15820 case OMPD_parallel_for:
15821 case OMPD_parallel_for_simd:
15822 case OMPD_parallel_loop:
15823 case OMPD_distribute_parallel_for:
15824 case OMPD_distribute_parallel_for_simd:
15825 case OMPD_parallel_master_taskloop:
15826 case OMPD_parallel_masked_taskloop:
15827 case OMPD_parallel_master_taskloop_simd:
15828 case OMPD_parallel_masked_taskloop_simd:
15831 case OMPD_target_data:
15832 case OMPD_target_enter_data:
15833 case OMPD_target_exit_data:
15834 case OMPD_target_update:
15836 case OMPD_target_simd:
15837 case OMPD_target_teams:
15838 case OMPD_target_teams_distribute:
15839 case OMPD_target_teams_distribute_simd:
15842 case OMPD_taskloop:
15843 case OMPD_taskloop_simd:
15844 case OMPD_master_taskloop:
15845 case OMPD_masked_taskloop:
15846 case OMPD_master_taskloop_simd:
15847 case OMPD_masked_taskloop_simd:
15848 case OMPD_threadprivate:
15849 case OMPD_allocate:
15850 case OMPD_taskyield:
15853 case OMPD_taskwait:
15854 case OMPD_cancellation_point:
15858 case OMPD_declare_reduction:
15859 case OMPD_declare_mapper:
15860 case OMPD_declare_simd:
15861 case OMPD_declare_variant:
15862 case OMPD_begin_declare_variant:
15863 case OMPD_end_declare_variant:
15864 case OMPD_declare_target:
15865 case OMPD_end_declare_target:
15867 case OMPD_teams_loop:
15868 case OMPD_target_teams_loop:
15874 case OMPD_for_simd:
15875 case OMPD_sections:
15880 case OMPD_critical:
15881 case OMPD_taskgroup:
15882 case OMPD_distribute:
15885 case OMPD_distribute_simd:
15886 case OMPD_teams_distribute:
15887 case OMPD_teams_distribute_simd:
15888 case OMPD_requires:
15889 case OMPD_metadirective:
15890 llvm_unreachable(
"Unexpected OpenMP directive with num_threads-clause");
15893 llvm_unreachable(
"Unknown OpenMP directive");
15896 case OMPC_num_teams:
15898 case OMPD_target_teams:
15899 case OMPD_target_teams_distribute:
15900 case OMPD_target_teams_distribute_simd:
15901 case OMPD_target_teams_distribute_parallel_for:
15902 case OMPD_target_teams_distribute_parallel_for_simd:
15903 case OMPD_target_teams_loop:
15904 CaptureRegion = OMPD_target;
15906 case OMPD_teams_distribute_parallel_for:
15907 case OMPD_teams_distribute_parallel_for_simd:
15909 case OMPD_teams_distribute:
15910 case OMPD_teams_distribute_simd:
15911 case OMPD_teams_loop:
15914 case OMPD_distribute_parallel_for:
15915 case OMPD_distribute_parallel_for_simd:
15917 case OMPD_taskloop:
15918 case OMPD_taskloop_simd:
15919 case OMPD_master_taskloop:
15920 case OMPD_masked_taskloop:
15921 case OMPD_master_taskloop_simd:
15922 case OMPD_masked_taskloop_simd:
15923 case OMPD_parallel_master_taskloop:
15924 case OMPD_parallel_masked_taskloop:
15925 case OMPD_parallel_master_taskloop_simd:
15926 case OMPD_parallel_masked_taskloop_simd:
15927 case OMPD_target_data:
15928 case OMPD_target_enter_data:
15929 case OMPD_target_exit_data:
15930 case OMPD_target_update:
15932 case OMPD_parallel:
15933 case OMPD_parallel_master:
15934 case OMPD_parallel_masked:
15935 case OMPD_parallel_sections:
15936 case OMPD_parallel_for:
15937 case OMPD_parallel_for_simd:
15938 case OMPD_parallel_loop:
15940 case OMPD_target_simd:
15941 case OMPD_target_parallel:
15942 case OMPD_target_parallel_for:
15943 case OMPD_target_parallel_for_simd:
15944 case OMPD_target_parallel_loop:
15945 case OMPD_threadprivate:
15946 case OMPD_allocate:
15947 case OMPD_taskyield:
15950 case OMPD_taskwait:
15951 case OMPD_cancellation_point:
15955 case OMPD_declare_reduction:
15956 case OMPD_declare_mapper:
15957 case OMPD_declare_simd:
15958 case OMPD_declare_variant:
15959 case OMPD_begin_declare_variant:
15960 case OMPD_end_declare_variant:
15961 case OMPD_declare_target:
15962 case OMPD_end_declare_target:
15968 case OMPD_for_simd:
15969 case OMPD_sections:
15974 case OMPD_critical:
15975 case OMPD_taskgroup:
15976 case OMPD_distribute:
15979 case OMPD_distribute_simd:
15980 case OMPD_requires:
15981 case OMPD_metadirective:
15982 llvm_unreachable(
"Unexpected OpenMP directive with num_teams-clause");
15985 llvm_unreachable(
"Unknown OpenMP directive");
15988 case OMPC_thread_limit:
15991 case OMPD_target_teams:
15992 case OMPD_target_teams_distribute:
15993 case OMPD_target_teams_distribute_simd:
15994 case OMPD_target_teams_distribute_parallel_for:
15995 case OMPD_target_teams_distribute_parallel_for_simd:
15996 case OMPD_target_teams_loop:
15997 case OMPD_target_simd:
15998 case OMPD_target_parallel:
15999 case OMPD_target_parallel_for:
16000 case OMPD_target_parallel_for_simd:
16001 case OMPD_target_parallel_loop:
16002 CaptureRegion = OMPD_target;
16004 case OMPD_teams_distribute_parallel_for:
16005 case OMPD_teams_distribute_parallel_for_simd:
16007 case OMPD_teams_distribute:
16008 case OMPD_teams_distribute_simd:
16009 case OMPD_teams_loop:
16012 case OMPD_distribute_parallel_for:
16013 case OMPD_distribute_parallel_for_simd:
16015 case OMPD_taskloop:
16016 case OMPD_taskloop_simd:
16017 case OMPD_master_taskloop:
16018 case OMPD_masked_taskloop:
16019 case OMPD_master_taskloop_simd:
16020 case OMPD_masked_taskloop_simd:
16021 case OMPD_parallel_master_taskloop:
16022 case OMPD_parallel_masked_taskloop:
16023 case OMPD_parallel_master_taskloop_simd:
16024 case OMPD_parallel_masked_taskloop_simd:
16025 case OMPD_target_data:
16026 case OMPD_target_enter_data:
16027 case OMPD_target_exit_data:
16028 case OMPD_target_update:
16030 case OMPD_parallel:
16031 case OMPD_parallel_master:
16032 case OMPD_parallel_masked:
16033 case OMPD_parallel_sections:
16034 case OMPD_parallel_for:
16035 case OMPD_parallel_for_simd:
16036 case OMPD_parallel_loop:
16037 case OMPD_threadprivate:
16038 case OMPD_allocate:
16039 case OMPD_taskyield:
16042 case OMPD_taskwait:
16043 case OMPD_cancellation_point:
16047 case OMPD_declare_reduction:
16048 case OMPD_declare_mapper:
16049 case OMPD_declare_simd:
16050 case OMPD_declare_variant:
16051 case OMPD_begin_declare_variant:
16052 case OMPD_end_declare_variant:
16053 case OMPD_declare_target:
16054 case OMPD_end_declare_target:
16060 case OMPD_for_simd:
16061 case OMPD_sections:
16066 case OMPD_critical:
16067 case OMPD_taskgroup:
16068 case OMPD_distribute:
16071 case OMPD_distribute_simd:
16072 case OMPD_requires:
16073 case OMPD_metadirective:
16074 llvm_unreachable(
"Unexpected OpenMP directive with thread_limit-clause");
16077 llvm_unreachable(
"Unknown OpenMP directive");
16080 case OMPC_schedule:
16082 case OMPD_parallel_for:
16083 case OMPD_parallel_for_simd:
16084 case OMPD_distribute_parallel_for:
16085 case OMPD_distribute_parallel_for_simd:
16086 case OMPD_teams_distribute_parallel_for:
16087 case OMPD_teams_distribute_parallel_for_simd:
16088 case OMPD_target_parallel_for:
16089 case OMPD_target_parallel_for_simd:
16090 case OMPD_target_teams_distribute_parallel_for:
16091 case OMPD_target_teams_distribute_parallel_for_simd:
16092 CaptureRegion = OMPD_parallel;
16095 case OMPD_for_simd:
16099 case OMPD_taskloop:
16100 case OMPD_taskloop_simd:
16101 case OMPD_master_taskloop:
16102 case OMPD_masked_taskloop:
16103 case OMPD_master_taskloop_simd:
16104 case OMPD_masked_taskloop_simd:
16105 case OMPD_parallel_master_taskloop:
16106 case OMPD_parallel_masked_taskloop:
16107 case OMPD_parallel_master_taskloop_simd:
16108 case OMPD_parallel_masked_taskloop_simd:
16109 case OMPD_target_data:
16110 case OMPD_target_enter_data:
16111 case OMPD_target_exit_data:
16112 case OMPD_target_update:
16114 case OMPD_teams_distribute:
16115 case OMPD_teams_distribute_simd:
16116 case OMPD_target_teams_distribute:
16117 case OMPD_target_teams_distribute_simd:
16119 case OMPD_target_simd:
16120 case OMPD_target_parallel:
16122 case OMPD_parallel:
16123 case OMPD_parallel_master:
16124 case OMPD_parallel_masked:
16125 case OMPD_parallel_sections:
16126 case OMPD_threadprivate:
16127 case OMPD_allocate:
16128 case OMPD_taskyield:
16131 case OMPD_taskwait:
16132 case OMPD_cancellation_point:
16136 case OMPD_declare_reduction:
16137 case OMPD_declare_mapper:
16138 case OMPD_declare_simd:
16139 case OMPD_declare_variant:
16140 case OMPD_begin_declare_variant:
16141 case OMPD_end_declare_variant:
16142 case OMPD_declare_target:
16143 case OMPD_end_declare_target:
16145 case OMPD_teams_loop:
16146 case OMPD_target_teams_loop:
16147 case OMPD_parallel_loop:
16148 case OMPD_target_parallel_loop:
16152 case OMPD_sections:
16157 case OMPD_critical:
16158 case OMPD_taskgroup:
16159 case OMPD_distribute:
16162 case OMPD_distribute_simd:
16163 case OMPD_target_teams:
16164 case OMPD_requires:
16165 case OMPD_metadirective:
16166 llvm_unreachable(
"Unexpected OpenMP directive with schedule clause");
16169 llvm_unreachable(
"Unknown OpenMP directive");
16172 case OMPC_dist_schedule:
16174 case OMPD_teams_distribute_parallel_for:
16175 case OMPD_teams_distribute_parallel_for_simd:
16176 case OMPD_teams_distribute:
16177 case OMPD_teams_distribute_simd:
16178 case OMPD_target_teams_distribute_parallel_for:
16179 case OMPD_target_teams_distribute_parallel_for_simd:
16180 case OMPD_target_teams_distribute:
16181 case OMPD_target_teams_distribute_simd:
16182 CaptureRegion = OMPD_teams;
16184 case OMPD_distribute_parallel_for:
16185 case OMPD_distribute_parallel_for_simd:
16186 case OMPD_distribute:
16187 case OMPD_distribute_simd:
16190 case OMPD_parallel_for:
16191 case OMPD_parallel_for_simd:
16192 case OMPD_target_parallel_for_simd:
16193 case OMPD_target_parallel_for:
16195 case OMPD_taskloop:
16196 case OMPD_taskloop_simd:
16197 case OMPD_master_taskloop:
16198 case OMPD_masked_taskloop:
16199 case OMPD_master_taskloop_simd:
16200 case OMPD_masked_taskloop_simd:
16201 case OMPD_parallel_master_taskloop:
16202 case OMPD_parallel_masked_taskloop:
16203 case OMPD_parallel_master_taskloop_simd:
16204 case OMPD_parallel_masked_taskloop_simd:
16205 case OMPD_target_data:
16206 case OMPD_target_enter_data:
16207 case OMPD_target_exit_data:
16208 case OMPD_target_update:
16211 case OMPD_target_simd:
16212 case OMPD_target_parallel:
16214 case OMPD_parallel:
16215 case OMPD_parallel_master:
16216 case OMPD_parallel_masked:
16217 case OMPD_parallel_sections:
16218 case OMPD_threadprivate:
16219 case OMPD_allocate:
16220 case OMPD_taskyield:
16223 case OMPD_taskwait:
16224 case OMPD_cancellation_point:
16228 case OMPD_declare_reduction:
16229 case OMPD_declare_mapper:
16230 case OMPD_declare_simd:
16231 case OMPD_declare_variant:
16232 case OMPD_begin_declare_variant:
16233 case OMPD_end_declare_variant:
16234 case OMPD_declare_target:
16235 case OMPD_end_declare_target:
16237 case OMPD_teams_loop:
16238 case OMPD_target_teams_loop:
16239 case OMPD_parallel_loop:
16240 case OMPD_target_parallel_loop:
16245 case OMPD_for_simd:
16246 case OMPD_sections:
16251 case OMPD_critical:
16252 case OMPD_taskgroup:
16255 case OMPD_target_teams:
16256 case OMPD_requires:
16257 case OMPD_metadirective:
16258 llvm_unreachable(
"Unexpected OpenMP directive with dist_schedule clause");
16261 llvm_unreachable(
"Unknown OpenMP directive");
16264 case OMPC_ompx_dyn_cgroup_mem:
16267 case OMPD_target_simd:
16268 case OMPD_target_teams:
16269 case OMPD_target_parallel:
16270 case OMPD_target_teams_distribute:
16271 case OMPD_target_teams_distribute_simd:
16272 case OMPD_target_parallel_for:
16273 case OMPD_target_parallel_for_simd:
16274 case OMPD_target_parallel_loop:
16275 case OMPD_target_teams_distribute_parallel_for:
16276 case OMPD_target_teams_distribute_parallel_for_simd:
16277 case OMPD_target_teams_loop:
16278 CaptureRegion = OMPD_target;
16281 llvm_unreachable(
"Unknown OpenMP directive");
16286 case OMPD_target_update:
16287 case OMPD_target_enter_data:
16288 case OMPD_target_exit_data:
16290 case OMPD_target_simd:
16291 case OMPD_target_teams:
16292 case OMPD_target_parallel:
16293 case OMPD_target_teams_distribute:
16294 case OMPD_target_teams_distribute_simd:
16295 case OMPD_target_parallel_for:
16296 case OMPD_target_parallel_for_simd:
16297 case OMPD_target_parallel_loop:
16298 case OMPD_target_teams_distribute_parallel_for:
16299 case OMPD_target_teams_distribute_parallel_for_simd:
16300 case OMPD_target_teams_loop:
16301 case OMPD_dispatch:
16302 CaptureRegion = OMPD_task;
16304 case OMPD_target_data:
16308 case OMPD_teams_distribute_parallel_for:
16309 case OMPD_teams_distribute_parallel_for_simd:
16311 case OMPD_teams_distribute:
16312 case OMPD_teams_distribute_simd:
16313 case OMPD_distribute_parallel_for:
16314 case OMPD_distribute_parallel_for_simd:
16316 case OMPD_taskloop:
16317 case OMPD_taskloop_simd:
16318 case OMPD_master_taskloop:
16319 case OMPD_masked_taskloop:
16320 case OMPD_master_taskloop_simd:
16321 case OMPD_masked_taskloop_simd:
16322 case OMPD_parallel_master_taskloop:
16323 case OMPD_parallel_masked_taskloop:
16324 case OMPD_parallel_master_taskloop_simd:
16325 case OMPD_parallel_masked_taskloop_simd:
16327 case OMPD_parallel:
16328 case OMPD_parallel_master:
16329 case OMPD_parallel_masked:
16330 case OMPD_parallel_sections:
16331 case OMPD_parallel_for:
16332 case OMPD_parallel_for_simd:
16333 case OMPD_threadprivate:
16334 case OMPD_allocate:
16335 case OMPD_taskyield:
16338 case OMPD_taskwait:
16339 case OMPD_cancellation_point:
16343 case OMPD_declare_reduction:
16344 case OMPD_declare_mapper:
16345 case OMPD_declare_simd:
16346 case OMPD_declare_variant:
16347 case OMPD_begin_declare_variant:
16348 case OMPD_end_declare_variant:
16349 case OMPD_declare_target:
16350 case OMPD_end_declare_target:
16352 case OMPD_teams_loop:
16353 case OMPD_parallel_loop:
16358 case OMPD_for_simd:
16359 case OMPD_sections:
16364 case OMPD_critical:
16365 case OMPD_taskgroup:
16366 case OMPD_distribute:
16369 case OMPD_distribute_simd:
16370 case OMPD_requires:
16371 case OMPD_metadirective:
16372 llvm_unreachable(
"Unexpected OpenMP directive with device-clause");
16375 llvm_unreachable(
"Unknown OpenMP directive");
16378 case OMPC_grainsize:
16379 case OMPC_num_tasks:
16381 case OMPC_priority:
16384 case OMPD_taskloop:
16385 case OMPD_taskloop_simd:
16386 case OMPD_master_taskloop:
16387 case OMPD_masked_taskloop:
16388 case OMPD_master_taskloop_simd:
16389 case OMPD_masked_taskloop_simd:
16391 case OMPD_parallel_masked_taskloop:
16392 case OMPD_parallel_masked_taskloop_simd:
16393 case OMPD_parallel_master_taskloop:
16394 case OMPD_parallel_master_taskloop_simd:
16395 CaptureRegion = OMPD_parallel;
16397 case OMPD_target_update:
16398 case OMPD_target_enter_data:
16399 case OMPD_target_exit_data:
16401 case OMPD_target_simd:
16402 case OMPD_target_teams:
16403 case OMPD_target_parallel:
16404 case OMPD_target_teams_distribute:
16405 case OMPD_target_teams_distribute_simd:
16406 case OMPD_target_parallel_for:
16407 case OMPD_target_parallel_for_simd:
16408 case OMPD_target_teams_distribute_parallel_for:
16409 case OMPD_target_teams_distribute_parallel_for_simd:
16410 case OMPD_target_data:
16411 case OMPD_teams_distribute_parallel_for:
16412 case OMPD_teams_distribute_parallel_for_simd:
16414 case OMPD_teams_distribute:
16415 case OMPD_teams_distribute_simd:
16416 case OMPD_distribute_parallel_for:
16417 case OMPD_distribute_parallel_for_simd:
16419 case OMPD_parallel:
16420 case OMPD_parallel_master:
16421 case OMPD_parallel_masked:
16422 case OMPD_parallel_sections:
16423 case OMPD_parallel_for:
16424 case OMPD_parallel_for_simd:
16425 case OMPD_threadprivate:
16426 case OMPD_allocate:
16427 case OMPD_taskyield:
16430 case OMPD_taskwait:
16431 case OMPD_cancellation_point:
16435 case OMPD_declare_reduction:
16436 case OMPD_declare_mapper:
16437 case OMPD_declare_simd:
16438 case OMPD_declare_variant:
16439 case OMPD_begin_declare_variant:
16440 case OMPD_end_declare_variant:
16441 case OMPD_declare_target:
16442 case OMPD_end_declare_target:
16444 case OMPD_teams_loop:
16445 case OMPD_target_teams_loop:
16446 case OMPD_parallel_loop:
16447 case OMPD_target_parallel_loop:
16452 case OMPD_for_simd:
16453 case OMPD_sections:
16458 case OMPD_critical:
16459 case OMPD_taskgroup:
16460 case OMPD_distribute:
16463 case OMPD_distribute_simd:
16464 case OMPD_requires:
16465 case OMPD_metadirective:
16466 llvm_unreachable(
"Unexpected OpenMP directive with grainsize-clause");
16469 llvm_unreachable(
"Unknown OpenMP directive");
16472 case OMPC_novariants:
16473 case OMPC_nocontext:
16475 case OMPD_dispatch:
16476 CaptureRegion = OMPD_task;
16479 llvm_unreachable(
"Unexpected OpenMP directive");
16486 if (DKind == OMPD_metadirective) {
16487 CaptureRegion = OMPD_metadirective;
16488 }
else if (DKind == OMPD_unknown) {
16489 llvm_unreachable(
"Unknown OpenMP directive");
16491 llvm_unreachable(
"Unexpected OpenMP directive with when clause");
16494 case OMPC_firstprivate:
16495 case OMPC_lastprivate:
16496 case OMPC_reduction:
16497 case OMPC_task_reduction:
16498 case OMPC_in_reduction:
16501 case OMPC_proc_bind:
16505 case OMPC_allocator:
16506 case OMPC_collapse:
16511 case OMPC_copyprivate:
16515 case OMPC_mergeable:
16516 case OMPC_threadprivate:
16517 case OMPC_allocate:
16536 case OMPC_defaultmap:
16541 case OMPC_use_device_ptr:
16542 case OMPC_use_device_addr:
16543 case OMPC_is_device_ptr:
16544 case OMPC_unified_address:
16545 case OMPC_unified_shared_memory:
16546 case OMPC_reverse_offload:
16547 case OMPC_dynamic_allocators:
16548 case OMPC_atomic_default_mem_order:
16549 case OMPC_device_type:
16551 case OMPC_nontemporal:
16554 case OMPC_severity:
16558 case OMPC_inclusive:
16559 case OMPC_exclusive:
16560 case OMPC_uses_allocators:
16561 case OMPC_affinity:
16564 llvm_unreachable(
"Unexpected OpenMP clause.");
16566 return CaptureRegion;
16576 Stmt *HelperValStmt =
nullptr;
16579 !
Condition->isInstantiationDependent() &&
16580 !
Condition->containsUnexpandedParameterPack()) {
16585 ValExpr = Val.
get();
16589 DKind, OMPC_if,
LangOpts.OpenMP, NameModifier);
16592 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16593 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
16599 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
16600 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
16608 Stmt *HelperValStmt =
nullptr;
16611 !
Condition->isInstantiationDependent() &&
16612 !
Condition->containsUnexpandedParameterPack()) {
16624 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16625 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
16631 StartLoc, LParenLoc, EndLoc);
16641 IntConvertDiagnoser()
16645 return S.
Diag(Loc, diag::err_omp_not_integral) << T;
16649 return S.
Diag(Loc, diag::err_omp_incomplete_type) << T;
16654 return S.
Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
16663 return S.
Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
16672 llvm_unreachable(
"conversion functions are permitted");
16674 } ConvertDiagnoser;
16680 bool StrictlyPositive,
bool BuildCapture =
false,
16683 Stmt **HelperValStmt =
nullptr) {
16689 if (
Value.isInvalid())
16692 ValExpr =
Value.get();
16694 if (std::optional<llvm::APSInt>
Result =
16696 if (
Result->isSigned() &&
16697 !((!StrictlyPositive &&
Result->isNonNegative()) ||
16698 (StrictlyPositive &&
Result->isStrictlyPositive()))) {
16699 SemaRef.
Diag(Loc, diag::err_omp_negative_expression_in_clause)
16700 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
16709 if (*CaptureRegion != OMPD_unknown &&
16712 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16713 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
16724 Expr *ValExpr = NumThreads;
16725 Stmt *HelperValStmt =
nullptr;
16738 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16739 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
16744 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
16749 bool StrictlyPositive,
16750 bool SuppressExprDiags) {
16759 if (SuppressExprDiags) {
16766 llvm_unreachable(
"Diagnostic suppressed");
16776 if ((StrictlyPositive && !
Result.isStrictlyPositive()) ||
16777 (!StrictlyPositive && !
Result.isNonNegative())) {
16778 Diag(E->
getExprLoc(), diag::err_omp_negative_expression_in_clause)
16779 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
16783 if ((CKind == OMPC_aligned || CKind == OMPC_align) && !
Result.isPowerOf2()) {
16784 Diag(E->
getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
16788 if (CKind == OMPC_collapse &&
DSAStack->getAssociatedLoops() == 1)
16790 else if (CKind == OMPC_ordered)
16823 DSAStackTy *Stack) {
16824 if (!Stack->getOMPAllocatorHandleT().isNull())
16831 S.
Diag(Loc, diag::err_omp_implied_type_not_found)
16832 <<
"omp_allocator_handle_t";
16837 Stack->setOMPAllocatorHandleT(AllocatorHandleEnumTy);
16840 bool ErrorFound =
false;
16841 for (
int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
16842 auto AllocatorKind =
static_cast<OMPAllocateDeclAttr::AllocatorTypeTy
>(I);
16843 StringRef Allocator =
16844 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
16846 auto *VD = dyn_cast_or_null<ValueDecl>(
16866 Stack->setAllocator(AllocatorKind, Res.
get());
16869 S.
Diag(Loc, diag::err_omp_implied_type_not_found)
16870 <<
"omp_allocator_handle_t";
16886 if (Allocator.isInvalid())
16889 DSAStack->getOMPAllocatorHandleT(),
16892 if (Allocator.isInvalid())
16918 Expr *NumForLoops) {
16924 if (NumForLoops && LParenLoc.
isValid()) {
16929 NumForLoops = NumForLoopsResult.
get();
16931 NumForLoops =
nullptr;
16934 Context, NumForLoops, NumForLoops ?
DSAStack->getAssociatedLoops() : 0,
16935 StartLoc, LParenLoc, EndLoc);
16936 DSAStack->setOrderedRegion(
true, NumForLoops, Clause);
16947 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16949 case OMPC_proc_bind:
16951 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16953 case OMPC_atomic_default_mem_order:
16956 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16961 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16965 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16969 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16973 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16975 case OMPC_severity:
16978 LParenLoc, EndLoc);
16982 case OMPC_num_threads:
16986 case OMPC_allocator:
16987 case OMPC_collapse:
16988 case OMPC_schedule:
16990 case OMPC_firstprivate:
16991 case OMPC_lastprivate:
16993 case OMPC_reduction:
16994 case OMPC_task_reduction:
16995 case OMPC_in_reduction:
16999 case OMPC_copyprivate:
17003 case OMPC_mergeable:
17004 case OMPC_threadprivate:
17005 case OMPC_allocate:
17022 case OMPC_num_teams:
17023 case OMPC_thread_limit:
17024 case OMPC_priority:
17025 case OMPC_grainsize:
17027 case OMPC_num_tasks:
17029 case OMPC_dist_schedule:
17030 case OMPC_defaultmap:
17035 case OMPC_use_device_ptr:
17036 case OMPC_use_device_addr:
17037 case OMPC_is_device_ptr:
17038 case OMPC_has_device_addr:
17039 case OMPC_unified_address:
17040 case OMPC_unified_shared_memory:
17041 case OMPC_reverse_offload:
17042 case OMPC_dynamic_allocators:
17043 case OMPC_device_type:
17045 case OMPC_nontemporal:
17047 case OMPC_novariants:
17048 case OMPC_nocontext:
17050 case OMPC_inclusive:
17051 case OMPC_exclusive:
17052 case OMPC_uses_allocators:
17053 case OMPC_affinity:
17057 llvm_unreachable(
"Clause is not allowed.");
17066 llvm::raw_svector_ostream Out(Buffer);
17067 unsigned Skipped = Exclude.size();
17068 for (
unsigned I =
First; I <
Last; ++I) {
17069 if (llvm::is_contained(Exclude, I)) {
17074 if (I + Skipped + 2 ==
Last)
17076 else if (I + Skipped + 1 !=
Last)
17079 return std::string(Out.str());
17087 if (Kind == OMP_DEFAULT_unknown) {
17088 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17090 unsigned(OMP_DEFAULT_unknown))
17091 << getOpenMPClauseName(OMPC_default);
17096 case OMP_DEFAULT_none:
17097 DSAStack->setDefaultDSANone(KindKwLoc);
17099 case OMP_DEFAULT_shared:
17100 DSAStack->setDefaultDSAShared(KindKwLoc);
17102 case OMP_DEFAULT_firstprivate:
17103 DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
17105 case OMP_DEFAULT_private:
17106 DSAStack->setDefaultDSAPrivate(KindKwLoc);
17109 llvm_unreachable(
"DSA unexpected in OpenMP default clause");
17121 if (Kind == OMP_PROC_BIND_unknown) {
17122 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17124 unsigned(OMP_PROC_BIND_master),
17127 ? OMP_PROC_BIND_primary
17128 : OMP_PROC_BIND_spread) +
17130 << getOpenMPClauseName(OMPC_proc_bind);
17133 if (Kind == OMP_PROC_BIND_primary &&
LangOpts.OpenMP < 51)
17134 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17136 unsigned(OMP_PROC_BIND_master),
17138 unsigned(OMP_PROC_BIND_spread) + 1)
17139 << getOpenMPClauseName(OMPC_proc_bind);
17148 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17150 OMPC_atomic_default_mem_order, 0,
17152 << getOpenMPClauseName(OMPC_atomic_default_mem_order);
17156 LParenLoc, EndLoc);
17165 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17168 << getOpenMPClauseName(OMPC_at);
17172 OMPAtClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
17181 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17184 << getOpenMPClauseName(OMPC_severity);
17194 assert(ME &&
"NULL expr in Message clause");
17195 if (!isa<StringLiteral>(ME)) {
17197 << getOpenMPClauseName(OMPC_message);
17207 if (Kind != OMPC_ORDER_concurrent ||
17212 "OMPC_ORDER_unknown not greater than 0");
17214 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
17218 << getOpenMPClauseName(OMPC_order);
17223 Diag(MLoc, diag::err_omp_unexpected_clause_value)
17227 << getOpenMPClauseName(OMPC_order);
17229 DSAStack->setRegionHasOrderConcurrent(
true);
17232 unsigned existingFlags =
DSAStack->getCurScope()->getFlags();
17233 DSAStack->getCurScope()->setFlags(existingFlags |
17239 EndLoc, Modifier, MLoc);
17248 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
17250 OMPC_DEPEND_source, OMPC_DEPEND_sink, OMPC_DEPEND_depobj,
17251 OMPC_DEPEND_outallmemory, OMPC_DEPEND_inoutallmemory};
17253 Except.push_back(OMPC_DEPEND_inoutset);
17254 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17257 << getOpenMPClauseName(OMPC_update);
17268 for (
Expr *SizeExpr : SizeExprs) {
17270 SizeExpr, OMPC_sizes,
true);
17271 if (!NumForLoopsResult.
isUsable())
17275 DSAStack->setAssociatedLoops(SizeExprs.size());
17293 FactorExpr, OMPC_partial,
true);
17296 FactorExpr = FactorResult.
get();
17321 case OMPC_schedule:
17322 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
17323 assert(Argument.size() == NumberOfElements &&
17324 ArgumentLoc.size() == NumberOfElements);
17329 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
17330 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
17333 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
17335 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
17338 case OMPC_dist_schedule:
17341 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
17343 case OMPC_defaultmap:
17344 enum { Modifier, DefaultmapKind };
17348 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
17352 enum { OrderModifier, OrderKind };
17356 LParenLoc, ArgumentLoc[OrderModifier], ArgumentLoc[OrderKind], EndLoc);
17359 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
17362 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17364 case OMPC_grainsize:
17365 assert(Argument.size() == 1 && ArgumentLoc.size() == 1 &&
17366 "Modifier for grainsize clause and its location are expected.");
17369 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17371 case OMPC_num_tasks:
17372 assert(Argument.size() == 1 && ArgumentLoc.size() == 1 &&
17373 "Modifier for num_tasks clause and its location are expected.");
17376 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17379 case OMPC_num_threads:
17383 case OMPC_allocator:
17384 case OMPC_collapse:
17386 case OMPC_proc_bind:
17388 case OMPC_firstprivate:
17389 case OMPC_lastprivate:
17391 case OMPC_reduction:
17392 case OMPC_task_reduction:
17393 case OMPC_in_reduction:
17397 case OMPC_copyprivate:
17401 case OMPC_mergeable:
17402 case OMPC_threadprivate:
17403 case OMPC_allocate:
17420 case OMPC_num_teams:
17421 case OMPC_thread_limit:
17422 case OMPC_priority:
17429 case OMPC_use_device_ptr:
17430 case OMPC_use_device_addr:
17431 case OMPC_is_device_ptr:
17432 case OMPC_has_device_addr:
17433 case OMPC_unified_address:
17434 case OMPC_unified_shared_memory:
17435 case OMPC_reverse_offload:
17436 case OMPC_dynamic_allocators:
17437 case OMPC_atomic_default_mem_order:
17438 case OMPC_device_type:
17440 case OMPC_nontemporal:
17442 case OMPC_severity:
17445 case OMPC_novariants:
17446 case OMPC_nocontext:
17448 case OMPC_inclusive:
17449 case OMPC_exclusive:
17450 case OMPC_uses_allocators:
17451 case OMPC_affinity:
17455 llvm_unreachable(
"Clause is not allowed.");
17466 Excluded.push_back(M2);
17467 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
17468 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
17469 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
17470 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
17471 S.
Diag(M1Loc, diag::err_omp_unexpected_clause_value)
17476 << getOpenMPClauseName(OMPC_schedule);
17494 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
17495 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
17496 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
17497 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
17498 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
17504 std::string Values;
17514 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
17515 << Values << getOpenMPClauseName(OMPC_schedule);
17523 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
17524 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
17525 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
17526 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
17527 diag::err_omp_schedule_nonmonotonic_static);
17530 Expr *ValExpr = ChunkSize;
17531 Stmt *HelperValStmt =
nullptr;
17542 ValExpr = Val.
get();
17547 if (std::optional<llvm::APSInt>
Result =
17549 if (
Result->isSigned() && !
Result->isStrictlyPositive()) {
17550 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
17555 DSAStack->getCurrentDirective(), OMPC_schedule,
17556 LangOpts.OpenMP) != OMPD_unknown &&
17559 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17560 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
17568 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
17585 case OMPC_mergeable:
17633 case OMPC_unified_address:
17636 case OMPC_unified_shared_memory:
17639 case OMPC_reverse_offload:
17642 case OMPC_dynamic_allocators:
17656 case OMPC_ompx_bare:
17661 case OMPC_num_threads:
17665 case OMPC_allocator:
17666 case OMPC_collapse:
17667 case OMPC_schedule:
17669 case OMPC_firstprivate:
17670 case OMPC_lastprivate:
17672 case OMPC_reduction:
17673 case OMPC_task_reduction:
17674 case OMPC_in_reduction:
17678 case OMPC_copyprivate:
17680 case OMPC_proc_bind:
17681 case OMPC_threadprivate:
17682 case OMPC_allocate:
17688 case OMPC_num_teams:
17689 case OMPC_thread_limit:
17690 case OMPC_priority:
17691 case OMPC_grainsize:
17692 case OMPC_num_tasks:
17694 case OMPC_dist_schedule:
17695 case OMPC_defaultmap:
17700 case OMPC_use_device_ptr:
17701 case OMPC_use_device_addr:
17702 case OMPC_is_device_ptr:
17703 case OMPC_has_device_addr:
17704 case OMPC_atomic_default_mem_order:
17705 case OMPC_device_type:
17707 case OMPC_nontemporal:
17710 case OMPC_severity:
17712 case OMPC_novariants:
17713 case OMPC_nocontext:
17715 case OMPC_inclusive:
17716 case OMPC_exclusive:
17717 case OMPC_uses_allocators:
17718 case OMPC_affinity:
17720 case OMPC_ompx_dyn_cgroup_mem:
17722 llvm_unreachable(
"Clause is not allowed.");
17780 Diag(KindLoc, diag::err_omp_atomic_fail_wrong_or_no_clauses);
17858 if (!
hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) {
17859 StringRef
Expected =
"'init', 'use', 'destroy', or 'nowait'";
17860 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
17861 <<
Expected << getOpenMPDirectiveName(OMPD_interop);
17874 bool HasInitClause =
false;
17875 bool IsTargetSync =
false;
17879 if (
const auto *InitClause = dyn_cast<OMPInitClause>(
C)) {
17880 HasInitClause =
true;
17881 if (InitClause->getIsTargetSync())
17882 IsTargetSync =
true;
17883 }
else if (
const auto *DC = dyn_cast<OMPDependClause>(
C)) {
17887 if (DependClause && HasInitClause && !IsTargetSync) {
17888 Diag(DependClause->
getBeginLoc(), diag::err_omp_interop_bad_depend_clause);
17902 if (ClauseKind == OMPC_init) {
17903 auto *E = cast<OMPInitClause>(
C)->getInteropVar();
17905 }
else if (ClauseKind == OMPC_use) {
17906 auto *E = cast<OMPUseClause>(
C)->getInteropVar();
17908 }
else if (ClauseKind == OMPC_destroy) {
17909 auto *E = cast<OMPDestroyClause>(
C)->getInteropVar();
17914 if (!InteropVars.insert(
DeclResult.first).second) {
17915 Diag(ELoc, diag::err_omp_interop_var_multiple_actions)
17930 Expr *RefExpr = InteropVarExpr;
17933 false,
"omp_interop_t");
17944 bool HasError =
false;
17950 if (
const auto *TD = dyn_cast<TypeDecl>(ND)) {
17951 InteropType =
QualType(TD->getTypeForDecl(), 0);
17960 SemaRef.
Diag(VarLoc, diag::err_omp_implied_type_not_found)
17961 <<
"omp_interop_t";
17967 SemaRef.
Diag(VarLoc, diag::err_omp_interop_variable_wrong_type);
17973 if ((Kind == OMPC_init || Kind == OMPC_destroy) &&
17975 SemaRef.
Diag(VarLoc, diag::err_omp_interop_variable_expected)
17998 if (isa<StringLiteral>(E))
18005 LParenLoc, VarLoc, EndLoc);
18017 OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
18025 if (!InteropVar &&
LangOpts.OpenMP >= 52 &&
18026 DSAStack->getCurrentDirective() == OMPD_depobj) {
18027 Diag(StartLoc, diag::err_omp_expected_clause_argument)
18028 << getOpenMPClauseName(OMPC_destroy)
18029 << getOpenMPDirectiveName(OMPD_depobj);
18045 Stmt *HelperValStmt =
nullptr;
18048 !
Condition->isInstantiationDependent() &&
18049 !
Condition->containsUnexpandedParameterPack()) {
18061 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18062 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
18068 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
18076 Stmt *HelperValStmt =
nullptr;
18079 !
Condition->isInstantiationDependent() &&
18080 !
Condition->containsUnexpandedParameterPack()) {
18092 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18093 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
18099 StartLoc, LParenLoc, EndLoc);
18106 Expr *ValExpr = ThreadID;
18107 Stmt *HelperValStmt =
nullptr;
18114 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18115 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
18120 StartLoc, LParenLoc, EndLoc);
18131 int ExtraModifier =
Data.ExtraModifier;
18138 case OMPC_firstprivate:
18141 case OMPC_lastprivate:
18143 "Unexpected lastprivate modifier.");
18146 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
18151 case OMPC_reduction:
18153 "Unexpected lastprivate modifier.");
18156 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
18157 Data.ReductionOrMapperIdScopeSpec,
Data.ReductionOrMapperId);
18159 case OMPC_task_reduction:
18161 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
18162 Data.ReductionOrMapperIdScopeSpec,
Data.ReductionOrMapperId);
18164 case OMPC_in_reduction:
18166 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
18167 Data.ReductionOrMapperIdScopeSpec,
Data.ReductionOrMapperId);
18171 "Unexpected linear modifier.");
18173 VarList,
Data.DepModOrTailExpr, StartLoc, LParenLoc,
18175 ColonLoc,
Data.StepModifierLoc, EndLoc);
18179 LParenLoc, ColonLoc, EndLoc);
18184 case OMPC_copyprivate:
18192 "Unexpected depend modifier.");
18195 ColonLoc,
Data.OmpAllMemoryLoc},
18196 Data.DepModOrTailExpr, VarList, StartLoc, LParenLoc, EndLoc);
18200 "Unexpected map modifier.");
18202 Data.IteratorExpr,
Data.MapTypeModifiers,
Data.MapTypeModifiersLoc,
18203 Data.ReductionOrMapperIdScopeSpec,
Data.ReductionOrMapperId,
18205 ExtraModifierLoc, ColonLoc, VarList, Locs);
18210 Data.ReductionOrMapperIdScopeSpec,
18211 Data.ReductionOrMapperId, ColonLoc, VarList, Locs);
18215 Data.ReductionOrMapperIdScopeSpec,
18216 Data.ReductionOrMapperId, ColonLoc, VarList,
18219 case OMPC_use_device_ptr:
18222 case OMPC_use_device_addr:
18225 case OMPC_is_device_ptr:
18228 case OMPC_has_device_addr:
18231 case OMPC_allocate:
18233 LParenLoc, ColonLoc, EndLoc);
18235 case OMPC_nontemporal:
18238 case OMPC_inclusive:
18241 case OMPC_exclusive:
18244 case OMPC_affinity:
18246 Data.DepModOrTailExpr, VarList);
18248 case OMPC_doacross:
18251 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
18256 case OMPC_num_threads:
18260 case OMPC_allocator:
18261 case OMPC_collapse:
18263 case OMPC_proc_bind:
18264 case OMPC_schedule:
18268 case OMPC_mergeable:
18269 case OMPC_threadprivate:
18283 case OMPC_num_teams:
18284 case OMPC_thread_limit:
18285 case OMPC_priority:
18286 case OMPC_grainsize:
18288 case OMPC_num_tasks:
18290 case OMPC_dist_schedule:
18291 case OMPC_defaultmap:
18294 case OMPC_unified_address:
18295 case OMPC_unified_shared_memory:
18296 case OMPC_reverse_offload:
18297 case OMPC_dynamic_allocators:
18298 case OMPC_atomic_default_mem_order:
18299 case OMPC_device_type:
18303 case OMPC_severity:
18306 case OMPC_novariants:
18307 case OMPC_nocontext:
18309 case OMPC_uses_allocators:
18313 llvm_unreachable(
"Clause is not allowed.");
18343 bool IsImplicitClause =
18345 for (
Expr *RefExpr : VarList) {
18346 assert(RefExpr &&
"NULL expr in OpenMP private clause.");
18349 Expr *SimpleRefExpr = RefExpr;
18353 Vars.push_back(RefExpr);
18354 PrivateCopies.push_back(
nullptr);
18361 auto *VD = dyn_cast<VarDecl>(D);
18368 Type =
Type.getNonReferenceType();
18388 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
18389 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
18390 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
18391 << getOpenMPClauseName(OMPC_private);
18400 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18401 << getOpenMPClauseName(OMPC_private) <<
Type
18402 << getOpenMPDirectiveName(CurrDir);
18403 bool IsDecl = !VD || VD->isThisDeclarationADefinition(
Context) ==
18406 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18420 CurrDir == OMPD_target) {
18422 if (
DSAStack->checkMappableExprComponentListsForDecl(
18426 ConflictKind = WhereFoundClauseKind;
18429 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18430 << getOpenMPClauseName(OMPC_private)
18431 << getOpenMPClauseName(ConflictKind)
18432 << getOpenMPDirectiveName(CurrDir);
18451 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
18460 auto *FD = dyn_cast<FieldDecl>(D);
18464 RefExpr->getExprLoc());
18468 if (!IsImplicitClause)
18469 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
18471 ? RefExpr->IgnoreParens()
18473 PrivateCopies.push_back(VDPrivateRefExpr);
18491 bool IsImplicitClause =
18495 for (
Expr *RefExpr : VarList) {
18496 assert(RefExpr &&
"NULL expr in OpenMP firstprivate clause.");
18499 Expr *SimpleRefExpr = RefExpr;
18503 Vars.push_back(RefExpr);
18504 PrivateCopies.push_back(
nullptr);
18505 Inits.push_back(
nullptr);
18511 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
18513 auto *VD = dyn_cast<VarDecl>(D);
18519 diag::err_omp_firstprivate_incomplete_type))
18521 Type =
Type.getNonReferenceType();
18530 DSAStackTy::DSAVarData TopDVar;
18531 if (!IsImplicitClause) {
18532 DSAStackTy::DSAVarData DVar =
18544 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
18546 DVar.CKind != OMPC_lastprivate) &&
18548 Diag(ELoc, diag::err_omp_wrong_dsa)
18549 << getOpenMPClauseName(DVar.CKind)
18550 << getOpenMPClauseName(OMPC_firstprivate);
18566 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
18567 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
18568 Diag(ELoc, diag::err_omp_wrong_dsa)
18569 << getOpenMPClauseName(DVar.CKind)
18570 << getOpenMPClauseName(OMPC_firstprivate);
18594 DVar =
DSAStack->getImplicitDSA(D,
true);
18595 if (DVar.CKind != OMPC_shared &&
18598 DVar.DKind == OMPD_unknown)) {
18599 Diag(ELoc, diag::err_omp_required_access)
18600 << getOpenMPClauseName(OMPC_firstprivate)
18601 << getOpenMPClauseName(OMPC_shared);
18621 return C == OMPC_reduction && !AppliedToPointee;
18629 if (DVar.CKind == OMPC_reduction &&
18633 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
18634 << getOpenMPDirectiveName(DVar.DKind);
18650 CurrDir == OMPD_target) {
18652 if (
DSAStack->checkMappableExprComponentListsForDecl(
18657 ConflictKind = WhereFoundClauseKind;
18660 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18661 << getOpenMPClauseName(OMPC_firstprivate)
18662 << getOpenMPClauseName(ConflictKind)
18663 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
18673 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18674 << getOpenMPClauseName(OMPC_firstprivate) <<
Type
18675 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
18676 bool IsDecl = !VD || VD->isThisDeclarationADefinition(
Context) ==
18679 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18688 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
18694 Expr *VDInitRefExpr =
nullptr;
18704 ".firstprivate.temp");
18719 ".firstprivate.temp");
18721 RefExpr->getExprLoc());
18727 if (IsImplicitClause) {
18728 Diag(RefExpr->getExprLoc(),
18729 diag::note_omp_task_predetermined_firstprivate_here);
18736 RefExpr->getExprLoc());
18739 if (TopDVar.CKind == OMPC_lastprivate) {
18740 Ref = TopDVar.PrivateCopy;
18742 auto *FD = dyn_cast<FieldDecl>(D);
18746 RefExpr->getExprLoc());
18750 ExprCaptures.push_back(Ref->
getDecl());
18753 if (!IsImplicitClause)
18754 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
18756 ? RefExpr->IgnoreParens()
18758 PrivateCopies.push_back(VDPrivateRefExpr);
18759 Inits.push_back(VDInitRefExpr);
18766 Vars, PrivateCopies, Inits,
18775 assert(ColonLoc.
isValid() &&
"Colon location must be valid.");
18776 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
18779 << getOpenMPClauseName(OMPC_lastprivate);
18789 for (
Expr *RefExpr : VarList) {
18790 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
18793 Expr *SimpleRefExpr = RefExpr;
18797 Vars.push_back(RefExpr);
18798 SrcExprs.push_back(
nullptr);
18799 DstExprs.push_back(
nullptr);
18800 AssignmentOps.push_back(
nullptr);
18807 auto *VD = dyn_cast<VarDecl>(D);
18813 diag::err_omp_lastprivate_incomplete_type))
18815 Type =
Type.getNonReferenceType();
18832 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
18833 bool IsDecl = !VD || VD->isThisDeclarationADefinition(
Context) ==
18836 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18850 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
18851 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
18853 DVar.CKind != OMPC_firstprivate) &&
18854 (DVar.CKind != OMPC_private || DVar.RefExpr !=
nullptr)) {
18855 Diag(ELoc, diag::err_omp_wrong_dsa)
18856 << getOpenMPClauseName(DVar.CKind)
18857 << getOpenMPClauseName(OMPC_lastprivate);
18868 DSAStackTy::DSAVarData TopDVar = DVar;
18872 DVar =
DSAStack->getImplicitDSA(D,
true);
18873 if (DVar.CKind != OMPC_shared) {
18874 Diag(ELoc, diag::err_omp_required_access)
18875 << getOpenMPClauseName(OMPC_lastprivate)
18876 << getOpenMPClauseName(OMPC_shared);
18892 Type.getUnqualifiedType(),
".lastprivate.src",
18903 PseudoDstExpr, PseudoSrcExpr);
18913 if (TopDVar.CKind == OMPC_firstprivate) {
18914 Ref = TopDVar.PrivateCopy;
18918 ExprCaptures.push_back(Ref->
getDecl());
18920 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
18931 ExprPostUpdates.push_back(
18935 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
18937 ? RefExpr->IgnoreParens()
18939 SrcExprs.push_back(PseudoSrcExpr);
18940 DstExprs.push_back(PseudoDstExpr);
18941 AssignmentOps.push_back(AssignmentOp.
get());
18948 Vars, SrcExprs, DstExprs, AssignmentOps,
18949 LPKind, LPKindLoc, ColonLoc,
18959 for (
Expr *RefExpr : VarList) {
18960 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
18963 Expr *SimpleRefExpr = RefExpr;
18967 Vars.push_back(RefExpr);
18973 auto *VD = dyn_cast<VarDecl>(D);
18981 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
18982 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
18984 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
18985 << getOpenMPClauseName(OMPC_shared);
18993 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
18995 ? RefExpr->IgnoreParens()
19006class DSARefChecker :
public StmtVisitor<DSARefChecker, bool> {
19011 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
19012 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD,
false);
19013 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
19015 if (DVar.CKind != OMPC_unknown)
19017 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
19024 return DVarPrivate.CKind != OMPC_unknown;
19028 bool VisitStmt(
Stmt *S) {
19029 for (
Stmt *Child : S->children()) {
19030 if (Child && Visit(Child))
19035 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
19042class TransformExprToCaptures :
public TreeTransform<TransformExprToCaptures> {
19049 : BaseTransform(SemaRef),
Field(
FieldDecl), CapturedExpr(nullptr) {}
19054 CapturedExpr =
buildCapture(SemaRef, Field, E,
false);
19055 return CapturedExpr;
19057 return BaseTransform::TransformMemberExpr(E);
19059 DeclRefExpr *getCapturedExpr() {
return CapturedExpr; }
19063template <
typename T,
typename U>
19066 for (
U &
Set : Lookups) {
19067 for (
auto *D :
Set) {
19068 if (T Res = Gen(cast<ValueDecl>(D)))
19078 for (
auto *RD : D->
redecls()) {
19083 auto ND = cast<NamedDecl>(RD);
19101 AssociatedClasses);
19114 for (
auto *NS : AssociatedNamespaces) {
19127 for (
auto *D : R) {
19128 auto *Underlying = D;
19129 if (
auto *USD = dyn_cast<UsingShadowDecl>(D))
19130 Underlying = USD->getTargetDecl();
19132 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
19133 !isa<OMPDeclareMapperDecl>(Underlying))
19140 if (
auto *USD = dyn_cast<UsingShadowDecl>(D))
19141 Underlying = USD->getTargetDecl();
19143 Lookups.emplace_back();
19144 Lookups.back().addDecl(Underlying);
19163 S = S->getParent();
19164 }
while (S && !S->isDeclScope(D));
19166 S = S->getParent();
19167 Lookups.emplace_back();
19168 Lookups.back().append(Lookup.
begin(), Lookup.
end());
19171 }
else if (
auto *ULE =
19172 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
19174 Decl *PrevD =
nullptr;
19178 else if (
auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
19179 Lookups.back().addDecl(DRD);
19186 filterLookupForUDReductionAndMapper<bool>(Lookups, [](
ValueDecl *D) {
19187 return !D->isInvalidDecl() &&
19188 (D->getType()->isDependentType() ||
19189 D->getType()->isInstantiationDependentType() ||
19190 D->getType()->containsUnexpandedParameterPack());
19203 true,
true, ResSet.
begin(), ResSet.
end());
19223 if (SemaRef.
isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
19224 TyRec->getDecl()->getDefinition()) {
19227 if (Lookup.
empty()) {
19228 Lookups.emplace_back();
19229 Lookups.back().append(Lookup.
begin(), Lookup.
end());
19236 if (
auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
19246 if (
auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
19260 Loc, VD->
getType(), Ty, Paths.front(),
19270 if (ReductionIdScopeSpec.
isSet()) {
19271 SemaRef.
Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
19280struct ReductionData {
19305 unsigned RedModifier = 0;
19306 ReductionData() =
delete;
19308 ReductionData(
unsigned Size,
unsigned Modifier = 0) : RedModifier(Modifier) {
19309 Vars.reserve(Size);
19310 Privates.reserve(Size);
19311 LHSs.reserve(Size);
19312 RHSs.reserve(Size);
19313 ReductionOps.reserve(Size);
19314 if (RedModifier == OMPC_REDUCTION_inscan) {
19315 InscanCopyOps.reserve(Size);
19316 InscanCopyArrayTemps.reserve(Size);
19317 InscanCopyArrayElems.reserve(Size);
19319 TaskgroupDescriptors.reserve(Size);
19320 ExprCaptures.reserve(Size);
19321 ExprPostUpdates.reserve(Size);
19325 void push(
Expr *Item,
Expr *ReductionOp) {
19326 Vars.emplace_back(Item);
19327 Privates.emplace_back(
nullptr);
19328 LHSs.emplace_back(
nullptr);
19329 RHSs.emplace_back(
nullptr);
19330 ReductionOps.emplace_back(ReductionOp);
19331 TaskgroupDescriptors.emplace_back(
nullptr);
19332 if (RedModifier == OMPC_REDUCTION_inscan) {
19333 InscanCopyOps.push_back(
nullptr);
19334 InscanCopyArrayTemps.push_back(
nullptr);
19335 InscanCopyArrayElems.push_back(
nullptr);
19340 Expr *TaskgroupDescriptor,
Expr *CopyOp,
Expr *CopyArrayTemp,
19341 Expr *CopyArrayElem) {
19342 Vars.emplace_back(Item);
19343 Privates.emplace_back(Private);
19344 LHSs.emplace_back(LHS);
19345 RHSs.emplace_back(RHS);
19346 ReductionOps.emplace_back(ReductionOp);
19347 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
19348 if (RedModifier == OMPC_REDUCTION_inscan) {
19349 InscanCopyOps.push_back(CopyOp);
19350 InscanCopyArrayTemps.push_back(CopyArrayTemp);
19351 InscanCopyArrayElems.push_back(CopyArrayElem);
19353 assert(CopyOp ==
nullptr && CopyArrayTemp ==
nullptr &&
19354 CopyArrayElem ==
nullptr &&
19355 "Copy operation must be used for inscan reductions only.");
19365 if (Length ==
nullptr) {
19372 SingleElement =
true;
19373 ArraySizes.push_back(llvm::APSInt::get(1));
19376 if (!Length->EvaluateAsInt(
Result, Context))
19379 llvm::APSInt ConstantLengthValue =
Result.Val.getInt();
19380 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
19381 ArraySizes.push_back(ConstantLengthValue);
19389 while (
const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(
Base)) {
19390 Length = TempOASE->getLength();
19391 if (Length ==
nullptr) {
19398 ArraySizes.push_back(llvm::APSInt::get(1));
19401 if (!Length->EvaluateAsInt(
Result, Context))
19404 llvm::APSInt ConstantLengthValue =
Result.Val.getInt();
19405 if (ConstantLengthValue.getSExtValue() != 1)
19408 ArraySizes.push_back(ConstantLengthValue);
19410 Base = TempOASE->getBase()->IgnoreParenImpCasts();
19414 if (!SingleElement) {
19415 while (
const auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base)) {
19417 ArraySizes.push_back(llvm::APSInt::get(1));
19418 Base = TempASE->getBase()->IgnoreParenImpCasts();
19430 return BO_AddAssign;
19432 return BO_MulAssign;
19434 return BO_AndAssign;
19436 return BO_OrAssign;
19438 return BO_XorAssign;
19494 case OO_Array_Delete:
19503 case OO_GreaterEqual:
19505 case OO_MinusEqual:
19507 case OO_SlashEqual:
19508 case OO_PercentEqual:
19509 case OO_CaretEqual:
19513 case OO_GreaterGreater:
19514 case OO_LessLessEqual:
19515 case OO_GreaterGreaterEqual:
19516 case OO_EqualEqual:
19517 case OO_ExclaimEqual:
19520 case OO_MinusMinus:
19526 case OO_Conditional:
19529 llvm_unreachable(
"Unexpected reduction identifier");
19532 if (II->isStr(
"max"))
19534 else if (II->isStr(
"min"))
19542 if (OOK == OO_Minus && S.
LangOpts.OpenMP == 52)
19543 S.
Diag(ReductionId.
getLoc(), diag::warn_omp_minus_in_reduction_deprecated);
19546 if (ReductionIdScopeSpec.
isValid())
19552 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
19553 bool FirstIter =
true;
19554 for (
Expr *RefExpr : VarList) {
19555 assert(RefExpr &&
"nullptr expr in OpenMP reduction clause.");
19563 if (!FirstIter && IR != ER)
19568 Expr *SimpleRefExpr = RefExpr;
19577 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
19578 ReductionId,
Type, BasePath, IR == ER ?
nullptr : *IR);
19579 Expr *ReductionOp =
nullptr;
19581 (DeclareReductionRef.
isUnset() ||
19582 isa<UnresolvedLookupExpr>(DeclareReductionRef.
get())))
19583 ReductionOp = DeclareReductionRef.
get();
19585 RD.push(RefExpr, ReductionOp);
19591 Expr *TaskgroupDescriptor =
nullptr;
19593 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
19594 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
19596 Type = ASE->getType().getNonReferenceType();
19601 Type = ATy->getElementType();
19604 Type =
Type.getNonReferenceType();
19608 auto *VD = dyn_cast<VarDecl>(D);
19614 diag::err_omp_reduction_incomplete_type))
19620 false, ASE || OASE))
19627 if (!ASE && !OASE) {
19629 VarDecl *VDDef = VD->getDefinition();
19631 DSARefChecker Check(Stack);
19632 if (Check.Visit(VDDef->
getInit())) {
19633 S.
Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
19634 << getOpenMPClauseName(ClauseKind) << ERange;
19652 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D,
false);
19653 if (DVar.CKind == OMPC_reduction) {
19654 S.
Diag(ELoc, diag::err_omp_once_referenced)
19655 << getOpenMPClauseName(ClauseKind);
19657 S.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
19660 if (DVar.CKind != OMPC_unknown) {
19661 S.
Diag(ELoc, diag::err_omp_wrong_dsa)
19662 << getOpenMPClauseName(DVar.CKind)
19663 << getOpenMPClauseName(OMPC_reduction);
19675 DVar = Stack->getImplicitDSA(D,
true);
19676 if (DVar.CKind != OMPC_shared) {
19677 S.
Diag(ELoc, diag::err_omp_required_access)
19678 << getOpenMPClauseName(OMPC_reduction)
19679 << getOpenMPClauseName(OMPC_shared);
19687 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D,
false);
19688 if (DVar.CKind == OMPC_threadprivate) {
19689 S.
Diag(ELoc, diag::err_omp_wrong_dsa)
19690 << getOpenMPClauseName(DVar.CKind)
19691 << getOpenMPClauseName(OMPC_reduction);
19701 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
19702 ReductionId,
Type, BasePath, IR == ER ?
nullptr : *IR);
19706 (DeclareReductionRef.
isUnset() ||
19707 isa<UnresolvedLookupExpr>(DeclareReductionRef.
get()))) {
19708 RD.push(RefExpr, DeclareReductionRef.
get());
19711 if (BOK == BO_Comma && DeclareReductionRef.
isUnset()) {
19715 diag::err_omp_unknown_reduction_identifier_since_omp_6_0)
19716 <<
Type << ReductionIdRange;
19719 diag::err_omp_unknown_reduction_identifier_prior_omp_6_0)
19720 <<
Type << ReductionIdRange;
19732 if (DeclareReductionRef.
isUnset()) {
19733 if ((BOK == BO_GT || BOK == BO_LT) &&
19736 S.
Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
19737 << getOpenMPClauseName(ClauseKind) << S.
getLangOpts().CPlusPlus;
19738 if (!ASE && !OASE) {
19739 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19742 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19747 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
19749 S.
Diag(ELoc, diag::err_omp_clause_floating_type_arg)
19750 << getOpenMPClauseName(ClauseKind);
19751 if (!ASE && !OASE) {
19752 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19755 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19762 Type =
Type.getNonLValueExprType(Context).getUnqualifiedType();
19771 bool ConstantLengthOASE =
false;
19773 bool SingleElement;
19776 Context, OASE, SingleElement, ArraySizes);
19779 if (ConstantLengthOASE && !SingleElement) {
19780 for (llvm::APSInt &Size : ArraySizes)
19787 if ((OASE && !ConstantLengthOASE) ||
19792 S.
Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
19793 S.
Diag(ELoc, diag::note_vla_unsupported);
19796 S.
targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
19797 S.
targetDiag(ELoc, diag::note_vla_unsupported);
19810 }
else if (!ASE && !OASE &&
19818 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
19823 if (DeclareReductionRef.
isUsable()) {
19825 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
19826 if (DRD->getInitializer()) {
19852 Type = ComplexTy->getElementType();
19854 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
19861 llvm::APInt InitValue = llvm::APInt::getAllOnes(Size);
19883 llvm::APInt InitValue =
19884 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
19885 : llvm::APInt::getMinValue(Size)
19886 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
19887 : llvm::APInt::getMaxValue(Size);
19898 llvm::APFloat InitValue = llvm::APFloat::getLargest(
19929 llvm_unreachable(
"Unexpected reduction operation");
19938 }
else if (!
Init) {
19948 S.
Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
19949 <<
Type << ReductionIdRange;
19950 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19953 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19959 if (DeclareReductionRef.
isUsable()) {
19964 if (!BasePath.empty()) {
19968 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.
get(), &BasePath,
19971 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.
get(), &BasePath,
19975 QualType Params[] = {PtrRedTy, PtrRedTy};
19990 CombBOK, LHSDRE, RHSDRE);
19997 if (BOK != BO_LT && BOK != BO_GT) {
20000 BO_Assign, LHSDRE, ReductionOp.
get());
20002 auto *ConditionalOp =
new (Context)
20007 BO_Assign, LHSDRE, ConditionalOp);
20020 ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
20021 if (ClauseKind == OMPC_reduction &&
20022 RD.RedModifier == OMPC_REDUCTION_inscan) {
20024 CopyOpRes = S.
BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
20034 if (Stack->getCurrentDirective() == OMPD_simd ||
20072 if (ClauseKind == OMPC_in_reduction) {
20075 const Expr *ParentReductionOp =
nullptr;
20076 Expr *ParentBOKTD =
nullptr, *ParentReductionOpTD =
nullptr;
20077 DSAStackTy::DSAVarData ParentBOKDSA =
20078 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
20080 DSAStackTy::DSAVarData ParentReductionOpDSA =
20081 Stack->getTopMostTaskgroupReductionData(
20082 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
20083 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
20084 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
20085 if ((DeclareReductionRef.
isUnset() && IsParentReductionOp) ||
20086 (DeclareReductionRef.
isUsable() && IsParentBOK) ||
20087 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
20088 bool EmitError =
true;
20089 if (IsParentReductionOp && DeclareReductionRef.
isUsable()) {
20090 llvm::FoldingSetNodeID RedId, ParentRedId;
20091 ParentReductionOp->
Profile(ParentRedId, Context,
true);
20092 DeclareReductionRef.
get()->
Profile(RedId, Context,
20094 EmitError = RedId != ParentRedId;
20098 diag::err_omp_reduction_identifier_mismatch)
20099 << ReductionIdRange << RefExpr->getSourceRange();
20101 diag::note_omp_previous_reduction_identifier)
20103 << (IsParentBOK ? ParentBOKDSA.RefExpr
20104 : ParentReductionOpDSA.RefExpr)
20105 ->getSourceRange();
20109 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
20116 TransformExprToCaptures RebuildToCapture(S, D);
20118 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
20119 Ref = RebuildToCapture.getCapturedExpr();
20121 VarsExpr = Ref =
buildCapture(S, D, SimpleRefExpr,
false);
20124 RD.ExprCaptures.emplace_back(Ref->
getDecl());
20130 S.
BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
20135 Stack->getCurrentDirective() == OMPD_taskgroup) {
20136 S.
Diag(RefExpr->getExprLoc(),
20137 diag::err_omp_reduction_non_addressable_expression)
20138 << RefExpr->getSourceRange();
20141 RD.ExprPostUpdates.emplace_back(
20148 unsigned Modifier = RD.RedModifier;
20151 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
20152 Modifier = OMPC_REDUCTION_task;
20153 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
20155 if (Modifier == OMPC_REDUCTION_task &&
20156 (CurrDir == OMPD_taskgroup ||
20160 if (DeclareReductionRef.
isUsable())
20161 Stack->addTaskgroupReductionData(D, ReductionIdRange,
20162 DeclareReductionRef.
get());
20164 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
20166 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.
get(),
20167 TaskgroupDescriptor, CopyOpRes.
get(), TempArrayRes.
get(),
20168 TempArrayElem.
get());
20170 return RD.Vars.empty();
20180 Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
20183 << getOpenMPClauseName(OMPC_reduction);
20191 if (Modifier == OMPC_REDUCTION_inscan &&
20192 (
DSAStack->getCurrentDirective() != OMPD_for &&
20193 DSAStack->getCurrentDirective() != OMPD_for_simd &&
20194 DSAStack->getCurrentDirective() != OMPD_simd &&
20195 DSAStack->getCurrentDirective() != OMPD_parallel_for &&
20196 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) {
20197 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
20201 ReductionData RD(VarList.size(), Modifier);
20203 StartLoc, LParenLoc, ColonLoc, EndLoc,
20204 ReductionIdScopeSpec, ReductionId,
20205 UnresolvedReductions, RD))
20209 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
20211 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
20212 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
20222 ReductionData RD(VarList.size());
20224 StartLoc, LParenLoc, ColonLoc, EndLoc,
20225 ReductionIdScopeSpec, ReductionId,
20226 UnresolvedReductions, RD))
20230 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
20232 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
20242 ReductionData RD(VarList.size());
20244 StartLoc, LParenLoc, ColonLoc, EndLoc,
20245 ReductionIdScopeSpec, ReductionId,
20246 UnresolvedReductions, RD))
20250 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
20252 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
20259 if ((!
LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
20261 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) <<
LangOpts.CPlusPlus;
20269 bool IsDeclareSimd) {
20270 const auto *VD = dyn_cast_or_null<VarDecl>(D);
20274 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
20276 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
20280 Type =
Type.getNonReferenceType();
20287 if (!IsDeclareSimd &&
20292 Type =
Type.getUnqualifiedType().getCanonicalType();
20293 const auto *Ty =
Type.getTypePtrOrNull();
20294 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
20295 !Ty->isIntegralType(
Context) && !Ty->isPointerType())) {
20296 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) <<
Type;
20298 bool IsDecl = !VD || VD->isThisDeclarationADefinition(
Context) ==
20301 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20324 Diag(Step->
getBeginLoc(), diag::err_omp_step_simple_modifier_exclusive);
20326 LinKind = OMPC_LINEAR_val;
20327 for (
Expr *RefExpr : VarList) {
20328 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
20331 Expr *SimpleRefExpr = RefExpr;
20335 Vars.push_back(RefExpr);
20336 Privates.push_back(
nullptr);
20337 Inits.push_back(
nullptr);
20344 auto *VD = dyn_cast<VarDecl>(D);
20350 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
20351 if (DVar.RefExpr) {
20352 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
20353 << getOpenMPClauseName(OMPC_linear);
20360 Type =
Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
20366 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
20375 ExprCaptures.push_back(Ref->
getDecl());
20382 SimpleRefExpr, RefRes.
get());
20385 ExprPostUpdates.push_back(
20390 if (LinKind == OMPC_LINEAR_uval)
20391 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
20393 InitExpr = VD ? SimpleRefExpr : Ref;
20398 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
20400 ? RefExpr->IgnoreParens()
20402 Privates.push_back(PrivateRef);
20403 Inits.push_back(InitRef);
20409 Expr *StepExpr = Step;
20410 Expr *CalcStepExpr =
nullptr;
20418 StepExpr = Val.
get();
20426 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.
get(), StepExpr);
20431 if (std::optional<llvm::APSInt>
Result =
20433 if (!
Result->isNegative() && !
Result->isStrictlyPositive())
20434 Diag(StepLoc, diag::warn_omp_linear_step_zero)
20435 << Vars[0] << (Vars.size() > 1);
20439 CalcStepExpr = CalcStep.
get();
20444 ColonLoc, StepModifierLoc, EndLoc, Vars,
20445 Privates, Inits, StepExpr, CalcStepExpr,
20451 Expr *NumIterations,
Sema &SemaRef,
20452 Scope *S, DSAStackTy *Stack) {
20464 Step = cast<BinaryOperator>(CalcStep)->getLHS();
20465 bool HasErrors =
false;
20466 auto CurInit = Clause.
inits().begin();
20467 auto CurPrivate = Clause.
privates().begin();
20472 Expr *SimpleRefExpr = RefExpr;
20473 auto Res =
getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
20475 if (Res.second || !D) {
20476 Updates.push_back(
nullptr);
20477 Finals.push_back(
nullptr);
20481 auto &&Info = Stack->isLoopControlVariable(D);
20488 diag::err_omp_linear_distribute_var_non_loop_iteration);
20489 Updates.push_back(
nullptr);
20490 Finals.push_back(
nullptr);
20494 Expr *InitExpr = *CurInit;
20497 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
20499 if (LinKind == OMPC_LINEAR_uval)
20500 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
20504 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
20511 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
20522 S, RefExpr->getExprLoc(), BO_Assign, CapturedRef,
20525 Final = *CurPrivate;
20529 if (!
Update.isUsable() || !Final.isUsable()) {
20530 Updates.push_back(
nullptr);
20531 Finals.push_back(
nullptr);
20532 UsedExprs.push_back(
nullptr);
20535 Updates.push_back(
Update.get());
20536 Finals.push_back(Final.get());
20538 UsedExprs.push_back(SimpleRefExpr);
20544 UsedExprs.push_back(S);
20546 UsedExprs.append(Clause.
varlist_size() + 1 - UsedExprs.size(),
nullptr);
20557 for (
Expr *RefExpr : VarList) {
20558 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
20561 Expr *SimpleRefExpr = RefExpr;
20565 Vars.push_back(RefExpr);
20572 auto *VD = dyn_cast<VarDecl>(D);
20580 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
20582 bool IsDecl = !VD || VD->isThisDeclarationADefinition(
Context) ==
20585 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20592 if (
const Expr *PrevRef =
DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
20593 Diag(ELoc, diag::err_omp_used_in_clause_twice)
20594 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
20595 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
20596 << getOpenMPClauseName(OMPC_aligned);
20604 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
20613 if (Alignment !=
nullptr) {
20618 Alignment = AlignResult.
get();
20624 EndLoc, Vars, Alignment);
20635 for (
Expr *RefExpr : VarList) {
20636 assert(RefExpr &&
"NULL expr in OpenMP copyin clause.");
20637 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
20639 Vars.push_back(RefExpr);
20640 SrcExprs.push_back(
nullptr);
20641 DstExprs.push_back(
nullptr);
20642 AssignmentOps.push_back(
nullptr);
20651 auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
20652 if (!DE || !isa<VarDecl>(DE->getDecl())) {
20653 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
20654 << 0 << RefExpr->getSourceRange();
20658 Decl *D = DE->getDecl();
20659 auto *VD = cast<VarDecl>(D);
20664 Vars.push_back(DE);
20665 SrcExprs.push_back(
nullptr);
20666 DstExprs.push_back(
nullptr);
20667 AssignmentOps.push_back(
nullptr);
20673 if (!
DSAStack->isThreadPrivate(VD)) {
20674 Diag(ELoc, diag::err_omp_required_access)
20675 << getOpenMPClauseName(OMPC_copyin)
20676 << getOpenMPDirectiveName(OMPD_threadprivate);
20691 buildVarDecl(*
this, DE->getBeginLoc(), ElemType,
".copyin.dst",
20698 BuildBinOp(
nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
20707 DSAStack->addDSA(VD, DE, OMPC_copyin);
20708 Vars.push_back(DE);
20709 SrcExprs.push_back(PseudoSrcExpr);
20710 DstExprs.push_back(PseudoDstExpr);
20711 AssignmentOps.push_back(AssignmentOp.
get());
20718 SrcExprs, DstExprs, AssignmentOps);
20729 for (
Expr *RefExpr : VarList) {
20730 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
20733 Expr *SimpleRefExpr = RefExpr;
20737 Vars.push_back(RefExpr);
20738 SrcExprs.push_back(
nullptr);
20739 DstExprs.push_back(
nullptr);
20740 AssignmentOps.push_back(
nullptr);
20747 auto *VD = dyn_cast<VarDecl>(D);
20752 if (!VD || !
DSAStack->isThreadPrivate(VD)) {
20753 DSAStackTy::DSAVarData DVar =
20755 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
20757 Diag(ELoc, diag::err_omp_wrong_dsa)
20758 << getOpenMPClauseName(DVar.CKind)
20759 << getOpenMPClauseName(OMPC_copyprivate);
20767 if (DVar.CKind == OMPC_unknown) {
20768 DVar =
DSAStack->getImplicitDSA(D,
false);
20769 if (DVar.CKind == OMPC_shared) {
20770 Diag(ELoc, diag::err_omp_required_access)
20771 << getOpenMPClauseName(OMPC_copyprivate)
20772 <<
"threadprivate or private in the enclosing context";
20781 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
20782 << getOpenMPClauseName(OMPC_copyprivate) <<
Type
20783 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
20784 bool IsDecl = !VD || VD->isThisDeclarationADefinition(
Context) ==
20787 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20807 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
20819 VD ? RefExpr->IgnoreParens()
20821 SrcExprs.push_back(PseudoSrcExpr);
20822 DstExprs.push_back(PseudoDstExpr);
20823 AssignmentOps.push_back(AssignmentOp.
get());
20830 Vars, SrcExprs, DstExprs, AssignmentOps);
20837 if (VarList.empty())
20845 bool Diagnose =
true) {
20846 QualType OMPDependT = Stack->getOMPDependT();
20847 if (!OMPDependT.
isNull())
20853 S.
Diag(Loc, diag::err_omp_implied_type_not_found) <<
"omp_depend_t";
20856 Stack->setOMPDependT(PT.
get());
20873 (OMPDependTFound &&
20876 Diag(Depobj->
getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
20881 Diag(Depobj->
getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
20890struct DoacrossDataInfoTy {
20896 llvm::APSInt TotalDepCount;
20899static DoacrossDataInfoTy
20906 llvm::APSInt DepCounter(32);
20907 llvm::APSInt TotalDepCount(32);
20909 if (
const Expr *OrderedCountExpr =
20910 Stack->getParentOrderedRegionParam().first) {
20911 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(SemaRef.
Context);
20912 TotalDepCount.setIsUnsigned(
true);
20915 for (
Expr *RefExpr : VarList) {
20916 assert(RefExpr &&
"NULL expr in OpenMP doacross clause.");
20917 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
20919 Vars.push_back(RefExpr);
20926 if (Stack->getParentOrderedRegionParam().first &&
20927 DepCounter >= TotalDepCount) {
20928 SemaRef.
Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
20942 Vars.push_back(RefExpr);
20948 Expr *LHS = SimpleExpr;
20949 Expr *RHS =
nullptr;
20950 if (
auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
20952 OOLoc = BO->getOperatorLoc();
20955 }
else if (
auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
20956 OOK = OCE->getOperator();
20957 OOLoc = OCE->getOperatorLoc();
20960 }
else if (
auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
20961 OOK = MCE->getMethodDecl()
20964 .getCXXOverloadedOperator();
20965 OOLoc = MCE->getCallee()->getExprLoc();
20974 Vars.push_back(RefExpr);
20980 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK !=
OO_None)) {
20981 SemaRef.
Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
20986 RHS, OMPC_depend,
false);
20991 Stack->getParentOrderedRegionParam().first &&
20992 DepCounter != Stack->isParentLoopControlVariable(D).first) {
20994 Stack->getParentLoopControlVariable(DepCounter.getZExtValue());
20996 SemaRef.
Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
20999 SemaRef.
Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
21003 OpsOffs.emplace_back(RHS, OOK);
21005 Vars.push_back(RefExpr->IgnoreParenImpCasts());
21008 TotalDepCount > VarList.size() &&
21009 Stack->getParentOrderedRegionParam().first &&
21010 Stack->getParentLoopControlVariable(VarList.size() + 1)) {
21011 SemaRef.
Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
21012 << 1 << Stack->getParentLoopControlVariable(VarList.size() + 1);
21014 return {Vars, OpsOffs, TotalDepCount};
21024 if (
DSAStack->getCurrentDirective() == OMPD_ordered &&
21025 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
21026 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
21027 <<
"'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
21030 if (
DSAStack->getCurrentDirective() == OMPD_taskwait &&
21031 DepKind == OMPC_DEPEND_mutexinoutset) {
21032 Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed);
21035 if ((
DSAStack->getCurrentDirective() != OMPD_ordered ||
21036 DSAStack->getCurrentDirective() == OMPD_depobj) &&
21038 DepKind == OMPC_DEPEND_sink ||
21040 DSAStack->getCurrentDirective() == OMPD_depobj) &&
21041 DepKind == OMPC_DEPEND_depobj))) {
21043 OMPC_DEPEND_outallmemory,
21044 OMPC_DEPEND_inoutallmemory};
21045 if (
LangOpts.OpenMP < 50 ||
DSAStack->getCurrentDirective() == OMPD_depobj)
21046 Except.push_back(OMPC_DEPEND_depobj);
21048 Except.push_back(OMPC_DEPEND_inoutset);
21050 ?
"depend modifier(iterator) or "
21052 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
21056 << getOpenMPClauseName(OMPC_depend);
21060 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
21062 diag::err_omp_depend_sink_source_with_modifier);
21067 Diag(DepModifier->
getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
21071 llvm::APSInt TotalDepCount(32);
21073 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
21075 *
this, DepKind == OMPC_DEPEND_source, VarList,
DSAStack, EndLoc);
21076 Vars = VarOffset.Vars;
21077 OpsOffs = VarOffset.OpsOffs;
21078 TotalDepCount = VarOffset.TotalDepCount;
21080 for (
Expr *RefExpr : VarList) {
21081 assert(RefExpr &&
"NULL expr in OpenMP shared clause.");
21082 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
21084 Vars.push_back(RefExpr);
21090 if (DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) {
21091 bool OMPDependTFound =
LangOpts.OpenMP >= 50;
21092 if (OMPDependTFound)
21094 DepKind == OMPC_DEPEND_depobj);
21095 if (DepKind == OMPC_DEPEND_depobj) {
21099 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
21100 !RefExpr->isInstantiationDependent() &&
21101 !RefExpr->containsUnexpandedParameterPack() &&
21102 (OMPDependTFound &&
21104 RefExpr->getType()))) {
21105 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
21106 << 0 << RefExpr->getType() << RefExpr->getSourceRange();
21109 if (!RefExpr->isLValue()) {
21110 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
21111 << 1 << RefExpr->getType() << RefExpr->getSourceRange();
21118 QualType ExprTy = RefExpr->getType().getNonReferenceType();
21119 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
21126 ExprTy = ATy->getElementType();
21132 const Expr *Length = OASE->getLength();
21134 if (Length && !Length->isValueDependent() &&
21136 Result.Val.getInt().isZero()) {
21138 diag::err_omp_depend_zero_length_array_section_not_allowed)
21148 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
21149 !RefExpr->isInstantiationDependent() &&
21150 !RefExpr->containsUnexpandedParameterPack() &&
21151 (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
21152 (OMPDependTFound &&
DSAStack->getOMPDependT().getTypePtr() ==
21154 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21155 << (
LangOpts.OpenMP >= 50 ? 1 : 0)
21156 << (
LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
21160 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
21161 if (ASE && !ASE->getBase()->isTypeDependent() &&
21164 .getNonReferenceType()
21165 ->isPointerType() &&
21166 !ASE->getBase()->getType().getNonReferenceType()->isArrayType()) {
21167 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21168 << (
LangOpts.OpenMP >= 50 ? 1 : 0)
21169 << (
LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
21177 RefExpr->IgnoreParenImpCasts());
21179 if (!Res.
isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
21180 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
21181 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21182 << (
LangOpts.OpenMP >= 50 ? 1 : 0)
21183 << (
LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
21188 Vars.push_back(RefExpr->IgnoreParenImpCasts());
21192 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
21193 DepKind != OMPC_DEPEND_outallmemory &&
21194 DepKind != OMPC_DEPEND_inoutallmemory && Vars.empty())
21198 Context, StartLoc, LParenLoc, EndLoc,
21199 {DepKind, DepLoc,
Data.ColonLoc,
Data.OmpAllMemoryLoc}, DepModifier, Vars,
21200 TotalDepCount.getZExtValue());
21201 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
21202 DSAStack->isParentOrderedRegion())
21203 DSAStack->addDoacrossDependClause(
C, OpsOffs);
21213 "Unexpected device modifier in OpenMP < 50.");
21215 bool ErrorFound =
false;
21217 std::string Values =
21219 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
21220 << Values << getOpenMPClauseName(OMPC_device);
21225 Stmt *HelperValStmt =
nullptr;
21238 if (Modifier == OMPC_DEVICE_ancestor) {
21242 diag::err_omp_device_ancestor_without_requires_reverse_offload);
21252 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
21253 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
21258 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
21259 LParenLoc, ModifierLoc, EndLoc);
21264 bool FullCheck =
true) {
21269 SemaRef.
Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
21279 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
21284 if (isa<ArraySubscriptExpr>(E) ||
21285 (OASE && OASE->getColonLocFirst().isInvalid())) {
21286 if (
const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
21287 return ATy->getSize().getSExtValue() != 1;
21292 assert(OASE &&
"Expecting array section if not an array subscript.");
21293 const Expr *LowerBound = OASE->getLowerBound();
21294 const Expr *Length = OASE->getLength();
21303 llvm::APSInt ConstLowerBound =
Result.Val.getInt();
21304 if (ConstLowerBound.getSExtValue())
21319 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr());
21327 llvm::APSInt ConstLength =
Result.Val.getInt();
21328 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
21337 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
21341 if (isa<ArraySubscriptExpr>(E) ||
21342 (OASE && OASE->getColonLocFirst().isInvalid()))
21345 assert(OASE &&
"Expecting array section if not an array subscript.");
21346 const Expr *Length = OASE->getLength();
21352 if (
const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
21353 return ATy->getSize().getSExtValue() != 1;
21363 llvm::APSInt ConstLength =
Result.Val.getInt();
21364 return ConstLength.getSExtValue() != 1;
21403class MapBaseChecker final :
public StmtVisitor<MapBaseChecker, bool> {
21408 bool IsNonContiguous =
false;
21409 bool NoDiagnose =
false;
21410 const Expr *RelevantExpr =
nullptr;
21411 bool AllowUnitySizeArraySection =
true;
21412 bool AllowWholeSizeArraySection =
true;
21413 bool AllowAnotherPtr =
true;
21417 void emitErrorMsg() {
21419 if (SemaRef.getLangOpts().OpenMP < 50) {
21421 diag::err_omp_expected_named_var_member_or_array_expression)
21424 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
21425 << getOpenMPClauseName(CKind) << ERange;
21431 if (!isa<VarDecl>(DRE->
getDecl())) {
21435 assert(!RelevantExpr &&
"RelevantExpr is expected to be nullptr");
21436 RelevantExpr = DRE;
21438 Components.emplace_back(DRE, DRE->
getDecl(), IsNonContiguous);
21446 if (isa<CXXThisExpr>(BaseE)) {
21447 assert(!RelevantExpr &&
"RelevantExpr is expected to be nullptr");
21456 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
21472 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
21492 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
21496 return RelevantExpr || Visit(E);
21506 AllowUnitySizeArraySection =
false;
21507 AllowWholeSizeArraySection =
false;
21510 Components.emplace_back(ME, FD, IsNonContiguous);
21511 return RelevantExpr || Visit(E);
21519 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
21523 return RelevantExpr || Visit(E);
21530 AllowWholeSizeArraySection =
false;
21536 !Result.Val.getInt().isZero()) {
21538 diag::err_omp_invalid_map_this_expr);
21540 diag::note_omp_invalid_subscript_on_this_ptr_map);
21542 assert(!RelevantExpr &&
"RelevantExpr is expected to be nullptr");
21547 Components.emplace_back(AE,
nullptr, IsNonContiguous);
21549 return RelevantExpr || Visit(E);
21555 assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) &&
21556 "Array sections cannot be implicitly mapped.");
21570 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
21580 if (AllowWholeSizeArraySection) {
21587 if (NotWhole || IsPointer)
21588 AllowWholeSizeArraySection =
false;
21589 }
else if (DKind == OMPD_target_update &&
21590 SemaRef.getLangOpts().OpenMP >= 50) {
21591 if (IsPointer && !AllowAnotherPtr)
21592 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
21595 IsNonContiguous =
true;
21596 }
else if (AllowUnitySizeArraySection && NotUnity) {
21602 diag::err_array_section_does_not_specify_contiguous_storage)
21608 AllowAnotherPtr =
false;
21610 if (
const auto *TE = dyn_cast<CXXThisExpr>(E)) {
21617 diag::err_omp_invalid_map_this_expr);
21619 diag::note_omp_invalid_length_on_this_ptr_mapping);
21623 SemaRef.getASTContext()) &&
21626 diag::err_omp_invalid_map_this_expr);
21628 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
21630 assert(!RelevantExpr &&
"RelevantExpr is expected to be nullptr");
21635 Components.emplace_back(OASE,
nullptr,
false);
21636 return RelevantExpr || Visit(E);
21642 Components.emplace_back(E,
nullptr, IsNonContiguous);
21644 return Visit(
Base->IgnoreParenImpCasts());
21648 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->
isLValue() ||
21653 if (!RelevantExpr) {
21655 Components.emplace_back(UO,
nullptr,
false);
21671 Components.emplace_back(BO,
nullptr,
false);
21674 "Either LHS or RHS have base decl inside");
21676 return RelevantExpr || Visit(LE);
21677 return RelevantExpr || Visit(RE);
21680 assert(!RelevantExpr &&
"RelevantExpr is expected to be nullptr");
21681 RelevantExpr = CTE;
21682 Components.emplace_back(CTE,
nullptr, IsNonContiguous);
21686 assert(!RelevantExpr &&
"RelevantExpr is expected to be nullptr");
21687 Components.emplace_back(COCE,
nullptr, IsNonContiguous);
21696 return Visit(Source);
21698 bool VisitStmt(
Stmt *) {
21702 const Expr *getFoundBase()
const {
return RelevantExpr; }
21703 explicit MapBaseChecker(
21707 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
21708 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
21722 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
21726 if (SemaRef.
getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
21727 (CKind == OMPC_to || CKind == OMPC_from)) {
21728 auto CI = CurComponents.rbegin();
21729 auto CE = CurComponents.rend();
21730 for (; CI != CE; ++CI) {
21732 dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
21737 SemaRef.
Diag(ELoc, diag::err_array_section_does_not_specify_length)
21741 return Checker.getFoundBase();
21750 bool CurrentRegionOnly,
21761 assert(!CurComponents.empty() &&
"Map clause expression with no components!");
21762 assert(CurComponents.back().getAssociatedDeclaration() == VD &&
21763 "Map clause expression with unexpected base!");
21766 bool IsEnclosedByDataEnvironmentExpr =
false;
21767 const Expr *EnclosingExpr =
nullptr;
21769 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
21770 VD, CurrentRegionOnly,
21771 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
21772 ERange, CKind, &EnclosingExpr,
21776 if (CKind == Kind && SemaRef.
LangOpts.OpenMP >= 50)
21778 assert(!StackComponents.empty() &&
21779 "Map clause expression with no components!");
21780 assert(StackComponents.back().getAssociatedDeclaration() == VD &&
21781 "Map clause expression with unexpected base!");
21785 const Expr *RE = StackComponents.front().getAssociatedExpression();
21791 auto CI = CurComponents.rbegin();
21792 auto CE = CurComponents.rend();
21793 auto SI = StackComponents.rbegin();
21794 auto SE = StackComponents.rend();
21795 for (; CI != CE && SI != SE; ++CI, ++SI) {
21800 if (CurrentRegionOnly &&
21801 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
21802 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
21803 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
21804 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
21805 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
21806 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
21807 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
21808 diag::err_omp_multiple_array_items_in_map_clause)
21809 << CI->getAssociatedExpression()->getSourceRange();
21810 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
21811 diag::note_used_here)
21812 << SI->getAssociatedExpression()->getSourceRange();
21817 if (CI->getAssociatedExpression()->getStmtClass() !=
21818 SI->getAssociatedExpression()->getStmtClass())
21822 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
21828 for (; SI != SE; ++SI) {
21830 if (
const auto *ASE =
21831 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
21832 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
21833 }
else if (
const auto *OASE = dyn_cast<OMPArraySectionExpr>(
21834 SI->getAssociatedExpression())) {
21835 const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
21837 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
21838 }
else if (
const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
21839 SI->getAssociatedExpression())) {
21840 Type = OASE->getBase()->getType()->getPointeeType();
21844 SemaRef, SI->getAssociatedExpression(),
Type))
21854 if (CI == CE && SI == SE) {
21855 if (CurrentRegionOnly) {
21856 if (CKind == OMPC_map) {
21857 SemaRef.
Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
21859 assert(CKind == OMPC_to || CKind == OMPC_from);
21860 SemaRef.
Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
21869 IsEnclosedByDataEnvironmentExpr =
true;
21874 std::prev(CI)->getAssociatedDeclaration()->getType();
21876 std::prev(CI)->getAssociatedExpression()->getExprLoc();
21895 if (CI == CE || SI == SE) {
21898 diag::err_omp_pointer_mapped_along_with_derived_section)
21904 if (CI->getAssociatedExpression()->getStmtClass() !=
21905 SI->getAssociatedExpression()->getStmtClass() ||
21906 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
21907 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
21908 assert(CI != CE && SI != SE);
21909 SemaRef.
Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
21922 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
21923 if (CKind == OMPC_map) {
21924 if (CI != CE || SI != SE) {
21928 CI != CE ? CurComponents.begin() : StackComponents.begin();
21929 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
21931 while (It != End && !It->getAssociatedDeclaration())
21932 std::advance(It, 1);
21933 assert(It != End &&
21934 "Expected at least one component with the declaration.");
21935 if (It !=
Begin && It->getAssociatedDeclaration()
21937 .getCanonicalType()
21938 ->isAnyPointerType()) {
21939 IsEnclosedByDataEnvironmentExpr =
false;
21940 EnclosingExpr =
nullptr;
21944 SemaRef.
Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
21946 assert(CKind == OMPC_to || CKind == OMPC_from);
21947 SemaRef.
Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
21957 if (!CurrentRegionOnly && SI != SE)
21958 EnclosingExpr = RE;
21962 IsEnclosedByDataEnvironmentExpr |=
21963 (!CurrentRegionOnly && CI != CE && SI == SE);
21968 if (CurrentRegionOnly)
21982 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
21984 diag::err_omp_original_storage_is_shared_and_does_not_contain)
22000 Expr *UnresolvedMapper) {
22015 while (S && !S->isDeclScope(D))
22016 S = S->getParent();
22018 S = S->getParent();
22019 Lookups.emplace_back();
22020 Lookups.back().append(Lookup.
begin(), Lookup.
end());
22023 }
else if (
auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
22027 auto *DMD = cast<OMPDeclareMapperDecl>(D);
22028 assert(DMD &&
"Expect valid OMPDeclareMapperDecl during instantiation.");
22029 Lookups.back().addDecl(DMD);
22037 filterLookupForUDReductionAndMapper<bool>(Lookups, [](
ValueDecl *D) {
22038 return !D->isInvalidDecl() &&
22039 (D->getType()->isDependentType() ||
22040 D->getType()->isInstantiationDependentType() ||
22041 D->getType()->containsUnexpandedParameterPack());
22052 false,
true, URS.
begin(), URS.
end());
22059 SemaRef.
Diag(Loc, diag::err_omp_mapper_wrong_type);
22066 if (
auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
22076 if (
auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
22099 SemaRef.
Diag(Loc, diag::err_omp_invalid_mapper)
22109struct MappableVarListInfo {
22124 VarComponents.reserve(VarList.size());
22125 VarBaseDeclarations.reserve(VarList.size());
22143 bool IsMapTypeImplicit =
false,
bool NoDiagnose =
false) {
22145 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
22146 "Unexpected clause kind with mappable expressions!");
22154 MapperId.
setName(DeclNames.getIdentifier(
22156 MapperId.
setLoc(StartLoc);
22160 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
22161 bool UpdateUMIt =
false;
22162 Expr *UnresolvedMapper =
nullptr;
22164 bool HasHoldModifier =
22165 llvm::is_contained(Modifiers, OMPC_MAP_MODIFIER_ompx_hold);
22173 for (
Expr *RE : MVLI.VarList) {
22174 assert(RE &&
"Null expr in omp to/from/map clause");
22178 if (UpdateUMIt && UMIt != UMEnd) {
22182 "Expect the size of UnresolvedMappers to match with that of VarList");
22186 UnresolvedMapper = *UMIt;
22195 SemaRef, DSAS->
getCurScope(), MapperIdScopeSpec, MapperId,
22199 MVLI.UDMapperList.push_back(ER.
get());
22202 MVLI.ProcessedVarList.push_back(RE);
22211 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
22214 SemaRef.
Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
22227 DSAS->getCurrentDirective(), NoDiagnose);
22231 assert(!CurComponents.empty() &&
22232 "Invalid mappable expression information.");
22234 if (
const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
22236 DSAS->addMappedClassesQualTypes(TE->getType());
22239 SemaRef, DSAS->
getCurScope(), MapperIdScopeSpec, MapperId,
22243 MVLI.UDMapperList.push_back(ER.
get());
22245 MVLI.ProcessedVarList.push_back(RE);
22246 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22247 MVLI.VarComponents.back().append(CurComponents.begin(),
22248 CurComponents.end());
22249 MVLI.VarBaseDeclarations.push_back(
nullptr);
22256 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
22257 assert(CurDeclaration &&
"Null decl on map clause.");
22260 "Expecting components to have associated only canonical declarations.");
22262 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
22263 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
22265 assert((VD || FD) &&
"Only variables or fields are expected here!");
22272 if (VD && DSAS->isThreadPrivate(VD)) {
22275 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD,
false);
22276 SemaRef.
Diag(ELoc, diag::err_omp_threadprivate_in_clause)
22277 << getOpenMPClauseName(CKind);
22291 true, CurComponents, CKind))
22293 if (CKind == OMPC_map &&
22296 false, CurComponents, CKind))
22303 auto I = llvm::find_if(
22308 assert(I != CurComponents.end() &&
"Null decl on map clause.");
22311 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->
IgnoreParens());
22312 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->
IgnoreParens());
22313 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->
IgnoreParens());
22315 Type = ASE->getType().getNonReferenceType();
22320 Type = ATy->getElementType();
22323 Type =
Type.getNonReferenceType();
22324 }
else if (OAShE) {
22338 if (CKind == OMPC_map) {
22345 if (DKind == OMPD_target_enter_data &&
22346 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc ||
22348 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
22349 << (IsMapTypeImplicit ? 1 : 0)
22351 << getOpenMPDirectiveName(DKind);
22360 if (DKind == OMPD_target_exit_data &&
22361 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
22362 MapType == OMPC_MAP_delete || SemaRef.
getLangOpts().OpenMP >= 52)) {
22363 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
22364 << (IsMapTypeImplicit ? 1 : 0)
22366 << getOpenMPDirectiveName(DKind);
22375 if ((DKind == OMPD_target_enter_data || DKind == OMPD_target_exit_data) &&
22377 SemaRef.
Diag(StartLoc,
22378 diag::err_omp_invalid_map_type_modifier_for_directive)
22380 OMPC_MAP_MODIFIER_ompx_hold)
22381 << getOpenMPDirectiveName(DKind);
22389 if ((DKind == OMPD_target_data ||
22391 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
22392 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
22393 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
22394 << (IsMapTypeImplicit ? 1 : 0)
22396 << getOpenMPDirectiveName(DKind);
22408 if (VD && ((SemaRef.
LangOpts.OpenMP <= 45 &&
22410 DKind == OMPD_target)) {
22411 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD,
false);
22413 SemaRef.
Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
22414 << getOpenMPClauseName(DVar.CKind)
22415 << getOpenMPClauseName(OMPC_map)
22416 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
22425 SemaRef, DSAS->
getCurScope(), MapperIdScopeSpec, MapperId,
22426 Type.getCanonicalType(), UnresolvedMapper);
22429 MVLI.UDMapperList.push_back(ER.
get());
22432 MVLI.ProcessedVarList.push_back(RE);
22436 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
22442 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22443 MVLI.VarComponents.back().append(CurComponents.begin(),
22444 CurComponents.end());
22445 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ?
nullptr
22465 BuiltinType::OMPIterator))
22467 diag::err_omp_map_modifier_not_iterator);
22470 unsigned Count = 0;
22471 for (
unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
22473 llvm::is_contained(Modifiers, MapTypeModifiers[I])) {
22474 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
22478 "Modifiers exceed the allowed number of map type modifiers");
22479 Modifiers[Count] = MapTypeModifiers[I];
22480 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
22484 MappableVarListInfo MVLI(VarList);
22486 MapperIdScopeSpec, MapperId, UnresolvedMappers,
22487 MapType, Modifiers, IsMapTypeImplicit,
22493 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
22494 MVLI.VarComponents, MVLI.UDMapperList, IteratorModifier, Modifiers,
22496 MapType, IsMapTypeImplicit, MapLoc);
22504 if (ReductionType.
isNull())
22512 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
22517 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
22521 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
22525 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
22528 return ReductionType;
22533 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
22536 Decls.reserve(ReductionTypes.size());
22544 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
22546 bool InCompoundScope =
true;
22547 if (S !=
nullptr) {
22556 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
22558 while (Filter.hasNext()) {
22559 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
22560 if (InCompoundScope) {
22561 auto I = UsedAsPrevious.find(PrevDecl);
22562 if (I == UsedAsPrevious.end())
22563 UsedAsPrevious[PrevDecl] =
false;
22565 UsedAsPrevious[D] =
true;
22567 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
22568 PrevDecl->getLocation();
22571 if (InCompoundScope) {
22572 for (
const auto &PrevData : UsedAsPrevious) {
22573 if (!PrevData.second) {
22574 PrevDRD = PrevData.first;
22579 }
else if (PrevDeclInScope !=
nullptr) {
22580 auto *PrevDRDInScope = PrevDRD =
22581 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
22583 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
22584 PrevDRDInScope->getLocation();
22585 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
22586 }
while (PrevDRDInScope !=
nullptr);
22588 for (
const auto &TyData : ReductionTypes) {
22589 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
22591 if (I != PreviousRedeclTypes.end()) {
22592 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
22594 Diag(I->second, diag::note_previous_definition);
22597 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
22599 Name, TyData.first, PrevDRD);
22601 DRD->setAccess(AS);
22602 Decls.push_back(DRD);
22604 DRD->setInvalidDecl();
22614 auto *DRD = cast<OMPDeclareReductionDecl>(D);
22629 QualType ReductionType = DRD->getType();
22646 if (S !=
nullptr) {
22650 DRD->addDecl(OmpInParm);
22651 DRD->addDecl(OmpOutParm);
22657 DRD->setCombinerData(InE, OutE);
22661 auto *DRD = cast<OMPDeclareReductionDecl>(D);
22668 if (Combiner !=
nullptr)
22669 DRD->setCombiner(Combiner);
22671 DRD->setInvalidDecl();
22675 auto *DRD = cast<OMPDeclareReductionDecl>(D);
22689 QualType ReductionType = DRD->getType();
22706 if (S !=
nullptr) {
22710 DRD->addDecl(OmpPrivParm);
22711 DRD->addDecl(OmpOrigParm);
22717 DRD->setInitializerData(OrigE, PrivE);
22718 return OmpPrivParm;
22723 auto *DRD = cast<OMPDeclareReductionDecl>(D);
22732 }
else if (OmpPrivParm->
hasInit()) {
22733 DRD->setInitializer(OmpPrivParm->
getInit(),
22738 DRD->setInvalidDecl();
22744 for (
Decl *D : DeclReductions.
get()) {
22750 D->setInvalidDecl();
22753 return DeclReductions;
22772 assert(
ParsedType.isUsable() &&
"Expect usable parsed mapper type");
22775 assert(!MapperType.
isNull() &&
"Expect valid mapper type");
22780 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
22796 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
22798 bool InCompoundScope =
true;
22799 if (S !=
nullptr) {
22808 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
22810 while (Filter.hasNext()) {
22811 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
22812 if (InCompoundScope) {
22813 auto I = UsedAsPrevious.find(PrevDecl);
22814 if (I == UsedAsPrevious.end())
22815 UsedAsPrevious[PrevDecl] =
false;
22817 UsedAsPrevious[D] =
true;
22819 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
22820 PrevDecl->getLocation();
22823 if (InCompoundScope) {
22824 for (
const auto &PrevData : UsedAsPrevious) {
22825 if (!PrevData.second) {
22826 PrevDMD = PrevData.first;
22831 }
else if (PrevDeclInScope) {
22832 auto *PrevDMDInScope = PrevDMD =
22833 cast<OMPDeclareMapperDecl>(PrevDeclInScope);
22835 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
22836 PrevDMDInScope->getLocation();
22837 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
22838 }
while (PrevDMDInScope !=
nullptr);
22842 if (I != PreviousRedeclTypes.end()) {
22843 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
22844 << MapperType << Name;
22845 Diag(I->second, diag::note_previous_definition);
22856 ClausesWithImplicit, PrevDMD);
22861 DMD->setAccess(AS);
22863 DMD->setInvalidDecl();
22865 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
22869 DMD->setMapperVarRef(MapperVarRef);
22886 DSAStack->addDeclareMapperVarRef(E);
22891 if (
DSAStack->getDeclareMapperVarRef())
22896 assert(
LangOpts.OpenMP &&
"Expected OpenMP mode.");
22898 if (
const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) {
22911 assert(
LangOpts.OpenMP &&
"Expected OpenMP mode.");
22912 return cast<DeclRefExpr>(
DSAStack->getDeclareMapperVarRef())->getDecl();
22919 Expr *ValExpr = NumTeams;
22920 Stmt *HelperValStmt =
nullptr;
22933 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22934 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
22939 StartLoc, LParenLoc, EndLoc);
22946 Expr *ValExpr = ThreadLimit;
22947 Stmt *HelperValStmt =
nullptr;
22957 DKind, OMPC_thread_limit,
LangOpts.OpenMP);
22960 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22961 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
22966 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
22974 Stmt *HelperValStmt =
nullptr;
22980 ValExpr, *
this, OMPC_priority,
22982 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
22986 StartLoc, LParenLoc, EndLoc);
22994 "Unexpected grainsize modifier in OpenMP < 51.");
22999 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
23000 << Values << getOpenMPClauseName(OMPC_grainsize);
23004 Expr *ValExpr = Grainsize;
23005 Stmt *HelperValStmt =
nullptr;
23015 &CaptureRegion, &HelperValStmt))
23020 StartLoc, LParenLoc, ModifierLoc, EndLoc);
23028 "Unexpected num_tasks modifier in OpenMP < 51.");
23033 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
23034 << Values << getOpenMPClauseName(OMPC_num_tasks);
23038 Expr *ValExpr = NumTasks;
23039 Stmt *HelperValStmt =
nullptr;
23046 ValExpr, *
this, OMPC_num_tasks,
23048 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
23053 StartLoc, LParenLoc, ModifierLoc, EndLoc);
23072 DSAStackTy *Stack) {
23073 QualType OMPEventHandleT = Stack->getOMPEventHandleT();
23074 if (!OMPEventHandleT.
isNull())
23079 S.
Diag(Loc, diag::err_omp_implied_type_not_found) <<
"omp_event_handle_t";
23082 Stack->setOMPEventHandleT(PT.
get());
23102 auto *VD = dyn_cast_or_null<VarDecl>(Ref->
getDecl());
23112 <<
"omp_event_handle_t" << 1 << VD->
getType()
23119 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(VD,
false);
23120 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
23123 << getOpenMPClauseName(DVar.CKind)
23124 << getOpenMPClauseName(OMPC_firstprivate);
23138 std::string Values;
23142 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23143 << Values << getOpenMPClauseName(OMPC_dist_schedule);
23146 Expr *ValExpr = ChunkSize;
23147 Stmt *HelperValStmt =
nullptr;
23158 ValExpr = Val.
get();
23163 if (std::optional<llvm::APSInt>
Result =
23165 if (
Result->isSigned() && !
Result->isStrictlyPositive()) {
23166 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
23171 DSAStack->getCurrentDirective(), OMPC_dist_schedule,
23172 LangOpts.OpenMP) != OMPD_unknown &&
23175 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
23176 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
23184 Kind, ValExpr, HelperValStmt);
23192 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
23193 Kind != OMPC_DEFAULTMAP_scalar) {
23197 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
23199 OMPC_DEFAULTMAP_MODIFIER_tofrom);
23203 OMPC_DEFAULTMAP_scalar);
23207 Diag(Loc, diag::err_omp_unexpected_clause_value)
23208 <<
Value << getOpenMPClauseName(OMPC_defaultmap);
23215 if (!isDefaultmapKind || !isDefaultmapModifier) {
23216 StringRef KindValue =
"'scalar', 'aggregate', 'pointer'";
23218 StringRef ModifierValue =
"'alloc', 'from', 'to', 'tofrom', "
23219 "'firstprivate', 'none', 'default'";
23220 if (!isDefaultmapKind && isDefaultmapModifier) {
23221 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23222 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23223 }
else if (isDefaultmapKind && !isDefaultmapModifier) {
23224 Diag(MLoc, diag::err_omp_unexpected_clause_value)
23225 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23227 Diag(MLoc, diag::err_omp_unexpected_clause_value)
23228 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23229 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23230 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23233 StringRef ModifierValue =
23234 "'alloc', 'from', 'to', 'tofrom', "
23235 "'firstprivate', 'none', 'default', 'present'";
23236 if (!isDefaultmapKind && isDefaultmapModifier) {
23237 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23238 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23239 }
else if (isDefaultmapKind && !isDefaultmapModifier) {
23240 Diag(MLoc, diag::err_omp_unexpected_clause_value)
23241 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23243 Diag(MLoc, diag::err_omp_unexpected_clause_value)
23244 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23245 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23246 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23255 if (
DSAStack->checkDefaultmapCategory(Kind)) {
23256 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
23262 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
23263 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
23264 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
23266 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
23279 !isa<CXXRecordDecl>(CurLexicalContext) &&
23280 !isa<ClassTemplateDecl>(CurLexicalContext) &&
23281 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
23282 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
23283 Diag(DTCI.
Loc, diag::err_omp_region_not_file_context);
23289 Diag(DTCI.
Loc, diag::warn_hip_omp_target_directives);
23291 DeclareTargetNesting.push_back(DTCI);
23297 assert(!DeclareTargetNesting.empty() &&
23298 "check isInOpenMPDeclareTargetContext() first!");
23299 return DeclareTargetNesting.pop_back_val();
23309 if (DeclareTargetNesting.empty())
23312 Diag(DTCI.
Loc, diag::warn_omp_unterminated_declare_target)
23313 << getOpenMPDirectiveName(DTCI.
Kind);
23327 VarOrFuncDeclFilterCCC CCC(*
this);
23337 Diag(
Id.getLoc(), diag::err_undeclared_var_use) <<
Id.getName();
23342 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
23343 !isa<FunctionTemplateDecl>(ND)) {
23344 Diag(
Id.getLoc(), diag::err_omp_invalid_target_decl) <<
Id.getName();
23351 OMPDeclareTargetDeclAttr::MapTypeTy MT,
23353 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
23354 isa<FunctionTemplateDecl>(ND)) &&
23355 "Expected variable, function or function template.");
23357 if (
auto *VD = dyn_cast<VarDecl>(ND)) {
23359 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
23360 !VD->isStaticDataMember()) {
23361 Diag(Loc, diag::err_omp_declare_target_has_local_vars)
23370 Diag(Loc, diag::warn_omp_declare_target_after_first_use);
23374 Diag(Loc, diag::warn_hip_omp_target_directives);
23377 const unsigned Level = -1;
23379 auto *VD = cast<ValueDecl>(ND);
23380 std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
23381 OMPDeclareTargetDeclAttr::getActiveAttr(VD);
23382 if (ActiveAttr && (*ActiveAttr)->getDevType() != DTCI.
DT &&
23383 (*ActiveAttr)->getLevel() == Level) {
23384 Diag(Loc, diag::err_omp_device_type_mismatch)
23385 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.
DT)
23386 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(
23387 (*ActiveAttr)->getDevType());
23390 if (ActiveAttr && (*ActiveAttr)->getMapType() != MT &&
23391 (*ActiveAttr)->getLevel() == Level) {
23392 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
23396 if (ActiveAttr && (*ActiveAttr)->getLevel() == Level)
23399 Expr *IndirectE =
nullptr;
23400 bool IsIndirect =
false;
23406 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
23407 Context, MT, DTCI.
DT, IndirectE, IsIndirect, Level,
23411 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
23413 if (
auto *VD = dyn_cast<VarDecl>(ND);
23415 VD->hasGlobalStorage())
23421 if (!D || !isa<VarDecl>(D))
23423 auto *VD = cast<VarDecl>(D);
23424 std::optional<OMPDeclareTargetDeclAttr::MapTypeTy>
MapTy =
23425 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
23426 if (SemaRef.
LangOpts.OpenMP >= 50 &&
23429 VD->hasGlobalStorage()) {
23430 if (!
MapTy || (*
MapTy != OMPDeclareTargetDeclAttr::MT_To &&
23431 *
MapTy != OMPDeclareTargetDeclAttr::MT_Enter)) {
23438 diag::err_omp_lambda_capture_in_declare_target_not_to);
23439 SemaRef.
Diag(SL, diag::note_var_explicitly_captured_here)
23446 SemaRef.
Diag(VD->
getLocation(), diag::warn_omp_not_in_target_context);
23447 SemaRef.
Diag(SL, diag::note_used_here) << SR;
23451 Sema &SemaRef, DSAStackTy *Stack,
23453 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
23464 if (
auto *VD = dyn_cast<VarDecl>(D)) {
23466 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
23467 !VD->isStaticDataMember())
23471 if (
DSAStack->isThreadPrivate(VD)) {
23472 Diag(SL, diag::err_omp_threadprivate_in_target);
23477 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
23478 D = FTD->getTemplatedDecl();
23479 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
23480 std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
23481 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
23482 if (IdLoc.
isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
23483 Diag(IdLoc, diag::err_omp_function_in_link_clause);
23488 if (
auto *VD = dyn_cast<ValueDecl>(D)) {
23496 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
23497 isa<FunctionTemplateDecl>(D)) {
23498 std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
23499 OMPDeclareTargetDeclAttr::getActiveAttr(VD);
23500 unsigned Level = DeclareTargetNesting.size();
23501 if (ActiveAttr && (*ActiveAttr)->getLevel() >= Level)
23504 Expr *IndirectE =
nullptr;
23505 bool IsIndirect =
false;
23511 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
23513 getLangOpts().OpenMP >= 52 ? OMPDeclareTargetDeclAttr::MT_Enter
23514 : OMPDeclareTargetDeclAttr::MT_To,
23515 DTCI.
DT, IndirectE, IsIndirect, Level,
23519 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
23540 if (
auto *VD = dyn_cast<VarDecl>(
Node->getDecl())) {
23542 DeclVector.push_back(VD);
23547 for (
auto *Child : Ex->
children()) {
23556 A = TD->
getAttr<OMPDeclareTargetDeclAttr>();
23557 DeclVector.push_back(cast<VarDecl>(TD));
23558 while (!DeclVector.empty()) {
23559 VarDecl *TargetVarDecl = DeclVector.pop_back_val();
23560 if (TargetVarDecl->
hasAttr<OMPDeclareTargetDeclAttr>() &&
23574 if (isa<VarDecl>(TargetDecl))
23589 unsigned Count = 0;
23590 for (
unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
23592 llvm::is_contained(Modifiers, MotionModifiers[I])) {
23593 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
23597 "Modifiers exceed the allowed number of motion modifiers");
23598 Modifiers[Count] = MotionModifiers[I];
23599 ModifiersLoc[Count] = MotionModifiersLoc[I];
23603 MappableVarListInfo MVLI(VarList);
23605 MapperIdScopeSpec, MapperId, UnresolvedMappers);
23606 if (MVLI.ProcessedVarList.empty())
23610 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
23611 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
23626 unsigned Count = 0;
23627 for (
unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
23629 llvm::is_contained(Modifiers, MotionModifiers[I])) {
23630 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
23634 "Modifiers exceed the allowed number of motion modifiers");
23635 Modifiers[Count] = MotionModifiers[I];
23636 ModifiersLoc[Count] = MotionModifiersLoc[I];
23640 MappableVarListInfo MVLI(VarList);
23642 MapperIdScopeSpec, MapperId, UnresolvedMappers);
23643 if (MVLI.ProcessedVarList.empty())
23647 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
23648 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
23654 MappableVarListInfo MVLI(VarList);
23658 for (
Expr *RefExpr : VarList) {
23659 assert(RefExpr &&
"NULL expr in OpenMP use_device_ptr clause.");
23662 Expr *SimpleRefExpr = RefExpr;
23666 MVLI.ProcessedVarList.push_back(RefExpr);
23667 PrivateCopies.push_back(
nullptr);
23668 Inits.push_back(
nullptr);
23675 Type =
Type.getNonReferenceType().getUnqualifiedType();
23677 auto *VD = dyn_cast<VarDecl>(D);
23681 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
23682 << 0 << RefExpr->getSourceRange();
23690 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
23691 if (VDPrivate->isInvalidDecl())
23696 *
this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
23702 *
this, VDInit, RefExpr->
getType(), RefExpr->getExprLoc());
23712 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
23713 PrivateCopies.push_back(VDPrivateRefExpr);
23714 Inits.push_back(VDInitRefExpr);
23719 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
23723 MVLI.VarBaseDeclarations.push_back(D);
23724 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23725 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
23729 if (MVLI.ProcessedVarList.empty())
23733 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
23734 MVLI.VarBaseDeclarations, MVLI.VarComponents);
23739 MappableVarListInfo MVLI(VarList);
23741 for (
Expr *RefExpr : VarList) {
23742 assert(RefExpr &&
"NULL expr in OpenMP use_device_addr clause.");
23745 Expr *SimpleRefExpr = RefExpr;
23750 MVLI.ProcessedVarList.push_back(RefExpr);
23755 auto *VD = dyn_cast<VarDecl>(D);
23762 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
23767 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
23771 MVLI.VarBaseDeclarations.push_back(D);
23772 MVLI.VarComponents.emplace_back();
23773 Expr *Component = SimpleRefExpr;
23774 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
23775 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
23777 MVLI.VarComponents.back().emplace_back(Component, D,
23781 if (MVLI.ProcessedVarList.empty())
23785 MVLI.VarBaseDeclarations,
23786 MVLI.VarComponents);
23791 MappableVarListInfo MVLI(VarList);
23792 for (
Expr *RefExpr : VarList) {
23793 assert(RefExpr &&
"NULL expr in OpenMP is_device_ptr clause.");
23796 Expr *SimpleRefExpr = RefExpr;
23800 MVLI.ProcessedVarList.push_back(RefExpr);
23810 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
23811 << 0 << RefExpr->getSourceRange();
23817 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
23819 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
23820 << getOpenMPClauseName(DVar.CKind)
23821 << getOpenMPClauseName(OMPC_is_device_ptr)
23822 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
23827 const Expr *ConflictExpr;
23828 if (
DSAStack->checkMappableExprComponentListsForDecl(
23833 ConflictExpr = R.front().getAssociatedExpression();
23836 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
23845 SimpleRefExpr, D,
false);
23846 DSAStack->addMappableExpressionComponents(
23847 D, MC, OMPC_is_device_ptr);
23850 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
23855 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
23856 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
23857 "Unexpected device pointer expression!");
23858 MVLI.VarBaseDeclarations.push_back(
23859 isa<DeclRefExpr>(SimpleRefExpr) ? D :
nullptr);
23860 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23861 MVLI.VarComponents.back().push_back(MC);
23864 if (MVLI.ProcessedVarList.empty())
23868 MVLI.VarBaseDeclarations,
23869 MVLI.VarComponents);
23874 MappableVarListInfo MVLI(VarList);
23875 for (
Expr *RefExpr : VarList) {
23876 assert(RefExpr &&
"NULL expr in OpenMP has_device_addr clause.");
23879 Expr *SimpleRefExpr = RefExpr;
23884 MVLI.ProcessedVarList.push_back(RefExpr);
23892 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
23894 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
23895 << getOpenMPClauseName(DVar.CKind)
23896 << getOpenMPClauseName(OMPC_has_device_addr)
23897 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
23902 const Expr *ConflictExpr;
23903 if (
DSAStack->checkMappableExprComponentListsForDecl(
23908 ConflictExpr = R.front().getAssociatedExpression();
23911 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
23919 Expr *Component = SimpleRefExpr;
23920 auto *VD = dyn_cast<VarDecl>(D);
23921 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
23922 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
23925 Component, D,
false);
23926 DSAStack->addMappableExpressionComponents(
23927 D, MC, OMPC_has_device_addr);
23933 assert(Ref &&
"has_device_addr capture failed");
23934 MVLI.ProcessedVarList.push_back(Ref);
23936 MVLI.ProcessedVarList.push_back(RefExpr->IgnoreParens());
23941 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
23942 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
23943 "Unexpected device pointer expression!");
23944 MVLI.VarBaseDeclarations.push_back(
23945 isa<DeclRefExpr>(SimpleRefExpr) ? D :
nullptr);
23946 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23947 MVLI.VarComponents.back().push_back(MC);
23950 if (MVLI.ProcessedVarList.empty())
23954 MVLI.VarBaseDeclarations,
23955 MVLI.VarComponents);
23971 DSAStack->getOMPAllocatorHandleT(),
23976 Allocator = AllocatorRes.
get();
23983 if (
LangOpts.OpenMPIsTargetDevice &&
23985 targetDiag(StartLoc, diag::err_expected_allocator_expression);
23989 for (
Expr *RefExpr : VarList) {
23990 assert(RefExpr &&
"NULL expr in OpenMP private clause.");
23993 Expr *SimpleRefExpr = RefExpr;
23997 Vars.push_back(RefExpr);
24003 auto *VD = dyn_cast<VarDecl>(D);
24008 ? RefExpr->IgnoreParens()
24016 DSAStack->addInnerAllocatorExpr(Allocator);
24018 ColonLoc, EndLoc, Vars);
24026 for (
Expr *RefExpr : VarList) {
24027 assert(RefExpr &&
"NULL expr in OpenMP nontemporal clause.");
24030 Expr *SimpleRefExpr = RefExpr;
24034 Vars.push_back(RefExpr);
24041 if (
const Expr *PrevRef =
24042 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
24043 Diag(ELoc, diag::err_omp_used_in_clause_twice)
24044 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
24045 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
24046 << getOpenMPClauseName(OMPC_nontemporal);
24050 Vars.push_back(RefExpr);
24076 for (
Expr *RefExpr : VarList) {
24077 assert(RefExpr &&
"NULL expr in OpenMP nontemporal clause.");
24080 Expr *SimpleRefExpr = RefExpr;
24085 Vars.push_back(RefExpr);
24090 const DSAStackTy::DSAVarData DVar =
24096 if (DVar.CKind != OMPC_reduction || DVar.Modifier != OMPC_REDUCTION_inscan)
24097 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
24098 << RefExpr->getSourceRange();
24100 if (
DSAStack->getParentDirective() != OMPD_unknown)
24101 DSAStack->markDeclAsUsedInScanDirective(D);
24102 Vars.push_back(RefExpr);
24116 for (
Expr *RefExpr : VarList) {
24117 assert(RefExpr &&
"NULL expr in OpenMP nontemporal clause.");
24120 Expr *SimpleRefExpr = RefExpr;
24125 Vars.push_back(RefExpr);
24131 DSAStackTy::DSAVarData DVar;
24132 if (ParentDirective != OMPD_unknown)
24133 DVar =
DSAStack->getTopDSA(D,
true);
24138 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
24139 DVar.Modifier != OMPC_REDUCTION_inscan) {
24140 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
24141 << RefExpr->getSourceRange();
24143 DSAStack->markDeclAsUsedInScanDirective(D);
24145 Vars.push_back(RefExpr);
24156 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
24157 if (!OMPAlloctraitT.
isNull())
24162 S.
Diag(Loc, diag::err_omp_implied_type_not_found) <<
"omp_alloctrait_t";
24165 Stack->setOMPAlloctraitT(PT.
get());
24184 for (
int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
24185 auto AllocatorKind =
static_cast<OMPAllocateDeclAttr::AllocatorTypeTy
>(I);
24186 StringRef Allocator =
24187 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
24195 Expr *AllocatorExpr =
nullptr;
24203 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
24204 bool IsPredefinedAllocator =
false;
24206 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorTy =
24208 IsPredefinedAllocator =
24210 OMPAllocateDeclAttr::AllocatorTypeTy::OMPUserDefinedMemAlloc;
24214 bool IsTypeCompatible = IsPredefinedAllocator;
24215 IsTypeCompatible = IsTypeCompatible ||
24217 OMPAllocatorHandleT);
24219 IsTypeCompatible ||
24221 bool IsNonConstantLValue =
24223 if (!DRE || !IsTypeCompatible ||
24224 (!IsPredefinedAllocator && !IsNonConstantLValue)) {
24226 <<
"omp_allocator_handle_t" << (DRE ? 1 : 0)
24235 diag::err_omp_predefined_allocator_with_traits)
24238 << cast<NamedDecl>(DRE->
getDecl())->getName()
24247 diag::err_omp_nonpredefined_allocator_without_traits);
24255 IsPredefinedAllocator
24256 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
24257 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
24259 Expr *AllocatorTraitsExpr =
nullptr;
24273 if (
const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
24274 TraitTy = ConstArrayTy->getElementType();
24281 diag::err_omp_expected_array_alloctraits)
24282 << AllocatorTraitsExpr->
getType();
24287 if (
auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
24290 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
24307 for (
Expr *RefExpr : Locators) {
24308 assert(RefExpr &&
"NULL expr in OpenMP shared clause.");
24309 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
24311 Vars.push_back(RefExpr);
24319 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
24320 << 1 << 0 << RefExpr->getSourceRange();
24329 if (!Res.
isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
24330 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
24331 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
24332 << 1 << 0 << RefExpr->getSourceRange();
24335 Vars.push_back(SimpleExpr);
24339 EndLoc, Modifier, Vars);
24348 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
24351 << getOpenMPClauseName(OMPC_bind);
24363 Expr *ValExpr = Size;
24364 Stmt *HelperValStmt =
nullptr;
24375 DKind, OMPC_ompx_dyn_cgroup_mem,
LangOpts.OpenMP);
24378 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
24379 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
24384 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
24392 if (
DSAStack->getCurrentDirective() == OMPD_ordered &&
24393 DepType != OMPC_DOACROSS_source && DepType != OMPC_DOACROSS_sink &&
24394 DepType != OMPC_DOACROSS_sink_omp_cur_iteration &&
24395 DepType != OMPC_DOACROSS_source_omp_cur_iteration &&
24396 DepType != OMPC_DOACROSS_source) {
24397 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
24398 <<
"'source' or 'sink'" << getOpenMPClauseName(OMPC_doacross);
24404 llvm::APSInt TotalDepCount(32);
24407 DepType == OMPC_DOACROSS_source ||
24408 DepType == OMPC_DOACROSS_source_omp_cur_iteration ||
24409 DepType == OMPC_DOACROSS_sink_omp_cur_iteration,
24411 Vars = VarOffset.Vars;
24412 OpsOffs = VarOffset.OpsOffs;
24413 TotalDepCount = VarOffset.TotalDepCount;
24415 DepType, DepLoc, ColonLoc, Vars,
24416 TotalDepCount.getZExtValue());
24417 if (
DSAStack->isParentOrderedRegion())
24418 DSAStack->addDoacrossDependClause(
C, OpsOffs);
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines OpenMP nodes for declarative directives.
llvm::DenseSet< const void * > Visited
static const Decl * getCanonicalDecl(const Decl *D)
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
This file defines OpenMP AST classes for clauses.
Defines some OpenMP-specific enums and functions.
llvm::DenseMap< Stmt *, Stmt * > MapTy
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
static VarDecl * buildVarDecl(Sema &S, SourceLocation Loc, QualType Type, IdentifierInfo *II)
Build a variable declaration for move parameter.
static NamedDecl * findAcceptableDecl(Sema &SemaRef, NamedDecl *D, unsigned IDNS)
Retrieve the visible declaration corresponding to D, if any.
static Expr * getOrderedNumberExpr(ArrayRef< OMPClause * > Clauses)
static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, bool Diagnose=true)
Tries to find omp_depend_t. type.
static Stmt * buildPreInits(ASTContext &Context, MutableArrayRef< Decl * > PreInits)
Build preinits statement for the given declarations.
static void argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, SourceLocation Loc, QualType Ty, SmallVectorImpl< UnresolvedSet< 8 > > &Lookups)
static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, Sema &SemaRef, Decl *D)
static bool checkGenericLoopLastprivate(Sema &S, ArrayRef< OMPClause * > Clauses, OpenMPDirectiveKind K, DSAStackTy *Stack)
static bool checkSimdlenSafelenSpecified(Sema &S, const ArrayRef< OMPClause * > Clauses)
static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, QualType NewType)
static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, ArrayRef< OMPClause * > Clauses, ArrayRef< OpenMPDirectiveKind > AllowedNameModifiers)
static void handleDeclareVariantConstructTrait(DSAStackTy *Stack, OpenMPDirectiveKind DKind, bool ScopeEntry)
static VarDecl * precomputeExpr(Sema &Actions, SmallVectorImpl< Stmt * > &BodyStmts, Expr *E, StringRef Name)
static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, CXXScopeSpec &MapperIdScopeSpec, const DeclarationNameInfo &MapperId, QualType Type, Expr *UnresolvedMapper)
static bool checkReductionClauseWithNogroup(Sema &S, ArrayRef< OMPClause * > Clauses)
static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, SourceLocation M1Loc, SourceLocation M2Loc)
static OMPAllocateDeclAttr::AllocatorTypeTy getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator)
static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, bool StrictlyPositive, bool BuildCapture=false, OpenMPDirectiveKind DKind=OMPD_unknown, OpenMPDirectiveKind *CaptureRegion=nullptr, Stmt **HelperValStmt=nullptr)
static Expr * buildPostUpdate(Sema &S, ArrayRef< Expr * > PostUpdates)
Build postupdate expression for the given list of postupdates expressions.
static CapturedStmt * buildLoopVarFunc(Sema &Actions, QualType LoopVarTy, QualType LogicalTy, DeclRefExpr *StartExpr, Expr *Step, bool Deref)
Create a closure that computes the loop variable from the logical iteration number.
static ExprResult buildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, bool IsNonRectangularLB, llvm::MapVector< const Expr *, DeclRefExpr * > *Captures=nullptr)
Build 'VarRef = Start + Iter * Step'.
static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, OpenMPDirectiveKind NameModifier=OMPD_unknown)
static Expr * getCollapseNumberExpr(ArrayRef< OMPClause * > Clauses)
static Expr * getDirectCallExpr(Expr *E)
static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
static OMPCapturedExprDecl * buildCaptureDecl(Sema &S, IdentifierInfo *Id, Expr *CaptureExpr, bool WithInit, DeclContext *CurContext, bool AsExpression)
static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, DSAStackTy *Stack)
Tries to find omp_allocator_handle_t type.
static bool isClauseMappable(ArrayRef< OMPClause * > Clauses)
Check if the variables in the mapping clause are externally visible.
static BinaryOperatorKind getRelatedCompoundReductionOp(BinaryOperatorKind BOK)
static bool checkMutuallyExclusiveClauses(Sema &S, ArrayRef< OMPClause * > Clauses, ArrayRef< OpenMPClauseKind > MutuallyExclusiveClauses)
Find and diagnose mutually exclusive clause kinds.
static bool checkOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, llvm::MutableArrayRef< LoopIterationSpace > ResultIterSpaces, llvm::MapVector< const Expr *, DeclRefExpr * > &Captures)
Called on a for stmt to check and extract its iteration space for further processing (such as collaps...
static bool checkOrderedOrderSpecified(Sema &S, const ArrayRef< OMPClause * > Clauses)
static OpenMPMapClauseKind getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, bool IsAggregateOrDeclareTarget)
static const Expr * getExprAsWritten(const Expr *E)
static bool checkMapConflicts(Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, bool CurrentRegionOnly, OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, OpenMPClauseKind CKind)
static bool isOpenMPDeviceDelayedContext(Sema &S)
static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef)
Convert integer expression E to make it have at least Bits bits.
static std::pair< ValueDecl *, bool > getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, SourceRange &ERange, bool AllowArraySection=false, StringRef DiagType="")
static void applyOMPAllocateAttribute(Sema &S, VarDecl *VD, OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator, Expr *Alignment, SourceRange SR)
static bool checkOMPArraySectionConstantForReduction(ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, SmallVectorImpl< llvm::APSInt > &ArraySizes)
static CapturedStmt * buildDistanceFunc(Sema &Actions, QualType LogicalTy, BinaryOperator::Opcode Rel, Expr *StartExpr, Expr *StopExpr, Expr *StepExpr)
Create a closure that computes the number of iterations of a loop.
static bool checkPreviousOMPAllocateAttribute(Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator)
static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, Expr *NumIterations, Sema &SemaRef, Scope *S, DSAStackTy *Stack)
static std::string getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, ArrayRef< unsigned > Exclude=std::nullopt)
static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, QualType Type, OpenMPClauseKind CKind, SourceLocation ELoc, bool AcceptIfMutable=true, bool ListItemNotVar=false)
static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr, SourceLocation VarLoc, OpenMPClauseKind Kind)
static const ValueDecl * getCanonicalDecl(const ValueDecl *D)
static const Expr * checkMapClauseExpressionBase(Sema &SemaRef, Expr *E, OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose)
Return the expression of the base of the mappable expression or null if it cannot be determined and d...
static bool hasClauses(ArrayRef< OMPClause * > Clauses, const OpenMPClauseKind K)
Check for existence of a map clause in the list of clauses.
static void processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack, SmallVectorImpl< OMPClause * > &Clauses)
Perform DFS through the structure/class data members trying to find member(s) with user-defined 'defa...
static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, OpenMPDirectiveKind CancelRegion, SourceLocation StartLoc)
static DeclRefExpr * buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, SourceLocation Loc, bool RefersToCapture=false)
static ExprResult buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, bool IsNonRectangularLB, llvm::MapVector< const Expr *, DeclRefExpr * > &Captures)
Build 'VarRef = Start.
static DoacrossDataInfoTy ProcessOpenMPDoacrossClauseCommon(Sema &SemaRef, bool IsSource, ArrayRef< Expr * > VarList, DSAStackTy *Stack, SourceLocation EndLoc)
static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, ValueDecl *VD)
static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, DSAStackTy *Stack)
Tries to find omp_event_handle_t type.
static ExprResult buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, Scope *S, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, QualType Ty, CXXCastPath &BasePath, Expr *UnresolvedReduction)
static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef)
Check if the given expression E is a constant integer that fits into Bits bits.
static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, ArrayRef< OMPClause * > Clauses)
static bool actOnOMPReductionKindClause(Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions, ReductionData &RD)
static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, const ValueDecl *D, const DSAStackTy::DSAVarData &DVar, bool IsLoopIterVar=false)
static VarDecl * buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, StringRef Name, const AttrVec *Attrs=nullptr, DeclRefExpr *OrigRef=nullptr)
Build a variable declaration for OpenMP loop iteration variable.
static DeclRefExpr * buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, bool WithInit)
static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack)
Tries to find omp_alloctrait_t type.
static void checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, MappableVarListInfo &MVLI, SourceLocation StartLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, ArrayRef< Expr * > UnresolvedMappers, OpenMPMapClauseKind MapType=OMPC_MAP_unknown, ArrayRef< OpenMPMapModifierKind > Modifiers=std::nullopt, bool IsMapTypeImplicit=false, bool NoDiagnose=false)
static bool isConstNotMutableType(Sema &SemaRef, QualType Type, bool AcceptIfMutable=true, bool *IsClassType=nullptr)
static void checkReductionClauses(Sema &S, DSAStackTy *Stack, ArrayRef< OMPClause * > Clauses)
Check consistency of the reduction clauses.
static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, QualType QTy, bool FullCheck=true)
static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, OpenMPDirectiveKind CurrentRegion, const DeclarationNameInfo &CurrentName, OpenMPDirectiveKind CancelRegion, OpenMPBindClauseKind BindKind, SourceLocation StartLoc)
static unsigned checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA, Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, OMPLoopBasedDirective::HelperExprs &Built)
Called on a for stmt to check itself and nested loops (if any).
static OpenMPDefaultmapClauseKind getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD)
static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
Return true if it can be proven that the provided array expression (array section or array subscript)...
static T filterLookupForUDReductionAndMapper(SmallVectorImpl< U > &Lookups, const llvm::function_ref< T(ValueDecl *)> Gen)
static CharSourceRange getRange(const CharSourceRange &EditRange, const SourceManager &SM, const LangOptions &LangOpts, bool IncludeMacroExpansion)
This file defines OpenMP AST classes for executable directives and clauses.
Allows QualTypes to be sorted and hence used in maps and sets.
This class visits every VarDecl that the initializer references and adds OMPDeclareTargetDeclAttr to ...
void declareTargetInitializer(Decl *TD)
A function that keeps a record of all the Decls that are variables, has OMPDeclareTargetDeclAttr,...
void VisitDeclRefExpr(DeclRefExpr *Node)
A StmtVisitor class function that visits all DeclRefExpr and adds OMPDeclareTargetDeclAttr to them.
void VisitExpr(Expr *Ex)
A function that iterates across each of the Expr's children.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
QualType getMemberPointerType(QualType T, const Type *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false, bool Unqualified=false, bool AllowCXX=false, bool IsConditionalOperator=false)
DeclarationNameTable DeclarationNames
QualType getUnsignedPointerDiffType() const
Return the unique unsigned counterpart of "ptrdiff_t" integer type.
QualType getVariableArrayType(QualType EltTy, Expr *NumElts, ArraySizeModifier ASM, unsigned IndexTypeQuals, SourceRange Brackets) const
Return a non-unique reference to the type for a variable array of the specified element type.
ASTMutationListener * getASTMutationListener() const
Retrieve a pointer to the AST mutation listener associated with this AST context, if any.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
bool DeclMustBeEmitted(const Decl *D)
Determines if the decl can be CodeGen'ed or deserialized from PCH lazily, only when used; this is onl...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
void Deallocate(void *Ptr) const
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
QualType getUIntPtrType() const
Return a type compatible with "uintptr_t" (C99 7.18.1.4), as defined by the target.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth,...
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
CanQualType BoundMemberTy
CharUnits getAlignOfGlobalVarInChars(QualType T, const VarDecl *VD) const
Return the alignment in characters that should be given to a global variable with type T.
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
const TargetInfo & getTargetInfo() const
bool typesAreCompatible(QualType T1, QualType T2, bool CompareUnqualified=false)
Compatibility predicates used to check assignment expressions.
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
Attr - This represents one attribute.
Represents an attribute applied to a statement.
static AttributedStmt * Create(const ASTContext &C, SourceLocation Loc, ArrayRef< const Attr * > Attrs, Stmt *SubStmt)
A builtin binary operation expression such as "x + y" or "x <= y".
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)
Retrieve the overloaded operator kind that corresponds to the given binary opcode.
static Opcode getOpForCompoundAssignment(Opcode Opc)
bool isRelationalOp() const
SourceLocation getOperatorLoc() const
SourceLocation getExprLoc() const
static Opcode reverseComparisonOp(Opcode Opc)
static Opcode getOverloadedOpcode(OverloadedOperatorKind OO)
Retrieve the binary opcode that corresponds to the given overloaded operator.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
Represents a C++ constructor within a class.
Represents a C++ conversion function within a class.
A call to an overloaded operator written using operator syntax.
Represents a C++ struct/union/class.
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
bool hasDefinition() const
Represents a C++ nested-name-specifier or a global scope specifier.
bool isValid() const
A scope specifier is present, and it refers to a real scope.
SourceLocation getBeginLoc() const
bool isSet() const
Deprecated.
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
Represents the this expression in C++.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
static CallExpr * Create(const ASTContext &Ctx, Expr *Fn, ArrayRef< Expr * > Args, QualType Ty, ExprValueKind VK, SourceLocation RParenLoc, FPOptionsOverride FPFeatures, unsigned MinNumArgs=0, ADLCallKind UsesADL=NotADL)
Create a call expression.
SourceLocation getBeginLoc() const LLVM_READONLY
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
QualType withConst() const
Retrieves a version of this type with const applied.
A wrapper class around a pointer that always points to its canonical declaration.
Represents the body of a CapturedStmt, and serves as its DeclContext.
unsigned getNumParams() const
void setNothrow(bool Nothrow=true)
ImplicitParamDecl * getParam(unsigned i) const
Describes the capture of either a variable, or 'this', or variable-length array type.
This captures a statement into a function.
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
SourceRange getSourceRange() const LLVM_READONLY
Stmt * getCapturedStmt()
Retrieve the statement being captured.
bool capturesVariable(const VarDecl *Var) const
True if this variable has been captured.
SourceLocation getBeginLoc() const LLVM_READONLY
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Declaration of a class template.
Complex values, per C99 6.2.5p11.
CompoundStmt - This represents a group of statements like { stmt stmt }.
static CompoundStmt * Create(const ASTContext &C, ArrayRef< Stmt * > Stmts, FPOptionsOverride FPFeatures, SourceLocation LB, SourceLocation RB)
ConditionalOperator - The ?: ternary operator.
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
The results of name lookup within a DeclContext.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC.
bool isFileContext() const
bool isExternCXXContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
DeclContext * getLexicalParent()
getLexicalParent - Returns the containing lexical DeclContext.
bool isTranslationUnit() const
void addDecl(Decl *D)
Add the declaration D into this context.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
bool isExternCContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
bool Encloses(const DeclContext *DC) const
Determine whether this declaration context encloses the declaration context DC.
void addHiddenDecl(Decl *D)
Add the declaration D to this context without modifying any lookup tables.
static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls)
A reference to a declared variable, function, enum, etc.
SourceLocation getBeginLoc() const LLVM_READONLY
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
SourceLocation getEndLoc() const LLVM_READONLY
ConstexprSpecKind getConstexprSpecifier() const
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
const Decl * getSingleDecl() const
Decl - This represents one declaration (or definition), e.g.
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
void markUsed(ASTContext &C)
Mark the declaration used, in the sense of odr-use.
bool isReferenced() const
Whether any declaration of this entity was referenced.
bool isCanonicalDecl() const
Whether this particular Decl is a canonical one.
bool isInvalidDecl() const
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
void setAccess(AccessSpecifier AS)
SourceLocation getLocation() const
void setImplicit(bool I=true)
void setReferenced(bool R=true)
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
void setDeclContext(DeclContext *DC)
setDeclContext - Set both the semantic and lexical DeclContext to DC.
void setLexicalDeclContext(DeclContext *DC)
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
The name of a declaration.
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
bool isEmpty() const
Evaluates true when this declaration name is empty.
Information about one declarator, including the parsed type information and the identifier.
void SetIdentifier(IdentifierInfo *Id, SourceLocation IdLoc)
Set the name of this declarator to be the given identifier.
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
SourceLocation getIdentifierLoc() const
SourceLocation getBeginLoc() const LLVM_READONLY
void setFunctionDefinitionKind(FunctionDefinitionKind Val)
const CXXScopeSpec & getCXXScopeSpec() const
getCXXScopeSpec - Return the C++ scope specifier (global scope or nested-name-specifier) that is part...
IdentifierInfo * getIdentifier() const
bool isInvalidType() const
RAII object that enters a new expression evaluation context.
The return type of classify().
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates).
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParenLValueCasts() LLVM_READONLY
Skip past any parentheses and lvalue casts which might surround this expression until reaching a fixe...
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
bool isIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
Represents difference between two FPOptions values.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
static FloatingLiteral * Create(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L)
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
ArrayRef< ParmVarDecl * > parameters() const
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Represents a prototype with parameter type info, e.g.
One of these records is kept for each identifier that is lexed.
void setMangledOpenMPVariantName(bool I)
Set whether this is the mangled name of an OpenMP variant.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
IfStmt - This represents an if/then/else.
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
ImplicitConversionSequence - Represents an implicit conversion sequence, which may be a standard conv...
Describes the kind of initialization being performed, along with location information for tokens rela...
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
Describes the sequence of initializations required to initialize a given object or reference with a s...
ExprResult Perform(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, QualType *ResultType=nullptr)
Perform the actual initialization of the given entity based on the computed initialization sequence.
Describes an entity that is being initialized.
static InitializedEntity InitializeVariable(VarDecl *Var)
Create the initialization entity for a variable.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
Describes the capture of a variable or of this, or of a C++1y init-capture.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
A class for iterating through a result set and possibly filtering out results.
Represents the results of name lookup.
LLVM_ATTRIBUTE_REINITIALIZES void clear()
Clears out any current state.
DeclClass * getAsSingle() const
bool empty() const
Return true if no decls were found.
Filter makeFilter()
Create a filter for this result set.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
static bool isVisible(Sema &SemaRef, NamedDecl *D)
Determine whether the given declaration is visible to the program.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
static MemberExpr * CreateImplicit(const ASTContext &C, Expr *Base, bool IsArrow, ValueDecl *MemberDecl, QualType T, ExprValueKind VK, ExprObjectKind OK)
Create an implicit MemberExpr, with no location, qualifier, template arguments, and so on.
SourceLocation getExprLoc() const LLVM_READONLY
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const
Appends a human-readable name for this declaration into the given stream.
A C++ nested-name-specifier augmented with source location information.
This represents 'acq_rel' clause in the '#pragma omp atomic|flush' directives.
This represents 'acquire' clause in the '#pragma omp atomic|flush' directives.
static OMPAffinityClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, Expr *Modifier, ArrayRef< Expr * > Locators)
Creates clause with a modifier a list of locator items.
static OMPAlignClause * Create(const ASTContext &C, Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build 'align' clause with the given alignment.
static OMPAlignedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, Expr *A)
Creates clause with a list of variables VL and alignment A.
static OMPAllocateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, Expr *Allocator, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
static bool classof(const OMPClause *T)
static OMPAllocateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< Expr * > VL, ArrayRef< OMPClause * > CL)
This represents 'allocator' clause in the '#pragma omp ...' directive.
OpenMP 5.0 [2.1.5, Array Sections].
Expr * getLength()
Get length of array section.
SourceLocation getColonLocFirst() const
Expr * getBase()
An array section can be written only as Base[LowerBound:Length].
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
Expr * getLowerBound()
Get lower bound of array section.
An explicit cast in C or a C-style cast in C++, which uses the syntax ([s1][s2]......
Expr * getBase()
Fetches base expression of array shaping expression.
This represents 'at' clause in the '#pragma omp error' directive.
SourceLocation getAtKindKwLoc() const
Returns location of clause kind.
OpenMPAtClauseKind getAtKind() const
Returns kind of the clause.
This represents 'atomic_default_mem_order' clause in the '#pragma omp requires' directive.
static OMPAtomicDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expressions Exprs)
Creates directive with a list of Clauses and 'x', 'v' and 'expr' parts of the atomic construct (see S...
static OMPBarrierDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
This represents 'bind' clause in the '#pragma omp ...' directives.
static OMPBindClause * Create(const ASTContext &C, OpenMPBindClauseKind K, SourceLocation KLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build 'bind' clause with kind K ('teams', 'parallel', or 'thread').
static OMPCancelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, OpenMPDirectiveKind CancelRegion)
Creates directive.
static OMPCancellationPointDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Creates directive.
static OMPCanonicalLoop * create(const ASTContext &Ctx, Stmt *LoopStmt, CapturedStmt *DistanceFunc, CapturedStmt *LoopVarFunc, DeclRefExpr *LoopVarRef)
Create a new OMPCanonicalLoop.
This represents 'capture' clause in the '#pragma omp atomic' directive.
Pseudo declaration for capturing expressions.
static OMPCapturedExprDecl * Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, QualType T, SourceLocation StartLoc)
Class that represents a component of a mappable expression.
ValueDecl * getAssociatedDeclaration() const
static OMPClauseWithPostUpdate * get(OMPClause *C)
Class that handles pre-initialization statement for some clauses, like 'shedule', 'firstprivate' etc.
static OMPClauseWithPreInit * get(OMPClause *C)
This is a basic class for representing single OpenMP clause.
SourceLocation getBeginLoc() const
Returns the starting location of the clause.
SourceLocation getEndLoc() const
Returns the ending location of the clause.
OpenMPClauseKind getClauseKind() const
Returns kind of OpenMP clause (private, shared, reduction, etc.).
This represents 'collapse' clause in the '#pragma omp ...' directive.
This represents 'compare' clause in the '#pragma omp atomic' directive.
static OMPCopyinClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps)
Creates clause with a list of variables VL.
static OMPCopyprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps)
Creates clause with a list of variables VL.
This represents '#pragma omp critical' directive.
static OMPCriticalDirective * Create(const ASTContext &C, const DeclarationNameInfo &Name, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive.
DeclarationNameInfo getDirectiveName() const
Return name of the directive.
This represents '#pragma omp declare mapper ...' directive.
static OMPDeclareMapperDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, QualType T, DeclarationName VarName, ArrayRef< OMPClause * > Clauses, OMPDeclareMapperDecl *PrevDeclInScope)
Creates declare mapper node.
This represents '#pragma omp declare reduction ...' directive.
static OMPDeclareReductionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, QualType T, OMPDeclareReductionDecl *PrevDeclInScope)
Create declare reduction node.
This represents 'default' clause in the '#pragma omp ...' directive.
This represents 'defaultmap' clause in the '#pragma omp ...' directive.
This represents implicit clause 'depend' for the '#pragma omp task' directive.
static OMPDependClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, DependDataTy Data, Expr *DepModifier, ArrayRef< Expr * > VL, unsigned NumLoops)
Creates clause with a list of variables VL.
static OMPDepobjClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, Expr *Depobj)
Creates clause.
static OMPDepobjDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive with a list of Clauses.
This represents 'destroy' clause in the '#pragma omp depobj' directive or the '#pragma omp interop' d...
This represents 'detach' clause in the '#pragma omp task' directive.
This represents 'device' clause in the '#pragma omp ...' directive.
static OMPDispatchDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, SourceLocation TargetCallLoc)
Creates directive with a list of Clauses.
This represents 'dist_schedule' clause in the '#pragma omp ...' directive.
static OMPDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, OpenMPDirectiveKind ParamPrevMappedDirective)
Creates directive with a list of Clauses.
static OMPDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
static OMPDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
This represents the 'doacross' clause for the '#pragma omp ordered' directive.
static OMPDoacrossClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, OpenMPDoacrossClauseModifier DepType, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VL, unsigned NumLoops)
Creates clause with a list of expressions VL.
This represents 'dynamic_allocators' clause in the '#pragma omp requires' directive.
static OMPErrorDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
static OMPExclusiveClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
This is a basic class for representing single OpenMP executable directive.
OpenMPDirectiveKind getDirectiveKind() const
This represents 'fail' clause in the '#pragma omp atomic' directive.
This represents 'filter' clause in the '#pragma omp ...' directive.
This represents 'final' clause in the '#pragma omp ...' directive.
static OMPFirstprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PrivateVL, ArrayRef< Expr * > InitVL, Stmt *PreInit)
Creates clause with a list of variables VL.
This represents implicit clause 'flush' for the '#pragma omp flush' directive.
static OMPFlushClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
static OMPFlushDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive with a list of Clauses.
static OMPForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, bool HasCancel, OpenMPDirectiveKind ParamPrevMappedDirective)
Creates directive with a list of Clauses.
static OMPForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPFromClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr * > UDMapperRefs, ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId)
Creates clause with a list of variables Vars.
Representation of the 'full' clause of the '#pragma omp unroll' directive.
static OMPFullClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Build an AST node for a 'full' clause.
static OMPGenericLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
This represents 'grainsize' clause in the '#pragma omp ...' directive.
static OMPHasDeviceAddrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
This represents 'hint' clause in the '#pragma omp ...' directive.
This represents 'if' clause in the '#pragma omp ...' directive.
static OMPInReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr * > Privates, ArrayRef< Expr * > LHSExprs, ArrayRef< Expr * > RHSExprs, ArrayRef< Expr * > ReductionOps, ArrayRef< Expr * > TaskgroupDescriptors, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
static OMPInclusiveClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
static OMPInitClause * Create(const ASTContext &C, Expr *InteropVar, OMPInteropInfo &InteropInfo, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Creates a fully specified clause.
static OMPInteropDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive.
static OMPIsDevicePtrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
static OMPLastprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > SrcExprs, ArrayRef< Expr * > DstExprs, ArrayRef< Expr * > AssignmentOps, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
This represents clause 'linear' in the '#pragma omp ...' directives.
Expr * getStep()
Returns linear step.
void setUpdates(ArrayRef< Expr * > UL)
Sets the list of update expressions for linear variables.
privates_range privates()
void setFinals(ArrayRef< Expr * > FL)
Sets the list of final update expressions for linear variables.
void setUsedExprs(ArrayRef< Expr * > UE)
Sets the list of used expressions for the linear clause.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation StepModifierLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
Expr * getCalcStep()
Returns expression to calculate linear step.
OpenMPLinearClauseKind getModifier() const
Return modifier.
The base class for all loop-based directives, including loop transformation directives.
static bool doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops, llvm::function_ref< bool(unsigned, Stmt *)> Callback, llvm::function_ref< void(OMPLoopTransformationDirective *)> OnTransformationCallback)
Calls the specified callback function for all the loops in CurStmt, from the outermost to the innermo...
static OMPMapClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr * > UDMapperRefs, Expr *IteratorModifier, ArrayRef< OpenMPMapModifierKind > MapModifiers, ArrayRef< SourceLocation > MapModifiersLoc, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId, OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc)
Creates clause with a list of variables VL.
static OMPMaskedDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive.
static OMPMaskedTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
static OMPMaskedTaskLoopSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPMasterDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt)
Creates directive.
static OMPMasterTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
static OMPMasterTaskLoopSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
This represents 'mergeable' clause in the '#pragma omp ...' directive.
This represents 'message' clause in the '#pragma omp error' directive.
Expr * getMessageString() const
Returns message string of the clause.
This represents 'nocontext' clause in the '#pragma omp ...' directive.
This represents 'nogroup' clause in the '#pragma omp ...' directive.
static OMPNontemporalClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
This represents 'novariants' clause in the '#pragma omp ...' directive.
This represents 'nowait' clause in the '#pragma omp ...' directive.
This represents 'num_tasks' clause in the '#pragma omp ...' directive.
This represents 'num_teams' clause in the '#pragma omp ...' directive.
This represents 'num_threads' clause in the '#pragma omp ...' directive.
This represents 'order' clause in the '#pragma omp ...' directive.
SourceLocation getKindKwLoc() const
Returns location of clause kind.
OpenMPOrderClauseKind getKind() const
Returns kind of the clause.
This represents 'ordered' clause in the '#pragma omp ...' directive.
Expr * getNumForLoops() const
Return the number of associated for-loops.
static OMPOrderedClause * Create(const ASTContext &C, Expr *Num, unsigned NumLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build 'ordered' clause.
static OMPOrderedDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive.
static OMPParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
static OMPParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
static OMPParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPParallelGenericLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPParallelMaskedDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef)
Creates directive with a list of Clauses.
static OMPParallelMaskedTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
static OMPParallelMaskedTaskLoopSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPParallelMasterDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef)
Creates directive with a list of Clauses.
static OMPParallelMasterTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
static OMPParallelMasterTaskLoopSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPParallelSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
Representation of the 'partial' clause of the '#pragma omp unroll' directive.
static OMPPartialClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, Expr *Factor)
Build an AST node for a 'partial' clause.
Expr * getFactor() const
Returns the argument of the clause or nullptr if not set.
This represents 'priority' clause in the '#pragma omp ...' directive.
static OMPPrivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PrivateVL)
Creates clause with a list of variables VL.
This represents 'proc_bind' clause in the '#pragma omp ...' directive.
This represents 'read' clause in the '#pragma omp atomic' directive.
static OMPReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, OpenMPReductionClauseModifier Modifier, ArrayRef< Expr * > VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr * > Privates, ArrayRef< Expr * > LHSExprs, ArrayRef< Expr * > RHSExprs, ArrayRef< Expr * > ReductionOps, ArrayRef< Expr * > CopyOps, ArrayRef< Expr * > CopyArrayTemps, ArrayRef< Expr * > CopyArrayElems, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
This represents 'relaxed' clause in the '#pragma omp atomic' directives.
This represents 'release' clause in the '#pragma omp atomic|flush' directives.
This represents '#pragma omp requires...' directive.
clauselist_range clauselists()
static OMPRequiresDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< OMPClause * > CL)
Create requires node.
This represents 'reverse_offload' clause in the '#pragma omp requires' directive.
This represents 'simd' clause in the '#pragma omp ...' directive.
This represents 'safelen' clause in the '#pragma omp ...' directive.
Expr * getSafelen() const
Return safe iteration space distance.
static OMPScanDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive with a list of Clauses.
This represents 'schedule' clause in the '#pragma omp ...' directive.
SourceLocation getFirstScheduleModifierLoc() const
Get the first modifier location.
OpenMPScheduleClauseModifier getSecondScheduleModifier() const
Get the second modifier of the clause.
OpenMPScheduleClauseModifier getFirstScheduleModifier() const
Get the first modifier of the clause.
SourceLocation getSecondScheduleModifierLoc() const
Get the second modifier location.
static OMPScopeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive.
static OMPSectionDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt, bool HasCancel)
Creates directive.
static OMPSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
This represents 'seq_cst' clause in the '#pragma omp atomic' directive.
This represents 'severity' clause in the '#pragma omp error' directive.
OpenMPSeverityClauseKind getSeverityKind() const
Returns kind of the clause.
SourceLocation getSeverityKindKwLoc() const
Returns location of clause kind.
static OMPSharedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
static OMPSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, OpenMPDirectiveKind ParamPrevMappedDirective)
Creates directive with a list of Clauses.
This represents 'simdlen' clause in the '#pragma omp ...' directive.
Expr * getSimdlen() const
Return safe iteration space distance.
static OMPSingleDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
This represents the 'sizes' clause in the '#pragma omp tile' directive.
static OMPSizesClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > Sizes)
Build a 'sizes' AST node.
unsigned getNumSizes() const
Returns the number of list items.
MutableArrayRef< Expr * > getSizesRefs()
Returns the tile size expressions.
static OMPTargetDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static OMPTargetDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static OMPTargetEnterDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static OMPTargetExitDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static OMPTargetParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
static OMPTargetParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
static OMPTargetParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTargetParallelGenericLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTargetSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTargetTeamsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static OMPTargetTeamsDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTargetTeamsDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
static OMPTargetTeamsDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTargetTeamsDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTargetTeamsGenericLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTargetUpdateDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static OMPTaskDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
static OMPTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
static OMPTaskLoopSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTaskReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr * > Privates, ArrayRef< Expr * > LHSExprs, ArrayRef< Expr * > RHSExprs, ArrayRef< Expr * > ReductionOps, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
static OMPTaskgroupDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, Expr *ReductionRef)
Creates directive.
static OMPTaskwaitDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive.
static OMPTaskyieldDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
static OMPTeamsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static OMPTeamsDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTeamsDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, bool HasCancel)
Creates directive with a list of Clauses.
static OMPTeamsDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTeamsDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTeamsGenericLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
This represents 'thread_limit' clause in the '#pragma omp ...' directive.
This represents '#pragma omp threadprivate ...' directive.
static OMPThreadPrivateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< Expr * > VL)
This represents 'threads' clause in the '#pragma omp ...' directive.
static OMPTileDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, unsigned NumLoops, Stmt *AssociatedStmt, Stmt *TransformedStmt, Stmt *PreInits)
Create a new AST node representation for '#pragma omp tile'.
static OMPToClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr * > UDMapperRefs, ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId)
Creates clause with a list of variables Vars.
Helper data structure representing the traits in a match clause of an declare variant or metadirectiv...
bool anyScoreOrCondition(llvm::function_ref< bool(Expr *&, bool)> Cond)
void getAsVariantMatchInfo(ASTContext &ASTCtx, llvm::omp::VariantMatchInfo &VMI) const
Create a variant match info object from this trait info object.
This represents 'unified_address' clause in the '#pragma omp requires' directive.
This represents 'unified_shared_memory' clause in the '#pragma omp requires' directive.
static OMPUnrollDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, unsigned NumGeneratedLoops, Stmt *TransformedStmt, Stmt *PreInits)
Create a new AST node representation for '#pragma omp unroll'.
This represents 'untied' clause in the '#pragma omp ...' directive.
static OMPUpdateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates clause for 'atomic' directive.
This represents the 'use' clause in '#pragma omp ...' directives.
static OMPUseDeviceAddrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
static OMPUseDevicePtrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr * > Vars, ArrayRef< Expr * > PrivateVars, ArrayRef< Expr * > Inits, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
static OMPUsesAllocatorsClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< OMPUsesAllocatorsClause::Data > Data)
Creates clause with a list of allocators Data.
SourceLocation getLParenLoc() const
Returns the location of '('.
unsigned varlist_size() const
This represents 'weak' clause in the '#pragma omp atomic' directives.
This represents 'write' clause in the '#pragma omp atomic' directive.
This represents 'ompx_attribute' clause in a directive that might generate an outlined function.
This represents 'ompx_bare' clause in the '#pragma omp target teams ...' directive.
This represents 'ompx_dyn_cgroup_mem' clause in the '#pragma omp target ...' directive.
Wrapper for void* pointer.
void * getAsOpaquePtr() const
static OpaquePtr make(PtrTy P)
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Represents a parameter to a function.
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
IdentifierTable & getIdentifierTable()
static PseudoObjectExpr * Create(const ASTContext &Context, Expr *syntactic, ArrayRef< Expr * > semantic, unsigned resultIndex)
A (possibly-)qualified type.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
bool hasQualifiers() const
Determine whether this type has any qualifiers.
QualType withRestrict() const
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type.
QualType withConst() const
void addConst()
Add the const type qualifier to this QualType.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
bool isConstant(const ASTContext &Ctx) const
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool isMoreQualifiedThan(QualType Other) const
Determine whether this type is more qualified than the other given type, requiring exact equality for...
const Type * getTypePtrOrNull() const
Represents a struct/union/class.
field_range fields() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
decl_type * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
decl_type * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
Base for LValueReferenceType and RValueReferenceType.
Scope - A scope is a transient data structure that is used while parsing the program.
bool isDeclScope(const Decl *D) const
isDeclScope - Return true if this is the scope that the specified decl is declared in.
Scope * getBreakParent()
getBreakParent - Return the closest scope that a break statement would be affected by.
bool isOpenMPOrderClauseScope() const
Determine whether this scope is some OpenMP directive with order clause which specifies concurrent sc...
const Scope * getParent() const
getParent - Return the scope that this is nested in.
bool isOpenMPLoopScope() const
Determine whether this scope is a loop having OpenMP loop directive attached.
@ OpenMPOrderClauseScope
This is a scope of some OpenMP directive with order clause which specifies concurrent.
A RAII object to enter scope of a compound statement.
A generic diagnostic builder for errors which may or may not be deferred.
@ K_Nop
Emit no diagnostics.
@ K_Deferred
Create a deferred diagnostic, which is emitted only if the function it's attached to is codegen'ed.
@ K_Immediate
Emit the diagnostic immediately (i.e., behave like Sema::Diag()).
RAII class used to indicate that we are performing provisional semantic analysis to determine the val...
Abstract base class used for diagnosing integer constant expression violations.
Sema - This implements semantic analysis and AST building for C.
OMPClause * ActOnOpenMPXBareClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on a well-formed 'ompx_bare' clause.
OMPClause * ActOnOpenMPMapClause(Expr *IteratorModifier, ArrayRef< OpenMPMapModifierKind > MapTypeModifiers, ArrayRef< SourceLocation > MapTypeModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, bool NoDiagnose=false, ArrayRef< Expr * > UnresolvedMappers=std::nullopt)
Called on well-formed 'map' clause.
OMPClause * ActOnOpenMPWeakClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'weak' clause.
ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo)
Package the given type and TSI into a ParsedType.
OMPClause * ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data, Expr *DepModifier, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'depend' clause.
QualType getCurrentThisType()
Try to retrieve the type of the 'this' pointer.
OMPClause * ActOnOpenMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Called on well-formed 'init' clause.
Scope * getCurScope() const
Retrieve the parser's current scope.
const ValueDecl * getOpenMPDeclareMapperVarName() const
OMPClause * ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'unified_address' clause.
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveStart(Scope *S, DeclContext *DC, DeclarationName Name, ArrayRef< std::pair< QualType, SourceLocation > > ReductionTypes, AccessSpecifier AS, Decl *PrevDeclInScope=nullptr)
Called on start of '#pragma omp declare reduction'.
DeclGroupPtrTy ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, ArrayRef< Expr * > Uniforms, ArrayRef< Expr * > Aligneds, ArrayRef< Expr * > Alignments, ArrayRef< Expr * > Linears, ArrayRef< unsigned > LinModifiers, ArrayRef< Expr * > Steps, SourceRange SR)
Called on well-formed '#pragma omp declare simd' after parsing of the associated method/function.
OMPClause * ActOnOpenMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_threads' clause.
bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S=nullptr, bool AllowInlineNamespace=false) const
isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true if 'D' is in Scope 'S',...
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val)
ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *InputExpr, bool IsAfterAmp=false)
void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath)
ExprResult IgnoredValueConversions(Expr *E)
IgnoredValueConversions - Given that an expression's result is syntactically ignored,...
OMPClause * ActOnOpenMPNovariantsClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'novariants' clause.
StmtResult ActOnOpenMPTargetTeamsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target teams' after parsing of the associated statement.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ LookupOMPReductionName
Look up the name of an OpenMP user-defined reduction operation.
@ LookupOMPMapperName
Look up the name of an OpenMP user-defined mapper.
@ LookupAnyName
Look up any declaration with any name.
OMPClause * ActOnOpenMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'write' clause.
OMPClause * ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, ArrayRef< unsigned > Arguments, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, ArrayRef< SourceLocation > ArgumentsLoc, SourceLocation DelimLoc, SourceLocation EndLoc)
OMPClause * ActOnOpenMPExclusiveClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'exclusive' clause.
static int getOpenMPCaptureLevels(OpenMPDirectiveKind Kind)
Return the number of captured regions created for an OpenMP directive.
OMPClause * ActOnOpenMPUseDevicePtrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'use_device_ptr' clause.
ImplicitConversionSequence TryImplicitConversion(Expr *From, QualType ToType, bool SuppressUserConversions, AllowedExplicit AllowExplicit, bool InOverloadResolution, bool CStyle, bool AllowObjCWritebackConversion)
StmtResult ActOnOpenMPScanDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp scan'.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init)
Check if the current region is an OpenMP loop region and if it is, mark loop control variable,...
void ActOnOpenMPEndAssumesDirective()
Called on well-formed '#pragma omp end assumes'.
OMPClause * ActOnOpenMPFlushClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'flush' pseudo clause.
void DiagnoseUnterminatedOpenMPDeclareTarget()
Report unterminated 'omp declare target' or 'omp begin declare target' at the end of a compilation un...
OMPClause * ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, Expr *Device, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc)
Called on well-formed 'device' clause.
OMPClause * ActOnOpenMPUseDeviceAddrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'use_device_addr' clause.
OMPClause * ActOnOpenMPPriorityClause(Expr *Priority, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'priority' clause.
FunctionEmissionStatus
Status of the function emission on the CUDA/HIP/OpenMP host/device attrs.
OMPClause * ActOnOpenMPOrderClause(OpenMPOrderClauseModifier Modifier, OpenMPOrderClauseKind Kind, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc)
Called on well-formed 'order' clause.
StmtResult ActOnOpenMPOrderedDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp ordered' after parsing of the associated statement.
void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl=nullptr, ExpressionEvaluationContextRecord::ExpressionKind Type=ExpressionEvaluationContextRecord::EK_Other)
StmtResult ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancellation point'.
ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E, bool IsConstexpr=false)
CheckBooleanCondition - Diagnose problems involving the use of the given expression as a boolean cond...
OMPClause * ActOnOpenMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'nowait' clause.
bool isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const
OMPClause * ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc)
SmallVector< sema::FunctionScopeInfo *, 4 > FunctionScopes
Stack containing information about each of the nested function, block, and method scopes that are cur...
StmtResult ActOnOpenMPDistributeParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute parallel for' after parsing of the associated statement...
PoppedFunctionScopePtr PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP=nullptr, const Decl *D=nullptr, QualType BlockType=QualType())
Pop a function (or block or lambda or captured region) scope from the stack.
OMPClause * ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'dynamic_allocators' clause.
bool CheckCXXThisCapture(SourceLocation Loc, bool Explicit=false, bool BuildAndDiagnose=true, const unsigned *const FunctionScopeIndexToStopAt=nullptr, bool ByCopy=false)
Make sure the value of 'this' is actually available in the current context, if it is a potentially ev...
OMPClause * ActOnOpenMPAllocateClause(Expr *Allocator, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'allocate' clause.
StmtResult ActOnOpenMPTargetSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target simd' after parsing of the associated statement.
StmtResult ActOnOpenMPForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for' after parsing of the associated statement.
NamedDecl * HandleDeclarator(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParameterLists)
ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, VerifyICEDiagnoser &Diagnoser, AllowFoldKind CanFold=NoFold)
VerifyIntegerConstantExpression - Verifies that an expression is an ICE, and reports the appropriate ...
StmtResult ActOnOpenMPLoopnest(Stmt *AStmt)
Process a canonical OpenMP loop nest that can either be a canonical literal loop (ForStmt or CXXForRa...
OMPClause * ActOnOpenMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'simd' clause.
StmtResult ActOnOpenMPTargetParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel for' after parsing of the associated statement.
FPOptionsOverride CurFPFeatureOverrides()
ExprResult ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType, SourceLocation StartLoc, DeclarationName VN)
Build the mapper variable of '#pragma omp declare mapper'.
StmtResult ActOnOpenMPTaskwaitDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskwait'.
void MarkDeclarationsReferencedInExpr(Expr *E, bool SkipLocalVariables=false, ArrayRef< const Expr * > StopAt=std::nullopt)
Mark any declarations that appear within this expression or any potentially-evaluated subexpressions ...
TypeResult ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D)
Check variable declaration in 'omp declare mapper' construct.
StmtResult ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute parallel for simd' after parsing of the associated stat...
DeclGroupPtrTy ActOnOpenMPRequiresDirective(SourceLocation Loc, ArrayRef< OMPClause * > ClauseList)
Called on well-formed '#pragma omp requires'.
void startOpenMPLoop()
If the current region is a loop-based region, mark the start of the loop construct.
OMPClause * ActOnOpenMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Called on well-formed 'destroy' clause.
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
ExprResult PerformContextualImplicitConversion(SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter)
Perform a contextual implicit conversion.
OMPClause * ActOnOpenMPBindClause(OpenMPBindClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on a well-formed 'bind' clause.
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, const ImplicitConversionSequence &ICS, AssignmentAction Action, CheckedConversionKind CCK=CCK_ImplicitConversion)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType ...
bool isInOpenMPTaskUntiedContext() const
Return true if currently in OpenMP task with untied clause context.
StmtResult ActOnOpenMPMaskedTaskLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp masked taskloop' after parsing of the associated statement.
StmtResult ActOnOpenMPTargetExitDataDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed '#pragma omp target exit data' after parsing of the associated statement.
OMPClause * ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'final' clause.
void ActOnCapturedRegionError()
StmtResult ActOnOpenMPFlushDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp flush'.
OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr * > Vars, const OMPVarListLocTy &Locs, OpenMPVarListDataTy &Data)
OMPClause * ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'hint' clause.
SemaDiagnosticBuilder diagIfOpenMPHostCode(SourceLocation Loc, unsigned DiagID, const FunctionDecl *FD)
Creates a SemaDiagnosticBuilder that emits the diagnostic if the current context is "used as host cod...
OMPClause * ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(SourceLocation Loc, ArrayRef< Expr * > VarList)
Called on well-formed '#pragma omp threadprivate'.
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext=true)
Add this decl to the scope shadowed decl chains.
void CleanupVarDeclMarking()
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
ASTContext & getASTContext() const
void finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, const FunctionDecl *Callee, SourceLocation Loc)
Finishes analysis of the deferred functions calls that may be declared as host/nohost during device/h...
StmtResult ActOnOpenMPDistributeSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute simd' after parsing of the associated statement.
OMPClause * ActOnOpenMPSharedClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'shared' clause.
NamedDecl * LookupSingleName(Scope *S, DeclarationName Name, SourceLocation Loc, LookupNameKind NameKind, RedeclarationKind Redecl=NotForRedeclaration)
Look up a name, looking for a single declaration.
ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input, bool IsAfterAmp=false)
StmtResult ActOnOpenMPTargetUpdateDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed '#pragma omp target update'.
StmtResult ActOnOpenMPSingleDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp single' after parsing of the associated statement.
bool tryCaptureVariable(ValueDecl *Var, SourceLocation Loc, TryCaptureKind Kind, SourceLocation EllipsisLoc, bool BuildAndDiagnose, QualType &CaptureType, QualType &DeclRefType, const unsigned *const FunctionScopeIndexToStopAt)
Try to capture the given variable.
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute parallel for simd' after parsing of the as...
void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var)
Mark a variable referenced, and check whether it is odr-used (C++ [basic.def.odr]p2,...
OMPClause * ActOnOpenMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'capture' clause.
void PopExpressionEvaluationContext()
StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef< OMPClause * > Clauses)
End of OpenMP region.
StmtResult ActOnOpenMPParallelMaskedTaskLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel masked taskloop' after parsing of the associated statemen...
StmtResult ActOnOpenMPTargetParallelDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target parallel' after parsing of the associated statement.
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
bool isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, unsigned CaptureLevel) const
Check if the specified global variable must be captured by outer capture regions.
OMPClause * ActOnOpenMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'at' clause.
DeclRefExpr * BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)
StmtResult ActOnOpenMPParallelMasterDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel master' after parsing of the associated statement.
StmtResult ActOnOpenMPTargetDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target' after parsing of the associated statement.
StmtResult ActOnOpenMPCancelDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancel'.
OMPClause * ActOnOpenMPReductionClause(ArrayRef< Expr * > VarList, OpenMPReductionClauseModifier Modifier, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions=std::nullopt)
Called on well-formed 'reduction' clause.
OMPClause * ActOnOpenMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'untied' clause.
void FindAssociatedClassesAndNamespaces(SourceLocation InstantiationLoc, ArrayRef< Expr * > Args, AssociatedNamespaceSet &AssociatedNamespaces, AssociatedClassSet &AssociatedClasses)
Find the associated classes and namespaces for argument-dependent lookup for a call with the given se...
ExprResult ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id, OpenMPDirectiveKind Kind)
Called on correct id-expression from the '#pragma omp threadprivate'.
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
void checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, SourceLocation IdLoc=SourceLocation())
Check declaration inside target region.
OMPClause * ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'update' clause.
ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op)
void PushFunctionScope()
Enter a new function scope.
OMPClause * ActOnOpenMPFirstprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'firstprivate' clause.
void tryCaptureOpenMPLambdas(ValueDecl *V)
Function tries to capture lambda's captured variables in the OpenMP region before the original lambda...
StmtResult ActOnOpenMPDepobjDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp depobj'.
StmtResult ActOnOpenMPInteropDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp interop'.
OMPClause * ActOnOpenMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on a well-formed 'ompx_dyn_cgroup_mem' clause.
const LangOptions & getLangOpts() const
TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC, CorrectTypoKind Mode, DeclContext *MemberContext=nullptr, bool EnteringContext=false, const ObjCObjectPointerType *OPT=nullptr, bool RecordFailure=true)
Try to "correct" a typo in the source code by finding visible declarations whose names are similar to...
OMPClause * ActOnOpenMPSeverityClause(OpenMPSeverityClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'severity' clause.
OMPClause * ActOnOpenMPAcquireClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'acquire' clause.
void ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
OMPClause * ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'schedule' clause.
StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind PrevMappedDirective=llvm::omp::OMPD_unknown)
void ActOnOpenMPIteratorVarDecl(VarDecl *VD)
OMPClause * ActOnOpenMPHasDeviceAddrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'has_device_addr' clause.
ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false, bool AllowRecovery=false)
BuildCallExpr - Handle a call to Fn with the specified array of arguments.
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, QualType Derived, const CXXBasePath &Path, unsigned DiagID, bool ForceCheck=false, bool ForceUnprivileged=false)
Checks access for a hierarchy conversion.
OMPClause * ActOnOpenMPAcqRelClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'acq_rel' clause.
StmtResult ActOnOpenMPParallelMasterTaskLoopSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel master taskloop simd' after parsing of the associated sta...
void ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Decl *D, SmallVectorImpl< FunctionDecl * > &Bases)
Register D as specialization of all base functions in Bases in the current omp begin/end declare vari...
ExprResult VerifyPositiveIntegerConstantInClause(Expr *Op, OpenMPClauseKind CKind, bool StrictlyPositive=true, bool SuppressExprDiags=false)
DeclGroupPtrTy ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef< Expr * > VarList, ArrayRef< OMPClause * > Clauses, DeclContext *Owner=nullptr)
Called on well-formed '#pragma omp allocate'.
void CheckExtraCXXDefaultArguments(Declarator &D)
CheckExtraCXXDefaultArguments - Check for any extra default arguments in the declarator,...
OMPClause * ActOnOpenMPSimdlenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'simdlen' clause.
const LangOptions & LangOpts
sema::LambdaScopeInfo * getCurLambda(bool IgnoreNonLambdaCapturingScope=false)
Retrieve the current lambda scope info, if any.
OMPClause * ActOnOpenMPFilterClause(Expr *ThreadID, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'filter' clause.
OMPClause * ActOnOpenMPAffinityClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, Expr *Modifier, ArrayRef< Expr * > Locators)
Called on well-formed 'affinity' clause.
OMPClause * ActOnOpenMPProcBindClause(llvm::omp::ProcBindKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'proc_bind' clause.
OMPThreadPrivateDecl * CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef< Expr * > VarList)
Builds a new OpenMPThreadPrivateDecl and checks its correctness.
SemaDiagnosticBuilder diagIfOpenMPDeviceCode(SourceLocation Loc, unsigned DiagID, const FunctionDecl *FD)
Creates a SemaDiagnosticBuilder that emits the diagnostic if the current context is "used as device c...
bool isInOpenMPAssumeScope() const
Check if there is an active global omp begin assumes directive.
void startOpenMPCXXRangeFor()
If the current region is a range loop-based region, mark the start of the loop construct.
void setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, unsigned Level)
Sets OpenMP capture kind (OMPC_private, OMPC_firstprivate, OMPC_map etc.) for FD based on DSA for the...
OMPClause * ActOnOpenMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'seq_cst' clause.
StmtResult ActOnOpenMPMaskedTaskLoopSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp masked taskloop simd' after parsing of the associated statement.
OMPClause * ActOnOpenMPAlignClause(Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'align' clause.
StmtResult ActOnOpenMPForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for simd' after parsing of the associated statement.
DeclContext * getCurLexicalContext() const
OMPClause * ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_teams' clause.
bool isInOpenMPDeclareTargetContext() const
Return true inside OpenMP declare target region.
bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, bool AllowBuiltinCreation=false, bool EnteringContext=false)
Performs name lookup for a name that was parsed in the source code, and may contain a C++ scope speci...
void ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, DeclareTargetContextInfo &DTCI)
Called on correct id-expression from the '#pragma omp declare target'.
OMPClause * ActOnOpenMPInReductionClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions=std::nullopt)
Called on well-formed 'in_reduction' clause.
OMPClause * ActOnOpenMPDefaultClause(llvm::omp::DefaultKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'default' clause.
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, CapturedRegionKind Kind, unsigned NumParams)
OMPClause * ActOnOpenMPNocontextClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'nocontext' clause.
StmtResult ActOnOpenMPMasterTaskLoopSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp master taskloop simd' after parsing of the associated statement.
sema::FunctionScopeInfo * getCurFunction() const
OMPClause * ActOnOpenMPAlignedClause(ArrayRef< Expr * > VarList, Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'aligned' clause.
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute parallel for' after parsing of the associa...
StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel sections' after parsing of the associated statement.
StmtResult ActOnOpenMPTargetEnterDataDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed '#pragma omp target enter data' after parsing of the associated statement.
Expr * BuildCXXThisExpr(SourceLocation Loc, QualType Type, bool IsImplicit)
Build a CXXThisExpr and mark it referenced in the current context.
OMPClause * ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'if' clause.
ExprResult ActOnOpenMPCall(ExprResult Call, Scope *Scope, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig)
Given the potential call expression Call, determine if there is a specialization via the OpenMP decla...
StmtResult ActOnOpenMPTargetTeamsDistributeDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute' after parsing of the associated statement...
OMPClause * ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< UsesAllocatorsData > Data)
Called on well-formed 'uses_allocators' clause.
OMPClause * ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc, SourceLocation LParenLoc=SourceLocation(), Expr *NumForLoops=nullptr)
Called on well-formed 'ordered' clause.
StmtResult ActOnOpenMPParallelMaskedTaskLoopSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel masked taskloop simd' after parsing of the associated sta...
StmtResult ActOnOpenMPTaskDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp task' after parsing of the associated statement.
ExprResult DefaultLvalueConversion(Expr *E)
bool isVisible(const NamedDecl *D)
Determine whether a declaration is visible to name lookup.
void ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI, ArrayRef< Expr * > AdjustArgsNothing, ArrayRef< Expr * > AdjustArgsNeedDevicePtr, ArrayRef< OMPInteropInfo > AppendArgs, SourceLocation AdjustArgsLoc, SourceLocation AppendArgsLoc, SourceRange SR)
Called on well-formed '#pragma omp declare variant' after parsing of the associated method/function.
FunctionEmissionStatus getEmissionStatus(const FunctionDecl *Decl, bool Final=false)
StmtResult ActOnOpenMPUnrollDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp unroll' after parsing of its clauses and the associated statement.
QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, TypeResult ParsedType)
Check if the specified type is allowed to be used in 'omp declare reduction' construct.
OMPClause * ActOnOpenMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'mergeable' clause.
sema::BlockScopeInfo * getCurBlock()
Retrieve the current block, if any.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope)
Initialization of captured region for OpenMP region.
bool CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, OpenMPLinearClauseKind LinKind, QualType Type, bool IsDeclareSimd=false)
Checks that the specified declaration matches requirements for the linear decls.
StmtResult ActOnOpenMPDistributeDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute' after parsing of the associated statement.
VarDecl * ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
void ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D)
Act on D, a function definition inside of an omp [begin/end] assumes.
StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp barrier'.
StmtResult ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp master' after parsing of the associated statement.
StmtResult ActOnOpenMPTaskgroupDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskgroup'.
OMPClause * ActOnOpenMPReleaseClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'release' clause.
OMPClause * ActOnOpenMPCopyinClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyin' clause.
StmtResult ActOnCapturedRegionEnd(Stmt *S)
StmtResult ActOnOpenMPTargetTeamsDistributeSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute simd' after parsing of the associated stat...
StmtResult ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp critical' after parsing of the associated statement.
StmtResult ActOnOpenMPParallelMaskedDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel masked' after parsing of the associated statement.
bool isInOpenMPDeclareVariantScope() const
Can we exit an OpenMP declare variant scope at the moment.
OMPClause * ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'dist_schedule' clause.
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, VarDecl *OmpPrivParm)
Finish current declare reduction construct initializer.
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
StmtResult ActOnOpenMPMaskedDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp masked' after parsing of the.
OMPClause * ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Called on well-formed 'use' clause.
OMPClause * ActOnOpenMPFullClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-form 'full' clauses.
bool inTemplateInstantiation() const
Determine whether we are currently performing template instantiation.
void ActOnOpenMPEndDeclareVariant()
Handle a omp end declare variant.
@ TryCapture_ExplicitByVal
StmtResult ActOnOpenMPTeamsDistributeDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute' after parsing of the associated statement.
OMPClause * ActOnOpenMPFailClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'fail' clause.
OMPClause * ActOnOpenMPCompareClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'compare' clause.
bool areMultiversionVariantFunctionsCompatible(const FunctionDecl *OldFD, const FunctionDecl *NewFD, const PartialDiagnostic &NoProtoDiagID, const PartialDiagnosticAt &NoteCausedDiagIDAt, const PartialDiagnosticAt &NoSupportDiagIDAt, const PartialDiagnosticAt &DiffDiagIDAt, bool TemplatesSupported, bool ConstexprSupported, bool CLinkageMayDiffer)
Checks if the variant/multiversion functions are compatible.
OMPClause * ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'detach' clause.
ExprResult ActOnConditionalOp(SourceLocation QuestionLoc, SourceLocation ColonLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr)
ActOnConditionalOp - Parse a ?: operation.
RedeclarationKind forRedeclarationInCurContext() const
StmtResult ActOnOpenMPTargetParallelGenericLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel loop' after parsing of the associated statement.
OMPClause * ActOnOpenMPLinearClause(ArrayRef< Expr * > VarList, Expr *Step, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation StepModifierLoc, SourceLocation EndLoc)
Called on well-formed 'linear' clause.
OMPClause * ActOnOpenMPXAttributeClause(ArrayRef< const Attr * > Attrs, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on a well-formed 'ompx_attribute' clause.
void ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParameterLists, SmallVectorImpl< FunctionDecl * > &Bases)
The declarator D defines a function in the scope S which is nested in an omp begin/end declare varian...
DeclGroupPtrTy ActOnOpenMPDeclareMapperDirective(Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, Expr *MapperVarRef, ArrayRef< OMPClause * > Clauses, Decl *PrevDeclInScope=nullptr)
Called on start of '#pragma omp declare mapper'.
StmtResult ActOnOpenMPTargetParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel for simd' after parsing of the associated statemen...
NamedDecl * lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id)
Searches for the provided declaration name for OpenMP declare target directive.
StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp section' after parsing of the associated statement.
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd(Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid)
Called at the end of '#pragma omp declare reduction'.
void ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, OMPTraitInfo &TI)
Handle a omp begin declare variant.
bool isCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind=CompleteTypeKind::Default)
VarDecl * isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo=false, unsigned StopAt=0)
Check if the specified variable is used in one of the private clauses (private, firstprivate,...
@ Private
The private module fragment, between 'module :private;' and the end of the translation unit.
void setFunctionHasBranchProtectedScope()
OMPClause * ActOnOpenMPCopyprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyprivate' clause.
OMPClause * ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'depobj' pseudo clause.
QualType ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, TypeResult ParsedType)
Check if the specified type is allowed to be used in 'omp declare mapper' construct.
OMPClause * ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'thread_limit' clause.
bool ActOnStartOpenMPDeclareTargetContext(DeclareTargetContextInfo &DTCI)
Called on the start of target region i.e. '#pragma omp declare target'.
const DeclareTargetContextInfo ActOnOpenMPEndDeclareTargetDirective()
Called at the end of target region i.e. '#pragma omp end declare target'.
void StartOpenMPClause(OpenMPClauseKind K)
Start analysis of clauses.
OMPClause * ActOnOpenMPPrivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'private' clause.
StmtResult ActOnOpenMPDispatchDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp dispatch' after parsing of the.
OMPClause * ActOnOpenMPToClause(ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, ArrayRef< Expr * > UnresolvedMappers=std::nullopt)
Called on well-formed 'to' clause.
std::pair< StringRef, QualType > CapturedParamNameType
OMPClause * ActOnOpenMPNontemporalClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'nontemporal' clause.
ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS=nullptr, bool isClassName=false, bool HasTrailingDot=false, ParsedType ObjectType=nullptr, bool IsCtorOrDtorName=false, bool WantNontrivialTypeSourceInfo=false, bool IsClassTemplateDeductionContext=true, ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No, IdentifierInfo **CorrectedII=nullptr)
If the identifier refers to a type name within this scope, return the declaration of that type.
OMPClause * ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'unified_address' clause.
bool isInOpenMPTargetExecutionDirective() const
Return true inside OpenMP target region.
OMPClause * ActOnOpenMPTaskReductionClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions=std::nullopt)
Called on well-formed 'task_reduction' clause.
ExprResult CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, Expr *Idx, SourceLocation RLoc)
StmtResult ActOnOpenMPTeamsGenericLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams loop' after parsing of the associated statement.
OMPClause * ActOnOpenMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'threads' clause.
OMPClause * ActOnOpenMPAtomicDefaultMemOrderClause(OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'atomic_default_mem_order' clause.
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
void ActOnOpenMPDeclareTargetInitializer(Decl *D)
Adds OMPDeclareTargetDeclAttr to referenced variables in declare target directive.
TypeSourceInfo * GetTypeForDeclarator(Declarator &D)
GetTypeForDeclarator - Convert the type for the specified declarator to Type instances.
void diagnoseTypo(const TypoCorrection &Correction, const PartialDiagnostic &TypoDiag, bool ErrorRecovery=true)
OMPClause * ActOnOpenMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier, Expr *Size, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc)
Called on well-formed 'grainsize' clause.
StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc)
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
StmtResult ActOnOpenMPTargetTeamsGenericLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams loop' after parsing of the associated statement.
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
OMPClause * ActOnOpenMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'read' clause.
StmtResult ActOnOpenMPTaskLoopSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop simd' after parsing of the associated statement.
OMPClause * ActOnOpenMPDoacrossClause(OpenMPDoacrossClauseModifier DepType, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'doacross' clause.
StmtResult ActOnOpenMPSectionsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp sections' after parsing of the associated statement.
void StartOpenMPDSABlock(OpenMPDirectiveKind K, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc)
Called on start of new data sharing attribute block.
void DiscardCleanupsInEvaluationContext()
StmtResult ActOnOpenMPErrorDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, bool InExContext=true)
Called on well-formed '#pragma omp error'.
void PushDeclContext(Scope *S, DeclContext *DC)
Set the current declaration context until it gets popped.
StmtResult ActOnOpenMPParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for' after parsing of the associated statement.
bool isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, unsigned OpenMPCaptureLevel) const
Return true if the provided declaration VD should be captured by reference.
OMPClause * ActOnOpenMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier, Expr *NumTasks, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc)
Called on well-formed 'num_tasks' clause.
MemberExpr * BuildMemberExpr(Expr *Base, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec *SS, SourceLocation TemplateKWLoc, ValueDecl *Member, DeclAccessPair FoundDecl, bool HadMultipleCandidates, const DeclarationNameInfo &MemberNameInfo, QualType Ty, ExprValueKind VK, ExprObjectKind OK, const TemplateArgumentListInfo *TemplateArgs=nullptr)
llvm::SmallDenseMap< const ValueDecl *, const Expr *, 4 > VarsWithInheritedDSAType
StmtResult ActOnOpenMPTeamsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp teams' after parsing of the associated statement.
OMPClause * ActOnOpenMPPartialClause(Expr *FactorExpr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-form 'partial' clauses.
OMPClause * ActOnOpenMPSafelenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'safelen' clause.
ExprResult DefaultFunctionArrayConversion(Expr *E, bool Diagnose=true)
DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4).
ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, ExprObjectKind OK, SourceLocation Loc)
StmtResult ActOnOpenMPAtomicDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp atomic' after parsing of the associated statement.
void EndOpenMPDSABlock(Stmt *CurDirective)
Called on end of data sharing attribute block.
OMPClause * ActOnOpenMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'nogroup' clause.
StmtResult ActOnOpenMPParallelDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel' after parsing of the associated statement.
void FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S, bool ConsiderLinkage, bool AllowInlineNamespace)
Filters out lookup results that don't fall within the given scope as determined by isDeclInScope.
StmtResult ActOnOpenMPTileDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp tile' after parsing of its clauses and the associated statement.
StmtResult ActOnOpenMPScopeDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp scope' after parsing of the associated statement.
StmtResult ActOnOpenMPParallelGenericLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel loop' after parsing of the associated statement.
void ActOnUninitializedDecl(Decl *dcl)
StmtResult ActOnOpenMPTaskLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop' after parsing of the associated statement.
OMPClause * ActOnOpenMPMessageClause(Expr *MS, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'message' clause.
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
StmtResult ActOnOpenMPTeamsDistributeSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute simd' after parsing of the associated statement.
OMPClause * ActOnOpenMPLastprivateClause(ArrayRef< Expr * > VarList, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'lastprivate' clause.
void ActOnOpenMPAssumesDirective(SourceLocation Loc, OpenMPDirectiveKind DKind, ArrayRef< std::string > Assumptions, bool SkippedClauses)
Called on well-formed '#pragma omp [begin] assume[s]'.
OMPClause * ActOnOpenMPSizesClause(ArrayRef< Expr * > SizeExprs, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-form 'sizes' clause.
void EndOpenMPClause()
End analysis of clauses.
bool isOpenMPRebuildMemberExpr(ValueDecl *D)
The member expression(this->fd) needs to be rebuilt in the template instantiation to generate private...
StmtResult ActOnOpenMPGenericLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp loop' after parsing of the associated statement.
SemaDiagnosticBuilder targetDiag(SourceLocation Loc, unsigned DiagID, const FunctionDecl *FD=nullptr)
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskyield'.
OMPClause * ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'reverse_offload' clause.
ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
CreateBuiltinBinOp - Creates a new built-in binary operation with operator Opc at location TokLoc.
StmtResult ActOnOpenMPTeamsDistributeParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute parallel for simd' after parsing of the associate...
bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base)
Determine whether the type Derived is a C++ class that is derived from the type Base.
sema::FunctionScopeInfo * getEnclosingFunction() const
StmtResult ActOnOpenMPMasterTaskLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp master taskloop' after parsing of the associated statement.
sema::CapturedRegionScopeInfo * getCurCapturedRegion()
Retrieve the current captured region, if any.
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, SourceLocation LinLoc)
Checks correctness of linear modifiers.
std::optional< std::pair< FunctionDecl *, Expr * > > checkOpenMPDeclareVariantFunction(DeclGroupPtrTy DG, Expr *VariantRef, OMPTraitInfo &TI, unsigned NumAppendArgs, SourceRange SR)
Checks '#pragma omp declare variant' variant function and original functions after parsing of the ass...
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
void ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner)
Finish current declare reduction construct initializer.
OMPClause * ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc)
Called on well-formed 'defaultmap' clause.
StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, ArrayRef< Stmt * > Elts, bool isStmtExpr)
StmtResult ActOnOpenMPCanonicalLoop(Stmt *AStmt)
Called for syntactical loops (ForStmt or CXXForRangeStmt) associated to an OpenMP loop directive.
StmtResult ActOnOpenMPParallelMasterTaskLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel master taskloop' after parsing of the associated statemen...
StmtResult ActOnOpenMPTeamsDistributeParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute parallel for' after parsing of the associated sta...
OMPClause * ActOnOpenMPInclusiveClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'inclusive' clause.
StmtResult ActOnOpenMPParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for simd' after parsing of the associated statement.
OpenMPClauseKind isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, unsigned CapLevel) const
Check if the specified variable is used in 'private' clause.
FullExprArg MakeFullExpr(Expr *Arg)
OMPClause * ActOnOpenMPCollapseClause(Expr *NumForLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'collapse' clause.
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
bool isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, unsigned CaptureLevel) const
Check if the specified variable is captured by 'target' directive.
OMPRequiresDecl * CheckOMPRequiresDecl(SourceLocation Loc, ArrayRef< OMPClause * > Clauses)
Check restrictions on Requires directive.
OMPClause * ActOnOpenMPIsDevicePtrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'is_device_ptr' clause.
StmtResult ActOnOpenMPTargetDataDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target data' after parsing of the associated statement.
OMPClause * ActOnOpenMPAllocatorClause(Expr *Allocator, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'allocator' clause.
OMPClause * ActOnOpenMPFromClause(ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, ArrayRef< Expr * > UnresolvedMappers=std::nullopt)
Called on well-formed 'from' clause.
StmtResult ActOnOpenMPSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp simd' after parsing of the associated statement.
void ActOnFinishedOpenMPDeclareTargetContext(DeclareTargetContextInfo &DTCI)
Called once a target context is completed, that can be when a '#pragma omp end declare target' was en...
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
OMPClause * ActOnOpenMPRelaxedClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'relaxed' clause.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
void setBegin(SourceLocation b)
SourceLocation getBegin() const
void setEnd(SourceLocation e)
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
Stmt * IgnoreContainers(bool IgnoreCaptured=false)
Skip no-op (attributed, compound) container stmts and skip captured stmt at the top,...
SourceLocation getBeginLoc() const LLVM_READONLY
bool isTLSSupported() const
Whether the target supports thread-local storage.
bool isVLASupported() const
Whether target supports variable-length arrays.
Represents a declaration of a type.
A container of type source information.
QualType getType() const
Return the type wrapped by this type source info.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
bool isArithmeticType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
bool isScalarType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool hasUnsignedIntegerRepresentation() const
Determine whether this type has an unsigned integer representation of some sort, e....
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isAnyComplexType() const
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
bool isFunctionProtoType() const
bool isOverloadableType() const
Determines whether this is a type for which one can define an overloaded operator.
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
const T * getAsAdjusted() const
Member-template getAsAdjusted<specific type>.
bool isFunctionType() const
bool isStructureOrClassType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isAnyPointerType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
bool isFunctionNoProtoType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Simple class containing the result of Sema::CorrectTypo.
NamedDecl * getCorrectionDecl() const
Gets the pointer to the declaration of the typo correction.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
static UnresolvedLookupExpr * Create(const ASTContext &Context, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded, UnresolvedSetIterator Begin, UnresolvedSetIterator End)
void append(iterator I, iterator E)
void addDecl(NamedDecl *D)
A set of unresolved declarations.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
void setType(QualType newType)
Represents a variable declaration or definition.
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
bool isFunctionOrMethodVarDecl() const
Similar to isLocalVarDecl, but excludes variables declared in blocks.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
TLSKind getTLSKind() const
void setInitStyle(InitializationStyle Style)
InitializationStyle getInitStyle() const
The style of initialization for this declaration.
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
@ CInit
C-style initialization with assignment.
@ CallInit
Call-style initialization (C++98)
bool isStaticDataMember() const
Determines whether this is a static data member.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
bool isFileVarDecl() const
Returns true for file scoped variable declaration.
const Expr * getInit() const
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
@ TLS_None
Not a TLS variable.
@ DeclarationOnly
This declaration is only a declaration.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
bool isDirectInit() const
Whether the initializer is a direct-initializer (list or call).
StorageDuration getStorageDuration() const
Get the storage duration of this variable, per C++ [basic.stc].
StorageClass getStorageClass() const
Returns the storage class as written in the source.
bool isUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value can be used in a constant expression, according to the releva...
bool isLocalVarDeclOrParm() const
Similar to isLocalVarDecl but also includes parameters.
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Directive - Abstract class representing a parsed verify directive.
Retains information about a captured region.
unsigned short OpenMPLevel
unsigned short OpenMPCaptureLevel
CapturedDecl * TheCapturedDecl
The CapturedDecl for this statement.
Retains information about a function, method, or block that is currently being parsed.
void setHasOMPDeclareReductionCombiner()
SmallVector< CompoundScopeInfo, 4 > CompoundScopes
The stack of currently active compound statement scopes in the function.
specific_attr_iterator - Iterates over a subrange of an AttrVec, only providing attributes that are o...
Defines the clang::TargetInfo interface.
bool LE(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a worksharing directive.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ Device
'device' clause, allowed on the 'update' construct.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ OO_None
Not an overloaded operator.
@ NUM_OVERLOADED_OPERATORS
bool isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified composite/combined directive constitutes a teams directive in the outermost n...
bool checkFailClauseParameter(OpenMPClauseKind FailClauseParameter)
Checks if the parameter to the fail clause in "#pragma atomic compare fail" is restricted only to mem...
bool isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target data offload directive.
bool isOpenMPLoopTransformationDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a loop transformation directive.
llvm::omp::Directive OpenMPDirectiveKind
OpenMP directives.
OpenMPDefaultmapClauseModifier
OpenMP modifiers for 'defaultmap' clause.
@ OMPC_DEFAULTMAP_MODIFIER_last
@ OMPC_DEFAULTMAP_MODIFIER_unknown
OpenMPOrderClauseModifier
OpenMP modifiers for 'order' clause.
@ OMPC_ORDER_MODIFIER_unknown
@ OMPC_ORDER_MODIFIER_last
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
@ OK_Ordinary
An ordinary object is located at an address in memory.
OpenMPAtClauseKind
OpenMP attributes for 'at' clause.
Expr * AssertSuccess(ExprResult R)
bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a distribute directive.
@ LCK_ByRef
Capturing by reference.
@ LCK_This
Capturing the *this object by reference.
OpenMPReductionClauseModifier
OpenMP modifiers for 'reduction' clause.
OpenMPScheduleClauseModifier
OpenMP modifiers for 'schedule' clause.
@ OMPC_SCHEDULE_MODIFIER_last
@ OMPC_SCHEDULE_MODIFIER_unknown
llvm::omp::Clause OpenMPClauseKind
OpenMP clauses.
const char * getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type)
bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a parallel-kind directive.
bool isOpenMPPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of private clauses like 'private', 'firstprivate',...
OpenMPDistScheduleClauseKind
OpenMP attributes for 'dist_schedule' clause.
@ OMPC_DIST_SCHEDULE_unknown
for(auto typeArg :T->getTypeArgsAsWritten())
static constexpr StringRef getOpenMPVariantManglingSeparatorStr()
OpenMP variants are mangled early based on their OpenMP context selector.
OpenMPDoacrossClauseModifier
OpenMP dependence types for 'doacross' clause.
bool isOpenMPTaskingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of tasking directives - task, taskloop,...
static constexpr unsigned NumberOfOMPMapClauseModifiers
Number of allowed map-type-modifiers.
bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target code offload directive.
@ SD_Static
Static storage duration.
@ Parameter
The parameter type of a method or function.
@ Result
The result type of a method or function.
bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a teams-kind directive.
bool isOpenMPGenericLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive constitutes a 'loop' directive in the outermost nest.
OpenMPBindClauseKind
OpenMP bindings for the 'bind' clause.
OpenMPLastprivateModifier
OpenMP 'lastprivate' clause modifier.
@ OMPC_LASTPRIVATE_unknown
OpenMPDependClauseKind
OpenMP attributes for 'depend' clause.
OpenMPGrainsizeClauseModifier
OpenMPNumTasksClauseModifier
ActionResult< Expr * > ExprResult
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
OpenMPSeverityClauseKind
OpenMP attributes for 'severity' clause.
bool isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of the composite or combined directives that need loop ...
static constexpr unsigned NumberOfOMPMotionModifiers
Number of allowed motion-modifiers.
OpenMPMotionModifierKind
OpenMP modifier kind for 'to' or 'from' clause.
@ OMPC_MOTION_MODIFIER_unknown
OpenMPDefaultmapClauseKind
OpenMP attributes for 'defaultmap' clause.
@ OMPC_DEFAULTMAP_unknown
bool isOpenMPThreadPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of threadprivate clauses like 'threadprivate',...
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
void getOpenMPCaptureRegions(llvm::SmallVectorImpl< OpenMPDirectiveKind > &CaptureRegions, OpenMPDirectiveKind DKind)
Return the captured regions of an OpenMP directive.
OpenMPAtomicDefaultMemOrderClauseKind
OpenMP attributes for 'atomic_default_mem_order' clause.
@ OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
ActionResult< Decl * > DeclResult
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
OpenMPDeviceClauseModifier
OpenMP modifiers for 'device' clause.
OpenMPMapModifierKind
OpenMP modifier kind for 'map' clause.
@ OMPC_MAP_MODIFIER_unknown
bool isOpenMPCombinedParallelADirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a combined construct for which the first construct is a parallel...
bool isOpenMPNestingDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified composite/combined directive constitutes a distribute directive in the outerm...
OpenMPOrderClauseKind
OpenMP attributes for 'order' clause.
OpenMPScheduleClauseKind
OpenMP attributes for 'schedule' clause.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
unsigned operator()(argument_type DK)
OpenMPDirectiveKind argument_type
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
DeclarationName getName() const
getName - Returns the embedded declaration name.
void setLoc(SourceLocation L)
setLoc - Sets the main location of the declaration name.
void setName(DeclarationName N)
setName - Sets the embedded declaration name.
SourceLocation getBeginLoc() const
getBeginLoc - Retrieve the location of the first token.
std::string getAsString() const
getAsString - Retrieve the human-readable string for this name.
SourceLocation getEndLoc() const LLVM_READONLY
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
Extra information about a function prototype.
llvm::SmallVector< Expr *, 4 > PreferTypes
Expr * ParForInDistCond
'omp parallel for' loop condition used when composed with 'omp distribute' in the same construct and ...
Expr * LB
DistributeLowerBound - used when composing 'omp distribute' with 'omp for' in a same construct.
Expr * Init
Distribute loop iteration variable init used when composing 'omp distribute' with 'omp for' in a same...
Expr * NUB
Update of UpperBound for statically scheduled omp loops for outer loop in combined constructs (e....
Expr * EUB
DistributeEnsureUpperBound - used when composing 'omp distribute' with 'omp for' in a same construct,...
Expr * UB
DistributeUpperBound - used when composing 'omp distribute' with 'omp for' in a same construct.
Expr * NLB
Update of LowerBound for statically scheduled omp loops for outer loop in combined constructs (e....
Expr * DistCond
Distribute Loop condition used when composing 'omp distribute' with 'omp for' in a same construct whe...
Expr * Cond
Distribute Loop condition used when composing 'omp distribute' with 'omp for' in a same construct.
The expressions built for the OpenMP loop CodeGen for the whole collapsed loop nest.
Expr * LastIteration
Loop last iteration number.
Expr * Cond
Loop condition.
SmallVector< Expr *, 4 > DependentInits
List of initializers required for the generation of the non-rectangular loops.
SmallVector< Expr *, 4 > Inits
Expressions for loop counters inits for CodeGen.
Expr * PrevEUB
PrevEUB - expression similar to EUB but to be used when loop scheduling uses PrevLB and PrevUB (e....
Expr * DistInc
DistInc - increment expression for distribute loop when found combined with a further loop level (e....
Expr * IL
IsLastIteration - local flag variable passed to runtime.
SmallVector< Expr *, 4 > PrivateCounters
PrivateCounters Loop counters.
bool builtAll()
Check if all the expressions are built (does not check the worksharing ones).
Expr * CalcLastIteration
Calculation of last iteration.
SmallVector< Expr *, 4 > Updates
Expressions for loop counters update for CodeGen.
Expr * ST
Stride - local variable passed to runtime.
SmallVector< Expr *, 4 > Finals
Final loop counter values for GodeGen.
SmallVector< Expr *, 4 > FinalsConditions
List of final conditions required for the generation of the non-rectangular loops.
Expr * PreCond
Loop pre-condition.
Stmt * PreInits
Init statement for all captured expressions.
Expr * IterationVarRef
Loop iteration variable.
Expr * NumIterations
Loop number of iterations.
SmallVector< Expr *, 4 > Counters
Counters Loop counters.
Expr * NLB
Update of LowerBound for statically scheduled 'omp for' loops.
Expr * PrevUB
PreviousUpperBound - local variable passed to runtime in the enclosing schedule or null if that does ...
DistCombinedHelperExprs DistCombinedFields
Expressions used when combining OpenMP loop pragmas.
void clear(unsigned Size)
Initialize all the fields to null.
Expr * Inc
Loop increment.
Expr * EUB
EnsureUpperBound – expression UB = min(UB, NumIterations).
Expr * UB
UpperBound - local variable passed to runtime.
Expr * NUB
Update of UpperBound for statically scheduled 'omp for' loops.
Expr * LB
LowerBound - local variable passed to runtime.
Expr * PrevLB
PreviousLowerBound - local variable passed to runtime in the enclosing schedule or null if that does ...
SmallVector< Expr *, 4 > DependentCounters
List of counters required for the generation of the non-rectangular loops.
Expr * Init
Loop iteration variable init.
Data for list of allocators.
SourceLocation LParenLoc
Locations of '(' and ')' symbols.
Expr * AllocatorTraits
Allocator traits.
Expr * Allocator
Allocator.
This structure contains most locations needed for by an OMPVarListClause.
SourceLocation StartLoc
Starting location of the clause (the clause keyword).
SourceLocation LParenLoc
Location of '('.
SourceLocation EndLoc
Ending location of the clause.
std::optional< Expr * > Indirect
The directive with indirect clause.
OMPDeclareTargetDeclAttr::DevTypeTy DT
The 'device_type' as parsed from the clause.
OpenMPDirectiveKind Kind
The directive kind, begin declare target or declare target.
SourceLocation Loc
The directive location.
llvm::DenseMap< NamedDecl *, MapInfo > ExplicitlyMapped
Explicitly listed variables and functions in a 'to' or 'link' clause.
Data used for processing a list of variables in OpenMP clauses.
Data for list of allocators.
Expr * Allocator
Allocator.
SourceLocation LParenLoc
Locations of '(' and ')' symbols.
Expr * AllocatorTraits
Allocator traits.
Clang specific specialization of the OMPContext to lookup target features.