39#include "llvm/ADT/IndexedMap.h"
40#include "llvm/ADT/PointerEmbeddedInt.h"
41#include "llvm/ADT/STLExtras.h"
42#include "llvm/ADT/SmallSet.h"
43#include "llvm/ADT/StringExtras.h"
44#include "llvm/Frontend/OpenMP/OMPAssume.h"
45#include "llvm/Frontend/OpenMP/OMPConstants.h"
50using namespace llvm::omp;
63enum DefaultDataSharingAttributes {
68 DSA_firstprivate = 1 << 3,
78 unsigned Modifier = 0;
79 const Expr *RefExpr =
nullptr;
82 bool AppliedToPointee =
false;
83 DSAVarData() =
default;
87 bool AppliedToPointee)
88 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
89 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
90 AppliedToPointee(AppliedToPointee) {}
92 using OperatorOffsetTy =
94 using DoacrossClauseMapTy = llvm::DenseMap<OMPClause *, OperatorOffsetTy>;
96 enum class UsesAllocatorsDeclKind {
100 UserDefinedAllocator,
108 unsigned Modifier = 0;
111 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
115 bool AppliedToPointee =
false;
117 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
118 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
119 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
120 using LoopControlVariablesMapTy =
121 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
124 struct MappedExprComponentTy {
128 using MappedExprComponentsTy =
129 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
130 using CriticalsWithHintsTy =
131 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
132 struct ReductionData {
133 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
135 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
136 ReductionData() =
default;
143 ReductionOp = RefExpr;
146 using DeclReductionMapTy =
147 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
148 struct DefaultmapInfo {
152 DefaultmapInfo() =
default;
154 : ImplicitBehavior(M), SLoc(Loc) {}
157 struct SharingMapTy {
158 DeclSAMapTy SharingMap;
159 DeclReductionMapTy ReductionMap;
160 UsedRefMapTy AlignedMap;
161 UsedRefMapTy NontemporalMap;
162 MappedExprComponentsTy MappedExprComponents;
163 LoopControlVariablesMapTy LCVMap;
164 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
173 Scope *CurScope =
nullptr;
179 DoacrossClauseMapTy DoacrossDepends;
183 std::optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
184 bool RegionHasOrderConcurrent =
false;
185 unsigned AssociatedLoops = 1;
186 bool HasMutipleLoops =
false;
187 const Decl *PossiblyLoopCounter =
nullptr;
188 bool NowaitRegion =
false;
189 bool UntiedRegion =
false;
190 bool CancelRegion =
false;
191 bool LoopStart =
false;
192 bool BodyComplete =
false;
197 Expr *TaskgroupReductionRef =
nullptr;
206 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
210 struct ImplicitDefaultFDInfoTy {
214 size_t StackLevel = 0;
217 ImplicitDefaultFDInfoTy(
const FieldDecl *FD,
size_t StackLevel,
219 : FD(FD), StackLevel(StackLevel), VD(VD) {}
223 ImplicitDefaultFirstprivateFDs;
224 Expr *DeclareMapperVar =
nullptr;
228 :
Directive(DKind), DirectiveName(Name), CurScope(CurScope),
230 SharingMapTy() =
default;
236 DeclSAMapTy Threadprivates;
243 bool ForceCapturing =
false;
246 bool ForceCaptureByReferenceInTargetExecutable =
false;
247 CriticalsWithHintsTy Criticals;
248 unsigned IgnoredStackElements = 0;
252 using const_iterator = StackTy::const_reverse_iterator;
253 const_iterator begin()
const {
254 return Stack.empty() ? const_iterator()
255 : Stack.back().first.rbegin() + IgnoredStackElements;
257 const_iterator end()
const {
258 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
260 using iterator = StackTy::reverse_iterator;
262 return Stack.empty() ? iterator()
263 : Stack.back().first.rbegin() + IgnoredStackElements;
266 return Stack.empty() ? iterator() : Stack.back().first.rend();
271 bool isStackEmpty()
const {
272 return Stack.empty() ||
273 Stack.back().second != CurrentNonCapturingFunctionScope ||
274 Stack.back().first.size() <= IgnoredStackElements;
276 size_t getStackSize()
const {
277 return isStackEmpty() ? 0
278 : Stack.back().first.size() - IgnoredStackElements;
281 SharingMapTy *getTopOfStackOrNull() {
282 size_t Size = getStackSize();
285 return &Stack.back().first[
Size - 1];
287 const SharingMapTy *getTopOfStackOrNull()
const {
288 return const_cast<DSAStackTy &
>(*this).getTopOfStackOrNull();
290 SharingMapTy &getTopOfStack() {
291 assert(!isStackEmpty() &&
"no current directive");
292 return *getTopOfStackOrNull();
294 const SharingMapTy &getTopOfStack()
const {
295 return const_cast<DSAStackTy &
>(*this).getTopOfStack();
298 SharingMapTy *getSecondOnStackOrNull() {
299 size_t Size = getStackSize();
302 return &Stack.back().first[
Size - 2];
304 const SharingMapTy *getSecondOnStackOrNull()
const {
305 return const_cast<DSAStackTy &
>(*this).getSecondOnStackOrNull();
314 SharingMapTy &getStackElemAtLevel(
unsigned Level) {
315 assert(Level < getStackSize() &&
"no such stack element");
316 return Stack.back().first[
Level];
318 const SharingMapTy &getStackElemAtLevel(
unsigned Level)
const {
319 return const_cast<DSAStackTy &
>(*this).getStackElemAtLevel(Level);
325 bool isOpenMPLocal(
VarDecl *D, const_iterator
Iter)
const;
338 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
347 explicit DSAStackTy(
Sema &S) : SemaRef(S) {}
350 void setOMPAllocatorHandleT(
QualType Ty) { OMPAllocatorHandleT = Ty; }
352 QualType getOMPAllocatorHandleT()
const {
return OMPAllocatorHandleT; }
354 void setOMPAlloctraitT(
QualType Ty) { OMPAlloctraitT = Ty; }
356 QualType getOMPAlloctraitT()
const {
return OMPAlloctraitT; }
358 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
360 OMPPredefinedAllocators[AllocatorKind] = Allocator;
363 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind)
const {
364 return OMPPredefinedAllocators[AllocatorKind];
367 void setOMPDependT(
QualType Ty) { OMPDependT = Ty; }
369 QualType getOMPDependT()
const {
return OMPDependT; }
372 void setOMPEventHandleT(
QualType Ty) { OMPEventHandleT = Ty; }
374 QualType getOMPEventHandleT()
const {
return OMPEventHandleT; }
376 bool isClauseParsingMode()
const {
return ClauseKindMode != OMPC_unknown; }
378 assert(isClauseParsingMode() &&
"Must be in clause parsing mode.");
379 return ClauseKindMode;
383 bool isBodyComplete()
const {
384 const SharingMapTy *Top = getTopOfStackOrNull();
385 return Top && Top->BodyComplete;
387 void setBodyComplete() { getTopOfStack().BodyComplete =
true; }
389 bool isForceVarCapturing()
const {
return ForceCapturing; }
390 void setForceVarCapturing(
bool V) { ForceCapturing =
V; }
392 void setForceCaptureByReferenceInTargetExecutable(
bool V) {
393 ForceCaptureByReferenceInTargetExecutable =
V;
395 bool isForceCaptureByReferenceInTargetExecutable()
const {
396 return ForceCaptureByReferenceInTargetExecutable;
401 assert(!IgnoredStackElements &&
402 "cannot change stack while ignoring elements");
404 Stack.back().second != CurrentNonCapturingFunctionScope)
405 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
406 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
407 Stack.back().first.back().DefaultAttrLoc = Loc;
411 assert(!IgnoredStackElements &&
412 "cannot change stack while ignoring elements");
413 assert(!Stack.back().first.empty() &&
414 "Data-sharing attributes stack is empty!");
415 Stack.back().first.pop_back();
420 class ParentDirectiveScope {
425 ParentDirectiveScope(DSAStackTy &Self,
bool Activate)
426 : Self(Self), Active(
false) {
430 ~ParentDirectiveScope() { disable(); }
433 --Self.IgnoredStackElements;
439 ++Self.IgnoredStackElements;
448 "Expected loop-based directive.");
449 getTopOfStack().LoopStart =
true;
454 "Expected loop-based directive.");
455 getTopOfStack().LoopStart =
false;
458 bool isLoopStarted()
const {
460 "Expected loop-based directive.");
461 return !getTopOfStack().LoopStart;
464 void resetPossibleLoopCounter(
const Decl *D =
nullptr) {
465 getTopOfStack().PossiblyLoopCounter = D ? D->getCanonicalDecl() : D;
468 const Decl *getPossiblyLoopCunter()
const {
469 return getTopOfStack().PossiblyLoopCounter;
472 void pushFunction() {
473 assert(!IgnoredStackElements &&
474 "cannot change stack while ignoring elements");
476 assert(!isa<CapturingScopeInfo>(CurFnScope));
477 CurrentNonCapturingFunctionScope = CurFnScope;
481 assert(!IgnoredStackElements &&
482 "cannot change stack while ignoring elements");
483 if (!Stack.empty() && Stack.back().second == OldFSI) {
484 assert(Stack.back().first.empty());
487 CurrentNonCapturingFunctionScope =
nullptr;
489 if (!isa<CapturingScopeInfo>(FSI)) {
490 CurrentNonCapturingFunctionScope = FSI;
499 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
501 auto I = Criticals.find(Name.getAsString());
502 if (I != Criticals.end())
504 return std::make_pair(
nullptr, llvm::APSInt());
521 const LCDeclInfo isLoopControlVariable(
const ValueDecl *D)
const;
526 const LCDeclInfo isParentLoopControlVariable(
const ValueDecl *D)
const;
531 const LCDeclInfo isLoopControlVariable(
const ValueDecl *D,
532 unsigned Level)
const;
535 const ValueDecl *getParentLoopControlVariable(
unsigned I)
const;
538 void markDeclAsUsedInScanDirective(
ValueDecl *D) {
539 if (SharingMapTy *Stack = getSecondOnStackOrNull())
540 Stack->UsedInScanDirective.insert(D);
544 bool isUsedInScanDirective(
ValueDecl *D)
const {
545 if (
const SharingMapTy *Stack = getTopOfStackOrNull())
546 return Stack->UsedInScanDirective.contains(D);
552 DeclRefExpr *PrivateCopy =
nullptr,
unsigned Modifier = 0,
553 bool AppliedToPointee =
false);
562 const Expr *ReductionRef);
568 Expr *&TaskgroupDescriptor)
const;
573 const Expr *&ReductionRef,
574 Expr *&TaskgroupDescriptor)
const;
577 Expr *getTaskgroupReductionRef()
const {
578 assert((getTopOfStack().
Directive == OMPD_taskgroup ||
582 "taskgroup reference expression requested for non taskgroup or "
583 "parallel/worksharing directive.");
584 return getTopOfStack().TaskgroupReductionRef;
588 bool isTaskgroupReductionRef(
const ValueDecl *VD,
unsigned Level)
const {
589 return getStackElemAtLevel(Level).TaskgroupReductionRef &&
590 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
596 const DSAVarData getTopDSA(
ValueDecl *D,
bool FromParent);
598 const DSAVarData getImplicitDSA(
ValueDecl *D,
bool FromParent)
const;
600 const DSAVarData getImplicitDSA(
ValueDecl *D,
unsigned Level)
const;
607 DefaultDataSharingAttributes)>
610 bool FromParent)
const;
618 bool FromParent)
const;
625 unsigned Level,
bool NotLastprivate =
false)
const;
629 bool hasExplicitDirective(
631 unsigned Level)
const;
635 const llvm::function_ref<
bool(
638 bool FromParent)
const;
642 const SharingMapTy *Top = getTopOfStackOrNull();
643 return Top ? Top->Directive : OMPD_unknown;
646 const SharingMapTy *Top = getTopOfStackOrNull();
647 return Top ? Top->MappedDirective : OMPD_unknown;
650 SharingMapTy *Top = getTopOfStackOrNull();
652 "Before calling setCurrentDirective Top of Stack not to be NULL.");
654 Top->Directive = NewDK;
657 SharingMapTy *Top = getTopOfStackOrNull();
659 "Before calling setMappedDirective Top of Stack not to be NULL.");
661 Top->MappedDirective = NewDK;
665 assert(!isStackEmpty() &&
"No directive at specified level.");
666 return getStackElemAtLevel(Level).Directive;
670 unsigned OpenMPCaptureLevel)
const {
673 return CaptureRegions[OpenMPCaptureLevel];
677 const SharingMapTy *
Parent = getSecondOnStackOrNull();
682 void addRequiresDecl(
OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); }
685 template <
typename ClauseType>
bool hasRequiresDeclWithClause()
const {
688 return isa<ClauseType>(C);
696 bool IsDuplicate =
false;
699 for (
const OMPClause *CPrev : D->clauselists()) {
700 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
701 SemaRef.
Diag(CNew->getBeginLoc(),
702 diag::err_omp_requires_clause_redeclaration)
703 << getOpenMPClauseName(CNew->getClauseKind());
704 SemaRef.
Diag(CPrev->getBeginLoc(),
705 diag::note_omp_requires_previous_clause)
706 << getOpenMPClauseName(CPrev->getClauseKind());
717 TargetLocations.push_back(LocStart);
723 AtomicLocation = Loc;
728 SourceLocation getAtomicDirectiveLoc()
const {
return AtomicLocation; }
732 return TargetLocations;
737 getTopOfStack().DefaultAttr = DSA_none;
738 getTopOfStack().DefaultAttrLoc = Loc;
742 getTopOfStack().DefaultAttr = DSA_shared;
743 getTopOfStack().DefaultAttrLoc = Loc;
747 getTopOfStack().DefaultAttr = DSA_private;
748 getTopOfStack().DefaultAttrLoc = Loc;
752 getTopOfStack().DefaultAttr = DSA_firstprivate;
753 getTopOfStack().DefaultAttrLoc = Loc;
758 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[
Kind];
759 DMI.ImplicitBehavior = M;
765 return getTopOfStack()
766 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
769 .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
772 .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
774 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
779 return ConstructTraits;
784 ConstructTraits.append(Traits.begin(), Traits.end());
786 for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits)) {
787 llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val();
788 assert(Top == Trait &&
"Something left a trait on the stack!");
794 DefaultDataSharingAttributes getDefaultDSA(
unsigned Level)
const {
795 return getStackSize() <=
Level ? DSA_unspecified
796 : getStackElemAtLevel(Level).DefaultAttr;
798 DefaultDataSharingAttributes getDefaultDSA()
const {
799 return isStackEmpty() ? DSA_unspecified : getTopOfStack().DefaultAttr;
802 return isStackEmpty() ?
SourceLocation() : getTopOfStack().DefaultAttrLoc;
806 return isStackEmpty()
808 : getTopOfStack().DefaultmapMap[
Kind].ImplicitBehavior;
811 getDefaultmapModifierAtLevel(
unsigned Level,
813 return getStackElemAtLevel(Level).DefaultmapMap[
Kind].ImplicitBehavior;
815 bool isDefaultmapCapturedByRef(
unsigned Level,
818 getDefaultmapModifierAtLevel(Level, Kind);
819 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
820 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
821 (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
822 (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
823 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
830 case OMPC_DEFAULTMAP_scalar:
831 case OMPC_DEFAULTMAP_pointer:
833 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
834 (M == OMPC_DEFAULTMAP_MODIFIER_default);
835 case OMPC_DEFAULTMAP_aggregate:
836 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
840 llvm_unreachable(
"Unexpected OpenMPDefaultmapClauseKind enum");
842 bool mustBeFirstprivateAtLevel(
unsigned Level,
845 getDefaultmapModifierAtLevel(Level, Kind);
846 return mustBeFirstprivateBase(M, Kind);
850 return mustBeFirstprivateBase(M, Kind);
854 bool isThreadPrivate(
VarDecl *D) {
855 const DSAVarData DVar = getTopDSA(D,
false);
860 void setOrderedRegion(
bool IsOrdered,
const Expr *Param,
863 getTopOfStack().OrderedRegion.emplace(Param, Clause);
865 getTopOfStack().OrderedRegion.reset();
869 bool isOrderedRegion()
const {
870 if (
const SharingMapTy *Top = getTopOfStackOrNull())
871 return Top->OrderedRegion.has_value();
875 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam()
const {
876 if (
const SharingMapTy *Top = getTopOfStackOrNull())
877 if (Top->OrderedRegion)
878 return *Top->OrderedRegion;
879 return std::make_pair(
nullptr,
nullptr);
883 bool isParentOrderedRegion()
const {
884 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
885 return Parent->OrderedRegion.has_value();
889 std::pair<const Expr *, OMPOrderedClause *>
890 getParentOrderedRegionParam()
const {
891 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
892 if (
Parent->OrderedRegion)
893 return *
Parent->OrderedRegion;
894 return std::make_pair(
nullptr,
nullptr);
897 void setRegionHasOrderConcurrent(
bool HasOrderConcurrent) {
898 getTopOfStack().RegionHasOrderConcurrent = HasOrderConcurrent;
902 bool isParentOrderConcurrent()
const {
903 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
904 return Parent->RegionHasOrderConcurrent;
908 void setNowaitRegion(
bool IsNowait =
true) {
909 getTopOfStack().NowaitRegion = IsNowait;
913 bool isParentNowaitRegion()
const {
914 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
915 return Parent->NowaitRegion;
919 void setUntiedRegion(
bool IsUntied =
true) {
920 getTopOfStack().UntiedRegion = IsUntied;
923 bool isUntiedRegion()
const {
924 const SharingMapTy *Top = getTopOfStackOrNull();
925 return Top ? Top->UntiedRegion :
false;
928 void setParentCancelRegion(
bool Cancel =
true) {
929 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
930 Parent->CancelRegion |= Cancel;
933 bool isCancelRegion()
const {
934 const SharingMapTy *Top = getTopOfStackOrNull();
935 return Top ? Top->CancelRegion :
false;
940 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
941 Parent->PrevScanLocation = Loc;
944 bool doesParentHasScanDirective()
const {
945 const SharingMapTy *Top = getSecondOnStackOrNull();
946 return Top ? Top->PrevScanLocation.isValid() :
false;
950 const SharingMapTy *Top = getSecondOnStackOrNull();
955 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
956 Parent->PrevOrderedLocation = Loc;
959 bool doesParentHasOrderedDirective()
const {
960 const SharingMapTy *Top = getSecondOnStackOrNull();
961 return Top ? Top->PrevOrderedLocation.isValid() :
false;
965 const SharingMapTy *Top = getSecondOnStackOrNull();
970 void setAssociatedLoops(
unsigned Val) {
971 getTopOfStack().AssociatedLoops = Val;
973 getTopOfStack().HasMutipleLoops =
true;
976 unsigned getAssociatedLoops()
const {
977 const SharingMapTy *Top = getTopOfStackOrNull();
978 return Top ? Top->AssociatedLoops : 0;
981 bool hasMutipleLoops()
const {
982 const SharingMapTy *Top = getTopOfStackOrNull();
983 return Top ? Top->HasMutipleLoops :
false;
989 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
990 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
993 bool hasInnerTeamsRegion()
const {
994 return getInnerTeamsRegionLoc().
isValid();
998 const SharingMapTy *Top = getTopOfStackOrNull();
1002 Scope *getCurScope()
const {
1003 const SharingMapTy *Top = getTopOfStackOrNull();
1004 return Top ? Top->CurScope :
nullptr;
1006 void setContext(
DeclContext *DC) { getTopOfStack().Context = DC; }
1008 const SharingMapTy *Top = getTopOfStackOrNull();
1014 bool checkMappableExprComponentListsForDecl(
1015 const ValueDecl *VD,
bool CurrentRegionOnly,
1016 const llvm::function_ref<
1028 if (CurrentRegionOnly)
1031 std::advance(SI, 1);
1033 for (; SI != SE; ++SI) {
1034 auto MI = SI->MappedExprComponents.find(VD);
1035 if (MI != SI->MappedExprComponents.end())
1037 MI->second.Components)
1038 if (Check(L, MI->second.Kind))
1046 bool checkMappableExprComponentListsForDeclAtLevel(
1048 const llvm::function_ref<
1052 if (getStackSize() <= Level)
1055 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1056 auto MI = StackElem.MappedExprComponents.find(VD);
1057 if (MI != StackElem.MappedExprComponents.end())
1059 MI->second.Components)
1060 if (Check(L, MI->second.Kind))
1067 void addMappableExpressionComponents(
1071 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
1073 MEC.Components.resize(MEC.Components.size() + 1);
1074 MEC.Components.back().append(Components.begin(), Components.end());
1075 MEC.Kind = WhereFoundClauseKind;
1078 unsigned getNestingLevel()
const {
1079 assert(!isStackEmpty());
1080 return getStackSize() - 1;
1082 void addDoacrossDependClause(
OMPClause *
C,
const OperatorOffsetTy &OpsOffs) {
1083 SharingMapTy *
Parent = getSecondOnStackOrNull();
1085 Parent->DoacrossDepends.try_emplace(
C, OpsOffs);
1087 llvm::iterator_range<DoacrossClauseMapTy::const_iterator>
1088 getDoacrossDependClauses()
const {
1089 const SharingMapTy &StackElem = getTopOfStack();
1091 const DoacrossClauseMapTy &Ref = StackElem.DoacrossDepends;
1092 return llvm::make_range(Ref.begin(), Ref.end());
1094 return llvm::make_range(StackElem.DoacrossDepends.end(),
1095 StackElem.DoacrossDepends.end());
1099 void addMappedClassesQualTypes(
QualType QT) {
1100 SharingMapTy &StackElem = getTopOfStack();
1101 StackElem.MappedClassesQualTypes.insert(QT);
1105 bool isClassPreviouslyMapped(
QualType QT)
const {
1106 const SharingMapTy &StackElem = getTopOfStack();
1107 return StackElem.MappedClassesQualTypes.contains(QT);
1111 void addToParentTargetRegionLinkGlobals(
DeclRefExpr *E) {
1112 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1113 E->
getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1114 "Expected declare target link global.");
1115 for (
auto &Elem : *
this) {
1117 Elem.DeclareTargetLinkVarDecls.push_back(E);
1127 "Expected target executable directive.");
1128 return getTopOfStack().DeclareTargetLinkVarDecls;
1132 void addInnerAllocatorExpr(
Expr *E) {
1133 getTopOfStack().InnerUsedAllocators.push_back(E);
1137 return getTopOfStack().InnerUsedAllocators;
1141 void addImplicitTaskFirstprivate(
unsigned Level,
Decl *D) {
1142 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1145 bool isImplicitTaskFirstprivate(
Decl *D)
const {
1146 return getTopOfStack().ImplicitTaskFirstprivates.contains(D);
1150 void addUsesAllocatorsDecl(
const Decl *D, UsesAllocatorsDeclKind Kind) {
1151 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1155 std::optional<UsesAllocatorsDeclKind>
1156 isUsesAllocatorsDecl(
unsigned Level,
const Decl *D)
const {
1157 const SharingMapTy &StackElem = getTopOfStack();
1158 auto I = StackElem.UsesAllocatorsDecls.find(D);
1159 if (I == StackElem.UsesAllocatorsDecls.end())
1160 return std::nullopt;
1161 return I->getSecond();
1163 std::optional<UsesAllocatorsDeclKind>
1164 isUsesAllocatorsDecl(
const Decl *D)
const {
1165 const SharingMapTy &StackElem = getTopOfStack();
1166 auto I = StackElem.UsesAllocatorsDecls.find(D);
1167 if (I == StackElem.UsesAllocatorsDecls.end())
1168 return std::nullopt;
1169 return I->getSecond();
1172 void addDeclareMapperVarRef(
Expr *Ref) {
1173 SharingMapTy &StackElem = getTopOfStack();
1174 StackElem.DeclareMapperVar = Ref;
1176 const Expr *getDeclareMapperVarRef()
const {
1177 const SharingMapTy *Top = getTopOfStackOrNull();
1178 return Top ? Top->DeclareMapperVar :
nullptr;
1182 void addIteratorVarDecl(
VarDecl *VD) {
1183 SharingMapTy &StackElem = getTopOfStack();
1187 bool isIteratorVarDecl(
const VarDecl *VD)
const {
1188 const SharingMapTy *Top = getTopOfStackOrNull();
1196 const_iterator I = begin();
1197 const_iterator EndI = end();
1198 size_t StackLevel = getStackSize();
1199 for (; I != EndI; ++I) {
1200 if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1204 assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1207 for (
const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1208 if (IFD.FD == FD && IFD.StackLevel == StackLevel)
1213 bool isImplicitDefaultFirstprivateFD(
VarDecl *VD)
const {
1214 const_iterator I = begin();
1215 const_iterator EndI = end();
1216 for (; I != EndI; ++I)
1217 if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1221 for (
const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1228 iterator I = begin();
1229 const_iterator EndI = end();
1230 size_t StackLevel = getStackSize();
1231 for (; I != EndI; ++I) {
1232 if (I->DefaultAttr == DSA_private || I->DefaultAttr == DSA_firstprivate) {
1233 I->ImplicitDefaultFirstprivateFDs.emplace_back(FD, StackLevel, VD);
1238 assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1248 DKind == OMPD_unknown;
1254 if (
const auto *FE = dyn_cast<FullExpr>(E))
1255 E = FE->getSubExpr();
1257 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1258 E = MTE->getSubExpr();
1260 while (
const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1261 E = Binder->getSubExpr();
1263 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1264 E = ICE->getSubExprAsWritten();
1273 if (
const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1274 if (
const auto *ME = dyn_cast<MemberExpr>(
getExprAsWritten(CED->getInit())))
1275 D = ME->getMemberDecl();
1276 const auto *VD = dyn_cast<VarDecl>(D);
1277 const auto *FD = dyn_cast<FieldDecl>(D);
1278 if (VD !=
nullptr) {
1294DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &
Iter,
1297 auto *VD = dyn_cast<VarDecl>(D);
1298 const auto *FD = dyn_cast<FieldDecl>(D);
1300 if (
Iter == end()) {
1307 DVar.CKind = OMPC_shared;
1314 DVar.CKind = OMPC_shared;
1318 DVar.CKind = OMPC_shared;
1329 DVar.CKind = OMPC_private;
1333 DVar.DKind =
Iter->Directive;
1336 if (
Iter->SharingMap.count(D)) {
1337 const DSAInfo &
Data =
Iter->SharingMap.lookup(D);
1338 DVar.RefExpr =
Data.RefExpr.getPointer();
1339 DVar.PrivateCopy =
Data.PrivateCopy;
1340 DVar.CKind =
Data.Attributes;
1341 DVar.ImplicitDSALoc =
Iter->DefaultAttrLoc;
1342 DVar.Modifier =
Data.Modifier;
1343 DVar.AppliedToPointee =
Data.AppliedToPointee;
1351 switch (
Iter->DefaultAttr) {
1353 DVar.CKind = OMPC_shared;
1354 DVar.ImplicitDSALoc =
Iter->DefaultAttrLoc;
1358 case DSA_firstprivate:
1361 DVar.CKind = OMPC_unknown;
1363 DVar.CKind = OMPC_firstprivate;
1365 DVar.ImplicitDSALoc =
Iter->DefaultAttrLoc;
1373 DVar.CKind = OMPC_unknown;
1375 DVar.CKind = OMPC_private;
1377 DVar.ImplicitDSALoc =
Iter->DefaultAttrLoc;
1379 case DSA_unspecified:
1384 DVar.ImplicitDSALoc =
Iter->DefaultAttrLoc;
1388 DVar.CKind = OMPC_shared;
1398 DSAVarData DVarTemp;
1399 const_iterator I =
Iter, E = end();
1407 DVarTemp = getDSA(I, D);
1408 if (DVarTemp.CKind != OMPC_shared) {
1409 DVar.RefExpr =
nullptr;
1410 DVar.CKind = OMPC_firstprivate;
1413 }
while (I != E && !isImplicitTaskingRegion(I->Directive));
1415 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1424 return getDSA(++
Iter, D);
1428 const Expr *NewDE) {
1429 assert(!isStackEmpty() &&
"Data sharing attributes stack is empty");
1431 SharingMapTy &StackElem = getTopOfStack();
1432 auto It = StackElem.AlignedMap.find(D);
1433 if (It == StackElem.AlignedMap.end()) {
1434 assert(NewDE &&
"Unexpected nullptr expr to be added into aligned map");
1435 StackElem.AlignedMap[D] = NewDE;
1438 assert(It->second &&
"Unexpected nullptr expr in the aligned map");
1442const Expr *DSAStackTy::addUniqueNontemporal(
const ValueDecl *D,
1443 const Expr *NewDE) {
1444 assert(!isStackEmpty() &&
"Data sharing attributes stack is empty");
1446 SharingMapTy &StackElem = getTopOfStack();
1447 auto It = StackElem.NontemporalMap.find(D);
1448 if (It == StackElem.NontemporalMap.end()) {
1449 assert(NewDE &&
"Unexpected nullptr expr to be added into aligned map");
1450 StackElem.NontemporalMap[D] = NewDE;
1453 assert(It->second &&
"Unexpected nullptr expr in the aligned map");
1458 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1460 SharingMapTy &StackElem = getTopOfStack();
1461 StackElem.LCVMap.try_emplace(
1462 D, LCDeclInfo(StackElem.LCVMap.size() + 1,
Capture));
1465const DSAStackTy::LCDeclInfo
1466DSAStackTy::isLoopControlVariable(
const ValueDecl *D)
const {
1467 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1469 const SharingMapTy &StackElem = getTopOfStack();
1470 auto It = StackElem.LCVMap.find(D);
1471 if (It != StackElem.LCVMap.end())
1473 return {0,
nullptr};
1476const DSAStackTy::LCDeclInfo
1477DSAStackTy::isLoopControlVariable(
const ValueDecl *D,
unsigned Level)
const {
1478 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1480 for (
unsigned I = Level + 1; I > 0; --I) {
1481 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1482 auto It = StackElem.LCVMap.find(D);
1483 if (It != StackElem.LCVMap.end())
1486 return {0,
nullptr};
1489const DSAStackTy::LCDeclInfo
1490DSAStackTy::isParentLoopControlVariable(
const ValueDecl *D)
const {
1491 const SharingMapTy *
Parent = getSecondOnStackOrNull();
1492 assert(
Parent &&
"Data-sharing attributes stack is empty");
1494 auto It =
Parent->LCVMap.find(D);
1495 if (It !=
Parent->LCVMap.end())
1497 return {0,
nullptr};
1500const ValueDecl *DSAStackTy::getParentLoopControlVariable(
unsigned I)
const {
1501 const SharingMapTy *
Parent = getSecondOnStackOrNull();
1502 assert(
Parent &&
"Data-sharing attributes stack is empty");
1503 if (
Parent->LCVMap.size() < I)
1505 for (
const auto &Pair :
Parent->LCVMap)
1506 if (Pair.second.first == I)
1513 bool AppliedToPointee) {
1515 if (A == OMPC_threadprivate) {
1516 DSAInfo &
Data = Threadprivates[D];
1517 Data.Attributes = A;
1518 Data.RefExpr.setPointer(E);
1519 Data.PrivateCopy =
nullptr;
1520 Data.Modifier = Modifier;
1522 DSAInfo &
Data = getTopOfStack().SharingMap[D];
1523 assert(
Data.Attributes == OMPC_unknown || (A ==
Data.Attributes) ||
1524 (A == OMPC_firstprivate &&
Data.Attributes == OMPC_lastprivate) ||
1525 (A == OMPC_lastprivate &&
Data.Attributes == OMPC_firstprivate) ||
1526 (isLoopControlVariable(D).first && A == OMPC_private));
1527 Data.Modifier = Modifier;
1528 if (A == OMPC_lastprivate &&
Data.Attributes == OMPC_firstprivate) {
1529 Data.RefExpr.setInt(
true);
1532 const bool IsLastprivate =
1533 A == OMPC_lastprivate ||
Data.Attributes == OMPC_lastprivate;
1534 Data.Attributes = A;
1535 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1536 Data.PrivateCopy = PrivateCopy;
1537 Data.AppliedToPointee = AppliedToPointee;
1539 DSAInfo &
Data = getTopOfStack().SharingMap[PrivateCopy->
getDecl()];
1540 Data.Modifier = Modifier;
1541 Data.Attributes = A;
1542 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1543 Data.PrivateCopy =
nullptr;
1544 Data.AppliedToPointee = AppliedToPointee;
1551 StringRef Name,
const AttrVec *Attrs =
nullptr,
1566 OMPReferencedVarAttr::CreateImplicit(SemaRef.
Context, OrigRef));
1573 bool RefersToCapture =
false) {
1584 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1586 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1587 "Additional reduction info may be specified only for reduction items.");
1588 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1589 assert(ReductionData.ReductionRange.isInvalid() &&
1590 (getTopOfStack().
Directive == OMPD_taskgroup ||
1594 "Additional reduction info may be specified only once for reduction "
1596 ReductionData.set(BOK, SR);
1597 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1598 if (!TaskgroupReductionRef) {
1601 TaskgroupReductionRef =
1607 const Expr *ReductionRef) {
1609 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1611 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1612 "Additional reduction info may be specified only for reduction items.");
1613 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1614 assert(ReductionData.ReductionRange.isInvalid() &&
1615 (getTopOfStack().
Directive == OMPD_taskgroup ||
1619 "Additional reduction info may be specified only once for reduction "
1621 ReductionData.set(ReductionRef, SR);
1622 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1623 if (!TaskgroupReductionRef) {
1626 TaskgroupReductionRef =
1631const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1633 Expr *&TaskgroupDescriptor)
const {
1635 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty.");
1636 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1637 const DSAInfo &
Data = I->SharingMap.lookup(D);
1638 if (
Data.Attributes != OMPC_reduction ||
1639 Data.Modifier != OMPC_REDUCTION_task)
1641 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1642 if (!ReductionData.ReductionOp ||
1643 ReductionData.ReductionOp.is<
const Expr *>())
1644 return DSAVarData();
1645 SR = ReductionData.ReductionRange;
1646 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1647 assert(I->TaskgroupReductionRef &&
"taskgroup reduction reference "
1648 "expression for the descriptor is not "
1650 TaskgroupDescriptor = I->TaskgroupReductionRef;
1651 return DSAVarData(I->Directive, OMPC_reduction,
Data.RefExpr.getPointer(),
1652 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1655 return DSAVarData();
1658const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1660 Expr *&TaskgroupDescriptor)
const {
1662 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty.");
1663 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1664 const DSAInfo &
Data = I->SharingMap.lookup(D);
1665 if (
Data.Attributes != OMPC_reduction ||
1666 Data.Modifier != OMPC_REDUCTION_task)
1668 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1669 if (!ReductionData.ReductionOp ||
1670 !ReductionData.ReductionOp.is<
const Expr *>())
1671 return DSAVarData();
1672 SR = ReductionData.ReductionRange;
1673 ReductionRef = ReductionData.ReductionOp.get<
const Expr *>();
1674 assert(I->TaskgroupReductionRef &&
"taskgroup reduction reference "
1675 "expression for the descriptor is not "
1677 TaskgroupDescriptor = I->TaskgroupReductionRef;
1678 return DSAVarData(I->Directive, OMPC_reduction,
Data.RefExpr.getPointer(),
1679 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1682 return DSAVarData();
1685bool DSAStackTy::isOpenMPLocal(
VarDecl *D, const_iterator I)
const {
1687 for (const_iterator E = end(); I != E; ++I) {
1688 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1692 Scope *CurScope = getCurScope();
1693 while (CurScope && CurScope != TopScope && !CurScope->
isDeclScope(D))
1695 return CurScope != TopScope;
1698 if (I->Context == DC)
1707 bool AcceptIfMutable =
true,
1708 bool *IsClassType =
nullptr) {
1710 Type =
Type.getNonReferenceType().getCanonicalType();
1711 bool IsConstant =
Type.isConstant(Context);
1716 if (
const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1718 RD = CTD->getTemplatedDecl();
1721 return IsConstant && !(SemaRef.
getLangOpts().CPlusPlus && RD &&
1728 bool AcceptIfMutable =
true,
1729 bool ListItemNotVar =
false) {
1733 unsigned Diag = ListItemNotVar ? diag::err_omp_const_list_item
1734 : IsClassType ? diag::err_omp_const_not_mutable_variable
1735 : diag::err_omp_const_variable;
1736 SemaRef.
Diag(ELoc,
Diag) << getOpenMPClauseName(CKind);
1737 if (!ListItemNotVar && D) {
1738 const VarDecl *VD = dyn_cast<VarDecl>(D);
1742 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1750const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(
ValueDecl *D,
1755 auto *VD = dyn_cast<VarDecl>(D);
1756 auto TI = Threadprivates.find(D);
1757 if (TI != Threadprivates.end()) {
1758 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1759 DVar.CKind = OMPC_threadprivate;
1760 DVar.Modifier = TI->getSecond().Modifier;
1763 if (VD && VD->
hasAttr<OMPThreadPrivateDeclAttr>()) {
1766 VD->
getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1767 DVar.CKind = OMPC_threadprivate;
1768 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1775 !(VD->
hasAttr<OMPThreadPrivateDeclAttr>() &&
1782 DVar.CKind = OMPC_threadprivate;
1783 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1788 !isLoopControlVariable(D).first) {
1789 const_iterator IterTarget =
1790 std::find_if(begin(), end(), [](
const SharingMapTy &
Data) {
1793 if (IterTarget != end()) {
1794 const_iterator ParentIterTarget = IterTarget + 1;
1795 for (const_iterator
Iter = begin();
Iter != ParentIterTarget; ++
Iter) {
1796 if (isOpenMPLocal(VD,
Iter)) {
1800 DVar.CKind = OMPC_threadprivate;
1804 if (!isClauseParsingMode() || IterTarget != begin()) {
1805 auto DSAIter = IterTarget->SharingMap.find(D);
1806 if (DSAIter != IterTarget->SharingMap.end() &&
1808 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1809 DVar.CKind = OMPC_threadprivate;
1812 const_iterator End = end();
1814 D, std::distance(ParentIterTarget, End),
1818 IterTarget->ConstructLoc);
1819 DVar.CKind = OMPC_threadprivate;
1839 const_iterator I = begin();
1840 const_iterator EndI = end();
1841 if (FromParent && I != EndI)
1844 auto It = I->SharingMap.find(D);
1845 if (It != I->SharingMap.end()) {
1846 const DSAInfo &
Data = It->getSecond();
1847 DVar.RefExpr =
Data.RefExpr.getPointer();
1848 DVar.PrivateCopy =
Data.PrivateCopy;
1849 DVar.CKind =
Data.Attributes;
1850 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1851 DVar.DKind = I->Directive;
1852 DVar.Modifier =
Data.Modifier;
1853 DVar.AppliedToPointee =
Data.AppliedToPointee;
1858 DVar.CKind = OMPC_shared;
1865 if (SemaRef.
LangOpts.OpenMP <= 31) {
1873 DSAVarData DVarTemp = hasInnermostDSA(
1876 return C == OMPC_firstprivate ||
C == OMPC_shared;
1878 MatchesAlways, FromParent);
1879 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1882 DVar.CKind = OMPC_shared;
1889 const_iterator I = begin();
1890 const_iterator EndI = end();
1891 if (FromParent && I != EndI)
1895 auto It = I->SharingMap.find(D);
1896 if (It != I->SharingMap.end()) {
1897 const DSAInfo &
Data = It->getSecond();
1898 DVar.RefExpr =
Data.RefExpr.getPointer();
1899 DVar.PrivateCopy =
Data.PrivateCopy;
1900 DVar.CKind =
Data.Attributes;
1901 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1902 DVar.DKind = I->Directive;
1903 DVar.Modifier =
Data.Modifier;
1904 DVar.AppliedToPointee =
Data.AppliedToPointee;
1910const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(
ValueDecl *D,
1911 bool FromParent)
const {
1912 if (isStackEmpty()) {
1914 return getDSA(I, D);
1917 const_iterator StartI = begin();
1918 const_iterator EndI = end();
1919 if (FromParent && StartI != EndI)
1921 return getDSA(StartI, D);
1924const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(
ValueDecl *D,
1925 unsigned Level)
const {
1926 if (getStackSize() <= Level)
1927 return DSAVarData();
1929 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1930 return getDSA(StartI, D);
1933const DSAStackTy::DSAVarData
1936 DefaultDataSharingAttributes)>
1939 bool FromParent)
const {
1943 const_iterator I = begin();
1944 const_iterator EndI = end();
1945 if (FromParent && I != EndI)
1947 for (; I != EndI; ++I) {
1948 if (!DPred(I->Directive) &&
1949 !isImplicitOrExplicitTaskingRegion(I->Directive))
1951 const_iterator NewI = I;
1952 DSAVarData DVar = getDSA(NewI, D);
1953 if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee, I->DefaultAttr))
1959const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1962 bool FromParent)
const {
1966 const_iterator StartI = begin();
1967 const_iterator EndI = end();
1968 if (FromParent && StartI != EndI)
1970 if (StartI == EndI || !DPred(StartI->Directive))
1972 const_iterator NewI = StartI;
1973 DSAVarData DVar = getDSA(NewI, D);
1974 return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1979bool DSAStackTy::hasExplicitDSA(
1982 unsigned Level,
bool NotLastprivate)
const {
1983 if (getStackSize() <= Level)
1986 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1987 auto I = StackElem.SharingMap.find(D);
1988 if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1989 CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1990 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1993 auto LI = StackElem.LCVMap.find(D);
1994 if (LI != StackElem.LCVMap.end())
1995 return CPred(OMPC_private,
false);
1999bool DSAStackTy::hasExplicitDirective(
2001 unsigned Level)
const {
2002 if (getStackSize() <= Level)
2004 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
2005 return DPred(StackElem.Directive);
2008bool DSAStackTy::hasDirective(
2012 bool FromParent)
const {
2014 size_t Skip = FromParent ? 2 : 1;
2015 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
2017 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
2023void SemaOpenMP::InitDataSharingAttributesStack() {
2024 VarDataSharingAttributesStack =
new DSAStackTy(
SemaRef);
2027#define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
2029void SemaOpenMP::pushOpenMPFunctionRegion() {
DSAStack->pushFunction(); }
2037 "Expected OpenMP device compilation.");
2043enum class FunctionEmissionStatus {
2054 "Expected OpenMP device compilation.");
2056 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
2061 Kind = SemaDiagnosticBuilder::K_Immediate;
2072 ? SemaDiagnosticBuilder::K_Deferred
2073 : SemaDiagnosticBuilder::K_Immediate;
2077 Kind = SemaDiagnosticBuilder::K_Nop;
2080 llvm_unreachable(
"CUDADiscarded unexpected in OpenMP device compilation");
2092 "Expected OpenMP host compilation.");
2094 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
2099 Kind = SemaDiagnosticBuilder::K_Immediate;
2102 Kind = SemaDiagnosticBuilder::K_Deferred;
2107 Kind = SemaDiagnosticBuilder::K_Nop;
2117 if (LO.OpenMP <= 45) {
2119 return OMPC_DEFAULTMAP_scalar;
2120 return OMPC_DEFAULTMAP_aggregate;
2123 return OMPC_DEFAULTMAP_pointer;
2125 return OMPC_DEFAULTMAP_scalar;
2126 return OMPC_DEFAULTMAP_aggregate;
2130 unsigned OpenMPCaptureLevel)
const {
2131 assert(
getLangOpts().OpenMP &&
"OpenMP is not allowed");
2134 bool IsByRef =
true;
2140 bool IsVariableUsedInMapClause =
false;
2202 bool IsVariableAssociatedWithSection =
false;
2204 DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2206 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection,
2213 if (WhereFoundClauseKind != OMPC_map &&
2214 WhereFoundClauseKind != OMPC_has_device_addr)
2217 auto EI = MapExprComponents.rbegin();
2218 auto EE = MapExprComponents.rend();
2220 assert(EI != EE &&
"Invalid map expression!");
2222 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2223 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2228 auto Last = std::prev(EE);
2230 dyn_cast<UnaryOperator>(
Last->getAssociatedExpression());
2231 if ((UO && UO->getOpcode() == UO_Deref) ||
2232 isa<ArraySubscriptExpr>(
Last->getAssociatedExpression()) ||
2233 isa<ArraySectionExpr>(
Last->getAssociatedExpression()) ||
2234 isa<MemberExpr>(EI->getAssociatedExpression()) ||
2235 isa<OMPArrayShapingExpr>(
Last->getAssociatedExpression())) {
2236 IsVariableAssociatedWithSection =
true;
2245 if (IsVariableUsedInMapClause) {
2248 IsByRef = !(Ty->
isPointerType() && IsVariableAssociatedWithSection);
2253 IsByRef = (
DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2256 DSAStack->isDefaultmapCapturedByRef(
2261 return K == OMPC_reduction && !AppliedToPointee;
2269 ((IsVariableUsedInMapClause &&
2270 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2275 return K == OMPC_firstprivate ||
2276 (K == OMPC_reduction && AppliedToPointee);
2279 DSAStack->isUsesAllocatorsDecl(Level, D))) &&
2282 !(isa<OMPCapturedExprDecl>(D) && !D->
hasAttr<OMPCaptureNoInitAttr>() &&
2283 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2286 !((
DSAStack->getDefaultDSA() == DSA_firstprivate ||
2287 DSAStack->getDefaultDSA() == DSA_private) &&
2291 !
DSAStack->isLoopControlVariable(D, Level).first);
2308unsigned SemaOpenMP::getOpenMPNestingLevel()
const {
2310 return DSAStack->getNestingLevel();
2320 !
DSAStack->isClauseParsingMode()) ||
2331 if (!dyn_cast<FieldDecl>(D))
2333 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2336 DefaultDataSharingAttributes DefaultAttr) {
2338 (DefaultAttr == DSA_firstprivate || DefaultAttr == DSA_private);
2342 if (DVarPrivate.CKind != OMPC_unknown)
2348 Expr *CaptureExpr,
bool WithInit,
2354 assert(
getLangOpts().OpenMP &&
"OpenMP is not allowed");
2357 auto *VD = dyn_cast<VarDecl>(D);
2366 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2376 DSAStackTy::DSAVarData DVarTop =
2378 if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr)
2383 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2390 if (!isa<CapturingScopeInfo>(FSI))
2392 if (
auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2398 assert(CSI &&
"Failed to find CapturedRegionScopeInfo");
2409 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2415 if (CheckScopeInfo) {
2416 bool OpenMPFound =
false;
2417 for (
unsigned I = StopAt + 1; I > 0; --I) {
2419 if (!isa<CapturingScopeInfo>(FSI))
2421 if (
auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2431 if (
DSAStack->getCurrentDirective() != OMPD_unknown &&
2432 (!
DSAStack->isClauseParsingMode() ||
2433 DSAStack->getParentDirective() != OMPD_unknown)) {
2434 auto &&Info =
DSAStack->isLoopControlVariable(D);
2437 isImplicitOrExplicitTaskingRegion(
DSAStack->getCurrentDirective())) ||
2438 (VD &&
DSAStack->isForceVarCapturing()))
2439 return VD ? VD : Info.second;
2440 DSAStackTy::DSAVarData DVarTop =
2442 if (DVarTop.CKind != OMPC_unknown &&
isOpenMPPrivate(DVarTop.CKind) &&
2444 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2450 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2458 if (VD && !VD->
hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2459 ((
DSAStack->getDefaultDSA() != DSA_none &&
2460 DSAStack->getDefaultDSA() != DSA_private &&
2461 DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2462 DVarTop.CKind == OMPC_shared))
2464 auto *FD = dyn_cast<FieldDecl>(D);
2465 if (DVarPrivate.CKind != OMPC_unknown && !VD && FD &&
2466 !DVarPrivate.PrivateCopy) {
2467 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2470 DefaultDataSharingAttributes DefaultAttr) {
2472 (DefaultAttr == DSA_firstprivate ||
2473 DefaultAttr == DSA_private);
2477 if (DVarPrivate.CKind == OMPC_unknown)
2500 VD = cast<VarDecl>(VDPrivateRefExpr->
getDecl());
2501 DSAStack->addImplicitDefaultFirstprivateFD(FD, VD);
2504 if (DVarPrivate.CKind != OMPC_unknown ||
2505 (VD && (
DSAStack->getDefaultDSA() == DSA_none ||
2506 DSAStack->getDefaultDSA() == DSA_private ||
2507 DSAStack->getDefaultDSA() == DSA_firstprivate)))
2508 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2513void SemaOpenMP::adjustOpenMPTargetScopeIndex(
unsigned &FunctionScopesIndex,
2514 unsigned Level)
const {
2519 assert(
getLangOpts().OpenMP &&
"OpenMP must be enabled.");
2525 assert(
getLangOpts().OpenMP &&
"OpenMP must be enabled.");
2527 DSAStack->resetPossibleLoopCounter();
2533 unsigned CapLevel)
const {
2534 assert(
getLangOpts().OpenMP &&
"OpenMP is not allowed");
2535 if (
DSAStack->getCurrentDirective() != OMPD_unknown &&
2536 (!
DSAStack->isClauseParsingMode() ||
2537 DSAStack->getParentDirective() != OMPD_unknown)) {
2538 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2541 DefaultDataSharingAttributes DefaultAttr) {
2543 DefaultAttr == DSA_private;
2547 if (DVarPrivate.CKind == OMPC_private && isa<OMPCapturedExprDecl>(D) &&
2548 DSAStack->isImplicitDefaultFirstprivateFD(cast<VarDecl>(D)) &&
2549 !
DSAStack->isLoopControlVariable(D).first)
2550 return OMPC_private;
2553 bool IsTriviallyCopyable =
2564 (IsTriviallyCopyable ||
2570 return OMPC_firstprivate;
2571 DSAStackTy::DSAVarData DVar =
DSAStack->getImplicitDSA(D, Level);
2572 if (DVar.CKind != OMPC_shared &&
2573 !
DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2574 DSAStack->addImplicitTaskFirstprivate(Level, D);
2575 return OMPC_firstprivate;
2582 DSAStack->resetPossibleLoopCounter(D);
2584 return OMPC_private;
2587 DSAStack->isLoopControlVariable(D).first) &&
2592 return OMPC_private;
2594 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
2600 return OMPC_private;
2605 DSAStack->isUsesAllocatorsDecl(Level, D).value_or(
2606 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2607 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2608 return OMPC_private;
2612 (
DSAStack->isClauseParsingMode() &&
2613 DSAStack->getClauseParsingMode() == OMPC_private) ||
2618 return K == OMPD_taskgroup ||
2619 ((isOpenMPParallelDirective(K) ||
2620 isOpenMPWorksharingDirective(K)) &&
2621 !isOpenMPSimdDirective(K));
2624 DSAStack->isTaskgroupReductionRef(D, Level)))
2631 assert(
getLangOpts().OpenMP &&
"OpenMP is not allowed");
2634 for (
unsigned I =
DSAStack->getNestingLevel() + 1; I > Level; --I) {
2635 const unsigned NewLevel = I - 1;
2639 if (isOpenMPPrivate(K) && !AppliedToPointee) {
2647 if (
DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2657 if (
DSAStack->mustBeFirstprivateAtLevel(
2659 OMPC = OMPC_firstprivate;
2663 if (OMPC != OMPC_unknown)
2665 OMPCaptureKindAttr::CreateImplicit(getASTContext(),
unsigned(OMPC)));
2669 unsigned CaptureLevel)
const {
2670 assert(
getLangOpts().OpenMP &&
"OpenMP is not allowed");
2675 const auto *VD = dyn_cast<VarDecl>(D);
2679 Regions[CaptureLevel] != OMPD_task;
2683 unsigned CaptureLevel)
const {
2684 assert(
getLangOpts().OpenMP &&
"OpenMP is not allowed");
2687 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
2691 DSAStackTy::DSAVarData TopDVar =
2693 unsigned NumLevels =
2698 return (NumLevels == CaptureLevel + 1 &&
2699 (TopDVar.CKind != OMPC_shared ||
2700 DSAStack->getDefaultDSA() == DSA_firstprivate));
2703 DSAStackTy::DSAVarData DVar =
DSAStack->getImplicitDSA(D, Level);
2704 if (DVar.CKind != OMPC_shared)
2706 }
while (Level > 0);
2712void SemaOpenMP::DestroyDataSharingAttributesStack() {
delete DSAStack; }
2716 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2721 "Not in OpenMP declare variant scope!");
2723 OMPDeclareVariantScopes.pop_back();
2729 assert(
getLangOpts().OpenMP &&
"Expected OpenMP compilation mode.");
2730 std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2734 (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host))
2737 if (!
getLangOpts().OpenMPIsTargetDevice && DevTy &&
2738 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2741 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2742 if (
getLangOpts().OpenMPIsTargetDevice && DevTy &&
2743 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2745 StringRef HostDevTy =
2747 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2748 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2749 diag::note_omp_marked_device_type_here)
2755 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2759 for (OMPDeclareVariantAttr *A :
2760 Callee->specific_attrs<OMPDeclareVariantAttr>()) {
2761 auto *DeclRefVariant = cast<DeclRefExpr>(A->getVariantFuncRef());
2762 auto *VariantFD = cast<FunctionDecl>(DeclRefVariant->getDecl());
2763 std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2764 OMPDeclareTargetDeclAttr::getDeviceType(
2765 VariantFD->getMostRecentDecl());
2766 if (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2772 Callee->hasAttr<OMPDeclareVariantAttr>() && HasHostAttr(Callee))
2776 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2777 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2778 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2779 diag::note_omp_marked_device_type_here)
2787 DSAStack->push(DKind, DirName, CurScope, Loc);
2797 DSAStack->setClauseParsingMode(OMPC_unknown);
2801static std::pair<ValueDecl *, bool>
2803 SourceRange &ERange,
bool AllowArraySection =
false,
2804 StringRef DiagType =
"");
2809 bool InscanFound =
false;
2816 if (
C->getClauseKind() != OMPC_reduction)
2818 auto *RC = cast<OMPReductionClause>(
C);
2819 if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2821 InscanLoc = RC->getModifierLoc();
2824 if (RC->getModifier() == OMPC_REDUCTION_task) {
2834 S.
Diag(RC->getModifierLoc(),
2835 diag::err_omp_reduction_task_not_parallel_or_worksharing);
2841 if (
C->getClauseKind() != OMPC_reduction)
2843 auto *RC = cast<OMPReductionClause>(
C);
2844 if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2847 : RC->getModifierLoc(),
2848 diag::err_omp_inscan_reduction_expected);
2849 S.
Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2852 for (
Expr *Ref : RC->varlists()) {
2853 assert(Ref &&
"NULL expr in OpenMP nontemporal clause.");
2856 Expr *SimpleRefExpr = Ref;
2863 S.
Diag(Ref->getExprLoc(),
2864 diag::err_omp_reduction_not_inclusive_exclusive)
2865 << Ref->getSourceRange();
2879 const DSAStackTy::DSAVarData &DVar,
2880 bool IsLoopIterVar =
false);
2888 if (
const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2890 if (
auto *Clause = dyn_cast<OMPLastprivateClause>(
C)) {
2892 for (
Expr *DE : Clause->varlists()) {
2893 if (DE->isValueDependent() || DE->isTypeDependent()) {
2894 PrivateCopies.push_back(
nullptr);
2897 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2898 auto *VD = cast<VarDecl>(DRE->getDecl());
2900 const DSAStackTy::DSAVarData DVar =
2902 if (DVar.CKind == OMPC_lastprivate) {
2909 SemaRef, DE->getExprLoc(),
Type.getUnqualifiedType(),
2913 PrivateCopies.push_back(
nullptr);
2921 PrivateCopies.push_back(
nullptr);
2924 Clause->setPrivateCopies(PrivateCopies);
2928 if (
auto *Clause = dyn_cast<OMPNontemporalClause>(
C)) {
2930 for (
Expr *RefExpr : Clause->varlists()) {
2931 assert(RefExpr &&
"NULL expr in OpenMP nontemporal clause.");
2934 Expr *SimpleRefExpr = RefExpr;
2938 PrivateRefs.push_back(RefExpr);
2943 const DSAStackTy::DSAVarData DVar =
2945 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2948 Clause->setPrivateRefs(PrivateRefs);
2951 if (
auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(
C)) {
2952 for (
unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2958 if (!VD || !isa<VarDecl>(VD))
2960 DSAStackTy::DSAVarData DVar =
2966 Expr *MapExpr =
nullptr;
2968 DSAStack->checkMappableExprComponentListsForDecl(
2974 auto MI = MapExprComponents.rbegin();
2975 auto ME = MapExprComponents.rend();
2977 MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2978 VD->getCanonicalDecl()) {
2979 MapExpr = MI->getAssociatedExpression();
2984 Diag(D.Allocator->getExprLoc(),
2985 diag::err_omp_allocator_used_in_clauses)
2990 Diag(MapExpr->getExprLoc(), diag::note_used_here)
2991 << MapExpr->getSourceRange();
3009 Expr *NumIterations,
Sema &SemaRef,
3010 Scope *S, DSAStackTy *Stack);
3019 explicit VarDeclFilterCCC(
Sema &S) : SemaRef(S) {}
3020 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
3022 if (
const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
3030 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
3031 return std::make_unique<VarDeclFilterCCC>(*
this);
3040 explicit VarOrFuncDeclFilterCCC(
Sema &S) : SemaRef(S) {}
3041 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
3043 if (ND && ((isa<VarDecl>(ND) && ND->
getKind() == Decl::Var) ||
3044 isa<FunctionDecl>(ND))) {
3051 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
3052 return std::make_unique<VarOrFuncDeclFilterCCC>(*
this);
3071 VarDeclFilterCCC CCC(
SemaRef);
3078 : diag::err_omp_expected_var_arg_suggest)
3080 VD = Corrected.getCorrectionDeclAs<
VarDecl>();
3082 Diag(
Id.getLoc(), Lookup.
empty() ? diag::err_undeclared_var_use
3083 : diag::err_omp_expected_var_arg)
3088 Diag(
Id.getLoc(), diag::err_omp_expected_var_arg) <<
Id.getName();
3097 Diag(
Id.getLoc(), diag::err_omp_global_var_arg)
3102 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3114 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3115 << getOpenMPDirectiveName(Kind) << VD;
3119 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3129 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3130 << getOpenMPDirectiveName(Kind) << VD;
3134 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3146 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3147 << getOpenMPDirectiveName(Kind) << VD;
3151 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3160 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3161 << getOpenMPDirectiveName(Kind) << VD;
3165 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3173 if (Kind == OMPD_threadprivate && VD->
isUsed() &&
3175 Diag(
Id.getLoc(), diag::err_omp_var_used)
3176 << getOpenMPDirectiveName(Kind) << VD;
3198class LocalVarRefChecker final
3204 if (
const auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
3207 diag::err_omp_local_var_in_threadprivate_init)
3209 SemaRef.Diag(VD->
getLocation(), diag::note_defined_here)
3216 bool VisitStmt(
const Stmt *S) {
3217 for (
const Stmt *Child : S->children()) {
3218 if (Child && Visit(Child))
3223 explicit LocalVarRefChecker(
Sema &SemaRef) : SemaRef(SemaRef) {}
3232 for (
Expr *RefExpr : VarList) {
3233 auto *DE = cast<DeclRefExpr>(RefExpr);
3234 auto *VD = cast<VarDecl>(DE->getDecl());
3251 ILoc, VD->
getType(), diag::err_omp_threadprivate_incomplete_type)) {
3258 Diag(ILoc, diag::err_omp_ref_type_arg)
3259 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->
getType();
3263 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3271 !(VD->
hasAttr<OMPThreadPrivateDeclAttr>() &&
3276 Diag(ILoc, diag::err_omp_var_thread_local)
3281 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3289 LocalVarRefChecker Checker(
SemaRef);
3290 if (Checker.Visit(
Init))
3294 Vars.push_back(RefExpr);
3295 DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3296 VD->
addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3299 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3302 if (!Vars.empty()) {
3310static OMPAllocateDeclAttr::AllocatorTypeTy
3313 return OMPAllocateDeclAttr::OMPNullMemAlloc;
3314 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3315 Allocator->isInstantiationDependent() ||
3316 Allocator->containsUnexpandedParameterPack())
3317 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3318 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3319 llvm::FoldingSetNodeID AEId;
3320 const Expr *AE = Allocator->IgnoreParenImpCasts();
3322 for (
int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3323 auto AllocatorKind =
static_cast<OMPAllocateDeclAttr::AllocatorTypeTy
>(I);
3324 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3325 llvm::FoldingSetNodeID DAEId;
3328 if (AEId == DAEId) {
3329 AllocatorKindRes = AllocatorKind;
3333 return AllocatorKindRes;
3338 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
Expr *Allocator) {
3339 if (!VD->
hasAttr<OMPAllocateDeclAttr>())
3341 const auto *A = VD->
getAttr<OMPAllocateDeclAttr>();
3342 Expr *PrevAllocator = A->getAllocator();
3343 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3345 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3346 if (AllocatorsMatch &&
3347 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3348 Allocator && PrevAllocator) {
3349 const Expr *AE = Allocator->IgnoreParenImpCasts();
3351 llvm::FoldingSetNodeID AEId, PAEId;
3354 AllocatorsMatch = AEId == PAEId;
3356 if (!AllocatorsMatch) {
3358 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3362 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3364 PrevAllocator->printPretty(PrevAllocatorStream,
nullptr,
3368 Allocator ? Allocator->getExprLoc() : RefExpr->
getExprLoc();
3370 Allocator ? Allocator->getSourceRange() : RefExpr->
getSourceRange();
3372 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3374 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3375 S.
Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3376 << (Allocator ? 1 : 0) << AllocatorStream.str()
3377 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3379 S.
Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3380 << PrevAllocatorRange;
3388 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3390 if (VD->
hasAttr<OMPAllocateDeclAttr>())
3399 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3400 Allocator->isInstantiationDependent() ||
3401 Allocator->containsUnexpandedParameterPack()))
3403 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.
Context, AllocatorKind,
3404 Allocator, Alignment, SR);
3407 ML->DeclarationMarkedOpenMPAllocate(VD, A);
3413 assert(Clauses.size() <= 2 &&
"Expected at most two clauses.");
3414 Expr *Alignment =
nullptr;
3415 Expr *Allocator =
nullptr;
3416 if (Clauses.empty()) {
3426 if (
const auto *AC = dyn_cast<OMPAllocatorClause>(
C))
3427 Allocator = AC->getAllocator();
3428 else if (
const auto *AC = dyn_cast<OMPAlignClause>(
C))
3429 Alignment = AC->getAlignment();
3431 llvm_unreachable(
"Unexpected clause on allocate directive");
3433 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3436 for (
Expr *RefExpr : VarList) {
3437 auto *DE = cast<DeclRefExpr>(RefExpr);
3438 auto *VD = cast<VarDecl>(DE->getDecl());
3442 VD->
hasAttr<OMPThreadPrivateDeclAttr>() ||
3450 AllocatorKind, Allocator))
3458 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3459 Diag(Allocator->getExprLoc(),
3460 diag::err_omp_expected_predefined_allocator)
3461 << Allocator->getSourceRange();
3465 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3471 Vars.push_back(RefExpr);
3490 Diag(Loc, diag::err_omp_invalid_scope) <<
"requires";
3504 bool SkippedClauses) {
3505 if (!SkippedClauses && Assumptions.empty())
3506 Diag(Loc, diag::err_omp_no_clause_for_directive)
3507 << llvm::omp::getAllAssumeClauseOptions()
3508 << llvm::omp::getOpenMPDirectiveName(DKind);
3511 OMPAssumeAttr::Create(
getASTContext(), llvm::join(Assumptions,
","), Loc);
3512 if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3513 OMPAssumeScoped.push_back(AA);
3518 if (Assumptions.empty())
3521 assert(DKind == llvm::omp::Directive::OMPD_assumes &&
3522 "Unexpected omp assumption directive!");
3523 OMPAssumeGlobal.push_back(AA);
3531 while (Ctx->getLexicalParent())
3533 DeclContexts.push_back(Ctx);
3534 while (!DeclContexts.empty()) {
3536 for (
auto *SubDC : DC->
decls()) {
3537 if (SubDC->isInvalidDecl())
3539 if (
auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3540 DeclContexts.push_back(CTD->getTemplatedDecl());
3541 llvm::append_range(DeclContexts, CTD->specializations());
3544 if (
auto *DC = dyn_cast<DeclContext>(SubDC))
3545 DeclContexts.push_back(DC);
3546 if (
auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3556 OMPAssumeScoped.pop_back();
3566 DSAStack->getEncounteredTargetLocs();
3568 if (!TargetLocations.empty() || !AtomicLoc.
isInvalid()) {
3569 for (
const OMPClause *CNew : ClauseList) {
3571 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3572 isa<OMPUnifiedAddressClause>(CNew) ||
3573 isa<OMPReverseOffloadClause>(CNew) ||
3574 isa<OMPDynamicAllocatorsClause>(CNew)) {
3575 Diag(Loc, diag::err_omp_directive_before_requires)
3576 <<
"target" << getOpenMPClauseName(CNew->getClauseKind());
3578 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3582 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3583 Diag(Loc, diag::err_omp_directive_before_requires)
3584 <<
"atomic" << getOpenMPClauseName(CNew->getClauseKind());
3585 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3591 if (!
DSAStack->hasDuplicateRequiresClause(ClauseList))
3599 const DSAStackTy::DSAVarData &DVar,
3600 bool IsLoopIterVar) {
3602 SemaRef.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3603 << getOpenMPClauseName(DVar.CKind);
3607 PDSA_StaticMemberShared,
3608 PDSA_StaticLocalVarShared,
3609 PDSA_LoopIterVarPrivate,
3610 PDSA_LoopIterVarLinear,
3611 PDSA_LoopIterVarLastprivate,
3612 PDSA_ConstVarShared,
3613 PDSA_GlobalVarShared,
3614 PDSA_TaskVarFirstprivate,
3615 PDSA_LocalVarPrivate,
3617 } Reason = PDSA_Implicit;
3618 bool ReportHint =
false;
3620 auto *VD = dyn_cast<VarDecl>(D);
3621 if (IsLoopIterVar) {
3622 if (DVar.CKind == OMPC_private)
3623 Reason = PDSA_LoopIterVarPrivate;
3624 else if (DVar.CKind == OMPC_lastprivate)
3625 Reason = PDSA_LoopIterVarLastprivate;
3627 Reason = PDSA_LoopIterVarLinear;
3629 DVar.CKind == OMPC_firstprivate) {
3630 Reason = PDSA_TaskVarFirstprivate;
3631 ReportLoc = DVar.ImplicitDSALoc;
3633 Reason = PDSA_StaticLocalVarShared;
3635 Reason = PDSA_StaticMemberShared;
3637 Reason = PDSA_GlobalVarShared;
3639 Reason = PDSA_ConstVarShared;
3640 else if (VD && VD->
isLocalVarDecl() && DVar.CKind == OMPC_private) {
3642 Reason = PDSA_LocalVarPrivate;
3644 if (Reason != PDSA_Implicit) {
3645 SemaRef.
Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3646 << Reason << ReportHint
3647 << getOpenMPDirectiveName(Stack->getCurrentDirective());
3648 }
else if (DVar.ImplicitDSALoc.isValid()) {
3649 SemaRef.
Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3650 << getOpenMPClauseName(DVar.CKind);
3656 bool IsAggregateOrDeclareTarget) {
3659 case OMPC_DEFAULTMAP_MODIFIER_alloc:
3660 Kind = OMPC_MAP_alloc;
3662 case OMPC_DEFAULTMAP_MODIFIER_to:
3665 case OMPC_DEFAULTMAP_MODIFIER_from:
3666 Kind = OMPC_MAP_from;
3668 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3669 Kind = OMPC_MAP_tofrom;
3671 case OMPC_DEFAULTMAP_MODIFIER_present:
3677 Kind = OMPC_MAP_alloc;
3679 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3681 llvm_unreachable(
"Unexpected defaultmap implicit behavior");
3682 case OMPC_DEFAULTMAP_MODIFIER_none:
3683 case OMPC_DEFAULTMAP_MODIFIER_default:
3688 if (IsAggregateOrDeclareTarget) {
3689 Kind = OMPC_MAP_tofrom;
3692 llvm_unreachable(
"Unexpected defaultmap implicit behavior");
3699class DSAAttrChecker final :
public StmtVisitor<DSAAttrChecker, void> {
3702 bool ErrorFound =
false;
3703 bool TryCaptureCXXThisMembers =
false;
3710 ImplicitMapModifier[DefaultmapKindNum];
3712 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3716 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3718 if (S->getDirectiveKind() == OMPD_atomic ||
3719 S->getDirectiveKind() == OMPD_critical ||
3720 S->getDirectiveKind() == OMPD_section ||
3721 S->getDirectiveKind() == OMPD_master ||
3722 S->getDirectiveKind() == OMPD_masked ||
3723 S->getDirectiveKind() == OMPD_scope ||
3725 Visit(S->getAssociatedStmt());
3728 visitSubCaptures(S->getInnermostCapturedStmt());
3731 if (TryCaptureCXXThisMembers ||
3733 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3735 return C.capturesThis();
3737 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3738 TryCaptureCXXThisMembers =
true;
3739 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3740 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3747 if (
auto *FC = dyn_cast<OMPFirstprivateClause>(
C)) {
3748 for (
Expr *Ref : FC->varlists())
3760 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
3763 !Stack->getTopDSA(VD,
false).RefExpr &&
3764 !Stack->isImplicitDefaultFirstprivateFD(VD))) {
3765 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3766 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3767 Visit(CED->getInit());
3770 }
else if (VD->
isImplicit() || isa<OMPCapturedExprDecl>(VD))
3773 if (!Stack->isImplicitDefaultFirstprivateFD(VD))
3778 !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3779 !Stack->isImplicitTaskFirstprivate(VD))
3782 if (Stack->isUsesAllocatorsDecl(VD))
3785 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD,
false);
3787 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3791 std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3792 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3795 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3796 !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3797 !Stack->isImplicitTaskFirstprivate(VD))
3806 if (DVar.CKind == OMPC_unknown &&
3807 (Stack->getDefaultDSA() == DSA_none ||
3808 Stack->getDefaultDSA() == DSA_private ||
3809 Stack->getDefaultDSA() == DSA_firstprivate) &&
3810 isImplicitOrExplicitTaskingRegion(DKind) &&
3811 VarsWithInheritedDSA.count(VD) == 0) {
3812 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3813 if (!InheritedDSA && (Stack->getDefaultDSA() == DSA_firstprivate ||
3814 Stack->getDefaultDSA() == DSA_private)) {
3815 DSAStackTy::DSAVarData DVar =
3816 Stack->getImplicitDSA(VD,
false);
3817 InheritedDSA = DVar.CKind == OMPC_unknown;
3820 VarsWithInheritedDSA[VD] = E;
3821 if (Stack->getDefaultDSA() == DSA_none)
3836 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3837 OMPC_DEFAULTMAP_MODIFIER_none;
3838 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3839 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3843 if (!Stack->checkMappableExprComponentListsForDecl(
3848 auto MI = MapExprComponents.rbegin();
3849 auto ME = MapExprComponents.rend();
3850 return MI != ME && MI->getAssociatedDeclaration() == VD;
3852 VarsWithInheritedDSA[VD] = E;
3858 bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3859 OMPC_DEFAULTMAP_MODIFIER_present;
3860 if (IsModifierPresent) {
3861 if (!llvm::is_contained(ImplicitMapModifier[ClauseKind],
3862 OMPC_MAP_MODIFIER_present)) {
3863 ImplicitMapModifier[ClauseKind].push_back(
3864 OMPC_MAP_MODIFIER_present);
3870 !Stack->isLoopControlVariable(VD).first) {
3871 if (!Stack->checkMappableExprComponentListsForDecl(
3876 if (SemaRef.LangOpts.OpenMP >= 50)
3877 return !StackComponents.empty();
3880 return StackComponents.size() == 1 ||
3882 llvm::drop_begin(llvm::reverse(StackComponents)),
3883 [](const OMPClauseMappableExprCommon::
3884 MappableComponent &MC) {
3885 return MC.getAssociatedDeclaration() ==
3887 (isa<ArraySectionExpr>(
3888 MC.getAssociatedExpression()) ||
3889 isa<OMPArrayShapingExpr>(
3890 MC.getAssociatedExpression()) ||
3891 isa<ArraySubscriptExpr>(
3892 MC.getAssociatedExpression()));
3895 bool IsFirstprivate =
false;
3897 if (
const auto *RD =
3899 IsFirstprivate = RD->isLambda();
3901 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3902 if (IsFirstprivate) {
3903 ImplicitFirstprivate.emplace_back(E);
3906 Stack->getDefaultmapModifier(ClauseKind);
3908 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3909 ImplicitMap[ClauseKind][
Kind].emplace_back(E);
3919 DVar = Stack->hasInnermostDSA(
3922 return C == OMPC_reduction && !AppliedToPointee;
3931 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
3937 DVar = Stack->getImplicitDSA(VD,
false);
3939 (((Stack->getDefaultDSA() == DSA_firstprivate &&
3940 DVar.CKind == OMPC_firstprivate) ||
3941 (Stack->getDefaultDSA() == DSA_private &&
3942 DVar.CKind == OMPC_private)) &&
3944 !Stack->isLoopControlVariable(VD).first) {
3945 if (Stack->getDefaultDSA() == DSA_private)
3946 ImplicitPrivate.push_back(E);
3948 ImplicitFirstprivate.push_back(E);
3955 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3956 Stack->addToParentTargetRegionLinkGlobals(E);
3970 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD,
false);
3973 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3977 !Stack->isLoopControlVariable(FD).first &&
3978 !Stack->checkMappableExprComponentListsForDecl(
3983 return isa<CXXThisExpr>(
3985 StackComponents.back().getAssociatedExpression())
3997 if (Stack->isClassPreviouslyMapped(TE->getType()))
4001 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
4006 ImplicitMap[ClauseKind][
Kind].emplace_back(E);
4015 DVar = Stack->hasInnermostDSA(
4018 return C == OMPC_reduction && !AppliedToPointee;
4027 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
4033 DVar = Stack->getImplicitDSA(FD,
false);
4035 !Stack->isLoopControlVariable(FD).first) {
4040 if (DVar.CKind != OMPC_unknown)
4041 ImplicitFirstprivate.push_back(E);
4048 Stack->getCurrentDirective(),
4051 const auto *VD = cast<ValueDecl>(
4052 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
4053 if (!Stack->checkMappableExprComponentListsForDecl(
4059 auto CCI = CurComponents.rbegin();
4060 auto CCE = CurComponents.rend();
4061 for (const auto &SC : llvm::reverse(StackComponents)) {
4063 if (CCI->getAssociatedExpression()->getStmtClass() !=
4064 SC.getAssociatedExpression()->getStmtClass())
4065 if (!((isa<ArraySectionExpr>(
4066 SC.getAssociatedExpression()) ||
4067 isa<OMPArrayShapingExpr>(
4068 SC.getAssociatedExpression())) &&
4069 isa<ArraySubscriptExpr>(
4070 CCI->getAssociatedExpression())))
4073 const Decl *CCD = CCI->getAssociatedDeclaration();
4074 const Decl *SCD = SC.getAssociatedDeclaration();
4075 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
4076 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
4079 std::advance(CCI, 1);
4087 }
else if (!TryCaptureCXXThisMembers) {
4095 if (isa_and_nonnull<OMPPrivateClause>(
C))
4101 if (
C && !((isa<OMPFirstprivateClause>(
C) || isa<OMPMapClause>(
C)) &&
4104 for (
Stmt *CC :
C->children()) {
4111 VisitSubCaptures(S);
4120 for (
Stmt *
C : S->arguments()) {
4127 if (
Expr *Callee = S->getCallee()) {
4128 auto *CI =
Callee->IgnoreParenImpCasts();
4129 if (
auto *CE = dyn_cast<MemberExpr>(CI))
4130 Visit(CE->getBase());
4131 else if (
auto *CE = dyn_cast<DeclRefExpr>(CI))
4135 void VisitStmt(
Stmt *S) {
4136 for (
Stmt *
C : S->children()) {
4147 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
4149 VarDecl *VD = Cap.getCapturedVar();
4153 Stack->checkMappableExprComponentListsForDecl(
4160 Cap.getLocation(),
true);
4164 bool isErrorFound()
const {
return ErrorFound; }
4166 return ImplicitFirstprivate;
4171 return ImplicitMap[DK][MK];
4175 return ImplicitMapModifier[
Kind];
4178 return VarsWithInheritedDSA;
4182 : Stack(S), SemaRef(SemaRef), ErrorFound(
false), CS(CS) {
4197 Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target);
4199 Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams);
4201 Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel);
4203 Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for);
4205 Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd);
4206 Stack->handleConstructTrait(Traits, ScopeEntry);
4214 case OMPD_parallel_for:
4215 case OMPD_parallel_for_simd:
4216 case OMPD_parallel_sections:
4217 case OMPD_parallel_master:
4218 case OMPD_parallel_masked:
4219 case OMPD_parallel_loop:
4221 case OMPD_teams_distribute:
4222 case OMPD_teams_distribute_simd: {
4227 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4228 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4229 std::make_pair(StringRef(),
QualType())
4235 case OMPD_target_teams:
4236 case OMPD_target_parallel:
4237 case OMPD_target_parallel_for:
4238 case OMPD_target_parallel_for_simd:
4239 case OMPD_target_parallel_loop:
4240 case OMPD_target_teams_distribute:
4241 case OMPD_target_teams_distribute_simd: {
4251 std::make_pair(
".global_tid.", KmpInt32Ty),
4252 std::make_pair(
".part_id.", KmpInt32PtrTy),
4253 std::make_pair(
".privates.", VoidPtrTy),
4258 std::make_pair(StringRef(),
QualType())
4266 AlwaysInlineAttr::CreateImplicit(
4267 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4270 ParamsTarget.push_back(std::make_pair(StringRef(
"dyn_ptr"), VoidPtrTy));
4271 ParamsTarget.push_back(
4272 std::make_pair(StringRef(),
QualType()));
4278 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4279 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4280 std::make_pair(StringRef(),
QualType())
4290 case OMPD_target_simd: {
4300 std::make_pair(
".global_tid.", KmpInt32Ty),
4301 std::make_pair(
".part_id.", KmpInt32PtrTy),
4302 std::make_pair(
".privates.", VoidPtrTy),
4307 std::make_pair(StringRef(),
QualType())
4315 AlwaysInlineAttr::CreateImplicit(
4316 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4319 ParamsTarget.push_back(std::make_pair(StringRef(
"dyn_ptr"), VoidPtrTy));
4320 ParamsTarget.push_back(
4321 std::make_pair(StringRef(),
QualType()));
4343 case OMPD_taskgroup:
4344 case OMPD_distribute:
4345 case OMPD_distribute_simd:
4348 case OMPD_target_data:
4349 case OMPD_dispatch: {
4351 std::make_pair(StringRef(),
QualType())
4367 std::make_pair(
".global_tid.", KmpInt32Ty),
4368 std::make_pair(
".part_id.", KmpInt32PtrTy),
4369 std::make_pair(
".privates.", VoidPtrTy),
4374 std::make_pair(StringRef(),
QualType())
4381 AlwaysInlineAttr::CreateImplicit(
4382 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4386 case OMPD_taskloop_simd:
4387 case OMPD_master_taskloop:
4388 case OMPD_masked_taskloop:
4389 case OMPD_masked_taskloop_simd:
4390 case OMPD_master_taskloop_simd: {
4408 std::make_pair(
".global_tid.", KmpInt32Ty),
4409 std::make_pair(
".part_id.", KmpInt32PtrTy),
4410 std::make_pair(
".privates.", VoidPtrTy),
4415 std::make_pair(
".lb.", KmpUInt64Ty),
4416 std::make_pair(
".ub.", KmpUInt64Ty),
4417 std::make_pair(
".st.", KmpInt64Ty),
4418 std::make_pair(
".liter.", KmpInt32Ty),
4419 std::make_pair(
".reductions.", VoidPtrTy),
4420 std::make_pair(StringRef(),
QualType())
4427 AlwaysInlineAttr::CreateImplicit(
4428 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4431 case OMPD_parallel_masked_taskloop:
4432 case OMPD_parallel_masked_taskloop_simd:
4433 case OMPD_parallel_master_taskloop:
4434 case OMPD_parallel_master_taskloop_simd: {
4448 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4449 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4450 std::make_pair(StringRef(),
QualType())
4461 std::make_pair(
".global_tid.", KmpInt32Ty),
4462 std::make_pair(
".part_id.", KmpInt32PtrTy),
4463 std::make_pair(
".privates.", VoidPtrTy),
4468 std::make_pair(
".lb.", KmpUInt64Ty),
4469 std::make_pair(
".ub.", KmpUInt64Ty),
4470 std::make_pair(
".st.", KmpInt64Ty),
4471 std::make_pair(
".liter.", KmpInt32Ty),
4472 std::make_pair(
".reductions.", VoidPtrTy),
4473 std::make_pair(StringRef(),
QualType())
4481 AlwaysInlineAttr::CreateImplicit(
4482 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4485 case OMPD_distribute_parallel_for_simd:
4486 case OMPD_distribute_parallel_for: {
4491 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4492 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4495 std::make_pair(StringRef(),
QualType())
4503 case OMPD_target_teams_loop:
4504 case OMPD_target_teams_distribute_parallel_for:
4505 case OMPD_target_teams_distribute_parallel_for_simd: {
4516 std::make_pair(
".global_tid.", KmpInt32Ty),
4517 std::make_pair(
".part_id.", KmpInt32PtrTy),
4518 std::make_pair(
".privates.", VoidPtrTy),
4523 std::make_pair(StringRef(),
QualType())
4531 AlwaysInlineAttr::CreateImplicit(
4532 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4535 ParamsTarget.push_back(std::make_pair(StringRef(
"dyn_ptr"), VoidPtrTy));
4536 ParamsTarget.push_back(
4537 std::make_pair(StringRef(),
QualType()));
4544 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4545 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4546 std::make_pair(StringRef(),
QualType())
4554 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4555 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4558 std::make_pair(StringRef(),
QualType())
4568 case OMPD_teams_loop:
4569 case OMPD_teams_distribute_parallel_for:
4570 case OMPD_teams_distribute_parallel_for_simd: {
4576 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4577 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4578 std::make_pair(StringRef(),
QualType())
4586 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4587 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4590 std::make_pair(StringRef(),
QualType())
4599 case OMPD_target_update:
4600 case OMPD_target_enter_data:
4601 case OMPD_target_exit_data: {
4611 std::make_pair(
".global_tid.", KmpInt32Ty),
4612 std::make_pair(
".part_id.", KmpInt32PtrTy),
4613 std::make_pair(
".privates.", VoidPtrTy),
4618 std::make_pair(StringRef(),
QualType())
4625 AlwaysInlineAttr::CreateImplicit(
4626 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4629 case OMPD_threadprivate:
4631 case OMPD_taskyield:
4635 case OMPD_cancellation_point:
4640 case OMPD_declare_reduction:
4641 case OMPD_declare_mapper:
4642 case OMPD_declare_simd:
4643 case OMPD_declare_target:
4644 case OMPD_end_declare_target:
4646 case OMPD_declare_variant:
4647 case OMPD_begin_declare_variant:
4648 case OMPD_end_declare_variant:
4649 case OMPD_metadirective:
4650 llvm_unreachable(
"OpenMP Directive is not allowed");
4653 llvm_unreachable(
"Unknown OpenMP directive");
4659int SemaOpenMP::getNumberOfConstructScopes(
unsigned Level)
const {
4666 return CaptureRegions.size();
4670 Expr *CaptureExpr,
bool WithInit,
4672 bool AsExpression) {
4673 assert(CaptureExpr);
4679 Ty =
C.getLValueReferenceType(Ty);
4681 Ty =
C.getPointerType(Ty);
4693 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(
C));
4704 CD = cast<OMPCapturedExprDecl>(VD);
4743class CaptureRegionUnwinderRAII {
4750 CaptureRegionUnwinderRAII(
Sema &S,
bool &ErrorFound,
4752 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4753 ~CaptureRegionUnwinderRAII() {
4756 while (--ThisCaptureLevel >= 0)
4769 DSAStack->getCurrentDirective()))) {
4771 if (
const auto *RD =
Type.getCanonicalType()
4772 .getNonReferenceType()
4774 bool SavedForceCaptureByReferenceInTargetExecutable =
4775 DSAStack->isForceCaptureByReferenceInTargetExecutable();
4776 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4778 if (RD->isLambda()) {
4779 llvm::DenseMap<const ValueDecl *, FieldDecl *> Captures;
4781 RD->getCaptureFields(Captures, ThisCapture);
4784 VarDecl *VD = cast<VarDecl>(LC.getCapturedVar());
4789 }
else if (LC.getCaptureKind() ==
LCK_This) {
4792 ThisTy, ThisCapture->
getType()))
4797 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4798 SavedForceCaptureByReferenceInTargetExecutable);
4808 for (
const OMPClause *Clause : Clauses) {
4810 Ordered = cast<OMPOrderedClause>(Clause);
4812 Order = cast<OMPOrderClause>(Clause);
4813 if (Order->
getKind() != OMPC_ORDER_concurrent)
4816 if (Ordered && Order)
4820 if (Ordered && Order) {
4822 diag::err_omp_simple_clause_incompatible_with_ordered)
4823 << getOpenMPClauseName(OMPC_order)
4837 if (
DSAStack->getCurrentDirective() == OMPD_atomic ||
4838 DSAStack->getCurrentDirective() == OMPD_critical ||
4839 DSAStack->getCurrentDirective() == OMPD_section ||
4840 DSAStack->getCurrentDirective() == OMPD_master ||
4841 DSAStack->getCurrentDirective() == OMPD_masked)
4844 bool ErrorFound =
false;
4845 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4847 if (!S.isUsable()) {
4862 DSAStack->getCurrentDirective() == OMPD_target) &&
4866 auto *IRC = cast<OMPInReductionClause>(Clause);
4867 for (
Expr *E : IRC->taskgroup_descriptors())
4879 if (
auto *E = cast_or_null<Expr>(VarRef)) {
4883 DSAStack->setForceVarCapturing(
false);
4885 DSAStack->getCurrentDirective())) {
4886 assert(CaptureRegions.empty() &&
4887 "No captured regions in loop transformation directives.");
4888 }
else if (CaptureRegions.size() > 1 ||
4889 CaptureRegions.back() != OMPD_unknown) {
4893 if (
Expr *E =
C->getPostUpdateExpr())
4898 SC = cast<OMPScheduleClause>(Clause);
4900 OC = cast<OMPOrderedClause>(Clause);
4902 LCs.push_back(cast<OMPLinearClause>(Clause));
4913 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4918 diag::err_omp_simple_clause_incompatible_with_ordered)
4919 << getOpenMPClauseName(OMPC_schedule)
4921 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4932 Diag(
C->getBeginLoc(), diag::err_omp_linear_ordered)
4941 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
4948 unsigned CompletedRegions = 0;
4953 if (ThisCaptureRegion != OMPD_unknown) {
4961 if (CaptureRegion == ThisCaptureRegion ||
4962 CaptureRegion == OMPD_unknown) {
4963 if (
auto *DS = cast_or_null<DeclStmt>(
C->getPreInitStmt())) {
4964 for (
Decl *D : DS->decls())
4971 if (ThisCaptureRegion == OMPD_target) {
4975 if (
const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(
C)) {
4976 for (
unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4986 if (ThisCaptureRegion == OMPD_parallel) {
4990 if (
auto *RC = dyn_cast<OMPReductionClause>(
C)) {
4991 if (RC->getModifier() != OMPC_REDUCTION_inscan)
4993 for (
Expr *E : RC->copy_array_temps())
4997 if (
auto *AC = dyn_cast<OMPAlignedClause>(
C)) {
4998 for (
Expr *E : AC->varlists())
5003 if (++CompletedRegions == CaptureRegions.size())
5014 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
5017 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
5018 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
5021 SemaRef.
Diag(StartLoc, diag::err_omp_wrong_cancel_region)
5022 << getOpenMPDirectiveName(CancelRegion);
5032 if (Stack->getCurScope()) {
5035 bool NestingProhibited =
false;
5036 bool CloseNesting =
true;
5037 bool OrphanSeen =
false;
5040 ShouldBeInParallelRegion,
5041 ShouldBeInOrderedRegion,
5042 ShouldBeInTargetRegion,
5043 ShouldBeInTeamsRegion,
5044 ShouldBeInLoopSimdRegion,
5045 } Recommend = NoRecommend;
5046 if (SemaRef.
LangOpts.OpenMP >= 51 && Stack->isParentOrderConcurrent() &&
5047 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_loop &&
5048 CurrentRegion != OMPD_parallel &&
5050 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_order)
5051 << getOpenMPDirectiveName(CurrentRegion);
5055 ((SemaRef.
LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
5056 (SemaRef.
LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
5057 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
5058 CurrentRegion != OMPD_scan))) {
5071 SemaRef.
Diag(StartLoc, (CurrentRegion != OMPD_simd)
5072 ? diag::err_omp_prohibited_region_simd
5073 : diag::warn_omp_nesting_simd)
5074 << (SemaRef.
LangOpts.OpenMP >= 50 ? 1 : 0);
5075 return CurrentRegion != OMPD_simd;
5077 if (ParentRegion == OMPD_atomic) {
5080 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
5083 if (CurrentRegion == OMPD_section) {
5088 if (ParentRegion != OMPD_sections &&
5089 ParentRegion != OMPD_parallel_sections) {
5090 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_section_directive)
5091 << (ParentRegion != OMPD_unknown)
5092 << getOpenMPDirectiveName(ParentRegion);
5100 if (ParentRegion == OMPD_unknown &&
5102 CurrentRegion != OMPD_cancellation_point &&
5103 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
5107 if (SemaRef.
LangOpts.OpenMP >= 50 && CurrentRegion == OMPD_loop &&
5108 (BindKind == OMPC_BIND_parallel || BindKind == OMPC_BIND_teams) &&
5110 ParentRegion == OMPD_loop)) {
5111 int ErrorMsgNumber = (BindKind == OMPC_BIND_parallel) ? 1 : 4;
5112 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region)
5113 <<
true << getOpenMPDirectiveName(ParentRegion) << ErrorMsgNumber
5114 << getOpenMPDirectiveName(CurrentRegion);
5117 if (CurrentRegion == OMPD_cancellation_point ||
5118 CurrentRegion == OMPD_cancel) {
5131 !((CancelRegion == OMPD_parallel &&
5132 (ParentRegion == OMPD_parallel ||
5133 ParentRegion == OMPD_target_parallel)) ||
5134 (CancelRegion == OMPD_for &&
5135 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
5136 ParentRegion == OMPD_target_parallel_for ||
5137 ParentRegion == OMPD_distribute_parallel_for ||
5138 ParentRegion == OMPD_teams_distribute_parallel_for ||
5139 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
5140 (CancelRegion == OMPD_taskgroup &&
5141 (ParentRegion == OMPD_task ||
5143 (ParentRegion == OMPD_taskloop ||
5144 ParentRegion == OMPD_master_taskloop ||
5145 ParentRegion == OMPD_masked_taskloop ||
5146 ParentRegion == OMPD_parallel_masked_taskloop ||
5147 ParentRegion == OMPD_parallel_master_taskloop)))) ||
5148 (CancelRegion == OMPD_sections &&
5149 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
5150 ParentRegion == OMPD_parallel_sections)));
5151 OrphanSeen = ParentRegion == OMPD_unknown;
5152 }
else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
5159 }
else if (CurrentRegion == OMPD_critical && CurrentName.
getName()) {
5165 bool DeadLock = Stack->hasDirective(
5169 if (K == OMPD_critical && DNI.
getName() == CurrentName.
getName()) {
5170 PreviousCriticalLoc = Loc;
5177 SemaRef.
Diag(StartLoc,
5178 diag::err_omp_prohibited_region_critical_same_name)
5180 if (PreviousCriticalLoc.
isValid())
5181 SemaRef.
Diag(PreviousCriticalLoc,
5182 diag::note_omp_previous_critical_region);
5185 }
else if (CurrentRegion == OMPD_barrier || CurrentRegion == OMPD_scope) {
5196 ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5197 ParentRegion == OMPD_parallel_master ||
5198 ParentRegion == OMPD_parallel_masked ||
5199 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5211 ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5212 ParentRegion == OMPD_parallel_master ||
5213 ParentRegion == OMPD_parallel_masked ||
5214 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5215 Recommend = ShouldBeInParallelRegion;
5216 }
else if (CurrentRegion == OMPD_ordered) {
5225 NestingProhibited = ParentRegion == OMPD_critical ||
5228 Stack->isParentOrderedRegion());
5229 Recommend = ShouldBeInOrderedRegion;
5235 (SemaRef.
LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
5236 (SemaRef.
LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
5237 ParentRegion != OMPD_target);
5238 OrphanSeen = ParentRegion == OMPD_unknown;
5239 Recommend = ShouldBeInTargetRegion;
5240 }
else if (CurrentRegion == OMPD_scan) {
5246 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
5247 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
5248 ParentRegion != OMPD_parallel_for_simd);
5249 OrphanSeen = ParentRegion == OMPD_unknown;
5250 Recommend = ShouldBeInLoopSimdRegion;
5252 if (!NestingProhibited &&
5255 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
5267 CurrentRegion != OMPD_loop &&
5269 CurrentRegion == OMPD_atomic);
5270 Recommend = ShouldBeInParallelRegion;
5272 if (!NestingProhibited && CurrentRegion == OMPD_loop) {
5277 NestingProhibited = BindKind == OMPC_BIND_teams &&
5278 ParentRegion != OMPD_teams &&
5279 ParentRegion != OMPD_target_teams;
5280 Recommend = ShouldBeInTeamsRegion;
5282 if (!NestingProhibited &&
5288 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
5289 Recommend = ShouldBeInTeamsRegion;
5291 if (!NestingProhibited &&
5298 NestingProhibited = Stack->hasDirective(
5302 OffendingRegion = K;
5308 CloseNesting =
false;
5310 if (NestingProhibited) {
5312 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_device_directive)
5313 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
5315 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region)
5316 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
5317 << Recommend << getOpenMPDirectiveName(CurrentRegion);
5332 bool ErrorFound =
false;
5333 unsigned NamedModifiersNumber = 0;
5334 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
5335 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
5338 if (
const auto *IC = dyn_cast_or_null<OMPIfClause>(
C)) {
5342 if (FoundNameModifiers[CurNM]) {
5343 S.
Diag(
C->getBeginLoc(), diag::err_omp_more_one_clause)
5344 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
5345 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
5347 }
else if (CurNM != OMPD_unknown) {
5348 NameModifierLoc.push_back(IC->getNameModifierLoc());
5349 ++NamedModifiersNumber;
5351 FoundNameModifiers[CurNM] = IC;
5352 if (CurNM == OMPD_unknown)
5358 if (!llvm::is_contained(AllowedNameModifiers, CurNM)) {
5359 S.
Diag(IC->getNameModifierLoc(),
5360 diag::err_omp_wrong_if_directive_name_modifier)
5361 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
5368 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
5369 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
5370 S.
Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
5371 diag::err_omp_no_more_if_clause);
5374 std::string Sep(
", ");
5375 unsigned AllowedCnt = 0;
5376 unsigned TotalAllowedNum =
5377 AllowedNameModifiers.size() - NamedModifiersNumber;
5378 for (
unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
5381 if (!FoundNameModifiers[NM]) {
5383 Values += getOpenMPDirectiveName(NM);
5385 if (AllowedCnt + 2 == TotalAllowedNum)
5387 else if (AllowedCnt + 1 != TotalAllowedNum)
5392 S.
Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
5393 diag::err_omp_unnamed_if_clause)
5394 << (TotalAllowedNum > 1) << Values;
5397 S.
Diag(Loc, diag::note_omp_previous_named_if_clause);
5407 bool AllowArraySection,
5408 StringRef DiagType) {
5411 return std::make_pair(
nullptr,
true);
5423 } IsArrayExpr = NoArrayExpr;
5424 if (AllowArraySection) {
5425 if (
auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
5426 Expr *
Base = ASE->getBase()->IgnoreParenImpCasts();
5427 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base))
5428 Base = TempASE->getBase()->IgnoreParenImpCasts();
5430 IsArrayExpr = ArraySubscript;
5431 }
else if (
auto *OASE = dyn_cast_or_null<ArraySectionExpr>(RefExpr)) {
5432 Expr *
Base = OASE->getBase()->IgnoreParenImpCasts();
5433 while (
auto *TempOASE = dyn_cast<ArraySectionExpr>(
Base))
5434 Base = TempOASE->getBase()->IgnoreParenImpCasts();
5435 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base))
5436 Base = TempASE->getBase()->IgnoreParenImpCasts();
5438 IsArrayExpr = OMPArraySection;
5444 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5445 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
5446 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
5448 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
5449 !isa<FieldDecl>(ME->getMemberDecl()))) {
5450 if (IsArrayExpr != NoArrayExpr) {
5451 S.
Diag(ELoc, diag::err_omp_expected_base_var_name)
5452 << IsArrayExpr << ERange;
5453 }
else if (!DiagType.empty()) {
5457 S.
Diag(ELoc, diag::err_omp_expected_var_name_member_expr_with_type)
5458 << DiagSelect << DiagType << ERange;
5462 ? diag::err_omp_expected_var_name_member_expr_or_array_item
5463 : diag::err_omp_expected_var_name_member_expr)
5466 return std::make_pair(
nullptr,
false);
5468 return std::make_pair(
5475class AllocatorChecker final :
public ConstStmtVisitor<AllocatorChecker, bool> {
5476 DSAStackTy *S =
nullptr;
5480 return S->isUsesAllocatorsDecl(E->
getDecl())
5481 .value_or(DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5482 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5484 bool VisitStmt(
const Stmt *S) {
5485 for (
const Stmt *Child : S->children()) {
5486 if (Child && Visit(Child))
5491 explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5498 "Expected non-dependent context.");
5499 auto AllocateRange =
5502 auto PrivateRange = llvm::make_filter_range(Clauses, [](
const OMPClause *
C) {
5507 if (
Cl->getClauseKind() == OMPC_private) {
5508 auto *PC = cast<OMPPrivateClause>(
Cl);
5509 I = PC->private_copies().begin();
5510 It = PC->varlist_begin();
5511 Et = PC->varlist_end();
5512 }
else if (
Cl->getClauseKind() == OMPC_firstprivate) {
5513 auto *PC = cast<OMPFirstprivateClause>(
Cl);
5514 I = PC->private_copies().begin();
5515 It = PC->varlist_begin();
5516 Et = PC->varlist_end();
5517 }
else if (
Cl->getClauseKind() == OMPC_lastprivate) {
5518 auto *PC = cast<OMPLastprivateClause>(
Cl);
5519 I = PC->private_copies().begin();
5520 It = PC->varlist_begin();
5521 Et = PC->varlist_end();
5522 }
else if (
Cl->getClauseKind() == OMPC_linear) {
5523 auto *PC = cast<OMPLinearClause>(
Cl);
5524 I = PC->privates().begin();
5525 It = PC->varlist_begin();
5526 Et = PC->varlist_end();
5527 }
else if (
Cl->getClauseKind() == OMPC_reduction) {
5528 auto *PC = cast<OMPReductionClause>(
Cl);
5529 I = PC->privates().begin();
5530 It = PC->varlist_begin();
5531 Et = PC->varlist_end();
5532 }
else if (
Cl->getClauseKind() == OMPC_task_reduction) {
5533 auto *PC = cast<OMPTaskReductionClause>(
Cl);
5534 I = PC->privates().begin();
5535 It = PC->varlist_begin();
5536 Et = PC->varlist_end();
5537 }
else if (
Cl->getClauseKind() == OMPC_in_reduction) {
5538 auto *PC = cast<OMPInReductionClause>(
Cl);
5539 I = PC->privates().begin();
5540 It = PC->varlist_begin();
5541 Et = PC->varlist_end();
5543 llvm_unreachable(
"Expected private clause.");
5545 for (
Expr *E : llvm::make_range(It, Et)) {
5552 Expr *SimpleRefExpr = E;
5555 DeclToCopy.try_emplace(Res.first,
5556 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5561 auto *AC = cast<OMPAllocateClause>(
C);
5565 AC->getAllocator()) {
5566 Expr *Allocator = AC->getAllocator();
5572 AllocatorChecker Checker(Stack);
5573 if (Checker.Visit(Allocator))
5574 S.
Diag(Allocator->getExprLoc(),
5575 diag::err_omp_allocator_not_in_uses_allocators)
5576 << Allocator->getSourceRange();
5578 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5584 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5587 S.
Diag(AC->getAllocator()->getExprLoc(),
5588 diag::warn_omp_allocate_thread_on_task_target_directive)
5589 << getOpenMPDirectiveName(Stack->getCurrentDirective());
5591 for (
Expr *E : AC->varlists()) {
5594 Expr *SimpleRefExpr = E;
5597 DSAStackTy::DSAVarData
Data = Stack->getTopDSA(VD,
false);
5600 diag::err_omp_expected_private_copy_for_allocate);
5603 VarDecl *PrivateVD = DeclToCopy[VD];
5605 AllocatorKind, AC->getAllocator()))
5608 Expr *Alignment =
nullptr;
5625 CaptureVars(
Sema &Actions) : BaseTransform(Actions) {}
5627 bool AlwaysRebuild() {
return true; }
5640 BodyStmts.push_back(NewDeclStmt);
5678 DistParam, LogicalTy,
VK_LValue, {},
nullptr,
nullptr, {},
nullptr);
5689 auto BuildVarRef = [&](
VarDecl *VD) {
5694 Ctx, llvm::APInt(Ctx.
getIntWidth(LogicalTy), 0), LogicalTy, {});
5696 Ctx, llvm::APInt(Ctx.
getIntWidth(LogicalTy), 1), LogicalTy, {});
5702 Actions.
BuildBinOp(
nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero));
5706 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5710 nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep)));
5714 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5718 Actions.
BuildUnaryOp(
nullptr, {}, UO_Minus, BuildVarRef(NewStep)));
5720 Actions.
BuildBinOp(
nullptr, {}, BO_Div, BackwardRange, NegIncAmount));
5724 {}, {}, IsNegStep, BackwardDist, ForwardDist));
5726 assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) &&
5727 "Expected one of these relational operators");
5734 nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5738 if (Rel == BO_GE || Rel == BO_GT)
5740 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5743 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5749 if (Rel == BO_LE || Rel == BO_GE) {
5761 Expr *Divisor = BuildVarRef(NewStep);
5762 if (Rel == BO_GE || Rel == BO_GT)
5765 Expr *DivisorMinusOne =
5768 Actions.
BuildBinOp(
nullptr, {}, BO_Add, Range, DivisorMinusOne));
5770 Actions.
BuildBinOp(
nullptr, {}, BO_Div, RangeRoundUp, Divisor));
5780 Actions.
getCurScope(), {}, BO_Assign, DistRef, Dist));
5781 BodyStmts.push_back(ResultAssign);
5786 return cast<CapturedStmt>(
5813 {
"Logical", LogicalTy},
5824 assert(!
Invalid &&
"Expecting capture-by-value to work.");
5829 auto *CS = cast<CapturedDecl>(Actions.
CurContext);
5833 TargetParam, LoopVarTy,
VK_LValue, {},
nullptr,
nullptr, {},
nullptr);
5836 IndvarParam, LogicalTy,
VK_LValue, {},
nullptr,
nullptr, {},
nullptr);
5839 CaptureVars Recap(Actions);
5844 Actions.
BuildBinOp(
nullptr, {}, BO_Mul, NewStep, LogicalRef));
5859 BO_Assign, TargetRef, Advanced));
5861 return cast<CapturedStmt>(
5872 if (
auto *For = dyn_cast<ForStmt>(AStmt)) {
5874 if (
auto *LCVarDeclStmt = dyn_cast<DeclStmt>(
Init)) {
5876 LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl());
5877 }
else if (
auto *LCAssign = dyn_cast<BinaryOperator>(
Init)) {
5879 assert(LCAssign->getOpcode() == BO_Assign &&
5880 "init part must be a loop variable assignment");
5881 auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS());
5882 LIVDecl = cast<VarDecl>(CounterRef->getDecl());
5884 llvm_unreachable(
"Cannot determine loop variable");
5887 Cond = For->getCond();
5888 Inc = For->getInc();
5889 }
else if (
auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) {
5890 DeclStmt *BeginStmt = RangeFor->getBeginStmt();
5892 LUVDecl = RangeFor->getLoopVariable();
5894 Cond = RangeFor->getCond();
5895 Inc = RangeFor->getInc();
5897 llvm_unreachable(
"unhandled kind of loop");
5906 if (
auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) {
5907 LHS = CondBinExpr->getLHS();
5908 RHS = CondBinExpr->getRHS();
5909 CondRel = CondBinExpr->getOpcode();
5910 }
else if (
auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) {
5911 assert(CondCXXOp->getNumArgs() == 2 &&
"Comparison should have 2 operands");
5912 LHS = CondCXXOp->getArg(0);
5913 RHS = CondCXXOp->getArg(1);
5914 switch (CondCXXOp->getOperator()) {
5915 case OO_ExclaimEqual:
5927 case OO_GreaterEqual:
5931 llvm_unreachable(
"unexpected iterator operator");
5934 llvm_unreachable(
"unexpected loop condition");
5938 cast<DeclRefExpr>(LHS->
IgnoreImplicit())->getDecl() != LIVDecl) {
5939 std::swap(LHS, RHS);
5956 if (
auto *IncUn = dyn_cast<UnaryOperator>(Inc)) {
5958 switch (IncUn->getOpcode()) {
5968 llvm_unreachable(
"unhandled unary increment operator");
5971 Ctx, llvm::APInt(Ctx.
getIntWidth(LogicalTy), Direction), LogicalTy, {});
5972 }
else if (
auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
5973 if (IncBin->getOpcode() == BO_AddAssign) {
5974 Step = IncBin->getRHS();
5975 }
else if (IncBin->getOpcode() == BO_SubAssign) {
5979 llvm_unreachable(
"unhandled binary increment operator");
5980 }
else if (
auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) {
5981 switch (CondCXXOp->getOperator()) {
5984 Ctx, llvm::APInt(Ctx.
getIntWidth(LogicalTy), 1), LogicalTy, {});
5988 Ctx, llvm::APInt(Ctx.
getIntWidth(LogicalTy), -1), LogicalTy, {});
5991 Step = CondCXXOp->getArg(1);
5998 llvm_unreachable(
"unhandled overloaded increment operator");
6001 llvm_unreachable(
"unknown increment expression");
6006 SemaRef, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt));
6009 nullptr,
nullptr, {},
nullptr);
6011 LoopVarFunc, LVRef);
6016 if (isa<ForStmt>(AStmt) || isa<CXXForRangeStmt>(AStmt))
6023 "Loop transformation directive expected");
6024 return LoopTransform;
6031 Expr *UnresolvedMapper);
6043 for (
int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) {
6044 auto *
C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
6048 auto *MI =
C->mapperlist_begin();
6049 for (
auto I =
C->varlist_begin(), End =
C->varlist_end(); I != End;
6069 ElemType = ATy->getElementType();
6072 CanonType = ElemType;
6077 1, {CanonType,
nullptr});
6078 llvm::DenseMap<const Type *, Expr *>
Visited;
6081 while (!Types.empty()) {
6084 std::tie(BaseType, CurFD) = Types.pop_back_val();
6085 while (ParentChain.back().second == 0)
6086 ParentChain.pop_back();
6087 --ParentChain.back().second;
6103 S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
6114 Expr *BaseExpr = OE;
6115 for (
const auto &
P : ParentChain) {
6133 SubExprs.push_back(BaseExpr);
6137 bool FirstIter =
true;
6147 ParentChain.emplace_back(CurFD, 1);
6149 ++ParentChain.back().second;
6151 Types.emplace_back(FieldTy, FD);
6155 if (SubExprs.empty())
6160 nullptr,
C->getMapTypeModifiers(),
C->getMapTypeModifiersLoc(),
6161 MapperIdScopeSpec, MapperId,
C->getMapType(),
6164 Clauses.push_back(NewClause);
6181 if (
C->getBindKind() == OMPC_BIND_parallel) {
6182 TeamsLoopCanBeParallelFor =
false;
6198 bool IsOpenMPAPI =
false;
6199 auto *FD = dyn_cast_or_null<FunctionDecl>(
C->getCalleeDecl());
6201 std::string Name = FD->getNameInfo().getAsString();
6202 IsOpenMPAPI = Name.find(
"omp_") == 0;
6204 TeamsLoopCanBeParallelFor =
6205 IsOpenMPAPI || SemaRef.getLangOpts().OpenMPNoNestedParallelism;
6206 if (!TeamsLoopCanBeParallelFor)
6209 for (
const Stmt *Child :
C->children())
6217 Visit(S->getCapturedDecl()->getBody());
6220 void VisitStmt(
const Stmt *S) {
6223 for (
const Stmt *Child : S->children())
6227 explicit TeamsLoopChecker(
Sema &SemaRef)
6228 : SemaRef(SemaRef), TeamsLoopCanBeParallelFor(
true) {}
6231 bool TeamsLoopCanBeParallelFor;
6236 TeamsLoopChecker Checker(SemaRef);
6237 Checker.Visit(AStmt);
6238 return Checker.teamsLoopCanBeParallelFor();
6241bool SemaOpenMP::mapLoopConstruct(
6248 bool UseClausesWithoutBind =
false;
6251 if (
getLangOpts().OpenMP >= 50 && Kind == OMPD_loop) {
6258 BindKind = OMPC_BIND_thread;
6260 if (ParentDirective == OMPD_unknown) {
6262 diag::err_omp_bind_required_on_loop);
6263 }
else if (ParentDirective == OMPD_parallel ||
6264 ParentDirective == OMPD_target_parallel) {
6265 BindKind = OMPC_BIND_parallel;
6266 }
else if (ParentDirective == OMPD_teams ||
6267 ParentDirective == OMPD_target_teams) {
6268 BindKind = OMPC_BIND_teams;
6275 UseClausesWithoutBind =
true;
6280 if (BindKind == OMPC_BIND_teams &&
6281 C->getClauseKind() == llvm::omp::Clause::OMPC_reduction)
6283 diag::err_omp_loop_reduction_clause);
6287 if (
C->getClauseKind() != llvm::omp::Clause::OMPC_bind)
6288 ClausesWithoutBind.push_back(
C);
6292 case OMPC_BIND_parallel:
6294 DSAStack->setCurrentDirective(OMPD_for);
6295 DSAStack->setMappedDirective(OMPD_loop);
6296 PrevMappedDirective = OMPD_loop;
6298 case OMPC_BIND_teams:
6299 Kind = OMPD_distribute;
6300 DSAStack->setCurrentDirective(OMPD_distribute);
6301 DSAStack->setMappedDirective(OMPD_loop);
6302 PrevMappedDirective = OMPD_loop;
6304 case OMPC_BIND_thread:
6306 DSAStack->setCurrentDirective(OMPD_simd);
6307 DSAStack->setMappedDirective(OMPD_loop);
6308 PrevMappedDirective = OMPD_loop;
6313 }
else if (PrevMappedDirective == OMPD_loop) {
6322 DSAStack->setMappedDirective(OMPD_loop);
6325 return UseClausesWithoutBind;
6336 bool UseClausesWithoutBind =
false;
6339 OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses))
6340 BindKind = BC->getBindKind();
6345 if (Kind == OMPD_loop || PrevMappedDirective == OMPD_loop) {
6346 UseClausesWithoutBind = mapLoopConstruct(
6347 ClausesWithoutBind, Clauses, BindKind, Kind, PrevMappedDirective,
6348 StartLoc, EndLoc, DirName, CancelRegion);
6355 BindKind, StartLoc)) {
6362 Diag(StartLoc, diag::warn_hip_omp_target_directives);
6366 bool ErrorFound =
false;
6367 if (
getLangOpts().OpenMP >= 50 && UseClausesWithoutBind) {
6368 ClausesWithImplicit.append(ClausesWithoutBind.begin(),
6369 ClausesWithoutBind.end());
6371 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
6374 Kind != OMPD_atomic && Kind != OMPD_critical && Kind != OMPD_section &&
6375 Kind != OMPD_master && Kind != OMPD_masked &&
6377 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6380 DSAAttrChecker DSAChecker(
DSAStack,
SemaRef, cast<CapturedStmt>(AStmt));
6383 while (--ThisCaptureLevel >= 0)
6384 S = cast<CapturedStmt>(S)->getCapturedStmt();
6385 DSAChecker.Visit(S);
6389 auto *CS = cast<CapturedStmt>(AStmt);
6393 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
6395 DSAChecker.visitSubCaptures(CS);
6397 if (DSAChecker.isErrorFound())
6400 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
6403 DSAChecker.getImplicitFirstprivate().begin(),
6404 DSAChecker.getImplicitFirstprivate().end());
6406 DSAChecker.getImplicitPrivate().begin(),
6407 DSAChecker.getImplicitPrivate().end());
6411 ImplicitMapModifiers[DefaultmapKindNum];
6413 ImplicitMapModifiersLoc[DefaultmapKindNum];
6417 if (
auto *DMC = dyn_cast<OMPDefaultmapClause>(
C))
6418 if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
6419 PresentModifierLocs[DMC->getDefaultmapKind()] =
6420 DMC->getDefaultmapModifierLoc();
6422 for (
unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
6424 for (
unsigned I = 0; I < OMPC_MAP_delete; ++I) {
6427 ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
6430 DSAChecker.getImplicitMapModifier(Kind);
6431 ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
6432 ImplicitModifier.end());
6433 std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
6434 ImplicitModifier.size(), PresentModifierLocs[VC]);
6438 if (
auto *IRC = dyn_cast<OMPInReductionClause>(
C)) {
6439 for (
Expr *E : IRC->taskgroup_descriptors())
6441 ImplicitFirstprivates.emplace_back(E);
6446 if (
auto *DC = dyn_cast<OMPDetachClause>(
C))
6447 ImplicitFirstprivates.push_back(DC->getEventHandler());
6449 if (!ImplicitFirstprivates.empty()) {
6453 ClausesWithImplicit.push_back(
Implicit);
6454 ErrorFound = cast<OMPFirstprivateClause>(
Implicit)->varlist_size() !=
6455 ImplicitFirstprivates.size();
6460 if (!ImplicitPrivates.empty()) {
6464 ClausesWithImplicit.push_back(
Implicit);
6465 ErrorFound = cast<OMPPrivateClause>(
Implicit)->varlist_size() !=
6466 ImplicitPrivates.size();
6475 if (
getLangOpts().OpenMP >= 50 && Kind != OMPD_target &&
6479 if (
auto *RC = dyn_cast<OMPReductionClause>(
C))
6480 for (
Expr *E : RC->varlists())
6482 ImplicitExprs.emplace_back(E);
6484 if (!ImplicitExprs.empty()) {
6490 MapperIdScopeSpec, MapperId, OMPC_MAP_tofrom,
6493 ClausesWithImplicit.emplace_back(
Implicit);
6496 for (
unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
6497 int ClauseKindCnt = -1;
6500 if (ImplicitMap.empty())
6506 nullptr, ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
6507 MapperIdScopeSpec, MapperId, Kind,
true,
6510 ClausesWithImplicit.emplace_back(
Implicit);
6511 ErrorFound |= cast<OMPMapClause>(
Implicit)->varlist_size() !=
6522 ClausesWithImplicit);
6530 AllowedNameModifiers.push_back(OMPD_parallel);
6534 VarsWithInheritedDSA);
6536 AllowedNameModifiers.push_back(OMPD_simd);
6548 VarsWithInheritedDSA);
6552 EndLoc, VarsWithInheritedDSA);
6554 AllowedNameModifiers.push_back(OMPD_simd);
6561 assert(ClausesWithImplicit.empty() &&
6562 "No clauses are allowed for 'omp section' directive");
6570 assert(ClausesWithImplicit.empty() &&
6571 "No clauses are allowed for 'omp master' directive");
6582 case OMPD_parallel_for:
6584 EndLoc, VarsWithInheritedDSA);
6585 AllowedNameModifiers.push_back(OMPD_parallel);
6587 case OMPD_parallel_for_simd:
6589 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6590 AllowedNameModifiers.push_back(OMPD_parallel);
6592 AllowedNameModifiers.push_back(OMPD_simd);
6598 case OMPD_parallel_master:
6601 AllowedNameModifiers.push_back(OMPD_parallel);
6603 case OMPD_parallel_masked:
6606 AllowedNameModifiers.push_back(OMPD_parallel);
6608 case OMPD_parallel_sections:
6611 AllowedNameModifiers.push_back(OMPD_parallel);
6616 AllowedNameModifiers.push_back(OMPD_task);
6618 case OMPD_taskyield:
6619 assert(ClausesWithImplicit.empty() &&
6620 "No clauses are allowed for 'omp taskyield' directive");
6621 assert(AStmt ==
nullptr &&
6622 "No associated statement allowed for 'omp taskyield' directive");
6626 assert(AStmt ==
nullptr &&
6627 "No associated statement allowed for 'omp error' directive");
6631 assert(ClausesWithImplicit.empty() &&
6632 "No clauses are allowed for 'omp barrier' directive");
6633 assert(AStmt ==
nullptr &&
6634 "No associated statement allowed for 'omp barrier' directive");
6638 assert(AStmt ==
nullptr &&
6639 "No associated statement allowed for 'omp taskwait' directive");
6642 case OMPD_taskgroup:
6647 assert(AStmt ==
nullptr &&
6648 "No associated statement allowed for 'omp flush' directive");
6652 assert(AStmt ==
nullptr &&
6653 "No associated statement allowed for 'omp depobj' directive");
6657 assert(AStmt ==
nullptr &&
6658 "No associated statement allowed for 'omp scan' directive");
6676 AllowedNameModifiers.push_back(OMPD_target);
6678 case OMPD_target_parallel:
6681 AllowedNameModifiers.push_back(OMPD_target);
6682 AllowedNameModifiers.push_back(OMPD_parallel);
6684 case OMPD_target_parallel_for:
6686 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6687 AllowedNameModifiers.push_back(OMPD_target);
6688 AllowedNameModifiers.push_back(OMPD_parallel);
6690 case OMPD_cancellation_point:
6691 assert(ClausesWithImplicit.empty() &&
6692 "No clauses are allowed for 'omp cancellation point' directive");
6693 assert(AStmt ==
nullptr &&
"No associated statement allowed for 'omp "
6694 "cancellation point' directive");
6698 assert(AStmt ==
nullptr &&
6699 "No associated statement allowed for 'omp cancel' directive");
6702 AllowedNameModifiers.push_back(OMPD_cancel);
6704 case OMPD_target_data:
6707 AllowedNameModifiers.push_back(OMPD_target_data);
6709 case OMPD_target_enter_data:
6712 AllowedNameModifiers.push_back(OMPD_target_enter_data);
6714 case OMPD_target_exit_data:
6717 AllowedNameModifiers.push_back(OMPD_target_exit_data);
6721 EndLoc, VarsWithInheritedDSA);
6722 AllowedNameModifiers.push_back(OMPD_taskloop);
6724 case OMPD_taskloop_simd:
6726 EndLoc, VarsWithInheritedDSA);
6727 AllowedNameModifiers.push_back(OMPD_taskloop);
6729 AllowedNameModifiers.push_back(OMPD_simd);
6731 case OMPD_master_taskloop:
6733 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6734 AllowedNameModifiers.push_back(OMPD_taskloop);
6736 case OMPD_masked_taskloop:
6738 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6739 AllowedNameModifiers.push_back(OMPD_taskloop);
6741 case OMPD_master_taskloop_simd:
6743 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6744 AllowedNameModifiers.push_back(OMPD_taskloop);
6746 AllowedNameModifiers.push_back(OMPD_simd);
6748 case OMPD_masked_taskloop_simd:
6750 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6752 AllowedNameModifiers.push_back(OMPD_taskloop);
6753 AllowedNameModifiers.push_back(OMPD_simd);
6756 case OMPD_parallel_master_taskloop:
6758 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6759 AllowedNameModifiers.push_back(OMPD_taskloop);
6760 AllowedNameModifiers.push_back(OMPD_parallel);
6762 case OMPD_parallel_masked_taskloop:
6764 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6766 AllowedNameModifiers.push_back(OMPD_taskloop);
6767 AllowedNameModifiers.push_back(OMPD_parallel);
6770 case OMPD_parallel_master_taskloop_simd:
6772 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6773 AllowedNameModifiers.push_back(OMPD_taskloop);
6774 AllowedNameModifiers.push_back(OMPD_parallel);
6776 AllowedNameModifiers.push_back(OMPD_simd);
6778 case OMPD_parallel_masked_taskloop_simd:
6780 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6782 AllowedNameModifiers.push_back(OMPD_taskloop);
6783 AllowedNameModifiers.push_back(OMPD_parallel);
6784 AllowedNameModifiers.push_back(OMPD_simd);
6787 case OMPD_distribute:
6789 EndLoc, VarsWithInheritedDSA);
6791 case OMPD_target_update:
6794 AllowedNameModifiers.push_back(OMPD_target_update);
6796 case OMPD_distribute_parallel_for:
6798 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6799 AllowedNameModifiers.push_back(OMPD_parallel);
6801 case OMPD_distribute_parallel_for_simd:
6803 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6804 AllowedNameModifiers.push_back(OMPD_parallel);
6806 AllowedNameModifiers.push_back(OMPD_simd);
6808 case OMPD_distribute_simd:
6810 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6812 AllowedNameModifiers.push_back(OMPD_simd);
6814 case OMPD_target_parallel_for_simd:
6816 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6817 AllowedNameModifiers.push_back(OMPD_target);
6818 AllowedNameModifiers.push_back(OMPD_parallel);
6820 AllowedNameModifiers.push_back(OMPD_simd);
6822 case OMPD_target_simd:
6824 EndLoc, VarsWithInheritedDSA);
6825 AllowedNameModifiers.push_back(OMPD_target);
6827 AllowedNameModifiers.push_back(OMPD_simd);
6829 case OMPD_teams_distribute:
6831 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6833 case OMPD_teams_distribute_simd:
6835 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6837 AllowedNameModifiers.push_back(OMPD_simd);
6839 case OMPD_teams_distribute_parallel_for_simd:
6841 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6842 AllowedNameModifiers.push_back(OMPD_parallel);
6844 AllowedNameModifiers.push_back(OMPD_simd);
6846 case OMPD_teams_distribute_parallel_for:
6848 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6849 AllowedNameModifiers.push_back(OMPD_parallel);
6851 case OMPD_target_teams:
6854 AllowedNameModifiers.push_back(OMPD_target);
6856 case OMPD_target_teams_distribute:
6858 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6859 AllowedNameModifiers.push_back(OMPD_target);
6861 case OMPD_target_teams_distribute_parallel_for:
6863 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6864 AllowedNameModifiers.push_back(OMPD_target);
6865 AllowedNameModifiers.push_back(OMPD_parallel);
6867 case OMPD_target_teams_distribute_parallel_for_simd:
6869 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6870 AllowedNameModifiers.push_back(OMPD_target);
6871 AllowedNameModifiers.push_back(OMPD_parallel);
6873 AllowedNameModifiers.push_back(OMPD_simd);
6875 case OMPD_target_teams_distribute_simd:
6877 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6878 AllowedNameModifiers.push_back(OMPD_target);
6880 AllowedNameModifiers.push_back(OMPD_simd);
6883 assert(AStmt ==
nullptr &&
6884 "No associated statement allowed for 'omp interop' directive");
6893 EndLoc, VarsWithInheritedDSA);
6895 case OMPD_teams_loop:
6897 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6899 case OMPD_target_teams_loop:
6901 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6902 AllowedNameModifiers.push_back(OMPD_target);
6904 case OMPD_parallel_loop:
6906 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6908 case OMPD_target_parallel_loop:
6910 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6912 case OMPD_declare_target:
6913 case OMPD_end_declare_target:
6914 case OMPD_threadprivate:
6916 case OMPD_declare_reduction:
6917 case OMPD_declare_mapper:
6918 case OMPD_declare_simd:
6920 case OMPD_declare_variant:
6921 case OMPD_begin_declare_variant:
6922 case OMPD_end_declare_variant:
6923 llvm_unreachable(
"OpenMP Directive is not allowed");
6926 llvm_unreachable(
"Unknown OpenMP directive");
6929 ErrorFound = Res.
isInvalid() || ErrorFound;
6933 if (
DSAStack->getDefaultDSA() == DSA_none ||
6934 DSAStack->getDefaultDSA() == DSA_private ||
6935 DSAStack->getDefaultDSA() == DSA_firstprivate) {
6938 switch (
C->getClauseKind()) {
6939 case OMPC_num_threads:
6940 case OMPC_dist_schedule:
6947 cast<OMPIfClause>(
C)->getNameModifier() != OMPD_target)
6951 cast<OMPIfClause>(
C)->getNameModifier() != OMPD_parallel)
6957 case OMPC_grainsize:
6958 case OMPC_num_tasks:
6961 case OMPC_novariants:
6962 case OMPC_nocontext:
6969 case OMPC_num_teams:
6970 case OMPC_thread_limit:
6977 case OMPC_proc_bind:
6979 case OMPC_firstprivate:
6980 case OMPC_lastprivate:
6982 case OMPC_reduction:
6983 case OMPC_task_reduction:
6984 case OMPC_in_reduction:
6988 case OMPC_copyprivate:
6991 case OMPC_mergeable:
7008 case OMPC_defaultmap:
7011 case OMPC_use_device_ptr:
7012 case OMPC_use_device_addr:
7013 case OMPC_is_device_ptr:
7014 case OMPC_has_device_addr:
7015 case OMPC_nontemporal:
7018 case OMPC_inclusive:
7019 case OMPC_exclusive:
7020 case OMPC_uses_allocators:
7025 case OMPC_allocator:
7028 case OMPC_threadprivate:
7031 case OMPC_unified_address:
7032 case OMPC_unified_shared_memory:
7033 case OMPC_reverse_offload:
7034 case OMPC_dynamic_allocators:
7035 case OMPC_atomic_default_mem_order:
7036 case OMPC_device_type:
7043 llvm_unreachable(
"Unexpected clause");
7045 for (
Stmt *CC :
C->children()) {
7047 DSAChecker.Visit(CC);
7050 for (
const auto &
P : DSAChecker.getVarsWithInheritedDSA())
7051 VarsWithInheritedDSA[
P.getFirst()] =
P.getSecond();
7053 for (
const auto &
P : VarsWithInheritedDSA) {
7054 if (
P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(
P.getFirst()))
7057 if (
DSAStack->getDefaultDSA() == DSA_none ||
7058 DSAStack->getDefaultDSA() == DSA_private ||
7059 DSAStack->getDefaultDSA() == DSA_firstprivate) {
7060 Diag(
P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
7061 <<
P.first <<
P.second->getSourceRange();
7062 Diag(
DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
7064 Diag(
P.second->getExprLoc(),
7065 diag::err_omp_defaultmap_no_attr_for_variable)
7066 <<
P.first <<
P.second->getSourceRange();
7068 diag::note_omp_defaultmap_attr_none);
7072 if (!AllowedNameModifiers.empty())
7086 DSAStack->addTargetDirLocation(StartLoc);
7097 assert(Aligneds.size() == Alignments.size());
7098 assert(Linears.size() == LinModifiers.size());
7099 assert(Linears.size() == Steps.size());
7100 if (!DG || DG.
get().isNull())
7103 const int SimdId = 0;
7104 if (!DG.
get().isSingleDecl()) {
7105 Diag(SR.
getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
7109 Decl *ADecl = DG.
get().getSingleDecl();
7110 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
7111 ADecl = FTD->getTemplatedDecl();
7113 auto *FD = dyn_cast<FunctionDecl>(ADecl);
7115 Diag(ADecl->
getLocation(), diag::err_omp_function_expected) << SimdId;
7131 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
7132 const Expr *UniformedLinearThis =
nullptr;
7133 for (
const Expr *E : Uniforms) {
7135 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
7136 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
7137 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7138 FD->getParamDecl(PVD->getFunctionScopeIndex())
7140 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
7143 if (isa<CXXThisExpr>(E)) {
7144 UniformedLinearThis = E;
7148 << FD->
getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
7158 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
7159 const Expr *AlignedThis =
nullptr;
7160 for (
const Expr *E : Aligneds) {
7162 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
7163 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7165 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7166 FD->getParamDecl(PVD->getFunctionScopeIndex())
7170 if (AlignedArgs.count(CanonPVD) > 0) {
7172 << 1 << getOpenMPClauseName(OMPC_aligned)
7174 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
7175 diag::note_omp_explicit_dsa)
7176 << getOpenMPClauseName(OMPC_aligned);
7179 AlignedArgs[CanonPVD] = E;
7181 .getNonReferenceType()
7182 .getUnqualifiedType()
7183 .getCanonicalType();
7186 Diag(E->
getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
7188 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
7193 if (isa<CXXThisExpr>(E)) {
7196 << 2 << getOpenMPClauseName(OMPC_aligned) << E->
getSourceRange();
7198 << getOpenMPClauseName(OMPC_aligned);
7204 << FD->
getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
7211 for (
Expr *E : Alignments) {
7215 NewAligns.push_back(Align.
get());
7226 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
7227 const bool IsUniformedThis = UniformedLinearThis !=
nullptr;
7228 auto MI = LinModifiers.begin();
7229 for (
const Expr *E : Linears) {
7233 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
7234 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7236 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7237 FD->getParamDecl(PVD->getFunctionScopeIndex())
7241 if (LinearArgs.count(CanonPVD) > 0) {
7243 << getOpenMPClauseName(OMPC_linear)
7245 Diag(LinearArgs[CanonPVD]->getExprLoc(),
7246 diag::note_omp_explicit_dsa)
7247 << getOpenMPClauseName(OMPC_linear);
7251 if (UniformedArgs.count(CanonPVD) > 0) {
7253 << getOpenMPClauseName(OMPC_linear)
7255 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
7256 diag::note_omp_explicit_dsa)
7257 << getOpenMPClauseName(OMPC_uniform);
7260 LinearArgs[CanonPVD] = E;
7266 PVD->getOriginalType(),
7271 if (isa<CXXThisExpr>(E)) {
7272 if (UniformedLinearThis) {
7274 << getOpenMPClauseName(OMPC_linear)
7275 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
7277 Diag(UniformedLinearThis->
getExprLoc(), diag::note_omp_explicit_dsa)
7278 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
7282 UniformedLinearThis = E;
7291 << FD->
getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
7293 Expr *Step =
nullptr;
7294 Expr *NewStep =
nullptr;
7296 for (
Expr *E : Steps) {
7298 if (Step == E || !E) {
7299 NewSteps.push_back(E ? NewStep :
nullptr);
7303 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Step))
7304 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7306 if (UniformedArgs.count(CanonPVD) == 0) {
7313 NewSteps.push_back(Step);
7332 NewSteps.push_back(NewStep);
7334 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
7336 Uniforms.size(),
const_cast<Expr **
>(Aligneds.data()), Aligneds.size(),
7337 const_cast<Expr **
>(NewAligns.data()), NewAligns.size(),
7338 const_cast<Expr **
>(Linears.data()), Linears.size(),
7339 const_cast<unsigned *
>(LinModifiers.data()), LinModifiers.size(),
7340 NewSteps.data(), NewSteps.size(), SR);
7348 "Expected function type with prototype.");
7350 "Expected function with type with no prototype.");
7352 "Expected function with prototype.");
7360 Param->setScopeInfo(0, Params.size());
7361 Param->setImplicit();
7362 Params.push_back(Param);
7365 FD->setParams(Params);
7372 if (
auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7373 FD = UTemplDecl->getTemplatedDecl();
7375 FD = cast<FunctionDecl>(D);
7376 assert(FD &&
"Expected a function declaration!");
7382 for (OMPAssumeAttr *AA : OMPAssumeScoped)
7385 for (OMPAssumeAttr *AA : OMPAssumeGlobal)
7389SemaOpenMP::OMPDeclareVariantScope::OMPDeclareVariantScope(
OMPTraitInfo &TI)
7390 : TI(&TI), NameSuffix(TI.getMangledName()) {}
7398 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7401 bool IsTemplated = !TemplateParamLists.empty();
7403 !DVScope.TI->isExtensionActive(
7404 llvm::omp::TraitProperty::implementation_extension_allow_templates))
7420 for (
auto *Candidate : Lookup) {
7421 auto *CandidateDecl = Candidate->getUnderlyingDecl();
7423 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) {
7424 auto *FTD = cast<FunctionTemplateDecl>(CandidateDecl);
7425 if (FTD->getTemplateParameters()->size() == TemplateParamLists.size())
7426 UDecl = FTD->getTemplatedDecl();
7427 }
else if (!IsTemplated)
7428 UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
7442 FType, UDeclTy,
false,
7449 Bases.push_back(UDecl);
7452 bool UseImplicitBase = !DVScope.TI->isExtensionActive(
7453 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
7455 if (Bases.empty() && UseImplicitBase) {
7459 if (
auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
7460 Bases.push_back(BaseTemplD->getTemplatedDecl());
7462 Bases.push_back(cast<FunctionDecl>(BaseD));
7465 std::string MangledName;
7468 MangledName += DVScope.NameSuffix;
7483 if (
auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7484 FD = UTemplDecl->getTemplatedDecl();
7486 FD = cast<FunctionDecl>(D);
7493 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7494 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
7500 BaseFD->addAttr(OMPDeclareVariantA);
7519 CalleeFnDecl->
getName().starts_with_insensitive(
"omp_")) {
7522 Diag(LParenLoc, diag::err_omp_unexpected_call_to_omp_runtime_api);
7525 if (!CalleeFnDecl->
hasAttr<OMPDeclareVariantAttr>())
7529 std::function<void(StringRef)> DiagUnknownTrait = [
this,
7530 CE](StringRef ISATrait) {
7544 while (CalleeFnDecl) {
7545 for (OMPDeclareVariantAttr *A :
7547 Expr *VariantRef = A->getVariantFuncRef();
7549 VariantMatchInfo VMI;
7552 if (!isVariantApplicableInContext(VMI, OMPCtx,
7556 VMIs.push_back(VMI);
7557 Exprs.push_back(VariantRef);
7565 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
7568 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
7569 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
7585 if (
auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
7586 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
7588 Context, MemberCall->getImplicitObjectArgument(),
7590 MemberCall->getValueKind(), MemberCall->getObjectKind());
7593 RParenLoc, ExecConfig);
7595 if (
CallExpr *NCE = dyn_cast<CallExpr>(NewCall.
get())) {
7596 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
7598 CalleeFnType, NewCalleeFnDecl->
getType(),
7609 VMIs.erase(VMIs.begin() + BestIdx);
7610 Exprs.erase(Exprs.begin() + BestIdx);
7611 }
while (!VMIs.empty());
7618std::optional<std::pair<FunctionDecl *, Expr *>>
7622 unsigned NumAppendArgs,
7625 if (!DG || DG.
get().isNull())
7626 return std::nullopt;
7628 const int VariantId = 1;
7630 if (!DG.
get().isSingleDecl()) {
7631 Diag(SR.
getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
7633 return std::nullopt;
7635 Decl *ADecl = DG.
get().getSingleDecl();
7636 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
7637 ADecl = FTD->getTemplatedDecl();
7640 auto *FD = dyn_cast<FunctionDecl>(ADecl);
7644 return std::nullopt;
7647 auto &&HasMultiVersionAttributes = [](
const FunctionDecl *FD) {
7650 return FD->isMultiVersion() || FD->
hasAttr<TargetAttr>();
7653 if (HasMultiVersionAttributes(FD)) {
7654 Diag(FD->
getLocation(), diag::err_omp_declare_variant_incompat_attributes)
7656 return std::nullopt;
7661 Diag(SR.
getBegin(), diag::warn_omp_declare_variant_after_used)
7666 if (!FD->isThisDeclarationADefinition() && FD->isDefined(
Definition) &&
7668 Diag(SR.
getBegin(), diag::warn_omp_declare_variant_after_emitted)
7673 Diag(SR.
getBegin(), diag::err_omp_function_expected) << VariantId;
7674 return std::nullopt;
7677 auto ShouldDelayChecks = [](
Expr *&E,
bool) {
7683 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef,
false) ||
7685 return std::make_pair(FD, VariantRef);
7688 auto HandleNonConstantScoresAndConditions = [
this](
Expr *&E,
7689 bool IsScore) ->
bool {
7695 Diag(E->
getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
7703 diag::err_omp_declare_variant_user_condition_not_constant)
7709 return std::nullopt;
7712 if (NumAppendArgs) {
7715 Diag(FD->
getLocation(), diag::err_omp_declare_variant_prototype_required)
7717 return std::nullopt;
7726 TD = dyn_cast_or_null<TypeDecl>(ND);
7729 Diag(SR.
getBegin(), diag::err_omp_interop_type_not_found) << SR;
7730 return std::nullopt;
7733 if (PTy->isVariadic()) {
7734 Diag(FD->
getLocation(), diag::err_omp_append_args_with_varargs) << SR;
7735 return std::nullopt;
7738 Params.append(PTy->param_type_begin(), PTy->param_type_end());
7739 Params.insert(Params.end(), NumAppendArgs, InteropType);
7740 AdjustedFnType = Context.
getFunctionType(PTy->getReturnType(), Params,
7741 PTy->getExtProtoInfo());
7749 auto *Method = dyn_cast<CXXMethodDecl>(FD);
7750 if (Method && !Method->isStatic()) {
7751 const Type *ClassType =
7765 return std::nullopt;
7767 VariantRef = ER.
get();
7775 false, Sema::AllowedExplicit::None,
7781 diag::err_omp_declare_variant_incompat_types)
7783 << ((Method && !Method->isStatic()) ? FnPtrType : FD->
getType())
7785 return std::nullopt;
7790 return std::nullopt;
7793 if (Method && !Method->isStatic()) {
7794 Expr *PossibleAddrOfVariantRef = VariantRefCast.
get();
7795 if (
auto *UO = dyn_cast<UnaryOperator>(
7797 VariantRefCast = UO->getSubExpr();
7806 return std::nullopt;
7814 return std::nullopt;
7816 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
7820 return std::nullopt;
7825 diag::err_omp_declare_variant_same_base_function)
7827 return std::nullopt;
7836 diag::err_omp_declare_variant_incompat_types)
7837 << NewFD->getType() << FD->
getType() << (NumAppendArgs ? 1 : 0)
7839 return std::nullopt;
7844 else if (NewFD->getType()->isFunctionNoProtoType())
7850 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
7852 diag::warn_omp_declare_variant_marked_as_declare_variant)
7855 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->
getRange();
7856 Diag(SR.
getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
7857 return std::nullopt;
7860 enum DoesntSupport {
7869 if (
const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
7870 if (CXXFD->isVirtual()) {
7873 return std::nullopt;
7876 if (isa<CXXConstructorDecl>(FD)) {
7879 return std::nullopt;
7882 if (isa<CXXDestructorDecl>(FD)) {
7885 return std::nullopt;
7889 if (FD->isDeleted()) {
7892 return std::nullopt;
7895 if (FD->isDefaulted()) {
7898 return std::nullopt;
7901 if (FD->isConstexpr()) {
7903 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
7904 return std::nullopt;
7914 SemaRef.
PDiag(diag::err_omp_declare_variant_doesnt_support)),
7920 return std::nullopt;
7921 return std::make_pair(FD, cast<Expr>(DRE));
7937 llvm::append_range(AllAdjustArgs, AdjustArgsNothing);
7938 llvm::append_range(AllAdjustArgs, AdjustArgsNeedDevicePtr);
7940 if (!AllAdjustArgs.empty() || !AppendArgs.empty()) {
7941 VariantMatchInfo VMI;
7943 if (!llvm::is_contained(
7944 VMI.ConstructTraits,
7945 llvm::omp::TraitProperty::construct_dispatch_dispatch)) {
7946 if (!AllAdjustArgs.empty())
7947 Diag(AdjustArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7948 << getOpenMPClauseName(OMPC_adjust_args);
7949 if (!AppendArgs.empty())
7950 Diag(AppendArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7951 << getOpenMPClauseName(OMPC_append_args);
7961 for (
Expr *E : AllAdjustArgs) {
7963 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
7964 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7966 if (FD->
getNumParams() > PVD->getFunctionScopeIndex() &&
7970 if (!AdjustVars.insert(CanonPVD).second) {
7971 Diag(DRE->getLocation(), diag::err_omp_adjust_arg_multiple_clauses)
7980 Diag(E->
getExprLoc(), diag::err_omp_param_or_this_in_clause) << FD << 0;
7984 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
7986 const_cast<Expr **
>(AdjustArgsNothing.data()), AdjustArgsNothing.size(),
7987 const_cast<Expr **
>(AdjustArgsNeedDevicePtr.data()),
7988 AdjustArgsNeedDevicePtr.size(),
7989 const_cast<OMPInteropInfo *
>(AppendArgs.data()), AppendArgs.size(), SR);
8000 auto *CS = cast<CapturedStmt>(AStmt);
8017struct LoopIterationSpace final {
8020 bool IsStrictCompare =
false;
8022 Expr *PreCond =
nullptr;
8025 Expr *NumIterations =
nullptr;
8027 Expr *CounterVar =
nullptr;
8029 Expr *PrivateCounterVar =
nullptr;
8031 Expr *CounterInit =
nullptr;
8034 Expr *CounterStep =
nullptr;
8036 bool Subtract =
false;
8046 Expr *MinValue =
nullptr;
8050 Expr *MaxValue =
nullptr;
8052 bool IsNonRectangularLB =
false;
8054 bool IsNonRectangularUB =
false;
8057 unsigned LoopDependentIdx = 0;
8061 Expr *FinalCondition =
nullptr;
8067class OpenMPIterationSpaceChecker {
8071 bool SupportsNonRectangular;
8087 Expr *LCRef =
nullptr;
8093 Expr *Step =
nullptr;
8100 std::optional<bool> TestIsLessOp;
8102 bool TestIsStrictOp =
false;
8104 bool SubtractStep =
false;
8109 std::optional<unsigned> InitDependOnLC;
8112 std::optional<unsigned> CondDependOnLC;
8114 std::optional<unsigned> doesDependOnLoopCounter(
const Stmt *S,
8115 bool IsInitializer);
8121 OpenMPIterationSpaceChecker(
Sema &SemaRef,
bool SupportsNonRectangular,
8123 : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular),
8124 Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
8127 bool checkAndSetInit(
Stmt *S,
bool EmitDiags =
true);
8130 bool checkAndSetCond(
Expr *S);
8133 bool checkAndSetInc(
Expr *S);
8135 ValueDecl *getLoopDecl()
const {
return LCDecl; }
8137 Expr *getLoopDeclRefExpr()
const {
return LCRef; }
8139 SourceRange getInitSrcRange()
const {
return InitSrcRange; }
8141 SourceRange getConditionSrcRange()
const {
return ConditionSrcRange; }
8143 SourceRange getIncrementSrcRange()
const {
return IncrementSrcRange; }
8145 bool shouldSubtractStep()
const {
return SubtractStep; }
8147 bool isStrictTestOp()
const {
return TestIsStrictOp; }
8149 Expr *buildNumIterations(
8151 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const;
8155 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const;
8158 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8159 DSAStackTy &DSA)
const;
8162 Expr *buildPrivateCounterVar()
const;
8166 Expr *buildCounterStep()
const;
8170 buildOrderedLoopData(
Scope *S,
Expr *Counter,
8171 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8175 std::pair<Expr *, Expr *> buildMinMaxValues(
8176 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const;
8178 Expr *buildFinalCondition(
Scope *S)
const;
8180 bool dependent()
const;
8182 bool doesInitDependOnLC()
const {
return InitDependOnLC.has_value(); }
8184 bool doesCondDependOnLC()
const {
return CondDependOnLC.has_value(); }
8186 unsigned getLoopDependentIdx()
const {
8187 return InitDependOnLC.value_or(CondDependOnLC.value_or(0));
8193 bool checkAndSetIncRHS(
Expr *RHS);
8198 bool setUB(
Expr *NewUB, std::optional<bool> LessOp,
bool StrictOp,
8201 bool setStep(
Expr *NewStep,
bool Subtract);
8204bool OpenMPIterationSpaceChecker::dependent()
const {
8206 assert(!LB && !UB && !Step);
8214bool OpenMPIterationSpaceChecker::setLCDeclAndLB(
ValueDecl *NewLCDecl,
8216 Expr *NewLB,
bool EmitDiags) {
8218 assert(LCDecl ==
nullptr && LB ==
nullptr && LCRef ==
nullptr &&
8219 UB ==
nullptr && Step ==
nullptr && !TestIsLessOp && !TestIsStrictOp);
8223 LCRef = NewLCRefExpr;
8224 if (
auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
8226 if ((Ctor->isCopyOrMoveConstructor() ||
8227 Ctor->isConvertingConstructor(
false)) &&
8228 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
8232 InitDependOnLC = doesDependOnLoopCounter(LB,
true);
8236bool OpenMPIterationSpaceChecker::setUB(
Expr *NewUB, std::optional<bool> LessOp,
8240 assert(LCDecl !=
nullptr && LB !=
nullptr && UB ==
nullptr &&
8241 Step ==
nullptr && !TestIsLessOp && !TestIsStrictOp);
8246 TestIsLessOp = LessOp;
8247 TestIsStrictOp = StrictOp;
8248 ConditionSrcRange = SR;
8250 CondDependOnLC = doesDependOnLoopCounter(UB,
false);
8254bool OpenMPIterationSpaceChecker::setStep(
Expr *NewStep,
bool Subtract) {
8256 assert(LCDecl !=
nullptr && LB !=
nullptr && Step ==
nullptr);
8266 NewStep = Val.
get();
8279 std::optional<llvm::APSInt>
Result =
8290 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
8291 if (UB && (IsConstZero ||
8292 (*TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
8293 : (IsConstPos || (IsUnsigned && !Subtract))))) {
8295 diag::err_omp_loop_incr_not_compatible)
8297 SemaRef.
Diag(ConditionLoc,
8298 diag::note_omp_loop_cond_requres_compatible_incr)
8299 << *TestIsLessOp << ConditionSrcRange;
8302 if (*TestIsLessOp == Subtract) {
8306 Subtract = !Subtract;
8311 SubtractStep = Subtract;
8318class LoopCounterRefChecker final
8325 bool IsInitializer =
true;
8326 bool SupportsNonRectangular;
8327 unsigned BaseLoopId = 0;
8330 SemaRef.Diag(E->
getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
8331 << (IsInitializer ? 0 : 1);
8334 const auto &&
Data = Stack.isLoopControlVariable(VD);
8340 llvm::raw_svector_ostream OS(Name);
8344 diag::err_omp_wrong_dependency_iterator_type)
8346 SemaRef.Diag(VD->
getLocation(), diag::note_previous_decl) << VD;
8349 if (
Data.first && !SupportsNonRectangular) {
8350 SemaRef.Diag(E->
getExprLoc(), diag::err_omp_invariant_dependency);
8354 (DepDecl || (PrevDepDecl &&
8356 if (!DepDecl && PrevDepDecl)
8357 DepDecl = PrevDepDecl;
8359 llvm::raw_svector_ostream OS(Name);
8363 diag::err_omp_invariant_or_linear_dependency)
8369 BaseLoopId =
Data.first;
8377 if (isa<VarDecl>(VD))
8378 return checkDecl(E, VD);
8384 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
8385 return checkDecl(E, VD);
8389 bool VisitStmt(
const Stmt *S) {
8391 for (
const Stmt *Child : S->children())
8392 Res = (Child && Visit(Child)) || Res;
8395 explicit LoopCounterRefChecker(
Sema &SemaRef, DSAStackTy &Stack,
8396 const ValueDecl *CurLCDecl,
bool IsInitializer,
8398 bool SupportsNonRectangular =
true)
8399 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
8400 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer),
8401 SupportsNonRectangular(SupportsNonRectangular) {}
8402 unsigned getBaseLoopId()
const {
8403 assert(CurLCDecl &&
"Expected loop dependency.");
8407 assert(CurLCDecl &&
"Expected loop dependency.");
8413std::optional<unsigned>
8414OpenMPIterationSpaceChecker::doesDependOnLoopCounter(
const Stmt *S,
8415 bool IsInitializer) {
8417 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
8418 DepDecl, SupportsNonRectangular);
8419 if (LoopStmtChecker.Visit(S)) {
8420 DepDecl = LoopStmtChecker.getDepDecl();
8421 return LoopStmtChecker.getBaseLoopId();
8423 return std::nullopt;
8426bool OpenMPIterationSpaceChecker::checkAndSetInit(
Stmt *S,
bool EmitDiags) {
8437 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
8441 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8442 if (!ExprTemp->cleanupsHaveSideEffects())
8443 S = ExprTemp->getSubExpr();
8445 InitSrcRange = S->getSourceRange();
8446 if (
Expr *E = dyn_cast<Expr>(S))
8448 if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
8449 if (BO->getOpcode() == BO_Assign) {
8451 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8452 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8454 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8456 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
8458 if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
8459 if (ME->isArrow() &&
8460 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8461 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8465 }
else if (
auto *DS = dyn_cast<DeclStmt>(S)) {
8466 if (DS->isSingleDecl()) {
8467 if (
auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
8468 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
8471 SemaRef.Diag(S->getBeginLoc(),
8472 diag::ext_omp_loop_not_canonical_init)
8473 << S->getSourceRange();
8474 return setLCDeclAndLB(
8477 Var->getType().getNonReferenceType(),
8479 Var->getInit(), EmitDiags);
8483 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8484 if (CE->getOperator() == OO_Equal) {
8485 Expr *LHS = CE->getArg(0);
8486 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8487 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8489 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8491 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
8493 if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
8494 if (ME->isArrow() &&
8495 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8496 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8502 if (dependent() || SemaRef.CurContext->isDependentContext())
8505 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
8506 << S->getSourceRange();
8517 if (
const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
8519 if ((Ctor->isCopyOrMoveConstructor() ||
8520 Ctor->isConvertingConstructor(
false)) &&
8521 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
8523 if (
const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
8524 if (
const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
8527 if (
const auto *ME = dyn_cast_or_null<MemberExpr>(E))
8528 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8533bool OpenMPIterationSpaceChecker::checkAndSetCond(
Expr *S) {
8540 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
8542 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
8543 << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
8549 auto &&CheckAndSetCond =
8554 if (getInitLCDecl(LHS) == LCDecl)
8555 return setUB(
const_cast<Expr *
>(RHS),
8557 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8558 if (getInitLCDecl(RHS) == LCDecl)
8559 return setUB(
const_cast<Expr *
>(LHS),
8561 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8562 }
else if (IneqCondIsCanonical && Opcode == BO_NE) {
8563 return setUB(
const_cast<Expr *
>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS),
8567 return std::nullopt;
8569 std::optional<bool> Res;
8570 if (
auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) {
8573 RBO->getOperatorLoc());
8574 }
else if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
8575 Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(),
8576 BO->getSourceRange(), BO->getOperatorLoc());
8577 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8578 if (CE->getNumArgs() == 2) {
8579 Res = CheckAndSetCond(
8581 CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc());
8586 if (dependent() || SemaRef.CurContext->isDependentContext())
8588 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
8589 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
8593bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(
Expr *RHS) {
8600 if (
auto *BO = dyn_cast<BinaryOperator>(RHS)) {
8601 if (BO->isAdditiveOp()) {
8602 bool IsAdd = BO->getOpcode() == BO_Add;
8603 if (getInitLCDecl(BO->getLHS()) == LCDecl)
8604 return setStep(BO->getRHS(), !IsAdd);
8605 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
8606 return setStep(BO->getLHS(),
false);
8608 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
8609 bool IsAdd = CE->getOperator() == OO_Plus;
8610 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
8611 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8612 return setStep(CE->getArg(1), !IsAdd);
8613 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
8614 return setStep(CE->getArg(0),
false);
8617 if (dependent() || SemaRef.CurContext->isDependentContext())
8619 SemaRef.Diag(RHS->
getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8624bool OpenMPIterationSpaceChecker::checkAndSetInc(
Expr *S) {
8639 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
8642 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8643 if (!ExprTemp->cleanupsHaveSideEffects())
8644 S = ExprTemp->getSubExpr();
8646 IncrementSrcRange = S->getSourceRange();
8647 S = S->IgnoreParens();
8648 if (
auto *UO = dyn_cast<UnaryOperator>(S)) {
8649 if (UO->isIncrementDecrementOp() &&
8650 getInitLCDecl(UO->getSubExpr()) == LCDecl)
8651 return setStep(SemaRef
8652 .ActOnIntegerConstant(UO->getBeginLoc(),
8653 (UO->isDecrementOp() ? -1 : 1))
8656 }
else if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
8657 switch (BO->getOpcode()) {
8660 if (getInitLCDecl(BO->getLHS()) == LCDecl)
8661 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
8664 if (getInitLCDecl(BO->getLHS()) == LCDecl)
8665 return checkAndSetIncRHS(BO->getRHS());
8670 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8671 switch (CE->getOperator()) {
8674 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8675 return setStep(SemaRef
8676 .ActOnIntegerConstant(
8678 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
8684 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8685 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
8688 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8689 return checkAndSetIncRHS(CE->getArg(1));
8695 if (dependent() || SemaRef.CurContext->isDependentContext())
8697 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8698 << S->getSourceRange() << LCDecl;
8704 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8705 StringRef Name =
".capture_expr.") {
8712 auto I = Captures.find(
Capture);
8713 if (I != Captures.end())
8726 bool TestIsStrictOp,
bool RoundToStep,
8727 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8728 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures,
".new_step");
8731 llvm::APSInt LRes, SRes;
8732 bool IsLowerConst =
false, IsStepConst =
false;
8733 if (std::optional<llvm::APSInt> Res =
8736 IsLowerConst =
true;
8738 if (std::optional<llvm::APSInt> Res =
8743 bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
8744 ((!TestIsStrictOp && LRes.isNonNegative()) ||
8745 (TestIsStrictOp && LRes.isStrictlyPositive()));
8746 bool NeedToReorganize =
false;
8748 if (!NoNeedToConvert && IsLowerConst &&
8749 (TestIsStrictOp || (RoundToStep && IsStepConst))) {
8750 NoNeedToConvert =
true;
8752 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
8753 ? LRes.getBitWidth()
8754 : SRes.getBitWidth();
8755 LRes = LRes.extend(BW + 1);
8756 LRes.setIsSigned(
true);
8757 SRes = SRes.extend(BW + 1);
8758 SRes.setIsSigned(
true);
8760 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
8761 LRes = LRes.trunc(BW);
8763 if (TestIsStrictOp) {
8764 unsigned BW = LRes.getBitWidth();
8765 LRes = LRes.extend(BW + 1);
8766 LRes.setIsSigned(
true);
8769 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
8771 LRes = LRes.trunc(BW);
8773 NeedToReorganize = NoNeedToConvert;
8776 bool IsUpperConst =
false;
8777 if (std::optional<llvm::APSInt> Res =
8780 IsUpperConst =
true;
8782 if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
8783 (!RoundToStep || IsStepConst)) {
8784 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
8785 : URes.getBitWidth();
8786 LRes = LRes.extend(BW + 1);
8787 LRes.setIsSigned(
true);
8788 URes = URes.extend(BW + 1);
8789 URes.setIsSigned(
true);
8791 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
8792 NeedToReorganize = NoNeedToConvert;
8797 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
8803 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
8806 LowerSize > UpperSize ? LowerSize : UpperSize, 0);
8817 if (!Lower || !Upper || NewStep.
isInvalid())
8823 if (NeedToReorganize) {
8837 S, DefaultLoc, BO_Add, Diff.
get(),
8847 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.
get());
8851 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
8867 S, DefaultLoc, BO_Sub, Diff.
get(),
8887 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Div, Diff.
get(), NewStep.
get());
8895Expr *OpenMPIterationSpaceChecker::buildNumIterations(
8897 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const {
8906 if (InitDependOnLC) {
8907 const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
8908 if (!IS.MinValue || !IS.MaxValue)
8917 IS.CounterVar, MinValue.
get());
8922 SemaRef.
BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.
get(), LBVal);
8937 IS.CounterVar, MaxValue.
get());
8942 SemaRef.
BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.
get(), LBVal);
8951 tryBuildCapture(SemaRef, LBMinVal.
get(), Captures,
".lb_min").get();
8953 tryBuildCapture(SemaRef, LBMaxVal.
get(), Captures,
".lb_max").get();
8954 if (!LBMin || !LBMax)
8958 SemaRef.
BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
8962 tryBuildCapture(SemaRef, MinLessMaxRes.
get(), Captures,
".min_less_max")
8966 if (*TestIsLessOp) {
8970 MinLessMax, LBMin, LBMax);
8973 LBVal = MinLB.
get();
8978 MinLessMax, LBMax, LBMin);
8981 LBVal = MaxLB.
get();
8985 SemaRef.
BuildBinOp(S, DefaultLoc, BO_Assign, IS.CounterVar, LBVal);
8988 LBVal = LBMinVal.
get();
8992 if (CondDependOnLC) {
8993 const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
8994 if (!IS.MinValue || !IS.MaxValue)
9003 IS.CounterVar, MinValue.
get());
9008 SemaRef.
BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.
get(), UBVal);
9023 IS.CounterVar, MaxValue.
get());
9028 SemaRef.
BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.
get(), UBVal);
9037 tryBuildCapture(SemaRef, UBMinVal.
get(), Captures,
".ub_min").get();
9039 tryBuildCapture(SemaRef, UBMaxVal.
get(), Captures,
".ub_max").get();
9040 if (!UBMin || !UBMax)
9044 SemaRef.
BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
9047 Expr *MinGreaterMax = tryBuildCapture(SemaRef, MinGreaterMaxRes.
get(),
9048 Captures,
".min_greater_max")
9052 if (*TestIsLessOp) {
9056 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
9059 UBVal = MaxUB.
get();
9064 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
9067 UBVal = MinUB.
get();
9070 Expr *UBExpr = *TestIsLessOp ? UBVal : LBVal;
9071 Expr *LBExpr = *TestIsLessOp ? LBVal : UBVal;
9072 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures,
".upper").get();
9073 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures,
".lower").get();
9074 if (!Upper || !Lower)
9077 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
9078 Step, VarType, TestIsStrictOp,
9087 C.getTypeSize(
Type) >
C.getTypeSize(VarType);
9090 UseVarType ?
C.getTypeSize(VarType) :
C.getTypeSize(
Type);
9093 Type =
C.getIntTypeForBitwidth(NewSize, IsSigned);
9102 unsigned NewSize = (
C.getTypeSize(
Type) > 32) ? 64 : 32;
9103 if (NewSize !=
C.getTypeSize(
Type)) {
9104 if (NewSize <
C.getTypeSize(
Type)) {
9105 assert(NewSize == 64 &&
"incorrect loop var size");
9106 SemaRef.
Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
9107 << InitSrcRange << ConditionSrcRange;
9109 QualType NewType =
C.getIntTypeForBitwidth(
9111 C.getTypeSize(
Type) < NewSize);
9124std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
9125 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const {
9129 return std::make_pair(
nullptr,
nullptr);
9132 Expr *MinExpr =
nullptr;
9133 Expr *MaxExpr =
nullptr;
9134 Expr *LBExpr = *TestIsLessOp ? LB : UB;
9135 Expr *UBExpr = *TestIsLessOp ? UB : LB;
9137 *TestIsLessOp ? InitDependOnLC.has_value() : CondDependOnLC.has_value();
9139 *TestIsLessOp ? CondDependOnLC.has_value() : InitDependOnLC.has_value();
9141 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
9143 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
9144 if (!Upper || !Lower)
9145 return std::make_pair(
nullptr,
nullptr);
9155 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
9156 Step, VarType, TestIsStrictOp,
9159 return std::make_pair(
nullptr,
nullptr);
9165 return std::make_pair(
nullptr,
nullptr);
9167 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures,
".new_step");
9169 return std::make_pair(
nullptr,
nullptr);
9170 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Mul, Diff.
get(), NewStep.
get());
9172 return std::make_pair(
nullptr,
nullptr);
9177 return std::make_pair(
nullptr,
nullptr);
9189 return std::make_pair(
nullptr,
nullptr);
9191 if (*TestIsLessOp) {
9195 S, DefaultLoc, BO_Add,
9199 return std::make_pair(
nullptr,
nullptr);
9204 S, DefaultLoc, BO_Sub,
9208 return std::make_pair(
nullptr,
nullptr);
9217 return std::make_pair(
nullptr,
nullptr);
9222 return std::make_pair(
nullptr,
nullptr);
9225 MaxExpr = Diff.
get();
9227 MinExpr = Diff.
get();
9229 return std::make_pair(MinExpr, MaxExpr);
9232Expr *OpenMPIterationSpaceChecker::buildFinalCondition(
Scope *S)
const {
9233 if (InitDependOnLC || CondDependOnLC)
9238Expr *OpenMPIterationSpaceChecker::buildPreCond(
9240 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const {
9245 if (CondDependOnLC || InitDependOnLC)
9256 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
9257 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
9263 *TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
9264 : (TestIsStrictOp ? BO_GT : BO_GE),
9265 NewLB.
get(), NewUB.
get());
9275 return CondExpr.
isUsable() ? CondExpr.
get() : Cond;
9279DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
9280 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
9281 DSAStackTy &DSA)
const {
9282 auto *VD = dyn_cast<VarDecl>(LCDecl);
9287 const DSAStackTy::DSAVarData
Data =
9288 DSA.getTopDSA(LCDecl,
false);
9292 Captures.insert(std::make_pair(LCRef, Ref));
9295 return cast<DeclRefExpr>(LCRef);
9298Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar()
const {
9304 isa<VarDecl>(LCDecl)
9315Expr *OpenMPIterationSpaceChecker::buildCounterInit()
const {
return LB; }
9318Expr *OpenMPIterationSpaceChecker::buildCounterStep()
const {
return Step; }
9320Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
9322 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
SourceLocation Loc,
9328 assert((OOK == OO_Plus || OOK == OO_Minus) &&
9329 "Expected only + or - operations for depend clauses.");
9341 *TestIsLessOp ? Cnt : tryBuildCapture(SemaRef, LB, Captures).get();
9343 *TestIsLessOp ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt;
9344 if (!Upper || !Lower)
9348 SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
9349 false,
false, Captures);
9359 assert(
getLangOpts().OpenMP &&
"OpenMP is not active.");
9360 assert(
Init &&
"Expected loop in canonical form.");
9361 unsigned AssociatedLoops =
DSAStack->getAssociatedLoops();
9362 if (AssociatedLoops > 0 &&
9365 OpenMPIterationSpaceChecker ISC(
SemaRef,
true,
9367 if (!ISC.checkAndSetInit(
Init,
false)) {
9369 auto *VD = dyn_cast<VarDecl>(D);
9377 VD = cast<VarDecl>(PrivateRef->
getDecl());
9380 DSAStack->addLoopControlVariable(D, VD);
9382 if (LD != D->getCanonicalDecl()) {
9383 DSAStack->resetPossibleLoopCounter();
9384 if (
auto *Var = dyn_cast_or_null<VarDecl>(LD))
9398 DSAStackTy::DSAVarData DVar =
9402 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
9405 ? (
DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
9408 DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
9409 (
getLangOpts().OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
9410 DVar.CKind != OMPC_private))) ||
9412 DKind == OMPD_master_taskloop || DKind == OMPD_masked_taskloop ||
9413 DKind == OMPD_parallel_master_taskloop ||
9414 DKind == OMPD_parallel_masked_taskloop ||
9417 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
9418 (DVar.CKind != OMPC_private || DVar.RefExpr)) {
9419 Diag(
Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
9420 << getOpenMPClauseName(DVar.CKind)
9421 << getOpenMPDirectiveName(DKind)
9422 << getOpenMPClauseName(PredeterminedCKind);
9423 if (DVar.RefExpr ==
nullptr)
9424 DVar.CKind = PredeterminedCKind;
9427 }
else if (LoopDeclRefExpr) {
9432 if (DVar.CKind == OMPC_unknown)
9433 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
9438 DSAStack->setAssociatedLoops(AssociatedLoops - 1);
9444class OMPDoacrossKind {
9447 return C->getDependenceType() == OMPC_DOACROSS_source ||
9448 C->getDependenceType() == OMPC_DOACROSS_source_omp_cur_iteration;
9451 return C->getDependenceType() == OMPC_DOACROSS_sink;
9454 return C->getDependenceType() == OMPC_DOACROSS_sink_omp_cur_iteration;
9462 unsigned CurrentNestedLoopCount,
unsigned NestedLoopCount,
9463 unsigned TotalNestedLoopCount,
Expr *CollapseLoopCountExpr,
9464 Expr *OrderedLoopCountExpr,
9467 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9472 if (
auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S))
9473 S = CanonLoop->getLoopStmt();
9474 auto *For = dyn_cast_or_null<ForStmt>(S);
9475 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
9477 if (!For && (SemaRef.
LangOpts.OpenMP <= 45 || !CXXFor)) {
9479 DSA.getMappedDirective() == OMPD_unknown)
9481 : DSA.getMappedDirective();
9482 SemaRef.
Diag(S->getBeginLoc(), diag::err_omp_not_for)
9483 << (CollapseLoopCountExpr !=
nullptr || OrderedLoopCountExpr !=
nullptr)
9484 << getOpenMPDirectiveName(DK) << TotalNestedLoopCount
9485 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
9486 if (TotalNestedLoopCount > 1) {
9487 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
9488 SemaRef.
Diag(DSA.getConstructLoc(),
9489 diag::note_omp_collapse_ordered_expr)
9492 else if (CollapseLoopCountExpr)
9494 diag::note_omp_collapse_ordered_expr)
9498 diag::note_omp_collapse_ordered_expr)
9503 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
9509 OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA,
9510 For ? For->getForLoc() : CXXFor->getForLoc());
9513 Stmt *
Init = For ? For->getInit() : CXXFor->getBeginStmt();
9514 if (ISC.checkAndSetInit(
Init))
9517 bool HasErrors =
false;
9520 if (
ValueDecl *LCDecl = ISC.getLoopDecl()) {
9530 SemaRef.
Diag(
Init->getBeginLoc(), diag::err_omp_loop_variable_type)
9544 VarsWithImplicitDSA.erase(LCDecl);
9549 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
9552 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
9559 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
9560 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
9561 ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
9562 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
9569 ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
9570 ISC.buildCounterVar(Captures, DSA);
9571 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
9572 ISC.buildPrivateCounterVar();
9573 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
9574 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
9575 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
9576 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
9577 ISC.getConditionSrcRange();
9578 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
9579 ISC.getIncrementSrcRange();
9580 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
9581 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
9582 ISC.isStrictTestOp();
9583 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
9584 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
9585 ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
9586 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
9587 ISC.buildFinalCondition(DSA.getCurScope());
9588 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
9589 ISC.doesInitDependOnLC();
9590 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
9591 ISC.doesCondDependOnLC();
9592 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
9593 ISC.getLoopDependentIdx();
9596 (ResultIterSpaces[CurrentNestedLoopCount].PreCond ==
nullptr ||
9597 ResultIterSpaces[CurrentNestedLoopCount].NumIterations ==
nullptr ||
9598 ResultIterSpaces[CurrentNestedLoopCount].CounterVar ==
nullptr ||
9599 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar ==
nullptr ||
9600 ResultIterSpaces[CurrentNestedLoopCount].CounterInit ==
nullptr ||
9601 ResultIterSpaces[CurrentNestedLoopCount].CounterStep ==
nullptr);
9602 if (!HasErrors && DSA.isOrderedRegion()) {
9603 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
9604 if (CurrentNestedLoopCount <
9605 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
9606 DSA.getOrderedRegionParam().second->setLoopNumIterations(
9607 CurrentNestedLoopCount,
9608 ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
9609 DSA.getOrderedRegionParam().second->setLoopCounter(
9610 CurrentNestedLoopCount,
9611 ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
9614 for (
auto &Pair : DSA.getDoacrossDependClauses()) {
9615 auto *DependC = dyn_cast<OMPDependClause>(Pair.first);
9616 auto *DoacrossC = dyn_cast<OMPDoacrossClause>(Pair.first);
9618 DependC ? DependC->getNumLoops() : DoacrossC->getNumLoops();
9619 if (CurrentNestedLoopCount >= NumLoops) {
9623 if (DependC && DependC->getDependencyKind() == OMPC_DEPEND_sink &&
9624 Pair.second.size() <= CurrentNestedLoopCount) {
9626 DependC->setLoopData(CurrentNestedLoopCount,
nullptr);
9629 OMPDoacrossKind ODK;
9630 if (DoacrossC && ODK.isSink(DoacrossC) &&
9631 Pair.second.size() <= CurrentNestedLoopCount) {
9633 DoacrossC->setLoopData(CurrentNestedLoopCount,
nullptr);
9638 DependC ? DependC->getDependencyLoc() : DoacrossC->getDependenceLoc();
9639 if ((DependC && DependC->getDependencyKind() == OMPC_DEPEND_source) ||
9640 (DoacrossC && ODK.isSource(DoacrossC)))
9641 CntValue = ISC.buildOrderedLoopData(
9643 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9645 else if (DoacrossC && ODK.isSinkIter(DoacrossC)) {
9648 ResultIterSpaces[CurrentNestedLoopCount].CounterVar)
9656 CntValue = ISC.buildOrderedLoopData(
9658 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9659 DepLoc, Inc, clang::OO_Minus);
9661 CntValue = ISC.buildOrderedLoopData(
9663 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9664 DepLoc, Pair.second[CurrentNestedLoopCount].first,
9665 Pair.second[CurrentNestedLoopCount].second);
9667 DependC->setLoopData(CurrentNestedLoopCount, CntValue);
9669 DoacrossC->setLoopData(CurrentNestedLoopCount, CntValue);
9680 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9684 : tryBuildCapture(SemaRef, Start.
get(), Captures);
9705 bool IsNonRectangularLB,
9706 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures =
nullptr) {
9715 NewStep = tryBuildCapture(SemaRef, Step.
get(), *Captures);
9730 if (Captures && !IsNonRectangularLB)
9731 NewStart = tryBuildCapture(SemaRef, Start.
get(), *Captures);
9740 Update.get()->getType()->isOverloadableType()) {
9747 SemaRef.
BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
9748 VarRef.
get(), SavedUpdate.
get());
9759 NewStart.
get(), SavedUpdate.
get());
9783 unsigned HasBits =
C.getTypeSize(OldType);
9784 if (HasBits >= Bits)
9787 QualType NewType =
C.getIntTypeForBitwidth(Bits,
true);
9797 if (std::optional<llvm::APSInt>
Result =
9806 if (!PreInits.empty()) {
9817 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9818 if (!Captures.empty()) {
9820 for (
const auto &Pair : Captures)
9821 PreInits.push_back(Pair.second->getDecl());
9829 Expr *PostUpdate =
nullptr;
9830 if (!PostUpdates.empty()) {
9831 for (
Expr *E : PostUpdates) {
9837 PostUpdate = PostUpdate
9852 Expr *OrderedLoopCountExpr,
Stmt *AStmt,
Sema &SemaRef,
9856 unsigned NestedLoopCount = 1;
9857 bool SupportsNonPerfectlyNested = (SemaRef.
LangOpts.OpenMP >= 50) &&
9860 if (CollapseLoopCountExpr) {
9865 NestedLoopCount =
Result.Val.getInt().getLimitedValue();
9871 unsigned OrderedLoopCount = 1;
9872 if (OrderedLoopCountExpr) {
9879 if (
Result.getLimitedValue() < NestedLoopCount) {
9881 diag::err_omp_wrong_ordered_loop_count)
9884 diag::note_collapse_loop_count)
9887 OrderedLoopCount =
Result.getLimitedValue();
9895 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9896 unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount);
9900 SupportsNonPerfectlyNested, NumLoops,
9901 [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount,
9902 CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA,
9903 &IterSpaces, &Captures](
unsigned Cnt,
Stmt *CurStmt) {
9905 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
9906 NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr,
9907 VarsWithImplicitDSA, IterSpaces, Captures))
9909 if (Cnt > 0 && Cnt >= NestedLoopCount &&
9910 IterSpaces[Cnt].CounterVar) {
9912 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
9913 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
9914 Captures[DRE] = DRE;
9920 Stmt *DependentPreInits = Transform->getPreInits();
9921 if (!DependentPreInits)
9923 for (
Decl *
C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) {
9924 auto *D = cast<VarDecl>(
C);
9927 Captures[Ref] = Ref;
9932 Built.
clear( NestedLoopCount);
9935 return NestedLoopCount;
9968 auto PreCond =
ExprResult(IterSpaces[0].PreCond);
9969 Expr *N0 = IterSpaces[0].NumIterations;
9973 .PerformImplicitConversion(
9988 return NestedLoopCount;
9991 bool AllCountsNeedLessThan32Bits =
C.getTypeSize(N0->
getType()) < 32;
9993 Scope *CurScope = DSA.getCurScope();
9994 for (
unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
9995 if (PreCond.isUsable()) {
9997 SemaRef.
BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
9998 PreCond.get(), IterSpaces[Cnt].PreCond);
10000 Expr *N = IterSpaces[Cnt].NumIterations;
10002 AllCountsNeedLessThan32Bits &=
C.getTypeSize(N->
getType()) < 32;
10005 CurScope, Loc, BO_Mul, LastIteration32.
get(),
10013 CurScope, Loc, BO_Mul, LastIteration64.
get(),
10023 if (SemaRef.
getLangOpts().OpenMPOptimisticCollapse ||
10025 C.getTypeSize(LastIteration32.
get()->
getType()) == 32 &&
10026 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
10030 LastIteration64.
get(), SemaRef))))
10031 LastIteration = LastIteration32;
10050 LastIteration.
get(),
10062 tryBuildCapture(SemaRef, LastIteration.
get(), Captures);
10063 LastIteration = SaveRef;
10076 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
10105 buildVarDecl(SemaRef, InitLoc, StrideVType,
".omp.stride");
10114 UB.
get(), LastIteration.
get());
10117 LastIteration.
get(), UB.
get());
10118 EUB = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, UB.
get(),
10129 buildVarDecl(SemaRef, InitLoc, VType,
".omp.comb.lb");
10137 buildVarDecl(SemaRef, InitLoc, VType,
".omp.comb.ub");
10143 CurScope, InitLoc, BO_GT, CombUB.
get(), LastIteration.
get());
10146 LastIteration.
get(), CombUB.
get());
10147 CombEUB = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.
get(),
10152 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
10156 "Unexpected number of parameters in loop combined directive");
10197 SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, IV.
get(), CombRHS);
10203 bool UseStrictCompare =
10205 llvm::all_of(IterSpaces, [](
const LoopIterationSpace &LIS) {
10206 return LIS.IsStrictCompare;
10212 if (UseStrictCompare) {
10215 .
BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
10227 UseStrictCompare ? BO_LT : BO_LE, IV.
get(),
10230 NumIterations.
get());
10233 CombDistCond = SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LT, IV.
get(),
10234 NumIterations.
get());
10239 Expr *BoundCombUB = CombUB.
get();
10240 if (UseStrictCompare) {
10244 CurScope, CondLoc, BO_Add, BoundCombUB,
10252 SemaRef.
BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
10253 IV.
get(), BoundCombUB);
10260 if (!Inc.isUsable())
10262 Inc = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, IV.
get(), Inc.get());
10264 if (!Inc.isUsable())
10271 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
10277 NextLB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Add, LB.
get(), ST.
get());
10288 NextUB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Add, UB.
get(), ST.
get());
10304 CombNextLB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.
get(),
10316 CombNextUB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.
get(),
10330 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
10333 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.
get(), BoundUB);
10334 assert(DistCond.
isUsable() &&
"distribute cond expr was not built");
10338 assert(DistInc.
isUsable() &&
"distribute inc expr was not built");
10339 DistInc = SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.
get(),
10343 assert(DistInc.
isUsable() &&
"distribute inc expr was not built");
10354 DistEUBLoc, NewPrevUB.
get());
10359 UB.
get(), NewPrevUB.
get());
10361 DistEUBLoc, DistEUBLoc, IsUBGreater.
get(), NewPrevUB.
get(), UB.
get());
10362 PrevEUB = SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.
get(),
10370 Expr *BoundPrevUB = PrevUB.
get();
10371 if (UseStrictCompare) {
10375 CurScope, CondLoc, BO_Add, BoundPrevUB,
10383 SemaRef.
BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
10384 IV.
get(), BoundPrevUB);
10388 bool HasErrors =
false;
10389 Built.
Counters.resize(NestedLoopCount);
10390 Built.
Inits.resize(NestedLoopCount);
10391 Built.
Updates.resize(NestedLoopCount);
10392 Built.
Finals.resize(NestedLoopCount);
10413 for (
unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
10414 LoopIterationSpace &IS = IterSpaces[Cnt];
10420 for (
unsigned int K = Cnt + 1; K < NestedLoopCount; ++K)
10421 Prod = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.
get(),
10422 IterSpaces[K].NumIterations);
10427 if (Cnt + 1 < NestedLoopCount)
10432 if (!
Iter.isUsable()) {
10441 if (Cnt + 1 < NestedLoopCount)
10446 Acc = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Sub, Acc.
get(), Prod.
get());
10449 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
10451 SemaRef, VD, IS.CounterVar->
getType(), IS.CounterVar->getExprLoc(),
10455 IS.CounterInit, IS.IsNonRectangularLB, Captures);
10456 if (!
Init.isUsable()) {
10461 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
Iter,
10462 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
10463 if (!
Update.isUsable()) {
10471 IS.CounterInit, IS.NumIterations, IS.CounterStep,
10472 IS.Subtract, IS.IsNonRectangularLB, &Captures);
10473 if (!Final.isUsable()) {
10478 if (!
Update.isUsable() || !Final.isUsable()) {
10483 Built.
Counters[Cnt] = IS.CounterVar;
10487 Built.
Finals[Cnt] = Final.get();
10491 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
10510 Built.
PreCond = PreCond.get();
10514 Built.
Inc = Inc.get();
10515 Built.
LB = LB.
get();
10516 Built.
UB = UB.
get();
10517 Built.
IL = IL.
get();
10518 Built.
ST = ST.
get();
10520 Built.
NLB = NextLB.
get();
10521 Built.
NUB = NextUB.
get();
10536 return NestedLoopCount;
10540 auto CollapseClauses =
10541 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
10542 if (CollapseClauses.begin() != CollapseClauses.end())
10543 return (*CollapseClauses.begin())->getNumForLoops();
10548 auto OrderedClauses =
10549 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
10550 if (OrderedClauses.begin() != OrderedClauses.end())
10551 return (*OrderedClauses.begin())->getNumForLoops();
10560 for (
const OMPClause *Clause : Clauses) {
10562 Safelen = cast<OMPSafelenClause>(Clause);
10564 Simdlen = cast<OMPSimdlenClause>(Clause);
10565 if (Safelen && Simdlen)
10569 if (Simdlen && Safelen) {
10583 llvm::APSInt SimdlenRes = SimdlenResult.
Val.
getInt();
10584 llvm::APSInt SafelenRes = SafelenResult.
Val.
getInt();
10589 if (SimdlenRes > SafelenRes) {
10591 diag::err_omp_wrong_simdlen_safelen_values)
10601 DSAStackTy *Stack);
10603bool SemaOpenMP::checkLastPrivateForMappedDirectives(
10611 DSAStack->getMappedDirective() == OMPD_loop &&
10624 if (!checkLastPrivateForMappedDirectives(Clauses))
10627 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
10634 if (NestedLoopCount == 0)
10638 "omp simd loop exprs were not built");
10643 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
10656 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10658 return SimdDirective;
10667 if (!checkLastPrivateForMappedDirectives(Clauses))
10670 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
10677 if (NestedLoopCount == 0)
10681 "omp for loop exprs were not built");
10686 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
10695 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10698 return ForDirective;
10707 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
10711 unsigned NestedLoopCount =
10714 VarsWithImplicitDSA, B);
10715 if (NestedLoopCount == 0)
10719 "omp for simd loop exprs were not built");
10724 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
10737 NestedLoopCount, Clauses, AStmt, B);
10747 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
10748 auto BaseStmt = AStmt;
10749 while (
auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10751 if (
auto *
C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10752 auto S =
C->children();
10753 if (S.begin() == S.end())
10757 for (
Stmt *SectionStmt : llvm::drop_begin(S)) {
10758 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10760 Diag(SectionStmt->getBeginLoc(),
10761 diag::err_omp_sections_substmt_not_section);
10764 cast<OMPSectionDirective>(SectionStmt)
10765 ->setHasCancel(
DSAStack->isCancelRegion());
10768 Diag(AStmt->
getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
10794 if (
auto *CE = dyn_cast<CallExpr>(E))
10795 if (CE->getDirectCallee())
10807 Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt();
10817 Expr *TargetCall =
nullptr;
10819 auto *E = dyn_cast<Expr>(S);
10821 Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10827 if (
auto *BO = dyn_cast<BinaryOperator>(E)) {
10828 if (BO->getOpcode() == BO_Assign)
10831 if (
auto *COCE = dyn_cast<CXXOperatorCallExpr>(E))
10832 if (COCE->getOperator() == OO_Equal)
10847 Clauses, AStmt, TargetCallLoc);
10852 DSAStackTy *Stack) {
10853 bool ErrorFound =
false;
10855 if (
auto *LPC = dyn_cast<OMPLastprivateClause>(
C)) {
10856 for (
Expr *RefExpr : LPC->varlists()) {
10859 Expr *SimpleRefExpr = RefExpr;
10862 auto &&Info = Stack->isLoopControlVariable(D);
10864 S.
Diag(ELoc, diag::err_omp_lastprivate_loop_var_non_loop_iteration)
10865 << getOpenMPDirectiveName(K);
10887 auto *CS = cast<CapturedStmt>(AStmt);
10900 if (NestedLoopCount == 0)
10904 "omp loop exprs were not built");
10908 NestedLoopCount, Clauses, AStmt, B);
10923 auto *CS = cast<CapturedStmt>(AStmt);
10931 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10943 unsigned NestedLoopCount =
10946 VarsWithImplicitDSA, B);
10947 if (NestedLoopCount == 0)
10951 "omp loop exprs were not built");
10954 DSAStack->setParentTeamsRegionLoc(StartLoc);
10957 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10973 auto *CS = cast<CapturedStmt>(AStmt);
10981 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10993 unsigned NestedLoopCount =
10996 VarsWithImplicitDSA, B);
10997 if (NestedLoopCount == 0)
11001 "omp loop exprs were not built");
11006 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11023 auto *CS = cast<CapturedStmt>(AStmt);
11031 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11043 unsigned NestedLoopCount =
11046 VarsWithImplicitDSA, B);
11047 if (NestedLoopCount == 0)
11051 "omp loop exprs were not built");
11056 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11072 auto *CS = cast<CapturedStmt>(AStmt);
11080 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11092 unsigned NestedLoopCount =
11095 VarsWithImplicitDSA, B);
11096 if (NestedLoopCount == 0)
11100 "omp loop exprs were not built");
11105 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11115 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
11122 const OMPClause *Copyprivate =
nullptr;
11123 for (
const OMPClause *Clause : Clauses) {
11127 Copyprivate = Clause;
11128 if (Copyprivate && Nowait) {
11130 diag::err_omp_single_copyprivate_with_nowait);
11170 bool ErrorFound =
false;
11173 bool DependentHint =
false;
11175 if (
C->getClauseKind() == OMPC_hint) {
11177 Diag(
C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
11180 Expr *E = cast<OMPHintClause>(
C)->getHint();
11183 DependentHint =
true;
11186 HintLoc =
C->getBeginLoc();
11192 const auto Pair =
DSAStack->getCriticalWithHint(DirName);
11193 if (Pair.first && DirName.
getName() && !DependentHint) {
11194 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
11195 Diag(StartLoc, diag::err_omp_critical_with_hint);
11197 Diag(HintLoc, diag::note_omp_critical_hint_here)
11198 << 0 <<
toString(Hint, 10,
false);
11200 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
11201 if (
const auto *
C = Pair.first->getSingleClause<
OMPHintClause>()) {
11202 Diag(
C->getBeginLoc(), diag::note_omp_critical_hint_here)
11207 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
11215 EndLoc, Clauses, AStmt);
11216 if (!Pair.first && DirName.
getName() && !DependentHint)
11217 DSAStack->addCriticalWithHint(Dir, Hint);
11227 auto *CS = cast<CapturedStmt>(AStmt);
11238 unsigned NestedLoopCount =
11241 VarsWithImplicitDSA, B);
11242 if (NestedLoopCount == 0)
11246 "omp parallel for loop exprs were not built");
11251 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
11261 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11271 auto *CS = cast<CapturedStmt>(AStmt);
11282 unsigned NestedLoopCount =
11285 VarsWithImplicitDSA, B);
11286 if (NestedLoopCount == 0)
11292 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
11305 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11314 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
11315 auto *CS = cast<CapturedStmt>(AStmt);
11327 DSAStack->getTaskgroupReductionRef());
11336 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
11337 auto *CS = cast<CapturedStmt>(AStmt);
11349 DSAStack->getTaskgroupReductionRef());
11358 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
11359 auto BaseStmt = AStmt;
11360 while (
auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
11362 if (
auto *
C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
11363 auto S =
C->children();
11364 if (S.begin() == S.end())
11368 for (
Stmt *SectionStmt : llvm::drop_begin(S)) {
11369 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
11371 Diag(SectionStmt->getBeginLoc(),
11372 diag::err_omp_parallel_sections_substmt_not_section);
11375 cast<OMPSectionDirective>(SectionStmt)
11376 ->setHasCancel(
DSAStack->isCancelRegion());
11380 diag::err_omp_parallel_sections_not_compound_stmt);
11396 bool ErrorFound =
false;
11398 if (llvm::is_contained(MutuallyExclusiveClauses,
C->getClauseKind())) {
11402 S.
Diag(
C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
11403 << getOpenMPClauseName(
C->getClauseKind())
11425 {OMPC_detach, OMPC_mergeable}))
11428 auto *CS = cast<CapturedStmt>(AStmt);
11439 AStmt,
DSAStack->isCancelRegion());
11455 bool InExContext) {
11457 OMPExecutableDirective::getSingleClause<OMPAtClause>(Clauses);
11459 if (AtC && !InExContext && AtC->
getAtKind() == OMPC_AT_execution) {
11465 OMPExecutableDirective::getSingleClause<OMPSeverityClause>(Clauses);
11467 OMPExecutableDirective::getSingleClause<OMPMessageClause>(Clauses);
11470 if (!AtC || AtC->
getAtKind() == OMPC_AT_compilation) {
11471 if (SeverityC && SeverityC->
getSeverityKind() == OMPC_SEVERITY_warning)
11473 << (ME ? cast<StringLiteral>(ME)->getString() :
"WARNING");
11475 Diag(StartLoc, diag::err_diagnose_if_succeeded)
11476 << (ME ? cast<StringLiteral>(ME)->getString() :
"ERROR");
11477 if (!SeverityC || SeverityC->
getSeverityKind() != OMPC_SEVERITY_warning)
11488 OMPExecutableDirective::getSingleClause<OMPNowaitClause>(Clauses);
11490 !OMPExecutableDirective::getClausesOfKind<OMPDependClause>(Clauses)
11492 if (NowaitC && !HasDependC) {
11493 Diag(StartLoc, diag::err_omp_nowait_clause_without_depend);
11508 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
11514 DSAStack->getTaskgroupReductionRef());
11523 if (
C->getClauseKind() == OMPC_flush)
11524 FC = cast<OMPFlushClause>(
C);
11531 if (
C->getClauseKind() == OMPC_acq_rel ||
11532 C->getClauseKind() == OMPC_acquire ||
11533 C->getClauseKind() == OMPC_release) {
11534 if (MemOrderKind != OMPC_unknown) {
11535 Diag(
C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
11536 << getOpenMPDirectiveName(OMPD_flush) << 1
11538 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
11539 << getOpenMPClauseName(MemOrderKind);
11541 MemOrderKind =
C->getClauseKind();
11542 MemOrderLoc =
C->getBeginLoc();
11546 if (FC && OrderClause) {
11549 Diag(OrderClause->
getBeginLoc(), diag::note_omp_flush_order_clause_here)
11559 if (Clauses.empty()) {
11560 Diag(StartLoc, diag::err_omp_depobj_expected);
11562 }
else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
11563 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
11567 if (Clauses.size() > 2) {
11568 Diag(Clauses[2]->getBeginLoc(),
11569 diag::err_omp_depobj_single_clause_expected);
11571 }
else if (Clauses.size() < 1) {
11572 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
11582 if (Clauses.size() != 1) {
11583 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
11584 diag::err_omp_scan_single_clause_expected);
11589 Scope *ParentS = S->getParent();
11592 return StmtError(
Diag(StartLoc, diag::err_omp_orphaned_device_directive)
11593 << getOpenMPDirectiveName(OMPD_scan) << 5);
11597 if (
DSAStack->doesParentHasScanDirective()) {
11598 Diag(StartLoc, diag::err_omp_several_directives_in_region) <<
"scan";
11600 diag::note_omp_previous_directive)
11604 DSAStack->setParentHasScanDirective(StartLoc);
11612 const OMPClause *DependFound =
nullptr;
11613 const OMPClause *DependSourceClause =
nullptr;
11614 const OMPClause *DependSinkClause =
nullptr;
11615 const OMPClause *DoacrossFound =
nullptr;
11616 const OMPClause *DoacrossSourceClause =
nullptr;
11617 const OMPClause *DoacrossSinkClause =
nullptr;
11618 bool ErrorFound =
false;
11622 auto DOC = dyn_cast<OMPDoacrossClause>(
C);
11623 auto DC = dyn_cast<OMPDependClause>(
C);
11625 DependFound = DC ?
C :
nullptr;
11626 DoacrossFound = DOC ?
C :
nullptr;
11627 OMPDoacrossKind ODK;
11628 if ((DC && DC->getDependencyKind() == OMPC_DEPEND_source) ||
11629 (DOC && (ODK.isSource(DOC)))) {
11630 if ((DC && DependSourceClause) || (DOC && DoacrossSourceClause)) {
11631 Diag(
C->getBeginLoc(), diag::err_omp_more_one_clause)
11632 << getOpenMPDirectiveName(OMPD_ordered)
11633 << getOpenMPClauseName(DC ? OMPC_depend : OMPC_doacross) << 2;
11637 DependSourceClause =
C;
11639 DoacrossSourceClause =
C;
11641 if ((DC && DependSinkClause) || (DOC && DoacrossSinkClause)) {
11642 Diag(
C->getBeginLoc(), diag::err_omp_sink_and_source_not_allowed)
11643 << (DC ?
"depend" :
"doacross") << 0;
11646 }
else if ((DC && DC->getDependencyKind() == OMPC_DEPEND_sink) ||
11647 (DOC && (ODK.isSink(DOC) || ODK.isSinkIter(DOC)))) {
11648 if (DependSourceClause || DoacrossSourceClause) {
11649 Diag(
C->getBeginLoc(), diag::err_omp_sink_and_source_not_allowed)
11650 << (DC ?
"depend" :
"doacross") << 1;
11654 DependSinkClause =
C;
11656 DoacrossSinkClause =
C;
11658 }
else if (
C->getClauseKind() == OMPC_threads) {
11659 TC = cast<OMPThreadsClause>(
C);
11660 }
else if (
C->getClauseKind() == OMPC_simd) {
11661 SC = cast<OMPSIMDClause>(
C);
11664 if (!ErrorFound && !SC &&
11669 Diag(StartLoc, diag::err_omp_prohibited_region_simd)
11672 }
else if ((DependFound || DoacrossFound) && (TC || SC)) {
11675 Diag(Loc, diag::err_omp_depend_clause_thread_simd)
11676 << getOpenMPClauseName(DependFound ? OMPC_depend : OMPC_doacross)
11679 }
else if ((DependFound || DoacrossFound) &&
11680 !
DSAStack->getParentOrderedRegionParam().first) {
11683 Diag(Loc, diag::err_omp_ordered_directive_without_param)
11684 << getOpenMPClauseName(DependFound ? OMPC_depend : OMPC_doacross);
11686 }
else if (TC || Clauses.empty()) {
11687 if (
const Expr *Param =
DSAStack->getParentOrderedRegionParam().first) {
11689 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
11690 << (TC !=
nullptr);
11695 if ((!AStmt && !DependFound && !DoacrossFound) || ErrorFound)
11703 if (!DependFound && !DoacrossFound) {
11704 if (
DSAStack->doesParentHasOrderedDirective()) {
11705 Diag(StartLoc, diag::err_omp_several_directives_in_region) <<
"ordered";
11707 diag::note_omp_previous_directive)
11711 DSAStack->setParentHasOrderedDirective(StartLoc);
11715 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
11727class OpenMPAtomicUpdateChecker {
11729 enum ExprAnalysisErrorCode {
11733 NotABinaryOrUnaryExpression,
11735 NotAnUnaryIncDecExpression,
11741 NotABinaryExpression,
11744 NotABinaryOperator,
11747 NotAnUpdateExpression,
11750 NotAValidExpression,
11768 bool IsXLHSInRHSPart;
11773 bool IsPostfixUpdate;
11776 OpenMPAtomicUpdateChecker(
Sema &SemaRef)
11777 : SemaRef(SemaRef),
X(nullptr), E(nullptr), UpdateExpr(nullptr),
11778 IsXLHSInRHSPart(
false), Op(BO_PtrMemD), IsPostfixUpdate(
false) {}
11786 bool checkStatement(
Stmt *S,
unsigned DiagId = 0,
unsigned NoteId = 0);
11788 Expr *getX()
const {
return X; }
11790 Expr *getExpr()
const {
return E; }
11794 Expr *getUpdateExpr()
const {
return UpdateExpr; }
11797 bool isXLHSInRHSPart()
const {
return IsXLHSInRHSPart; }
11801 bool isPostfixUpdate()
const {
return IsPostfixUpdate; }
11804 bool checkBinaryOperation(
BinaryOperator *AtomicBinOp,
unsigned DiagId = 0,
11805 unsigned NoteId = 0);
11808bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
11809 BinaryOperator *AtomicBinOp,
unsigned DiagId,
unsigned NoteId) {
11810 ExprAnalysisErrorCode ErrorFound = NoError;
11816 if (AtomicBinOp->
getOpcode() == BO_Assign) {
11818 if (
const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
11820 if (AtomicInnerBinOp->isMultiplicativeOp() ||
11821 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
11822 AtomicInnerBinOp->isBitwiseOp()) {
11823 Op = AtomicInnerBinOp->getOpcode();
11824 OpLoc = AtomicInnerBinOp->getOperatorLoc();
11825 Expr *LHS = AtomicInnerBinOp->getLHS();
11826 Expr *RHS = AtomicInnerBinOp->getRHS();
11827 llvm::FoldingSetNodeID XId, LHSId, RHSId;
11834 if (XId == LHSId) {
11836 IsXLHSInRHSPart =
true;
11837 }
else if (XId == RHSId) {
11839 IsXLHSInRHSPart =
false;
11841 ErrorLoc = AtomicInnerBinOp->getExprLoc();
11842 ErrorRange = AtomicInnerBinOp->getSourceRange();
11843 NoteLoc =
X->getExprLoc();
11844 NoteRange =
X->getSourceRange();
11845 ErrorFound = NotAnUpdateExpression;
11848 ErrorLoc = AtomicInnerBinOp->getExprLoc();
11849 ErrorRange = AtomicInnerBinOp->getSourceRange();
11850 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
11852 ErrorFound = NotABinaryOperator;
11857 ErrorFound = NotABinaryExpression;
11864 ErrorFound = NotAnAssignmentOp;
11866 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11867 SemaRef.
Diag(ErrorLoc, DiagId) << ErrorRange;
11868 SemaRef.
Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11872 E =
X = UpdateExpr =
nullptr;
11873 return ErrorFound != NoError;
11876bool OpenMPAtomicUpdateChecker::checkStatement(
Stmt *S,
unsigned DiagId,
11878 ExprAnalysisErrorCode ErrorFound = NoError;
11889 if (
auto *AtomicBody = dyn_cast<Expr>(S)) {
11890 AtomicBody = AtomicBody->IgnoreParenImpCasts();
11891 if (AtomicBody->getType()->isScalarType() ||
11892 AtomicBody->isInstantiationDependent()) {
11893 if (
const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
11894 AtomicBody->IgnoreParenImpCasts())) {
11897 AtomicCompAssignOp->getOpcode());
11898 OpLoc = AtomicCompAssignOp->getOperatorLoc();
11899 E = AtomicCompAssignOp->getRHS();
11900 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
11901 IsXLHSInRHSPart =
true;
11902 }
else if (
auto *AtomicBinOp = dyn_cast<BinaryOperator>(
11903 AtomicBody->IgnoreParenImpCasts())) {
11905 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
11907 }
else if (
const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
11908 AtomicBody->IgnoreParenImpCasts())) {
11910 if (AtomicUnaryOp->isIncrementDecrementOp()) {
11911 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
11912 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
11913 OpLoc = AtomicUnaryOp->getOperatorLoc();
11914 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
11916 IsXLHSInRHSPart =
true;
11918 ErrorFound = NotAnUnaryIncDecExpression;
11919 ErrorLoc = AtomicUnaryOp->getExprLoc();
11920 ErrorRange = AtomicUnaryOp->getSourceRange();
11921 NoteLoc = AtomicUnaryOp->getOperatorLoc();
11924 }
else if (!AtomicBody->isInstantiationDependent()) {
11925 ErrorFound = NotABinaryOrUnaryExpression;
11926 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
11927 NoteRange = ErrorRange = AtomicBody->getSourceRange();
11928 }
else if (AtomicBody->containsErrors()) {
11929 ErrorFound = NotAValidExpression;
11930 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
11931 NoteRange = ErrorRange = AtomicBody->getSourceRange();
11934 ErrorFound = NotAScalarType;
11935 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
11936 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
11939 ErrorFound = NotAnExpression;
11940 NoteLoc = ErrorLoc = S->getBeginLoc();
11941 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
11943 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11944 SemaRef.
Diag(ErrorLoc, DiagId) << ErrorRange;
11945 SemaRef.
Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11949 E =
X = UpdateExpr =
nullptr;
11950 if (ErrorFound == NoError && E &&
X) {
11960 IsXLHSInRHSPart ? OVEExpr : OVEX);
11967 UpdateExpr =
Update.get();
11969 return ErrorFound != NoError;
11973llvm::FoldingSetNodeID getNodeId(
ASTContext &Context,
const Expr *S) {
11974 llvm::FoldingSetNodeID
Id;
11975 S->IgnoreParenImpCasts()->Profile(
Id, Context,
true);
11980bool checkIfTwoExprsAreSame(
ASTContext &Context,
const Expr *LHS,
11982 return getNodeId(Context, LHS) == getNodeId(Context, RHS);
11985class OpenMPAtomicCompareChecker {
12032 struct ErrorInfoTy {
12040 OpenMPAtomicCompareChecker(
Sema &S) : ContextRef(S.getASTContext()) {}
12043 bool checkStmt(
Stmt *S, ErrorInfoTy &ErrorInfo);
12045 Expr *getX()
const {
return X; }
12046 Expr *getE()
const {
return E; }
12047 Expr *getD()
const {
return D; }
12048 Expr *getCond()
const {
return C; }
12049 bool isXBinopExpr()
const {
return IsXBinopExpr; }
12068 bool IsXBinopExpr =
true;
12071 bool checkCondUpdateStmt(
IfStmt *S, ErrorInfoTy &ErrorInfo);
12074 bool checkCondExprStmt(
Stmt *S, ErrorInfoTy &ErrorInfo);
12077 bool checkType(ErrorInfoTy &ErrorInfo)
const;
12079 static bool CheckValue(
const Expr *E, ErrorInfoTy &ErrorInfo,
12080 bool ShouldBeLValue,
bool ShouldBeInteger =
false) {
12084 if (ShouldBeLValue && !E->
isLValue()) {
12085 ErrorInfo.Error = ErrorTy::XNotLValue;
12086 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->
getExprLoc();
12087 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->
getSourceRange();
12093 ErrorInfo.Error = ErrorTy::NotScalar;
12094 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->
getExprLoc();
12095 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->
getSourceRange();
12099 ErrorInfo.Error = ErrorTy::NotInteger;
12100 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->
getExprLoc();
12101 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->
getSourceRange();
12109bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(
IfStmt *S,
12110 ErrorInfoTy &ErrorInfo) {
12111 auto *Then = S->getThen();
12112 if (
auto *CS = dyn_cast<CompoundStmt>(Then)) {
12113 if (CS->body_empty()) {
12114 ErrorInfo.Error = ErrorTy::NoStmt;
12115 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12116 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12119 if (CS->size() > 1) {
12120 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12121 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12122 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12125 Then = CS->body_front();
12128 auto *BO = dyn_cast<BinaryOperator>(Then);
12130 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12131 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
12132 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
12135 if (BO->getOpcode() != BO_Assign) {
12136 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12137 ErrorInfo.ErrorLoc = BO->getExprLoc();
12138 ErrorInfo.NoteLoc = BO->getOperatorLoc();
12139 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12145 auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
12147 ErrorInfo.Error = ErrorTy::NotABinaryOp;
12148 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
12149 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
12153 switch (Cond->getOpcode()) {
12157 if (checkIfTwoExprsAreSame(ContextRef,
X, Cond->getLHS())) {
12158 E = Cond->getRHS();
12159 }
else if (checkIfTwoExprsAreSame(ContextRef,
X, Cond->getRHS())) {
12160 E = Cond->getLHS();
12162 ErrorInfo.Error = ErrorTy::InvalidComparison;
12163 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->
getExprLoc();
12164 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
12172 if (checkIfTwoExprsAreSame(ContextRef,
X, Cond->getLHS()) &&
12173 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
12175 }
else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
12176 checkIfTwoExprsAreSame(ContextRef,
X, Cond->getRHS())) {
12178 IsXBinopExpr =
false;
12180 ErrorInfo.Error = ErrorTy::InvalidComparison;
12181 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->
getExprLoc();
12182 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
12188 ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
12189 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->
getExprLoc();
12190 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
12194 if (S->getElse()) {
12195 ErrorInfo.Error = ErrorTy::UnexpectedElse;
12196 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc();
12197 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getElse()->getSourceRange();
12204bool OpenMPAtomicCompareChecker::checkCondExprStmt(
Stmt *S,
12205 ErrorInfoTy &ErrorInfo) {
12206 auto *BO = dyn_cast<BinaryOperator>(S);
12208 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12209 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12210 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12213 if (BO->getOpcode() != BO_Assign) {
12214 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12215 ErrorInfo.ErrorLoc = BO->getExprLoc();
12216 ErrorInfo.NoteLoc = BO->getOperatorLoc();
12217 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12223 auto *CO = dyn_cast<ConditionalOperator>(BO->getRHS()->IgnoreParenImpCasts());
12225 ErrorInfo.Error = ErrorTy::NotCondOp;
12226 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getRHS()->getExprLoc();
12227 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getRHS()->getSourceRange();
12231 if (!checkIfTwoExprsAreSame(ContextRef,
X, CO->getFalseExpr())) {
12232 ErrorInfo.Error = ErrorTy::WrongFalseExpr;
12233 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getFalseExpr()->getExprLoc();
12234 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12235 CO->getFalseExpr()->getSourceRange();
12239 auto *Cond = dyn_cast<BinaryOperator>(CO->getCond());
12241 ErrorInfo.Error = ErrorTy::NotABinaryOp;
12242 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getCond()->getExprLoc();
12243 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12244 CO->getCond()->getSourceRange();
12248 switch (Cond->getOpcode()) {
12251 D = CO->getTrueExpr();
12252 if (checkIfTwoExprsAreSame(ContextRef,
X, Cond->getLHS())) {
12253 E = Cond->getRHS();
12254 }
else if (checkIfTwoExprsAreSame(ContextRef,
X, Cond->getRHS())) {
12255 E = Cond->getLHS();
12257 ErrorInfo.Error = ErrorTy::InvalidComparison;
12258 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->
getExprLoc();
12259 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
12266 E = CO->getTrueExpr();
12267 if (checkIfTwoExprsAreSame(ContextRef,
X, Cond->getLHS()) &&
12268 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
12270 }
else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
12271 checkIfTwoExprsAreSame(ContextRef,
X, Cond->getRHS())) {
12273 IsXBinopExpr =
false;
12275 ErrorInfo.Error = ErrorTy::InvalidComparison;
12276 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->
getExprLoc();
12277 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
12283 ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
12284 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->
getExprLoc();
12285 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
12292bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo)
const {
12294 assert(
X && E &&
"X and E cannot be nullptr");
12296 if (!CheckValue(
X, ErrorInfo,
true))
12299 if (!CheckValue(E, ErrorInfo,
false))
12302 if (D && !CheckValue(D, ErrorInfo,
false))
12308bool OpenMPAtomicCompareChecker::checkStmt(
12309 Stmt *S, OpenMPAtomicCompareChecker::ErrorInfoTy &ErrorInfo) {
12310 auto *CS = dyn_cast<CompoundStmt>(S);
12312 if (CS->body_empty()) {
12313 ErrorInfo.Error = ErrorTy::NoStmt;
12314 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12315 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12319 if (CS->size() != 1) {
12320 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12321 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12322 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12325 S = CS->body_front();
12330 if (
auto *IS = dyn_cast<IfStmt>(S)) {
12336 Res = checkCondUpdateStmt(IS, ErrorInfo);
12342 Res = checkCondExprStmt(S, ErrorInfo);
12348 return checkType(ErrorInfo);
12351class OpenMPAtomicCompareCaptureChecker final
12352 :
public OpenMPAtomicCompareChecker {
12354 OpenMPAtomicCompareCaptureChecker(
Sema &S) : OpenMPAtomicCompareChecker(S) {}
12356 Expr *getV()
const {
return V; }
12357 Expr *getR()
const {
return R; }
12358 bool isFailOnly()
const {
return IsFailOnly; }
12359 bool isPostfixUpdate()
const {
return IsPostfixUpdate; }
12362 bool checkStmt(
Stmt *S, ErrorInfoTy &ErrorInfo);
12365 bool checkType(ErrorInfoTy &ErrorInfo);
12377 bool checkForm3(
IfStmt *S, ErrorInfoTy &ErrorInfo);
12381 bool checkForm45(
Stmt *S, ErrorInfoTy &ErrorInfo);
12388 bool IsFailOnly =
false;
12390 bool IsPostfixUpdate =
false;
12393bool OpenMPAtomicCompareCaptureChecker::checkType(ErrorInfoTy &ErrorInfo) {
12394 if (!OpenMPAtomicCompareChecker::checkType(ErrorInfo))
12397 if (
V && !CheckValue(
V, ErrorInfo,
true))
12400 if (R && !CheckValue(R, ErrorInfo,
true,
true))
12406bool OpenMPAtomicCompareCaptureChecker::checkForm3(
IfStmt *S,
12407 ErrorInfoTy &ErrorInfo) {
12410 auto *Then = S->getThen();
12411 if (
auto *CS = dyn_cast<CompoundStmt>(Then)) {
12412 if (CS->body_empty()) {
12413 ErrorInfo.Error = ErrorTy::NoStmt;
12414 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12415 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12418 if (CS->size() > 1) {
12419 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12420 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12421 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12424 Then = CS->body_front();
12427 auto *BO = dyn_cast<BinaryOperator>(Then);
12429 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12430 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
12431 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
12434 if (BO->getOpcode() != BO_Assign) {
12435 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12436 ErrorInfo.ErrorLoc = BO->getExprLoc();
12437 ErrorInfo.NoteLoc = BO->getOperatorLoc();
12438 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12445 auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
12447 ErrorInfo.Error = ErrorTy::NotABinaryOp;
12448 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
12449 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
12452 if (Cond->getOpcode() != BO_EQ) {
12453 ErrorInfo.Error = ErrorTy::NotEQ;
12454 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->
getExprLoc();
12455 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
12459 if (checkIfTwoExprsAreSame(ContextRef,
X, Cond->getLHS())) {
12460 E = Cond->getRHS();
12461 }
else if (checkIfTwoExprsAreSame(ContextRef,
X, Cond->getRHS())) {
12462 E = Cond->getLHS();
12464 ErrorInfo.Error = ErrorTy::InvalidComparison;
12465 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->
getExprLoc();
12466 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
12472 if (!S->getElse()) {
12473 ErrorInfo.Error = ErrorTy::NoElse;
12474 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12475 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12479 auto *Else = S->getElse();
12480 if (
auto *CS = dyn_cast<CompoundStmt>(Else)) {
12481 if (CS->body_empty()) {
12482 ErrorInfo.Error = ErrorTy::NoStmt;
12483 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12484 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12487 if (CS->size() > 1) {
12488 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12489 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12490 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12493 Else = CS->body_front();
12496 auto *ElseBO = dyn_cast<BinaryOperator>(Else);
12498 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12499 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
12500 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
12503 if (ElseBO->getOpcode() != BO_Assign) {
12504 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12505 ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
12506 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12507 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12511 if (!checkIfTwoExprsAreSame(ContextRef,
X, ElseBO->getRHS())) {
12512 ErrorInfo.Error = ErrorTy::InvalidAssignment;
12513 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseBO->getRHS()->getExprLoc();
12514 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12515 ElseBO->getRHS()->getSourceRange();
12519 V = ElseBO->getLHS();
12521 return checkType(ErrorInfo);
12524bool OpenMPAtomicCompareCaptureChecker::checkForm45(
Stmt *S,
12525 ErrorInfoTy &ErrorInfo) {
12528 auto *CS = cast<CompoundStmt>(S);
12529 assert(CS->size() == 2 &&
"CompoundStmt size is not expected");
12530 auto *S1 = cast<BinaryOperator>(CS->body_front());
12531 auto *S2 = cast<IfStmt>(CS->body_back());
12532 assert(S1->getOpcode() == BO_Assign &&
"unexpected binary operator");
12534 if (!checkIfTwoExprsAreSame(ContextRef, S1->getLHS(), S2->getCond())) {
12535 ErrorInfo.Error = ErrorTy::InvalidCondition;
12536 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getCond()->getExprLoc();
12537 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S1->getLHS()->getSourceRange();
12543 auto *Then = S2->getThen();
12544 if (
auto *ThenCS = dyn_cast<CompoundStmt>(Then)) {
12545 if (ThenCS->body_empty()) {
12546 ErrorInfo.Error = ErrorTy::NoStmt;
12547 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12548 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12551 if (ThenCS->size() > 1) {
12552 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12553 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12554 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12557 Then = ThenCS->body_front();
12560 auto *ThenBO = dyn_cast<BinaryOperator>(Then);
12562 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12563 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getBeginLoc();
12564 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S2->getSourceRange();
12567 if (ThenBO->getOpcode() != BO_Assign) {
12568 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12569 ErrorInfo.ErrorLoc = ThenBO->getExprLoc();
12570 ErrorInfo.NoteLoc = ThenBO->getOperatorLoc();
12571 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenBO->getSourceRange();
12575 X = ThenBO->getLHS();
12576 D = ThenBO->getRHS();
12578 auto *BO = cast<BinaryOperator>(S1->getRHS()->IgnoreImpCasts());
12579 if (BO->getOpcode() != BO_EQ) {
12580 ErrorInfo.Error = ErrorTy::NotEQ;
12581 ErrorInfo.ErrorLoc = BO->getExprLoc();
12582 ErrorInfo.NoteLoc = BO->getOperatorLoc();
12583 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12589 if (checkIfTwoExprsAreSame(ContextRef,
X, BO->getLHS())) {
12591 }
else if (checkIfTwoExprsAreSame(ContextRef,
X, BO->getRHS())) {
12594 ErrorInfo.Error = ErrorTy::InvalidComparison;
12595 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->
getExprLoc();
12596 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12600 if (S2->getElse()) {
12603 auto *Else = S2->getElse();
12604 if (
auto *ElseCS = dyn_cast<CompoundStmt>(Else)) {
12605 if (ElseCS->body_empty()) {
12606 ErrorInfo.Error = ErrorTy::NoStmt;
12607 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12608 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12611 if (ElseCS->size() > 1) {
12612 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12613 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12614 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12617 Else = ElseCS->body_front();
12620 auto *ElseBO = dyn_cast<BinaryOperator>(Else);
12622 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12623 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
12624 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
12627 if (ElseBO->getOpcode() != BO_Assign) {
12628 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12629 ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
12630 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12631 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12634 if (!checkIfTwoExprsAreSame(ContextRef,
X, ElseBO->getRHS())) {
12635 ErrorInfo.Error = ErrorTy::InvalidAssignment;
12636 ErrorInfo.ErrorLoc = ElseBO->getRHS()->getExprLoc();
12637 ErrorInfo.NoteLoc =
X->getExprLoc();
12638 ErrorInfo.ErrorRange = ElseBO->getRHS()->getSourceRange();
12639 ErrorInfo.NoteRange =
X->getSourceRange();
12643 V = ElseBO->getLHS();
12646 return checkType(ErrorInfo);
12649bool OpenMPAtomicCompareCaptureChecker::checkStmt(
Stmt *S,
12650 ErrorInfoTy &ErrorInfo) {
12652 if (
auto *IS = dyn_cast<IfStmt>(S))
12653 return checkForm3(IS, ErrorInfo);
12655 auto *CS = dyn_cast<CompoundStmt>(S);
12657 ErrorInfo.Error = ErrorTy::NotCompoundStmt;
12658 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12659 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12662 if (CS->body_empty()) {
12663 ErrorInfo.Error = ErrorTy::NoStmt;
12664 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12665 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12670 if (CS->size() == 1) {
12671 auto *IS = dyn_cast<IfStmt>(CS->body_front());
12673 ErrorInfo.Error = ErrorTy::NotIfStmt;
12674 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->body_front()->
getBeginLoc();
12675 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12680 return checkForm3(IS, ErrorInfo);
12681 }
else if (CS->size() == 2) {
12682 auto *S1 = CS->body_front();
12683 auto *S2 = CS->body_back();
12685 Stmt *UpdateStmt =
nullptr;
12686 Stmt *CondUpdateStmt =
nullptr;
12687 Stmt *CondExprStmt =
nullptr;
12689 if (
auto *BO = dyn_cast<BinaryOperator>(S1)) {
12695 if (isa<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) ||
12696 isa<ConditionalOperator>(BO->getRHS()->IgnoreImpCasts())) {
12698 if (isa<IfStmt>(S2))
12699 return checkForm45(CS, ErrorInfo);
12704 IsPostfixUpdate =
true;
12706 if (isa<IfStmt>(S2)) {
12708 CondUpdateStmt = S2;
12717 CondUpdateStmt = S1;
12720 auto CheckCondUpdateStmt = [
this, &ErrorInfo](
Stmt *CUS) {
12721 auto *IS = dyn_cast<IfStmt>(CUS);
12723 ErrorInfo.Error = ErrorTy::NotIfStmt;
12724 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CUS->getBeginLoc();
12725 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CUS->getSourceRange();
12729 return checkCondUpdateStmt(IS, ErrorInfo);
12733 auto CheckUpdateStmt = [
this, &ErrorInfo](
Stmt *US) {
12734 auto *BO = dyn_cast<BinaryOperator>(US);
12736 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12737 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = US->getBeginLoc();
12738 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = US->getSourceRange();
12741 if (BO->getOpcode() != BO_Assign) {
12742 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12743 ErrorInfo.ErrorLoc = BO->getExprLoc();
12744 ErrorInfo.NoteLoc = BO->getOperatorLoc();
12745 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12748 if (!checkIfTwoExprsAreSame(ContextRef, this->X, BO->getRHS())) {
12749 ErrorInfo.Error = ErrorTy::InvalidAssignment;
12750 ErrorInfo.ErrorLoc = BO->getRHS()->getExprLoc();
12752 ErrorInfo.ErrorRange = BO->getRHS()->getSourceRange();
12757 this->
V = BO->getLHS();
12762 if (CondUpdateStmt && !CheckCondUpdateStmt(CondUpdateStmt))
12764 if (CondExprStmt && !checkCondExprStmt(CondExprStmt, ErrorInfo))
12766 if (!CheckUpdateStmt(UpdateStmt))
12769 ErrorInfo.Error = ErrorTy::MoreThanTwoStmts;
12770 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12771 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12775 return checkType(ErrorInfo);
12785 DSAStack->addAtomicDirectiveLoc(StartLoc);
12798 bool MutexClauseEncountered =
false;
12799 llvm::SmallSet<OpenMPClauseKind, 2> EncounteredAtomicKinds;
12801 switch (
C->getClauseKind()) {
12805 MutexClauseEncountered =
true;
12808 case OMPC_compare: {
12809 if (AtomicKind != OMPC_unknown && MutexClauseEncountered) {
12810 Diag(
C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12812 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12813 << getOpenMPClauseName(AtomicKind);
12815 AtomicKind =
C->getClauseKind();
12816 AtomicKindLoc =
C->getBeginLoc();
12817 if (!EncounteredAtomicKinds.insert(
C->getClauseKind()).second) {
12818 Diag(
C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12820 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12821 << getOpenMPClauseName(AtomicKind);
12828 if (!EncounteredAtomicKinds.contains(OMPC_compare)) {
12829 Diag(
C->getBeginLoc(), diag::err_omp_atomic_no_compare)
12830 << getOpenMPClauseName(
C->getClauseKind())
12840 case OMPC_relaxed: {
12841 if (MemOrderKind != OMPC_unknown) {
12842 Diag(
C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
12843 << getOpenMPDirectiveName(OMPD_atomic) << 0
12845 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12846 << getOpenMPClauseName(MemOrderKind);
12848 MemOrderKind =
C->getClauseKind();
12849 MemOrderLoc =
C->getBeginLoc();
12857 llvm_unreachable(
"unknown clause is encountered");
12860 bool IsCompareCapture =
false;
12861 if (EncounteredAtomicKinds.contains(OMPC_compare) &&
12862 EncounteredAtomicKinds.contains(OMPC_capture)) {
12863 IsCompareCapture =
true;
12864 AtomicKind = OMPC_compare;
12873 if ((AtomicKind == OMPC_read &&
12874 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
12875 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
12876 AtomicKind == OMPC_unknown) &&
12877 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
12879 if (AtomicKind == OMPC_unknown)
12881 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
12882 << getOpenMPClauseName(AtomicKind)
12883 << (AtomicKind == OMPC_unknown ? 1 : 0)
12884 << getOpenMPClauseName(MemOrderKind);
12885 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12886 << getOpenMPClauseName(MemOrderKind);
12889 Stmt *Body = AStmt;
12890 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Body))
12891 Body = EWC->getSubExpr();
12896 Expr *UE =
nullptr;
12898 Expr *CE =
nullptr;
12900 bool IsXLHSInRHSPart =
false;
12901 bool IsPostfixUpdate =
false;
12902 bool IsFailOnly =
false;
12925 if (AtomicKind == OMPC_read) {
12932 } ErrorFound = NoError;
12937 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12938 const auto *AtomicBinOp =
12939 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12940 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
12943 if ((
X->isInstantiationDependent() ||
X->getType()->isScalarType()) &&
12944 (
V->isInstantiationDependent() ||
V->getType()->isScalarType())) {
12945 if (!
X->isLValue() || !
V->isLValue()) {
12946 const Expr *NotLValueExpr =
X->isLValue() ?
V :
X;
12947 ErrorFound = NotAnLValue;
12953 }
else if (!
X->isInstantiationDependent() ||
12954 !
V->isInstantiationDependent()) {
12955 const Expr *NotScalarExpr =
12956 (
X->isInstantiationDependent() ||
X->getType()->isScalarType())
12959 ErrorFound = NotAScalarType;
12965 }
else if (!AtomicBody->isInstantiationDependent()) {
12966 ErrorFound = NotAnAssignmentOp;
12967 ErrorLoc = AtomicBody->getExprLoc();
12968 ErrorRange = AtomicBody->getSourceRange();
12970 : AtomicBody->getExprLoc();
12972 : AtomicBody->getSourceRange();
12975 ErrorFound = NotAnExpression;
12977 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
12979 if (ErrorFound != NoError) {
12980 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
12982 Diag(NoteLoc, diag::note_omp_atomic_read_write)
12983 << ErrorFound << NoteRange;
12988 }
else if (AtomicKind == OMPC_write) {
12995 } ErrorFound = NoError;
13000 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
13001 const auto *AtomicBinOp =
13002 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
13003 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
13005 E = AtomicBinOp->
getRHS();
13006 if ((
X->isInstantiationDependent() ||
X->getType()->isScalarType()) &&
13008 if (!
X->isLValue()) {
13009 ErrorFound = NotAnLValue;
13012 NoteLoc =
X->getExprLoc();
13013 NoteRange =
X->getSourceRange();
13015 }
else if (!
X->isInstantiationDependent() ||
13017 const Expr *NotScalarExpr =
13018 (
X->isInstantiationDependent() ||
X->getType()->isScalarType())
13021 ErrorFound = NotAScalarType;
13027 }
else if (!AtomicBody->isInstantiationDependent()) {
13028 ErrorFound = NotAnAssignmentOp;
13029 ErrorLoc = AtomicBody->getExprLoc();
13030 ErrorRange = AtomicBody->getSourceRange();
13032 : AtomicBody->getExprLoc();
13034 : AtomicBody->getSourceRange();
13037 ErrorFound = NotAnExpression;
13039 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
13041 if (ErrorFound != NoError) {
13042 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
13044 Diag(NoteLoc, diag::note_omp_atomic_read_write)
13045 << ErrorFound << NoteRange;
13050 }
else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
13059 OpenMPAtomicUpdateChecker Checker(
SemaRef);
13060 if (Checker.checkStatement(
13062 (AtomicKind == OMPC_update)
13063 ? diag::err_omp_atomic_update_not_expression_statement
13064 : diag::err_omp_atomic_not_expression_statement,
13065 diag::note_omp_atomic_update))
13068 E = Checker.getExpr();
13069 X = Checker.getX();
13070 UE = Checker.getUpdateExpr();
13071 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
13073 }
else if (AtomicKind == OMPC_capture) {
13076 NotACompoundStatement,
13077 NotTwoSubstatements,
13078 NotASpecificExpression,
13080 } ErrorFound = NoError;
13083 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
13092 const auto *AtomicBinOp =
13093 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
13094 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
13097 OpenMPAtomicUpdateChecker Checker(
SemaRef);
13098 if (Checker.checkStatement(
13099 Body, diag::err_omp_atomic_capture_not_expression_statement,
13100 diag::note_omp_atomic_update))
13102 E = Checker.getExpr();
13103 X = Checker.getX();
13104 UE = Checker.getUpdateExpr();
13105 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
13106 IsPostfixUpdate = Checker.isPostfixUpdate();
13107 }
else if (!AtomicBody->isInstantiationDependent()) {
13108 ErrorLoc = AtomicBody->getExprLoc();
13109 ErrorRange = AtomicBody->getSourceRange();
13111 : AtomicBody->getExprLoc();
13113 : AtomicBody->getSourceRange();
13114 ErrorFound = NotAnAssignmentOp;
13116 if (ErrorFound != NoError) {
13117 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
13119 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
13123 UE =
V = E =
X =
nullptr;
13141 if (
auto *CS = dyn_cast<CompoundStmt>(Body)) {
13143 if (CS->size() == 2) {
13145 Stmt *Second = CS->body_back();
13146 if (
auto *EWC = dyn_cast<ExprWithCleanups>(
First))
13147 First = EWC->getSubExpr()->IgnoreParenImpCasts();
13148 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Second))
13149 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
13151 OpenMPAtomicUpdateChecker Checker(
SemaRef);
13152 bool IsUpdateExprFound = !Checker.checkStatement(Second);
13154 if (IsUpdateExprFound) {
13155 BinOp = dyn_cast<BinaryOperator>(
First);
13156 IsUpdateExprFound = BinOp && BinOp->
getOpcode() == BO_Assign;
13168 llvm::FoldingSetNodeID XId, PossibleXId;
13169 Checker.getX()->
Profile(XId, Context,
true);
13170 PossibleX->
Profile(PossibleXId, Context,
true);
13171 IsUpdateExprFound = XId == PossibleXId;
13172 if (IsUpdateExprFound) {
13174 X = Checker.getX();
13175 E = Checker.getExpr();
13176 UE = Checker.getUpdateExpr();
13177 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
13178 IsPostfixUpdate =
true;
13181 if (!IsUpdateExprFound) {
13182 IsUpdateExprFound = !Checker.checkStatement(
First);
13184 if (IsUpdateExprFound) {
13185 BinOp = dyn_cast<BinaryOperator>(Second);
13186 IsUpdateExprFound = BinOp && BinOp->
getOpcode() == BO_Assign;
13188 if (IsUpdateExprFound &&
13199 llvm::FoldingSetNodeID XId, PossibleXId;
13200 Checker.getX()->
Profile(XId, Context,
true);
13201 PossibleX->
Profile(PossibleXId, Context,
true);
13202 IsUpdateExprFound = XId == PossibleXId;
13203 if (IsUpdateExprFound) {
13205 X = Checker.getX();
13206 E = Checker.getExpr();
13207 UE = Checker.getUpdateExpr();
13208 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
13209 IsPostfixUpdate =
false;
13213 if (!IsUpdateExprFound) {
13215 auto *FirstExpr = dyn_cast<Expr>(
First);
13216 auto *SecondExpr = dyn_cast<Expr>(Second);
13217 if (!FirstExpr || !SecondExpr ||
13218 !(FirstExpr->isInstantiationDependent() ||
13219 SecondExpr->isInstantiationDependent())) {
13220 auto *FirstBinOp = dyn_cast<BinaryOperator>(
First);
13221 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
13222 ErrorFound = NotAnAssignmentOp;
13223 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
13224 :
First->getBeginLoc();
13225 NoteRange = ErrorRange = FirstBinOp
13226 ? FirstBinOp->getSourceRange()
13229 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
13230 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
13231 ErrorFound = NotAnAssignmentOp;
13232 NoteLoc = ErrorLoc = SecondBinOp
13233 ? SecondBinOp->getOperatorLoc()
13235 NoteRange = ErrorRange =
13236 SecondBinOp ? SecondBinOp->getSourceRange()
13239 Expr *PossibleXRHSInFirst =
13241 Expr *PossibleXLHSInSecond =
13243 llvm::FoldingSetNodeID X1Id, X2Id;
13244 PossibleXRHSInFirst->
Profile(X1Id, Context,
13246 PossibleXLHSInSecond->
Profile(X2Id, Context,
13248 IsUpdateExprFound = X1Id == X2Id;
13249 if (IsUpdateExprFound) {
13250 V = FirstBinOp->getLHS();
13251 X = SecondBinOp->getLHS();
13252 E = SecondBinOp->getRHS();
13254 IsXLHSInRHSPart =
false;
13255 IsPostfixUpdate =
true;
13257 ErrorFound = NotASpecificExpression;
13258 ErrorLoc = FirstBinOp->getExprLoc();
13259 ErrorRange = FirstBinOp->getSourceRange();
13260 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
13261 NoteRange = SecondBinOp->getRHS()->getSourceRange();
13269 NoteRange = ErrorRange =
13271 ErrorFound = NotTwoSubstatements;
13275 NoteRange = ErrorRange =
13277 ErrorFound = NotACompoundStatement;
13280 if (ErrorFound != NoError) {
13281 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
13283 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
13287 UE =
V = E =
X =
nullptr;
13288 }
else if (AtomicKind == OMPC_compare) {
13289 if (IsCompareCapture) {
13290 OpenMPAtomicCompareCaptureChecker::ErrorInfoTy ErrorInfo;
13291 OpenMPAtomicCompareCaptureChecker Checker(
SemaRef);
13292 if (!Checker.checkStmt(Body, ErrorInfo)) {
13293 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare_capture)
13294 << ErrorInfo.ErrorRange;
13295 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
13296 << ErrorInfo.Error << ErrorInfo.NoteRange;
13299 X = Checker.getX();
13300 E = Checker.getE();
13301 D = Checker.getD();
13302 CE = Checker.getCond();
13303 V = Checker.getV();
13304 R = Checker.getR();
13306 IsXLHSInRHSPart = Checker.isXBinopExpr();
13307 IsFailOnly = Checker.isFailOnly();
13308 IsPostfixUpdate = Checker.isPostfixUpdate();
13310 OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo;
13311 OpenMPAtomicCompareChecker Checker(
SemaRef);
13312 if (!Checker.checkStmt(Body, ErrorInfo)) {
13313 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare)
13314 << ErrorInfo.ErrorRange;
13315 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
13316 << ErrorInfo.Error << ErrorInfo.NoteRange;
13319 X = Checker.getX();
13320 E = Checker.getE();
13321 D = Checker.getD();
13322 CE = Checker.getCond();
13328 auto *It = find_if(Clauses, [](
OMPClause *
C) {
13329 return C->getClauseKind() == llvm::omp::Clause::OMPC_weak;
13331 if (It != Clauses.end()) {
13332 auto *Cond = dyn_cast<BinaryOperator>(CE);
13333 if (Cond->getOpcode() != BO_EQ) {
13334 ErrorInfo.Error = Checker.ErrorTy::NotAnAssignment;
13336 ErrorInfo.NoteLoc = Cond->getOperatorLoc();
13337 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
13339 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_weak_no_equality)
13340 << ErrorInfo.ErrorRange;
13345 IsXLHSInRHSPart = Checker.isXBinopExpr();
13352 Context, StartLoc, EndLoc, Clauses, AStmt,
13353 {
X,
V, R, E, UE, D, CE, IsXLHSInRHSPart, IsPostfixUpdate, IsFailOnly});
13363 auto *CS = cast<CapturedStmt>(AStmt);
13371 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13385 if (
DSAStack->hasInnerTeamsRegion()) {
13387 bool OMPTeamsFound =
true;
13388 if (
const auto *CS = dyn_cast<CompoundStmt>(S)) {
13389 auto I = CS->body_begin();
13390 while (I != CS->body_end()) {
13391 const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
13395 OMPTeamsFound =
false;
13400 assert(I != CS->body_end() &&
"Not found statement");
13403 const auto *OED = dyn_cast<OMPExecutableDirective>(S);
13406 if (!OMPTeamsFound) {
13407 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
13409 diag::note_omp_nested_teams_construct_here);
13410 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
13411 << isa<OMPExecutableDirective>(S);
13428 auto *CS = cast<CapturedStmt>(AStmt);
13436 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13459 auto *CS = cast<CapturedStmt>(AStmt);
13467 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13480 unsigned NestedLoopCount =
13483 VarsWithImplicitDSA, B);
13484 if (NestedLoopCount == 0)
13488 "omp target parallel for loop exprs were not built");
13493 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
13503 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13510 return llvm::any_of(
13511 Clauses, [K](
const OMPClause *
C) {
return C->getClauseKind() == K; });
13514template <
typename... Params>
13516 const Params... ClauseTypes) {
13523 if (
auto *TC = dyn_cast<OMPToClause>(
C))
13524 return llvm::all_of(TC->all_decls(), [](
ValueDecl *VD) {
13525 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13526 (VD->isExternallyVisible() &&
13527 VD->getVisibility() != HiddenVisibility);
13529 else if (
auto *FC = dyn_cast<OMPFromClause>(
C))
13530 return llvm::all_of(FC->all_decls(), [](
ValueDecl *VD) {
13531 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13532 (VD->isExternallyVisible() &&
13533 VD->getVisibility() != HiddenVisibility);
13547 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13552 if (!
hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
13554 !
hasClauses(Clauses, OMPC_use_device_addr))) {
13557 Expected =
"'map' or 'use_device_ptr'";
13559 Expected =
"'map', 'use_device_ptr', or 'use_device_addr'";
13560 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13561 <<
Expected << getOpenMPDirectiveName(OMPD_target_data);
13577 auto *CS = cast<CapturedStmt>(AStmt);
13585 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13598 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13599 <<
"'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
13613 auto *CS = cast<CapturedStmt>(AStmt);
13621 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13634 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13635 <<
"'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
13649 auto *CS = cast<CapturedStmt>(AStmt);
13657 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13667 if (!
hasClauses(Clauses, OMPC_to, OMPC_from)) {
13668 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
13673 Diag(StartLoc, diag::err_omp_cannot_update_with_internal_linkage);
13690 Diag(StartLoc, diag::warn_hip_omp_target_directives);
13692 auto *CS = cast<CapturedStmt>(AStmt);
13702 DSAStack->setParentTeamsRegionLoc(StartLoc);
13711 if (
DSAStack->isParentNowaitRegion()) {
13712 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
13715 if (
DSAStack->isParentOrderedRegion()) {
13716 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
13720 EndLoc, CancelRegion);
13726 if (
DSAStack->isParentNowaitRegion()) {
13727 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
13730 if (
DSAStack->isParentOrderedRegion()) {
13731 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
13734 DSAStack->setParentCancelRegion(
true);
13741 const OMPClause *ReductionClause =
nullptr;
13742 const OMPClause *NogroupClause =
nullptr;
13744 if (
C->getClauseKind() == OMPC_reduction) {
13745 ReductionClause =
C;
13750 if (
C->getClauseKind() == OMPC_nogroup) {
13752 if (ReductionClause)
13757 if (ReductionClause && NogroupClause) {
13758 S.
Diag(ReductionClause->
getBeginLoc(), diag::err_omp_reduction_with_nogroup)
13772 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13776 unsigned NestedLoopCount =
13779 *
DSAStack, VarsWithImplicitDSA, B);
13780 if (NestedLoopCount == 0)
13784 "omp for loop exprs were not built");
13790 {OMPC_grainsize, OMPC_num_tasks}))
13800 NestedLoopCount, Clauses, AStmt, B,
13810 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13814 unsigned NestedLoopCount =
13817 *
DSAStack, VarsWithImplicitDSA, B);
13818 if (NestedLoopCount == 0)
13822 "omp for loop exprs were not built");
13827 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
13839 {OMPC_grainsize, OMPC_num_tasks}))
13851 NestedLoopCount, Clauses, AStmt, B);
13860 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13864 unsigned NestedLoopCount =
13867 *
DSAStack, VarsWithImplicitDSA, B);
13868 if (NestedLoopCount == 0)
13872 "omp for loop exprs were not built");
13878 {OMPC_grainsize, OMPC_num_tasks}))
13888 NestedLoopCount, Clauses, AStmt, B,
13898 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13902 unsigned NestedLoopCount =
13905 *
DSAStack, VarsWithImplicitDSA, B);
13906 if (NestedLoopCount == 0)
13910 "omp for loop exprs were not built");
13916 {OMPC_grainsize, OMPC_num_tasks}))
13926 NestedLoopCount, Clauses, AStmt, B,
13936 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13940 unsigned NestedLoopCount =
13943 *
DSAStack, VarsWithImplicitDSA, B);
13944 if (NestedLoopCount == 0)
13948 "omp for loop exprs were not built");
13953 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
13965 {OMPC_grainsize, OMPC_num_tasks}))
13977 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13986 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13990 unsigned NestedLoopCount =
13993 *
DSAStack, VarsWithImplicitDSA, B);
13994 if (NestedLoopCount == 0)
13998 "omp for loop exprs were not built");
14003 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14015 {OMPC_grainsize, OMPC_num_tasks}))
14027 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14036 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
14037 auto *CS = cast<CapturedStmt>(AStmt);
14044 for (
int ThisCaptureLevel =
14046 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14062 VarsWithImplicitDSA, B);
14063 if (NestedLoopCount == 0)
14067 "omp for loop exprs were not built");
14073 {OMPC_grainsize, OMPC_num_tasks}))
14083 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14093 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
14094 auto *CS = cast<CapturedStmt>(AStmt);
14101 for (
int ThisCaptureLevel =
14103 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14119 VarsWithImplicitDSA, B);
14120 if (NestedLoopCount == 0)
14124 "omp for loop exprs were not built");
14130 {OMPC_grainsize, OMPC_num_tasks}))
14140 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14150 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
14151 auto *CS = cast<CapturedStmt>(AStmt);
14158 for (
int ThisCaptureLevel =
14160 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14176 VarsWithImplicitDSA, B);
14177 if (NestedLoopCount == 0)
14181 "omp for loop exprs were not built");
14186 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14198 {OMPC_grainsize, OMPC_num_tasks}))
14210 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14219 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
14220 auto *CS = cast<CapturedStmt>(AStmt);
14227 for (
int ThisCaptureLevel =
14229 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14245 VarsWithImplicitDSA, B);
14246 if (NestedLoopCount == 0)
14250 "omp for loop exprs were not built");
14255 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14267 {OMPC_grainsize, OMPC_num_tasks}))
14279 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14288 if (!checkLastPrivateForMappedDirectives(Clauses))
14291 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
14295 unsigned NestedLoopCount =
14299 if (NestedLoopCount == 0)
14303 "omp for loop exprs were not built");
14307 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14309 return DistributeDirective;
14318 auto *CS = cast<CapturedStmt>(AStmt);
14325 for (
int ThisCaptureLevel =
14327 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14343 VarsWithImplicitDSA, B);
14344 if (NestedLoopCount == 0)
14348 "omp for loop exprs were not built");
14352 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14362 auto *CS = cast<CapturedStmt>(AStmt);
14369 for (
int ThisCaptureLevel =
14371 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14387 VarsWithImplicitDSA, B);
14388 if (NestedLoopCount == 0)
14392 "omp for loop exprs were not built");
14397 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14410 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14419 auto *CS = cast<CapturedStmt>(AStmt);
14427 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14440 unsigned NestedLoopCount =
14444 if (NestedLoopCount == 0)
14448 "omp for loop exprs were not built");
14453 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14466 NestedLoopCount, Clauses, AStmt, B);
14475 auto *CS = cast<CapturedStmt>(AStmt);
14482 for (
int ThisCaptureLevel =
14484 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14500 VarsWithImplicitDSA, B);
14501 if (NestedLoopCount == 0)
14505 "omp target parallel for simd loop exprs were not built");
14510 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14522 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14531 auto *CS = cast<CapturedStmt>(AStmt);
14539 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14552 unsigned NestedLoopCount =
14555 VarsWithImplicitDSA, B);
14556 if (NestedLoopCount == 0)
14560 "omp target simd loop exprs were not built");
14565 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14578 NestedLoopCount, Clauses, AStmt, B);
14587 auto *CS = cast<CapturedStmt>(AStmt);
14595 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14608 unsigned NestedLoopCount =
14612 if (NestedLoopCount == 0)
14616 "omp teams distribute loop exprs were not built");
14620 DSAStack->setParentTeamsRegionLoc(StartLoc);
14623 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14632 auto *CS = cast<CapturedStmt>(AStmt);
14639 for (
int ThisCaptureLevel =
14641 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14657 VarsWithImplicitDSA, B);
14659 if (NestedLoopCount == 0)
14663 "omp teams distribute simd loop exprs were not built");
14668 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14681 DSAStack->setParentTeamsRegionLoc(StartLoc);
14684 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14693 auto *CS = cast<CapturedStmt>(AStmt);
14701 for (
int ThisCaptureLevel =
14703 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14719 VarsWithImplicitDSA, B);
14721 if (NestedLoopCount == 0)
14725 "omp for loop exprs were not built");
14730 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14743 DSAStack->setParentTeamsRegionLoc(StartLoc);
14746 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14755 auto *CS = cast<CapturedStmt>(AStmt);
14763 for (
int ThisCaptureLevel =
14765 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14781 VarsWithImplicitDSA, B);
14783 if (NestedLoopCount == 0)
14787 "omp for loop exprs were not built");
14791 DSAStack->setParentTeamsRegionLoc(StartLoc);
14794 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14804 auto *CS = cast<CapturedStmt>(AStmt);
14813 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14825 bool HasThreadLimitAndNumTeamsClause =
hasClauses(Clauses, OMPC_num_teams) &&
14827 bool HasBareClause = llvm::any_of(Clauses, [&](
const OMPClause *
C) {
14829 return C->getClauseKind() == OMPC_ompx_bare;
14832 if (HasBareClause && !HasThreadLimitAndNumTeamsClause) {
14847 auto *CS = cast<CapturedStmt>(AStmt);
14854 for (
int ThisCaptureLevel =
14856 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14872 VarsWithImplicitDSA, B);
14873 if (NestedLoopCount == 0)
14877 "omp target teams distribute loop exprs were not built");
14881 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14890 auto *CS = cast<CapturedStmt>(AStmt);
14897 for (
int ThisCaptureLevel =
14899 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14915 VarsWithImplicitDSA, B);
14916 if (NestedLoopCount == 0)
14920 "omp target teams distribute parallel for loop exprs were not built");
14925 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14935 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14945 auto *CS = cast<CapturedStmt>(AStmt);
14953 OMPD_target_teams_distribute_parallel_for_simd);
14954 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14967 unsigned NestedLoopCount =
14972 if (NestedLoopCount == 0)
14976 "omp target teams distribute parallel for simd loop exprs were not "
14982 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14995 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
15004 auto *CS = cast<CapturedStmt>(AStmt);
15011 for (
int ThisCaptureLevel =
15013 ThisCaptureLevel > 1; --ThisCaptureLevel) {
15029 VarsWithImplicitDSA, B);
15030 if (NestedLoopCount == 0)
15034 "omp target teams distribute simd loop exprs were not built");
15039 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
15052 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
15055bool SemaOpenMP::checkTransformableLoopNest(
15061 OriginalInits.emplace_back();
15064 [
this, &LoopHelpers, &Body, &OriginalInits, Kind](
unsigned Cnt,
15066 VarsWithInheritedDSAType TmpDSA;
15067 unsigned SingleNumLoops =
15068 checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, SemaRef, *DSAStack,
15069 TmpDSA, LoopHelpers[Cnt]);
15070 if (SingleNumLoops == 0)
15072 assert(SingleNumLoops == 1 &&
"Expect single loop iteration space");
15073 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
15074 OriginalInits.back().push_back(For->getInit());
15075 Body = For->getBody();
15077 assert(isa<CXXForRangeStmt>(CurStmt) &&
15078 "Expected canonical for or range-based for loops.");
15079 auto *CXXFor = cast<CXXForRangeStmt>(CurStmt);
15080 OriginalInits.back().push_back(CXXFor->getBeginStmt());
15081 Body = CXXFor->getBody();
15083 OriginalInits.emplace_back();
15087 Stmt *DependentPreInits;
15088 if (
auto *Dir = dyn_cast<OMPTileDirective>(Transform))
15089 DependentPreInits = Dir->getPreInits();
15090 else if (
auto *Dir = dyn_cast<OMPUnrollDirective>(Transform))
15091 DependentPreInits = Dir->getPreInits();
15093 llvm_unreachable(
"Unhandled loop transformation");
15094 if (!DependentPreInits)
15096 llvm::append_range(OriginalInits.back(),
15097 cast<DeclStmt>(DependentPreInits)->getDeclGroup());
15099 assert(OriginalInits.back().empty() &&
"No preinit after innermost loop");
15100 OriginalInits.pop_back();
15109 auto SizesClauses =
15110 OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses);
15111 if (SizesClauses.empty()) {
15124 Stmt *Body =
nullptr;
15127 if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body,
15134 NumLoops, AStmt,
nullptr,
nullptr);
15141 FloorIndVars.resize(NumLoops);
15142 TileIndVars.resize(NumLoops);
15143 for (
unsigned I = 0; I < NumLoops; ++I) {
15146 assert(LoopHelper.
Counters.size() == 1 &&
15147 "Expect single-dimensional loop iteration space");
15148 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.
Counters.front());
15149 std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
15155 std::string FloorCntName =
15156 (Twine(
".floor_") + llvm::utostr(I) +
".iv." + OrigVarName).str();
15159 FloorIndVars[I] = FloorCntDecl;
15164 std::string TileCntName =
15165 (Twine(
".tile_") + llvm::utostr(I) +
".iv." + OrigVarName).str();
15170 auto *TileCntDecl = cast<VarDecl>(IterVarRef->
getDecl());
15171 TileCntDecl->setDeclName(
15173 TileIndVars[I] = TileCntDecl;
15175 for (
auto &
P : OriginalInits[I]) {
15176 if (
auto *D =
P.dyn_cast<
Decl *>())
15177 PreInits.push_back(D);
15178 else if (
auto *PI = dyn_cast_or_null<DeclStmt>(
P.dyn_cast<
Stmt *>()))
15179 PreInits.append(PI->decl_begin(), PI->decl_end());
15181 if (
auto *PI = cast_or_null<DeclStmt>(LoopHelper.
PreInits))
15182 PreInits.append(PI->decl_begin(), PI->decl_end());
15185 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
15186 if (isa<OMPCapturedExprDecl>(CounterDecl))
15187 PreInits.push_back(CounterDecl);
15192 Stmt *Inner = Body;
15195 for (
int I = NumLoops - 1; I >= 0; --I) {
15198 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.
Counters[0]);
15199 QualType CntTy = OrigCntVar->getType();
15205 OrigCntVar->getExprLoc());
15207 OrigCntVar->getExprLoc());
15213 Decl *CounterDecl = TileIndVars[I];
15216 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
15223 CurScope, LoopHelper.
Cond->
getExprLoc(), BO_Add, FloorIV, DimTileSize);
15228 NumIterations, EndOfTile.
get());
15233 IsPartialTile.
get(), NumIterations, EndOfTile.
get());
15234 if (!MinTileAndIterSpace.
isUsable())
15238 TileIV, MinTileAndIterSpace.
get());
15244 CurScope, LoopHelper.
Inc->
getExprLoc(), UO_PreInc, TileIV);
15262 BodyParts.append(LoopHelper.
Updates.begin(), LoopHelper.
Updates.end());
15263 BodyParts.push_back(Inner);
15265 Inner->getBeginLoc(), Inner->getEndLoc());
15266 Inner =
new (Context)
15273 for (
int I = NumLoops - 1; I >= 0; --I) {
15274 auto &LoopHelper = LoopHelpers[I];
15275 Expr *NumIterations = LoopHelper.NumIterations;
15276 DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
15290 Decl *CounterDecl = FloorIndVars[I];
15299 CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, FloorIV, NumIterations);
15306 FloorIV, DimTileSize);
15310 Inner =
new (Context)
15312 IncrStmt.
get(), Inner, LoopHelper.Init->getBeginLoc(),
15313 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15332 {OMPC_partial, OMPC_full}))
15336 OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses);
15338 OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses);
15339 assert(!(FullClause && PartialClause) &&
15340 "mutual exclusivity must have been checked before");
15342 constexpr unsigned NumLoops = 1;
15343 Stmt *Body =
nullptr;
15348 if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers,
15349 Body, OriginalInits))
15352 unsigned NumGeneratedLoops = PartialClause ? 1 : 0;
15357 NumGeneratedLoops,
nullptr,
nullptr);
15366 Diag(AStmt->
getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count);
15368 <<
"#pragma omp unroll full";
15376 if (NumGeneratedLoops == 0)
15378 NumGeneratedLoops,
nullptr,
nullptr);
15424 assert(OriginalInits.size() == 1 &&
15425 "Expecting a single-dimensional loop iteration space");
15426 for (
auto &
P : OriginalInits[0]) {
15427 if (
auto *D =
P.dyn_cast<
Decl *>())
15428 PreInits.push_back(D);
15429 else if (
auto *PI = dyn_cast_or_null<DeclStmt>(
P.dyn_cast<
Stmt *>()))
15430 PreInits.append(PI->decl_begin(), PI->decl_end());
15432 if (
auto *PI = cast_or_null<DeclStmt>(LoopHelper.
PreInits))
15433 PreInits.append(PI->decl_begin(), PI->decl_end());
15436 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
15437 if (isa<OMPCapturedExprDecl>(CounterDecl))
15438 PreInits.push_back(CounterDecl);
15441 auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.
IterationVarRef);
15442 QualType IVTy = IterationVarRef->getType();
15443 assert(LoopHelper.
Counters.size() == 1 &&
15444 "Expecting a single-dimensional loop iteration space");
15445 auto *OrigVar = cast<DeclRefExpr>(LoopHelper.
Counters.front());
15451 Factor = FactorVal->getIntegerConstantExpr(Context)->getZExtValue();
15452 FactorLoc = FactorVal->getExprLoc();
15457 assert(Factor > 0 &&
"Expected positive unroll factor");
15458 auto MakeFactorExpr = [
this, Factor, IVTy, FactorLoc]() {
15470 std::string OrigVarName = OrigVar->getNameInfo().getAsString();
15471 std::string OuterIVName = (Twine(
".unrolled.iv.") + OrigVarName).str();
15472 std::string InnerIVName = (Twine(
".unroll_inner.iv.") + OrigVarName).str();
15473 std::string InnerTripCountName =
15474 (Twine(
".unroll_inner.tripcount.") + OrigVarName).str();
15479 auto MakeOuterRef = [
this, OuterIVDecl, IVTy, OrigVarLoc]() {
15485 auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl());
15487 auto MakeInnerRef = [
this, InnerIVDecl, IVTy, OrigVarLoc]() {
15493 CaptureVars CopyTransformer(
SemaRef);
15494 auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() ->
Expr * {
15517 MakeOuterRef(), MakeFactorExpr());
15522 MakeInnerRef(), EndOfTile.
get());
15527 MakeInnerRef(), MakeNumIterations());
15532 InnerCond1.
get(), InnerCond2.
get());
15538 CurScope, LoopHelper.
Inc->
getExprLoc(), UO_PreInc, MakeInnerRef());
15544 InnerBodyStmts.append(LoopHelper.
Updates.begin(), LoopHelper.
Updates.end());
15545 InnerBodyStmts.push_back(Body);
15549 ForStmt *InnerFor =
new (Context)
15550 ForStmt(Context, InnerInit.
get(), InnerCond.
get(),
nullptr,
15566 LoopHintAttr *UnrollHintAttr =
15567 LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount,
15568 LoopHintAttr::Numeric, MakeFactorExpr());
15585 MakeOuterRef(), MakeNumIterations());
15592 MakeOuterRef(), MakeFactorExpr());
15597 ForStmt *OuterFor =
new (Context)
15598 ForStmt(Context, OuterInit.
get(), OuterConde.
get(),
nullptr,
15603 NumGeneratedLoops, OuterFor,
15617 case OMPC_num_threads:
15626 case OMPC_allocator:
15629 case OMPC_collapse:
15635 case OMPC_num_teams:
15638 case OMPC_thread_limit:
15641 case OMPC_priority:
15653 case OMPC_novariants:
15656 case OMPC_nocontext:
15671 case OMPC_ompx_dyn_cgroup_mem:
15674 case OMPC_grainsize:
15675 case OMPC_num_tasks:
15679 case OMPC_proc_bind:
15680 case OMPC_schedule:
15682 case OMPC_firstprivate:
15683 case OMPC_lastprivate:
15685 case OMPC_reduction:
15686 case OMPC_task_reduction:
15687 case OMPC_in_reduction:
15691 case OMPC_copyprivate:
15694 case OMPC_mergeable:
15695 case OMPC_threadprivate:
15697 case OMPC_allocate:
15714 case OMPC_dist_schedule:
15715 case OMPC_defaultmap:
15720 case OMPC_use_device_ptr:
15721 case OMPC_use_device_addr:
15722 case OMPC_is_device_ptr:
15723 case OMPC_unified_address:
15724 case OMPC_unified_shared_memory:
15725 case OMPC_reverse_offload:
15726 case OMPC_dynamic_allocators:
15727 case OMPC_atomic_default_mem_order:
15728 case OMPC_device_type:
15730 case OMPC_nontemporal:
15733 case OMPC_severity:
15735 case OMPC_inclusive:
15736 case OMPC_exclusive:
15737 case OMPC_uses_allocators:
15738 case OMPC_affinity:
15742 llvm_unreachable(
"Clause is not allowed.");
15759 case OMPD_target_parallel_for_simd:
15760 if (OpenMPVersion >= 50 &&
15761 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15762 CaptureRegion = OMPD_parallel;
15766 case OMPD_target_parallel:
15767 case OMPD_target_parallel_for:
15768 case OMPD_target_parallel_loop:
15771 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
15772 CaptureRegion = OMPD_target;
15774 case OMPD_teams_loop:
15775 case OMPD_target_teams_loop:
15778 CaptureRegion = OMPD_teams;
15780 case OMPD_target_teams_distribute_parallel_for_simd:
15781 if (OpenMPVersion >= 50 &&
15782 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15783 CaptureRegion = OMPD_parallel;
15787 case OMPD_target_teams_distribute_parallel_for:
15790 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
15791 CaptureRegion = OMPD_teams;
15793 case OMPD_teams_distribute_parallel_for_simd:
15794 if (OpenMPVersion >= 50 &&
15795 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15796 CaptureRegion = OMPD_parallel;
15800 case OMPD_teams_distribute_parallel_for:
15801 CaptureRegion = OMPD_teams;
15803 case OMPD_target_update:
15804 case OMPD_target_enter_data:
15805 case OMPD_target_exit_data:
15806 CaptureRegion = OMPD_task;
15808 case OMPD_parallel_masked_taskloop:
15809 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
15810 CaptureRegion = OMPD_parallel;
15812 case OMPD_parallel_master_taskloop:
15813 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
15814 CaptureRegion = OMPD_parallel;
15816 case OMPD_parallel_masked_taskloop_simd:
15817 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
15818 NameModifier == OMPD_taskloop) {
15819 CaptureRegion = OMPD_parallel;
15822 if (OpenMPVersion <= 45)
15824 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15825 CaptureRegion = OMPD_taskloop;
15827 case OMPD_parallel_master_taskloop_simd:
15828 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
15829 NameModifier == OMPD_taskloop) {
15830 CaptureRegion = OMPD_parallel;
15833 if (OpenMPVersion <= 45)
15835 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15836 CaptureRegion = OMPD_taskloop;
15838 case OMPD_parallel_for_simd:
15839 if (OpenMPVersion <= 45)
15841 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15842 CaptureRegion = OMPD_parallel;
15844 case OMPD_taskloop_simd:
15845 case OMPD_master_taskloop_simd:
15846 case OMPD_masked_taskloop_simd:
15847 if (OpenMPVersion <= 45)
15849 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15850 CaptureRegion = OMPD_taskloop;
15852 case OMPD_distribute_parallel_for_simd:
15853 if (OpenMPVersion <= 45)
15855 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15856 CaptureRegion = OMPD_parallel;
15858 case OMPD_target_simd:
15859 if (OpenMPVersion >= 50 &&
15860 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
15861 CaptureRegion = OMPD_target;
15863 case OMPD_teams_distribute_simd:
15864 case OMPD_target_teams_distribute_simd:
15865 if (OpenMPVersion >= 50 &&
15866 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
15867 CaptureRegion = OMPD_teams;
15870 case OMPD_parallel:
15871 case OMPD_parallel_master:
15872 case OMPD_parallel_masked:
15873 case OMPD_parallel_sections:
15874 case OMPD_parallel_for:
15875 case OMPD_parallel_loop:
15877 case OMPD_target_teams:
15878 case OMPD_target_teams_distribute:
15879 case OMPD_distribute_parallel_for:
15881 case OMPD_taskloop:
15882 case OMPD_master_taskloop:
15883 case OMPD_masked_taskloop:
15884 case OMPD_target_data:
15886 case OMPD_for_simd:
15887 case OMPD_distribute_simd:
15890 case OMPD_threadprivate:
15891 case OMPD_allocate:
15892 case OMPD_taskyield:
15895 case OMPD_taskwait:
15896 case OMPD_cancellation_point:
15900 case OMPD_declare_reduction:
15901 case OMPD_declare_mapper:
15902 case OMPD_declare_simd:
15903 case OMPD_declare_variant:
15904 case OMPD_begin_declare_variant:
15905 case OMPD_end_declare_variant:
15906 case OMPD_declare_target:
15907 case OMPD_end_declare_target:
15913 case OMPD_sections:
15918 case OMPD_critical:
15919 case OMPD_taskgroup:
15920 case OMPD_distribute:
15923 case OMPD_teams_distribute:
15924 case OMPD_requires:
15925 case OMPD_metadirective:
15926 llvm_unreachable(
"Unexpected OpenMP directive with if-clause");
15929 llvm_unreachable(
"Unknown OpenMP directive");
15932 case OMPC_num_threads:
15934 case OMPD_target_parallel:
15935 case OMPD_target_parallel_for:
15936 case OMPD_target_parallel_for_simd:
15937 case OMPD_target_parallel_loop:
15938 CaptureRegion = OMPD_target;
15940 case OMPD_teams_distribute_parallel_for:
15941 case OMPD_teams_distribute_parallel_for_simd:
15942 case OMPD_target_teams_distribute_parallel_for:
15943 case OMPD_target_teams_distribute_parallel_for_simd:
15944 CaptureRegion = OMPD_teams;
15946 case OMPD_parallel:
15947 case OMPD_parallel_master:
15948 case OMPD_parallel_masked:
15949 case OMPD_parallel_sections:
15950 case OMPD_parallel_for:
15951 case OMPD_parallel_for_simd:
15952 case OMPD_parallel_loop:
15953 case OMPD_distribute_parallel_for:
15954 case OMPD_distribute_parallel_for_simd:
15955 case OMPD_parallel_master_taskloop:
15956 case OMPD_parallel_masked_taskloop:
15957 case OMPD_parallel_master_taskloop_simd:
15958 case OMPD_parallel_masked_taskloop_simd:
15961 case OMPD_target_data:
15962 case OMPD_target_enter_data:
15963 case OMPD_target_exit_data:
15964 case OMPD_target_update:
15966 case OMPD_target_simd:
15967 case OMPD_target_teams:
15968 case OMPD_target_teams_distribute:
15969 case OMPD_target_teams_distribute_simd:
15972 case OMPD_taskloop:
15973 case OMPD_taskloop_simd:
15974 case OMPD_master_taskloop:
15975 case OMPD_masked_taskloop:
15976 case OMPD_master_taskloop_simd:
15977 case OMPD_masked_taskloop_simd:
15978 case OMPD_threadprivate:
15979 case OMPD_allocate:
15980 case OMPD_taskyield:
15983 case OMPD_taskwait:
15984 case OMPD_cancellation_point:
15988 case OMPD_declare_reduction:
15989 case OMPD_declare_mapper:
15990 case OMPD_declare_simd:
15991 case OMPD_declare_variant:
15992 case OMPD_begin_declare_variant:
15993 case OMPD_end_declare_variant:
15994 case OMPD_declare_target:
15995 case OMPD_end_declare_target:
15997 case OMPD_teams_loop:
15998 case OMPD_target_teams_loop:
16004 case OMPD_for_simd:
16005 case OMPD_sections:
16010 case OMPD_critical:
16011 case OMPD_taskgroup:
16012 case OMPD_distribute:
16015 case OMPD_distribute_simd:
16016 case OMPD_teams_distribute:
16017 case OMPD_teams_distribute_simd:
16018 case OMPD_requires:
16019 case OMPD_metadirective:
16020 llvm_unreachable(
"Unexpected OpenMP directive with num_threads-clause");
16023 llvm_unreachable(
"Unknown OpenMP directive");
16026 case OMPC_num_teams:
16028 case OMPD_target_teams:
16029 case OMPD_target_teams_distribute:
16030 case OMPD_target_teams_distribute_simd:
16031 case OMPD_target_teams_distribute_parallel_for:
16032 case OMPD_target_teams_distribute_parallel_for_simd:
16033 case OMPD_target_teams_loop:
16034 CaptureRegion = OMPD_target;
16036 case OMPD_teams_distribute_parallel_for:
16037 case OMPD_teams_distribute_parallel_for_simd:
16039 case OMPD_teams_distribute:
16040 case OMPD_teams_distribute_simd:
16041 case OMPD_teams_loop:
16044 case OMPD_distribute_parallel_for:
16045 case OMPD_distribute_parallel_for_simd:
16047 case OMPD_taskloop:
16048 case OMPD_taskloop_simd:
16049 case OMPD_master_taskloop:
16050 case OMPD_masked_taskloop:
16051 case OMPD_master_taskloop_simd:
16052 case OMPD_masked_taskloop_simd:
16053 case OMPD_parallel_master_taskloop:
16054 case OMPD_parallel_masked_taskloop:
16055 case OMPD_parallel_master_taskloop_simd:
16056 case OMPD_parallel_masked_taskloop_simd:
16057 case OMPD_target_data:
16058 case OMPD_target_enter_data:
16059 case OMPD_target_exit_data:
16060 case OMPD_target_update:
16062 case OMPD_parallel:
16063 case OMPD_parallel_master:
16064 case OMPD_parallel_masked:
16065 case OMPD_parallel_sections:
16066 case OMPD_parallel_for:
16067 case OMPD_parallel_for_simd:
16068 case OMPD_parallel_loop:
16070 case OMPD_target_simd:
16071 case OMPD_target_parallel:
16072 case OMPD_target_parallel_for:
16073 case OMPD_target_parallel_for_simd:
16074 case OMPD_target_parallel_loop:
16075 case OMPD_threadprivate:
16076 case OMPD_allocate:
16077 case OMPD_taskyield:
16080 case OMPD_taskwait:
16081 case OMPD_cancellation_point:
16085 case OMPD_declare_reduction:
16086 case OMPD_declare_mapper:
16087 case OMPD_declare_simd:
16088 case OMPD_declare_variant:
16089 case OMPD_begin_declare_variant:
16090 case OMPD_end_declare_variant:
16091 case OMPD_declare_target:
16092 case OMPD_end_declare_target:
16098 case OMPD_for_simd:
16099 case OMPD_sections:
16104 case OMPD_critical:
16105 case OMPD_taskgroup:
16106 case OMPD_distribute:
16109 case OMPD_distribute_simd:
16110 case OMPD_requires:
16111 case OMPD_metadirective:
16112 llvm_unreachable(
"Unexpected OpenMP directive with num_teams-clause");
16115 llvm_unreachable(
"Unknown OpenMP directive");
16118 case OMPC_thread_limit:
16121 case OMPD_target_teams:
16122 case OMPD_target_teams_distribute:
16123 case OMPD_target_teams_distribute_simd:
16124 case OMPD_target_teams_distribute_parallel_for:
16125 case OMPD_target_teams_distribute_parallel_for_simd:
16126 case OMPD_target_teams_loop:
16127 case OMPD_target_simd:
16128 case OMPD_target_parallel:
16129 case OMPD_target_parallel_for:
16130 case OMPD_target_parallel_for_simd:
16131 case OMPD_target_parallel_loop:
16132 CaptureRegion = OMPD_target;
16134 case OMPD_teams_distribute_parallel_for:
16135 case OMPD_teams_distribute_parallel_for_simd:
16137 case OMPD_teams_distribute:
16138 case OMPD_teams_distribute_simd:
16139 case OMPD_teams_loop:
16142 case OMPD_distribute_parallel_for:
16143 case OMPD_distribute_parallel_for_simd:
16145 case OMPD_taskloop:
16146 case OMPD_taskloop_simd:
16147 case OMPD_master_taskloop:
16148 case OMPD_masked_taskloop:
16149 case OMPD_master_taskloop_simd:
16150 case OMPD_masked_taskloop_simd:
16151 case OMPD_parallel_master_taskloop:
16152 case OMPD_parallel_masked_taskloop:
16153 case OMPD_parallel_master_taskloop_simd:
16154 case OMPD_parallel_masked_taskloop_simd:
16155 case OMPD_target_data:
16156 case OMPD_target_enter_data:
16157 case OMPD_target_exit_data:
16158 case OMPD_target_update:
16160 case OMPD_parallel:
16161 case OMPD_parallel_master:
16162 case OMPD_parallel_masked:
16163 case OMPD_parallel_sections:
16164 case OMPD_parallel_for:
16165 case OMPD_parallel_for_simd:
16166 case OMPD_parallel_loop:
16167 case OMPD_threadprivate:
16168 case OMPD_allocate:
16169 case OMPD_taskyield:
16172 case OMPD_taskwait:
16173 case OMPD_cancellation_point:
16177 case OMPD_declare_reduction:
16178 case OMPD_declare_mapper:
16179 case OMPD_declare_simd:
16180 case OMPD_declare_variant:
16181 case OMPD_begin_declare_variant:
16182 case OMPD_end_declare_variant:
16183 case OMPD_declare_target:
16184 case OMPD_end_declare_target:
16190 case OMPD_for_simd:
16191 case OMPD_sections:
16196 case OMPD_critical:
16197 case OMPD_taskgroup:
16198 case OMPD_distribute:
16201 case OMPD_distribute_simd:
16202 case OMPD_requires:
16203 case OMPD_metadirective:
16204 llvm_unreachable(
"Unexpected OpenMP directive with thread_limit-clause");
16207 llvm_unreachable(
"Unknown OpenMP directive");
16210 case OMPC_schedule:
16212 case OMPD_parallel_for:
16213 case OMPD_parallel_for_simd:
16214 case OMPD_distribute_parallel_for:
16215 case OMPD_distribute_parallel_for_simd:
16216 case OMPD_teams_distribute_parallel_for:
16217 case OMPD_teams_distribute_parallel_for_simd:
16218 case OMPD_target_parallel_for:
16219 case OMPD_target_parallel_for_simd:
16220 case OMPD_target_teams_distribute_parallel_for:
16221 case OMPD_target_teams_distribute_parallel_for_simd:
16222 CaptureRegion = OMPD_parallel;
16225 case OMPD_for_simd:
16229 case OMPD_taskloop:
16230 case OMPD_taskloop_simd:
16231 case OMPD_master_taskloop:
16232 case OMPD_masked_taskloop:
16233 case OMPD_master_taskloop_simd:
16234 case OMPD_masked_taskloop_simd:
16235 case OMPD_parallel_master_taskloop:
16236 case OMPD_parallel_masked_taskloop:
16237 case OMPD_parallel_master_taskloop_simd:
16238 case OMPD_parallel_masked_taskloop_simd:
16239 case OMPD_target_data:
16240 case OMPD_target_enter_data:
16241 case OMPD_target_exit_data:
16242 case OMPD_target_update:
16244 case OMPD_teams_distribute:
16245 case OMPD_teams_distribute_simd:
16246 case OMPD_target_teams_distribute:
16247 case OMPD_target_teams_distribute_simd:
16249 case OMPD_target_simd:
16250 case OMPD_target_parallel:
16252 case OMPD_parallel:
16253 case OMPD_parallel_master:
16254 case OMPD_parallel_masked:
16255 case OMPD_parallel_sections:
16256 case OMPD_threadprivate:
16257 case OMPD_allocate:
16258 case OMPD_taskyield:
16261 case OMPD_taskwait:
16262 case OMPD_cancellation_point:
16266 case OMPD_declare_reduction:
16267 case OMPD_declare_mapper:
16268 case OMPD_declare_simd:
16269 case OMPD_declare_variant:
16270 case OMPD_begin_declare_variant:
16271 case OMPD_end_declare_variant:
16272 case OMPD_declare_target:
16273 case OMPD_end_declare_target:
16275 case OMPD_teams_loop:
16276 case OMPD_target_teams_loop:
16277 case OMPD_parallel_loop:
16278 case OMPD_target_parallel_loop:
16282 case OMPD_sections:
16287 case OMPD_critical:
16288 case OMPD_taskgroup:
16289 case OMPD_distribute:
16292 case OMPD_distribute_simd:
16293 case OMPD_target_teams:
16294 case OMPD_requires:
16295 case OMPD_metadirective:
16296 llvm_unreachable(
"Unexpected OpenMP directive with schedule clause");
16299 llvm_unreachable(
"Unknown OpenMP directive");
16302 case OMPC_dist_schedule:
16304 case OMPD_teams_distribute_parallel_for:
16305 case OMPD_teams_distribute_parallel_for_simd:
16306 case OMPD_teams_distribute:
16307 case OMPD_teams_distribute_simd:
16308 case OMPD_target_teams_distribute_parallel_for:
16309 case OMPD_target_teams_distribute_parallel_for_simd:
16310 case OMPD_target_teams_distribute:
16311 case OMPD_target_teams_distribute_simd:
16312 CaptureRegion = OMPD_teams;
16314 case OMPD_distribute_parallel_for:
16315 case OMPD_distribute_parallel_for_simd:
16316 case OMPD_distribute:
16317 case OMPD_distribute_simd:
16320 case OMPD_parallel_for:
16321 case OMPD_parallel_for_simd:
16322 case OMPD_target_parallel_for_simd:
16323 case OMPD_target_parallel_for:
16325 case OMPD_taskloop:
16326 case OMPD_taskloop_simd:
16327 case OMPD_master_taskloop:
16328 case OMPD_masked_taskloop:
16329 case OMPD_master_taskloop_simd:
16330 case OMPD_masked_taskloop_simd:
16331 case OMPD_parallel_master_taskloop:
16332 case OMPD_parallel_masked_taskloop:
16333 case OMPD_parallel_master_taskloop_simd:
16334 case OMPD_parallel_masked_taskloop_simd:
16335 case OMPD_target_data:
16336 case OMPD_target_enter_data:
16337 case OMPD_target_exit_data:
16338 case OMPD_target_update:
16341 case OMPD_target_simd:
16342 case OMPD_target_parallel:
16344 case OMPD_parallel:
16345 case OMPD_parallel_master:
16346 case OMPD_parallel_masked:
16347 case OMPD_parallel_sections:
16348 case OMPD_threadprivate:
16349 case OMPD_allocate:
16350 case OMPD_taskyield:
16353 case OMPD_taskwait:
16354 case OMPD_cancellation_point:
16358 case OMPD_declare_reduction:
16359 case OMPD_declare_mapper:
16360 case OMPD_declare_simd:
16361 case OMPD_declare_variant:
16362 case OMPD_begin_declare_variant:
16363 case OMPD_end_declare_variant:
16364 case OMPD_declare_target:
16365 case OMPD_end_declare_target:
16367 case OMPD_teams_loop:
16368 case OMPD_target_teams_loop:
16369 case OMPD_parallel_loop:
16370 case OMPD_target_parallel_loop:
16375 case OMPD_for_simd:
16376 case OMPD_sections:
16381 case OMPD_critical:
16382 case OMPD_taskgroup:
16385 case OMPD_target_teams:
16386 case OMPD_requires:
16387 case OMPD_metadirective:
16388 llvm_unreachable(
"Unexpected OpenMP directive with dist_schedule clause");
16391 llvm_unreachable(
"Unknown OpenMP directive");
16394 case OMPC_ompx_dyn_cgroup_mem:
16397 case OMPD_target_simd:
16398 case OMPD_target_teams:
16399 case OMPD_target_parallel:
16400 case OMPD_target_teams_distribute:
16401 case OMPD_target_teams_distribute_simd:
16402 case OMPD_target_parallel_for:
16403 case OMPD_target_parallel_for_simd:
16404 case OMPD_target_parallel_loop:
16405 case OMPD_target_teams_distribute_parallel_for:
16406 case OMPD_target_teams_distribute_parallel_for_simd:
16407 case OMPD_target_teams_loop:
16408 CaptureRegion = OMPD_target;
16411 llvm_unreachable(
"Unknown OpenMP directive");
16416 case OMPD_target_update:
16417 case OMPD_target_enter_data:
16418 case OMPD_target_exit_data:
16420 case OMPD_target_simd:
16421 case OMPD_target_teams:
16422 case OMPD_target_parallel:
16423 case OMPD_target_teams_distribute:
16424 case OMPD_target_teams_distribute_simd:
16425 case OMPD_target_parallel_for:
16426 case OMPD_target_parallel_for_simd:
16427 case OMPD_target_parallel_loop:
16428 case OMPD_target_teams_distribute_parallel_for:
16429 case OMPD_target_teams_distribute_parallel_for_simd:
16430 case OMPD_target_teams_loop:
16431 case OMPD_dispatch:
16432 CaptureRegion = OMPD_task;
16434 case OMPD_target_data:
16438 case OMPD_teams_distribute_parallel_for:
16439 case OMPD_teams_distribute_parallel_for_simd:
16441 case OMPD_teams_distribute:
16442 case OMPD_teams_distribute_simd:
16443 case OMPD_distribute_parallel_for:
16444 case OMPD_distribute_parallel_for_simd:
16446 case OMPD_taskloop:
16447 case OMPD_taskloop_simd:
16448 case OMPD_master_taskloop:
16449 case OMPD_masked_taskloop:
16450 case OMPD_master_taskloop_simd:
16451 case OMPD_masked_taskloop_simd:
16452 case OMPD_parallel_master_taskloop:
16453 case OMPD_parallel_masked_taskloop:
16454 case OMPD_parallel_master_taskloop_simd:
16455 case OMPD_parallel_masked_taskloop_simd:
16457 case OMPD_parallel:
16458 case OMPD_parallel_master:
16459 case OMPD_parallel_masked:
16460 case OMPD_parallel_sections:
16461 case OMPD_parallel_for:
16462 case OMPD_parallel_for_simd:
16463 case OMPD_threadprivate:
16464 case OMPD_allocate:
16465 case OMPD_taskyield:
16468 case OMPD_taskwait:
16469 case OMPD_cancellation_point:
16473 case OMPD_declare_reduction:
16474 case OMPD_declare_mapper:
16475 case OMPD_declare_simd:
16476 case OMPD_declare_variant:
16477 case OMPD_begin_declare_variant:
16478 case OMPD_end_declare_variant:
16479 case OMPD_declare_target:
16480 case OMPD_end_declare_target:
16482 case OMPD_teams_loop:
16483 case OMPD_parallel_loop:
16488 case OMPD_for_simd:
16489 case OMPD_sections:
16494 case OMPD_critical:
16495 case OMPD_taskgroup:
16496 case OMPD_distribute:
16499 case OMPD_distribute_simd:
16500 case OMPD_requires:
16501 case OMPD_metadirective:
16502 llvm_unreachable(
"Unexpected OpenMP directive with device-clause");
16505 llvm_unreachable(
"Unknown OpenMP directive");
16508 case OMPC_grainsize:
16509 case OMPC_num_tasks:
16511 case OMPC_priority:
16514 case OMPD_taskloop:
16515 case OMPD_taskloop_simd:
16516 case OMPD_master_taskloop:
16517 case OMPD_masked_taskloop:
16518 case OMPD_master_taskloop_simd:
16519 case OMPD_masked_taskloop_simd:
16521 case OMPD_parallel_masked_taskloop:
16522 case OMPD_parallel_masked_taskloop_simd:
16523 case OMPD_parallel_master_taskloop:
16524 case OMPD_parallel_master_taskloop_simd:
16525 CaptureRegion = OMPD_parallel;
16527 case OMPD_target_update:
16528 case OMPD_target_enter_data:
16529 case OMPD_target_exit_data:
16531 case OMPD_target_simd:
16532 case OMPD_target_teams:
16533 case OMPD_target_parallel:
16534 case OMPD_target_teams_distribute:
16535 case OMPD_target_teams_distribute_simd:
16536 case OMPD_target_parallel_for:
16537 case OMPD_target_parallel_for_simd:
16538 case OMPD_target_teams_distribute_parallel_for:
16539 case OMPD_target_teams_distribute_parallel_for_simd:
16540 case OMPD_target_data:
16541 case OMPD_teams_distribute_parallel_for:
16542 case OMPD_teams_distribute_parallel_for_simd:
16544 case OMPD_teams_distribute:
16545 case OMPD_teams_distribute_simd:
16546 case OMPD_distribute_parallel_for:
16547 case OMPD_distribute_parallel_for_simd:
16549 case OMPD_parallel:
16550 case OMPD_parallel_master:
16551 case OMPD_parallel_masked:
16552 case OMPD_parallel_sections:
16553 case OMPD_parallel_for:
16554 case OMPD_parallel_for_simd:
16555 case OMPD_threadprivate:
16556 case OMPD_allocate:
16557 case OMPD_taskyield:
16560 case OMPD_taskwait:
16561 case OMPD_cancellation_point:
16565 case OMPD_declare_reduction:
16566 case OMPD_declare_mapper:
16567 case OMPD_declare_simd:
16568 case OMPD_declare_variant:
16569 case OMPD_begin_declare_variant:
16570 case OMPD_end_declare_variant:
16571 case OMPD_declare_target:
16572 case OMPD_end_declare_target:
16574 case OMPD_teams_loop:
16575 case OMPD_target_teams_loop:
16576 case OMPD_parallel_loop:
16577 case OMPD_target_parallel_loop:
16582 case OMPD_for_simd:
16583 case OMPD_sections:
16588 case OMPD_critical:
16589 case OMPD_taskgroup:
16590 case OMPD_distribute:
16593 case OMPD_distribute_simd:
16594 case OMPD_requires:
16595 case OMPD_metadirective:
16596 llvm_unreachable(
"Unexpected OpenMP directive with grainsize-clause");
16599 llvm_unreachable(
"Unknown OpenMP directive");
16602 case OMPC_novariants:
16603 case OMPC_nocontext:
16605 case OMPD_dispatch:
16606 CaptureRegion = OMPD_task;
16609 llvm_unreachable(
"Unexpected OpenMP directive");
16616 if (DKind == OMPD_metadirective) {
16617 CaptureRegion = OMPD_metadirective;
16618 }
else if (DKind == OMPD_unknown) {
16619 llvm_unreachable(
"Unknown OpenMP directive");
16621 llvm_unreachable(
"Unexpected OpenMP directive with when clause");
16624 case OMPC_firstprivate:
16625 case OMPC_lastprivate:
16626 case OMPC_reduction:
16627 case OMPC_task_reduction:
16628 case OMPC_in_reduction:
16631 case OMPC_proc_bind:
16635 case OMPC_allocator:
16636 case OMPC_collapse:
16641 case OMPC_copyprivate:
16645 case OMPC_mergeable:
16646 case OMPC_threadprivate:
16647 case OMPC_allocate:
16666 case OMPC_defaultmap:
16671 case OMPC_use_device_ptr:
16672 case OMPC_use_device_addr:
16673 case OMPC_is_device_ptr:
16674 case OMPC_unified_address:
16675 case OMPC_unified_shared_memory:
16676 case OMPC_reverse_offload:
16677 case OMPC_dynamic_allocators:
16678 case OMPC_atomic_default_mem_order:
16679 case OMPC_device_type:
16681 case OMPC_nontemporal:
16684 case OMPC_severity:
16688 case OMPC_inclusive:
16689 case OMPC_exclusive:
16690 case OMPC_uses_allocators:
16691 case OMPC_affinity:
16694 llvm_unreachable(
"Unexpected OpenMP clause.");
16696 return CaptureRegion;
16704 Stmt *HelperValStmt =
nullptr;
16707 !
Condition->isInstantiationDependent() &&
16708 !
Condition->containsUnexpandedParameterPack()) {
16713 ValExpr = Val.
get();
16717 DKind, OMPC_if,
getLangOpts().OpenMP, NameModifier);
16718 if (CaptureRegion != OMPD_unknown &&
16721 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16722 ValExpr = tryBuildCapture(
SemaRef, ValExpr, Captures).get();
16728 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
16729 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
16737 Stmt *HelperValStmt =
nullptr;
16740 !
Condition->isInstantiationDependent() &&
16741 !
Condition->containsUnexpandedParameterPack()) {
16751 if (CaptureRegion != OMPD_unknown &&
16754 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16755 ValExpr = tryBuildCapture(
SemaRef, ValExpr, Captures).get();
16761 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
16772 IntConvertDiagnoser()
16773 : ICEConvertDiagnoser(
false,
false,
true) {}
16776 return S.
Diag(Loc, diag::err_omp_not_integral) <<
T;
16780 return S.
Diag(Loc, diag::err_omp_incomplete_type) <<
T;
16785 return S.
Diag(Loc, diag::err_omp_explicit_conversion) <<
T << ConvTy;
16794 return S.
Diag(Loc, diag::err_omp_ambiguous_conversion) <<
T;
16803 llvm_unreachable(
"conversion functions are permitted");
16805 } ConvertDiagnoser;
16811 bool StrictlyPositive,
bool BuildCapture =
false,
16814 Stmt **HelperValStmt =
nullptr) {
16820 if (
Value.isInvalid())
16823 ValExpr =
Value.get();
16825 if (std::optional<llvm::APSInt>
Result =
16827 if (
Result->isSigned() &&
16828 !((!StrictlyPositive &&
Result->isNonNegative()) ||
16829 (StrictlyPositive &&
Result->isStrictlyPositive()))) {
16830 SemaRef.
Diag(Loc, diag::err_omp_negative_expression_in_clause)
16831 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
16840 if (*CaptureRegion != OMPD_unknown &&
16843 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16844 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
16855 Expr *ValExpr = NumThreads;
16856 Stmt *HelperValStmt =
nullptr;
16867 if (CaptureRegion != OMPD_unknown &&
16870 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16871 ValExpr = tryBuildCapture(
SemaRef, ValExpr, Captures).get();
16876 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
16881 bool SuppressExprDiags) {
16890 if (SuppressExprDiags) {
16894 SuppressedDiagnoser() : VerifyICEDiagnoser(
true) {}
16897 llvm_unreachable(
"Diagnostic suppressed");
16909 if ((StrictlyPositive && !
Result.isStrictlyPositive()) ||
16910 (!StrictlyPositive && !
Result.isNonNegative())) {
16911 Diag(E->
getExprLoc(), diag::err_omp_negative_expression_in_clause)
16912 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
16916 if ((CKind == OMPC_aligned || CKind == OMPC_align) && !
Result.isPowerOf2()) {
16917 Diag(E->
getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
16921 if (CKind == OMPC_collapse &&
DSAStack->getAssociatedLoops() == 1)
16923 else if (CKind == OMPC_ordered)
16958 DSAStackTy *Stack) {
16959 if (!Stack->getOMPAllocatorHandleT().isNull())
16966 S.
Diag(Loc, diag::err_omp_implied_type_not_found)
16967 <<
"omp_allocator_handle_t";
16972 Stack->setOMPAllocatorHandleT(AllocatorHandleEnumTy);
16975 bool ErrorFound =
false;
16976 for (
int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
16977 auto AllocatorKind =
static_cast<OMPAllocateDeclAttr::AllocatorTypeTy
>(I);
16978 StringRef Allocator =
16979 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
16981 auto *VD = dyn_cast_or_null<ValueDecl>(
17001 Stack->setAllocator(AllocatorKind, Res.
get());
17004 S.
Diag(Loc, diag::err_omp_implied_type_not_found)
17005 <<
"omp_allocator_handle_t";
17022 if (Allocator.isInvalid())
17025 Allocator.get(),
DSAStack->getOMPAllocatorHandleT(),
17028 if (Allocator.isInvalid())
17054 Expr *NumForLoops) {
17060 if (NumForLoops && LParenLoc.
isValid()) {
17065 NumForLoops = NumForLoopsResult.
get();
17067 NumForLoops =
nullptr;
17071 NumForLoops ?
DSAStack->getAssociatedLoops() : 0,
17072 StartLoc, LParenLoc, EndLoc);
17073 DSAStack->setOrderedRegion(
true, NumForLoops, Clause);
17084 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
17086 case OMPC_proc_bind:
17088 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
17090 case OMPC_atomic_default_mem_order:
17093 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
17098 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
17102 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
17106 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
17110 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
17112 case OMPC_severity:
17115 LParenLoc, EndLoc);
17119 case OMPC_num_threads:
17123 case OMPC_allocator:
17124 case OMPC_collapse:
17125 case OMPC_schedule:
17127 case OMPC_firstprivate:
17128 case OMPC_lastprivate:
17130 case OMPC_reduction:
17131 case OMPC_task_reduction:
17132 case OMPC_in_reduction:
17136 case OMPC_copyprivate:
17140 case OMPC_mergeable:
17141 case OMPC_threadprivate:
17142 case OMPC_allocate:
17159 case OMPC_num_teams:
17160 case OMPC_thread_limit:
17161 case OMPC_priority:
17162 case OMPC_grainsize:
17164 case OMPC_num_tasks:
17166 case OMPC_dist_schedule:
17167 case OMPC_defaultmap:
17172 case OMPC_use_device_ptr:
17173 case OMPC_use_device_addr:
17174 case OMPC_is_device_ptr:
17175 case OMPC_has_device_addr:
17176 case OMPC_unified_address:
17177 case OMPC_unified_shared_memory:
17178 case OMPC_reverse_offload:
17179 case OMPC_dynamic_allocators:
17180 case OMPC_device_type:
17182 case OMPC_nontemporal:
17184 case OMPC_novariants:
17185 case OMPC_nocontext:
17187 case OMPC_inclusive:
17188 case OMPC_exclusive:
17189 case OMPC_uses_allocators:
17190 case OMPC_affinity:
17194 llvm_unreachable(
"Clause is not allowed.");
17203 llvm::raw_svector_ostream Out(Buffer);
17204 unsigned Skipped = Exclude.size();
17205 for (
unsigned I =
First; I <
Last; ++I) {
17206 if (llvm::is_contained(Exclude, I)) {
17211 if (I + Skipped + 2 ==
Last)
17213 else if (I + Skipped + 1 !=
Last)
17216 return std::string(Out.str());
17224 if (Kind == OMP_DEFAULT_unknown) {
17225 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17227 unsigned(OMP_DEFAULT_unknown))
17228 << getOpenMPClauseName(OMPC_default);
17233 case OMP_DEFAULT_none:
17234 DSAStack->setDefaultDSANone(KindKwLoc);
17236 case OMP_DEFAULT_shared:
17237 DSAStack->setDefaultDSAShared(KindKwLoc);
17239 case OMP_DEFAULT_firstprivate:
17240 DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
17242 case OMP_DEFAULT_private:
17243 DSAStack->setDefaultDSAPrivate(KindKwLoc);
17246 llvm_unreachable(
"DSA unexpected in OpenMP default clause");
17258 if (Kind == OMP_PROC_BIND_unknown) {
17259 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17261 unsigned(OMP_PROC_BIND_master),
17264 ? OMP_PROC_BIND_primary
17265 : OMP_PROC_BIND_spread) +
17267 << getOpenMPClauseName(OMPC_proc_bind);
17270 if (Kind == OMP_PROC_BIND_primary &&
getLangOpts().OpenMP < 51)
17271 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17273 unsigned(OMP_PROC_BIND_master),
17275 unsigned(OMP_PROC_BIND_spread) + 1)
17276 << getOpenMPClauseName(OMPC_proc_bind);
17285 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17287 OMPC_atomic_default_mem_order, 0,
17289 << getOpenMPClauseName(OMPC_atomic_default_mem_order);
17293 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
17302 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17305 << getOpenMPClauseName(OMPC_at);
17309 OMPAtClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
17318 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17321 << getOpenMPClauseName(OMPC_severity);
17332 assert(ME &&
"NULL expr in Message clause");
17333 if (!isa<StringLiteral>(ME)) {
17335 << getOpenMPClauseName(OMPC_message);
17346 if (Kind != OMPC_ORDER_concurrent ||
17351 "OMPC_ORDER_unknown not greater than 0");
17353 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
17357 << getOpenMPClauseName(OMPC_order);
17362 Diag(MLoc, diag::err_omp_unexpected_clause_value)
17366 << getOpenMPClauseName(OMPC_order);
17368 DSAStack->setRegionHasOrderConcurrent(
true);
17371 unsigned existingFlags =
DSAStack->getCurScope()->getFlags();
17372 DSAStack->getCurScope()->setFlags(existingFlags |
17378 Kind, KindLoc, StartLoc, LParenLoc, EndLoc, Modifier, MLoc);
17387 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
17389 OMPC_DEPEND_source, OMPC_DEPEND_sink, OMPC_DEPEND_depobj,
17390 OMPC_DEPEND_outallmemory, OMPC_DEPEND_inoutallmemory};
17392 Except.push_back(OMPC_DEPEND_inoutset);
17393 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17396 << getOpenMPClauseName(OMPC_update);
17400 KindKwLoc, Kind, EndLoc);
17407 for (
Expr *SizeExpr : SizeExprs) {
17409 SizeExpr, OMPC_sizes,
true);
17410 if (!NumForLoopsResult.
isUsable())
17414 DSAStack->setAssociatedLoops(SizeExprs.size());
17432 FactorExpr, OMPC_partial,
true);
17435 FactorExpr = FactorResult.
get();
17450 LParenLoc, EndLoc);
17460 case OMPC_schedule:
17461 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
17462 assert(Argument.size() == NumberOfElements &&
17463 ArgumentLoc.size() == NumberOfElements);
17468 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
17469 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
17472 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
17474 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
17477 case OMPC_dist_schedule:
17480 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
17482 case OMPC_defaultmap:
17483 enum { Modifier, DefaultmapKind };
17487 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
17491 enum { OrderModifier, OrderKind };
17495 LParenLoc, ArgumentLoc[OrderModifier], ArgumentLoc[OrderKind], EndLoc);
17498 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
17501 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17503 case OMPC_grainsize:
17504 assert(Argument.size() == 1 && ArgumentLoc.size() == 1 &&
17505 "Modifier for grainsize clause and its location are expected.");
17508 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17510 case OMPC_num_tasks:
17511 assert(Argument.size() == 1 && ArgumentLoc.size() == 1 &&
17512 "Modifier for num_tasks clause and its location are expected.");
17515 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17518 case OMPC_num_threads:
17522 case OMPC_allocator:
17523 case OMPC_collapse:
17525 case OMPC_proc_bind:
17527 case OMPC_firstprivate:
17528 case OMPC_lastprivate:
17530 case OMPC_reduction:
17531 case OMPC_task_reduction:
17532 case OMPC_in_reduction:
17536 case OMPC_copyprivate:
17540 case OMPC_mergeable:
17541 case OMPC_threadprivate:
17542 case OMPC_allocate:
17559 case OMPC_num_teams:
17560 case OMPC_thread_limit:
17561 case OMPC_priority:
17568 case OMPC_use_device_ptr:
17569 case OMPC_use_device_addr:
17570 case OMPC_is_device_ptr:
17571 case OMPC_has_device_addr:
17572 case OMPC_unified_address:
17573 case OMPC_unified_shared_memory:
17574 case OMPC_reverse_offload:
17575 case OMPC_dynamic_allocators:
17576 case OMPC_atomic_default_mem_order:
17577 case OMPC_device_type:
17579 case OMPC_nontemporal:
17581 case OMPC_severity:
17584 case OMPC_novariants:
17585 case OMPC_nocontext:
17587 case OMPC_inclusive:
17588 case OMPC_exclusive:
17589 case OMPC_uses_allocators:
17590 case OMPC_affinity:
17594 llvm_unreachable(
"Clause is not allowed.");
17605 Excluded.push_back(M2);
17606 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
17607 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
17608 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
17609 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
17610 S.
Diag(M1Loc, diag::err_omp_unexpected_clause_value)
17615 << getOpenMPClauseName(OMPC_schedule);
17633 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
17634 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
17635 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
17636 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
17637 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
17643 std::string Values;
17653 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
17654 << Values << getOpenMPClauseName(OMPC_schedule);
17662 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
17663 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
17664 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
17665 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
17666 diag::err_omp_schedule_nonmonotonic_static);
17669 Expr *ValExpr = ChunkSize;
17670 Stmt *HelperValStmt =
nullptr;
17681 ValExpr = Val.
get();
17686 if (std::optional<llvm::APSInt>
Result =
17688 if (
Result->isSigned() && !
Result->isStrictlyPositive()) {
17689 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
17694 DSAStack->getCurrentDirective(), OMPC_schedule,
17698 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17699 ValExpr = tryBuildCapture(
SemaRef, ValExpr, Captures).get();
17707 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
17724 case OMPC_mergeable:
17772 case OMPC_unified_address:
17775 case OMPC_unified_shared_memory:
17778 case OMPC_reverse_offload:
17781 case OMPC_dynamic_allocators:
17795 case OMPC_ompx_bare:
17800 case OMPC_num_threads:
17804 case OMPC_allocator:
17805 case OMPC_collapse:
17806 case OMPC_schedule:
17808 case OMPC_firstprivate:
17809 case OMPC_lastprivate:
17811 case OMPC_reduction:
17812 case OMPC_task_reduction:
17813 case OMPC_in_reduction:
17817 case OMPC_copyprivate:
17819 case OMPC_proc_bind:
17820 case OMPC_threadprivate:
17821 case OMPC_allocate:
17827 case OMPC_num_teams:
17828 case OMPC_thread_limit:
17829 case OMPC_priority:
17830 case OMPC_grainsize:
17831 case OMPC_num_tasks:
17833 case OMPC_dist_schedule:
17834 case OMPC_defaultmap:
17839 case OMPC_use_device_ptr:
17840 case OMPC_use_device_addr:
17841 case OMPC_is_device_ptr:
17842 case OMPC_has_device_addr:
17843 case OMPC_atomic_default_mem_order:
17844 case OMPC_device_type:
17846 case OMPC_nontemporal:
17849 case OMPC_severity:
17851 case OMPC_novariants:
17852 case OMPC_nocontext:
17854 case OMPC_inclusive:
17855 case OMPC_exclusive:
17856 case OMPC_uses_allocators:
17857 case OMPC_affinity:
17859 case OMPC_ompx_dyn_cgroup_mem:
17861 llvm_unreachable(
"Clause is not allowed.");
17920 Diag(KindLoc, diag::err_omp_atomic_fail_wrong_or_no_clauses);
18001 if (!
hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) {
18002 StringRef
Expected =
"'init', 'use', 'destroy', or 'nowait'";
18003 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
18004 <<
Expected << getOpenMPDirectiveName(OMPD_interop);
18017 bool HasInitClause =
false;
18018 bool IsTargetSync =
false;
18022 if (
const auto *InitClause = dyn_cast<OMPInitClause>(
C)) {
18023 HasInitClause =
true;
18024 if (InitClause->getIsTargetSync())
18025 IsTargetSync =
true;
18026 }
else if (
const auto *DC = dyn_cast<OMPDependClause>(
C)) {
18030 if (DependClause && HasInitClause && !IsTargetSync) {
18031 Diag(DependClause->
getBeginLoc(), diag::err_omp_interop_bad_depend_clause);
18045 if (ClauseKind == OMPC_init) {
18046 auto *E = cast<OMPInitClause>(
C)->getInteropVar();
18048 }
else if (ClauseKind == OMPC_use) {
18049 auto *E = cast<OMPUseClause>(
C)->getInteropVar();
18051 }
else if (ClauseKind == OMPC_destroy) {
18052 auto *E = cast<OMPDestroyClause>(
C)->getInteropVar();
18057 if (!InteropVars.insert(
DeclResult.first).second) {
18058 Diag(ELoc, diag::err_omp_interop_var_multiple_actions)
18074 Expr *RefExpr = InteropVarExpr;
18077 false,
"omp_interop_t");
18088 bool HasError =
false;
18094 if (
const auto *TD = dyn_cast<TypeDecl>(ND)) {
18095 InteropType =
QualType(TD->getTypeForDecl(), 0);
18104 SemaRef.
Diag(VarLoc, diag::err_omp_implied_type_not_found)
18105 <<
"omp_interop_t";
18111 SemaRef.
Diag(VarLoc, diag::err_omp_interop_variable_wrong_type);
18117 if ((Kind == OMPC_init || Kind == OMPC_destroy) &&
18119 SemaRef.
Diag(VarLoc, diag::err_omp_interop_variable_expected)
18141 if (isa<StringLiteral>(E))
18148 StartLoc, LParenLoc, VarLoc, EndLoc);
18161 OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
18170 DSAStack->getCurrentDirective() == OMPD_depobj) {
18171 Diag(StartLoc, diag::err_omp_expected_clause_argument)
18172 << getOpenMPClauseName(OMPC_destroy)
18173 << getOpenMPDirectiveName(OMPD_depobj);
18189 Stmt *HelperValStmt =
nullptr;
18192 !
Condition->isInstantiationDependent() &&
18193 !
Condition->containsUnexpandedParameterPack()) {
18203 if (CaptureRegion != OMPD_unknown &&
18206 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18207 ValExpr = tryBuildCapture(
SemaRef, ValExpr, Captures).get();
18213 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
18221 Stmt *HelperValStmt =
nullptr;
18224 !
Condition->isInstantiationDependent() &&
18225 !
Condition->containsUnexpandedParameterPack()) {
18235 if (CaptureRegion != OMPD_unknown &&
18238 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18239 ValExpr = tryBuildCapture(
SemaRef, ValExpr, Captures).get();
18245 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
18252 Expr *ValExpr = ThreadID;
18253 Stmt *HelperValStmt =
nullptr;
18258 if (CaptureRegion != OMPD_unknown &&
18261 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18262 ValExpr = tryBuildCapture(
SemaRef, ValExpr, Captures).get();
18267 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
18278 int ExtraModifier =
Data.ExtraModifier;
18285 case OMPC_firstprivate:
18288 case OMPC_lastprivate:
18290 "Unexpected lastprivate modifier.");
18293 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
18298 case OMPC_reduction:
18300 "Unexpected lastprivate modifier.");
18303 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
18304 Data.ReductionOrMapperIdScopeSpec,
Data.ReductionOrMapperId);
18306 case OMPC_task_reduction:
18308 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
18309 Data.ReductionOrMapperIdScopeSpec,
Data.ReductionOrMapperId);
18311 case OMPC_in_reduction:
18313 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
18314 Data.ReductionOrMapperIdScopeSpec,
Data.ReductionOrMapperId);
18318 "Unexpected linear modifier.");
18320 VarList,
Data.DepModOrTailExpr, StartLoc, LParenLoc,
18322 ColonLoc,
Data.StepModifierLoc, EndLoc);
18326 LParenLoc, ColonLoc, EndLoc);
18331 case OMPC_copyprivate:
18339 "Unexpected depend modifier.");
18342 ColonLoc,
Data.OmpAllMemoryLoc},
18343 Data.DepModOrTailExpr, VarList, StartLoc, LParenLoc, EndLoc);
18347 "Unexpected map modifier.");
18349 Data.IteratorExpr,
Data.MapTypeModifiers,
Data.MapTypeModifiersLoc,
18350 Data.ReductionOrMapperIdScopeSpec,
Data.ReductionOrMapperId,
18352 ExtraModifierLoc, ColonLoc, VarList, Locs);
18357 Data.ReductionOrMapperIdScopeSpec,
18358 Data.ReductionOrMapperId, ColonLoc, VarList, Locs);
18362 Data.ReductionOrMapperIdScopeSpec,
18363 Data.ReductionOrMapperId, ColonLoc, VarList,
18366 case OMPC_use_device_ptr:
18369 case OMPC_use_device_addr:
18372 case OMPC_is_device_ptr:
18375 case OMPC_has_device_addr:
18378 case OMPC_allocate:
18380 LParenLoc, ColonLoc, EndLoc);
18382 case OMPC_nontemporal:
18385 case OMPC_inclusive:
18388 case OMPC_exclusive:
18391 case OMPC_affinity:
18393 Data.DepModOrTailExpr, VarList);
18395 case OMPC_doacross:
18398 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
18403 case OMPC_num_threads:
18407 case OMPC_allocator:
18408 case OMPC_collapse:
18410 case OMPC_proc_bind:
18411 case OMPC_schedule:
18415 case OMPC_mergeable:
18416 case OMPC_threadprivate:
18430 case OMPC_num_teams:
18431 case OMPC_thread_limit:
18432 case OMPC_priority:
18433 case OMPC_grainsize:
18435 case OMPC_num_tasks:
18437 case OMPC_dist_schedule:
18438 case OMPC_defaultmap:
18441 case OMPC_unified_address:
18442 case OMPC_unified_shared_memory:
18443 case OMPC_reverse_offload:
18444 case OMPC_dynamic_allocators:
18445 case OMPC_atomic_default_mem_order:
18446 case OMPC_device_type:
18450 case OMPC_severity:
18453 case OMPC_novariants:
18454 case OMPC_nocontext:
18456 case OMPC_uses_allocators:
18460 llvm_unreachable(
"Clause is not allowed.");
18491 bool IsImplicitClause =
18493 for (
Expr *RefExpr : VarList) {
18494 assert(RefExpr &&
"NULL expr in OpenMP private clause.");
18497 Expr *SimpleRefExpr = RefExpr;
18501 Vars.push_back(RefExpr);
18502 PrivateCopies.push_back(
nullptr);
18509 auto *VD = dyn_cast<VarDecl>(D);
18515 diag::err_omp_private_incomplete_type))
18517 Type =
Type.getNonReferenceType();
18537 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
18538 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
18539 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
18540 << getOpenMPClauseName(OMPC_private);
18549 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18550 << getOpenMPClauseName(OMPC_private) <<
Type
18551 << getOpenMPDirectiveName(CurrDir);
18552 bool IsDecl = !VD || VD->isThisDeclarationADefinition(
getASTContext()) ==
18555 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18570 CurrDir == OMPD_target) {
18572 if (
DSAStack->checkMappableExprComponentListsForDecl(
18576 ConflictKind = WhereFoundClauseKind;
18579 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18580 << getOpenMPClauseName(OMPC_private)
18581 << getOpenMPClauseName(ConflictKind)
18582 << getOpenMPDirectiveName(CurrDir);
18601 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
18610 auto *FD = dyn_cast<FieldDecl>(D);
18614 RefExpr->getExprLoc());
18618 if (!IsImplicitClause)
18619 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
18621 ? RefExpr->IgnoreParens()
18623 PrivateCopies.push_back(VDPrivateRefExpr);
18630 Vars, PrivateCopies);
18641 bool IsImplicitClause =
18645 for (
Expr *RefExpr : VarList) {
18646 assert(RefExpr &&
"NULL expr in OpenMP firstprivate clause.");
18649 Expr *SimpleRefExpr = RefExpr;
18653 Vars.push_back(RefExpr);
18654 PrivateCopies.push_back(
nullptr);
18655 Inits.push_back(
nullptr);
18661 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
18663 auto *VD = dyn_cast<VarDecl>(D);
18669 diag::err_omp_firstprivate_incomplete_type))
18671 Type =
Type.getNonReferenceType();
18681 DSAStackTy::DSAVarData TopDVar;
18682 if (!IsImplicitClause) {
18683 DSAStackTy::DSAVarData DVar =
18695 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
18697 DVar.CKind != OMPC_lastprivate) &&
18699 Diag(ELoc, diag::err_omp_wrong_dsa)
18700 << getOpenMPClauseName(DVar.CKind)
18701 << getOpenMPClauseName(OMPC_firstprivate);
18717 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
18718 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
18719 Diag(ELoc, diag::err_omp_wrong_dsa)
18720 << getOpenMPClauseName(DVar.CKind)
18721 << getOpenMPClauseName(OMPC_firstprivate);
18745 DVar =
DSAStack->getImplicitDSA(D,
true);
18746 if (DVar.CKind != OMPC_shared &&
18749 DVar.DKind == OMPD_unknown)) {
18750 Diag(ELoc, diag::err_omp_required_access)
18751 << getOpenMPClauseName(OMPC_firstprivate)
18752 << getOpenMPClauseName(OMPC_shared);
18772 return C == OMPC_reduction && !AppliedToPointee;
18780 if (DVar.CKind == OMPC_reduction &&
18784 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
18785 << getOpenMPDirectiveName(DVar.DKind);
18801 CurrDir == OMPD_target) {
18803 if (
DSAStack->checkMappableExprComponentListsForDecl(
18808 ConflictKind = WhereFoundClauseKind;
18811 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18812 << getOpenMPClauseName(OMPC_firstprivate)
18813 << getOpenMPClauseName(ConflictKind)
18814 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
18824 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18825 << getOpenMPClauseName(OMPC_firstprivate) <<
Type
18826 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
18827 bool IsDecl = !VD || VD->isThisDeclarationADefinition(
getASTContext()) ==
18830 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18839 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
18845 Expr *VDInitRefExpr =
nullptr;
18855 ElemType,
".firstprivate.temp");
18870 ".firstprivate.temp");
18872 RefExpr->getExprLoc());
18878 if (IsImplicitClause) {
18879 Diag(RefExpr->getExprLoc(),
18880 diag::note_omp_task_predetermined_firstprivate_here);
18887 RefExpr->getExprLoc());
18890 if (TopDVar.CKind == OMPC_lastprivate) {
18891 Ref = TopDVar.PrivateCopy;
18893 auto *FD = dyn_cast<FieldDecl>(D);
18898 RefExpr->getExprLoc());
18902 ExprCaptures.push_back(Ref->
getDecl());
18905 if (!IsImplicitClause)
18906 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
18908 ? RefExpr->IgnoreParens()
18910 PrivateCopies.push_back(VDPrivateRefExpr);
18911 Inits.push_back(VDInitRefExpr);
18918 getASTContext(), StartLoc, LParenLoc, EndLoc, Vars, PrivateCopies, Inits,
18927 assert(ColonLoc.
isValid() &&
"Colon location must be valid.");
18928 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
18931 << getOpenMPClauseName(OMPC_lastprivate);
18941 for (
Expr *RefExpr : VarList) {
18942 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
18945 Expr *SimpleRefExpr = RefExpr;
18949 Vars.push_back(RefExpr);
18950 SrcExprs.push_back(
nullptr);
18951 DstExprs.push_back(
nullptr);
18952 AssignmentOps.push_back(
nullptr);
18959 auto *VD = dyn_cast<VarDecl>(D);
18965 diag::err_omp_lastprivate_incomplete_type))
18967 Type =
Type.getNonReferenceType();
18984 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
18985 bool IsDecl = !VD || VD->isThisDeclarationADefinition(
getASTContext()) ==
18988 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19002 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
19003 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
19005 DVar.CKind != OMPC_firstprivate) &&
19006 (DVar.CKind != OMPC_private || DVar.RefExpr !=
nullptr)) {
19007 Diag(ELoc, diag::err_omp_wrong_dsa)
19008 << getOpenMPClauseName(DVar.CKind)
19009 << getOpenMPClauseName(OMPC_lastprivate);
19020 DSAStackTy::DSAVarData TopDVar = DVar;
19024 DVar =
DSAStack->getImplicitDSA(D,
true);
19025 if (DVar.CKind != OMPC_shared) {
19026 Diag(ELoc, diag::err_omp_required_access)
19027 << getOpenMPClauseName(OMPC_lastprivate)
19028 << getOpenMPClauseName(OMPC_shared);
19044 Type.getUnqualifiedType(),
".lastprivate.src",
19055 PseudoDstExpr, PseudoSrcExpr);
19065 if (TopDVar.CKind == OMPC_firstprivate) {
19066 Ref = TopDVar.PrivateCopy;
19070 ExprCaptures.push_back(Ref->
getDecl());
19072 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
19080 SimpleRefExpr, RefRes.
get());
19083 ExprPostUpdates.push_back(
19087 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
19089 ? RefExpr->IgnoreParens()
19091 SrcExprs.push_back(PseudoSrcExpr);
19092 DstExprs.push_back(PseudoDstExpr);
19093 AssignmentOps.push_back(AssignmentOp.
get());
19100 getASTContext(), StartLoc, LParenLoc, EndLoc, Vars, SrcExprs, DstExprs,
19101 AssignmentOps, LPKind, LPKindLoc, ColonLoc,
19111 for (
Expr *RefExpr : VarList) {
19112 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
19115 Expr *SimpleRefExpr = RefExpr;
19119 Vars.push_back(RefExpr);
19125 auto *VD = dyn_cast<VarDecl>(D);
19133 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
19134 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
19136 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
19137 << getOpenMPClauseName(OMPC_shared);
19146 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
19148 ? RefExpr->IgnoreParens()
19160class DSARefChecker :
public StmtVisitor<DSARefChecker, bool> {
19165 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
19166 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD,
false);
19167 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
19169 if (DVar.CKind != OMPC_unknown)
19171 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
19178 return DVarPrivate.CKind != OMPC_unknown;
19182 bool VisitStmt(
Stmt *S) {
19183 for (
Stmt *Child : S->children()) {
19184 if (Child && Visit(Child))
19189 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
19196class TransformExprToCaptures :
public TreeTransform<TransformExprToCaptures> {
19203 : BaseTransform(SemaRef),
Field(
FieldDecl), CapturedExpr(nullptr) {}
19208 CapturedExpr =
buildCapture(SemaRef, Field, E,
false);
19209 return CapturedExpr;
19211 return BaseTransform::TransformMemberExpr(E);
19213 DeclRefExpr *getCapturedExpr() {
return CapturedExpr; }
19217template <
typename T,
typename U>
19220 for (
U &
Set : Lookups) {
19221 for (
auto *D :
Set) {
19222 if (
T Res = Gen(cast<ValueDecl>(D)))
19232 for (
auto *RD : D->
redecls()) {
19237 auto ND = cast<NamedDecl>(RD);
19255 AssociatedClasses);
19268 for (
auto *NS : AssociatedNamespaces) {
19281 for (
auto *D : R) {
19282 auto *Underlying = D;
19283 if (
auto *USD = dyn_cast<UsingShadowDecl>(D))
19284 Underlying = USD->getTargetDecl();
19286 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
19287 !isa<OMPDeclareMapperDecl>(Underlying))
19294 if (
auto *USD = dyn_cast<UsingShadowDecl>(D))
19295 Underlying = USD->getTargetDecl();
19297 Lookups.emplace_back();
19298 Lookups.back().addDecl(Underlying);
19317 S = S->getParent();
19318 }
while (S && !S->isDeclScope(D));
19320 S = S->getParent();
19321 Lookups.emplace_back();
19322 Lookups.back().append(Lookup.
begin(), Lookup.
end());
19325 }
else if (
auto *ULE =
19326 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
19328 Decl *PrevD =
nullptr;
19332 else if (
auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
19333 Lookups.back().addDecl(DRD);
19340 filterLookupForUDReductionAndMapper<bool>(Lookups, [](
ValueDecl *D) {
19341 return !D->isInvalidDecl() &&
19342 (D->getType()->isDependentType() ||
19343 D->getType()->isInstantiationDependentType() ||
19344 D->getType()->containsUnexpandedParameterPack());
19357 true, ResSet.
begin(), ResSet.
end(),
false);
19377 if (SemaRef.
isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
19378 TyRec->getDecl()->getDefinition()) {
19381 if (Lookup.
empty()) {
19382 Lookups.emplace_back();
19383 Lookups.back().append(Lookup.
begin(), Lookup.
end());
19390 if (
auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
19400 if (
auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
19414 Loc, VD->
getType(), Ty, Paths.front(),
19424 if (ReductionIdScopeSpec.
isSet()) {
19425 SemaRef.
Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
19434struct ReductionData {
19459 unsigned RedModifier = 0;
19460 ReductionData() =
delete;
19462 ReductionData(
unsigned Size,
unsigned Modifier = 0) : RedModifier(Modifier) {
19463 Vars.reserve(Size);
19464 Privates.reserve(Size);
19465 LHSs.reserve(Size);
19466 RHSs.reserve(Size);
19467 ReductionOps.reserve(Size);
19468 if (RedModifier == OMPC_REDUCTION_inscan) {
19469 InscanCopyOps.reserve(Size);
19470 InscanCopyArrayTemps.reserve(Size);
19471 InscanCopyArrayElems.reserve(Size);
19473 TaskgroupDescriptors.reserve(Size);
19474 ExprCaptures.reserve(Size);
19475 ExprPostUpdates.reserve(Size);
19479 void push(
Expr *Item,
Expr *ReductionOp) {
19480 Vars.emplace_back(Item);
19481 Privates.emplace_back(
nullptr);
19482 LHSs.emplace_back(
nullptr);
19483 RHSs.emplace_back(
nullptr);
19484 ReductionOps.emplace_back(ReductionOp);
19485 TaskgroupDescriptors.emplace_back(
nullptr);
19486 if (RedModifier == OMPC_REDUCTION_inscan) {
19487 InscanCopyOps.push_back(
nullptr);
19488 InscanCopyArrayTemps.push_back(
nullptr);
19489 InscanCopyArrayElems.push_back(
nullptr);
19494 Expr *TaskgroupDescriptor,
Expr *CopyOp,
Expr *CopyArrayTemp,
19495 Expr *CopyArrayElem) {
19496 Vars.emplace_back(Item);
19497 Privates.emplace_back(Private);
19498 LHSs.emplace_back(LHS);
19499 RHSs.emplace_back(RHS);
19500 ReductionOps.emplace_back(ReductionOp);
19501 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
19502 if (RedModifier == OMPC_REDUCTION_inscan) {
19503 InscanCopyOps.push_back(CopyOp);
19504 InscanCopyArrayTemps.push_back(CopyArrayTemp);
19505 InscanCopyArrayElems.push_back(CopyArrayElem);
19507 assert(CopyOp ==
nullptr && CopyArrayTemp ==
nullptr &&
19508 CopyArrayElem ==
nullptr &&
19509 "Copy operation must be used for inscan reductions only.");
19519 if (Length ==
nullptr) {
19526 SingleElement =
true;
19527 ArraySizes.push_back(llvm::APSInt::get(1));
19530 if (!Length->EvaluateAsInt(
Result, Context))
19533 llvm::APSInt ConstantLengthValue =
Result.Val.getInt();
19534 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
19535 ArraySizes.push_back(ConstantLengthValue);
19543 while (
const auto *TempOASE = dyn_cast<ArraySectionExpr>(
Base)) {
19544 Length = TempOASE->getLength();
19545 if (Length ==
nullptr) {
19552 ArraySizes.push_back(llvm::APSInt::get(1));
19555 if (!Length->EvaluateAsInt(
Result, Context))
19558 llvm::APSInt ConstantLengthValue =
Result.Val.getInt();
19559 if (ConstantLengthValue.getSExtValue() != 1)
19562 ArraySizes.push_back(ConstantLengthValue);
19564 Base = TempOASE->getBase()->IgnoreParenImpCasts();
19568 if (!SingleElement) {
19569 while (
const auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base)) {
19571 ArraySizes.push_back(llvm::APSInt::get(1));
19572 Base = TempASE->getBase()->IgnoreParenImpCasts();
19584 return BO_AddAssign;
19586 return BO_MulAssign;
19588 return BO_AndAssign;
19590 return BO_OrAssign;
19592 return BO_XorAssign;
19648 case OO_Array_Delete:
19657 case OO_GreaterEqual:
19659 case OO_MinusEqual:
19661 case OO_SlashEqual:
19662 case OO_PercentEqual:
19663 case OO_CaretEqual:
19667 case OO_GreaterGreater:
19668 case OO_LessLessEqual:
19669 case OO_GreaterGreaterEqual:
19670 case OO_EqualEqual:
19671 case OO_ExclaimEqual:
19674 case OO_MinusMinus:
19680 case OO_Conditional:
19683 llvm_unreachable(
"Unexpected reduction identifier");
19686 if (II->isStr(
"max"))
19688 else if (II->isStr(
"min"))
19696 if (OOK == OO_Minus && S.
LangOpts.OpenMP == 52)
19697 S.
Diag(ReductionId.
getLoc(), diag::warn_omp_minus_in_reduction_deprecated);
19700 if (ReductionIdScopeSpec.
isValid())
19706 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
19707 bool FirstIter =
true;
19708 for (
Expr *RefExpr : VarList) {
19709 assert(RefExpr &&
"nullptr expr in OpenMP reduction clause.");
19717 if (!FirstIter && IR != ER)
19722 Expr *SimpleRefExpr = RefExpr;
19731 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
19732 ReductionId,
Type, BasePath, IR == ER ?
nullptr : *IR);
19733 Expr *ReductionOp =
nullptr;
19735 (DeclareReductionRef.
isUnset() ||
19736 isa<UnresolvedLookupExpr>(DeclareReductionRef.
get())))
19737 ReductionOp = DeclareReductionRef.
get();
19739 RD.push(RefExpr, ReductionOp);
19745 Expr *TaskgroupDescriptor =
nullptr;
19747 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
19748 auto *OASE = dyn_cast<ArraySectionExpr>(RefExpr->IgnoreParens());
19750 Type = ASE->getType().getNonReferenceType();
19755 Type = ATy->getElementType();
19758 Type =
Type.getNonReferenceType();
19762 auto *VD = dyn_cast<VarDecl>(D);
19768 diag::err_omp_reduction_incomplete_type))
19774 false, ASE || OASE))
19781 if (!ASE && !OASE) {
19783 VarDecl *VDDef = VD->getDefinition();
19785 DSARefChecker Check(Stack);
19786 if (Check.Visit(VDDef->
getInit())) {
19787 S.
Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
19788 << getOpenMPClauseName(ClauseKind) << ERange;
19806 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D,
false);
19807 if (DVar.CKind == OMPC_reduction) {
19808 S.
Diag(ELoc, diag::err_omp_once_referenced)
19809 << getOpenMPClauseName(ClauseKind);
19811 S.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
19814 if (DVar.CKind != OMPC_unknown) {
19815 S.
Diag(ELoc, diag::err_omp_wrong_dsa)
19816 << getOpenMPClauseName(DVar.CKind)
19817 << getOpenMPClauseName(OMPC_reduction);
19829 DVar = Stack->getImplicitDSA(D,
true);
19830 if (DVar.CKind != OMPC_shared) {
19831 S.
Diag(ELoc, diag::err_omp_required_access)
19832 << getOpenMPClauseName(OMPC_reduction)
19833 << getOpenMPClauseName(OMPC_shared);
19841 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D,
false);
19842 if (DVar.CKind == OMPC_threadprivate) {
19843 S.
Diag(ELoc, diag::err_omp_wrong_dsa)
19844 << getOpenMPClauseName(DVar.CKind)
19845 << getOpenMPClauseName(OMPC_reduction);
19855 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
19856 ReductionId,
Type, BasePath, IR == ER ?
nullptr : *IR);
19860 (DeclareReductionRef.
isUnset() ||
19861 isa<UnresolvedLookupExpr>(DeclareReductionRef.
get()))) {
19862 RD.push(RefExpr, DeclareReductionRef.
get());
19865 if (BOK == BO_Comma && DeclareReductionRef.
isUnset()) {
19869 diag::err_omp_unknown_reduction_identifier_since_omp_6_0)
19870 <<
Type << ReductionIdRange;
19873 diag::err_omp_unknown_reduction_identifier_prior_omp_6_0)
19874 <<
Type << ReductionIdRange;
19886 if (DeclareReductionRef.
isUnset()) {
19887 if ((BOK == BO_GT || BOK == BO_LT) &&
19890 S.
Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
19891 << getOpenMPClauseName(ClauseKind) << S.
getLangOpts().CPlusPlus;
19892 if (!ASE && !OASE) {
19893 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19896 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19901 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
19903 S.
Diag(ELoc, diag::err_omp_clause_floating_type_arg)
19904 << getOpenMPClauseName(ClauseKind);
19905 if (!ASE && !OASE) {
19906 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19909 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19916 Type =
Type.getNonLValueExprType(Context).getUnqualifiedType();
19925 bool ConstantLengthOASE =
false;
19927 bool SingleElement;
19930 Context, OASE, SingleElement, ArraySizes);
19933 if (ConstantLengthOASE && !SingleElement) {
19934 for (llvm::APSInt &Size : ArraySizes)
19941 if ((OASE && !ConstantLengthOASE) ||
19946 S.
Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
19947 S.
Diag(ELoc, diag::note_vla_unsupported);
19950 S.
targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
19951 S.
targetDiag(ELoc, diag::note_vla_unsupported);
19964 }
else if (!ASE && !OASE &&
19972 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
19977 if (DeclareReductionRef.
isUsable()) {
19979 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
19980 if (DRD->getInitializer()) {
20006 Type = ComplexTy->getElementType();
20008 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
20015 llvm::APInt InitValue = llvm::APInt::getAllOnes(Size);
20037 llvm::APInt InitValue =
20038 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
20039 : llvm::APInt::getMinValue(Size)
20040 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
20041 : llvm::APInt::getMaxValue(Size);
20052 llvm::APFloat InitValue = llvm::APFloat::getLargest(
20083 llvm_unreachable(
"Unexpected reduction operation");
20092 }
else if (!
Init) {
20102 S.
Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
20103 <<
Type << ReductionIdRange;
20104 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
20107 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20113 if (DeclareReductionRef.
isUsable()) {
20118 if (!BasePath.empty()) {
20122 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.
get(), &BasePath,
20125 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.
get(), &BasePath,
20129 QualType Params[] = {PtrRedTy, PtrRedTy};
20144 CombBOK, LHSDRE, RHSDRE);
20151 if (BOK != BO_LT && BOK != BO_GT) {
20154 BO_Assign, LHSDRE, ReductionOp.
get());
20156 auto *ConditionalOp =
new (Context)
20161 BO_Assign, LHSDRE, ConditionalOp);
20174 ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
20175 if (ClauseKind == OMPC_reduction &&
20176 RD.RedModifier == OMPC_REDUCTION_inscan) {
20178 CopyOpRes = S.
BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
20188 if (Stack->getCurrentDirective() == OMPD_simd ||
20226 if (ClauseKind == OMPC_in_reduction) {
20229 const Expr *ParentReductionOp =
nullptr;
20230 Expr *ParentBOKTD =
nullptr, *ParentReductionOpTD =
nullptr;
20231 DSAStackTy::DSAVarData ParentBOKDSA =
20232 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
20234 DSAStackTy::DSAVarData ParentReductionOpDSA =
20235 Stack->getTopMostTaskgroupReductionData(
20236 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
20237 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
20238 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
20239 if ((DeclareReductionRef.
isUnset() && IsParentReductionOp) ||
20240 (DeclareReductionRef.
isUsable() && IsParentBOK) ||
20241 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
20242 bool EmitError =
true;
20243 if (IsParentReductionOp && DeclareReductionRef.
isUsable()) {
20244 llvm::FoldingSetNodeID RedId, ParentRedId;
20245 ParentReductionOp->
Profile(ParentRedId, Context,
true);
20246 DeclareReductionRef.
get()->
Profile(RedId, Context,
20248 EmitError = RedId != ParentRedId;
20252 diag::err_omp_reduction_identifier_mismatch)
20253 << ReductionIdRange << RefExpr->getSourceRange();
20255 diag::note_omp_previous_reduction_identifier)
20257 << (IsParentBOK ? ParentBOKDSA.RefExpr
20258 : ParentReductionOpDSA.RefExpr)
20259 ->getSourceRange();
20263 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
20270 TransformExprToCaptures RebuildToCapture(S, D);
20272 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
20273 Ref = RebuildToCapture.getCapturedExpr();
20275 VarsExpr = Ref =
buildCapture(S, D, SimpleRefExpr,
false);
20278 RD.ExprCaptures.emplace_back(Ref->
getDecl());
20284 S.
BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
20289 Stack->getCurrentDirective() == OMPD_taskgroup) {
20290 S.
Diag(RefExpr->getExprLoc(),
20291 diag::err_omp_reduction_non_addressable_expression)
20292 << RefExpr->getSourceRange();
20295 RD.ExprPostUpdates.emplace_back(
20302 unsigned Modifier = RD.RedModifier;
20305 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
20306 Modifier = OMPC_REDUCTION_task;
20307 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
20309 if (Modifier == OMPC_REDUCTION_task &&
20310 (CurrDir == OMPD_taskgroup ||
20314 if (DeclareReductionRef.
isUsable())
20315 Stack->addTaskgroupReductionData(D, ReductionIdRange,
20316 DeclareReductionRef.
get());
20318 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
20320 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.
get(),
20321 TaskgroupDescriptor, CopyOpRes.
get(), TempArrayRes.
get(),
20322 TempArrayElem.
get());
20324 return RD.Vars.empty();
20334 Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
20337 << getOpenMPClauseName(OMPC_reduction);
20345 if (Modifier == OMPC_REDUCTION_inscan &&
20346 (
DSAStack->getCurrentDirective() != OMPD_for &&
20347 DSAStack->getCurrentDirective() != OMPD_for_simd &&
20348 DSAStack->getCurrentDirective() != OMPD_simd &&
20349 DSAStack->getCurrentDirective() != OMPD_parallel_for &&
20350 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) {
20351 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
20355 ReductionData RD(VarList.size(), Modifier);
20357 StartLoc, LParenLoc, ColonLoc, EndLoc,
20358 ReductionIdScopeSpec, ReductionId,
20359 UnresolvedReductions, RD))
20363 getASTContext(), StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc,
20366 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
20367 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
20377 ReductionData RD(VarList.size());
20379 VarList, StartLoc, LParenLoc, ColonLoc,
20380 EndLoc, ReductionIdScopeSpec, ReductionId,
20381 UnresolvedReductions, RD))
20385 getASTContext(), StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
20387 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
20397 ReductionData RD(VarList.size());
20399 StartLoc, LParenLoc, ColonLoc, EndLoc,
20400 ReductionIdScopeSpec, ReductionId,
20401 UnresolvedReductions, RD))
20405 getASTContext(), StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
20407 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
20416 Diag(LinLoc, diag::err_omp_wrong_linear_modifier)
20426 const auto *VD = dyn_cast_or_null<VarDecl>(D);
20429 diag::err_omp_linear_incomplete_type))
20431 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
20433 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
20437 Type =
Type.getNonReferenceType();
20444 if (!IsDeclareSimd &&
20449 Type =
Type.getUnqualifiedType().getCanonicalType();
20450 const auto *Ty =
Type.getTypePtrOrNull();
20451 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
20452 !Ty->isIntegralType(
getASTContext()) && !Ty->isPointerType())) {
20453 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) <<
Type;
20455 bool IsDecl = !VD || VD->isThisDeclarationADefinition(
getASTContext()) ==
20458 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20481 Diag(Step->
getBeginLoc(), diag::err_omp_step_simple_modifier_exclusive);
20483 LinKind = OMPC_LINEAR_val;
20484 for (
Expr *RefExpr : VarList) {
20485 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
20488 Expr *SimpleRefExpr = RefExpr;
20492 Vars.push_back(RefExpr);
20493 Privates.push_back(
nullptr);
20494 Inits.push_back(
nullptr);
20501 auto *VD = dyn_cast<VarDecl>(D);
20507 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
20508 if (DVar.RefExpr) {
20509 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
20510 << getOpenMPClauseName(OMPC_linear);
20517 Type =
Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
20523 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
20532 ExprCaptures.push_back(Ref->
getDecl());
20539 SimpleRefExpr, RefRes.
get());
20542 ExprPostUpdates.push_back(
20547 if (LinKind == OMPC_LINEAR_uval)
20548 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
20550 InitExpr = VD ? SimpleRefExpr : Ref;
20556 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
20558 ? RefExpr->IgnoreParens()
20560 Privates.push_back(PrivateRef);
20561 Inits.push_back(InitRef);
20567 Expr *StepExpr = Step;
20568 Expr *CalcStepExpr =
nullptr;
20576 StepExpr = Val.
get();
20590 if (std::optional<llvm::APSInt>
Result =
20592 if (!
Result->isNegative() && !
Result->isStrictlyPositive())
20593 Diag(StepLoc, diag::warn_omp_linear_step_zero)
20594 << Vars[0] << (Vars.size() > 1);
20598 CalcStepExpr = CalcStep.
get();
20603 LinLoc, ColonLoc, StepModifierLoc, EndLoc,
20604 Vars, Privates, Inits, StepExpr, CalcStepExpr,
20610 Expr *NumIterations,
Sema &SemaRef,
20611 Scope *S, DSAStackTy *Stack) {
20623 Step = cast<BinaryOperator>(CalcStep)->getLHS();
20624 bool HasErrors =
false;
20625 auto CurInit = Clause.
inits().begin();
20626 auto CurPrivate = Clause.
privates().begin();
20631 Expr *SimpleRefExpr = RefExpr;
20632 auto Res =
getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
20634 if (Res.second || !D) {
20635 Updates.push_back(
nullptr);
20636 Finals.push_back(
nullptr);
20640 auto &&Info = Stack->isLoopControlVariable(D);
20647 diag::err_omp_linear_distribute_var_non_loop_iteration);
20648 Updates.push_back(
nullptr);
20649 Finals.push_back(
nullptr);
20653 Expr *InitExpr = *CurInit;
20656 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
20658 if (LinKind == OMPC_LINEAR_uval)
20659 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
20663 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
20670 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
20681 S, RefExpr->getExprLoc(), BO_Assign, CapturedRef,
20684 Final = *CurPrivate;
20688 if (!
Update.isUsable() || !Final.isUsable()) {
20689 Updates.push_back(
nullptr);
20690 Finals.push_back(
nullptr);
20691 UsedExprs.push_back(
nullptr);
20694 Updates.push_back(
Update.get());
20695 Finals.push_back(Final.get());
20697 UsedExprs.push_back(SimpleRefExpr);
20703 UsedExprs.push_back(S);
20705 UsedExprs.append(Clause.
varlist_size() + 1 - UsedExprs.size(),
nullptr);
20716 for (
Expr *RefExpr : VarList) {
20717 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
20720 Expr *SimpleRefExpr = RefExpr;
20724 Vars.push_back(RefExpr);
20731 auto *VD = dyn_cast<VarDecl>(D);
20739 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
20741 bool IsDecl = !VD || VD->isThisDeclarationADefinition(
getASTContext()) ==
20744 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20751 if (
const Expr *PrevRef =
DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
20752 Diag(ELoc, diag::err_omp_used_in_clause_twice)
20753 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
20754 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
20755 << getOpenMPClauseName(OMPC_aligned);
20763 .DefaultFunctionArrayConversion(
20764 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
20773 if (Alignment !=
nullptr) {
20778 Alignment = AlignResult.
get();
20784 ColonLoc, EndLoc, Vars, Alignment);
20795 for (
Expr *RefExpr : VarList) {
20796 assert(RefExpr &&
"NULL expr in OpenMP copyin clause.");
20797 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
20799 Vars.push_back(RefExpr);
20800 SrcExprs.push_back(
nullptr);
20801 DstExprs.push_back(
nullptr);
20802 AssignmentOps.push_back(
nullptr);
20811 auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
20812 if (!DE || !isa<VarDecl>(DE->getDecl())) {
20813 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
20814 << 0 << RefExpr->getSourceRange();
20818 Decl *D = DE->getDecl();
20819 auto *VD = cast<VarDecl>(D);
20824 Vars.push_back(DE);
20825 SrcExprs.push_back(
nullptr);
20826 DstExprs.push_back(
nullptr);
20827 AssignmentOps.push_back(
nullptr);
20833 if (!
DSAStack->isThreadPrivate(VD)) {
20834 Diag(ELoc, diag::err_omp_required_access)
20835 << getOpenMPClauseName(OMPC_copyin)
20836 << getOpenMPDirectiveName(OMPD_threadprivate);
20860 PseudoDstExpr, PseudoSrcExpr);
20869 DSAStack->addDSA(VD, DE, OMPC_copyin);
20870 Vars.push_back(DE);
20871 SrcExprs.push_back(PseudoSrcExpr);
20872 DstExprs.push_back(PseudoDstExpr);
20873 AssignmentOps.push_back(AssignmentOp.
get());
20880 Vars, SrcExprs, DstExprs, AssignmentOps);
20891 for (
Expr *RefExpr : VarList) {
20892 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
20895 Expr *SimpleRefExpr = RefExpr;
20899 Vars.push_back(RefExpr);
20900 SrcExprs.push_back(
nullptr);
20901 DstExprs.push_back(
nullptr);
20902 AssignmentOps.push_back(
nullptr);
20909 auto *VD = dyn_cast<VarDecl>(D);
20914 if (!VD || !
DSAStack->isThreadPrivate(VD)) {
20915 DSAStackTy::DSAVarData DVar =
20917 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
20919 Diag(ELoc, diag::err_omp_wrong_dsa)
20920 << getOpenMPClauseName(DVar.CKind)
20921 << getOpenMPClauseName(OMPC_copyprivate);
20929 if (DVar.CKind == OMPC_unknown) {
20930 DVar =
DSAStack->getImplicitDSA(D,
false);
20931 if (DVar.CKind == OMPC_shared) {
20932 Diag(ELoc, diag::err_omp_required_access)
20933 << getOpenMPClauseName(OMPC_copyprivate)
20934 <<
"threadprivate or private in the enclosing context";
20943 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
20944 << getOpenMPClauseName(OMPC_copyprivate) <<
Type
20945 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
20946 bool IsDecl = !VD || VD->isThisDeclarationADefinition(
getASTContext()) ==
20949 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20970 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
20982 VD ? RefExpr->IgnoreParens()
20984 SrcExprs.push_back(PseudoSrcExpr);
20985 DstExprs.push_back(PseudoDstExpr);
20986 AssignmentOps.push_back(AssignmentOp.
get());
20993 EndLoc, Vars, SrcExprs, DstExprs,
21001 if (VarList.empty())
21010 bool Diagnose =
true) {
21011 QualType OMPDependT = Stack->getOMPDependT();
21012 if (!OMPDependT.
isNull())
21018 S.
Diag(Loc, diag::err_omp_implied_type_not_found) <<
"omp_depend_t";
21021 Stack->setOMPDependT(PT.
get());
21042 Diag(Depobj->
getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
21047 Diag(Depobj->
getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
21057struct DoacrossDataInfoTy {
21063 llvm::APSInt TotalDepCount;
21066static DoacrossDataInfoTy
21073 llvm::APSInt DepCounter(32);
21074 llvm::APSInt TotalDepCount(32);
21076 if (
const Expr *OrderedCountExpr =
21077 Stack->getParentOrderedRegionParam().first) {
21078 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(SemaRef.
Context);
21079 TotalDepCount.setIsUnsigned(
true);
21082 for (
Expr *RefExpr : VarList) {
21083 assert(RefExpr &&
"NULL expr in OpenMP doacross clause.");
21084 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
21086 Vars.push_back(RefExpr);
21093 if (Stack->getParentOrderedRegionParam().first &&
21094 DepCounter >= TotalDepCount) {
21095 SemaRef.
Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
21109 Vars.push_back(RefExpr);
21115 Expr *LHS = SimpleExpr;
21116 Expr *RHS =
nullptr;
21117 if (
auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
21119 OOLoc = BO->getOperatorLoc();
21122 }
else if (
auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
21123 OOK = OCE->getOperator();
21124 OOLoc = OCE->getOperatorLoc();
21127 }
else if (
auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
21128 OOK = MCE->getMethodDecl()
21131 .getCXXOverloadedOperator();
21132 OOLoc = MCE->getCallee()->getExprLoc();
21141 Vars.push_back(RefExpr);
21147 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK !=
OO_None)) {
21148 SemaRef.
Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
21154 RHS, OMPC_depend,
false);
21159 Stack->getParentOrderedRegionParam().first &&
21160 DepCounter != Stack->isParentLoopControlVariable(D).first) {
21162 Stack->getParentLoopControlVariable(DepCounter.getZExtValue());
21164 SemaRef.
Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
21167 SemaRef.
Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
21171 OpsOffs.emplace_back(RHS, OOK);
21173 Vars.push_back(RefExpr->IgnoreParenImpCasts());
21176 TotalDepCount > VarList.size() &&
21177 Stack->getParentOrderedRegionParam().first &&
21178 Stack->getParentLoopControlVariable(VarList.size() + 1)) {
21179 SemaRef.
Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
21180 << 1 << Stack->getParentLoopControlVariable(VarList.size() + 1);
21182 return {Vars, OpsOffs, TotalDepCount};
21191 if (
DSAStack->getCurrentDirective() == OMPD_ordered &&
21192 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
21193 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
21194 <<
"'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
21197 if (
DSAStack->getCurrentDirective() == OMPD_taskwait &&
21198 DepKind == OMPC_DEPEND_mutexinoutset) {
21199 Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed);
21202 if ((
DSAStack->getCurrentDirective() != OMPD_ordered ||
21203 DSAStack->getCurrentDirective() == OMPD_depobj) &&
21205 DepKind == OMPC_DEPEND_sink ||
21207 DSAStack->getCurrentDirective() == OMPD_depobj) &&
21208 DepKind == OMPC_DEPEND_depobj))) {
21210 OMPC_DEPEND_outallmemory,
21211 OMPC_DEPEND_inoutallmemory};
21213 DSAStack->getCurrentDirective() == OMPD_depobj)
21214 Except.push_back(OMPC_DEPEND_depobj);
21216 Except.push_back(OMPC_DEPEND_inoutset);
21218 ?
"depend modifier(iterator) or "
21220 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
21224 << getOpenMPClauseName(OMPC_depend);
21228 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
21230 diag::err_omp_depend_sink_source_with_modifier);
21235 Diag(DepModifier->
getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
21239 llvm::APSInt TotalDepCount(32);
21241 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
21244 Vars = VarOffset.Vars;
21245 OpsOffs = VarOffset.OpsOffs;
21246 TotalDepCount = VarOffset.TotalDepCount;
21248 for (
Expr *RefExpr : VarList) {
21249 assert(RefExpr &&
"NULL expr in OpenMP shared clause.");
21250 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
21252 Vars.push_back(RefExpr);
21258 if (DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) {
21259 bool OMPDependTFound =
getLangOpts().OpenMP >= 50;
21260 if (OMPDependTFound)
21262 DepKind == OMPC_DEPEND_depobj);
21263 if (DepKind == OMPC_DEPEND_depobj) {
21267 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
21268 !RefExpr->isInstantiationDependent() &&
21269 !RefExpr->containsUnexpandedParameterPack() &&
21270 (OMPDependTFound &&
21272 DSAStack->getOMPDependT(), RefExpr->getType()))) {
21273 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
21274 << 0 << RefExpr->getType() << RefExpr->getSourceRange();
21277 if (!RefExpr->isLValue()) {
21278 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
21279 << 1 << RefExpr->getType() << RefExpr->getSourceRange();
21286 QualType ExprTy = RefExpr->getType().getNonReferenceType();
21287 const auto *OASE = dyn_cast<ArraySectionExpr>(SimpleExpr);
21294 ExprTy = ATy->getElementType();
21300 const Expr *Length = OASE->getLength();
21302 if (Length && !Length->isValueDependent() &&
21304 Result.Val.getInt().isZero()) {
21306 diag::err_omp_depend_zero_length_array_section_not_allowed)
21316 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
21317 !RefExpr->isInstantiationDependent() &&
21318 !RefExpr->containsUnexpandedParameterPack() &&
21319 (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
21320 (OMPDependTFound &&
DSAStack->getOMPDependT().getTypePtr() ==
21322 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21325 << RefExpr->getSourceRange();
21329 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
21330 if (ASE && !ASE->getBase()->isTypeDependent() &&
21333 .getNonReferenceType()
21334 ->isPointerType() &&
21335 !ASE->getBase()->getType().getNonReferenceType()->isArrayType()) {
21336 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21339 << RefExpr->getSourceRange();
21347 RefExpr->IgnoreParenImpCasts());
21349 if (!Res.
isUsable() && !isa<ArraySectionExpr>(SimpleExpr) &&
21350 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
21351 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21354 << RefExpr->getSourceRange();
21359 Vars.push_back(RefExpr->IgnoreParenImpCasts());
21363 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
21364 DepKind != OMPC_DEPEND_outallmemory &&
21365 DepKind != OMPC_DEPEND_inoutallmemory && Vars.empty())
21370 {DepKind, DepLoc,
Data.ColonLoc,
Data.OmpAllMemoryLoc}, DepModifier, Vars,
21371 TotalDepCount.getZExtValue());
21372 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
21373 DSAStack->isParentOrderedRegion())
21374 DSAStack->addDoacrossDependClause(
C, OpsOffs);
21383 "Unexpected device modifier in OpenMP < 50.");
21385 bool ErrorFound =
false;
21387 std::string Values =
21389 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
21390 << Values << getOpenMPClauseName(OMPC_device);
21395 Stmt *HelperValStmt =
nullptr;
21408 if (Modifier == OMPC_DEVICE_ancestor) {
21412 diag::err_omp_device_ancestor_without_requires_reverse_offload);
21420 if (CaptureRegion != OMPD_unknown &&
21423 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
21424 ValExpr = tryBuildCapture(
SemaRef, ValExpr, Captures).get();
21429 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
21430 LParenLoc, ModifierLoc, EndLoc);
21435 bool FullCheck =
true) {
21440 SemaRef.
Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
21450 const auto *OASE = dyn_cast<ArraySectionExpr>(E);
21455 if (isa<ArraySubscriptExpr>(E) ||
21456 (OASE && OASE->getColonLocFirst().isInvalid())) {
21457 if (
const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
21458 return ATy->getSExtSize() != 1;
21463 assert(OASE &&
"Expecting array section if not an array subscript.");
21464 const Expr *LowerBound = OASE->getLowerBound();
21465 const Expr *Length = OASE->getLength();
21474 llvm::APSInt ConstLowerBound =
Result.Val.getInt();
21475 if (ConstLowerBound.getSExtValue())
21490 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr());
21498 llvm::APSInt ConstLength =
Result.Val.getInt();
21499 return CATy->getSExtSize() != ConstLength.getSExtValue();
21508 const auto *OASE = dyn_cast<ArraySectionExpr>(E);
21512 if (isa<ArraySubscriptExpr>(E) ||
21513 (OASE && OASE->getColonLocFirst().isInvalid()))
21516 assert(OASE &&
"Expecting array section if not an array subscript.");
21517 const Expr *Length = OASE->getLength();
21523 if (
const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
21524 return ATy->getSExtSize() != 1;
21534 llvm::APSInt ConstLength =
Result.Val.getInt();
21535 return ConstLength.getSExtValue() != 1;
21574class MapBaseChecker final :
public StmtVisitor<MapBaseChecker, bool> {
21579 bool IsNonContiguous =
false;
21580 bool NoDiagnose =
false;
21581 const Expr *RelevantExpr =
nullptr;
21582 bool AllowUnitySizeArraySection =
true;
21583 bool AllowWholeSizeArraySection =
true;
21584 bool AllowAnotherPtr =
true;
21588 void emitErrorMsg() {
21590 if (SemaRef.getLangOpts().OpenMP < 50) {
21592 diag::err_omp_expected_named_var_member_or_array_expression)
21595 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
21596 << getOpenMPClauseName(CKind) << ERange;
21602 if (!isa<VarDecl>(DRE->
getDecl())) {
21606 assert(!RelevantExpr &&
"RelevantExpr is expected to be nullptr");
21607 RelevantExpr = DRE;
21609 Components.emplace_back(DRE, DRE->
getDecl(), IsNonContiguous);
21617 if (isa<CXXThisExpr>(BaseE)) {
21618 assert(!RelevantExpr &&
"RelevantExpr is expected to be nullptr");
21627 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
21643 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
21663 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
21667 return RelevantExpr || Visit(E);
21677 AllowUnitySizeArraySection =
false;
21678 AllowWholeSizeArraySection =
false;
21681 Components.emplace_back(ME, FD, IsNonContiguous);
21682 return RelevantExpr || Visit(E);
21690 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
21694 return RelevantExpr || Visit(E);
21701 AllowWholeSizeArraySection =
false;
21707 !Result.Val.getInt().isZero()) {
21709 diag::err_omp_invalid_map_this_expr);
21711 diag::note_omp_invalid_subscript_on_this_ptr_map);
21713 assert(!RelevantExpr &&
"RelevantExpr is expected to be nullptr");
21718 Components.emplace_back(AE,
nullptr, IsNonContiguous);
21720 return RelevantExpr || Visit(E);
21726 assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) &&
21727 "Array sections cannot be implicitly mapped.");
21741 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
21751 if (AllowWholeSizeArraySection) {
21758 if (NotWhole || IsPointer)
21759 AllowWholeSizeArraySection =
false;
21760 }
else if (DKind == OMPD_target_update &&
21761 SemaRef.getLangOpts().OpenMP >= 50) {
21762 if (IsPointer && !AllowAnotherPtr)
21763 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
21766 IsNonContiguous =
true;
21767 }
else if (AllowUnitySizeArraySection && NotUnity) {
21773 diag::err_array_section_does_not_specify_contiguous_storage)
21779 AllowAnotherPtr =
false;
21781 if (
const auto *TE = dyn_cast<CXXThisExpr>(E)) {
21788 diag::err_omp_invalid_map_this_expr);
21790 diag::note_omp_invalid_length_on_this_ptr_mapping);
21794 SemaRef.getASTContext()) &&
21797 diag::err_omp_invalid_map_this_expr);
21799 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
21801 assert(!RelevantExpr &&
"RelevantExpr is expected to be nullptr");
21806 Components.emplace_back(OASE,
nullptr,
false);
21807 return RelevantExpr || Visit(E);
21813 Components.emplace_back(E,
nullptr, IsNonContiguous);
21815 return Visit(
Base->IgnoreParenImpCasts());
21819 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->
isLValue() ||
21824 if (!RelevantExpr) {
21826 Components.emplace_back(UO,
nullptr,
false);
21842 Components.emplace_back(BO,
nullptr,
false);
21845 "Either LHS or RHS have base decl inside");
21847 return RelevantExpr || Visit(LE);
21848 return RelevantExpr || Visit(RE);
21851 assert(!RelevantExpr &&
"RelevantExpr is expected to be nullptr");
21852 RelevantExpr = CTE;
21853 Components.emplace_back(CTE,
nullptr, IsNonContiguous);
21857 assert(!RelevantExpr &&
"RelevantExpr is expected to be nullptr");
21858 Components.emplace_back(COCE,
nullptr, IsNonContiguous);
21867 return Visit(Source);
21869 bool VisitStmt(
Stmt *) {
21873 const Expr *getFoundBase()
const {
return RelevantExpr; }
21874 explicit MapBaseChecker(
21878 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
21879 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
21893 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
21897 if (SemaRef.
getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
21898 (CKind == OMPC_to || CKind == OMPC_from)) {
21899 auto CI = CurComponents.rbegin();
21900 auto CE = CurComponents.rend();
21901 for (; CI != CE; ++CI) {
21903 dyn_cast<ArraySectionExpr>(CI->getAssociatedExpression());
21908 SemaRef.
Diag(ELoc, diag::err_array_section_does_not_specify_length)
21912 return Checker.getFoundBase();
21921 bool CurrentRegionOnly,
21932 assert(!CurComponents.empty() &&
"Map clause expression with no components!");
21933 assert(CurComponents.back().getAssociatedDeclaration() == VD &&
21934 "Map clause expression with unexpected base!");
21937 bool IsEnclosedByDataEnvironmentExpr =
false;
21938 const Expr *EnclosingExpr =
nullptr;
21940 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
21941 VD, CurrentRegionOnly,
21942 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
21943 ERange, CKind, &EnclosingExpr,
21947 if (CKind == Kind && SemaRef.
LangOpts.OpenMP >= 50)
21949 assert(!StackComponents.empty() &&
21950 "Map clause expression with no components!");
21951 assert(StackComponents.back().getAssociatedDeclaration() == VD &&
21952 "Map clause expression with unexpected base!");
21956 const Expr *RE = StackComponents.front().getAssociatedExpression();
21962 auto CI = CurComponents.rbegin();
21963 auto CE = CurComponents.rend();
21964 auto SI = StackComponents.rbegin();
21965 auto SE = StackComponents.rend();
21966 for (; CI != CE && SI != SE; ++CI, ++SI) {
21971 if (CurrentRegionOnly &&
21972 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
21973 isa<ArraySectionExpr>(CI->getAssociatedExpression()) ||
21974 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
21975 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
21976 isa<ArraySectionExpr>(SI->getAssociatedExpression()) ||
21977 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
21978 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
21979 diag::err_omp_multiple_array_items_in_map_clause)
21980 << CI->getAssociatedExpression()->getSourceRange();
21981 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
21982 diag::note_used_here)
21983 << SI->getAssociatedExpression()->getSourceRange();
21988 if (CI->getAssociatedExpression()->getStmtClass() !=
21989 SI->getAssociatedExpression()->getStmtClass())
21993 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
21999 for (; SI != SE; ++SI) {
22001 if (
const auto *ASE =
22002 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
22003 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
22004 }
else if (
const auto *OASE = dyn_cast<ArraySectionExpr>(
22005 SI->getAssociatedExpression())) {
22006 const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
22007 Type = ArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
22008 }
else if (
const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
22009 SI->getAssociatedExpression())) {
22010 Type = OASE->getBase()->getType()->getPointeeType();
22014 SemaRef, SI->getAssociatedExpression(),
Type))
22024 if (CI == CE && SI == SE) {
22025 if (CurrentRegionOnly) {
22026 if (CKind == OMPC_map) {
22027 SemaRef.
Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
22029 assert(CKind == OMPC_to || CKind == OMPC_from);
22030 SemaRef.
Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
22039 IsEnclosedByDataEnvironmentExpr =
true;
22044 std::prev(CI)->getAssociatedDeclaration()->getType();
22046 std::prev(CI)->getAssociatedExpression()->getExprLoc();
22065 if (CI == CE || SI == SE) {
22068 diag::err_omp_pointer_mapped_along_with_derived_section)
22074 if (CI->getAssociatedExpression()->getStmtClass() !=
22075 SI->getAssociatedExpression()->getStmtClass() ||
22076 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
22077 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
22078 assert(CI != CE && SI != SE);
22079 SemaRef.
Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
22092 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
22093 if (CKind == OMPC_map) {
22094 if (CI != CE || SI != SE) {
22098 CI != CE ? CurComponents.begin() : StackComponents.begin();
22099 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
22101 while (It != End && !It->getAssociatedDeclaration())
22102 std::advance(It, 1);
22103 assert(It != End &&
22104 "Expected at least one component with the declaration.");
22105 if (It !=
Begin && It->getAssociatedDeclaration()
22107 .getCanonicalType()
22108 ->isAnyPointerType()) {
22109 IsEnclosedByDataEnvironmentExpr =
false;
22110 EnclosingExpr =
nullptr;
22114 SemaRef.
Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
22116 assert(CKind == OMPC_to || CKind == OMPC_from);
22117 SemaRef.
Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
22127 if (!CurrentRegionOnly && SI != SE)
22128 EnclosingExpr = RE;
22132 IsEnclosedByDataEnvironmentExpr |=
22133 (!CurrentRegionOnly && CI != CE && SI == SE);
22138 if (CurrentRegionOnly)
22152 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
22154 diag::err_omp_original_storage_is_shared_and_does_not_contain)
22170 Expr *UnresolvedMapper) {
22185 while (S && !S->isDeclScope(D))
22186 S = S->getParent();
22188 S = S->getParent();
22189 Lookups.emplace_back();
22190 Lookups.back().append(Lookup.
begin(), Lookup.
end());
22193 }
else if (
auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
22197 auto *DMD = cast<OMPDeclareMapperDecl>(D);
22198 assert(DMD &&
"Expect valid OMPDeclareMapperDecl during instantiation.");
22199 Lookups.back().addDecl(DMD);
22207 filterLookupForUDReductionAndMapper<bool>(Lookups, [](
ValueDecl *D) {
22208 return !D->isInvalidDecl() &&
22209 (D->getType()->isDependentType() ||
22210 D->getType()->isInstantiationDependentType() ||
22211 D->getType()->containsUnexpandedParameterPack());
22222 false, URS.
begin(), URS.
end(),
false);
22229 SemaRef.
Diag(Loc, diag::err_omp_mapper_wrong_type);
22236 if (
auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
22246 if (
auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
22269 SemaRef.
Diag(Loc, diag::err_omp_invalid_mapper)
22279struct MappableVarListInfo {
22294 VarComponents.reserve(VarList.size());
22295 VarBaseDeclarations.reserve(VarList.size());
22313 bool IsMapTypeImplicit =
false,
bool NoDiagnose =
false) {
22315 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
22316 "Unexpected clause kind with mappable expressions!");
22324 MapperId.
setName(DeclNames.getIdentifier(
22326 MapperId.
setLoc(StartLoc);
22330 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
22331 bool UpdateUMIt =
false;
22332 Expr *UnresolvedMapper =
nullptr;
22334 bool HasHoldModifier =
22335 llvm::is_contained(Modifiers, OMPC_MAP_MODIFIER_ompx_hold);
22343 for (
Expr *RE : MVLI.VarList) {
22344 assert(RE &&
"Null expr in omp to/from/map clause");
22348 if (UpdateUMIt && UMIt != UMEnd) {
22352 "Expect the size of UnresolvedMappers to match with that of VarList");
22356 UnresolvedMapper = *UMIt;
22365 SemaRef, DSAS->
getCurScope(), MapperIdScopeSpec, MapperId,
22369 MVLI.UDMapperList.push_back(ER.
get());
22372 MVLI.ProcessedVarList.push_back(RE);
22381 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
22384 SemaRef.
Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
22397 DSAS->getCurrentDirective(), NoDiagnose);
22401 assert(!CurComponents.empty() &&
22402 "Invalid mappable expression information.");
22404 if (
const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
22406 DSAS->addMappedClassesQualTypes(TE->getType());
22409 SemaRef, DSAS->
getCurScope(), MapperIdScopeSpec, MapperId,
22413 MVLI.UDMapperList.push_back(ER.
get());
22415 MVLI.ProcessedVarList.push_back(RE);
22416 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22417 MVLI.VarComponents.back().append(CurComponents.begin(),
22418 CurComponents.end());
22419 MVLI.VarBaseDeclarations.push_back(
nullptr);
22426 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
22427 assert(CurDeclaration &&
"Null decl on map clause.");
22430 "Expecting components to have associated only canonical declarations.");
22432 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
22433 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
22435 assert((VD || FD) &&
"Only variables or fields are expected here!");
22442 if (VD && DSAS->isThreadPrivate(VD)) {
22445 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD,
false);
22446 SemaRef.
Diag(ELoc, diag::err_omp_threadprivate_in_clause)
22447 << getOpenMPClauseName(CKind);
22461 true, CurComponents, CKind))
22463 if (CKind == OMPC_map &&
22466 false, CurComponents, CKind))
22473 auto I = llvm::find_if(
22478 assert(I != CurComponents.end() &&
"Null decl on map clause.");
22481 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->
IgnoreParens());
22482 auto *OASE = dyn_cast<ArraySectionExpr>(VE->
IgnoreParens());
22483 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->
IgnoreParens());
22485 Type = ASE->getType().getNonReferenceType();
22490 Type = ATy->getElementType();
22493 Type =
Type.getNonReferenceType();
22494 }
else if (OAShE) {
22508 if (CKind == OMPC_map) {
22515 if (DKind == OMPD_target_enter_data &&
22516 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc ||
22518 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
22519 << (IsMapTypeImplicit ? 1 : 0)
22521 << getOpenMPDirectiveName(DKind);
22530 if (DKind == OMPD_target_exit_data &&
22531 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
22532 MapType == OMPC_MAP_delete || SemaRef.
getLangOpts().OpenMP >= 52)) {
22533 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
22534 << (IsMapTypeImplicit ? 1 : 0)
22536 << getOpenMPDirectiveName(DKind);
22545 if ((DKind == OMPD_target_enter_data || DKind == OMPD_target_exit_data) &&
22547 SemaRef.
Diag(StartLoc,
22548 diag::err_omp_invalid_map_type_modifier_for_directive)
22550 OMPC_MAP_MODIFIER_ompx_hold)
22551 << getOpenMPDirectiveName(DKind);
22559 if ((DKind == OMPD_target_data ||
22561 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
22562 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
22563 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
22564 << (IsMapTypeImplicit ? 1 : 0)
22566 << getOpenMPDirectiveName(DKind);
22578 if (VD && ((SemaRef.
LangOpts.OpenMP <= 45 &&
22580 DKind == OMPD_target)) {
22581 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD,
false);
22583 SemaRef.
Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
22584 << getOpenMPClauseName(DVar.CKind)
22585 << getOpenMPClauseName(OMPC_map)
22586 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
22595 SemaRef, DSAS->
getCurScope(), MapperIdScopeSpec, MapperId,
22596 Type.getCanonicalType(), UnresolvedMapper);
22599 MVLI.UDMapperList.push_back(ER.
get());
22602 MVLI.ProcessedVarList.push_back(RE);
22606 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
22612 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22613 MVLI.VarComponents.back().append(CurComponents.begin(),
22614 CurComponents.end());
22615 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ?
nullptr
22635 BuiltinType::OMPIterator))
22637 diag::err_omp_map_modifier_not_iterator);
22640 unsigned Count = 0;
22641 for (
unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
22643 llvm::is_contained(Modifiers, MapTypeModifiers[I])) {
22644 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
22648 "Modifiers exceed the allowed number of map type modifiers");
22649 Modifiers[Count] = MapTypeModifiers[I];
22650 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
22654 MappableVarListInfo MVLI(VarList);
22656 MapperIdScopeSpec, MapperId, UnresolvedMappers,
22657 MapType, Modifiers, IsMapTypeImplicit,
22663 getASTContext(), Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
22664 MVLI.VarComponents, MVLI.UDMapperList, IteratorModifier, Modifiers,
22666 MapperId, MapType, IsMapTypeImplicit, MapLoc);
22674 if (ReductionType.
isNull())
22682 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
22687 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
22691 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
22695 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
22698 return ReductionType;
22704 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
22707 Decls.reserve(ReductionTypes.size());
22716 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
22718 bool InCompoundScope =
true;
22719 if (S !=
nullptr) {
22728 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
22730 while (Filter.hasNext()) {
22731 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
22732 if (InCompoundScope) {
22733 auto I = UsedAsPrevious.find(PrevDecl);
22734 if (I == UsedAsPrevious.end())
22735 UsedAsPrevious[PrevDecl] =
false;
22737 UsedAsPrevious[D] =
true;
22739 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
22740 PrevDecl->getLocation();
22743 if (InCompoundScope) {
22744 for (
const auto &PrevData : UsedAsPrevious) {
22745 if (!PrevData.second) {
22746 PrevDRD = PrevData.first;
22751 }
else if (PrevDeclInScope !=
nullptr) {
22752 auto *PrevDRDInScope = PrevDRD =
22753 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
22755 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
22756 PrevDRDInScope->getLocation();
22757 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
22758 }
while (PrevDRDInScope !=
nullptr);
22760 for (
const auto &TyData : ReductionTypes) {
22761 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
22763 if (I != PreviousRedeclTypes.end()) {
22764 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
22766 Diag(I->second, diag::note_previous_definition);
22769 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
22771 getASTContext(), DC, TyData.second, Name, TyData.first, PrevDRD);
22773 DRD->setAccess(AS);
22774 Decls.push_back(DRD);
22776 DRD->setInvalidDecl();
22786 auto *DRD = cast<OMPDeclareReductionDecl>(D);
22801 QualType ReductionType = DRD->getType();
22818 if (S !=
nullptr) {
22822 DRD->addDecl(OmpInParm);
22823 DRD->addDecl(OmpOutParm);
22829 DRD->setCombinerData(InE, OutE);
22834 auto *DRD = cast<OMPDeclareReductionDecl>(D);
22841 if (Combiner !=
nullptr)
22842 DRD->setCombiner(Combiner);
22844 DRD->setInvalidDecl();
22849 auto *DRD = cast<OMPDeclareReductionDecl>(D);
22863 QualType ReductionType = DRD->getType();
22880 if (S !=
nullptr) {
22884 DRD->addDecl(OmpPrivParm);
22885 DRD->addDecl(OmpOrigParm);
22891 DRD->setInitializerData(OrigE, PrivE);
22892 return OmpPrivParm;
22897 auto *DRD = cast<OMPDeclareReductionDecl>(D);
22906 }
else if (OmpPrivParm->
hasInit()) {
22907 DRD->setInitializer(OmpPrivParm->
getInit(),
22912 DRD->setInvalidDecl();
22918 for (
Decl *D : DeclReductions.
get()) {
22924 D->setInvalidDecl();
22927 return DeclReductions;
22947 assert(
ParsedType.isUsable() &&
"Expect usable parsed mapper type");
22950 assert(!MapperType.
isNull() &&
"Expect valid mapper type");
22955 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
22972 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
22974 bool InCompoundScope =
true;
22975 if (S !=
nullptr) {
22984 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
22986 while (Filter.hasNext()) {
22987 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
22988 if (InCompoundScope) {
22989 auto I = UsedAsPrevious.find(PrevDecl);
22990 if (I == UsedAsPrevious.end())
22991 UsedAsPrevious[PrevDecl] =
false;
22993 UsedAsPrevious[D] =
true;
22995 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
22996 PrevDecl->getLocation();
22999 if (InCompoundScope) {
23000 for (
const auto &PrevData : UsedAsPrevious) {
23001 if (!PrevData.second) {
23002 PrevDMD = PrevData.first;
23007 }
else if (PrevDeclInScope) {
23008 auto *PrevDMDInScope = PrevDMD =
23009 cast<OMPDeclareMapperDecl>(PrevDeclInScope);
23011 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
23012 PrevDMDInScope->getLocation();
23013 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
23014 }
while (PrevDMDInScope !=
nullptr);
23018 if (I != PreviousRedeclTypes.end()) {
23019 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
23020 << MapperType << Name;
23021 Diag(I->second, diag::note_previous_definition);
23030 ClausesWithImplicit);
23032 MapperType, VN, ClausesWithImplicit,
23038 DMD->setAccess(AS);
23040 DMD->setInvalidDecl();
23042 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
23046 DMD->setMapperVarRef(MapperVarRef);
23062 DSAStack->addDeclareMapperVarRef(E);
23067 if (
DSAStack->getDeclareMapperVarRef())
23072 assert(
getLangOpts().OpenMP &&
"Expected OpenMP mode.");
23074 if (
const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) {
23087 assert(
getLangOpts().OpenMP &&
"Expected OpenMP mode.");
23088 return cast<DeclRefExpr>(
DSAStack->getDeclareMapperVarRef())->getDecl();
23095 Expr *ValExpr = NumTeams;
23096 Stmt *HelperValStmt =
nullptr;
23107 if (CaptureRegion != OMPD_unknown &&
23110 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
23111 ValExpr = tryBuildCapture(
SemaRef, ValExpr, Captures).get();
23116 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
23123 Expr *ValExpr = ThreadLimit;
23124 Stmt *HelperValStmt =
nullptr;
23135 if (CaptureRegion != OMPD_unknown &&
23138 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
23139 ValExpr = tryBuildCapture(
SemaRef, ValExpr, Captures).get();
23144 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
23152 Stmt *HelperValStmt =
nullptr;
23158 ValExpr,
SemaRef, OMPC_priority,
23160 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
23164 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
23172 "Unexpected grainsize modifier in OpenMP < 51.");
23177 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
23178 << Values << getOpenMPClauseName(OMPC_grainsize);
23182 Expr *ValExpr = Grainsize;
23183 Stmt *HelperValStmt =
nullptr;
23193 &CaptureRegion, &HelperValStmt))
23198 StartLoc, LParenLoc, ModifierLoc, EndLoc);
23206 "Unexpected num_tasks modifier in OpenMP < 51.");
23211 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
23212 << Values << getOpenMPClauseName(OMPC_num_tasks);
23216 Expr *ValExpr = NumTasks;
23217 Stmt *HelperValStmt =
nullptr;
23224 ValExpr,
SemaRef, OMPC_num_tasks,
23226 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
23231 StartLoc, LParenLoc, ModifierLoc, EndLoc);
23251 DSAStackTy *Stack) {
23252 QualType OMPEventHandleT = Stack->getOMPEventHandleT();
23253 if (!OMPEventHandleT.
isNull())
23258 S.
Diag(Loc, diag::err_omp_implied_type_not_found) <<
"omp_event_handle_t";
23261 Stack->setOMPEventHandleT(PT.
get());
23282 auto *VD = dyn_cast_or_null<VarDecl>(Ref->
getDecl());
23292 <<
"omp_event_handle_t" << 1 << VD->
getType()
23299 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(VD,
false);
23300 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
23303 << getOpenMPClauseName(DVar.CKind)
23304 << getOpenMPClauseName(OMPC_firstprivate);
23319 std::string Values;
23323 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23324 << Values << getOpenMPClauseName(OMPC_dist_schedule);
23327 Expr *ValExpr = ChunkSize;
23328 Stmt *HelperValStmt =
nullptr;
23339 ValExpr = Val.
get();
23344 if (std::optional<llvm::APSInt>
Result =
23346 if (
Result->isSigned() && !
Result->isStrictlyPositive()) {
23347 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
23352 DSAStack->getCurrentDirective(), OMPC_dist_schedule,
23356 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
23357 ValExpr = tryBuildCapture(
SemaRef, ValExpr, Captures).get();
23365 Kind, ValExpr, HelperValStmt);
23373 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
23374 Kind != OMPC_DEFAULTMAP_scalar) {
23378 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
23380 OMPC_DEFAULTMAP_MODIFIER_tofrom);
23384 OMPC_DEFAULTMAP_scalar);
23388 Diag(Loc, diag::err_omp_unexpected_clause_value)
23389 <<
Value << getOpenMPClauseName(OMPC_defaultmap);
23396 if (!isDefaultmapKind || !isDefaultmapModifier) {
23397 StringRef KindValue =
"'scalar', 'aggregate', 'pointer'";
23399 StringRef ModifierValue =
"'alloc', 'from', 'to', 'tofrom', "
23400 "'firstprivate', 'none', 'default'";
23401 if (!isDefaultmapKind && isDefaultmapModifier) {
23402 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23403 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23404 }
else if (isDefaultmapKind && !isDefaultmapModifier) {
23405 Diag(MLoc, diag::err_omp_unexpected_clause_value)
23406 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23408 Diag(MLoc, diag::err_omp_unexpected_clause_value)
23409 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23410 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23411 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23414 StringRef ModifierValue =
23415 "'alloc', 'from', 'to', 'tofrom', "
23416 "'firstprivate', 'none', 'default', 'present'";
23417 if (!isDefaultmapKind && isDefaultmapModifier) {
23418 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23419 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23420 }
else if (isDefaultmapKind && !isDefaultmapModifier) {
23421 Diag(MLoc, diag::err_omp_unexpected_clause_value)
23422 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23424 Diag(MLoc, diag::err_omp_unexpected_clause_value)
23425 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23426 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23427 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23436 if (
DSAStack->checkDefaultmapCategory(Kind)) {
23437 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
23443 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
23444 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
23445 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
23447 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
23460 !isa<CXXRecordDecl>(CurLexicalContext) &&
23461 !isa<ClassTemplateDecl>(CurLexicalContext) &&
23462 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
23463 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
23464 Diag(DTCI.
Loc, diag::err_omp_region_not_file_context);
23470 Diag(DTCI.
Loc, diag::warn_hip_omp_target_directives);
23472 DeclareTargetNesting.push_back(DTCI);
23478 assert(!DeclareTargetNesting.empty() &&
23479 "check isInOpenMPDeclareTargetContext() first!");
23480 return DeclareTargetNesting.pop_back_val();
23490 if (DeclareTargetNesting.empty())
23493 Diag(DTCI.
Loc, diag::warn_omp_unterminated_declare_target)
23494 << getOpenMPDirectiveName(DTCI.
Kind);
23507 VarOrFuncDeclFilterCCC CCC(
SemaRef);
23518 Diag(
Id.getLoc(), diag::err_undeclared_var_use) <<
Id.getName();
23523 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
23524 !isa<FunctionTemplateDecl>(ND)) {
23525 Diag(
Id.getLoc(), diag::err_omp_invalid_target_decl) <<
Id.getName();
23534 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
23535 isa<FunctionTemplateDecl>(ND)) &&
23536 "Expected variable, function or function template.");
23538 if (
auto *VD = dyn_cast<VarDecl>(ND)) {
23540 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
23541 !VD->isStaticDataMember()) {
23542 Diag(Loc, diag::err_omp_declare_target_has_local_vars)
23551 Diag(Loc, diag::warn_omp_declare_target_after_first_use);
23555 Diag(Loc, diag::warn_hip_omp_target_directives);
23558 const unsigned Level = -1;
23560 auto *VD = cast<ValueDecl>(ND);
23561 std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
23562 OMPDeclareTargetDeclAttr::getActiveAttr(VD);
23563 if (ActiveAttr && (*ActiveAttr)->getDevType() != DTCI.
DT &&
23564 (*ActiveAttr)->getLevel() == Level) {
23565 Diag(Loc, diag::err_omp_device_type_mismatch)
23566 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.
DT)
23567 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(
23568 (*ActiveAttr)->getDevType());
23571 if (ActiveAttr && (*ActiveAttr)->getMapType() != MT &&
23572 (*ActiveAttr)->getLevel() == Level) {
23573 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
23577 if (ActiveAttr && (*ActiveAttr)->getLevel() == Level)
23580 Expr *IndirectE =
nullptr;
23581 bool IsIndirect =
false;
23587 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
23592 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
23594 if (
auto *VD = dyn_cast<VarDecl>(ND);
23596 VD->hasGlobalStorage())
23602 if (!D || !isa<VarDecl>(D))
23604 auto *VD = cast<VarDecl>(D);
23605 std::optional<OMPDeclareTargetDeclAttr::MapTypeTy>
MapTy =
23606 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
23607 if (SemaRef.
LangOpts.OpenMP >= 50 &&
23610 VD->hasGlobalStorage()) {
23611 if (!
MapTy || (*
MapTy != OMPDeclareTargetDeclAttr::MT_To &&
23612 *
MapTy != OMPDeclareTargetDeclAttr::MT_Enter)) {
23619 diag::err_omp_lambda_capture_in_declare_target_not_to);
23620 SemaRef.
Diag(SL, diag::note_var_explicitly_captured_here)
23627 SemaRef.
Diag(VD->
getLocation(), diag::warn_omp_not_in_target_context);
23628 SemaRef.
Diag(SL, diag::note_used_here) << SR;
23632 Sema &SemaRef, DSAStackTy *Stack,
23634 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
23645 if (
auto *VD = dyn_cast<VarDecl>(D)) {
23647 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
23648 !VD->isStaticDataMember())
23652 if (
DSAStack->isThreadPrivate(VD)) {
23653 Diag(SL, diag::err_omp_threadprivate_in_target);
23658 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
23659 D = FTD->getTemplatedDecl();
23660 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
23661 std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
23662 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
23663 if (IdLoc.
isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
23664 Diag(IdLoc, diag::err_omp_function_in_link_clause);
23669 if (
auto *VD = dyn_cast<ValueDecl>(D)) {
23677 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
23678 isa<FunctionTemplateDecl>(D)) {
23679 std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
23680 OMPDeclareTargetDeclAttr::getActiveAttr(VD);
23681 unsigned Level = DeclareTargetNesting.size();
23682 if (ActiveAttr && (*ActiveAttr)->getLevel() >= Level)
23685 Expr *IndirectE =
nullptr;
23686 bool IsIndirect =
false;
23692 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
23694 getLangOpts().OpenMP >= 52 ? OMPDeclareTargetDeclAttr::MT_Enter
23695 : OMPDeclareTargetDeclAttr::MT_To,
23696 DTCI.
DT, IndirectE, IsIndirect, Level,
23700 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
23721 if (
auto *VD = dyn_cast<VarDecl>(
Node->getDecl())) {
23723 DeclVector.push_back(VD);
23728 for (
auto *Child : Ex->
children()) {
23737 A = TD->
getAttr<OMPDeclareTargetDeclAttr>();
23738 DeclVector.push_back(cast<VarDecl>(TD));
23739 while (!DeclVector.empty()) {
23740 VarDecl *TargetVarDecl = DeclVector.pop_back_val();
23741 if (TargetVarDecl->
hasAttr<OMPDeclareTargetDeclAttr>() &&
23755 if (isa<VarDecl>(TargetDecl))
23770 unsigned Count = 0;
23771 for (
unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
23773 llvm::is_contained(Modifiers, MotionModifiers[I])) {
23774 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
23778 "Modifiers exceed the allowed number of motion modifiers");
23779 Modifiers[Count] = MotionModifiers[I];
23780 ModifiersLoc[Count] = MotionModifiersLoc[I];
23784 MappableVarListInfo MVLI(VarList);
23786 MapperIdScopeSpec, MapperId, UnresolvedMappers);
23787 if (MVLI.ProcessedVarList.empty())
23791 getASTContext(), Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
23792 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
23807 unsigned Count = 0;
23808 for (
unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
23810 llvm::is_contained(Modifiers, MotionModifiers[I])) {
23811 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
23815 "Modifiers exceed the allowed number of motion modifiers");
23816 Modifiers[Count] = MotionModifiers[I];
23817 ModifiersLoc[Count] = MotionModifiersLoc[I];
23821 MappableVarListInfo MVLI(VarList);
23823 MapperIdScopeSpec, MapperId, UnresolvedMappers);
23824 if (MVLI.ProcessedVarList.empty())
23828 getASTContext(), Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
23829 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
23836 MappableVarListInfo MVLI(VarList);
23840 for (
Expr *RefExpr : VarList) {
23841 assert(RefExpr &&
"NULL expr in OpenMP use_device_ptr clause.");
23844 Expr *SimpleRefExpr = RefExpr;
23848 MVLI.ProcessedVarList.push_back(RefExpr);
23849 PrivateCopies.push_back(
nullptr);
23850 Inits.push_back(
nullptr);
23857 Type =
Type.getNonReferenceType().getUnqualifiedType();
23859 auto *VD = dyn_cast<VarDecl>(D);
23863 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
23864 << 0 << RefExpr->getSourceRange();
23872 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
23873 if (VDPrivate->isInvalidDecl())
23878 SemaRef, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
23894 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
23895 PrivateCopies.push_back(VDPrivateRefExpr);
23896 Inits.push_back(VDInitRefExpr);
23901 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
23905 MVLI.VarBaseDeclarations.push_back(D);
23906 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23907 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
23911 if (MVLI.ProcessedVarList.empty())
23915 getASTContext(), Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
23916 MVLI.VarBaseDeclarations, MVLI.VarComponents);
23922 MappableVarListInfo MVLI(VarList);
23924 for (
Expr *RefExpr : VarList) {
23925 assert(RefExpr &&
"NULL expr in OpenMP use_device_addr clause.");
23928 Expr *SimpleRefExpr = RefExpr;
23933 MVLI.ProcessedVarList.push_back(RefExpr);
23938 auto *VD = dyn_cast<VarDecl>(D);
23945 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
23950 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
23954 MVLI.VarBaseDeclarations.push_back(D);
23955 MVLI.VarComponents.emplace_back();
23956 Expr *Component = SimpleRefExpr;
23957 if (VD && (isa<ArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
23958 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
23961 MVLI.VarComponents.back().emplace_back(Component, D,
23965 if (MVLI.ProcessedVarList.empty())
23969 getASTContext(), Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
23970 MVLI.VarComponents);
23976 MappableVarListInfo MVLI(VarList);
23977 for (
Expr *RefExpr : VarList) {
23978 assert(RefExpr &&
"NULL expr in OpenMP is_device_ptr clause.");
23981 Expr *SimpleRefExpr = RefExpr;
23985 MVLI.ProcessedVarList.push_back(RefExpr);
23995 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
23996 << 0 << RefExpr->getSourceRange();
24002 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
24004 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
24005 << getOpenMPClauseName(DVar.CKind)
24006 << getOpenMPClauseName(OMPC_is_device_ptr)
24007 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
24012 const Expr *ConflictExpr;
24013 if (
DSAStack->checkMappableExprComponentListsForDecl(
24018 ConflictExpr = R.front().getAssociatedExpression();
24021 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
24030 SimpleRefExpr, D,
false);
24031 DSAStack->addMappableExpressionComponents(
24032 D, MC, OMPC_is_device_ptr);
24035 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
24040 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
24041 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
24042 "Unexpected device pointer expression!");
24043 MVLI.VarBaseDeclarations.push_back(
24044 isa<DeclRefExpr>(SimpleRefExpr) ? D :
nullptr);
24045 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
24046 MVLI.VarComponents.back().push_back(MC);
24049 if (MVLI.ProcessedVarList.empty())
24053 getASTContext(), Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
24054 MVLI.VarComponents);
24060 MappableVarListInfo MVLI(VarList);
24061 for (
Expr *RefExpr : VarList) {
24062 assert(RefExpr &&
"NULL expr in OpenMP has_device_addr clause.");
24065 Expr *SimpleRefExpr = RefExpr;
24070 MVLI.ProcessedVarList.push_back(RefExpr);
24078 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
24080 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
24081 << getOpenMPClauseName(DVar.CKind)
24082 << getOpenMPClauseName(OMPC_has_device_addr)
24083 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
24088 const Expr *ConflictExpr;
24089 if (
DSAStack->checkMappableExprComponentListsForDecl(
24094 ConflictExpr = R.front().getAssociatedExpression();
24097 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
24105 Expr *Component = SimpleRefExpr;
24106 auto *VD = dyn_cast<VarDecl>(D);
24107 if (VD && (isa<ArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
24108 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
24112 Component, D,
false);
24113 DSAStack->addMappableExpressionComponents(
24114 D, MC, OMPC_has_device_addr);
24120 assert(Ref &&
"has_device_addr capture failed");
24121 MVLI.ProcessedVarList.push_back(Ref);
24123 MVLI.ProcessedVarList.push_back(RefExpr->IgnoreParens());
24128 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
24129 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
24130 "Unexpected device pointer expression!");
24131 MVLI.VarBaseDeclarations.push_back(
24132 isa<DeclRefExpr>(SimpleRefExpr) ? D :
nullptr);
24133 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
24134 MVLI.VarComponents.back().push_back(MC);
24137 if (MVLI.ProcessedVarList.empty())
24141 getASTContext(), Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
24142 MVLI.VarComponents);
24158 AllocatorRes.
get(),
DSAStack->getOMPAllocatorHandleT(),
24163 Allocator = AllocatorRes.
get();
24176 for (
Expr *RefExpr : VarList) {
24177 assert(RefExpr &&
"NULL expr in OpenMP private clause.");
24180 Expr *SimpleRefExpr = RefExpr;
24184 Vars.push_back(RefExpr);
24190 auto *VD = dyn_cast<VarDecl>(D);
24195 ? RefExpr->IgnoreParens()
24203 DSAStack->addInnerAllocatorExpr(Allocator);
24205 Allocator, ColonLoc, EndLoc, Vars);
24213 for (
Expr *RefExpr : VarList) {
24214 assert(RefExpr &&
"NULL expr in OpenMP nontemporal clause.");
24217 Expr *SimpleRefExpr = RefExpr;
24221 Vars.push_back(RefExpr);
24228 if (
const Expr *PrevRef =
24229 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
24230 Diag(ELoc, diag::err_omp_used_in_clause_twice)
24231 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
24232 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
24233 << getOpenMPClauseName(OMPC_nontemporal);
24237 Vars.push_back(RefExpr);
24265 for (
Expr *RefExpr : VarList) {
24266 assert(RefExpr &&
"NULL expr in OpenMP nontemporal clause.");
24269 Expr *SimpleRefExpr = RefExpr;
24274 Vars.push_back(RefExpr);
24279 const DSAStackTy::DSAVarData DVar =
24285 if (DVar.CKind != OMPC_reduction || DVar.Modifier != OMPC_REDUCTION_inscan)
24286 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
24287 << RefExpr->getSourceRange();
24289 if (
DSAStack->getParentDirective() != OMPD_unknown)
24290 DSAStack->markDeclAsUsedInScanDirective(D);
24291 Vars.push_back(RefExpr);
24306 for (
Expr *RefExpr : VarList) {
24307 assert(RefExpr &&
"NULL expr in OpenMP nontemporal clause.");
24310 Expr *SimpleRefExpr = RefExpr;
24315 Vars.push_back(RefExpr);
24321 DSAStackTy::DSAVarData DVar;
24322 if (ParentDirective != OMPD_unknown)
24323 DVar =
DSAStack->getTopDSA(D,
true);
24328 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
24329 DVar.Modifier != OMPC_REDUCTION_inscan) {
24330 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
24331 << RefExpr->getSourceRange();
24333 DSAStack->markDeclAsUsedInScanDirective(D);
24335 Vars.push_back(RefExpr);
24347 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
24348 if (!OMPAlloctraitT.
isNull())
24353 S.
Diag(Loc, diag::err_omp_implied_type_not_found) <<
"omp_alloctrait_t";
24356 Stack->setOMPAlloctraitT(PT.
get());
24376 for (
int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
24377 auto AllocatorKind =
static_cast<OMPAllocateDeclAttr::AllocatorTypeTy
>(I);
24378 StringRef Allocator =
24379 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
24387 Expr *AllocatorExpr =
nullptr;
24395 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
24396 bool IsPredefinedAllocator =
false;
24398 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorTy =
24400 IsPredefinedAllocator =
24402 OMPAllocateDeclAttr::AllocatorTypeTy::OMPUserDefinedMemAlloc;
24406 bool IsTypeCompatible = IsPredefinedAllocator;
24407 IsTypeCompatible = IsTypeCompatible ||
24409 OMPAllocatorHandleT);
24411 IsTypeCompatible ||
24413 bool IsNonConstantLValue =
24415 if (!DRE || !IsTypeCompatible ||
24416 (!IsPredefinedAllocator && !IsNonConstantLValue)) {
24418 <<
"omp_allocator_handle_t" << (DRE ? 1 : 0)
24427 diag::err_omp_predefined_allocator_with_traits)
24430 << cast<NamedDecl>(DRE->
getDecl())->getName()
24439 diag::err_omp_nonpredefined_allocator_without_traits);
24447 IsPredefinedAllocator
24448 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
24449 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
24451 Expr *AllocatorTraitsExpr =
nullptr;
24465 if (
const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
24466 TraitTy = ConstArrayTy->getElementType();
24473 diag::err_omp_expected_array_alloctraits)
24474 << AllocatorTraitsExpr->
getType();
24479 if (
auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
24482 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
24499 for (
Expr *RefExpr : Locators) {
24500 assert(RefExpr &&
"NULL expr in OpenMP shared clause.");
24501 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
24503 Vars.push_back(RefExpr);
24511 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
24512 << 1 << 0 << RefExpr->getSourceRange();
24521 if (!Res.
isUsable() && !isa<ArraySectionExpr>(SimpleExpr) &&
24522 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
24523 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
24524 << 1 << 0 << RefExpr->getSourceRange();
24527 Vars.push_back(SimpleExpr);
24531 ColonLoc, EndLoc, Modifier, Vars);
24540 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
24543 << getOpenMPClauseName(OMPC_bind);
24548 LParenLoc, EndLoc);
24555 Expr *ValExpr = Size;
24556 Stmt *HelperValStmt =
nullptr;
24567 DKind, OMPC_ompx_dyn_cgroup_mem,
getLangOpts().OpenMP);
24568 if (CaptureRegion != OMPD_unknown &&
24571 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
24572 ValExpr = tryBuildCapture(
SemaRef, ValExpr, Captures).get();
24577 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
24585 if (
DSAStack->getCurrentDirective() == OMPD_ordered &&
24586 DepType != OMPC_DOACROSS_source && DepType != OMPC_DOACROSS_sink &&
24587 DepType != OMPC_DOACROSS_sink_omp_cur_iteration &&
24588 DepType != OMPC_DOACROSS_source_omp_cur_iteration &&
24589 DepType != OMPC_DOACROSS_source) {
24590 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
24591 <<
"'source' or 'sink'" << getOpenMPClauseName(OMPC_doacross);
24597 llvm::APSInt TotalDepCount(32);
24600 DepType == OMPC_DOACROSS_source ||
24601 DepType == OMPC_DOACROSS_source_omp_cur_iteration ||
24602 DepType == OMPC_DOACROSS_sink_omp_cur_iteration,
24604 Vars = VarOffset.Vars;
24605 OpsOffs = VarOffset.OpsOffs;
24606 TotalDepCount = VarOffset.TotalDepCount;
24608 EndLoc, DepType, DepLoc, ColonLoc, Vars,
24609 TotalDepCount.getZExtValue());
24610 if (
DSAStack->isParentOrderedRegion())
24611 DSAStack->addDoacrossDependClause(
C, OpsOffs);
24633 if (
Base->hasPlaceholderType() &&
24634 !
Base->hasPlaceholderType(BuiltinType::ArraySection)) {
24647 LowerBound =
Result.get();
24649 if (Length && Length->getType()->isNonOverloadPlaceholderType()) {
24669 if (
Base->isTypeDependent() ||
24672 (Length && (Length->isTypeDependent() || Length->isValueDependent())) ||
24676 OK_Ordinary, ColonLocFirst, ColonLocSecond, RBLoc);
24688 Diag(
Base->getExprLoc(), diag::err_omp_typecheck_section_value)
24689 <<
Base->getSourceRange());
24695 if (Res.isInvalid())
24697 diag::err_omp_typecheck_section_not_integer)
24699 LowerBound = Res.get();
24709 if (Res.isInvalid())
24711 diag::err_omp_typecheck_section_not_integer)
24712 << 1 << Length->getSourceRange());
24713 Length = Res.get();
24715 if (Length->getType()->isSpecificBuiltinType(BuiltinType::Char_S) ||
24716 Length->getType()->isSpecificBuiltinType(BuiltinType::Char_U))
24717 Diag(Length->getExprLoc(), diag::warn_omp_section_is_char)
24718 << 1 << Length->getSourceRange();
24725 diag::err_omp_typecheck_section_not_integer)
24727 Stride = Res.
get();
24740 Diag(
Base->getExprLoc(), diag::err_omp_section_function_type)
24741 << ResultTy <<
Base->getSourceRange();
24746 diag::err_omp_section_incomplete_type,
Base))
24754 llvm::APSInt LowerBoundValue =
Result.Val.getInt();
24755 if (LowerBoundValue.isNegative()) {
24757 diag::err_omp_section_not_subset_of_array)
24766 if (Length->EvaluateAsInt(
Result, Context)) {
24769 llvm::APSInt LengthValue =
Result.Val.getInt();
24770 if (LengthValue.isNegative()) {
24771 Diag(Length->getExprLoc(), diag::err_omp_section_length_negative)
24772 <<
toString(LengthValue, 10,
true)
24773 << Length->getSourceRange();
24777 }
else if (ColonLocFirst.
isValid() &&
24783 Diag(ColonLocFirst, diag::err_omp_section_length_undefined)
24793 llvm::APSInt StrideValue =
Result.Val.getInt();
24794 if (!StrideValue.isStrictlyPositive()) {
24795 Diag(Stride->
getExprLoc(), diag::err_omp_section_stride_non_positive)
24796 <<
toString(StrideValue, 10,
true)
24803 if (!
Base->hasPlaceholderType(BuiltinType::ArraySection)) {
24811 OK_Ordinary, ColonLocFirst, ColonLocSecond, RBLoc);
24818 if (
Base->hasPlaceholderType()) {
24832 LParenLoc, RParenLoc, Dims, Brackets);
24834 (!
Base->isTypeDependent() &&
24837 diag::err_omp_non_pointer_type_array_shaping_base)
24838 <<
Base->getSourceRange());
24841 bool ErrorFound =
false;
24842 for (
Expr *Dim : Dims) {
24843 if (Dim->hasPlaceholderType()) {
24845 if (
Result.isInvalid()) {
24850 if (
Result.isInvalid()) {
24856 if (!Dim->isTypeDependent()) {
24859 if (
Result.isInvalid()) {
24861 Diag(Dim->getExprLoc(), diag::err_omp_typecheck_shaping_not_integer)
24862 << Dim->getSourceRange();
24867 if (!Dim->isValueDependent() && Dim->EvaluateAsInt(EvResult, Context)) {
24872 if (!
Value.isStrictlyPositive()) {
24873 Diag(Dim->getExprLoc(), diag::err_omp_shaping_dimension_not_positive)
24875 << Dim->getSourceRange();
24881 NewDims.push_back(Dim);
24886 LParenLoc, RParenLoc, NewDims, Brackets);
24896 bool IsCorrect =
true;
24901 if (!D.Type.getAsOpaquePtr()) {
24905 DeclTy = Context.
IntTy;
24906 StartLoc = D.DeclIdentLoc;
24912 bool IsDeclTyDependent = DeclTy->isDependentType() ||
24913 DeclTy->containsUnexpandedParameterPack() ||
24914 DeclTy->isInstantiationDependentType();
24915 if (!IsDeclTyDependent) {
24916 if (!DeclTy->isIntegralType(Context) && !DeclTy->isAnyPointerType()) {
24919 Diag(StartLoc, diag::err_omp_iterator_not_integral_or_pointer)
24924 if (DeclTy.isConstant(Context)) {
24927 Diag(StartLoc, diag::err_omp_iterator_not_integral_or_pointer)
24935 assert(D.DeclIdent &&
"Identifier expected.");
24940 D.DeclIdent, DeclTy, TInfo,
SC_None);
24946 RedeclarationKind::ForVisibleRedeclaration);
24968 if (!IsDeclTyDependent &&
Begin && !
Begin->isTypeDependent()) {
24973 Expr *End = D.Range.End;
24974 if (!IsDeclTyDependent && End && !End->isTypeDependent()) {
24977 End = EndRes.
get();
24979 Expr *Step = D.Range.Step;
24982 Diag(Step->
getExprLoc(), diag::err_omp_iterator_step_not_integral)
24987 std::optional<llvm::APSInt>
Result =
24993 Diag(Step->
getExprLoc(), diag::err_omp_iterator_step_constant_zero)
24999 if (!
Begin || !End || !IsCorrect) {
25015 if (
Decl *ID = D.IteratorDecl)
25016 ID->setInvalidDecl();
25028 D.Range.End, D.Range.Begin);
25034 if (D.Range.Step) {
25045 D.AssignmentLoc, BO_Sub, Res.
get(),
25062 D.AssignmentLoc, BO_Sub, D.Range.Begin, D.Range.End);
25076 D.AssignmentLoc, BO_Sub, Res1.
get(),
25091 D.AssignmentLoc, BO_GT, D.Range.Step,
25116 CounterVD->setImplicit();
25123 if (D.Range.Step) {
25125 D.AssignmentLoc, BO_Mul,
25135 D.Range.Begin, UpdateRes.
get());
25142 cast<VarDecl>(D.IteratorDecl)->getType(),
25145 VDRes.
get(), UpdateRes.
get());
25157 D.AssignmentLoc, UO_PreInc, RefRes.
get());
25158 if (!CounterUpdateRes.
isUsable()) {
25164 if (!CounterUpdateRes.
isUsable()) {
25175 Helpers.assign(ID.size(), {});
25180 if (
Decl *ID = D.IteratorDecl)
25181 ID->setInvalidDecl();
25186 LLoc, RLoc, ID, Helpers);
25190 :
SemaBase(S), VarDataSharingAttributesStack(nullptr) {}
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 checkOMPArraySectionConstantForReduction(ASTContext &Context, const ArraySectionExpr *OASE, bool &SingleElement, SmallVectorImpl< llvm::APSInt > &ArraySizes)
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 bool teamsLoopCanBeParallelFor(Stmt *AStmt, Sema &SemaRef)
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 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 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 bool checkOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, SemaOpenMP::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 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, SemaOpenMP::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)
This file declares semantic analysis for OpenMP constructs and clauses.
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 ...
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...
CanQualType OMPArrayShapingTy
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.
CanQualType OMPIteratorTy
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.
CanQualType ArraySectionTy
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...
This class represents BOTH the OpenMP Array Section and OpenACC 'subarray', with a boolean differenti...
Expr * getBase()
Get base of the array section.
Expr * getLength()
Get length of array section.
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
Expr * getLowerBound()
Get lower bound of array section.
SourceLocation getColonLocFirst() const
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.
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
SourceLocation getIdentifierLoc() const
void SetIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Set the name of this declarator to be the given identifier.
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...
bool isInvalidType() const
const IdentifierInfo * getIdentifier() 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.
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.
static OMPArrayShapingExpr * Create(const ASTContext &Context, QualType T, Expr *Op, SourceLocation L, SourceLocation R, ArrayRef< Expr * > Dims, ArrayRef< SourceRange > BracketRanges)
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
SourceLocation getBeginLoc() const
Returns starting location of directive kind.
static const SpecificClause * getSingleClause(ArrayRef< OMPClause * > Clauses)
Gets a single clause of the specified kind associated with the current directive iff there is only on...
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 OMPIteratorExpr * Create(const ASTContext &Context, QualType T, SourceLocation IteratorKwLoc, SourceLocation L, SourceLocation R, ArrayRef< IteratorDefinition > Data, ArrayRef< OMPIteratorHelperData > Helpers)
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, bool CanBeParallelFor)
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, const 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 generic diagnostic builder for errors which may or may not be deferred.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
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.
OMPClause * ActOnOpenMPNocontextClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'nocontext' clause.
OMPClause * ActOnOpenMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on a well-formed 'ompx_dyn_cgroup_mem' clause.
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd(Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid)
Called at the end of '#pragma omp declare reduction'.
bool isInOpenMPTaskUntiedContext() const
Return true if currently in OpenMP task with untied clause context.
OMPClause * ActOnOpenMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'untied' clause.
OMPClause * ActOnOpenMPSafelenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'safelen' 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...
OMPClause * ActOnOpenMPDefaultClause(llvm::omp::DefaultKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'default' clause.
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 ActOnOpenMPDispatchDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp dispatch' after parsing of the.
OMPClause * ActOnOpenMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'read' clause.
OMPClause * ActOnOpenMPFilterClause(Expr *ThreadID, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'filter' clause.
void ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner)
Finish current declare reduction construct initializer.
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...
OMPClause * ActOnOpenMPFullClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-form 'full' clauses.
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.
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.
OMPClause * ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'detach' clause.
OMPClause * ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Called on well-formed 'use' clause.
OMPClause * ActOnOpenMPFailClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'fail' clause.
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 ActOnFinishedOpenMPDeclareTargetContext(DeclareTargetContextInfo &DTCI)
Called once a target context is completed, that can be when a '#pragma omp end declare target' was en...
void tryCaptureOpenMPLambdas(ValueDecl *V)
Function tries to capture lambda's captured variables in the OpenMP region before the original lambda...
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.
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...
OMPClause * ActOnOpenMPPrivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'private' clause.
void StartOpenMPClause(OpenMPClauseKind K)
Start analysis of clauses.
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, SourceLocation LinLoc)
Checks correctness of linear modifiers.
ExprResult ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType, SourceLocation StartLoc, DeclarationName VN)
Build the mapper variable of '#pragma omp declare mapper'.
OMPClause * ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc, SourceLocation LParenLoc=SourceLocation(), Expr *NumForLoops=nullptr)
Called on well-formed 'ordered' clause.
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.
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.
OMPClause * ActOnOpenMPIsDevicePtrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'is_device_ptr' clause.
OMPClause * ActOnOpenMPHasDeviceAddrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'has_device_addr' clause.
StmtResult ActOnOpenMPErrorDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, bool InExContext=true)
Called on well-formed '#pragma omp error'.
OMPClause * ActOnOpenMPPartialClause(Expr *FactorExpr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-form 'partial' clauses.
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.
OMPClause * ActOnOpenMPLastprivateClause(ArrayRef< Expr * > VarList, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'lastprivate' clause.
void ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, DeclareTargetContextInfo &DTCI)
Called on correct id-expression from the '#pragma omp declare target'.
DeclGroupPtrTy ActOnOpenMPRequiresDirective(SourceLocation Loc, ArrayRef< OMPClause * > ClauseList)
Called on well-formed '#pragma omp requires'.
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 * ActOnOpenMPFirstprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'firstprivate' clause.
StmtResult ActOnOpenMPDepobjDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp depobj'.
ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, ExprObjectKind OK, SourceLocation Loc)
OMPClause * ActOnOpenMPPriorityClause(Expr *Priority, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'priority' clause.
OMPClause * ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, ArrayRef< unsigned > Arguments, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, ArrayRef< SourceLocation > ArgumentsLoc, SourceLocation DelimLoc, SourceLocation EndLoc)
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.
OMPClause * ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'dist_schedule' clause.
OpenMPClauseKind isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, unsigned CapLevel) const
Check if the specified variable is used in 'private' clause.
OMPClause * ActOnOpenMPAllocateClause(Expr *Allocator, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'allocate' clause.
OMPClause * ActOnOpenMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'nowait' clause.
OMPClause * ActOnOpenMPNontemporalClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'nontemporal' clause.
OMPClause * ActOnOpenMPBindClause(OpenMPBindClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on a well-formed 'bind' clause.
OMPClause * ActOnOpenMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'threads' clause.
OMPClause * ActOnOpenMPSharedClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'shared' clause.
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.
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 * ActOnOpenMPCopyinClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyin' clause.
OMPClause * ActOnOpenMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'mergeable' clause.
void startOpenMPCXXRangeFor()
If the current region is a range 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.
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...
OMPClause * ActOnOpenMPAffinityClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, Expr *Modifier, ArrayRef< Expr * > Locators)
Called on well-formed 'affinity' clause.
OMPClause * ActOnOpenMPCompareClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'compare' clause.
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.
OMPClause * ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'update' clause.
OMPClause * ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data, Expr *DepModifier, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'depend' clause.
OMPClause * ActOnOpenMPDoacrossClause(OpenMPDoacrossClauseModifier DepType, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'doacross' clause.
VarDecl * ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
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...
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'.
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,...
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.
ExprResult ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id, OpenMPDirectiveKind Kind)
Called on correct id-expression from the '#pragma omp threadprivate'.
void ActOnOpenMPEndAssumesDirective()
Called on well-formed '#pragma omp end assumes'.
OMPClause * ActOnOpenMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'nogroup' clause.
OMPClause * ActOnOpenMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier, Expr *Size, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc)
Called on well-formed 'grainsize' clause.
ExprResult ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, Expr *LowerBound, SourceLocation ColonLocFirst, SourceLocation ColonLocSecond, Expr *Length, Expr *Stride, SourceLocation RBLoc)
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.
bool isOpenMPRebuildMemberExpr(ValueDecl *D)
The member expression(this->fd) needs to be rebuilt in the template instantiation to generate private...
QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, TypeResult ParsedType)
Check if the specified type is allowed to be used in 'omp declare reduction' construct.
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.
bool isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, unsigned OpenMPCaptureLevel) const
Return true if the provided declaration VD should be captured by reference.
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.
DeclGroupPtrTy ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef< Expr * > VarList, ArrayRef< OMPClause * > Clauses, DeclContext *Owner=nullptr)
Called on well-formed '#pragma omp allocate'.
OMPClause * ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
OMPClause * ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'unified_address' clause.
static int getOpenMPCaptureLevels(OpenMPDirectiveKind Kind)
Return the number of captured regions created for an OpenMP directive.
bool isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, unsigned CaptureLevel) const
Check if the specified variable is captured by 'target' directive.
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...
OMPClause * ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'dynamic_allocators' clause.
StmtResult ActOnOpenMPScopeDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp scope' after parsing of the associated statement.
void ActOnOpenMPIteratorVarDecl(VarDecl *VD)
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.
bool isInOpenMPDeclareVariantScope() const
Can we exit an OpenMP declare variant scope at the moment.
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...
StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp barrier'.
TypeResult ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D)
Check variable declaration in 'omp declare mapper' construct.
ExprResult ActOnOMPIteratorExpr(Scope *S, SourceLocation IteratorKwLoc, SourceLocation LLoc, SourceLocation RLoc, ArrayRef< OMPIteratorData > Data)
OMPClause * ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< UsesAllocatorsData > Data)
Called on well-formed 'uses_allocators' clause.
StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef< OMPClause * > Clauses)
End of OpenMP region.
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'.
OMPClause * ActOnOpenMPAcqRelClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'acq_rel' clause.
OMPClause * ActOnOpenMPAllocatorClause(Expr *Allocator, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'allocator' clause.
ExprResult VerifyPositiveIntegerConstantInClause(Expr *Op, OpenMPClauseKind CKind, bool StrictlyPositive=true, bool SuppressExprDiags=false)
bool isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const
OMPClause * ActOnOpenMPInclusiveClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'inclusive' 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...
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...
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 ActOnOpenMPEndDeclareVariant()
Handle a omp end declare variant.
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 ActOnOpenMPMaskedDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp masked' after parsing of the.
void ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D)
Act on D, a function definition inside of an omp [begin/end] assumes.
void EndOpenMPDSABlock(Stmt *CurDirective)
Called on end of data sharing attribute block.
OMPClause * ActOnOpenMPOrderClause(OpenMPOrderClauseModifier Modifier, OpenMPOrderClauseKind Kind, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc)
Called on well-formed 'order' clause.
OMPClause * ActOnOpenMPSizesClause(ArrayRef< Expr * > SizeExprs, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-form 'sizes' clause.
bool ActOnStartOpenMPDeclareTargetContext(DeclareTargetContextInfo &DTCI)
Called on the start of target region i.e. '#pragma omp declare target'.
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...
OMPClause * ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, Expr *Device, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc)
Called on well-formed 'device' clause.
OMPClause * ActOnOpenMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_threads' clause.
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.
StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp section' after parsing of the associated statement.
bool isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, unsigned CaptureLevel) const
Check if the specified global variable must be captured by outer capture regions.
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.
StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind PrevMappedDirective=llvm::omp::OMPD_unknown)
OMPClause * ActOnOpenMPFlushClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'flush' pseudo clause.
OMPRequiresDecl * CheckOMPRequiresDecl(SourceLocation Loc, ArrayRef< OMPClause * > Clauses)
Check restrictions on Requires directive.
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...
void EndOpenMPClause()
End analysis of clauses.
bool isInOpenMPAssumeScope() const
Check if there is an active global omp begin assumes directive.
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...
OMPClause * ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_teams' clause.
QualType ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, TypeResult ParsedType)
Check if the specified type is allowed to be used in 'omp declare mapper' construct.
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.
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.
OMPClause * ActOnOpenMPMessageClause(Expr *MS, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'message' 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 * 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.
StmtResult ActOnOpenMPScanDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp scan'.
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.
void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init)
Check if the current region is an OpenMP loop region and if it is, mark loop control variable,...
OMPClause * ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'unified_address' clause.
void DiagnoseUnterminatedOpenMPDeclareTarget()
Report unterminated 'omp declare target' or 'omp begin declare target' at the end of a compilation un...
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...
OMPClause * ActOnOpenMPSimdlenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'simdlen' clause.
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...
OMPClause * ActOnOpenMPUseDevicePtrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'use_device_ptr' 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.
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
OMPClause * ActOnOpenMPReleaseClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'release' clause.
OMPClause * ActOnOpenMPAcquireClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'acquire' clause.
OMPClause * ActOnOpenMPProcBindClause(llvm::omp::ProcBindKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'proc_bind' clause.
OMPClause * ActOnOpenMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'simd' clause.
OMPClause * ActOnOpenMPXBareClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on a well-formed 'ompx_bare' clause.
StmtResult ActOnOpenMPCanonicalLoop(Stmt *AStmt)
Called for syntactical loops (ForStmt or CXXForRangeStmt) associated to an OpenMP loop directive.
OMPClause * ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'hint' clause.
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
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...
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.
OMPClause * ActOnOpenMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'capture' clause.
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.
StmtResult ActOnOpenMPAtomicDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp atomic' after parsing of the associated statement.
StmtResult ActOnOpenMPTargetUpdateDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed '#pragma omp target update'.
StmtResult ActOnOpenMPOrderedDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp ordered' after parsing of the associated statement.
ExprResult ActOnOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc, SourceLocation RParenLoc, ArrayRef< Expr * > Dims, ArrayRef< SourceRange > Brackets)
OMPClause * ActOnOpenMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'at' clause.
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 * ActOnOpenMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Called on well-formed 'init' clause.
OMPClause * ActOnOpenMPUseDeviceAddrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'use_device_addr' clause.
void ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
std::pair< StringRef, QualType > CapturedParamNameType
OMPClause * ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'final' clause.
bool isInOpenMPTargetExecutionDirective() const
Return true inside OpenMP target region.
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.
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.
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...
StmtResult ActOnOpenMPFlushDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp flush'.
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.
OMPClause * ActOnOpenMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier, Expr *NumTasks, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc)
Called on well-formed 'num_tasks' clause.
void ActOnOpenMPDeclareTargetInitializer(Decl *D)
Adds OMPDeclareTargetDeclAttr to referenced variables in declare target directive.
bool isInOpenMPDeclareTargetContext() const
Return true inside OpenMP declare target region.
StmtResult ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancellation point'.
OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr * > Vars, const OMPVarListLocTy &Locs, OpenMPVarListDataTy &Data)
void startOpenMPLoop()
If the current region is a loop-based region, mark the start of the loop construct.
StmtResult ActOnOpenMPTargetDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target' 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.
OMPThreadPrivateDecl * CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef< Expr * > VarList)
Builds a new OpenMPThreadPrivateDecl and checks its correctness.
OMPClause * ActOnOpenMPSeverityClause(OpenMPSeverityClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'severity' clause.
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.
void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, VarDecl *OmpPrivParm)
Finish current declare reduction construct initializer.
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 * ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc)
Called on well-formed 'defaultmap' clause.
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 ActOnOpenMPTaskwaitDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskwait'.
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.
OMPClause * ActOnOpenMPRelaxedClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'relaxed' clause.
OMPClause * ActOnOpenMPAlignedClause(ArrayRef< Expr * > VarList, Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'aligned' clause.
StmtResult ActOnOpenMPInteropDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp interop'.
OMPClause * ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'depobj' pseudo clause.
OMPClause * ActOnOpenMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'seq_cst' clause.
void checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, SourceLocation IdLoc=SourceLocation())
Check declaration inside target region.
OMPClause * ActOnOpenMPNovariantsClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'novariants' clause.
OMPClause * ActOnOpenMPCopyprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyprivate' clause.
OMPClause * ActOnOpenMPCollapseClause(Expr *NumForLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'collapse' clause.
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.
ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op)
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.
OMPClause * ActOnOpenMPAlignClause(Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'align' clause.
OMPClause * ActOnOpenMPAtomicDefaultMemOrderClause(OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'atomic_default_mem_order' clause.
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 * ActOnOpenMPWeakClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'weak' clause.
OMPClause * ActOnOpenMPXAttributeClause(ArrayRef< const Attr * > Attrs, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on a well-formed 'ompx_attribute' clause.
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.
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.
StmtResult ActOnOpenMPParallelDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel' after parsing of the associated statement.
StmtResult ActOnOpenMPSingleDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp single' after parsing of the associated statement.
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.
const ValueDecl * getOpenMPDeclareMapperVarName() const
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...
DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(SourceLocation Loc, ArrayRef< Expr * > VarList)
Called on well-formed '#pragma omp threadprivate'.
void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope)
Initialization of captured region for OpenMP region.
NamedDecl * lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id)
Searches for the provided declaration name for OpenMP declare target directive.
OMPClause * ActOnOpenMPExclusiveClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'exclusive' clause.
OMPClause * ActOnOpenMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'write' clause.
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.
void ActOnOpenMPAssumesDirective(SourceLocation Loc, OpenMPDirectiveKind DKind, ArrayRef< std::string > Assumptions, bool SkippedClauses)
Called on well-formed '#pragma omp [begin] assume[s]'.
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...
void ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, OMPTraitInfo &TI)
Handle a omp begin declare variant.
StmtResult ActOnOpenMPLoopnest(Stmt *AStmt)
Process a canonical OpenMP loop nest that can either be a canonical literal loop (ForStmt or CXXForRa...
OMPClause * ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'reverse_offload' clause.
OMPClause * ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'thread_limit' clause.
StmtResult ActOnOpenMPTaskDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp task' after parsing of the associated statement.
OMPClause * ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'if' clause.
llvm::SmallDenseMap< const ValueDecl *, const Expr *, 4 > VarsWithInheritedDSAType
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...
const DeclareTargetContextInfo ActOnOpenMPEndDeclareTargetDirective()
Called at the end of target region i.e. '#pragma omp end declare target'.
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 * ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc)
StmtResult ActOnOpenMPCancelDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancel'.
StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskyield'.
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.
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'.
A RAII object to enter scope of a compound statement.
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.
ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo)
Package the given type and TSI into a ParsedType.
QualType getCurrentThisType()
Try to retrieve the type of the 'this' pointer.
Scope * getCurScope() const
Retrieve the parser's current scope.
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,...
@ 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.
ImplicitConversionSequence TryImplicitConversion(Expr *From, QualType ToType, bool SuppressUserConversions, AllowedExplicit AllowExplicit, bool InOverloadResolution, bool CStyle, bool AllowObjCWritebackConversion)
FunctionEmissionStatus
Status of the function emission on the CUDA/HIP/OpenMP host/device attrs.
void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl=nullptr, ExpressionEvaluationContextRecord::ExpressionKind Type=ExpressionEvaluationContextRecord::EK_Other)
ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E, bool IsConstexpr=false)
CheckBooleanCondition - Diagnose problems involving the use of the given expression as a boolean cond...
SmallVector< sema::FunctionScopeInfo *, 4 > FunctionScopes
Stack containing information about each of the nested function, block, and method scopes that are cur...
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.
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...
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 ...
FPOptionsOverride CurFPFeatureOverrides()
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 ...
NamedDecl * LookupSingleName(Scope *S, DeclarationName Name, SourceLocation Loc, LookupNameKind NameKind, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)
Look up a name, looking for a single declaration.
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.
void ActOnCapturedRegionError()
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
ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input, bool IsAfterAmp=false)
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.
void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var)
Mark a variable referenced, and check whether it is odr-used (C++ [basic.def.odr]p2,...
void PopExpressionEvaluationContext()
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
DeclRefExpr * BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)
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...
void PushFunctionScope()
Enter a new function scope.
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...
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.
void CheckExtraCXXDefaultArguments(Declarator &D)
CheckExtraCXXDefaultArguments - Check for any extra default arguments in the declarator,...
const LangOptions & LangOpts
sema::LambdaScopeInfo * getCurLambda(bool IgnoreNonLambdaCapturingScope=false)
Retrieve the current lambda scope info, if any.
DeclContext * getCurLexicalContext() const
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...
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, CapturedRegionKind Kind, unsigned NumParams)
sema::FunctionScopeInfo * getCurFunction() const
Expr * BuildCXXThisExpr(SourceLocation Loc, QualType Type, bool IsImplicit)
Build a CXXThisExpr and mark it referenced in the current context.
ExprResult DefaultLvalueConversion(Expr *E)
bool isVisible(const NamedDecl *D)
Determine whether a declaration is visible to name lookup.
FunctionEmissionStatus getEmissionStatus(const FunctionDecl *Decl, bool Final=false)
sema::BlockScopeInfo * getCurBlock()
Retrieve the current block, if any.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
StmtResult ActOnCapturedRegionEnd(Stmt *S)
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
bool inTemplateInstantiation() const
Determine whether we are currently performing template instantiation.
@ TryCapture_ExplicitByVal
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.
ExprResult ActOnConditionalOp(SourceLocation QuestionLoc, SourceLocation ColonLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr)
ActOnConditionalOp - Parse a ?: operation.
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, const ImplicitConversionSequence &ICS, AssignmentAction Action, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType ...
bool isCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind=CompleteTypeKind::Default)
void setFunctionHasBranchProtectedScope()
RedeclarationKind forRedeclarationInCurContext() const
std::pair< StringRef, QualType > CapturedParamNameType
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.
ExprResult CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, Expr *Idx, SourceLocation RLoc)
@ 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),...
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)
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.
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
void DiscardCleanupsInEvaluationContext()
void PushDeclContext(Scope *S, DeclContext *DC)
Set the current declaration context until it gets popped.
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)
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.
void ActOnUninitializedDecl(Decl *dcl)
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
SemaDiagnosticBuilder targetDiag(SourceLocation Loc, unsigned DiagID, const FunctionDecl *FD=nullptr)
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
CreateBuiltinBinOp - Creates a new built-in binary operation with operator Opc at location TokLoc.
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
sema::CapturedRegionScopeInfo * getCurCapturedRegion()
Retrieve the current captured region, if any.
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)
StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, ArrayRef< Stmt * > Elts, bool isStmtExpr)
FullExprArg MakeFullExpr(Expr *Arg)
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
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.
SourceLocation getBeginLoc() const
Get the begin source location.
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
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 isConstantArrayType() const
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
bool isVariableArrayType() const
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
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 isNonOverloadPlaceholderType() const
Test for a placeholder type other than Overload; see BuiltinType::isNonOverloadPlaceholderType.
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, UnresolvedSetIterator Begin, UnresolvedSetIterator End, bool KnownDependent)
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.
@ Private
'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...
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...
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
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
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.
for(const auto &A :T->param_types())
const FunctionProtoType * T
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
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.
@ Implicit
An implicit conversion.
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
Iterator definition representation.
SourceLocation AssignmentLoc
SourceLocation SecondColonLoc
Helper expressions and declaration for OMPIteratorExpr class for each iteration space.
Expr * CounterUpdate
Updater for the internal counter: ++CounterVD;.
Expr * Upper
Normalized upper bound.
Expr * Update
Update expression for the originally specified iteration variable, calculated as VD = Begin + Counter...
VarDecl * CounterVD
Internal normalized counter.
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.
OpenMPDirectiveKind Kind
The directive kind, begin declare target or declare target.
OMPDeclareTargetDeclAttr::DevTypeTy DT
The 'device_type' as parsed from the clause.
SourceLocation Loc
The directive location.
llvm::DenseMap< NamedDecl *, MapInfo > ExplicitlyMapped
Explicitly listed variables and functions in a 'to' or 'link' clause.
Data structure for iterator expression.
Data used for processing a list of variables in OpenMP clauses.
Data for list of allocators.
Expr * AllocatorTraits
Allocator traits.
SourceLocation LParenLoc
Locations of '(' and ')' symbols.
Expr * Allocator
Allocator.
Clang specific specialization of the OMPContext to lookup target features.