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())
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())
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)
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);
3073 VarDeclFilterCCC CCC(
SemaRef);
3080 : diag::err_omp_expected_var_arg_suggest)
3082 VD = Corrected.getCorrectionDeclAs<
VarDecl>();
3084 Diag(
Id.getLoc(), Lookup.
empty() ? diag::err_undeclared_var_use
3085 : diag::err_omp_expected_var_arg)
3090 Diag(
Id.getLoc(), diag::err_omp_expected_var_arg) <<
Id.getName();
3099 Diag(
Id.getLoc(), diag::err_omp_global_var_arg)
3104 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3116 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3117 << getOpenMPDirectiveName(Kind) << VD;
3121 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3131 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3132 << getOpenMPDirectiveName(Kind) << VD;
3136 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3148 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3149 << getOpenMPDirectiveName(Kind) << VD;
3153 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3162 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3163 << getOpenMPDirectiveName(Kind) << VD;
3167 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3175 if (Kind == OMPD_threadprivate && VD->
isUsed() &&
3177 Diag(
Id.getLoc(), diag::err_omp_var_used)
3178 << getOpenMPDirectiveName(Kind) << VD;
3200class LocalVarRefChecker final
3206 if (
const auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
3209 diag::err_omp_local_var_in_threadprivate_init)
3211 SemaRef.Diag(VD->
getLocation(), diag::note_defined_here)
3218 bool VisitStmt(
const Stmt *S) {
3219 for (
const Stmt *Child : S->children()) {
3220 if (Child && Visit(Child))
3225 explicit LocalVarRefChecker(
Sema &SemaRef) : SemaRef(SemaRef) {}
3234 for (
Expr *RefExpr : VarList) {
3235 auto *DE = cast<DeclRefExpr>(RefExpr);
3236 auto *VD = cast<VarDecl>(DE->getDecl());
3253 ILoc, VD->
getType(), diag::err_omp_threadprivate_incomplete_type)) {
3260 Diag(ILoc, diag::err_omp_ref_type_arg)
3261 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->
getType();
3265 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3273 !(VD->
hasAttr<OMPThreadPrivateDeclAttr>() &&
3278 Diag(ILoc, diag::err_omp_var_thread_local)
3283 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3291 LocalVarRefChecker Checker(
SemaRef);
3292 if (Checker.Visit(
Init))
3296 Vars.push_back(RefExpr);
3297 DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3298 VD->
addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3301 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3304 if (!Vars.empty()) {
3312static OMPAllocateDeclAttr::AllocatorTypeTy
3315 return OMPAllocateDeclAttr::OMPNullMemAlloc;
3316 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3317 Allocator->isInstantiationDependent() ||
3318 Allocator->containsUnexpandedParameterPack())
3319 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3320 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3321 llvm::FoldingSetNodeID AEId;
3322 const Expr *AE = Allocator->IgnoreParenImpCasts();
3324 for (
int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3325 auto AllocatorKind =
static_cast<OMPAllocateDeclAttr::AllocatorTypeTy
>(I);
3326 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3327 llvm::FoldingSetNodeID DAEId;
3330 if (AEId == DAEId) {
3331 AllocatorKindRes = AllocatorKind;
3335 return AllocatorKindRes;
3340 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
Expr *Allocator) {
3341 if (!VD->
hasAttr<OMPAllocateDeclAttr>())
3343 const auto *A = VD->
getAttr<OMPAllocateDeclAttr>();
3344 Expr *PrevAllocator = A->getAllocator();
3345 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3347 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3348 if (AllocatorsMatch &&
3349 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3350 Allocator && PrevAllocator) {
3351 const Expr *AE = Allocator->IgnoreParenImpCasts();
3353 llvm::FoldingSetNodeID AEId, PAEId;
3356 AllocatorsMatch = AEId == PAEId;
3358 if (!AllocatorsMatch) {
3360 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3364 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3366 PrevAllocator->printPretty(PrevAllocatorStream,
nullptr,
3370 Allocator ? Allocator->getExprLoc() : RefExpr->
getExprLoc();
3372 Allocator ? Allocator->getSourceRange() : RefExpr->
getSourceRange();
3374 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3376 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3377 S.
Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3378 << (Allocator ? 1 : 0) << AllocatorStream.str()
3379 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3381 S.
Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3382 << PrevAllocatorRange;
3390 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3392 if (VD->
hasAttr<OMPAllocateDeclAttr>())
3401 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3402 Allocator->isInstantiationDependent() ||
3403 Allocator->containsUnexpandedParameterPack()))
3405 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.
Context, AllocatorKind,
3406 Allocator, Alignment, SR);
3409 ML->DeclarationMarkedOpenMPAllocate(VD, A);
3415 assert(Clauses.size() <= 2 &&
"Expected at most two clauses.");
3416 Expr *Alignment =
nullptr;
3417 Expr *Allocator =
nullptr;
3418 if (Clauses.empty()) {
3428 if (
const auto *AC = dyn_cast<OMPAllocatorClause>(
C))
3429 Allocator = AC->getAllocator();
3430 else if (
const auto *AC = dyn_cast<OMPAlignClause>(
C))
3431 Alignment = AC->getAlignment();
3433 llvm_unreachable(
"Unexpected clause on allocate directive");
3435 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3438 for (
Expr *RefExpr : VarList) {
3439 auto *DE = cast<DeclRefExpr>(RefExpr);
3440 auto *VD = cast<VarDecl>(DE->getDecl());
3444 VD->
hasAttr<OMPThreadPrivateDeclAttr>() ||
3452 AllocatorKind, Allocator))
3460 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3461 Diag(Allocator->getExprLoc(),
3462 diag::err_omp_expected_predefined_allocator)
3463 << Allocator->getSourceRange();
3467 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3473 Vars.push_back(RefExpr);
3492 Diag(
Loc, diag::err_omp_invalid_scope) <<
"requires";
3506 bool SkippedClauses) {
3507 if (!SkippedClauses && Assumptions.empty())
3508 Diag(
Loc, diag::err_omp_no_clause_for_directive)
3509 << llvm::omp::getAllAssumeClauseOptions()
3510 << llvm::omp::getOpenMPDirectiveName(DKind);
3514 if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3515 OMPAssumeScoped.push_back(AA);
3520 if (Assumptions.empty())
3523 assert(DKind == llvm::omp::Directive::OMPD_assumes &&
3524 "Unexpected omp assumption directive!");
3525 OMPAssumeGlobal.push_back(AA);
3533 while (Ctx->getLexicalParent())
3535 DeclContexts.push_back(Ctx);
3536 while (!DeclContexts.empty()) {
3538 for (
auto *SubDC : DC->
decls()) {
3539 if (SubDC->isInvalidDecl())
3541 if (
auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3542 DeclContexts.push_back(CTD->getTemplatedDecl());
3543 llvm::append_range(DeclContexts, CTD->specializations());
3546 if (
auto *DC = dyn_cast<DeclContext>(SubDC))
3547 DeclContexts.push_back(DC);
3548 if (
auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3558 OMPAssumeScoped.pop_back();
3568 DSAStack->getEncounteredTargetLocs();
3570 if (!TargetLocations.empty() || !AtomicLoc.
isInvalid()) {
3571 for (
const OMPClause *CNew : ClauseList) {
3573 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3574 isa<OMPUnifiedAddressClause>(CNew) ||
3575 isa<OMPReverseOffloadClause>(CNew) ||
3576 isa<OMPDynamicAllocatorsClause>(CNew)) {
3577 Diag(
Loc, diag::err_omp_directive_before_requires)
3578 <<
"target" << getOpenMPClauseName(CNew->getClauseKind());
3580 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3584 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3585 Diag(
Loc, diag::err_omp_directive_before_requires)
3586 <<
"atomic" << getOpenMPClauseName(CNew->getClauseKind());
3587 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3593 if (!
DSAStack->hasDuplicateRequiresClause(ClauseList))
3601 const DSAStackTy::DSAVarData &DVar,
3602 bool IsLoopIterVar) {
3604 SemaRef.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3605 << getOpenMPClauseName(DVar.CKind);
3609 PDSA_StaticMemberShared,
3610 PDSA_StaticLocalVarShared,
3611 PDSA_LoopIterVarPrivate,
3612 PDSA_LoopIterVarLinear,
3613 PDSA_LoopIterVarLastprivate,
3614 PDSA_ConstVarShared,
3615 PDSA_GlobalVarShared,
3616 PDSA_TaskVarFirstprivate,
3617 PDSA_LocalVarPrivate,
3619 } Reason = PDSA_Implicit;
3620 bool ReportHint =
false;
3622 auto *VD = dyn_cast<VarDecl>(D);
3623 if (IsLoopIterVar) {
3624 if (DVar.CKind == OMPC_private)
3625 Reason = PDSA_LoopIterVarPrivate;
3626 else if (DVar.CKind == OMPC_lastprivate)
3627 Reason = PDSA_LoopIterVarLastprivate;
3629 Reason = PDSA_LoopIterVarLinear;
3631 DVar.CKind == OMPC_firstprivate) {
3632 Reason = PDSA_TaskVarFirstprivate;
3633 ReportLoc = DVar.ImplicitDSALoc;
3635 Reason = PDSA_StaticLocalVarShared;
3637 Reason = PDSA_StaticMemberShared;
3639 Reason = PDSA_GlobalVarShared;
3641 Reason = PDSA_ConstVarShared;
3642 else if (VD && VD->
isLocalVarDecl() && DVar.CKind == OMPC_private) {
3644 Reason = PDSA_LocalVarPrivate;
3646 if (Reason != PDSA_Implicit) {
3647 SemaRef.
Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3648 << Reason << ReportHint
3649 << getOpenMPDirectiveName(Stack->getCurrentDirective());
3650 }
else if (DVar.ImplicitDSALoc.isValid()) {
3651 SemaRef.
Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3652 << getOpenMPClauseName(DVar.CKind);
3658 bool IsAggregateOrDeclareTarget) {
3661 case OMPC_DEFAULTMAP_MODIFIER_alloc:
3662 Kind = OMPC_MAP_alloc;
3664 case OMPC_DEFAULTMAP_MODIFIER_to:
3667 case OMPC_DEFAULTMAP_MODIFIER_from:
3668 Kind = OMPC_MAP_from;
3670 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3671 Kind = OMPC_MAP_tofrom;
3673 case OMPC_DEFAULTMAP_MODIFIER_present:
3679 Kind = OMPC_MAP_alloc;
3681 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3683 llvm_unreachable(
"Unexpected defaultmap implicit behavior");
3684 case OMPC_DEFAULTMAP_MODIFIER_none:
3685 case OMPC_DEFAULTMAP_MODIFIER_default:
3690 if (IsAggregateOrDeclareTarget) {
3691 Kind = OMPC_MAP_tofrom;
3694 llvm_unreachable(
"Unexpected defaultmap implicit behavior");
3701class DSAAttrChecker final :
public StmtVisitor<DSAAttrChecker, void> {
3704 bool ErrorFound =
false;
3705 bool TryCaptureCXXThisMembers =
false;
3712 ImplicitMapModifier[DefaultmapKindNum];
3714 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3718 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3720 if (S->getDirectiveKind() == OMPD_atomic ||
3721 S->getDirectiveKind() == OMPD_critical ||
3722 S->getDirectiveKind() == OMPD_section ||
3723 S->getDirectiveKind() == OMPD_master ||
3724 S->getDirectiveKind() == OMPD_masked ||
3725 S->getDirectiveKind() == OMPD_scope ||
3727 Visit(S->getAssociatedStmt());
3730 visitSubCaptures(S->getInnermostCapturedStmt());
3733 if (TryCaptureCXXThisMembers ||
3735 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3737 return C.capturesThis();
3739 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3740 TryCaptureCXXThisMembers =
true;
3741 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3742 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3749 if (
auto *FC = dyn_cast<OMPFirstprivateClause>(
C)) {
3750 for (
Expr *Ref : FC->varlists())
3763 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
3766 !Stack->getTopDSA(VD,
false).RefExpr &&
3767 !Stack->isImplicitDefaultFirstprivateFD(VD))) {
3768 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3769 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3770 Visit(CED->getInit());
3773 }
else if (VD->
isImplicit() || isa<OMPCapturedExprDecl>(VD))
3776 if (!Stack->isImplicitDefaultFirstprivateFD(VD))
3781 !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3782 !Stack->isImplicitTaskFirstprivate(VD))
3785 if (Stack->isUsesAllocatorsDecl(VD))
3788 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD,
false);
3790 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3794 std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3795 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3798 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3799 !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3800 !Stack->isImplicitTaskFirstprivate(VD))
3809 if (DVar.CKind == OMPC_unknown &&
3810 (Stack->getDefaultDSA() == DSA_none ||
3811 Stack->getDefaultDSA() == DSA_private ||
3812 Stack->getDefaultDSA() == DSA_firstprivate) &&
3813 isImplicitOrExplicitTaskingRegion(DKind) &&
3814 VarsWithInheritedDSA.count(VD) == 0) {
3815 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3816 if (!InheritedDSA && (Stack->getDefaultDSA() == DSA_firstprivate ||
3817 Stack->getDefaultDSA() == DSA_private)) {
3818 DSAStackTy::DSAVarData DVar =
3819 Stack->getImplicitDSA(VD,
false);
3820 InheritedDSA = DVar.CKind == OMPC_unknown;
3823 VarsWithInheritedDSA[VD] = E;
3824 if (Stack->getDefaultDSA() == DSA_none)
3839 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3840 OMPC_DEFAULTMAP_MODIFIER_none;
3841 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3842 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3846 if (!Stack->checkMappableExprComponentListsForDecl(
3851 auto MI = MapExprComponents.rbegin();
3852 auto ME = MapExprComponents.rend();
3853 return MI != ME && MI->getAssociatedDeclaration() == VD;
3855 VarsWithInheritedDSA[VD] = E;
3861 bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3862 OMPC_DEFAULTMAP_MODIFIER_present;
3863 if (IsModifierPresent) {
3864 if (!llvm::is_contained(ImplicitMapModifier[ClauseKind],
3865 OMPC_MAP_MODIFIER_present)) {
3866 ImplicitMapModifier[ClauseKind].push_back(
3867 OMPC_MAP_MODIFIER_present);
3873 !Stack->isLoopControlVariable(VD).first) {
3874 if (!Stack->checkMappableExprComponentListsForDecl(
3879 if (SemaRef.LangOpts.OpenMP >= 50)
3880 return !StackComponents.empty();
3883 return StackComponents.size() == 1 ||
3885 llvm::drop_begin(llvm::reverse(StackComponents)),
3886 [](const OMPClauseMappableExprCommon::
3887 MappableComponent &MC) {
3888 return MC.getAssociatedDeclaration() ==
3890 (isa<ArraySectionExpr>(
3891 MC.getAssociatedExpression()) ||
3892 isa<OMPArrayShapingExpr>(
3893 MC.getAssociatedExpression()) ||
3894 isa<ArraySubscriptExpr>(
3895 MC.getAssociatedExpression()));
3898 bool IsFirstprivate =
false;
3900 if (
const auto *RD =
3902 IsFirstprivate = RD->isLambda();
3904 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3905 if (IsFirstprivate) {
3906 ImplicitFirstprivate.emplace_back(E);
3909 Stack->getDefaultmapModifier(ClauseKind);
3911 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3912 ImplicitMap[ClauseKind][
Kind].emplace_back(E);
3922 DVar = Stack->hasInnermostDSA(
3925 return C == OMPC_reduction && !AppliedToPointee;
3934 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
3940 DVar = Stack->getImplicitDSA(VD,
false);
3942 (((Stack->getDefaultDSA() == DSA_firstprivate &&
3943 DVar.CKind == OMPC_firstprivate) ||
3944 (Stack->getDefaultDSA() == DSA_private &&
3945 DVar.CKind == OMPC_private)) &&
3947 !Stack->isLoopControlVariable(VD).first) {
3948 if (Stack->getDefaultDSA() == DSA_private)
3949 ImplicitPrivate.push_back(E);
3951 ImplicitFirstprivate.push_back(E);
3958 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3959 Stack->addToParentTargetRegionLinkGlobals(E);
3973 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD,
false);
3976 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3980 !Stack->isLoopControlVariable(FD).first &&
3981 !Stack->checkMappableExprComponentListsForDecl(
3986 return isa<CXXThisExpr>(
3988 StackComponents.back().getAssociatedExpression())
4000 if (Stack->isClassPreviouslyMapped(TE->getType()))
4004 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
4009 ImplicitMap[ClauseKind][
Kind].emplace_back(E);
4018 DVar = Stack->hasInnermostDSA(
4021 return C == OMPC_reduction && !AppliedToPointee;
4030 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
4036 DVar = Stack->getImplicitDSA(FD,
false);
4038 !Stack->isLoopControlVariable(FD).first) {
4043 if (DVar.CKind != OMPC_unknown)
4044 ImplicitFirstprivate.push_back(E);
4051 Stack->getCurrentDirective(),
4054 const auto *VD = cast<ValueDecl>(
4055 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
4056 if (!Stack->checkMappableExprComponentListsForDecl(
4062 auto CCI = CurComponents.rbegin();
4063 auto CCE = CurComponents.rend();
4064 for (const auto &SC : llvm::reverse(StackComponents)) {
4066 if (CCI->getAssociatedExpression()->getStmtClass() !=
4067 SC.getAssociatedExpression()->getStmtClass())
4068 if (!((isa<ArraySectionExpr>(
4069 SC.getAssociatedExpression()) ||
4070 isa<OMPArrayShapingExpr>(
4071 SC.getAssociatedExpression())) &&
4072 isa<ArraySubscriptExpr>(
4073 CCI->getAssociatedExpression())))
4076 const Decl *CCD = CCI->getAssociatedDeclaration();
4077 const Decl *SCD = SC.getAssociatedDeclaration();
4078 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
4079 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
4082 std::advance(CCI, 1);
4090 }
else if (!TryCaptureCXXThisMembers) {
4098 if (isa_and_nonnull<OMPPrivateClause>(
C))
4104 if (
C && !((isa<OMPFirstprivateClause>(
C) || isa<OMPMapClause>(
C)) &&
4107 for (
Stmt *CC :
C->children()) {
4114 VisitSubCaptures(S);
4123 for (
Stmt *
C : S->arguments()) {
4130 if (
Expr *Callee = S->getCallee()) {
4131 auto *CI =
Callee->IgnoreParenImpCasts();
4132 if (
auto *CE = dyn_cast<MemberExpr>(CI))
4133 Visit(CE->getBase());
4134 else if (
auto *CE = dyn_cast<DeclRefExpr>(CI))
4138 void VisitStmt(
Stmt *S) {
4139 for (
Stmt *
C : S->children()) {
4150 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
4152 VarDecl *VD = Cap.getCapturedVar();
4156 Stack->checkMappableExprComponentListsForDecl(
4163 Cap.getLocation(),
true);
4167 bool isErrorFound()
const {
return ErrorFound; }
4169 return ImplicitFirstprivate;
4174 return ImplicitMap[DK][MK];
4178 return ImplicitMapModifier[
Kind];
4181 return VarsWithInheritedDSA;
4185 : Stack(S), SemaRef(SemaRef), ErrorFound(
false), CS(CS) {
4200 Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target);
4202 Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams);
4204 Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel);
4206 Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for);
4208 Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd);
4209 Stack->handleConstructTrait(Traits, ScopeEntry);
4217 case OMPD_parallel_for:
4218 case OMPD_parallel_for_simd:
4219 case OMPD_parallel_sections:
4220 case OMPD_parallel_master:
4221 case OMPD_parallel_masked:
4222 case OMPD_parallel_loop:
4224 case OMPD_teams_distribute:
4225 case OMPD_teams_distribute_simd: {
4230 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4231 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4232 std::make_pair(StringRef(),
QualType())
4238 case OMPD_target_teams:
4239 case OMPD_target_parallel:
4240 case OMPD_target_parallel_for:
4241 case OMPD_target_parallel_for_simd:
4242 case OMPD_target_parallel_loop:
4243 case OMPD_target_teams_distribute:
4244 case OMPD_target_teams_distribute_simd: {
4254 std::make_pair(
".global_tid.", KmpInt32Ty),
4255 std::make_pair(
".part_id.", KmpInt32PtrTy),
4256 std::make_pair(
".privates.", VoidPtrTy),
4261 std::make_pair(StringRef(),
QualType())
4269 AlwaysInlineAttr::CreateImplicit(
4270 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4273 ParamsTarget.push_back(std::make_pair(StringRef(
"dyn_ptr"), VoidPtrTy));
4274 ParamsTarget.push_back(
4275 std::make_pair(StringRef(),
QualType()));
4281 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4282 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4283 std::make_pair(StringRef(),
QualType())
4293 case OMPD_target_simd: {
4303 std::make_pair(
".global_tid.", KmpInt32Ty),
4304 std::make_pair(
".part_id.", KmpInt32PtrTy),
4305 std::make_pair(
".privates.", VoidPtrTy),
4310 std::make_pair(StringRef(),
QualType())
4318 AlwaysInlineAttr::CreateImplicit(
4319 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4322 ParamsTarget.push_back(std::make_pair(StringRef(
"dyn_ptr"), VoidPtrTy));
4323 ParamsTarget.push_back(
4324 std::make_pair(StringRef(),
QualType()));
4346 case OMPD_taskgroup:
4347 case OMPD_distribute:
4348 case OMPD_distribute_simd:
4351 case OMPD_target_data:
4352 case OMPD_dispatch: {
4354 std::make_pair(StringRef(),
QualType())
4370 std::make_pair(
".global_tid.", KmpInt32Ty),
4371 std::make_pair(
".part_id.", KmpInt32PtrTy),
4372 std::make_pair(
".privates.", VoidPtrTy),
4377 std::make_pair(StringRef(),
QualType())
4384 AlwaysInlineAttr::CreateImplicit(
4385 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4389 case OMPD_taskloop_simd:
4390 case OMPD_master_taskloop:
4391 case OMPD_masked_taskloop:
4392 case OMPD_masked_taskloop_simd:
4393 case OMPD_master_taskloop_simd: {
4411 std::make_pair(
".global_tid.", KmpInt32Ty),
4412 std::make_pair(
".part_id.", KmpInt32PtrTy),
4413 std::make_pair(
".privates.", VoidPtrTy),
4418 std::make_pair(
".lb.", KmpUInt64Ty),
4419 std::make_pair(
".ub.", KmpUInt64Ty),
4420 std::make_pair(
".st.", KmpInt64Ty),
4421 std::make_pair(
".liter.", KmpInt32Ty),
4422 std::make_pair(
".reductions.", VoidPtrTy),
4423 std::make_pair(StringRef(),
QualType())
4430 AlwaysInlineAttr::CreateImplicit(
4431 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4434 case OMPD_parallel_masked_taskloop:
4435 case OMPD_parallel_masked_taskloop_simd:
4436 case OMPD_parallel_master_taskloop:
4437 case OMPD_parallel_master_taskloop_simd: {
4451 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4452 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4453 std::make_pair(StringRef(),
QualType())
4464 std::make_pair(
".global_tid.", KmpInt32Ty),
4465 std::make_pair(
".part_id.", KmpInt32PtrTy),
4466 std::make_pair(
".privates.", VoidPtrTy),
4471 std::make_pair(
".lb.", KmpUInt64Ty),
4472 std::make_pair(
".ub.", KmpUInt64Ty),
4473 std::make_pair(
".st.", KmpInt64Ty),
4474 std::make_pair(
".liter.", KmpInt32Ty),
4475 std::make_pair(
".reductions.", VoidPtrTy),
4476 std::make_pair(StringRef(),
QualType())
4484 AlwaysInlineAttr::CreateImplicit(
4485 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4488 case OMPD_distribute_parallel_for_simd:
4489 case OMPD_distribute_parallel_for: {
4494 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4495 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4498 std::make_pair(StringRef(),
QualType())
4506 case OMPD_target_teams_loop:
4507 case OMPD_target_teams_distribute_parallel_for:
4508 case OMPD_target_teams_distribute_parallel_for_simd: {
4519 std::make_pair(
".global_tid.", KmpInt32Ty),
4520 std::make_pair(
".part_id.", KmpInt32PtrTy),
4521 std::make_pair(
".privates.", VoidPtrTy),
4526 std::make_pair(StringRef(),
QualType())
4534 AlwaysInlineAttr::CreateImplicit(
4535 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4538 ParamsTarget.push_back(std::make_pair(StringRef(
"dyn_ptr"), VoidPtrTy));
4539 ParamsTarget.push_back(
4540 std::make_pair(StringRef(),
QualType()));
4547 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4548 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4549 std::make_pair(StringRef(),
QualType())
4557 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4558 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4561 std::make_pair(StringRef(),
QualType())
4571 case OMPD_teams_loop:
4572 case OMPD_teams_distribute_parallel_for:
4573 case OMPD_teams_distribute_parallel_for_simd: {
4579 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4580 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4581 std::make_pair(StringRef(),
QualType())
4589 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4590 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4593 std::make_pair(StringRef(),
QualType())
4602 case OMPD_target_update:
4603 case OMPD_target_enter_data:
4604 case OMPD_target_exit_data: {
4614 std::make_pair(
".global_tid.", KmpInt32Ty),
4615 std::make_pair(
".part_id.", KmpInt32PtrTy),
4616 std::make_pair(
".privates.", VoidPtrTy),
4621 std::make_pair(StringRef(),
QualType())
4628 AlwaysInlineAttr::CreateImplicit(
4629 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4632 case OMPD_threadprivate:
4634 case OMPD_taskyield:
4638 case OMPD_cancellation_point:
4643 case OMPD_declare_reduction:
4644 case OMPD_declare_mapper:
4645 case OMPD_declare_simd:
4646 case OMPD_declare_target:
4647 case OMPD_end_declare_target:
4649 case OMPD_declare_variant:
4650 case OMPD_begin_declare_variant:
4651 case OMPD_end_declare_variant:
4652 case OMPD_metadirective:
4653 llvm_unreachable(
"OpenMP Directive is not allowed");
4656 llvm_unreachable(
"Unknown OpenMP directive");
4662int SemaOpenMP::getNumberOfConstructScopes(
unsigned Level)
const {
4669 return CaptureRegions.size();
4673 Expr *CaptureExpr,
bool WithInit,
4675 bool AsExpression) {
4676 assert(CaptureExpr);
4682 Ty =
C.getLValueReferenceType(Ty);
4684 Ty =
C.getPointerType(Ty);
4696 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(
C));
4707 CD = cast<OMPCapturedExprDecl>(VD);
4746class CaptureRegionUnwinderRAII {
4753 CaptureRegionUnwinderRAII(
Sema &S,
bool &ErrorFound,
4755 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4756 ~CaptureRegionUnwinderRAII() {
4759 while (--ThisCaptureLevel >= 0)
4772 DSAStack->getCurrentDirective()))) {
4774 if (
const auto *RD =
Type.getCanonicalType()
4775 .getNonReferenceType()
4777 bool SavedForceCaptureByReferenceInTargetExecutable =
4778 DSAStack->isForceCaptureByReferenceInTargetExecutable();
4779 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4781 if (RD->isLambda()) {
4782 llvm::DenseMap<const ValueDecl *, FieldDecl *> Captures;
4784 RD->getCaptureFields(Captures, ThisCapture);
4787 VarDecl *VD = cast<VarDecl>(LC.getCapturedVar());
4792 }
else if (LC.getCaptureKind() ==
LCK_This) {
4795 ThisTy, ThisCapture->
getType()))
4800 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4801 SavedForceCaptureByReferenceInTargetExecutable);
4811 for (
const OMPClause *Clause : Clauses) {
4813 Ordered = cast<OMPOrderedClause>(Clause);
4815 Order = cast<OMPOrderClause>(Clause);
4816 if (Order->
getKind() != OMPC_ORDER_concurrent)
4819 if (Ordered && Order)
4823 if (Ordered && Order) {
4825 diag::err_omp_simple_clause_incompatible_with_ordered)
4826 << getOpenMPClauseName(OMPC_order)
4840 if (
DSAStack->getCurrentDirective() == OMPD_atomic ||
4841 DSAStack->getCurrentDirective() == OMPD_critical ||
4842 DSAStack->getCurrentDirective() == OMPD_section ||
4843 DSAStack->getCurrentDirective() == OMPD_master ||
4844 DSAStack->getCurrentDirective() == OMPD_masked)
4847 bool ErrorFound =
false;
4848 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4850 if (!S.isUsable()) {
4865 DSAStack->getCurrentDirective() == OMPD_target) &&
4869 auto *IRC = cast<OMPInReductionClause>(Clause);
4870 for (
Expr *E : IRC->taskgroup_descriptors())
4882 if (
auto *E = cast_or_null<Expr>(VarRef)) {
4886 DSAStack->setForceVarCapturing(
false);
4888 DSAStack->getCurrentDirective())) {
4889 assert(CaptureRegions.empty() &&
4890 "No captured regions in loop transformation directives.");
4891 }
else if (CaptureRegions.size() > 1 ||
4892 CaptureRegions.back() != OMPD_unknown) {
4896 if (
Expr *E =
C->getPostUpdateExpr())
4901 SC = cast<OMPScheduleClause>(Clause);
4903 OC = cast<OMPOrderedClause>(Clause);
4905 LCs.push_back(cast<OMPLinearClause>(Clause));
4916 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4921 diag::err_omp_simple_clause_incompatible_with_ordered)
4922 << getOpenMPClauseName(OMPC_schedule)
4924 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4935 Diag(
C->getBeginLoc(), diag::err_omp_linear_ordered)
4944 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
4951 unsigned CompletedRegions = 0;
4956 if (ThisCaptureRegion != OMPD_unknown) {
4964 if (CaptureRegion == ThisCaptureRegion ||
4965 CaptureRegion == OMPD_unknown) {
4966 if (
auto *DS = cast_or_null<DeclStmt>(
C->getPreInitStmt())) {
4967 for (
Decl *D : DS->decls())
4974 if (ThisCaptureRegion == OMPD_target) {
4978 if (
const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(
C)) {
4979 for (
unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4989 if (ThisCaptureRegion == OMPD_parallel) {
4993 if (
auto *RC = dyn_cast<OMPReductionClause>(
C)) {
4994 if (RC->getModifier() != OMPC_REDUCTION_inscan)
4996 for (
Expr *E : RC->copy_array_temps())
5000 if (
auto *AC = dyn_cast<OMPAlignedClause>(
C)) {
5001 for (
Expr *E : AC->varlists())
5006 if (++CompletedRegions == CaptureRegions.size())
5017 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
5020 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
5021 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
5024 SemaRef.
Diag(StartLoc, diag::err_omp_wrong_cancel_region)
5025 << getOpenMPDirectiveName(CancelRegion);
5035 if (Stack->getCurScope()) {
5038 bool NestingProhibited =
false;
5039 bool CloseNesting =
true;
5040 bool OrphanSeen =
false;
5043 ShouldBeInParallelRegion,
5044 ShouldBeInOrderedRegion,
5045 ShouldBeInTargetRegion,
5046 ShouldBeInTeamsRegion,
5047 ShouldBeInLoopSimdRegion,
5048 } Recommend = NoRecommend;
5049 if (SemaRef.
LangOpts.OpenMP >= 51 && Stack->isParentOrderConcurrent() &&
5050 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_loop &&
5051 CurrentRegion != OMPD_parallel &&
5053 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_order)
5054 << getOpenMPDirectiveName(CurrentRegion);
5058 ((SemaRef.
LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
5059 (SemaRef.
LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
5060 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
5061 CurrentRegion != OMPD_scan))) {
5074 SemaRef.
Diag(StartLoc, (CurrentRegion != OMPD_simd)
5075 ? diag::err_omp_prohibited_region_simd
5076 : diag::warn_omp_nesting_simd)
5077 << (SemaRef.
LangOpts.OpenMP >= 50 ? 1 : 0);
5078 return CurrentRegion != OMPD_simd;
5080 if (ParentRegion == OMPD_atomic) {
5083 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
5086 if (CurrentRegion == OMPD_section) {
5091 if (ParentRegion != OMPD_sections &&
5092 ParentRegion != OMPD_parallel_sections) {
5093 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_section_directive)
5094 << (ParentRegion != OMPD_unknown)
5095 << getOpenMPDirectiveName(ParentRegion);
5103 if (ParentRegion == OMPD_unknown &&
5105 CurrentRegion != OMPD_cancellation_point &&
5106 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
5110 if (SemaRef.
LangOpts.OpenMP >= 50 && CurrentRegion == OMPD_loop &&
5111 (BindKind == OMPC_BIND_parallel || BindKind == OMPC_BIND_teams) &&
5113 ParentRegion == OMPD_loop)) {
5114 int ErrorMsgNumber = (BindKind == OMPC_BIND_parallel) ? 1 : 4;
5115 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region)
5116 <<
true << getOpenMPDirectiveName(ParentRegion) << ErrorMsgNumber
5117 << getOpenMPDirectiveName(CurrentRegion);
5120 if (CurrentRegion == OMPD_cancellation_point ||
5121 CurrentRegion == OMPD_cancel) {
5134 !((CancelRegion == OMPD_parallel &&
5135 (ParentRegion == OMPD_parallel ||
5136 ParentRegion == OMPD_target_parallel)) ||
5137 (CancelRegion == OMPD_for &&
5138 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
5139 ParentRegion == OMPD_target_parallel_for ||
5140 ParentRegion == OMPD_distribute_parallel_for ||
5141 ParentRegion == OMPD_teams_distribute_parallel_for ||
5142 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
5143 (CancelRegion == OMPD_taskgroup &&
5144 (ParentRegion == OMPD_task ||
5146 (ParentRegion == OMPD_taskloop ||
5147 ParentRegion == OMPD_master_taskloop ||
5148 ParentRegion == OMPD_masked_taskloop ||
5149 ParentRegion == OMPD_parallel_masked_taskloop ||
5150 ParentRegion == OMPD_parallel_master_taskloop)))) ||
5151 (CancelRegion == OMPD_sections &&
5152 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
5153 ParentRegion == OMPD_parallel_sections)));
5154 OrphanSeen = ParentRegion == OMPD_unknown;
5155 }
else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
5162 }
else if (CurrentRegion == OMPD_critical && CurrentName.
getName()) {
5168 bool DeadLock = Stack->hasDirective(
5172 if (K == OMPD_critical && DNI.
getName() == CurrentName.
getName()) {
5173 PreviousCriticalLoc = Loc;
5180 SemaRef.
Diag(StartLoc,
5181 diag::err_omp_prohibited_region_critical_same_name)
5183 if (PreviousCriticalLoc.
isValid())
5184 SemaRef.
Diag(PreviousCriticalLoc,
5185 diag::note_omp_previous_critical_region);
5188 }
else if (CurrentRegion == OMPD_barrier || CurrentRegion == OMPD_scope) {
5199 ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5200 ParentRegion == OMPD_parallel_master ||
5201 ParentRegion == OMPD_parallel_masked ||
5202 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5214 ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5215 ParentRegion == OMPD_parallel_master ||
5216 ParentRegion == OMPD_parallel_masked ||
5217 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5218 Recommend = ShouldBeInParallelRegion;
5219 }
else if (CurrentRegion == OMPD_ordered) {
5228 NestingProhibited = ParentRegion == OMPD_critical ||
5231 Stack->isParentOrderedRegion());
5232 Recommend = ShouldBeInOrderedRegion;
5238 (SemaRef.
LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
5239 (SemaRef.
LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
5240 ParentRegion != OMPD_target);
5241 OrphanSeen = ParentRegion == OMPD_unknown;
5242 Recommend = ShouldBeInTargetRegion;
5243 }
else if (CurrentRegion == OMPD_scan) {
5249 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
5250 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
5251 ParentRegion != OMPD_parallel_for_simd);
5252 OrphanSeen = ParentRegion == OMPD_unknown;
5253 Recommend = ShouldBeInLoopSimdRegion;
5255 if (!NestingProhibited &&
5258 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
5270 CurrentRegion != OMPD_loop &&
5272 CurrentRegion == OMPD_atomic);
5273 Recommend = ShouldBeInParallelRegion;
5275 if (!NestingProhibited && CurrentRegion == OMPD_loop) {
5280 NestingProhibited = BindKind == OMPC_BIND_teams &&
5281 ParentRegion != OMPD_teams &&
5282 ParentRegion != OMPD_target_teams;
5283 Recommend = ShouldBeInTeamsRegion;
5285 if (!NestingProhibited &&
5291 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
5292 Recommend = ShouldBeInTeamsRegion;
5294 if (!NestingProhibited &&
5301 NestingProhibited = Stack->hasDirective(
5305 OffendingRegion = K;
5311 CloseNesting =
false;
5313 if (NestingProhibited) {
5315 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_device_directive)
5316 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
5318 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region)
5319 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
5320 << Recommend << getOpenMPDirectiveName(CurrentRegion);
5335 bool ErrorFound =
false;
5336 unsigned NamedModifiersNumber = 0;
5337 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
5338 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
5341 if (
const auto *IC = dyn_cast_or_null<OMPIfClause>(
C)) {
5345 if (FoundNameModifiers[CurNM]) {
5346 S.
Diag(
C->getBeginLoc(), diag::err_omp_more_one_clause)
5347 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
5348 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
5350 }
else if (CurNM != OMPD_unknown) {
5351 NameModifierLoc.push_back(IC->getNameModifierLoc());
5352 ++NamedModifiersNumber;
5354 FoundNameModifiers[CurNM] = IC;
5355 if (CurNM == OMPD_unknown)
5361 if (!llvm::is_contained(AllowedNameModifiers, CurNM)) {
5362 S.
Diag(IC->getNameModifierLoc(),
5363 diag::err_omp_wrong_if_directive_name_modifier)
5364 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
5371 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
5372 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
5373 S.
Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
5374 diag::err_omp_no_more_if_clause);
5377 std::string Sep(
", ");
5378 unsigned AllowedCnt = 0;
5379 unsigned TotalAllowedNum =
5380 AllowedNameModifiers.size() - NamedModifiersNumber;
5381 for (
unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
5384 if (!FoundNameModifiers[NM]) {
5386 Values += getOpenMPDirectiveName(NM);
5388 if (AllowedCnt + 2 == TotalAllowedNum)
5390 else if (AllowedCnt + 1 != TotalAllowedNum)
5395 S.
Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
5396 diag::err_omp_unnamed_if_clause)
5397 << (TotalAllowedNum > 1) << Values;
5400 S.
Diag(
Loc, diag::note_omp_previous_named_if_clause);
5410 bool AllowArraySection,
5411 StringRef DiagType) {
5414 return std::make_pair(
nullptr,
true);
5426 } IsArrayExpr = NoArrayExpr;
5427 if (AllowArraySection) {
5428 if (
auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
5429 Expr *
Base = ASE->getBase()->IgnoreParenImpCasts();
5430 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base))
5431 Base = TempASE->getBase()->IgnoreParenImpCasts();
5433 IsArrayExpr = ArraySubscript;
5434 }
else if (
auto *OASE = dyn_cast_or_null<ArraySectionExpr>(RefExpr)) {
5435 Expr *
Base = OASE->getBase()->IgnoreParenImpCasts();
5436 while (
auto *TempOASE = dyn_cast<ArraySectionExpr>(
Base))
5437 Base = TempOASE->getBase()->IgnoreParenImpCasts();
5438 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base))
5439 Base = TempASE->getBase()->IgnoreParenImpCasts();
5441 IsArrayExpr = OMPArraySection;
5447 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5448 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
5449 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
5451 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
5452 !isa<FieldDecl>(ME->getMemberDecl()))) {
5453 if (IsArrayExpr != NoArrayExpr) {
5454 S.
Diag(ELoc, diag::err_omp_expected_base_var_name)
5455 << IsArrayExpr << ERange;
5456 }
else if (!DiagType.empty()) {
5460 S.
Diag(ELoc, diag::err_omp_expected_var_name_member_expr_with_type)
5461 << DiagSelect << DiagType << ERange;
5465 ? diag::err_omp_expected_var_name_member_expr_or_array_item
5466 : diag::err_omp_expected_var_name_member_expr)
5469 return std::make_pair(
nullptr,
false);
5471 return std::make_pair(
5478class AllocatorChecker final :
public ConstStmtVisitor<AllocatorChecker, bool> {
5479 DSAStackTy *S =
nullptr;
5483 return S->isUsesAllocatorsDecl(E->
getDecl())
5484 .value_or(DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5485 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5487 bool VisitStmt(
const Stmt *S) {
5488 for (
const Stmt *Child : S->children()) {
5489 if (Child && Visit(Child))
5494 explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5501 "Expected non-dependent context.");
5502 auto AllocateRange =
5505 auto PrivateRange = llvm::make_filter_range(Clauses, [](
const OMPClause *
C) {
5510 if (
Cl->getClauseKind() == OMPC_private) {
5511 auto *PC = cast<OMPPrivateClause>(
Cl);
5512 I = PC->private_copies().begin();
5513 It = PC->varlist_begin();
5514 Et = PC->varlist_end();
5515 }
else if (
Cl->getClauseKind() == OMPC_firstprivate) {
5516 auto *PC = cast<OMPFirstprivateClause>(
Cl);
5517 I = PC->private_copies().begin();
5518 It = PC->varlist_begin();
5519 Et = PC->varlist_end();
5520 }
else if (
Cl->getClauseKind() == OMPC_lastprivate) {
5521 auto *PC = cast<OMPLastprivateClause>(
Cl);
5522 I = PC->private_copies().begin();
5523 It = PC->varlist_begin();
5524 Et = PC->varlist_end();
5525 }
else if (
Cl->getClauseKind() == OMPC_linear) {
5526 auto *PC = cast<OMPLinearClause>(
Cl);
5527 I = PC->privates().begin();
5528 It = PC->varlist_begin();
5529 Et = PC->varlist_end();
5530 }
else if (
Cl->getClauseKind() == OMPC_reduction) {
5531 auto *PC = cast<OMPReductionClause>(
Cl);
5532 I = PC->privates().begin();
5533 It = PC->varlist_begin();
5534 Et = PC->varlist_end();
5535 }
else if (
Cl->getClauseKind() == OMPC_task_reduction) {
5536 auto *PC = cast<OMPTaskReductionClause>(
Cl);
5537 I = PC->privates().begin();
5538 It = PC->varlist_begin();
5539 Et = PC->varlist_end();
5540 }
else if (
Cl->getClauseKind() == OMPC_in_reduction) {
5541 auto *PC = cast<OMPInReductionClause>(
Cl);
5542 I = PC->privates().begin();
5543 It = PC->varlist_begin();
5544 Et = PC->varlist_end();
5546 llvm_unreachable(
"Expected private clause.");
5548 for (
Expr *E : llvm::make_range(It, Et)) {
5555 Expr *SimpleRefExpr = E;
5558 DeclToCopy.try_emplace(Res.first,
5559 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5564 auto *AC = cast<OMPAllocateClause>(
C);
5568 AC->getAllocator()) {
5569 Expr *Allocator = AC->getAllocator();
5575 AllocatorChecker Checker(Stack);
5576 if (Checker.Visit(Allocator))
5577 S.
Diag(Allocator->getExprLoc(),
5578 diag::err_omp_allocator_not_in_uses_allocators)
5579 << Allocator->getSourceRange();
5581 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5587 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5590 S.
Diag(AC->getAllocator()->getExprLoc(),
5591 diag::warn_omp_allocate_thread_on_task_target_directive)
5592 << getOpenMPDirectiveName(Stack->getCurrentDirective());
5594 for (
Expr *E : AC->varlists()) {
5597 Expr *SimpleRefExpr = E;
5600 DSAStackTy::DSAVarData
Data = Stack->getTopDSA(VD,
false);
5603 diag::err_omp_expected_private_copy_for_allocate);
5606 VarDecl *PrivateVD = DeclToCopy[VD];
5608 AllocatorKind, AC->getAllocator()))
5611 Expr *Alignment =
nullptr;
5628 CaptureVars(
Sema &Actions) : BaseTransform(Actions) {}
5630 bool AlwaysRebuild() {
return true; }
5643 BodyStmts.push_back(NewDeclStmt);
5681 DistParam, LogicalTy,
VK_LValue, {},
nullptr,
nullptr, {},
nullptr);
5692 auto BuildVarRef = [&](
VarDecl *VD) {
5697 Ctx, llvm::APInt(Ctx.
getIntWidth(LogicalTy), 0), LogicalTy, {});
5699 Ctx, llvm::APInt(Ctx.
getIntWidth(LogicalTy), 1), LogicalTy, {});
5705 Actions.
BuildBinOp(
nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero));
5709 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5713 nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep)));
5717 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5721 Actions.
BuildUnaryOp(
nullptr, {}, UO_Minus, BuildVarRef(NewStep)));
5723 Actions.
BuildBinOp(
nullptr, {}, BO_Div, BackwardRange, NegIncAmount));
5727 {}, {}, IsNegStep, BackwardDist, ForwardDist));
5729 assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) &&
5730 "Expected one of these relational operators");
5737 nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5741 if (Rel == BO_GE || Rel == BO_GT)
5743 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5746 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5752 if (Rel == BO_LE || Rel == BO_GE) {
5764 Expr *Divisor = BuildVarRef(NewStep);
5765 if (Rel == BO_GE || Rel == BO_GT)
5768 Expr *DivisorMinusOne =
5773 Actions.
BuildBinOp(
nullptr, {}, BO_Div, RangeRoundUp, Divisor));
5783 Actions.
getCurScope(), {}, BO_Assign, DistRef, Dist));
5784 BodyStmts.push_back(ResultAssign);
5789 return cast<CapturedStmt>(
5816 {
"Logical", LogicalTy},
5827 assert(!
Invalid &&
"Expecting capture-by-value to work.");
5832 auto *CS = cast<CapturedDecl>(Actions.
CurContext);
5836 TargetParam, LoopVarTy,
VK_LValue, {},
nullptr,
nullptr, {},
nullptr);
5839 IndvarParam, LogicalTy,
VK_LValue, {},
nullptr,
nullptr, {},
nullptr);
5842 CaptureVars Recap(Actions);
5847 Actions.
BuildBinOp(
nullptr, {}, BO_Mul, NewStep, LogicalRef));
5862 BO_Assign, TargetRef, Advanced));
5864 return cast<CapturedStmt>(
5875 if (
auto *For = dyn_cast<ForStmt>(AStmt)) {
5877 if (
auto *LCVarDeclStmt = dyn_cast<DeclStmt>(
Init)) {
5879 LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl());
5880 }
else if (
auto *LCAssign = dyn_cast<BinaryOperator>(
Init)) {
5882 assert(LCAssign->getOpcode() == BO_Assign &&
5883 "init part must be a loop variable assignment");
5884 auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS());
5885 LIVDecl = cast<VarDecl>(CounterRef->getDecl());
5887 llvm_unreachable(
"Cannot determine loop variable");
5890 Cond = For->getCond();
5891 Inc = For->getInc();
5892 }
else if (
auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) {
5893 DeclStmt *BeginStmt = RangeFor->getBeginStmt();
5895 LUVDecl = RangeFor->getLoopVariable();
5897 Cond = RangeFor->getCond();
5898 Inc = RangeFor->getInc();
5900 llvm_unreachable(
"unhandled kind of loop");
5909 if (
auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) {
5910 LHS = CondBinExpr->getLHS();
5911 RHS = CondBinExpr->getRHS();
5912 CondRel = CondBinExpr->getOpcode();
5913 }
else if (
auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) {
5914 assert(CondCXXOp->getNumArgs() == 2 &&
"Comparison should have 2 operands");
5915 LHS = CondCXXOp->getArg(0);
5916 RHS = CondCXXOp->getArg(1);
5917 switch (CondCXXOp->getOperator()) {
5918 case OO_ExclaimEqual:
5930 case OO_GreaterEqual:
5934 llvm_unreachable(
"unexpected iterator operator");
5937 llvm_unreachable(
"unexpected loop condition");
5941 cast<DeclRefExpr>(LHS->
IgnoreImplicit())->getDecl() != LIVDecl) {
5942 std::swap(LHS, RHS);
5959 if (
auto *IncUn = dyn_cast<UnaryOperator>(Inc)) {
5961 switch (IncUn->getOpcode()) {
5971 llvm_unreachable(
"unhandled unary increment operator");
5974 Ctx, llvm::APInt(Ctx.
getIntWidth(LogicalTy), Direction), LogicalTy, {});
5975 }
else if (
auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
5976 if (IncBin->getOpcode() == BO_AddAssign) {
5977 Step = IncBin->getRHS();
5978 }
else if (IncBin->getOpcode() == BO_SubAssign) {
5982 llvm_unreachable(
"unhandled binary increment operator");
5983 }
else if (
auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) {
5984 switch (CondCXXOp->getOperator()) {
5987 Ctx, llvm::APInt(Ctx.
getIntWidth(LogicalTy), 1), LogicalTy, {});
5991 Ctx, llvm::APInt(Ctx.
getIntWidth(LogicalTy), -1), LogicalTy, {});
5994 Step = CondCXXOp->getArg(1);
6001 llvm_unreachable(
"unhandled overloaded increment operator");
6004 llvm_unreachable(
"unknown increment expression");
6009 SemaRef, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt));
6012 nullptr,
nullptr, {},
nullptr);
6014 LoopVarFunc, LVRef);
6019 if (isa<ForStmt>(AStmt) || isa<CXXForRangeStmt>(AStmt))
6026 "Loop transformation directive expected");
6027 return LoopTransform;
6034 Expr *UnresolvedMapper);
6046 for (
int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) {
6047 auto *
C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
6051 auto *MI =
C->mapperlist_begin();
6052 for (
auto I =
C->varlist_begin(), End =
C->varlist_end(); I != End;
6072 ElemType = ATy->getElementType();
6075 CanonType = ElemType;
6080 1, {CanonType,
nullptr});
6081 llvm::DenseMap<const Type *, Expr *>
Visited;
6084 while (!Types.empty()) {
6087 std::tie(BaseType, CurFD) = Types.pop_back_val();
6088 while (ParentChain.back().second == 0)
6089 ParentChain.pop_back();
6090 --ParentChain.back().second;
6106 S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
6117 Expr *BaseExpr = OE;
6118 for (
const auto &
P : ParentChain) {
6136 SubExprs.push_back(BaseExpr);
6140 bool FirstIter =
true;
6150 ParentChain.emplace_back(CurFD, 1);
6152 ++ParentChain.back().second;
6154 Types.emplace_back(FieldTy, FD);
6158 if (SubExprs.empty())
6163 nullptr,
C->getMapTypeModifiers(),
C->getMapTypeModifiersLoc(),
6164 MapperIdScopeSpec, MapperId,
C->getMapType(),
6167 Clauses.push_back(NewClause);
6184 if (
C->getBindKind() == OMPC_BIND_parallel) {
6185 TeamsLoopCanBeParallelFor =
false;
6201 bool IsOpenMPAPI =
false;
6202 auto *FD = dyn_cast_or_null<FunctionDecl>(
C->getCalleeDecl());
6204 std::string Name = FD->getNameInfo().getAsString();
6205 IsOpenMPAPI = Name.find(
"omp_") == 0;
6207 TeamsLoopCanBeParallelFor =
6208 IsOpenMPAPI || SemaRef.getLangOpts().OpenMPNoNestedParallelism;
6209 if (!TeamsLoopCanBeParallelFor)
6212 for (
const Stmt *Child :
C->children())
6220 Visit(S->getCapturedDecl()->getBody());
6223 void VisitStmt(
const Stmt *S) {
6226 for (
const Stmt *Child : S->children())
6230 explicit TeamsLoopChecker(
Sema &SemaRef)
6231 : SemaRef(SemaRef), TeamsLoopCanBeParallelFor(
true) {}
6234 bool TeamsLoopCanBeParallelFor;
6239 TeamsLoopChecker Checker(SemaRef);
6240 Checker.Visit(AStmt);
6241 return Checker.teamsLoopCanBeParallelFor();
6244bool SemaOpenMP::mapLoopConstruct(
6251 bool UseClausesWithoutBind =
false;
6254 if (
getLangOpts().OpenMP >= 50 && Kind == OMPD_loop) {
6261 BindKind = OMPC_BIND_thread;
6263 if (ParentDirective == OMPD_unknown) {
6265 diag::err_omp_bind_required_on_loop);
6266 }
else if (ParentDirective == OMPD_parallel ||
6267 ParentDirective == OMPD_target_parallel) {
6268 BindKind = OMPC_BIND_parallel;
6269 }
else if (ParentDirective == OMPD_teams ||
6270 ParentDirective == OMPD_target_teams) {
6271 BindKind = OMPC_BIND_teams;
6278 UseClausesWithoutBind =
true;
6283 if (BindKind == OMPC_BIND_teams &&
6284 C->getClauseKind() == llvm::omp::Clause::OMPC_reduction)
6286 diag::err_omp_loop_reduction_clause);
6290 if (
C->getClauseKind() != llvm::omp::Clause::OMPC_bind)
6291 ClausesWithoutBind.push_back(
C);
6295 case OMPC_BIND_parallel:
6297 DSAStack->setCurrentDirective(OMPD_for);
6298 DSAStack->setMappedDirective(OMPD_loop);
6299 PrevMappedDirective = OMPD_loop;
6301 case OMPC_BIND_teams:
6302 Kind = OMPD_distribute;
6303 DSAStack->setCurrentDirective(OMPD_distribute);
6304 DSAStack->setMappedDirective(OMPD_loop);
6305 PrevMappedDirective = OMPD_loop;
6307 case OMPC_BIND_thread:
6309 DSAStack->setCurrentDirective(OMPD_simd);
6310 DSAStack->setMappedDirective(OMPD_loop);
6311 PrevMappedDirective = OMPD_loop;
6316 }
else if (PrevMappedDirective == OMPD_loop) {
6325 DSAStack->setMappedDirective(OMPD_loop);
6328 return UseClausesWithoutBind;
6339 bool UseClausesWithoutBind =
false;
6342 OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses))
6343 BindKind = BC->getBindKind();
6348 if (Kind == OMPD_loop || PrevMappedDirective == OMPD_loop) {
6349 UseClausesWithoutBind = mapLoopConstruct(
6350 ClausesWithoutBind, Clauses, BindKind, Kind, PrevMappedDirective,
6351 StartLoc, EndLoc, DirName, CancelRegion);
6358 BindKind, StartLoc)) {
6365 Diag(StartLoc, diag::warn_hip_omp_target_directives);
6369 bool ErrorFound =
false;
6370 if (
getLangOpts().OpenMP >= 50 && UseClausesWithoutBind) {
6371 ClausesWithImplicit.append(ClausesWithoutBind.begin(),
6372 ClausesWithoutBind.end());
6374 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
6377 Kind != OMPD_atomic && Kind != OMPD_critical && Kind != OMPD_section &&
6378 Kind != OMPD_master && Kind != OMPD_masked &&
6380 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6383 DSAAttrChecker DSAChecker(
DSAStack,
SemaRef, cast<CapturedStmt>(AStmt));
6386 while (--ThisCaptureLevel >= 0)
6387 S = cast<CapturedStmt>(S)->getCapturedStmt();
6388 DSAChecker.Visit(S);
6392 auto *CS = cast<CapturedStmt>(AStmt);
6396 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
6398 DSAChecker.visitSubCaptures(CS);
6400 if (DSAChecker.isErrorFound())
6403 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
6406 DSAChecker.getImplicitFirstprivate().begin(),
6407 DSAChecker.getImplicitFirstprivate().end());
6409 DSAChecker.getImplicitPrivate().begin(),
6410 DSAChecker.getImplicitPrivate().end());
6414 ImplicitMapModifiers[DefaultmapKindNum];
6416 ImplicitMapModifiersLoc[DefaultmapKindNum];
6420 if (
auto *DMC = dyn_cast<OMPDefaultmapClause>(
C))
6421 if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
6422 PresentModifierLocs[DMC->getDefaultmapKind()] =
6423 DMC->getDefaultmapModifierLoc();
6425 for (
unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
6427 for (
unsigned I = 0; I < OMPC_MAP_delete; ++I) {
6430 ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
6433 DSAChecker.getImplicitMapModifier(Kind);
6434 ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
6435 ImplicitModifier.end());
6436 std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
6437 ImplicitModifier.size(), PresentModifierLocs[VC]);
6441 if (
auto *IRC = dyn_cast<OMPInReductionClause>(
C)) {
6442 for (
Expr *E : IRC->taskgroup_descriptors())
6444 ImplicitFirstprivates.emplace_back(E);
6449 if (
auto *DC = dyn_cast<OMPDetachClause>(
C))
6450 ImplicitFirstprivates.push_back(DC->getEventHandler());
6452 if (!ImplicitFirstprivates.empty()) {
6456 ClausesWithImplicit.push_back(
Implicit);
6457 ErrorFound = cast<OMPFirstprivateClause>(
Implicit)->varlist_size() !=
6458 ImplicitFirstprivates.size();
6463 if (!ImplicitPrivates.empty()) {
6467 ClausesWithImplicit.push_back(
Implicit);
6468 ErrorFound = cast<OMPPrivateClause>(
Implicit)->varlist_size() !=
6469 ImplicitPrivates.size();
6478 if (
getLangOpts().OpenMP >= 50 && Kind != OMPD_target &&
6482 if (
auto *RC = dyn_cast<OMPReductionClause>(
C))
6483 for (
Expr *E : RC->varlists())
6485 ImplicitExprs.emplace_back(E);
6487 if (!ImplicitExprs.empty()) {
6493 MapperIdScopeSpec, MapperId, OMPC_MAP_tofrom,
6496 ClausesWithImplicit.emplace_back(
Implicit);
6499 for (
unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
6500 int ClauseKindCnt = -1;
6503 if (ImplicitMap.empty())
6509 nullptr, ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
6510 MapperIdScopeSpec, MapperId, Kind,
true,
6513 ClausesWithImplicit.emplace_back(
Implicit);
6514 ErrorFound |= cast<OMPMapClause>(
Implicit)->varlist_size() !=
6525 ClausesWithImplicit);
6533 AllowedNameModifiers.push_back(OMPD_parallel);
6537 VarsWithInheritedDSA);
6539 AllowedNameModifiers.push_back(OMPD_simd);
6551 VarsWithInheritedDSA);
6555 EndLoc, VarsWithInheritedDSA);
6557 AllowedNameModifiers.push_back(OMPD_simd);
6564 assert(ClausesWithImplicit.empty() &&
6565 "No clauses are allowed for 'omp section' directive");
6573 assert(ClausesWithImplicit.empty() &&
6574 "No clauses are allowed for 'omp master' directive");
6585 case OMPD_parallel_for:
6587 EndLoc, VarsWithInheritedDSA);
6588 AllowedNameModifiers.push_back(OMPD_parallel);
6590 case OMPD_parallel_for_simd:
6592 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6593 AllowedNameModifiers.push_back(OMPD_parallel);
6595 AllowedNameModifiers.push_back(OMPD_simd);
6601 case OMPD_parallel_master:
6604 AllowedNameModifiers.push_back(OMPD_parallel);
6606 case OMPD_parallel_masked:
6609 AllowedNameModifiers.push_back(OMPD_parallel);
6611 case OMPD_parallel_sections:
6614 AllowedNameModifiers.push_back(OMPD_parallel);
6619 AllowedNameModifiers.push_back(OMPD_task);
6621 case OMPD_taskyield:
6622 assert(ClausesWithImplicit.empty() &&
6623 "No clauses are allowed for 'omp taskyield' directive");
6624 assert(AStmt ==
nullptr &&
6625 "No associated statement allowed for 'omp taskyield' directive");
6629 assert(AStmt ==
nullptr &&
6630 "No associated statement allowed for 'omp error' directive");
6634 assert(ClausesWithImplicit.empty() &&
6635 "No clauses are allowed for 'omp barrier' directive");
6636 assert(AStmt ==
nullptr &&
6637 "No associated statement allowed for 'omp barrier' directive");
6641 assert(AStmt ==
nullptr &&
6642 "No associated statement allowed for 'omp taskwait' directive");
6645 case OMPD_taskgroup:
6650 assert(AStmt ==
nullptr &&
6651 "No associated statement allowed for 'omp flush' directive");
6655 assert(AStmt ==
nullptr &&
6656 "No associated statement allowed for 'omp depobj' directive");
6660 assert(AStmt ==
nullptr &&
6661 "No associated statement allowed for 'omp scan' directive");
6679 AllowedNameModifiers.push_back(OMPD_target);
6681 case OMPD_target_parallel:
6684 AllowedNameModifiers.push_back(OMPD_target);
6685 AllowedNameModifiers.push_back(OMPD_parallel);
6687 case OMPD_target_parallel_for:
6689 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6690 AllowedNameModifiers.push_back(OMPD_target);
6691 AllowedNameModifiers.push_back(OMPD_parallel);
6693 case OMPD_cancellation_point:
6694 assert(ClausesWithImplicit.empty() &&
6695 "No clauses are allowed for 'omp cancellation point' directive");
6696 assert(AStmt ==
nullptr &&
"No associated statement allowed for 'omp "
6697 "cancellation point' directive");
6701 assert(AStmt ==
nullptr &&
6702 "No associated statement allowed for 'omp cancel' directive");
6705 AllowedNameModifiers.push_back(OMPD_cancel);
6707 case OMPD_target_data:
6710 AllowedNameModifiers.push_back(OMPD_target_data);
6712 case OMPD_target_enter_data:
6715 AllowedNameModifiers.push_back(OMPD_target_enter_data);
6717 case OMPD_target_exit_data:
6720 AllowedNameModifiers.push_back(OMPD_target_exit_data);
6724 EndLoc, VarsWithInheritedDSA);
6725 AllowedNameModifiers.push_back(OMPD_taskloop);
6727 case OMPD_taskloop_simd:
6729 EndLoc, VarsWithInheritedDSA);
6730 AllowedNameModifiers.push_back(OMPD_taskloop);
6732 AllowedNameModifiers.push_back(OMPD_simd);
6734 case OMPD_master_taskloop:
6736 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6737 AllowedNameModifiers.push_back(OMPD_taskloop);
6739 case OMPD_masked_taskloop:
6741 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6742 AllowedNameModifiers.push_back(OMPD_taskloop);
6744 case OMPD_master_taskloop_simd:
6746 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6747 AllowedNameModifiers.push_back(OMPD_taskloop);
6749 AllowedNameModifiers.push_back(OMPD_simd);
6751 case OMPD_masked_taskloop_simd:
6753 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6755 AllowedNameModifiers.push_back(OMPD_taskloop);
6756 AllowedNameModifiers.push_back(OMPD_simd);
6759 case OMPD_parallel_master_taskloop:
6761 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6762 AllowedNameModifiers.push_back(OMPD_taskloop);
6763 AllowedNameModifiers.push_back(OMPD_parallel);
6765 case OMPD_parallel_masked_taskloop:
6767 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6769 AllowedNameModifiers.push_back(OMPD_taskloop);
6770 AllowedNameModifiers.push_back(OMPD_parallel);
6773 case OMPD_parallel_master_taskloop_simd:
6775 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6776 AllowedNameModifiers.push_back(OMPD_taskloop);
6777 AllowedNameModifiers.push_back(OMPD_parallel);
6779 AllowedNameModifiers.push_back(OMPD_simd);
6781 case OMPD_parallel_masked_taskloop_simd:
6783 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6785 AllowedNameModifiers.push_back(OMPD_taskloop);
6786 AllowedNameModifiers.push_back(OMPD_parallel);
6787 AllowedNameModifiers.push_back(OMPD_simd);
6790 case OMPD_distribute:
6792 EndLoc, VarsWithInheritedDSA);
6794 case OMPD_target_update:
6797 AllowedNameModifiers.push_back(OMPD_target_update);
6799 case OMPD_distribute_parallel_for:
6801 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6802 AllowedNameModifiers.push_back(OMPD_parallel);
6804 case OMPD_distribute_parallel_for_simd:
6806 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6807 AllowedNameModifiers.push_back(OMPD_parallel);
6809 AllowedNameModifiers.push_back(OMPD_simd);
6811 case OMPD_distribute_simd:
6813 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6815 AllowedNameModifiers.push_back(OMPD_simd);
6817 case OMPD_target_parallel_for_simd:
6819 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6820 AllowedNameModifiers.push_back(OMPD_target);
6821 AllowedNameModifiers.push_back(OMPD_parallel);
6823 AllowedNameModifiers.push_back(OMPD_simd);
6825 case OMPD_target_simd:
6827 EndLoc, VarsWithInheritedDSA);
6828 AllowedNameModifiers.push_back(OMPD_target);
6830 AllowedNameModifiers.push_back(OMPD_simd);
6832 case OMPD_teams_distribute:
6834 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6836 case OMPD_teams_distribute_simd:
6838 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6840 AllowedNameModifiers.push_back(OMPD_simd);
6842 case OMPD_teams_distribute_parallel_for_simd:
6844 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6845 AllowedNameModifiers.push_back(OMPD_parallel);
6847 AllowedNameModifiers.push_back(OMPD_simd);
6849 case OMPD_teams_distribute_parallel_for:
6851 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6852 AllowedNameModifiers.push_back(OMPD_parallel);
6854 case OMPD_target_teams:
6857 AllowedNameModifiers.push_back(OMPD_target);
6859 case OMPD_target_teams_distribute:
6861 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6862 AllowedNameModifiers.push_back(OMPD_target);
6864 case OMPD_target_teams_distribute_parallel_for:
6866 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6867 AllowedNameModifiers.push_back(OMPD_target);
6868 AllowedNameModifiers.push_back(OMPD_parallel);
6870 case OMPD_target_teams_distribute_parallel_for_simd:
6872 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6873 AllowedNameModifiers.push_back(OMPD_target);
6874 AllowedNameModifiers.push_back(OMPD_parallel);
6876 AllowedNameModifiers.push_back(OMPD_simd);
6878 case OMPD_target_teams_distribute_simd:
6880 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6881 AllowedNameModifiers.push_back(OMPD_target);
6883 AllowedNameModifiers.push_back(OMPD_simd);
6886 assert(AStmt ==
nullptr &&
6887 "No associated statement allowed for 'omp interop' directive");
6896 EndLoc, VarsWithInheritedDSA);
6898 case OMPD_teams_loop:
6900 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6902 case OMPD_target_teams_loop:
6904 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6905 AllowedNameModifiers.push_back(OMPD_target);
6907 case OMPD_parallel_loop:
6909 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6911 case OMPD_target_parallel_loop:
6913 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6915 case OMPD_declare_target:
6916 case OMPD_end_declare_target:
6917 case OMPD_threadprivate:
6919 case OMPD_declare_reduction:
6920 case OMPD_declare_mapper:
6921 case OMPD_declare_simd:
6923 case OMPD_declare_variant:
6924 case OMPD_begin_declare_variant:
6925 case OMPD_end_declare_variant:
6926 llvm_unreachable(
"OpenMP Directive is not allowed");
6929 llvm_unreachable(
"Unknown OpenMP directive");
6932 ErrorFound = Res.
isInvalid() || ErrorFound;
6936 if (
DSAStack->getDefaultDSA() == DSA_none ||
6937 DSAStack->getDefaultDSA() == DSA_private ||
6938 DSAStack->getDefaultDSA() == DSA_firstprivate) {
6941 switch (
C->getClauseKind()) {
6942 case OMPC_num_threads:
6943 case OMPC_dist_schedule:
6950 cast<OMPIfClause>(
C)->getNameModifier() != OMPD_target)
6954 cast<OMPIfClause>(
C)->getNameModifier() != OMPD_parallel)
6960 case OMPC_grainsize:
6961 case OMPC_num_tasks:
6964 case OMPC_novariants:
6965 case OMPC_nocontext:
6972 case OMPC_num_teams:
6973 case OMPC_thread_limit:
6980 case OMPC_proc_bind:
6982 case OMPC_firstprivate:
6983 case OMPC_lastprivate:
6985 case OMPC_reduction:
6986 case OMPC_task_reduction:
6987 case OMPC_in_reduction:
6991 case OMPC_copyprivate:
6994 case OMPC_mergeable:
7011 case OMPC_defaultmap:
7014 case OMPC_use_device_ptr:
7015 case OMPC_use_device_addr:
7016 case OMPC_is_device_ptr:
7017 case OMPC_has_device_addr:
7018 case OMPC_nontemporal:
7021 case OMPC_inclusive:
7022 case OMPC_exclusive:
7023 case OMPC_uses_allocators:
7028 case OMPC_allocator:
7031 case OMPC_threadprivate:
7034 case OMPC_unified_address:
7035 case OMPC_unified_shared_memory:
7036 case OMPC_reverse_offload:
7037 case OMPC_dynamic_allocators:
7038 case OMPC_atomic_default_mem_order:
7039 case OMPC_device_type:
7046 llvm_unreachable(
"Unexpected clause");
7048 for (
Stmt *CC :
C->children()) {
7050 DSAChecker.Visit(CC);
7053 for (
const auto &
P : DSAChecker.getVarsWithInheritedDSA())
7054 VarsWithInheritedDSA[
P.getFirst()] =
P.getSecond();
7056 for (
const auto &
P : VarsWithInheritedDSA) {
7057 if (
P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(
P.getFirst()))
7060 if (
DSAStack->getDefaultDSA() == DSA_none ||
7061 DSAStack->getDefaultDSA() == DSA_private ||
7062 DSAStack->getDefaultDSA() == DSA_firstprivate) {
7063 Diag(
P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
7064 <<
P.first <<
P.second->getSourceRange();
7065 Diag(
DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
7067 Diag(
P.second->getExprLoc(),
7068 diag::err_omp_defaultmap_no_attr_for_variable)
7069 <<
P.first <<
P.second->getSourceRange();
7071 diag::note_omp_defaultmap_attr_none);
7075 if (!AllowedNameModifiers.empty())
7089 DSAStack->addTargetDirLocation(StartLoc);
7100 assert(Aligneds.size() == Alignments.size());
7101 assert(Linears.size() == LinModifiers.size());
7102 assert(Linears.size() == Steps.size());
7103 if (!DG || DG.
get().isNull())
7106 const int SimdId = 0;
7107 if (!DG.
get().isSingleDecl()) {
7108 Diag(SR.
getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
7112 Decl *ADecl = DG.
get().getSingleDecl();
7113 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
7114 ADecl = FTD->getTemplatedDecl();
7116 auto *FD = dyn_cast<FunctionDecl>(ADecl);
7118 Diag(ADecl->
getLocation(), diag::err_omp_function_expected) << SimdId;
7134 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
7135 const Expr *UniformedLinearThis =
nullptr;
7136 for (
const Expr *E : Uniforms) {
7138 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
7139 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
7140 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7141 FD->getParamDecl(PVD->getFunctionScopeIndex())
7143 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
7146 if (isa<CXXThisExpr>(E)) {
7147 UniformedLinearThis = E;
7151 << FD->
getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
7161 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
7162 const Expr *AlignedThis =
nullptr;
7163 for (
const Expr *E : Aligneds) {
7165 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
7166 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7168 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7169 FD->getParamDecl(PVD->getFunctionScopeIndex())
7173 if (AlignedArgs.count(CanonPVD) > 0) {
7175 << 1 << getOpenMPClauseName(OMPC_aligned)
7177 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
7178 diag::note_omp_explicit_dsa)
7179 << getOpenMPClauseName(OMPC_aligned);
7182 AlignedArgs[CanonPVD] = E;
7184 .getNonReferenceType()
7185 .getUnqualifiedType()
7186 .getCanonicalType();
7189 Diag(E->
getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
7191 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
7196 if (isa<CXXThisExpr>(E)) {
7199 << 2 << getOpenMPClauseName(OMPC_aligned) << E->
getSourceRange();
7201 << getOpenMPClauseName(OMPC_aligned);
7207 << FD->
getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
7214 for (
Expr *E : Alignments) {
7218 NewAligns.push_back(Align.
get());
7229 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
7230 const bool IsUniformedThis = UniformedLinearThis !=
nullptr;
7231 auto MI = LinModifiers.begin();
7232 for (
const Expr *E : Linears) {
7236 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
7237 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7239 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7240 FD->getParamDecl(PVD->getFunctionScopeIndex())
7244 if (LinearArgs.count(CanonPVD) > 0) {
7246 << getOpenMPClauseName(OMPC_linear)
7248 Diag(LinearArgs[CanonPVD]->getExprLoc(),
7249 diag::note_omp_explicit_dsa)
7250 << getOpenMPClauseName(OMPC_linear);
7254 if (UniformedArgs.count(CanonPVD) > 0) {
7256 << getOpenMPClauseName(OMPC_linear)
7258 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
7259 diag::note_omp_explicit_dsa)
7260 << getOpenMPClauseName(OMPC_uniform);
7263 LinearArgs[CanonPVD] = E;
7269 PVD->getOriginalType(),
7274 if (isa<CXXThisExpr>(E)) {
7275 if (UniformedLinearThis) {
7277 << getOpenMPClauseName(OMPC_linear)
7278 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
7280 Diag(UniformedLinearThis->
getExprLoc(), diag::note_omp_explicit_dsa)
7281 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
7285 UniformedLinearThis = E;
7294 << FD->
getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
7296 Expr *Step =
nullptr;
7297 Expr *NewStep =
nullptr;
7299 for (
Expr *E : Steps) {
7301 if (Step == E || !E) {
7302 NewSteps.push_back(E ? NewStep :
nullptr);
7306 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Step))
7307 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7309 if (UniformedArgs.count(CanonPVD) == 0) {
7316 NewSteps.push_back(Step);
7335 NewSteps.push_back(NewStep);
7337 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
7339 Uniforms.size(),
const_cast<Expr **
>(Aligneds.data()), Aligneds.size(),
7340 const_cast<Expr **
>(NewAligns.data()), NewAligns.size(),
7341 const_cast<Expr **
>(Linears.data()), Linears.size(),
7342 const_cast<unsigned *
>(LinModifiers.data()), LinModifiers.size(),
7343 NewSteps.data(), NewSteps.size(), SR);
7351 "Expected function type with prototype.");
7353 "Expected function with type with no prototype.");
7355 "Expected function with prototype.");
7363 Param->setScopeInfo(0, Params.size());
7364 Param->setImplicit();
7365 Params.push_back(Param);
7368 FD->setParams(Params);
7375 if (
auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7376 FD = UTemplDecl->getTemplatedDecl();
7378 FD = cast<FunctionDecl>(D);
7379 assert(FD &&
"Expected a function declaration!");
7385 for (OMPAssumeAttr *AA : OMPAssumeScoped)
7388 for (OMPAssumeAttr *AA : OMPAssumeGlobal)
7392SemaOpenMP::OMPDeclareVariantScope::OMPDeclareVariantScope(
OMPTraitInfo &TI)
7393 : TI(&TI), NameSuffix(TI.getMangledName()) {}
7401 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7404 bool IsTemplated = !TemplateParamLists.empty();
7406 !DVScope.TI->isExtensionActive(
7407 llvm::omp::TraitProperty::implementation_extension_allow_templates))
7424 for (
auto *Candidate : Lookup) {
7425 auto *CandidateDecl = Candidate->getUnderlyingDecl();
7427 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) {
7428 auto *FTD = cast<FunctionTemplateDecl>(CandidateDecl);
7429 if (FTD->getTemplateParameters()->size() == TemplateParamLists.size())
7430 UDecl = FTD->getTemplatedDecl();
7431 }
else if (!IsTemplated)
7432 UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
7446 FType, UDeclTy,
false,
7453 Bases.push_back(UDecl);
7456 bool UseImplicitBase = !DVScope.TI->isExtensionActive(
7457 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
7459 if (Bases.empty() && UseImplicitBase) {
7463 if (
auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
7464 Bases.push_back(BaseTemplD->getTemplatedDecl());
7466 Bases.push_back(cast<FunctionDecl>(BaseD));
7469 std::string MangledName;
7472 MangledName += DVScope.NameSuffix;
7487 if (
auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7488 FD = UTemplDecl->getTemplatedDecl();
7490 FD = cast<FunctionDecl>(D);
7497 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7498 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
7504 BaseFD->addAttr(OMPDeclareVariantA);
7523 CalleeFnDecl->
getName().starts_with_insensitive(
"omp_")) {
7526 Diag(LParenLoc, diag::err_omp_unexpected_call_to_omp_runtime_api);
7529 if (!CalleeFnDecl->
hasAttr<OMPDeclareVariantAttr>())
7533 std::function<void(StringRef)> DiagUnknownTrait = [
this,
7534 CE](StringRef ISATrait) {
7548 while (CalleeFnDecl) {
7549 for (OMPDeclareVariantAttr *A :
7551 Expr *VariantRef = A->getVariantFuncRef();
7553 VariantMatchInfo VMI;
7556 if (!isVariantApplicableInContext(VMI, OMPCtx,
7560 VMIs.push_back(VMI);
7561 Exprs.push_back(VariantRef);
7569 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
7572 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
7573 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
7589 if (
auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
7590 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
7592 Context, MemberCall->getImplicitObjectArgument(),
7594 MemberCall->getValueKind(), MemberCall->getObjectKind());
7597 RParenLoc, ExecConfig);
7599 if (
CallExpr *NCE = dyn_cast<CallExpr>(NewCall.
get())) {
7600 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
7602 CalleeFnType, NewCalleeFnDecl->
getType(),
7613 VMIs.erase(VMIs.begin() + BestIdx);
7614 Exprs.erase(Exprs.begin() + BestIdx);
7615 }
while (!VMIs.empty());
7622std::optional<std::pair<FunctionDecl *, Expr *>>
7626 unsigned NumAppendArgs,
7629 if (!DG || DG.
get().isNull())
7630 return std::nullopt;
7632 const int VariantId = 1;
7634 if (!DG.
get().isSingleDecl()) {
7635 Diag(SR.
getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
7637 return std::nullopt;
7639 Decl *ADecl = DG.
get().getSingleDecl();
7640 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
7641 ADecl = FTD->getTemplatedDecl();
7644 auto *FD = dyn_cast<FunctionDecl>(ADecl);
7648 return std::nullopt;
7651 auto &&HasMultiVersionAttributes = [](
const FunctionDecl *FD) {
7654 return FD->isMultiVersion() || FD->
hasAttr<TargetAttr>();
7657 if (HasMultiVersionAttributes(FD)) {
7658 Diag(FD->
getLocation(), diag::err_omp_declare_variant_incompat_attributes)
7660 return std::nullopt;
7665 Diag(SR.
getBegin(), diag::warn_omp_declare_variant_after_used)
7670 if (!FD->isThisDeclarationADefinition() && FD->isDefined(
Definition) &&
7672 Diag(SR.
getBegin(), diag::warn_omp_declare_variant_after_emitted)
7677 Diag(SR.
getBegin(), diag::err_omp_function_expected) << VariantId;
7678 return std::nullopt;
7681 auto ShouldDelayChecks = [](
Expr *&E,
bool) {
7687 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef,
false) ||
7689 return std::make_pair(FD, VariantRef);
7692 auto HandleNonConstantScoresAndConditions = [
this](
Expr *&E,
7693 bool IsScore) ->
bool {
7699 Diag(E->
getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
7707 diag::err_omp_declare_variant_user_condition_not_constant)
7713 return std::nullopt;
7716 if (NumAppendArgs) {
7719 Diag(FD->
getLocation(), diag::err_omp_declare_variant_prototype_required)
7721 return std::nullopt;
7730 TD = dyn_cast_or_null<TypeDecl>(ND);
7733 Diag(SR.
getBegin(), diag::err_omp_interop_type_not_found) << SR;
7734 return std::nullopt;
7737 if (PTy->isVariadic()) {
7738 Diag(FD->
getLocation(), diag::err_omp_append_args_with_varargs) << SR;
7739 return std::nullopt;
7742 Params.append(PTy->param_type_begin(), PTy->param_type_end());
7743 Params.insert(Params.end(), NumAppendArgs, InteropType);
7744 AdjustedFnType = Context.
getFunctionType(PTy->getReturnType(), Params,
7745 PTy->getExtProtoInfo());
7753 auto *Method = dyn_cast<CXXMethodDecl>(FD);
7754 if (Method && !Method->isStatic()) {
7755 const Type *ClassType =
7769 return std::nullopt;
7771 VariantRef = ER.
get();
7779 false, Sema::AllowedExplicit::None,
7785 diag::err_omp_declare_variant_incompat_types)
7787 << ((Method && !Method->isStatic()) ? FnPtrType : FD->
getType())
7789 return std::nullopt;
7794 return std::nullopt;
7797 if (Method && !Method->isStatic()) {
7798 Expr *PossibleAddrOfVariantRef = VariantRefCast.
get();
7799 if (
auto *UO = dyn_cast<UnaryOperator>(
7801 VariantRefCast = UO->getSubExpr();
7810 return std::nullopt;
7818 return std::nullopt;
7820 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
7824 return std::nullopt;
7829 diag::err_omp_declare_variant_same_base_function)
7831 return std::nullopt;
7840 diag::err_omp_declare_variant_incompat_types)
7841 << NewFD->getType() << FD->
getType() << (NumAppendArgs ? 1 : 0)
7843 return std::nullopt;
7848 else if (NewFD->getType()->isFunctionNoProtoType())
7854 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
7856 diag::warn_omp_declare_variant_marked_as_declare_variant)
7859 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->
getRange();
7860 Diag(SR.
getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
7861 return std::nullopt;
7864 enum DoesntSupport {
7873 if (
const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
7874 if (CXXFD->isVirtual()) {
7877 return std::nullopt;
7880 if (isa<CXXConstructorDecl>(FD)) {
7883 return std::nullopt;
7886 if (isa<CXXDestructorDecl>(FD)) {
7889 return std::nullopt;
7893 if (FD->isDeleted()) {
7896 return std::nullopt;
7899 if (FD->isDefaulted()) {
7902 return std::nullopt;
7905 if (FD->isConstexpr()) {
7907 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
7908 return std::nullopt;
7918 SemaRef.
PDiag(diag::err_omp_declare_variant_doesnt_support)),
7924 return std::nullopt;
7925 return std::make_pair(FD, cast<Expr>(DRE));
7941 llvm::append_range(AllAdjustArgs, AdjustArgsNothing);
7942 llvm::append_range(AllAdjustArgs, AdjustArgsNeedDevicePtr);
7944 if (!AllAdjustArgs.empty() || !AppendArgs.empty()) {
7945 VariantMatchInfo VMI;
7947 if (!llvm::is_contained(
7948 VMI.ConstructTraits,
7949 llvm::omp::TraitProperty::construct_dispatch_dispatch)) {
7950 if (!AllAdjustArgs.empty())
7951 Diag(AdjustArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7952 << getOpenMPClauseName(OMPC_adjust_args);
7953 if (!AppendArgs.empty())
7954 Diag(AppendArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7955 << getOpenMPClauseName(OMPC_append_args);
7965 for (
Expr *E : AllAdjustArgs) {
7967 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
7968 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7970 if (FD->
getNumParams() > PVD->getFunctionScopeIndex() &&
7974 if (!AdjustVars.insert(CanonPVD).second) {
7975 Diag(DRE->getLocation(), diag::err_omp_adjust_arg_multiple_clauses)
7984 Diag(E->
getExprLoc(), diag::err_omp_param_or_this_in_clause) << FD << 0;
7988 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
7990 const_cast<Expr **
>(AdjustArgsNothing.data()), AdjustArgsNothing.size(),
7991 const_cast<Expr **
>(AdjustArgsNeedDevicePtr.data()),
7992 AdjustArgsNeedDevicePtr.size(),
7993 const_cast<OMPInteropInfo *
>(AppendArgs.data()), AppendArgs.size(), SR);
8004 auto *CS = cast<CapturedStmt>(AStmt);
8021struct LoopIterationSpace final {
8024 bool IsStrictCompare =
false;
8026 Expr *PreCond =
nullptr;
8029 Expr *NumIterations =
nullptr;
8031 Expr *CounterVar =
nullptr;
8033 Expr *PrivateCounterVar =
nullptr;
8035 Expr *CounterInit =
nullptr;
8038 Expr *CounterStep =
nullptr;
8040 bool Subtract =
false;
8050 Expr *MinValue =
nullptr;
8054 Expr *MaxValue =
nullptr;
8056 bool IsNonRectangularLB =
false;
8058 bool IsNonRectangularUB =
false;
8061 unsigned LoopDependentIdx = 0;
8065 Expr *FinalCondition =
nullptr;
8071class OpenMPIterationSpaceChecker {
8075 bool SupportsNonRectangular;
8091 Expr *LCRef =
nullptr;
8097 Expr *Step =
nullptr;
8104 std::optional<bool> TestIsLessOp;
8106 bool TestIsStrictOp =
false;
8108 bool SubtractStep =
false;
8113 std::optional<unsigned> InitDependOnLC;
8116 std::optional<unsigned> CondDependOnLC;
8118 std::optional<unsigned> doesDependOnLoopCounter(
const Stmt *S,
8119 bool IsInitializer);
8125 OpenMPIterationSpaceChecker(
Sema &SemaRef,
bool SupportsNonRectangular,
8127 : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular),
8128 Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
8131 bool checkAndSetInit(
Stmt *S,
bool EmitDiags =
true);
8134 bool checkAndSetCond(
Expr *S);
8137 bool checkAndSetInc(
Expr *S);
8139 ValueDecl *getLoopDecl()
const {
return LCDecl; }
8141 Expr *getLoopDeclRefExpr()
const {
return LCRef; }
8143 SourceRange getInitSrcRange()
const {
return InitSrcRange; }
8145 SourceRange getConditionSrcRange()
const {
return ConditionSrcRange; }
8147 SourceRange getIncrementSrcRange()
const {
return IncrementSrcRange; }
8149 bool shouldSubtractStep()
const {
return SubtractStep; }
8151 bool isStrictTestOp()
const {
return TestIsStrictOp; }
8153 Expr *buildNumIterations(
8155 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const;
8159 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const;
8162 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8163 DSAStackTy &DSA)
const;
8166 Expr *buildPrivateCounterVar()
const;
8170 Expr *buildCounterStep()
const;
8174 buildOrderedLoopData(
Scope *S,
Expr *Counter,
8175 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8179 std::pair<Expr *, Expr *> buildMinMaxValues(
8180 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const;
8182 Expr *buildFinalCondition(
Scope *S)
const;
8184 bool dependent()
const;
8186 bool doesInitDependOnLC()
const {
return InitDependOnLC.has_value(); }
8188 bool doesCondDependOnLC()
const {
return CondDependOnLC.has_value(); }
8190 unsigned getLoopDependentIdx()
const {
8191 return InitDependOnLC.value_or(CondDependOnLC.value_or(0));
8197 bool checkAndSetIncRHS(
Expr *RHS);
8202 bool setUB(
Expr *NewUB, std::optional<bool> LessOp,
bool StrictOp,
8205 bool setStep(
Expr *NewStep,
bool Subtract);
8208bool OpenMPIterationSpaceChecker::dependent()
const {
8210 assert(!LB && !UB && !Step);
8218bool OpenMPIterationSpaceChecker::setLCDeclAndLB(
ValueDecl *NewLCDecl,
8220 Expr *NewLB,
bool EmitDiags) {
8222 assert(LCDecl ==
nullptr && LB ==
nullptr && LCRef ==
nullptr &&
8223 UB ==
nullptr && Step ==
nullptr && !TestIsLessOp && !TestIsStrictOp);
8227 LCRef = NewLCRefExpr;
8228 if (
auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
8230 if ((Ctor->isCopyOrMoveConstructor() ||
8231 Ctor->isConvertingConstructor(
false)) &&
8232 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
8236 InitDependOnLC = doesDependOnLoopCounter(LB,
true);
8240bool OpenMPIterationSpaceChecker::setUB(
Expr *NewUB, std::optional<bool> LessOp,
8244 assert(LCDecl !=
nullptr && LB !=
nullptr && UB ==
nullptr &&
8245 Step ==
nullptr && !TestIsLessOp && !TestIsStrictOp);
8250 TestIsLessOp = LessOp;
8251 TestIsStrictOp = StrictOp;
8252 ConditionSrcRange = SR;
8254 CondDependOnLC = doesDependOnLoopCounter(UB,
false);
8258bool OpenMPIterationSpaceChecker::setStep(
Expr *NewStep,
bool Subtract) {
8260 assert(LCDecl !=
nullptr && LB !=
nullptr && Step ==
nullptr);
8270 NewStep = Val.
get();
8283 std::optional<llvm::APSInt>
Result =
8294 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
8295 if (UB && (IsConstZero ||
8296 (*TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
8297 : (IsConstPos || (IsUnsigned && !Subtract))))) {
8299 diag::err_omp_loop_incr_not_compatible)
8301 SemaRef.
Diag(ConditionLoc,
8302 diag::note_omp_loop_cond_requres_compatible_incr)
8303 << *TestIsLessOp << ConditionSrcRange;
8306 if (*TestIsLessOp == Subtract) {
8310 Subtract = !Subtract;
8315 SubtractStep = Subtract;
8322class LoopCounterRefChecker final
8329 bool IsInitializer =
true;
8330 bool SupportsNonRectangular;
8331 unsigned BaseLoopId = 0;
8334 SemaRef.Diag(E->
getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
8335 << (IsInitializer ? 0 : 1);
8338 const auto &&
Data = Stack.isLoopControlVariable(VD);
8344 llvm::raw_svector_ostream OS(Name);
8348 diag::err_omp_wrong_dependency_iterator_type)
8350 SemaRef.Diag(VD->
getLocation(), diag::note_previous_decl) << VD;
8353 if (
Data.first && !SupportsNonRectangular) {
8354 SemaRef.Diag(E->
getExprLoc(), diag::err_omp_invariant_dependency);
8358 (DepDecl || (PrevDepDecl &&
8360 if (!DepDecl && PrevDepDecl)
8361 DepDecl = PrevDepDecl;
8363 llvm::raw_svector_ostream OS(Name);
8367 diag::err_omp_invariant_or_linear_dependency)
8373 BaseLoopId =
Data.first;
8381 if (isa<VarDecl>(VD))
8382 return checkDecl(E, VD);
8388 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
8389 return checkDecl(E, VD);
8393 bool VisitStmt(
const Stmt *S) {
8395 for (
const Stmt *Child : S->children())
8396 Res = (Child && Visit(Child)) || Res;
8399 explicit LoopCounterRefChecker(
Sema &SemaRef, DSAStackTy &Stack,
8400 const ValueDecl *CurLCDecl,
bool IsInitializer,
8402 bool SupportsNonRectangular =
true)
8403 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
8404 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer),
8405 SupportsNonRectangular(SupportsNonRectangular) {}
8406 unsigned getBaseLoopId()
const {
8407 assert(CurLCDecl &&
"Expected loop dependency.");
8411 assert(CurLCDecl &&
"Expected loop dependency.");
8417std::optional<unsigned>
8418OpenMPIterationSpaceChecker::doesDependOnLoopCounter(
const Stmt *S,
8419 bool IsInitializer) {
8421 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
8422 DepDecl, SupportsNonRectangular);
8423 if (LoopStmtChecker.Visit(S)) {
8424 DepDecl = LoopStmtChecker.getDepDecl();
8425 return LoopStmtChecker.getBaseLoopId();
8427 return std::nullopt;
8430bool OpenMPIterationSpaceChecker::checkAndSetInit(
Stmt *S,
bool EmitDiags) {
8441 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
8445 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8446 if (!ExprTemp->cleanupsHaveSideEffects())
8447 S = ExprTemp->getSubExpr();
8449 InitSrcRange = S->getSourceRange();
8450 if (
Expr *E = dyn_cast<Expr>(S))
8452 if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
8453 if (BO->getOpcode() == BO_Assign) {
8455 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8456 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8458 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8460 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
8462 if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
8463 if (ME->isArrow() &&
8464 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8465 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8469 }
else if (
auto *DS = dyn_cast<DeclStmt>(S)) {
8470 if (DS->isSingleDecl()) {
8471 if (
auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
8472 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
8475 SemaRef.Diag(S->getBeginLoc(),
8476 diag::ext_omp_loop_not_canonical_init)
8477 << S->getSourceRange();
8478 return setLCDeclAndLB(
8481 Var->getType().getNonReferenceType(),
8483 Var->getInit(), EmitDiags);
8487 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8488 if (CE->getOperator() == OO_Equal) {
8489 Expr *LHS = CE->getArg(0);
8490 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8491 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8493 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8495 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
8497 if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
8498 if (ME->isArrow() &&
8499 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8500 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8506 if (dependent() || SemaRef.CurContext->isDependentContext())
8509 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
8510 << S->getSourceRange();
8521 if (
const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
8523 if ((Ctor->isCopyOrMoveConstructor() ||
8524 Ctor->isConvertingConstructor(
false)) &&
8525 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
8527 if (
const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
8528 if (
const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
8531 if (
const auto *ME = dyn_cast_or_null<MemberExpr>(E))
8532 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8537bool OpenMPIterationSpaceChecker::checkAndSetCond(
Expr *S) {
8544 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
8546 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
8547 << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
8553 auto &&CheckAndSetCond =
8558 if (getInitLCDecl(LHS) == LCDecl)
8559 return setUB(
const_cast<Expr *
>(RHS),
8561 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8562 if (getInitLCDecl(RHS) == LCDecl)
8563 return setUB(
const_cast<Expr *
>(LHS),
8565 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8566 }
else if (IneqCondIsCanonical && Opcode == BO_NE) {
8567 return setUB(
const_cast<Expr *
>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS),
8571 return std::nullopt;
8573 std::optional<bool> Res;
8574 if (
auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) {
8577 RBO->getOperatorLoc());
8578 }
else if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
8579 Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(),
8580 BO->getSourceRange(), BO->getOperatorLoc());
8581 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8582 if (CE->getNumArgs() == 2) {
8583 Res = CheckAndSetCond(
8585 CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc());
8590 if (dependent() || SemaRef.CurContext->isDependentContext())
8592 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
8593 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
8597bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(
Expr *RHS) {
8604 if (
auto *BO = dyn_cast<BinaryOperator>(RHS)) {
8605 if (BO->isAdditiveOp()) {
8606 bool IsAdd = BO->getOpcode() == BO_Add;
8607 if (getInitLCDecl(BO->getLHS()) == LCDecl)
8608 return setStep(BO->getRHS(), !IsAdd);
8609 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
8610 return setStep(BO->getLHS(),
false);
8612 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
8613 bool IsAdd = CE->getOperator() == OO_Plus;
8614 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
8615 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8616 return setStep(CE->getArg(1), !IsAdd);
8617 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
8618 return setStep(CE->getArg(0),
false);
8621 if (dependent() || SemaRef.CurContext->isDependentContext())
8623 SemaRef.Diag(RHS->
getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8628bool OpenMPIterationSpaceChecker::checkAndSetInc(
Expr *S) {
8643 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
8646 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8647 if (!ExprTemp->cleanupsHaveSideEffects())
8648 S = ExprTemp->getSubExpr();
8650 IncrementSrcRange = S->getSourceRange();
8651 S = S->IgnoreParens();
8652 if (
auto *UO = dyn_cast<UnaryOperator>(S)) {
8653 if (UO->isIncrementDecrementOp() &&
8654 getInitLCDecl(UO->getSubExpr()) == LCDecl)
8655 return setStep(SemaRef
8656 .ActOnIntegerConstant(UO->getBeginLoc(),
8657 (UO->isDecrementOp() ? -1 : 1))
8660 }
else if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
8661 switch (BO->getOpcode()) {
8664 if (getInitLCDecl(BO->getLHS()) == LCDecl)
8665 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
8668 if (getInitLCDecl(BO->getLHS()) == LCDecl)
8669 return checkAndSetIncRHS(BO->getRHS());
8674 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8675 switch (CE->getOperator()) {
8678 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8679 return setStep(SemaRef
8680 .ActOnIntegerConstant(
8682 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
8688 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8689 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
8692 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8693 return checkAndSetIncRHS(CE->getArg(1));
8699 if (dependent() || SemaRef.CurContext->isDependentContext())
8701 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8702 << S->getSourceRange() << LCDecl;
8708 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8709 StringRef Name =
".capture_expr.") {
8716 auto I = Captures.find(
Capture);
8717 if (I != Captures.end())
8730 bool TestIsStrictOp,
bool RoundToStep,
8731 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8732 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures,
".new_step");
8735 llvm::APSInt LRes, SRes;
8736 bool IsLowerConst =
false, IsStepConst =
false;
8737 if (std::optional<llvm::APSInt> Res =
8740 IsLowerConst =
true;
8742 if (std::optional<llvm::APSInt> Res =
8747 bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
8748 ((!TestIsStrictOp && LRes.isNonNegative()) ||
8749 (TestIsStrictOp && LRes.isStrictlyPositive()));
8750 bool NeedToReorganize =
false;
8752 if (!NoNeedToConvert && IsLowerConst &&
8753 (TestIsStrictOp || (RoundToStep && IsStepConst))) {
8754 NoNeedToConvert =
true;
8756 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
8757 ? LRes.getBitWidth()
8758 : SRes.getBitWidth();
8759 LRes = LRes.extend(BW + 1);
8760 LRes.setIsSigned(
true);
8761 SRes = SRes.extend(BW + 1);
8762 SRes.setIsSigned(
true);
8764 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
8765 LRes = LRes.trunc(BW);
8767 if (TestIsStrictOp) {
8768 unsigned BW = LRes.getBitWidth();
8769 LRes = LRes.extend(BW + 1);
8770 LRes.setIsSigned(
true);
8773 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
8775 LRes = LRes.trunc(BW);
8777 NeedToReorganize = NoNeedToConvert;
8780 bool IsUpperConst =
false;
8781 if (std::optional<llvm::APSInt> Res =
8784 IsUpperConst =
true;
8786 if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
8787 (!RoundToStep || IsStepConst)) {
8788 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
8789 : URes.getBitWidth();
8790 LRes = LRes.extend(BW + 1);
8791 LRes.setIsSigned(
true);
8792 URes = URes.extend(BW + 1);
8793 URes.setIsSigned(
true);
8795 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
8796 NeedToReorganize = NoNeedToConvert;
8801 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
8807 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
8810 LowerSize > UpperSize ? LowerSize : UpperSize, 0);
8821 if (!Lower || !Upper || NewStep.
isInvalid())
8827 if (NeedToReorganize) {
8841 S, DefaultLoc, BO_Add, Diff.
get(),
8851 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.
get());
8855 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
8871 S, DefaultLoc, BO_Sub, Diff.
get(),
8891 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Div, Diff.
get(), NewStep.
get());
8899Expr *OpenMPIterationSpaceChecker::buildNumIterations(
8901 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const {
8910 if (InitDependOnLC) {
8911 const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
8912 if (!IS.MinValue || !IS.MaxValue)
8921 IS.CounterVar, MinValue.
get());
8926 SemaRef.
BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.
get(), LBVal);
8941 IS.CounterVar, MaxValue.
get());
8946 SemaRef.
BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.
get(), LBVal);
8955 tryBuildCapture(SemaRef, LBMinVal.
get(), Captures,
".lb_min").get();
8957 tryBuildCapture(SemaRef, LBMaxVal.
get(), Captures,
".lb_max").get();
8958 if (!LBMin || !LBMax)
8962 SemaRef.
BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
8966 tryBuildCapture(SemaRef, MinLessMaxRes.
get(), Captures,
".min_less_max")
8970 if (*TestIsLessOp) {
8974 MinLessMax, LBMin, LBMax);
8977 LBVal = MinLB.
get();
8982 MinLessMax, LBMax, LBMin);
8985 LBVal = MaxLB.
get();
8989 SemaRef.
BuildBinOp(S, DefaultLoc, BO_Assign, IS.CounterVar, LBVal);
8992 LBVal = LBMinVal.
get();
8996 if (CondDependOnLC) {
8997 const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
8998 if (!IS.MinValue || !IS.MaxValue)
9007 IS.CounterVar, MinValue.
get());
9012 SemaRef.
BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.
get(), UBVal);
9027 IS.CounterVar, MaxValue.
get());
9032 SemaRef.
BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.
get(), UBVal);
9041 tryBuildCapture(SemaRef, UBMinVal.
get(), Captures,
".ub_min").get();
9043 tryBuildCapture(SemaRef, UBMaxVal.
get(), Captures,
".ub_max").get();
9044 if (!UBMin || !UBMax)
9048 SemaRef.
BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
9051 Expr *MinGreaterMax = tryBuildCapture(SemaRef, MinGreaterMaxRes.
get(),
9052 Captures,
".min_greater_max")
9056 if (*TestIsLessOp) {
9060 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
9063 UBVal = MaxUB.
get();
9068 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
9071 UBVal = MinUB.
get();
9074 Expr *UBExpr = *TestIsLessOp ? UBVal : LBVal;
9075 Expr *LBExpr = *TestIsLessOp ? LBVal : UBVal;
9076 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures,
".upper").get();
9077 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures,
".lower").get();
9078 if (!Upper || !Lower)
9081 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
9082 Step, VarType, TestIsStrictOp,
9091 C.getTypeSize(
Type) >
C.getTypeSize(VarType);
9094 UseVarType ?
C.getTypeSize(VarType) :
C.getTypeSize(
Type);
9097 Type =
C.getIntTypeForBitwidth(NewSize, IsSigned);
9106 unsigned NewSize = (
C.getTypeSize(
Type) > 32) ? 64 : 32;
9107 if (NewSize !=
C.getTypeSize(
Type)) {
9108 if (NewSize <
C.getTypeSize(
Type)) {
9109 assert(NewSize == 64 &&
"incorrect loop var size");
9110 SemaRef.
Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
9111 << InitSrcRange << ConditionSrcRange;
9113 QualType NewType =
C.getIntTypeForBitwidth(
9115 C.getTypeSize(
Type) < NewSize);
9128std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
9129 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const {
9133 return std::make_pair(
nullptr,
nullptr);
9136 Expr *MinExpr =
nullptr;
9137 Expr *MaxExpr =
nullptr;
9138 Expr *LBExpr = *TestIsLessOp ? LB : UB;
9139 Expr *UBExpr = *TestIsLessOp ? UB : LB;
9141 *TestIsLessOp ? InitDependOnLC.has_value() : CondDependOnLC.has_value();
9143 *TestIsLessOp ? CondDependOnLC.has_value() : InitDependOnLC.has_value();
9145 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
9147 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
9148 if (!Upper || !Lower)
9149 return std::make_pair(
nullptr,
nullptr);
9159 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
9160 Step, VarType, TestIsStrictOp,
9163 return std::make_pair(
nullptr,
nullptr);
9169 return std::make_pair(
nullptr,
nullptr);
9171 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures,
".new_step");
9173 return std::make_pair(
nullptr,
nullptr);
9174 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Mul, Diff.
get(), NewStep.
get());
9176 return std::make_pair(
nullptr,
nullptr);
9181 return std::make_pair(
nullptr,
nullptr);
9193 return std::make_pair(
nullptr,
nullptr);
9195 if (*TestIsLessOp) {
9199 S, DefaultLoc, BO_Add,
9203 return std::make_pair(
nullptr,
nullptr);
9208 S, DefaultLoc, BO_Sub,
9212 return std::make_pair(
nullptr,
nullptr);
9221 return std::make_pair(
nullptr,
nullptr);
9226 return std::make_pair(
nullptr,
nullptr);
9229 MaxExpr = Diff.
get();
9231 MinExpr = Diff.
get();
9233 return std::make_pair(MinExpr, MaxExpr);
9236Expr *OpenMPIterationSpaceChecker::buildFinalCondition(
Scope *S)
const {
9237 if (InitDependOnLC || CondDependOnLC)
9242Expr *OpenMPIterationSpaceChecker::buildPreCond(
9244 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const {
9249 if (CondDependOnLC || InitDependOnLC)
9260 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
9261 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
9267 *TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
9268 : (TestIsStrictOp ? BO_GT : BO_GE),
9269 NewLB.
get(), NewUB.
get());
9279 return CondExpr.
isUsable() ? CondExpr.
get() : Cond;
9283DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
9284 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
9285 DSAStackTy &DSA)
const {
9286 auto *VD = dyn_cast<VarDecl>(LCDecl);
9291 const DSAStackTy::DSAVarData
Data =
9292 DSA.getTopDSA(LCDecl,
false);
9296 Captures.insert(std::make_pair(LCRef, Ref));
9299 return cast<DeclRefExpr>(LCRef);
9302Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar()
const {
9308 isa<VarDecl>(LCDecl)
9319Expr *OpenMPIterationSpaceChecker::buildCounterInit()
const {
return LB; }
9322Expr *OpenMPIterationSpaceChecker::buildCounterStep()
const {
return Step; }
9324Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
9332 assert((OOK == OO_Plus || OOK == OO_Minus) &&
9333 "Expected only + or - operations for depend clauses.");
9345 *TestIsLessOp ? Cnt : tryBuildCapture(SemaRef, LB, Captures).get();
9347 *TestIsLessOp ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt;
9348 if (!Upper || !Lower)
9352 SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
9353 false,
false, Captures);
9363 assert(
getLangOpts().OpenMP &&
"OpenMP is not active.");
9364 assert(
Init &&
"Expected loop in canonical form.");
9365 unsigned AssociatedLoops =
DSAStack->getAssociatedLoops();
9366 if (AssociatedLoops > 0 &&
9369 OpenMPIterationSpaceChecker ISC(
SemaRef,
true,
9371 if (!ISC.checkAndSetInit(
Init,
false)) {
9373 auto *VD = dyn_cast<VarDecl>(D);
9381 VD = cast<VarDecl>(PrivateRef->
getDecl());
9384 DSAStack->addLoopControlVariable(D, VD);
9386 if (LD != D->getCanonicalDecl()) {
9387 DSAStack->resetPossibleLoopCounter();
9388 if (
auto *Var = dyn_cast_or_null<VarDecl>(LD))
9402 DSAStackTy::DSAVarData DVar =
9406 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
9409 ? (
DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
9412 DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
9413 (
getLangOpts().OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
9414 DVar.CKind != OMPC_private))) ||
9416 DKind == OMPD_master_taskloop || DKind == OMPD_masked_taskloop ||
9417 DKind == OMPD_parallel_master_taskloop ||
9418 DKind == OMPD_parallel_masked_taskloop ||
9421 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
9422 (DVar.CKind != OMPC_private || DVar.RefExpr)) {
9423 Diag(
Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
9424 << getOpenMPClauseName(DVar.CKind)
9425 << getOpenMPDirectiveName(DKind)
9426 << getOpenMPClauseName(PredeterminedCKind);
9427 if (DVar.RefExpr ==
nullptr)
9428 DVar.CKind = PredeterminedCKind;
9431 }
else if (LoopDeclRefExpr) {
9436 if (DVar.CKind == OMPC_unknown)
9437 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
9442 DSAStack->setAssociatedLoops(AssociatedLoops - 1);
9448class OMPDoacrossKind {
9451 return C->getDependenceType() == OMPC_DOACROSS_source ||
9452 C->getDependenceType() == OMPC_DOACROSS_source_omp_cur_iteration;
9455 return C->getDependenceType() == OMPC_DOACROSS_sink;
9458 return C->getDependenceType() == OMPC_DOACROSS_sink_omp_cur_iteration;
9466 unsigned CurrentNestedLoopCount,
unsigned NestedLoopCount,
9467 unsigned TotalNestedLoopCount,
Expr *CollapseLoopCountExpr,
9468 Expr *OrderedLoopCountExpr,
9471 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9476 if (
auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S))
9477 S = CanonLoop->getLoopStmt();
9478 auto *For = dyn_cast_or_null<ForStmt>(S);
9479 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
9481 if (!For && (SemaRef.
LangOpts.OpenMP <= 45 || !CXXFor)) {
9483 DSA.getMappedDirective() == OMPD_unknown)
9485 : DSA.getMappedDirective();
9486 SemaRef.
Diag(S->getBeginLoc(), diag::err_omp_not_for)
9487 << (CollapseLoopCountExpr !=
nullptr || OrderedLoopCountExpr !=
nullptr)
9488 << getOpenMPDirectiveName(DK) << TotalNestedLoopCount
9489 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
9490 if (TotalNestedLoopCount > 1) {
9491 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
9492 SemaRef.
Diag(DSA.getConstructLoc(),
9493 diag::note_omp_collapse_ordered_expr)
9496 else if (CollapseLoopCountExpr)
9498 diag::note_omp_collapse_ordered_expr)
9502 diag::note_omp_collapse_ordered_expr)
9507 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
9513 OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA,
9514 For ? For->getForLoc() : CXXFor->getForLoc());
9517 Stmt *
Init = For ? For->getInit() : CXXFor->getBeginStmt();
9518 if (ISC.checkAndSetInit(
Init))
9521 bool HasErrors =
false;
9524 if (
ValueDecl *LCDecl = ISC.getLoopDecl()) {
9534 SemaRef.
Diag(
Init->getBeginLoc(), diag::err_omp_loop_variable_type)
9548 VarsWithImplicitDSA.erase(LCDecl);
9553 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
9556 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
9563 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
9564 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
9565 ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
9566 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
9573 ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
9574 ISC.buildCounterVar(Captures, DSA);
9575 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
9576 ISC.buildPrivateCounterVar();
9577 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
9578 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
9579 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
9580 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
9581 ISC.getConditionSrcRange();
9582 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
9583 ISC.getIncrementSrcRange();
9584 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
9585 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
9586 ISC.isStrictTestOp();
9587 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
9588 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
9589 ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
9590 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
9591 ISC.buildFinalCondition(DSA.getCurScope());
9592 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
9593 ISC.doesInitDependOnLC();
9594 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
9595 ISC.doesCondDependOnLC();
9596 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
9597 ISC.getLoopDependentIdx();
9600 (ResultIterSpaces[CurrentNestedLoopCount].PreCond ==
nullptr ||
9601 ResultIterSpaces[CurrentNestedLoopCount].NumIterations ==
nullptr ||
9602 ResultIterSpaces[CurrentNestedLoopCount].CounterVar ==
nullptr ||
9603 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar ==
nullptr ||
9604 ResultIterSpaces[CurrentNestedLoopCount].CounterInit ==
nullptr ||
9605 ResultIterSpaces[CurrentNestedLoopCount].CounterStep ==
nullptr);
9606 if (!HasErrors && DSA.isOrderedRegion()) {
9607 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
9608 if (CurrentNestedLoopCount <
9609 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
9610 DSA.getOrderedRegionParam().second->setLoopNumIterations(
9611 CurrentNestedLoopCount,
9612 ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
9613 DSA.getOrderedRegionParam().second->setLoopCounter(
9614 CurrentNestedLoopCount,
9615 ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
9618 for (
auto &Pair : DSA.getDoacrossDependClauses()) {
9619 auto *DependC = dyn_cast<OMPDependClause>(Pair.first);
9620 auto *DoacrossC = dyn_cast<OMPDoacrossClause>(Pair.first);
9622 DependC ? DependC->getNumLoops() : DoacrossC->getNumLoops();
9623 if (CurrentNestedLoopCount >= NumLoops) {
9627 if (DependC && DependC->getDependencyKind() == OMPC_DEPEND_sink &&
9628 Pair.second.size() <= CurrentNestedLoopCount) {
9630 DependC->setLoopData(CurrentNestedLoopCount,
nullptr);
9633 OMPDoacrossKind ODK;
9634 if (DoacrossC && ODK.isSink(DoacrossC) &&
9635 Pair.second.size() <= CurrentNestedLoopCount) {
9637 DoacrossC->setLoopData(CurrentNestedLoopCount,
nullptr);
9642 DependC ? DependC->getDependencyLoc() : DoacrossC->getDependenceLoc();
9643 if ((DependC && DependC->getDependencyKind() == OMPC_DEPEND_source) ||
9644 (DoacrossC && ODK.isSource(DoacrossC)))
9645 CntValue = ISC.buildOrderedLoopData(
9647 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9649 else if (DoacrossC && ODK.isSinkIter(DoacrossC)) {
9652 ResultIterSpaces[CurrentNestedLoopCount].CounterVar)
9660 CntValue = ISC.buildOrderedLoopData(
9662 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9663 DepLoc, Inc, clang::OO_Minus);
9665 CntValue = ISC.buildOrderedLoopData(
9667 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9668 DepLoc, Pair.second[CurrentNestedLoopCount].first,
9669 Pair.second[CurrentNestedLoopCount].second);
9671 DependC->setLoopData(CurrentNestedLoopCount, CntValue);
9673 DoacrossC->setLoopData(CurrentNestedLoopCount, CntValue);
9684 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9688 : tryBuildCapture(SemaRef, Start.
get(), Captures);
9709 bool IsNonRectangularLB,
9710 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures =
nullptr) {
9719 NewStep = tryBuildCapture(SemaRef, Step.
get(), *Captures);
9734 if (Captures && !IsNonRectangularLB)
9735 NewStart = tryBuildCapture(SemaRef, Start.
get(), *Captures);
9744 Update.get()->getType()->isOverloadableType()) {
9751 SemaRef.
BuildBinOp(S,
Loc, Subtract ? BO_SubAssign : BO_AddAssign,
9752 VarRef.
get(), SavedUpdate.
get());
9763 NewStart.
get(), SavedUpdate.
get());
9787 unsigned HasBits =
C.getTypeSize(OldType);
9788 if (HasBits >= Bits)
9791 QualType NewType =
C.getIntTypeForBitwidth(Bits,
true);
9801 if (std::optional<llvm::APSInt>
Result =
9810 if (!PreInits.empty()) {
9821 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9822 if (!Captures.empty()) {
9824 for (
const auto &Pair : Captures)
9825 PreInits.push_back(Pair.second->getDecl());
9833 Expr *PostUpdate =
nullptr;
9834 if (!PostUpdates.empty()) {
9835 for (
Expr *E : PostUpdates) {
9841 PostUpdate = PostUpdate
9856 Expr *OrderedLoopCountExpr,
Stmt *AStmt,
Sema &SemaRef,
9860 unsigned NestedLoopCount = 1;
9861 bool SupportsNonPerfectlyNested = (SemaRef.
LangOpts.OpenMP >= 50) &&
9864 if (CollapseLoopCountExpr) {
9869 NestedLoopCount =
Result.Val.getInt().getLimitedValue();
9875 unsigned OrderedLoopCount = 1;
9876 if (OrderedLoopCountExpr) {
9883 if (
Result.getLimitedValue() < NestedLoopCount) {
9885 diag::err_omp_wrong_ordered_loop_count)
9888 diag::note_collapse_loop_count)
9891 OrderedLoopCount =
Result.getLimitedValue();
9899 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9900 unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount);
9904 SupportsNonPerfectlyNested, NumLoops,
9905 [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount,
9906 CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA,
9907 &IterSpaces, &Captures](
unsigned Cnt,
Stmt *CurStmt) {
9909 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
9910 NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr,
9911 VarsWithImplicitDSA, IterSpaces, Captures))
9913 if (Cnt > 0 && Cnt >= NestedLoopCount &&
9914 IterSpaces[Cnt].CounterVar) {
9916 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
9917 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
9918 Captures[DRE] = DRE;
9924 Stmt *DependentPreInits = Transform->getPreInits();
9925 if (!DependentPreInits)
9927 for (
Decl *
C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) {
9928 auto *D = cast<VarDecl>(
C);
9931 Captures[Ref] = Ref;
9936 Built.
clear( NestedLoopCount);
9939 return NestedLoopCount;
9972 auto PreCond =
ExprResult(IterSpaces[0].PreCond);
9973 Expr *N0 = IterSpaces[0].NumIterations;
9977 .PerformImplicitConversion(
9992 return NestedLoopCount;
9995 bool AllCountsNeedLessThan32Bits =
C.getTypeSize(N0->
getType()) < 32;
9997 Scope *CurScope = DSA.getCurScope();
9998 for (
unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
9999 if (PreCond.isUsable()) {
10001 SemaRef.
BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
10002 PreCond.get(), IterSpaces[Cnt].PreCond);
10004 Expr *N = IterSpaces[Cnt].NumIterations;
10006 AllCountsNeedLessThan32Bits &=
C.getTypeSize(N->
getType()) < 32;
10009 CurScope,
Loc, BO_Mul, LastIteration32.
get(),
10017 CurScope,
Loc, BO_Mul, LastIteration64.
get(),
10027 if (SemaRef.
getLangOpts().OpenMPOptimisticCollapse ||
10029 C.getTypeSize(LastIteration32.
get()->
getType()) == 32 &&
10030 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
10034 LastIteration64.
get(), SemaRef))))
10035 LastIteration = LastIteration32;
10054 LastIteration.
get(),
10066 tryBuildCapture(SemaRef, LastIteration.
get(), Captures);
10067 LastIteration = SaveRef;
10080 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
10109 buildVarDecl(SemaRef, InitLoc, StrideVType,
".omp.stride");
10118 UB.
get(), LastIteration.
get());
10121 LastIteration.
get(), UB.
get());
10122 EUB = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, UB.
get(),
10133 buildVarDecl(SemaRef, InitLoc, VType,
".omp.comb.lb");
10141 buildVarDecl(SemaRef, InitLoc, VType,
".omp.comb.ub");
10147 CurScope, InitLoc, BO_GT, CombUB.
get(), LastIteration.
get());
10150 LastIteration.
get(), CombUB.
get());
10151 CombEUB = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.
get(),
10156 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
10160 "Unexpected number of parameters in loop combined directive");
10201 SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, IV.
get(), CombRHS);
10207 bool UseStrictCompare =
10209 llvm::all_of(IterSpaces, [](
const LoopIterationSpace &LIS) {
10210 return LIS.IsStrictCompare;
10216 if (UseStrictCompare) {
10219 .
BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
10231 UseStrictCompare ? BO_LT : BO_LE, IV.
get(),
10234 NumIterations.
get());
10237 CombDistCond = SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LT, IV.
get(),
10238 NumIterations.
get());
10243 Expr *BoundCombUB = CombUB.
get();
10244 if (UseStrictCompare) {
10248 CurScope, CondLoc, BO_Add, BoundCombUB,
10256 SemaRef.
BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
10257 IV.
get(), BoundCombUB);
10264 if (!Inc.isUsable())
10266 Inc = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, IV.
get(), Inc.get());
10268 if (!Inc.isUsable())
10275 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
10281 NextLB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Add, LB.
get(), ST.
get());
10292 NextUB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Add, UB.
get(), ST.
get());
10308 CombNextLB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.
get(),
10320 CombNextUB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.
get(),
10334 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
10337 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.
get(), BoundUB);
10338 assert(DistCond.
isUsable() &&
"distribute cond expr was not built");
10342 assert(DistInc.
isUsable() &&
"distribute inc expr was not built");
10343 DistInc = SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.
get(),
10347 assert(DistInc.
isUsable() &&
"distribute inc expr was not built");
10358 DistEUBLoc, NewPrevUB.
get());
10363 UB.
get(), NewPrevUB.
get());
10365 DistEUBLoc, DistEUBLoc, IsUBGreater.
get(), NewPrevUB.
get(), UB.
get());
10366 PrevEUB = SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.
get(),
10374 Expr *BoundPrevUB = PrevUB.
get();
10375 if (UseStrictCompare) {
10379 CurScope, CondLoc, BO_Add, BoundPrevUB,
10387 SemaRef.
BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
10388 IV.
get(), BoundPrevUB);
10392 bool HasErrors =
false;
10393 Built.
Counters.resize(NestedLoopCount);
10394 Built.
Inits.resize(NestedLoopCount);
10395 Built.
Updates.resize(NestedLoopCount);
10396 Built.
Finals.resize(NestedLoopCount);
10417 for (
unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
10418 LoopIterationSpace &IS = IterSpaces[Cnt];
10424 for (
unsigned int K = Cnt + 1; K < NestedLoopCount; ++K)
10425 Prod = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.
get(),
10426 IterSpaces[K].NumIterations);
10431 if (Cnt + 1 < NestedLoopCount)
10436 if (!
Iter.isUsable()) {
10445 if (Cnt + 1 < NestedLoopCount)
10450 Acc = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Sub, Acc.
get(), Prod.
get());
10453 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
10455 SemaRef, VD, IS.CounterVar->
getType(), IS.CounterVar->getExprLoc(),
10459 IS.CounterInit, IS.IsNonRectangularLB, Captures);
10460 if (!
Init.isUsable()) {
10465 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
Iter,
10466 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
10467 if (!
Update.isUsable()) {
10475 IS.CounterInit, IS.NumIterations, IS.CounterStep,
10476 IS.Subtract, IS.IsNonRectangularLB, &Captures);
10477 if (!Final.isUsable()) {
10482 if (!
Update.isUsable() || !Final.isUsable()) {
10487 Built.
Counters[Cnt] = IS.CounterVar;
10491 Built.
Finals[Cnt] = Final.get();
10495 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
10514 Built.
PreCond = PreCond.get();
10518 Built.
Inc = Inc.get();
10519 Built.
LB = LB.
get();
10520 Built.
UB = UB.
get();
10521 Built.
IL = IL.
get();
10522 Built.
ST = ST.
get();
10524 Built.
NLB = NextLB.
get();
10525 Built.
NUB = NextUB.
get();
10540 return NestedLoopCount;
10544 auto CollapseClauses =
10545 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
10546 if (CollapseClauses.begin() != CollapseClauses.end())
10547 return (*CollapseClauses.begin())->getNumForLoops();
10552 auto OrderedClauses =
10553 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
10554 if (OrderedClauses.begin() != OrderedClauses.end())
10555 return (*OrderedClauses.begin())->getNumForLoops();
10564 for (
const OMPClause *Clause : Clauses) {
10566 Safelen = cast<OMPSafelenClause>(Clause);
10568 Simdlen = cast<OMPSimdlenClause>(Clause);
10569 if (Safelen && Simdlen)
10573 if (Simdlen && Safelen) {
10587 llvm::APSInt SimdlenRes = SimdlenResult.
Val.
getInt();
10588 llvm::APSInt SafelenRes = SafelenResult.
Val.
getInt();
10593 if (SimdlenRes > SafelenRes) {
10595 diag::err_omp_wrong_simdlen_safelen_values)
10605 DSAStackTy *Stack);
10607bool SemaOpenMP::checkLastPrivateForMappedDirectives(
10615 DSAStack->getMappedDirective() == OMPD_loop &&
10628 if (!checkLastPrivateForMappedDirectives(Clauses))
10631 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
10638 if (NestedLoopCount == 0)
10642 "omp simd loop exprs were not built");
10647 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
10660 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10662 return SimdDirective;
10671 if (!checkLastPrivateForMappedDirectives(Clauses))
10674 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
10681 if (NestedLoopCount == 0)
10685 "omp for loop exprs were not built");
10690 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
10699 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10702 return ForDirective;
10711 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
10715 unsigned NestedLoopCount =
10718 VarsWithImplicitDSA, B);
10719 if (NestedLoopCount == 0)
10723 "omp for simd loop exprs were not built");
10728 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
10741 NestedLoopCount, Clauses, AStmt, B);
10751 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
10752 auto BaseStmt = AStmt;
10753 while (
auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10755 if (
auto *
C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10756 auto S =
C->children();
10757 if (S.begin() == S.end())
10761 for (
Stmt *SectionStmt : llvm::drop_begin(S)) {
10762 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10764 Diag(SectionStmt->getBeginLoc(),
10765 diag::err_omp_sections_substmt_not_section);
10768 cast<OMPSectionDirective>(SectionStmt)
10769 ->setHasCancel(
DSAStack->isCancelRegion());
10772 Diag(AStmt->
getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
10798 if (
auto *CE = dyn_cast<CallExpr>(E))
10799 if (CE->getDirectCallee())
10811 Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt();
10821 Expr *TargetCall =
nullptr;
10823 auto *E = dyn_cast<Expr>(S);
10825 Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10831 if (
auto *BO = dyn_cast<BinaryOperator>(E)) {
10832 if (BO->getOpcode() == BO_Assign)
10835 if (
auto *COCE = dyn_cast<CXXOperatorCallExpr>(E))
10836 if (COCE->getOperator() == OO_Equal)
10851 Clauses, AStmt, TargetCallLoc);
10856 DSAStackTy *Stack) {
10857 bool ErrorFound =
false;
10859 if (
auto *LPC = dyn_cast<OMPLastprivateClause>(
C)) {
10860 for (
Expr *RefExpr : LPC->varlists()) {
10863 Expr *SimpleRefExpr = RefExpr;
10866 auto &&Info = Stack->isLoopControlVariable(D);
10868 S.
Diag(ELoc, diag::err_omp_lastprivate_loop_var_non_loop_iteration)
10869 << getOpenMPDirectiveName(K);
10891 auto *CS = cast<CapturedStmt>(AStmt);
10904 if (NestedLoopCount == 0)
10908 "omp loop exprs were not built");
10912 NestedLoopCount, Clauses, AStmt, B);
10927 auto *CS = cast<CapturedStmt>(AStmt);
10935 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10947 unsigned NestedLoopCount =
10950 VarsWithImplicitDSA, B);
10951 if (NestedLoopCount == 0)
10955 "omp loop exprs were not built");
10958 DSAStack->setParentTeamsRegionLoc(StartLoc);
10961 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10977 auto *CS = cast<CapturedStmt>(AStmt);
10985 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10997 unsigned NestedLoopCount =
11000 VarsWithImplicitDSA, B);
11001 if (NestedLoopCount == 0)
11005 "omp loop exprs were not built");
11010 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11027 auto *CS = cast<CapturedStmt>(AStmt);
11035 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11047 unsigned NestedLoopCount =
11050 VarsWithImplicitDSA, B);
11051 if (NestedLoopCount == 0)
11055 "omp loop exprs were not built");
11060 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11076 auto *CS = cast<CapturedStmt>(AStmt);
11084 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11096 unsigned NestedLoopCount =
11099 VarsWithImplicitDSA, B);
11100 if (NestedLoopCount == 0)
11104 "omp loop exprs were not built");
11109 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11119 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
11126 const OMPClause *Copyprivate =
nullptr;
11127 for (
const OMPClause *Clause : Clauses) {
11131 Copyprivate = Clause;
11132 if (Copyprivate && Nowait) {
11134 diag::err_omp_single_copyprivate_with_nowait);
11174 bool ErrorFound =
false;
11177 bool DependentHint =
false;
11179 if (
C->getClauseKind() == OMPC_hint) {
11181 Diag(
C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
11184 Expr *E = cast<OMPHintClause>(
C)->getHint();
11187 DependentHint =
true;
11190 HintLoc =
C->getBeginLoc();
11196 const auto Pair =
DSAStack->getCriticalWithHint(DirName);
11197 if (Pair.first && DirName.
getName() && !DependentHint) {
11198 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
11199 Diag(StartLoc, diag::err_omp_critical_with_hint);
11201 Diag(HintLoc, diag::note_omp_critical_hint_here)
11202 << 0 <<
toString(Hint, 10,
false);
11204 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
11205 if (
const auto *
C = Pair.first->getSingleClause<
OMPHintClause>()) {
11206 Diag(
C->getBeginLoc(), diag::note_omp_critical_hint_here)
11211 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
11219 EndLoc, Clauses, AStmt);
11220 if (!Pair.first && DirName.
getName() && !DependentHint)
11221 DSAStack->addCriticalWithHint(Dir, Hint);
11231 auto *CS = cast<CapturedStmt>(AStmt);
11242 unsigned NestedLoopCount =
11245 VarsWithImplicitDSA, B);
11246 if (NestedLoopCount == 0)
11250 "omp parallel for loop exprs were not built");
11255 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
11265 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11275 auto *CS = cast<CapturedStmt>(AStmt);
11286 unsigned NestedLoopCount =
11289 VarsWithImplicitDSA, B);
11290 if (NestedLoopCount == 0)
11296 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
11309 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11318 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
11319 auto *CS = cast<CapturedStmt>(AStmt);
11331 DSAStack->getTaskgroupReductionRef());
11340 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
11341 auto *CS = cast<CapturedStmt>(AStmt);
11353 DSAStack->getTaskgroupReductionRef());
11362 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
11363 auto BaseStmt = AStmt;
11364 while (
auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
11366 if (
auto *
C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
11367 auto S =
C->children();
11368 if (S.begin() == S.end())
11372 for (
Stmt *SectionStmt : llvm::drop_begin(S)) {
11373 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
11375 Diag(SectionStmt->getBeginLoc(),
11376 diag::err_omp_parallel_sections_substmt_not_section);
11379 cast<OMPSectionDirective>(SectionStmt)
11380 ->setHasCancel(
DSAStack->isCancelRegion());
11384 diag::err_omp_parallel_sections_not_compound_stmt);
11400 bool ErrorFound =
false;
11402 if (llvm::is_contained(MutuallyExclusiveClauses,
C->getClauseKind())) {
11406 S.
Diag(
C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
11407 << getOpenMPClauseName(
C->getClauseKind())
11429 {OMPC_detach, OMPC_mergeable}))
11432 auto *CS = cast<CapturedStmt>(AStmt);
11443 AStmt,
DSAStack->isCancelRegion());
11459 bool InExContext) {
11461 OMPExecutableDirective::getSingleClause<OMPAtClause>(Clauses);
11463 if (AtC && !InExContext && AtC->
getAtKind() == OMPC_AT_execution) {
11469 OMPExecutableDirective::getSingleClause<OMPSeverityClause>(Clauses);
11471 OMPExecutableDirective::getSingleClause<OMPMessageClause>(Clauses);
11474 if (!AtC || AtC->
getAtKind() == OMPC_AT_compilation) {
11475 if (SeverityC && SeverityC->
getSeverityKind() == OMPC_SEVERITY_warning)
11477 << (ME ? cast<StringLiteral>(ME)->getString() :
"WARNING");
11479 Diag(StartLoc, diag::err_diagnose_if_succeeded)
11480 << (ME ? cast<StringLiteral>(ME)->getString() :
"ERROR");
11481 if (!SeverityC || SeverityC->
getSeverityKind() != OMPC_SEVERITY_warning)
11492 OMPExecutableDirective::getSingleClause<OMPNowaitClause>(Clauses);
11494 !OMPExecutableDirective::getClausesOfKind<OMPDependClause>(Clauses)
11496 if (NowaitC && !HasDependC) {
11497 Diag(StartLoc, diag::err_omp_nowait_clause_without_depend);
11512 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
11518 DSAStack->getTaskgroupReductionRef());
11527 if (
C->getClauseKind() == OMPC_flush)
11528 FC = cast<OMPFlushClause>(
C);
11535 if (
C->getClauseKind() == OMPC_acq_rel ||
11536 C->getClauseKind() == OMPC_acquire ||
11537 C->getClauseKind() == OMPC_release) {
11538 if (MemOrderKind != OMPC_unknown) {
11539 Diag(
C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
11540 << getOpenMPDirectiveName(OMPD_flush) << 1
11542 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
11543 << getOpenMPClauseName(MemOrderKind);
11545 MemOrderKind =
C->getClauseKind();
11546 MemOrderLoc =
C->getBeginLoc();
11550 if (FC && OrderClause) {
11553 Diag(OrderClause->
getBeginLoc(), diag::note_omp_flush_order_clause_here)
11563 if (Clauses.empty()) {
11564 Diag(StartLoc, diag::err_omp_depobj_expected);
11566 }
else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
11567 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
11571 if (Clauses.size() > 2) {
11572 Diag(Clauses[2]->getBeginLoc(),
11573 diag::err_omp_depobj_single_clause_expected);
11575 }
else if (Clauses.size() < 1) {
11576 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
11586 if (Clauses.size() != 1) {
11587 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
11588 diag::err_omp_scan_single_clause_expected);
11593 Scope *ParentS = S->getParent();
11596 return StmtError(
Diag(StartLoc, diag::err_omp_orphaned_device_directive)
11597 << getOpenMPDirectiveName(OMPD_scan) << 5);
11601 if (
DSAStack->doesParentHasScanDirective()) {
11602 Diag(StartLoc, diag::err_omp_several_directives_in_region) <<
"scan";
11604 diag::note_omp_previous_directive)
11608 DSAStack->setParentHasScanDirective(StartLoc);
11616 const OMPClause *DependFound =
nullptr;
11617 const OMPClause *DependSourceClause =
nullptr;
11618 const OMPClause *DependSinkClause =
nullptr;
11619 const OMPClause *DoacrossFound =
nullptr;
11620 const OMPClause *DoacrossSourceClause =
nullptr;
11621 const OMPClause *DoacrossSinkClause =
nullptr;
11622 bool ErrorFound =
false;
11626 auto DOC = dyn_cast<OMPDoacrossClause>(
C);
11627 auto DC = dyn_cast<OMPDependClause>(
C);
11629 DependFound = DC ?
C :
nullptr;
11630 DoacrossFound = DOC ?
C :
nullptr;
11631 OMPDoacrossKind ODK;
11632 if ((DC && DC->getDependencyKind() == OMPC_DEPEND_source) ||
11633 (DOC && (ODK.isSource(DOC)))) {
11634 if ((DC && DependSourceClause) || (DOC && DoacrossSourceClause)) {
11635 Diag(
C->getBeginLoc(), diag::err_omp_more_one_clause)
11636 << getOpenMPDirectiveName(OMPD_ordered)
11637 << getOpenMPClauseName(DC ? OMPC_depend : OMPC_doacross) << 2;
11641 DependSourceClause =
C;
11643 DoacrossSourceClause =
C;
11645 if ((DC && DependSinkClause) || (DOC && DoacrossSinkClause)) {
11646 Diag(
C->getBeginLoc(), diag::err_omp_sink_and_source_not_allowed)
11647 << (DC ?
"depend" :
"doacross") << 0;
11650 }
else if ((DC && DC->getDependencyKind() == OMPC_DEPEND_sink) ||
11651 (DOC && (ODK.isSink(DOC) || ODK.isSinkIter(DOC)))) {
11652 if (DependSourceClause || DoacrossSourceClause) {
11653 Diag(
C->getBeginLoc(), diag::err_omp_sink_and_source_not_allowed)
11654 << (DC ?
"depend" :
"doacross") << 1;
11658 DependSinkClause =
C;
11660 DoacrossSinkClause =
C;
11662 }
else if (
C->getClauseKind() == OMPC_threads) {
11663 TC = cast<OMPThreadsClause>(
C);
11664 }
else if (
C->getClauseKind() == OMPC_simd) {
11665 SC = cast<OMPSIMDClause>(
C);
11668 if (!ErrorFound && !SC &&
11673 Diag(StartLoc, diag::err_omp_prohibited_region_simd)
11676 }
else if ((DependFound || DoacrossFound) && (TC || SC)) {
11679 Diag(
Loc, diag::err_omp_depend_clause_thread_simd)
11680 << getOpenMPClauseName(DependFound ? OMPC_depend : OMPC_doacross)
11683 }
else if ((DependFound || DoacrossFound) &&
11684 !
DSAStack->getParentOrderedRegionParam().first) {
11687 Diag(
Loc, diag::err_omp_ordered_directive_without_param)
11688 << getOpenMPClauseName(DependFound ? OMPC_depend : OMPC_doacross);
11690 }
else if (TC || Clauses.empty()) {
11691 if (
const Expr *Param =
DSAStack->getParentOrderedRegionParam().first) {
11693 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
11694 << (TC !=
nullptr);
11699 if ((!AStmt && !DependFound && !DoacrossFound) || ErrorFound)
11707 if (!DependFound && !DoacrossFound) {
11708 if (
DSAStack->doesParentHasOrderedDirective()) {
11709 Diag(StartLoc, diag::err_omp_several_directives_in_region) <<
"ordered";
11711 diag::note_omp_previous_directive)
11715 DSAStack->setParentHasOrderedDirective(StartLoc);
11719 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
11731class OpenMPAtomicUpdateChecker {
11733 enum ExprAnalysisErrorCode {
11737 NotABinaryOrUnaryExpression,
11739 NotAnUnaryIncDecExpression,
11745 NotABinaryExpression,
11748 NotABinaryOperator,
11751 NotAnUpdateExpression,
11754 NotAValidExpression,
11772 bool IsXLHSInRHSPart;
11777 bool IsPostfixUpdate;
11780 OpenMPAtomicUpdateChecker(
Sema &SemaRef)
11781 : SemaRef(SemaRef),
X(nullptr), E(nullptr), UpdateExpr(nullptr),
11782 IsXLHSInRHSPart(
false), Op(BO_PtrMemD), IsPostfixUpdate(
false) {}
11790 bool checkStatement(
Stmt *S,
unsigned DiagId = 0,
unsigned NoteId = 0);
11792 Expr *getX()
const {
return X; }
11794 Expr *getExpr()
const {
return E; }
11798 Expr *getUpdateExpr()
const {
return UpdateExpr; }
11801 bool isXLHSInRHSPart()
const {
return IsXLHSInRHSPart; }
11805 bool isPostfixUpdate()
const {
return IsPostfixUpdate; }
11808 bool checkBinaryOperation(
BinaryOperator *AtomicBinOp,
unsigned DiagId = 0,
11809 unsigned NoteId = 0);
11812bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
11813 BinaryOperator *AtomicBinOp,
unsigned DiagId,
unsigned NoteId) {
11814 ExprAnalysisErrorCode ErrorFound = NoError;
11820 if (AtomicBinOp->
getOpcode() == BO_Assign) {
11822 if (
const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
11824 if (AtomicInnerBinOp->isMultiplicativeOp() ||
11825 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
11826 AtomicInnerBinOp->isBitwiseOp()) {
11827 Op = AtomicInnerBinOp->getOpcode();
11828 OpLoc = AtomicInnerBinOp->getOperatorLoc();
11829 Expr *LHS = AtomicInnerBinOp->getLHS();
11830 Expr *RHS = AtomicInnerBinOp->getRHS();
11831 llvm::FoldingSetNodeID XId, LHSId, RHSId;
11838 if (XId == LHSId) {
11840 IsXLHSInRHSPart =
true;
11841 }
else if (XId == RHSId) {
11843 IsXLHSInRHSPart =
false;
11845 ErrorLoc = AtomicInnerBinOp->getExprLoc();
11846 ErrorRange = AtomicInnerBinOp->getSourceRange();
11847 NoteLoc =
X->getExprLoc();
11848 NoteRange =
X->getSourceRange();
11849 ErrorFound = NotAnUpdateExpression;
11852 ErrorLoc = AtomicInnerBinOp->getExprLoc();
11853 ErrorRange = AtomicInnerBinOp->getSourceRange();
11854 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
11856 ErrorFound = NotABinaryOperator;
11861 ErrorFound = NotABinaryExpression;
11868 ErrorFound = NotAnAssignmentOp;
11870 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11871 SemaRef.
Diag(ErrorLoc, DiagId) << ErrorRange;
11872 SemaRef.
Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11876 E =
X = UpdateExpr =
nullptr;
11877 return ErrorFound != NoError;
11880bool OpenMPAtomicUpdateChecker::checkStatement(
Stmt *S,
unsigned DiagId,
11882 ExprAnalysisErrorCode ErrorFound = NoError;
11893 if (
auto *AtomicBody = dyn_cast<Expr>(S)) {
11894 AtomicBody = AtomicBody->IgnoreParenImpCasts();
11895 if (AtomicBody->getType()->isScalarType() ||
11896 AtomicBody->isInstantiationDependent()) {
11897 if (
const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
11898 AtomicBody->IgnoreParenImpCasts())) {
11901 AtomicCompAssignOp->getOpcode());
11902 OpLoc = AtomicCompAssignOp->getOperatorLoc();
11903 E = AtomicCompAssignOp->getRHS();
11904 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
11905 IsXLHSInRHSPart =
true;
11906 }
else if (
auto *AtomicBinOp = dyn_cast<BinaryOperator>(
11907 AtomicBody->IgnoreParenImpCasts())) {
11909 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
11911 }
else if (
const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
11912 AtomicBody->IgnoreParenImpCasts())) {
11914 if (AtomicUnaryOp->isIncrementDecrementOp()) {
11915 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
11916 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
11917 OpLoc = AtomicUnaryOp->getOperatorLoc();
11918 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
11920 IsXLHSInRHSPart =
true;
11922 ErrorFound = NotAnUnaryIncDecExpression;
11923 ErrorLoc = AtomicUnaryOp->getExprLoc();
11924 ErrorRange = AtomicUnaryOp->getSourceRange();
11925 NoteLoc = AtomicUnaryOp->getOperatorLoc();
11928 }
else if (!AtomicBody->isInstantiationDependent()) {
11929 ErrorFound = NotABinaryOrUnaryExpression;
11930 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
11931 NoteRange = ErrorRange = AtomicBody->getSourceRange();
11932 }
else if (AtomicBody->containsErrors()) {
11933 ErrorFound = NotAValidExpression;
11934 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
11935 NoteRange = ErrorRange = AtomicBody->getSourceRange();
11938 ErrorFound = NotAScalarType;
11939 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
11940 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
11943 ErrorFound = NotAnExpression;
11944 NoteLoc = ErrorLoc = S->getBeginLoc();
11945 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
11947 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11948 SemaRef.
Diag(ErrorLoc, DiagId) << ErrorRange;
11949 SemaRef.
Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11953 E =
X = UpdateExpr =
nullptr;
11954 if (ErrorFound == NoError && E &&
X) {
11964 IsXLHSInRHSPart ? OVEExpr : OVEX);
11971 UpdateExpr =
Update.get();
11973 return ErrorFound != NoError;
11977llvm::FoldingSetNodeID getNodeId(
ASTContext &Context,
const Expr *S) {
11978 llvm::FoldingSetNodeID
Id;
11979 S->IgnoreParenImpCasts()->Profile(
Id, Context,
true);
11984bool checkIfTwoExprsAreSame(
ASTContext &Context,
const Expr *LHS,
11986 return getNodeId(Context, LHS) == getNodeId(Context, RHS);
11989class OpenMPAtomicCompareChecker {
12036 struct ErrorInfoTy {
12044 OpenMPAtomicCompareChecker(
Sema &S) : ContextRef(S.getASTContext()) {}
12047 bool checkStmt(
Stmt *S, ErrorInfoTy &ErrorInfo);
12049 Expr *getX()
const {
return X; }
12050 Expr *getE()
const {
return E; }
12051 Expr *getD()
const {
return D; }
12052 Expr *getCond()
const {
return C; }
12053 bool isXBinopExpr()
const {
return IsXBinopExpr; }
12072 bool IsXBinopExpr =
true;
12075 bool checkCondUpdateStmt(
IfStmt *S, ErrorInfoTy &ErrorInfo);
12078 bool checkCondExprStmt(
Stmt *S, ErrorInfoTy &ErrorInfo);
12081 bool checkType(ErrorInfoTy &ErrorInfo)
const;
12083 static bool CheckValue(
const Expr *E, ErrorInfoTy &ErrorInfo,
12084 bool ShouldBeLValue,
bool ShouldBeInteger =
false) {
12088 if (ShouldBeLValue && !E->
isLValue()) {
12089 ErrorInfo.Error = ErrorTy::XNotLValue;
12090 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->
getExprLoc();
12091 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->
getSourceRange();
12097 ErrorInfo.Error = ErrorTy::NotScalar;
12098 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->
getExprLoc();
12099 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->
getSourceRange();
12103 ErrorInfo.Error = ErrorTy::NotInteger;
12104 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->
getExprLoc();
12105 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->
getSourceRange();
12113bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(
IfStmt *S,
12114 ErrorInfoTy &ErrorInfo) {
12115 auto *Then = S->getThen();
12116 if (
auto *CS = dyn_cast<CompoundStmt>(Then)) {
12117 if (CS->body_empty()) {
12118 ErrorInfo.Error = ErrorTy::NoStmt;
12119 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12120 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12123 if (CS->size() > 1) {
12124 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12125 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12126 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12129 Then = CS->body_front();
12132 auto *BO = dyn_cast<BinaryOperator>(Then);
12134 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12135 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
12136 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
12139 if (BO->getOpcode() != BO_Assign) {
12140 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12141 ErrorInfo.ErrorLoc = BO->getExprLoc();
12142 ErrorInfo.NoteLoc = BO->getOperatorLoc();
12143 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12149 auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
12151 ErrorInfo.Error = ErrorTy::NotABinaryOp;
12152 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
12153 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
12157 switch (Cond->getOpcode()) {
12161 if (checkIfTwoExprsAreSame(ContextRef,
X, Cond->getLHS())) {
12162 E = Cond->getRHS();
12163 }
else if (checkIfTwoExprsAreSame(ContextRef,
X, Cond->getRHS())) {
12164 E = Cond->getLHS();
12166 ErrorInfo.Error = ErrorTy::InvalidComparison;
12167 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->
getExprLoc();
12168 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
12176 if (checkIfTwoExprsAreSame(ContextRef,
X, Cond->getLHS()) &&
12177 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
12179 }
else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
12180 checkIfTwoExprsAreSame(ContextRef,
X, Cond->getRHS())) {
12182 IsXBinopExpr =
false;
12184 ErrorInfo.Error = ErrorTy::InvalidComparison;
12185 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->
getExprLoc();
12186 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
12192 ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
12193 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->
getExprLoc();
12194 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
12198 if (S->getElse()) {
12199 ErrorInfo.Error = ErrorTy::UnexpectedElse;
12200 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc();
12201 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getElse()->getSourceRange();
12208bool OpenMPAtomicCompareChecker::checkCondExprStmt(
Stmt *S,
12209 ErrorInfoTy &ErrorInfo) {
12210 auto *BO = dyn_cast<BinaryOperator>(S);
12212 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12213 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12214 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12217 if (BO->getOpcode() != BO_Assign) {
12218 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12219 ErrorInfo.ErrorLoc = BO->getExprLoc();
12220 ErrorInfo.NoteLoc = BO->getOperatorLoc();
12221 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12227 auto *CO = dyn_cast<ConditionalOperator>(BO->getRHS()->IgnoreParenImpCasts());
12229 ErrorInfo.Error = ErrorTy::NotCondOp;
12230 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getRHS()->getExprLoc();
12231 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getRHS()->getSourceRange();
12235 if (!checkIfTwoExprsAreSame(ContextRef,
X, CO->getFalseExpr())) {
12236 ErrorInfo.Error = ErrorTy::WrongFalseExpr;
12237 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getFalseExpr()->getExprLoc();
12238 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12239 CO->getFalseExpr()->getSourceRange();
12243 auto *Cond = dyn_cast<BinaryOperator>(CO->getCond());
12245 ErrorInfo.Error = ErrorTy::NotABinaryOp;
12246 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getCond()->getExprLoc();
12247 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12248 CO->getCond()->getSourceRange();
12252 switch (Cond->getOpcode()) {
12255 D = CO->getTrueExpr();
12256 if (checkIfTwoExprsAreSame(ContextRef,
X, Cond->getLHS())) {
12257 E = Cond->getRHS();
12258 }
else if (checkIfTwoExprsAreSame(ContextRef,
X, Cond->getRHS())) {
12259 E = Cond->getLHS();
12261 ErrorInfo.Error = ErrorTy::InvalidComparison;
12262 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->
getExprLoc();
12263 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
12270 E = CO->getTrueExpr();
12271 if (checkIfTwoExprsAreSame(ContextRef,
X, Cond->getLHS()) &&
12272 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
12274 }
else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
12275 checkIfTwoExprsAreSame(ContextRef,
X, Cond->getRHS())) {
12277 IsXBinopExpr =
false;
12279 ErrorInfo.Error = ErrorTy::InvalidComparison;
12280 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->
getExprLoc();
12281 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
12287 ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
12288 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->
getExprLoc();
12289 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
12296bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo)
const {
12298 assert(
X && E &&
"X and E cannot be nullptr");
12300 if (!CheckValue(
X, ErrorInfo,
true))
12303 if (!CheckValue(E, ErrorInfo,
false))
12306 if (D && !CheckValue(D, ErrorInfo,
false))
12312bool OpenMPAtomicCompareChecker::checkStmt(
12313 Stmt *S, OpenMPAtomicCompareChecker::ErrorInfoTy &ErrorInfo) {
12314 auto *CS = dyn_cast<CompoundStmt>(S);
12316 if (CS->body_empty()) {
12317 ErrorInfo.Error = ErrorTy::NoStmt;
12318 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12319 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12323 if (CS->size() != 1) {
12324 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12325 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12326 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12329 S = CS->body_front();
12334 if (
auto *IS = dyn_cast<IfStmt>(S)) {
12340 Res = checkCondUpdateStmt(IS, ErrorInfo);
12346 Res = checkCondExprStmt(S, ErrorInfo);
12352 return checkType(ErrorInfo);
12355class OpenMPAtomicCompareCaptureChecker final
12356 :
public OpenMPAtomicCompareChecker {
12358 OpenMPAtomicCompareCaptureChecker(
Sema &S) : OpenMPAtomicCompareChecker(S) {}
12360 Expr *getV()
const {
return V; }
12361 Expr *getR()
const {
return R; }
12362 bool isFailOnly()
const {
return IsFailOnly; }
12363 bool isPostfixUpdate()
const {
return IsPostfixUpdate; }
12366 bool checkStmt(
Stmt *S, ErrorInfoTy &ErrorInfo);
12369 bool checkType(ErrorInfoTy &ErrorInfo);
12381 bool checkForm3(
IfStmt *S, ErrorInfoTy &ErrorInfo);
12385 bool checkForm45(
Stmt *S, ErrorInfoTy &ErrorInfo);
12392 bool IsFailOnly =
false;
12394 bool IsPostfixUpdate =
false;
12397bool OpenMPAtomicCompareCaptureChecker::checkType(ErrorInfoTy &ErrorInfo) {
12398 if (!OpenMPAtomicCompareChecker::checkType(ErrorInfo))
12401 if (
V && !CheckValue(
V, ErrorInfo,
true))
12404 if (R && !CheckValue(R, ErrorInfo,
true,
true))
12410bool OpenMPAtomicCompareCaptureChecker::checkForm3(
IfStmt *S,
12411 ErrorInfoTy &ErrorInfo) {
12414 auto *Then = S->getThen();
12415 if (
auto *CS = dyn_cast<CompoundStmt>(Then)) {
12416 if (CS->body_empty()) {
12417 ErrorInfo.Error = ErrorTy::NoStmt;
12418 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12419 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12422 if (CS->size() > 1) {
12423 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12424 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12425 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12428 Then = CS->body_front();
12431 auto *BO = dyn_cast<BinaryOperator>(Then);
12433 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12434 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
12435 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
12438 if (BO->getOpcode() != BO_Assign) {
12439 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12440 ErrorInfo.ErrorLoc = BO->getExprLoc();
12441 ErrorInfo.NoteLoc = BO->getOperatorLoc();
12442 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12449 auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
12451 ErrorInfo.Error = ErrorTy::NotABinaryOp;
12452 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
12453 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
12456 if (Cond->getOpcode() != BO_EQ) {
12457 ErrorInfo.Error = ErrorTy::NotEQ;
12458 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->
getExprLoc();
12459 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
12463 if (checkIfTwoExprsAreSame(ContextRef,
X, Cond->getLHS())) {
12464 E = Cond->getRHS();
12465 }
else if (checkIfTwoExprsAreSame(ContextRef,
X, Cond->getRHS())) {
12466 E = Cond->getLHS();
12468 ErrorInfo.Error = ErrorTy::InvalidComparison;
12469 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->
getExprLoc();
12470 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
12476 if (!S->getElse()) {
12477 ErrorInfo.Error = ErrorTy::NoElse;
12478 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12479 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12483 auto *Else = S->getElse();
12484 if (
auto *CS = dyn_cast<CompoundStmt>(Else)) {
12485 if (CS->body_empty()) {
12486 ErrorInfo.Error = ErrorTy::NoStmt;
12487 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12488 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12491 if (CS->size() > 1) {
12492 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12493 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12494 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12497 Else = CS->body_front();
12500 auto *ElseBO = dyn_cast<BinaryOperator>(Else);
12502 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12503 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
12504 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
12507 if (ElseBO->getOpcode() != BO_Assign) {
12508 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12509 ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
12510 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12511 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12515 if (!checkIfTwoExprsAreSame(ContextRef,
X, ElseBO->getRHS())) {
12516 ErrorInfo.Error = ErrorTy::InvalidAssignment;
12517 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseBO->getRHS()->getExprLoc();
12518 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12519 ElseBO->getRHS()->getSourceRange();
12523 V = ElseBO->getLHS();
12525 return checkType(ErrorInfo);
12528bool OpenMPAtomicCompareCaptureChecker::checkForm45(
Stmt *S,
12529 ErrorInfoTy &ErrorInfo) {
12532 auto *CS = cast<CompoundStmt>(S);
12533 assert(CS->size() == 2 &&
"CompoundStmt size is not expected");
12534 auto *S1 = cast<BinaryOperator>(CS->body_front());
12535 auto *S2 = cast<IfStmt>(CS->body_back());
12536 assert(S1->getOpcode() == BO_Assign &&
"unexpected binary operator");
12538 if (!checkIfTwoExprsAreSame(ContextRef, S1->getLHS(), S2->getCond())) {
12539 ErrorInfo.Error = ErrorTy::InvalidCondition;
12540 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getCond()->getExprLoc();
12541 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S1->getLHS()->getSourceRange();
12547 auto *Then = S2->getThen();
12548 if (
auto *ThenCS = dyn_cast<CompoundStmt>(Then)) {
12549 if (ThenCS->body_empty()) {
12550 ErrorInfo.Error = ErrorTy::NoStmt;
12551 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12552 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12555 if (ThenCS->size() > 1) {
12556 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12557 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12558 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12561 Then = ThenCS->body_front();
12564 auto *ThenBO = dyn_cast<BinaryOperator>(Then);
12566 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12567 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getBeginLoc();
12568 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S2->getSourceRange();
12571 if (ThenBO->getOpcode() != BO_Assign) {
12572 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12573 ErrorInfo.ErrorLoc = ThenBO->getExprLoc();
12574 ErrorInfo.NoteLoc = ThenBO->getOperatorLoc();
12575 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenBO->getSourceRange();
12579 X = ThenBO->getLHS();
12580 D = ThenBO->getRHS();
12582 auto *BO = cast<BinaryOperator>(S1->getRHS()->IgnoreImpCasts());
12583 if (BO->getOpcode() != BO_EQ) {
12584 ErrorInfo.Error = ErrorTy::NotEQ;
12585 ErrorInfo.ErrorLoc = BO->getExprLoc();
12586 ErrorInfo.NoteLoc = BO->getOperatorLoc();
12587 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12593 if (checkIfTwoExprsAreSame(ContextRef,
X, BO->getLHS())) {
12595 }
else if (checkIfTwoExprsAreSame(ContextRef,
X, BO->getRHS())) {
12598 ErrorInfo.Error = ErrorTy::InvalidComparison;
12599 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->
getExprLoc();
12600 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12604 if (S2->getElse()) {
12607 auto *Else = S2->getElse();
12608 if (
auto *ElseCS = dyn_cast<CompoundStmt>(Else)) {
12609 if (ElseCS->body_empty()) {
12610 ErrorInfo.Error = ErrorTy::NoStmt;
12611 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12612 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12615 if (ElseCS->size() > 1) {
12616 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12617 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12618 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12621 Else = ElseCS->body_front();
12624 auto *ElseBO = dyn_cast<BinaryOperator>(Else);
12626 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12627 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
12628 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
12631 if (ElseBO->getOpcode() != BO_Assign) {
12632 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12633 ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
12634 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12635 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12638 if (!checkIfTwoExprsAreSame(ContextRef,
X, ElseBO->getRHS())) {
12639 ErrorInfo.Error = ErrorTy::InvalidAssignment;
12640 ErrorInfo.ErrorLoc = ElseBO->getRHS()->getExprLoc();
12641 ErrorInfo.NoteLoc =
X->getExprLoc();
12642 ErrorInfo.ErrorRange = ElseBO->getRHS()->getSourceRange();
12643 ErrorInfo.NoteRange =
X->getSourceRange();
12647 V = ElseBO->getLHS();
12650 return checkType(ErrorInfo);
12653bool OpenMPAtomicCompareCaptureChecker::checkStmt(
Stmt *S,
12654 ErrorInfoTy &ErrorInfo) {
12656 if (
auto *IS = dyn_cast<IfStmt>(S))
12657 return checkForm3(IS, ErrorInfo);
12659 auto *CS = dyn_cast<CompoundStmt>(S);
12661 ErrorInfo.Error = ErrorTy::NotCompoundStmt;
12662 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12663 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12666 if (CS->body_empty()) {
12667 ErrorInfo.Error = ErrorTy::NoStmt;
12668 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12669 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12674 if (CS->size() == 1) {
12675 auto *IS = dyn_cast<IfStmt>(CS->body_front());
12677 ErrorInfo.Error = ErrorTy::NotIfStmt;
12678 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->body_front()->
getBeginLoc();
12679 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12684 return checkForm3(IS, ErrorInfo);
12685 }
else if (CS->size() == 2) {
12686 auto *S1 = CS->body_front();
12687 auto *S2 = CS->body_back();
12689 Stmt *UpdateStmt =
nullptr;
12690 Stmt *CondUpdateStmt =
nullptr;
12691 Stmt *CondExprStmt =
nullptr;
12693 if (
auto *BO = dyn_cast<BinaryOperator>(S1)) {
12699 if (isa<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) ||
12700 isa<ConditionalOperator>(BO->getRHS()->IgnoreImpCasts())) {
12702 if (isa<IfStmt>(S2))
12703 return checkForm45(CS, ErrorInfo);
12708 IsPostfixUpdate =
true;
12710 if (isa<IfStmt>(S2)) {
12712 CondUpdateStmt = S2;
12721 CondUpdateStmt = S1;
12724 auto CheckCondUpdateStmt = [
this, &ErrorInfo](
Stmt *CUS) {
12725 auto *IS = dyn_cast<IfStmt>(CUS);
12727 ErrorInfo.Error = ErrorTy::NotIfStmt;
12728 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CUS->getBeginLoc();
12729 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CUS->getSourceRange();
12733 return checkCondUpdateStmt(IS, ErrorInfo);
12737 auto CheckUpdateStmt = [
this, &ErrorInfo](
Stmt *US) {
12738 auto *BO = dyn_cast<BinaryOperator>(US);
12740 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12741 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = US->getBeginLoc();
12742 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = US->getSourceRange();
12745 if (BO->getOpcode() != BO_Assign) {
12746 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12747 ErrorInfo.ErrorLoc = BO->getExprLoc();
12748 ErrorInfo.NoteLoc = BO->getOperatorLoc();
12749 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12752 if (!checkIfTwoExprsAreSame(ContextRef, this->X, BO->getRHS())) {
12753 ErrorInfo.Error = ErrorTy::InvalidAssignment;
12754 ErrorInfo.ErrorLoc = BO->getRHS()->getExprLoc();
12756 ErrorInfo.ErrorRange = BO->getRHS()->getSourceRange();
12761 this->
V = BO->getLHS();
12766 if (CondUpdateStmt && !CheckCondUpdateStmt(CondUpdateStmt))
12768 if (CondExprStmt && !checkCondExprStmt(CondExprStmt, ErrorInfo))
12770 if (!CheckUpdateStmt(UpdateStmt))
12773 ErrorInfo.Error = ErrorTy::MoreThanTwoStmts;
12774 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->
getBeginLoc();
12775 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->
getSourceRange();
12779 return checkType(ErrorInfo);
12789 DSAStack->addAtomicDirectiveLoc(StartLoc);
12802 bool MutexClauseEncountered =
false;
12803 llvm::SmallSet<OpenMPClauseKind, 2> EncounteredAtomicKinds;
12805 switch (
C->getClauseKind()) {
12809 MutexClauseEncountered =
true;
12812 case OMPC_compare: {
12813 if (AtomicKind != OMPC_unknown && MutexClauseEncountered) {
12814 Diag(
C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12816 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12817 << getOpenMPClauseName(AtomicKind);
12819 AtomicKind =
C->getClauseKind();
12820 AtomicKindLoc =
C->getBeginLoc();
12821 if (!EncounteredAtomicKinds.insert(
C->getClauseKind()).second) {
12822 Diag(
C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12824 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12825 << getOpenMPClauseName(AtomicKind);
12832 if (!EncounteredAtomicKinds.contains(OMPC_compare)) {
12833 Diag(
C->getBeginLoc(), diag::err_omp_atomic_no_compare)
12834 << getOpenMPClauseName(
C->getClauseKind())
12844 case OMPC_relaxed: {
12845 if (MemOrderKind != OMPC_unknown) {
12846 Diag(
C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
12847 << getOpenMPDirectiveName(OMPD_atomic) << 0
12849 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12850 << getOpenMPClauseName(MemOrderKind);
12852 MemOrderKind =
C->getClauseKind();
12853 MemOrderLoc =
C->getBeginLoc();
12861 llvm_unreachable(
"unknown clause is encountered");
12864 bool IsCompareCapture =
false;
12865 if (EncounteredAtomicKinds.contains(OMPC_compare) &&
12866 EncounteredAtomicKinds.contains(OMPC_capture)) {
12867 IsCompareCapture =
true;
12868 AtomicKind = OMPC_compare;
12877 if ((AtomicKind == OMPC_read &&
12878 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
12879 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
12880 AtomicKind == OMPC_unknown) &&
12881 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
12883 if (AtomicKind == OMPC_unknown)
12885 Diag(
Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
12886 << getOpenMPClauseName(AtomicKind)
12887 << (AtomicKind == OMPC_unknown ? 1 : 0)
12888 << getOpenMPClauseName(MemOrderKind);
12889 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12890 << getOpenMPClauseName(MemOrderKind);
12893 Stmt *Body = AStmt;
12894 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Body))
12895 Body = EWC->getSubExpr();
12900 Expr *UE =
nullptr;
12902 Expr *CE =
nullptr;
12904 bool IsXLHSInRHSPart =
false;
12905 bool IsPostfixUpdate =
false;
12906 bool IsFailOnly =
false;
12929 if (AtomicKind == OMPC_read) {
12936 } ErrorFound = NoError;
12941 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12942 const auto *AtomicBinOp =
12943 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12944 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
12947 if ((
X->isInstantiationDependent() ||
X->getType()->isScalarType()) &&
12948 (
V->isInstantiationDependent() ||
V->getType()->isScalarType())) {
12949 if (!
X->isLValue() || !
V->isLValue()) {
12950 const Expr *NotLValueExpr =
X->isLValue() ?
V :
X;
12951 ErrorFound = NotAnLValue;
12957 }
else if (!
X->isInstantiationDependent() ||
12958 !
V->isInstantiationDependent()) {
12959 const Expr *NotScalarExpr =
12960 (
X->isInstantiationDependent() ||
X->getType()->isScalarType())
12963 ErrorFound = NotAScalarType;
12969 }
else if (!AtomicBody->isInstantiationDependent()) {
12970 ErrorFound = NotAnAssignmentOp;
12971 ErrorLoc = AtomicBody->getExprLoc();
12972 ErrorRange = AtomicBody->getSourceRange();
12974 : AtomicBody->getExprLoc();
12976 : AtomicBody->getSourceRange();
12979 ErrorFound = NotAnExpression;
12981 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
12983 if (ErrorFound != NoError) {
12984 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
12986 Diag(NoteLoc, diag::note_omp_atomic_read_write)
12987 << ErrorFound << NoteRange;
12992 }
else if (AtomicKind == OMPC_write) {
12999 } ErrorFound = NoError;
13004 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
13005 const auto *AtomicBinOp =
13006 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
13007 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
13009 E = AtomicBinOp->
getRHS();
13010 if ((
X->isInstantiationDependent() ||
X->getType()->isScalarType()) &&
13012 if (!
X->isLValue()) {
13013 ErrorFound = NotAnLValue;
13016 NoteLoc =
X->getExprLoc();
13017 NoteRange =
X->getSourceRange();
13019 }
else if (!
X->isInstantiationDependent() ||
13021 const Expr *NotScalarExpr =
13022 (
X->isInstantiationDependent() ||
X->getType()->isScalarType())
13025 ErrorFound = NotAScalarType;
13031 }
else if (!AtomicBody->isInstantiationDependent()) {
13032 ErrorFound = NotAnAssignmentOp;
13033 ErrorLoc = AtomicBody->getExprLoc();
13034 ErrorRange = AtomicBody->getSourceRange();
13036 : AtomicBody->getExprLoc();
13038 : AtomicBody->getSourceRange();
13041 ErrorFound = NotAnExpression;
13043 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
13045 if (ErrorFound != NoError) {
13046 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
13048 Diag(NoteLoc, diag::note_omp_atomic_read_write)
13049 << ErrorFound << NoteRange;
13054 }
else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
13063 OpenMPAtomicUpdateChecker Checker(
SemaRef);
13064 if (Checker.checkStatement(
13066 (AtomicKind == OMPC_update)
13067 ? diag::err_omp_atomic_update_not_expression_statement
13068 : diag::err_omp_atomic_not_expression_statement,
13069 diag::note_omp_atomic_update))
13072 E = Checker.getExpr();
13073 X = Checker.getX();
13074 UE = Checker.getUpdateExpr();
13075 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
13077 }
else if (AtomicKind == OMPC_capture) {
13080 NotACompoundStatement,
13081 NotTwoSubstatements,
13082 NotASpecificExpression,
13084 } ErrorFound = NoError;
13087 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
13096 const auto *AtomicBinOp =
13097 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
13098 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
13101 OpenMPAtomicUpdateChecker Checker(
SemaRef);
13102 if (Checker.checkStatement(
13103 Body, diag::err_omp_atomic_capture_not_expression_statement,
13104 diag::note_omp_atomic_update))
13106 E = Checker.getExpr();
13107 X = Checker.getX();
13108 UE = Checker.getUpdateExpr();
13109 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
13110 IsPostfixUpdate = Checker.isPostfixUpdate();
13111 }
else if (!AtomicBody->isInstantiationDependent()) {
13112 ErrorLoc = AtomicBody->getExprLoc();
13113 ErrorRange = AtomicBody->getSourceRange();
13115 : AtomicBody->getExprLoc();
13117 : AtomicBody->getSourceRange();
13118 ErrorFound = NotAnAssignmentOp;
13120 if (ErrorFound != NoError) {
13121 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
13123 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
13127 UE =
V = E =
X =
nullptr;
13145 if (
auto *CS = dyn_cast<CompoundStmt>(Body)) {
13147 if (CS->size() == 2) {
13149 Stmt *Second = CS->body_back();
13150 if (
auto *EWC = dyn_cast<ExprWithCleanups>(
First))
13151 First = EWC->getSubExpr()->IgnoreParenImpCasts();
13152 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Second))
13153 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
13155 OpenMPAtomicUpdateChecker Checker(
SemaRef);
13156 bool IsUpdateExprFound = !Checker.checkStatement(Second);
13158 if (IsUpdateExprFound) {
13159 BinOp = dyn_cast<BinaryOperator>(
First);
13160 IsUpdateExprFound = BinOp && BinOp->
getOpcode() == BO_Assign;
13172 llvm::FoldingSetNodeID XId, PossibleXId;
13173 Checker.getX()->
Profile(XId, Context,
true);
13174 PossibleX->
Profile(PossibleXId, Context,
true);
13175 IsUpdateExprFound = XId == PossibleXId;
13176 if (IsUpdateExprFound) {
13178 X = Checker.getX();
13179 E = Checker.getExpr();
13180 UE = Checker.getUpdateExpr();
13181 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
13182 IsPostfixUpdate =
true;
13185 if (!IsUpdateExprFound) {
13186 IsUpdateExprFound = !Checker.checkStatement(
First);
13188 if (IsUpdateExprFound) {
13189 BinOp = dyn_cast<BinaryOperator>(Second);
13190 IsUpdateExprFound = BinOp && BinOp->
getOpcode() == BO_Assign;
13192 if (IsUpdateExprFound &&
13203 llvm::FoldingSetNodeID XId, PossibleXId;
13204 Checker.getX()->
Profile(XId, Context,
true);
13205 PossibleX->
Profile(PossibleXId, Context,
true);
13206 IsUpdateExprFound = XId == PossibleXId;
13207 if (IsUpdateExprFound) {
13209 X = Checker.getX();
13210 E = Checker.getExpr();
13211 UE = Checker.getUpdateExpr();
13212 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
13213 IsPostfixUpdate =
false;
13217 if (!IsUpdateExprFound) {
13219 auto *FirstExpr = dyn_cast<Expr>(
First);
13220 auto *SecondExpr = dyn_cast<Expr>(Second);
13221 if (!FirstExpr || !SecondExpr ||
13222 !(FirstExpr->isInstantiationDependent() ||
13223 SecondExpr->isInstantiationDependent())) {
13224 auto *FirstBinOp = dyn_cast<BinaryOperator>(
First);
13225 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
13226 ErrorFound = NotAnAssignmentOp;
13227 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
13228 :
First->getBeginLoc();
13229 NoteRange = ErrorRange = FirstBinOp
13230 ? FirstBinOp->getSourceRange()
13233 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
13234 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
13235 ErrorFound = NotAnAssignmentOp;
13236 NoteLoc = ErrorLoc = SecondBinOp
13237 ? SecondBinOp->getOperatorLoc()
13239 NoteRange = ErrorRange =
13240 SecondBinOp ? SecondBinOp->getSourceRange()
13243 Expr *PossibleXRHSInFirst =
13245 Expr *PossibleXLHSInSecond =
13247 llvm::FoldingSetNodeID X1Id, X2Id;
13248 PossibleXRHSInFirst->
Profile(X1Id, Context,
13250 PossibleXLHSInSecond->
Profile(X2Id, Context,
13252 IsUpdateExprFound = X1Id == X2Id;
13253 if (IsUpdateExprFound) {
13254 V = FirstBinOp->getLHS();
13255 X = SecondBinOp->getLHS();
13256 E = SecondBinOp->getRHS();
13258 IsXLHSInRHSPart =
false;
13259 IsPostfixUpdate =
true;
13261 ErrorFound = NotASpecificExpression;
13262 ErrorLoc = FirstBinOp->getExprLoc();
13263 ErrorRange = FirstBinOp->getSourceRange();
13264 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
13265 NoteRange = SecondBinOp->getRHS()->getSourceRange();
13273 NoteRange = ErrorRange =
13275 ErrorFound = NotTwoSubstatements;
13279 NoteRange = ErrorRange =
13281 ErrorFound = NotACompoundStatement;
13284 if (ErrorFound != NoError) {
13285 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
13287 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
13291 UE =
V = E =
X =
nullptr;
13292 }
else if (AtomicKind == OMPC_compare) {
13293 if (IsCompareCapture) {
13294 OpenMPAtomicCompareCaptureChecker::ErrorInfoTy ErrorInfo;
13295 OpenMPAtomicCompareCaptureChecker Checker(
SemaRef);
13296 if (!Checker.checkStmt(Body, ErrorInfo)) {
13297 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare_capture)
13298 << ErrorInfo.ErrorRange;
13299 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
13300 << ErrorInfo.Error << ErrorInfo.NoteRange;
13303 X = Checker.getX();
13304 E = Checker.getE();
13305 D = Checker.getD();
13306 CE = Checker.getCond();
13307 V = Checker.getV();
13308 R = Checker.getR();
13310 IsXLHSInRHSPart = Checker.isXBinopExpr();
13311 IsFailOnly = Checker.isFailOnly();
13312 IsPostfixUpdate = Checker.isPostfixUpdate();
13314 OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo;
13315 OpenMPAtomicCompareChecker Checker(
SemaRef);
13316 if (!Checker.checkStmt(Body, ErrorInfo)) {
13317 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare)
13318 << ErrorInfo.ErrorRange;
13319 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
13320 << ErrorInfo.Error << ErrorInfo.NoteRange;
13323 X = Checker.getX();
13324 E = Checker.getE();
13325 D = Checker.getD();
13326 CE = Checker.getCond();
13332 auto *It = find_if(Clauses, [](
OMPClause *
C) {
13333 return C->getClauseKind() == llvm::omp::Clause::OMPC_weak;
13335 if (It != Clauses.end()) {
13336 auto *Cond = dyn_cast<BinaryOperator>(CE);
13337 if (Cond->getOpcode() != BO_EQ) {
13338 ErrorInfo.Error = Checker.ErrorTy::NotAnAssignment;
13340 ErrorInfo.NoteLoc = Cond->getOperatorLoc();
13341 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->
getSourceRange();
13343 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_weak_no_equality)
13344 << ErrorInfo.ErrorRange;
13349 IsXLHSInRHSPart = Checker.isXBinopExpr();
13356 Context, StartLoc, EndLoc, Clauses, AStmt,
13357 {
X,
V, R, E, UE, D, CE, IsXLHSInRHSPart, IsPostfixUpdate, IsFailOnly});
13367 auto *CS = cast<CapturedStmt>(AStmt);
13375 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13389 if (
DSAStack->hasInnerTeamsRegion()) {
13391 bool OMPTeamsFound =
true;
13392 if (
const auto *CS = dyn_cast<CompoundStmt>(S)) {
13393 auto I = CS->body_begin();
13394 while (I != CS->body_end()) {
13395 const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
13399 OMPTeamsFound =
false;
13404 assert(I != CS->body_end() &&
"Not found statement");
13407 const auto *OED = dyn_cast<OMPExecutableDirective>(S);
13410 if (!OMPTeamsFound) {
13411 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
13413 diag::note_omp_nested_teams_construct_here);
13414 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
13415 << isa<OMPExecutableDirective>(S);
13432 auto *CS = cast<CapturedStmt>(AStmt);
13440 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13463 auto *CS = cast<CapturedStmt>(AStmt);
13471 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13484 unsigned NestedLoopCount =
13487 VarsWithImplicitDSA, B);
13488 if (NestedLoopCount == 0)
13492 "omp target parallel for loop exprs were not built");
13497 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
13507 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13514 return llvm::any_of(
13515 Clauses, [K](
const OMPClause *
C) {
return C->getClauseKind() == K; });
13518template <
typename... Params>
13520 const Params... ClauseTypes) {
13527 if (
auto *TC = dyn_cast<OMPToClause>(
C))
13528 return llvm::all_of(TC->all_decls(), [](
ValueDecl *VD) {
13529 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13530 (VD->isExternallyVisible() &&
13531 VD->getVisibility() != HiddenVisibility);
13533 else if (
auto *FC = dyn_cast<OMPFromClause>(
C))
13534 return llvm::all_of(FC->all_decls(), [](
ValueDecl *VD) {
13535 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13536 (VD->isExternallyVisible() &&
13537 VD->getVisibility() != HiddenVisibility);
13551 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13556 if (!
hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
13558 !
hasClauses(Clauses, OMPC_use_device_addr))) {
13561 Expected =
"'map' or 'use_device_ptr'";
13563 Expected =
"'map', 'use_device_ptr', or 'use_device_addr'";
13564 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13565 <<
Expected << getOpenMPDirectiveName(OMPD_target_data);
13581 auto *CS = cast<CapturedStmt>(AStmt);
13589 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13602 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13603 <<
"'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
13617 auto *CS = cast<CapturedStmt>(AStmt);
13625 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13638 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13639 <<
"'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
13653 auto *CS = cast<CapturedStmt>(AStmt);
13661 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13671 if (!
hasClauses(Clauses, OMPC_to, OMPC_from)) {
13672 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
13677 Diag(StartLoc, diag::err_omp_cannot_update_with_internal_linkage);
13694 Diag(StartLoc, diag::warn_hip_omp_target_directives);
13696 auto *CS = cast<CapturedStmt>(AStmt);
13706 DSAStack->setParentTeamsRegionLoc(StartLoc);
13715 if (
DSAStack->isParentNowaitRegion()) {
13716 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
13719 if (
DSAStack->isParentOrderedRegion()) {
13720 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
13724 EndLoc, CancelRegion);
13730 if (
DSAStack->isParentNowaitRegion()) {
13731 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
13734 if (
DSAStack->isParentOrderedRegion()) {
13735 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
13738 DSAStack->setParentCancelRegion(
true);
13745 const OMPClause *ReductionClause =
nullptr;
13746 const OMPClause *NogroupClause =
nullptr;
13748 if (
C->getClauseKind() == OMPC_reduction) {
13749 ReductionClause =
C;
13754 if (
C->getClauseKind() == OMPC_nogroup) {
13756 if (ReductionClause)
13761 if (ReductionClause && NogroupClause) {
13762 S.
Diag(ReductionClause->
getBeginLoc(), diag::err_omp_reduction_with_nogroup)
13776 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13780 unsigned NestedLoopCount =
13783 *
DSAStack, VarsWithImplicitDSA, B);
13784 if (NestedLoopCount == 0)
13788 "omp for loop exprs were not built");
13794 {OMPC_grainsize, OMPC_num_tasks}))
13804 NestedLoopCount, Clauses, AStmt, B,
13814 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13818 unsigned NestedLoopCount =
13821 *
DSAStack, VarsWithImplicitDSA, B);
13822 if (NestedLoopCount == 0)
13826 "omp for loop exprs were not built");
13831 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
13843 {OMPC_grainsize, OMPC_num_tasks}))
13855 NestedLoopCount, Clauses, AStmt, B);
13864 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13868 unsigned NestedLoopCount =
13871 *
DSAStack, VarsWithImplicitDSA, B);
13872 if (NestedLoopCount == 0)
13876 "omp for loop exprs were not built");
13882 {OMPC_grainsize, OMPC_num_tasks}))
13892 NestedLoopCount, Clauses, AStmt, B,
13902 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13906 unsigned NestedLoopCount =
13909 *
DSAStack, VarsWithImplicitDSA, B);
13910 if (NestedLoopCount == 0)
13914 "omp for loop exprs were not built");
13920 {OMPC_grainsize, OMPC_num_tasks}))
13930 NestedLoopCount, Clauses, AStmt, B,
13940 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13944 unsigned NestedLoopCount =
13947 *
DSAStack, VarsWithImplicitDSA, B);
13948 if (NestedLoopCount == 0)
13952 "omp for loop exprs were not built");
13957 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
13969 {OMPC_grainsize, OMPC_num_tasks}))
13981 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13990 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
13994 unsigned NestedLoopCount =
13997 *
DSAStack, VarsWithImplicitDSA, B);
13998 if (NestedLoopCount == 0)
14002 "omp for loop exprs were not built");
14007 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14019 {OMPC_grainsize, OMPC_num_tasks}))
14031 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14040 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
14041 auto *CS = cast<CapturedStmt>(AStmt);
14048 for (
int ThisCaptureLevel =
14050 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14066 VarsWithImplicitDSA, B);
14067 if (NestedLoopCount == 0)
14071 "omp for loop exprs were not built");
14077 {OMPC_grainsize, OMPC_num_tasks}))
14087 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14097 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
14098 auto *CS = cast<CapturedStmt>(AStmt);
14105 for (
int ThisCaptureLevel =
14107 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14123 VarsWithImplicitDSA, B);
14124 if (NestedLoopCount == 0)
14128 "omp for loop exprs were not built");
14134 {OMPC_grainsize, OMPC_num_tasks}))
14144 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14154 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
14155 auto *CS = cast<CapturedStmt>(AStmt);
14162 for (
int ThisCaptureLevel =
14164 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14180 VarsWithImplicitDSA, B);
14181 if (NestedLoopCount == 0)
14185 "omp for loop exprs were not built");
14190 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14202 {OMPC_grainsize, OMPC_num_tasks}))
14214 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14223 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
14224 auto *CS = cast<CapturedStmt>(AStmt);
14231 for (
int ThisCaptureLevel =
14233 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14249 VarsWithImplicitDSA, B);
14250 if (NestedLoopCount == 0)
14254 "omp for loop exprs were not built");
14259 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14271 {OMPC_grainsize, OMPC_num_tasks}))
14283 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14292 if (!checkLastPrivateForMappedDirectives(Clauses))
14295 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
14299 unsigned NestedLoopCount =
14303 if (NestedLoopCount == 0)
14307 "omp for loop exprs were not built");
14311 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14313 return DistributeDirective;
14322 auto *CS = cast<CapturedStmt>(AStmt);
14329 for (
int ThisCaptureLevel =
14331 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14347 VarsWithImplicitDSA, B);
14348 if (NestedLoopCount == 0)
14352 "omp for loop exprs were not built");
14356 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14366 auto *CS = cast<CapturedStmt>(AStmt);
14373 for (
int ThisCaptureLevel =
14375 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14391 VarsWithImplicitDSA, B);
14392 if (NestedLoopCount == 0)
14396 "omp for loop exprs were not built");
14401 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14414 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14423 auto *CS = cast<CapturedStmt>(AStmt);
14431 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14444 unsigned NestedLoopCount =
14448 if (NestedLoopCount == 0)
14452 "omp for loop exprs were not built");
14457 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14470 NestedLoopCount, Clauses, AStmt, B);
14479 auto *CS = cast<CapturedStmt>(AStmt);
14486 for (
int ThisCaptureLevel =
14488 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14504 VarsWithImplicitDSA, B);
14505 if (NestedLoopCount == 0)
14509 "omp target parallel for simd loop exprs were not built");
14514 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14526 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14535 auto *CS = cast<CapturedStmt>(AStmt);
14543 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14556 unsigned NestedLoopCount =
14559 VarsWithImplicitDSA, B);
14560 if (NestedLoopCount == 0)
14564 "omp target simd loop exprs were not built");
14569 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14582 NestedLoopCount, Clauses, AStmt, B);
14591 auto *CS = cast<CapturedStmt>(AStmt);
14599 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14612 unsigned NestedLoopCount =
14616 if (NestedLoopCount == 0)
14620 "omp teams distribute loop exprs were not built");
14624 DSAStack->setParentTeamsRegionLoc(StartLoc);
14627 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14636 auto *CS = cast<CapturedStmt>(AStmt);
14643 for (
int ThisCaptureLevel =
14645 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14661 VarsWithImplicitDSA, B);
14663 if (NestedLoopCount == 0)
14667 "omp teams distribute simd loop exprs were not built");
14672 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14685 DSAStack->setParentTeamsRegionLoc(StartLoc);
14688 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14697 auto *CS = cast<CapturedStmt>(AStmt);
14705 for (
int ThisCaptureLevel =
14707 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14723 VarsWithImplicitDSA, B);
14725 if (NestedLoopCount == 0)
14729 "omp for loop exprs were not built");
14734 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14747 DSAStack->setParentTeamsRegionLoc(StartLoc);
14750 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14759 auto *CS = cast<CapturedStmt>(AStmt);
14767 for (
int ThisCaptureLevel =
14769 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14785 VarsWithImplicitDSA, B);
14787 if (NestedLoopCount == 0)
14791 "omp for loop exprs were not built");
14795 DSAStack->setParentTeamsRegionLoc(StartLoc);
14798 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14808 auto *CS = cast<CapturedStmt>(AStmt);
14817 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14829 bool HasThreadLimitAndNumTeamsClause =
hasClauses(Clauses, OMPC_num_teams) &&
14831 bool HasBareClause = llvm::any_of(Clauses, [&](
const OMPClause *
C) {
14833 return C->getClauseKind() == OMPC_ompx_bare;
14836 if (HasBareClause && !HasThreadLimitAndNumTeamsClause) {
14851 auto *CS = cast<CapturedStmt>(AStmt);
14858 for (
int ThisCaptureLevel =
14860 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14876 VarsWithImplicitDSA, B);
14877 if (NestedLoopCount == 0)
14881 "omp target teams distribute loop exprs were not built");
14885 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14894 auto *CS = cast<CapturedStmt>(AStmt);
14901 for (
int ThisCaptureLevel =
14903 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14919 VarsWithImplicitDSA, B);
14920 if (NestedLoopCount == 0)
14924 "omp target teams distribute parallel for loop exprs were not built");
14929 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14939 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14949 auto *CS = cast<CapturedStmt>(AStmt);
14957 OMPD_target_teams_distribute_parallel_for_simd);
14958 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14971 unsigned NestedLoopCount =
14976 if (NestedLoopCount == 0)
14980 "omp target teams distribute parallel for simd loop exprs were not "
14986 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
14999 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
15008 auto *CS = cast<CapturedStmt>(AStmt);
15015 for (
int ThisCaptureLevel =
15017 ThisCaptureLevel > 1; --ThisCaptureLevel) {
15033 VarsWithImplicitDSA, B);
15034 if (NestedLoopCount == 0)
15038 "omp target teams distribute simd loop exprs were not built");
15043 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
15056 getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
15059bool SemaOpenMP::checkTransformableLoopNest(
15065 OriginalInits.emplace_back();
15068 [
this, &LoopHelpers, &Body, &OriginalInits, Kind](
unsigned Cnt,
15070 VarsWithInheritedDSAType TmpDSA;
15071 unsigned SingleNumLoops =
15072 checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, SemaRef, *DSAStack,
15073 TmpDSA, LoopHelpers[Cnt]);
15074 if (SingleNumLoops == 0)
15076 assert(SingleNumLoops == 1 &&
"Expect single loop iteration space");
15077 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
15078 OriginalInits.back().push_back(For->getInit());
15079 Body = For->getBody();
15081 assert(isa<CXXForRangeStmt>(CurStmt) &&
15082 "Expected canonical for or range-based for loops.");
15083 auto *CXXFor = cast<CXXForRangeStmt>(CurStmt);
15084 OriginalInits.back().push_back(CXXFor->getBeginStmt());
15085 Body = CXXFor->getBody();
15087 OriginalInits.emplace_back();
15091 Stmt *DependentPreInits;
15092 if (
auto *Dir = dyn_cast<OMPTileDirective>(Transform))
15093 DependentPreInits = Dir->getPreInits();
15094 else if (
auto *Dir = dyn_cast<OMPUnrollDirective>(Transform))
15095 DependentPreInits = Dir->getPreInits();
15097 llvm_unreachable(
"Unhandled loop transformation");
15098 if (!DependentPreInits)
15100 llvm::append_range(OriginalInits.back(),
15101 cast<DeclStmt>(DependentPreInits)->getDeclGroup());
15103 assert(OriginalInits.back().empty() &&
"No preinit after innermost loop");
15104 OriginalInits.pop_back();
15115 const auto *SizesClause =
15116 OMPExecutableDirective::getSingleClause<OMPSizesClause>(Clauses);
15117 if (!SizesClause ||
15118 llvm::any_of(SizesClause->getSizesRefs(), [](
Expr *E) { return !E; }))
15120 unsigned NumLoops = SizesClause->getNumSizes();
15128 Stmt *Body =
nullptr;
15131 if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body,
15138 NumLoops, AStmt,
nullptr,
nullptr);
15140 assert(LoopHelpers.size() == NumLoops &&
15141 "Expecting loop iteration space dimensionality to match number of "
15143 assert(OriginalInits.size() == NumLoops &&
15144 "Expecting loop iteration space dimensionality to match number of "
15148 CaptureVars CopyTransformer(
SemaRef);
15153 FloorIndVars.resize(NumLoops);
15154 TileIndVars.resize(NumLoops);
15155 for (
unsigned I = 0; I < NumLoops; ++I) {
15158 assert(LoopHelper.
Counters.size() == 1 &&
15159 "Expect single-dimensional loop iteration space");
15160 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.
Counters.front());
15161 std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
15167 std::string FloorCntName =
15168 (Twine(
".floor_") + llvm::utostr(I) +
".iv." + OrigVarName).str();
15171 FloorIndVars[I] = FloorCntDecl;
15176 std::string TileCntName =
15177 (Twine(
".tile_") + llvm::utostr(I) +
".iv." + OrigVarName).str();
15182 auto *TileCntDecl = cast<VarDecl>(IterVarRef->
getDecl());
15183 TileCntDecl->setDeclName(
15185 TileIndVars[I] = TileCntDecl;
15187 for (
auto &
P : OriginalInits[I]) {
15188 if (
auto *D =
P.dyn_cast<
Decl *>())
15189 PreInits.push_back(D);
15190 else if (
auto *PI = dyn_cast_or_null<DeclStmt>(
P.dyn_cast<
Stmt *>()))
15191 PreInits.append(PI->decl_begin(), PI->decl_end());
15193 if (
auto *PI = cast_or_null<DeclStmt>(LoopHelper.
PreInits))
15194 PreInits.append(PI->decl_begin(), PI->decl_end());
15197 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
15198 if (isa<OMPCapturedExprDecl>(CounterDecl))
15199 PreInits.push_back(CounterDecl);
15204 Stmt *Inner = Body;
15206 auto MakeDimTileSize = [&
SemaRef = this->
SemaRef, &CopyTransformer, &Context,
15207 SizesClause, CurScope](
int I) ->
Expr * {
15208 Expr *DimTileSizeExpr = SizesClause->getSizesRefs()[I];
15209 if (isa<ConstantExpr>(DimTileSizeExpr))
15210 return AssertSuccess(CopyTransformer.TransformExpr(DimTileSizeExpr));
15231 Context, llvm::APInt::getZero(DimWidth), DimTy, {});
15235 CurScope, {}, BO_LE,
15236 AssertSuccess(CopyTransformer.TransformExpr(DimTileSizeExpr)), Zero));
15239 AssertSuccess(CopyTransformer.TransformExpr(DimTileSizeExpr)), DimTy,
15245 for (
int I = NumLoops - 1; I >= 0; --I) {
15248 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.
Counters[0]);
15249 QualType CntTy = OrigCntVar->getType();
15254 auto MakeTileIVRef = [&
SemaRef = this->
SemaRef, &TileIndVars, I, CntTy,
15257 OrigCntVar->getExprLoc());
15259 auto MakeFloorIVRef = [&
SemaRef = this->
SemaRef, &FloorIndVars, I, CntTy,
15262 OrigCntVar->getExprLoc());
15269 Decl *CounterDecl = TileIndVars[I];
15272 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
15280 MakeFloorIVRef(), MakeDimTileSize(I));
15285 NumIterations, EndOfTile.
get());
15290 IsPartialTile.
get(), NumIterations, EndOfTile.
get());
15291 if (!MinTileAndIterSpace.
isUsable())
15295 MakeTileIVRef(), MinTileAndIterSpace.
get());
15301 CurScope, LoopHelper.
Inc->
getExprLoc(), UO_PreInc, MakeTileIVRef());
15322 BodyParts.append(LoopHelper.
Updates.begin(), LoopHelper.
Updates.end());
15323 BodyParts.push_back(Inner);
15325 Inner->getBeginLoc(), Inner->getEndLoc());
15326 Inner =
new (Context)
15333 for (
int I = NumLoops - 1; I >= 0; --I) {
15334 auto &LoopHelper = LoopHelpers[I];
15335 Expr *NumIterations = LoopHelper.NumIterations;
15336 DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
15340 auto MakeFloorIVRef = [&
SemaRef = this->
SemaRef, &FloorIndVars, I, CntTy,
15351 Decl *CounterDecl = FloorIndVars[I];
15361 MakeFloorIVRef(), NumIterations);
15368 MakeFloorIVRef(), MakeDimTileSize(I));
15372 Inner =
new (Context)
15374 IncrStmt.
get(), Inner, LoopHelper.Init->getBeginLoc(),
15375 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15394 {OMPC_partial, OMPC_full}))
15398 OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses);
15400 OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses);
15401 assert(!(FullClause && PartialClause) &&
15402 "mutual exclusivity must have been checked before");
15404 constexpr unsigned NumLoops = 1;
15405 Stmt *Body =
nullptr;
15410 if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers,
15411 Body, OriginalInits))
15414 unsigned NumGeneratedLoops = PartialClause ? 1 : 0;
15419 NumGeneratedLoops,
nullptr,
nullptr);
15428 Diag(AStmt->
getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count);
15430 <<
"#pragma omp unroll full";
15438 if (NumGeneratedLoops == 0)
15440 NumGeneratedLoops,
nullptr,
nullptr);
15486 assert(OriginalInits.size() == 1 &&
15487 "Expecting a single-dimensional loop iteration space");
15488 for (
auto &
P : OriginalInits[0]) {
15489 if (
auto *D =
P.dyn_cast<
Decl *>())
15490 PreInits.push_back(D);
15491 else if (
auto *PI = dyn_cast_or_null<DeclStmt>(
P.dyn_cast<
Stmt *>()))
15492 PreInits.append(PI->decl_begin(), PI->decl_end());
15494 if (
auto *PI = cast_or_null<DeclStmt>(LoopHelper.
PreInits))
15495 PreInits.append(PI->decl_begin(), PI->decl_end());
15498 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
15499 if (isa<OMPCapturedExprDecl>(CounterDecl))
15500 PreInits.push_back(CounterDecl);
15503 auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.
IterationVarRef);
15504 QualType IVTy = IterationVarRef->getType();
15505 assert(LoopHelper.
Counters.size() == 1 &&
15506 "Expecting a single-dimensional loop iteration space");
15507 auto *OrigVar = cast<DeclRefExpr>(LoopHelper.
Counters.front());
15513 Factor = FactorVal->getIntegerConstantExpr(Context)->getZExtValue();
15514 FactorLoc = FactorVal->getExprLoc();
15519 assert(Factor > 0 &&
"Expected positive unroll factor");
15520 auto MakeFactorExpr = [
this, Factor, IVTy, FactorLoc]() {
15532 std::string OrigVarName = OrigVar->getNameInfo().getAsString();
15533 std::string OuterIVName = (Twine(
".unrolled.iv.") + OrigVarName).str();
15534 std::string InnerIVName = (Twine(
".unroll_inner.iv.") + OrigVarName).str();
15535 std::string InnerTripCountName =
15536 (Twine(
".unroll_inner.tripcount.") + OrigVarName).str();
15541 auto MakeOuterRef = [
this, OuterIVDecl, IVTy, OrigVarLoc]() {
15547 auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl());
15549 auto MakeInnerRef = [
this, InnerIVDecl, IVTy, OrigVarLoc]() {
15555 CaptureVars CopyTransformer(
SemaRef);
15556 auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() ->
Expr * {
15579 MakeOuterRef(), MakeFactorExpr());
15584 MakeInnerRef(), EndOfTile.
get());
15589 MakeInnerRef(), MakeNumIterations());
15594 InnerCond1.
get(), InnerCond2.
get());
15600 CurScope, LoopHelper.
Inc->
getExprLoc(), UO_PreInc, MakeInnerRef());
15606 InnerBodyStmts.append(LoopHelper.
Updates.begin(), LoopHelper.
Updates.end());
15607 InnerBodyStmts.push_back(Body);
15611 ForStmt *InnerFor =
new (Context)
15612 ForStmt(Context, InnerInit.
get(), InnerCond.
get(),
nullptr,
15628 LoopHintAttr *UnrollHintAttr =
15629 LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount,
15630 LoopHintAttr::Numeric, MakeFactorExpr());
15647 MakeOuterRef(), MakeNumIterations());
15654 MakeOuterRef(), MakeFactorExpr());
15659 ForStmt *OuterFor =
new (Context)
15660 ForStmt(Context, OuterInit.
get(), OuterConde.
get(),
nullptr,
15665 NumGeneratedLoops, OuterFor,
15679 case OMPC_num_threads:
15688 case OMPC_allocator:
15691 case OMPC_collapse:
15697 case OMPC_num_teams:
15700 case OMPC_thread_limit:
15703 case OMPC_priority:
15715 case OMPC_novariants:
15718 case OMPC_nocontext:
15733 case OMPC_ompx_dyn_cgroup_mem:
15736 case OMPC_grainsize:
15737 case OMPC_num_tasks:
15741 case OMPC_proc_bind:
15742 case OMPC_schedule:
15744 case OMPC_firstprivate:
15745 case OMPC_lastprivate:
15747 case OMPC_reduction:
15748 case OMPC_task_reduction:
15749 case OMPC_in_reduction:
15753 case OMPC_copyprivate:
15756 case OMPC_mergeable:
15757 case OMPC_threadprivate:
15759 case OMPC_allocate:
15776 case OMPC_dist_schedule:
15777 case OMPC_defaultmap:
15782 case OMPC_use_device_ptr:
15783 case OMPC_use_device_addr:
15784 case OMPC_is_device_ptr:
15785 case OMPC_unified_address:
15786 case OMPC_unified_shared_memory:
15787 case OMPC_reverse_offload:
15788 case OMPC_dynamic_allocators:
15789 case OMPC_atomic_default_mem_order:
15790 case OMPC_device_type:
15792 case OMPC_nontemporal:
15795 case OMPC_severity:
15797 case OMPC_inclusive:
15798 case OMPC_exclusive:
15799 case OMPC_uses_allocators:
15800 case OMPC_affinity:
15804 llvm_unreachable(
"Clause is not allowed.");
15821 case OMPD_target_parallel_for_simd:
15822 if (OpenMPVersion >= 50 &&
15823 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15824 CaptureRegion = OMPD_parallel;
15828 case OMPD_target_parallel:
15829 case OMPD_target_parallel_for:
15830 case OMPD_target_parallel_loop:
15833 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
15834 CaptureRegion = OMPD_target;
15836 case OMPD_teams_loop:
15837 case OMPD_target_teams_loop:
15840 CaptureRegion = OMPD_teams;
15842 case OMPD_target_teams_distribute_parallel_for_simd:
15843 if (OpenMPVersion >= 50 &&
15844 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15845 CaptureRegion = OMPD_parallel;
15849 case OMPD_target_teams_distribute_parallel_for:
15852 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
15853 CaptureRegion = OMPD_teams;
15855 case OMPD_teams_distribute_parallel_for_simd:
15856 if (OpenMPVersion >= 50 &&
15857 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15858 CaptureRegion = OMPD_parallel;
15862 case OMPD_teams_distribute_parallel_for:
15863 CaptureRegion = OMPD_teams;
15865 case OMPD_target_update:
15866 case OMPD_target_enter_data:
15867 case OMPD_target_exit_data:
15868 CaptureRegion = OMPD_task;
15870 case OMPD_parallel_masked_taskloop:
15871 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
15872 CaptureRegion = OMPD_parallel;
15874 case OMPD_parallel_master_taskloop:
15875 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
15876 CaptureRegion = OMPD_parallel;
15878 case OMPD_parallel_masked_taskloop_simd:
15879 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
15880 NameModifier == OMPD_taskloop) {
15881 CaptureRegion = OMPD_parallel;
15884 if (OpenMPVersion <= 45)
15886 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15887 CaptureRegion = OMPD_taskloop;
15889 case OMPD_parallel_master_taskloop_simd:
15890 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
15891 NameModifier == OMPD_taskloop) {
15892 CaptureRegion = OMPD_parallel;
15895 if (OpenMPVersion <= 45)
15897 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15898 CaptureRegion = OMPD_taskloop;
15900 case OMPD_parallel_for_simd:
15901 if (OpenMPVersion <= 45)
15903 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15904 CaptureRegion = OMPD_parallel;
15906 case OMPD_taskloop_simd:
15907 case OMPD_master_taskloop_simd:
15908 case OMPD_masked_taskloop_simd:
15909 if (OpenMPVersion <= 45)
15911 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15912 CaptureRegion = OMPD_taskloop;
15914 case OMPD_distribute_parallel_for_simd:
15915 if (OpenMPVersion <= 45)
15917 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15918 CaptureRegion = OMPD_parallel;
15920 case OMPD_target_simd:
15921 if (OpenMPVersion >= 50 &&
15922 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
15923 CaptureRegion = OMPD_target;
15925 case OMPD_teams_distribute_simd:
15926 case OMPD_target_teams_distribute_simd:
15927 if (OpenMPVersion >= 50 &&
15928 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
15929 CaptureRegion = OMPD_teams;
15932 case OMPD_parallel:
15933 case OMPD_parallel_master:
15934 case OMPD_parallel_masked:
15935 case OMPD_parallel_sections:
15936 case OMPD_parallel_for:
15937 case OMPD_parallel_loop:
15939 case OMPD_target_teams:
15940 case OMPD_target_teams_distribute:
15941 case OMPD_distribute_parallel_for:
15943 case OMPD_taskloop:
15944 case OMPD_master_taskloop:
15945 case OMPD_masked_taskloop:
15946 case OMPD_target_data:
15948 case OMPD_for_simd:
15949 case OMPD_distribute_simd:
15952 case OMPD_threadprivate:
15953 case OMPD_allocate:
15954 case OMPD_taskyield:
15957 case OMPD_taskwait:
15958 case OMPD_cancellation_point:
15962 case OMPD_declare_reduction:
15963 case OMPD_declare_mapper:
15964 case OMPD_declare_simd:
15965 case OMPD_declare_variant:
15966 case OMPD_begin_declare_variant:
15967 case OMPD_end_declare_variant:
15968 case OMPD_declare_target:
15969 case OMPD_end_declare_target:
15975 case OMPD_sections:
15980 case OMPD_critical:
15981 case OMPD_taskgroup:
15982 case OMPD_distribute:
15985 case OMPD_teams_distribute:
15986 case OMPD_requires:
15987 case OMPD_metadirective:
15988 llvm_unreachable(
"Unexpected OpenMP directive with if-clause");
15991 llvm_unreachable(
"Unknown OpenMP directive");
15994 case OMPC_num_threads:
15996 case OMPD_target_parallel:
15997 case OMPD_target_parallel_for:
15998 case OMPD_target_parallel_for_simd:
15999 case OMPD_target_parallel_loop:
16000 CaptureRegion = OMPD_target;
16002 case OMPD_teams_distribute_parallel_for:
16003 case OMPD_teams_distribute_parallel_for_simd:
16004 case OMPD_target_teams_distribute_parallel_for:
16005 case OMPD_target_teams_distribute_parallel_for_simd:
16006 CaptureRegion = OMPD_teams;
16008 case OMPD_parallel:
16009 case OMPD_parallel_master:
16010 case OMPD_parallel_masked:
16011 case OMPD_parallel_sections:
16012 case OMPD_parallel_for:
16013 case OMPD_parallel_for_simd:
16014 case OMPD_parallel_loop:
16015 case OMPD_distribute_parallel_for:
16016 case OMPD_distribute_parallel_for_simd:
16017 case OMPD_parallel_master_taskloop:
16018 case OMPD_parallel_masked_taskloop:
16019 case OMPD_parallel_master_taskloop_simd:
16020 case OMPD_parallel_masked_taskloop_simd:
16023 case OMPD_target_data:
16024 case OMPD_target_enter_data:
16025 case OMPD_target_exit_data:
16026 case OMPD_target_update:
16028 case OMPD_target_simd:
16029 case OMPD_target_teams:
16030 case OMPD_target_teams_distribute:
16031 case OMPD_target_teams_distribute_simd:
16034 case OMPD_taskloop:
16035 case OMPD_taskloop_simd:
16036 case OMPD_master_taskloop:
16037 case OMPD_masked_taskloop:
16038 case OMPD_master_taskloop_simd:
16039 case OMPD_masked_taskloop_simd:
16040 case OMPD_threadprivate:
16041 case OMPD_allocate:
16042 case OMPD_taskyield:
16045 case OMPD_taskwait:
16046 case OMPD_cancellation_point:
16050 case OMPD_declare_reduction:
16051 case OMPD_declare_mapper:
16052 case OMPD_declare_simd:
16053 case OMPD_declare_variant:
16054 case OMPD_begin_declare_variant:
16055 case OMPD_end_declare_variant:
16056 case OMPD_declare_target:
16057 case OMPD_end_declare_target:
16059 case OMPD_teams_loop:
16060 case OMPD_target_teams_loop:
16066 case OMPD_for_simd:
16067 case OMPD_sections:
16072 case OMPD_critical:
16073 case OMPD_taskgroup:
16074 case OMPD_distribute:
16077 case OMPD_distribute_simd:
16078 case OMPD_teams_distribute:
16079 case OMPD_teams_distribute_simd:
16080 case OMPD_requires:
16081 case OMPD_metadirective:
16082 llvm_unreachable(
"Unexpected OpenMP directive with num_threads-clause");
16085 llvm_unreachable(
"Unknown OpenMP directive");
16088 case OMPC_num_teams:
16090 case OMPD_target_teams:
16091 case OMPD_target_teams_distribute:
16092 case OMPD_target_teams_distribute_simd:
16093 case OMPD_target_teams_distribute_parallel_for:
16094 case OMPD_target_teams_distribute_parallel_for_simd:
16095 case OMPD_target_teams_loop:
16096 CaptureRegion = OMPD_target;
16098 case OMPD_teams_distribute_parallel_for:
16099 case OMPD_teams_distribute_parallel_for_simd:
16101 case OMPD_teams_distribute:
16102 case OMPD_teams_distribute_simd:
16103 case OMPD_teams_loop:
16106 case OMPD_distribute_parallel_for:
16107 case OMPD_distribute_parallel_for_simd:
16109 case OMPD_taskloop:
16110 case OMPD_taskloop_simd:
16111 case OMPD_master_taskloop:
16112 case OMPD_masked_taskloop:
16113 case OMPD_master_taskloop_simd:
16114 case OMPD_masked_taskloop_simd:
16115 case OMPD_parallel_master_taskloop:
16116 case OMPD_parallel_masked_taskloop:
16117 case OMPD_parallel_master_taskloop_simd:
16118 case OMPD_parallel_masked_taskloop_simd:
16119 case OMPD_target_data:
16120 case OMPD_target_enter_data:
16121 case OMPD_target_exit_data:
16122 case OMPD_target_update:
16124 case OMPD_parallel:
16125 case OMPD_parallel_master:
16126 case OMPD_parallel_masked:
16127 case OMPD_parallel_sections:
16128 case OMPD_parallel_for:
16129 case OMPD_parallel_for_simd:
16130 case OMPD_parallel_loop:
16132 case OMPD_target_simd:
16133 case OMPD_target_parallel:
16134 case OMPD_target_parallel_for:
16135 case OMPD_target_parallel_for_simd:
16136 case OMPD_target_parallel_loop:
16137 case OMPD_threadprivate:
16138 case OMPD_allocate:
16139 case OMPD_taskyield:
16142 case OMPD_taskwait:
16143 case OMPD_cancellation_point:
16147 case OMPD_declare_reduction:
16148 case OMPD_declare_mapper:
16149 case OMPD_declare_simd:
16150 case OMPD_declare_variant:
16151 case OMPD_begin_declare_variant:
16152 case OMPD_end_declare_variant:
16153 case OMPD_declare_target:
16154 case OMPD_end_declare_target:
16160 case OMPD_for_simd:
16161 case OMPD_sections:
16166 case OMPD_critical:
16167 case OMPD_taskgroup:
16168 case OMPD_distribute:
16171 case OMPD_distribute_simd:
16172 case OMPD_requires:
16173 case OMPD_metadirective:
16174 llvm_unreachable(
"Unexpected OpenMP directive with num_teams-clause");
16177 llvm_unreachable(
"Unknown OpenMP directive");
16180 case OMPC_thread_limit:
16183 case OMPD_target_teams:
16184 case OMPD_target_teams_distribute:
16185 case OMPD_target_teams_distribute_simd:
16186 case OMPD_target_teams_distribute_parallel_for:
16187 case OMPD_target_teams_distribute_parallel_for_simd:
16188 case OMPD_target_teams_loop:
16189 case OMPD_target_simd:
16190 case OMPD_target_parallel:
16191 case OMPD_target_parallel_for:
16192 case OMPD_target_parallel_for_simd:
16193 case OMPD_target_parallel_loop:
16194 CaptureRegion = OMPD_target;
16196 case OMPD_teams_distribute_parallel_for:
16197 case OMPD_teams_distribute_parallel_for_simd:
16199 case OMPD_teams_distribute:
16200 case OMPD_teams_distribute_simd:
16201 case OMPD_teams_loop:
16204 case OMPD_distribute_parallel_for:
16205 case OMPD_distribute_parallel_for_simd:
16207 case OMPD_taskloop:
16208 case OMPD_taskloop_simd:
16209 case OMPD_master_taskloop:
16210 case OMPD_masked_taskloop:
16211 case OMPD_master_taskloop_simd:
16212 case OMPD_masked_taskloop_simd:
16213 case OMPD_parallel_master_taskloop:
16214 case OMPD_parallel_masked_taskloop:
16215 case OMPD_parallel_master_taskloop_simd:
16216 case OMPD_parallel_masked_taskloop_simd:
16217 case OMPD_target_data:
16218 case OMPD_target_enter_data:
16219 case OMPD_target_exit_data:
16220 case OMPD_target_update:
16222 case OMPD_parallel:
16223 case OMPD_parallel_master:
16224 case OMPD_parallel_masked:
16225 case OMPD_parallel_sections:
16226 case OMPD_parallel_for:
16227 case OMPD_parallel_for_simd:
16228 case OMPD_parallel_loop:
16229 case OMPD_threadprivate:
16230 case OMPD_allocate:
16231 case OMPD_taskyield:
16234 case OMPD_taskwait:
16235 case OMPD_cancellation_point:
16239 case OMPD_declare_reduction:
16240 case OMPD_declare_mapper:
16241 case OMPD_declare_simd:
16242 case OMPD_declare_variant:
16243 case OMPD_begin_declare_variant:
16244 case OMPD_end_declare_variant:
16245 case OMPD_declare_target:
16246 case OMPD_end_declare_target:
16252 case OMPD_for_simd:
16253 case OMPD_sections:
16258 case OMPD_critical:
16259 case OMPD_taskgroup:
16260 case OMPD_distribute:
16263 case OMPD_distribute_simd:
16264 case OMPD_requires:
16265 case OMPD_metadirective:
16266 llvm_unreachable(
"Unexpected OpenMP directive with thread_limit-clause");
16269 llvm_unreachable(
"Unknown OpenMP directive");
16272 case OMPC_schedule:
16274 case OMPD_parallel_for:
16275 case OMPD_parallel_for_simd:
16276 case OMPD_distribute_parallel_for:
16277 case OMPD_distribute_parallel_for_simd:
16278 case OMPD_teams_distribute_parallel_for:
16279 case OMPD_teams_distribute_parallel_for_simd:
16280 case OMPD_target_parallel_for:
16281 case OMPD_target_parallel_for_simd:
16282 case OMPD_target_teams_distribute_parallel_for:
16283 case OMPD_target_teams_distribute_parallel_for_simd:
16284 CaptureRegion = OMPD_parallel;
16287 case OMPD_for_simd:
16291 case OMPD_taskloop:
16292 case OMPD_taskloop_simd:
16293 case OMPD_master_taskloop:
16294 case OMPD_masked_taskloop:
16295 case OMPD_master_taskloop_simd:
16296 case OMPD_masked_taskloop_simd:
16297 case OMPD_parallel_master_taskloop:
16298 case OMPD_parallel_masked_taskloop:
16299 case OMPD_parallel_master_taskloop_simd:
16300 case OMPD_parallel_masked_taskloop_simd:
16301 case OMPD_target_data:
16302 case OMPD_target_enter_data:
16303 case OMPD_target_exit_data:
16304 case OMPD_target_update:
16306 case OMPD_teams_distribute:
16307 case OMPD_teams_distribute_simd:
16308 case OMPD_target_teams_distribute:
16309 case OMPD_target_teams_distribute_simd:
16311 case OMPD_target_simd:
16312 case OMPD_target_parallel:
16314 case OMPD_parallel:
16315 case OMPD_parallel_master:
16316 case OMPD_parallel_masked:
16317 case OMPD_parallel_sections:
16318 case OMPD_threadprivate:
16319 case OMPD_allocate:
16320 case OMPD_taskyield:
16323 case OMPD_taskwait:
16324 case OMPD_cancellation_point:
16328 case OMPD_declare_reduction:
16329 case OMPD_declare_mapper:
16330 case OMPD_declare_simd:
16331 case OMPD_declare_variant:
16332 case OMPD_begin_declare_variant:
16333 case OMPD_end_declare_variant:
16334 case OMPD_declare_target:
16335 case OMPD_end_declare_target:
16337 case OMPD_teams_loop:
16338 case OMPD_target_teams_loop:
16339 case OMPD_parallel_loop:
16340 case OMPD_target_parallel_loop:
16344 case OMPD_sections:
16349 case OMPD_critical:
16350 case OMPD_taskgroup:
16351 case OMPD_distribute:
16354 case OMPD_distribute_simd:
16355 case OMPD_target_teams:
16356 case OMPD_requires:
16357 case OMPD_metadirective:
16358 llvm_unreachable(
"Unexpected OpenMP directive with schedule clause");
16361 llvm_unreachable(
"Unknown OpenMP directive");
16364 case OMPC_dist_schedule:
16366 case OMPD_teams_distribute_parallel_for:
16367 case OMPD_teams_distribute_parallel_for_simd:
16368 case OMPD_teams_distribute:
16369 case OMPD_teams_distribute_simd:
16370 case OMPD_target_teams_distribute_parallel_for:
16371 case OMPD_target_teams_distribute_parallel_for_simd:
16372 case OMPD_target_teams_distribute:
16373 case OMPD_target_teams_distribute_simd:
16374 CaptureRegion = OMPD_teams;
16376 case OMPD_distribute_parallel_for:
16377 case OMPD_distribute_parallel_for_simd:
16378 case OMPD_distribute:
16379 case OMPD_distribute_simd:
16382 case OMPD_parallel_for:
16383 case OMPD_parallel_for_simd:
16384 case OMPD_target_parallel_for_simd:
16385 case OMPD_target_parallel_for:
16387 case OMPD_taskloop:
16388 case OMPD_taskloop_simd:
16389 case OMPD_master_taskloop:
16390 case OMPD_masked_taskloop:
16391 case OMPD_master_taskloop_simd:
16392 case OMPD_masked_taskloop_simd:
16393 case OMPD_parallel_master_taskloop:
16394 case OMPD_parallel_masked_taskloop:
16395 case OMPD_parallel_master_taskloop_simd:
16396 case OMPD_parallel_masked_taskloop_simd:
16397 case OMPD_target_data:
16398 case OMPD_target_enter_data:
16399 case OMPD_target_exit_data:
16400 case OMPD_target_update:
16403 case OMPD_target_simd:
16404 case OMPD_target_parallel:
16406 case OMPD_parallel:
16407 case OMPD_parallel_master:
16408 case OMPD_parallel_masked:
16409 case OMPD_parallel_sections:
16410 case OMPD_threadprivate:
16411 case OMPD_allocate:
16412 case OMPD_taskyield:
16415 case OMPD_taskwait:
16416 case OMPD_cancellation_point:
16420 case OMPD_declare_reduction:
16421 case OMPD_declare_mapper:
16422 case OMPD_declare_simd:
16423 case OMPD_declare_variant:
16424 case OMPD_begin_declare_variant:
16425 case OMPD_end_declare_variant:
16426 case OMPD_declare_target:
16427 case OMPD_end_declare_target:
16429 case OMPD_teams_loop:
16430 case OMPD_target_teams_loop:
16431 case OMPD_parallel_loop:
16432 case OMPD_target_parallel_loop:
16437 case OMPD_for_simd:
16438 case OMPD_sections:
16443 case OMPD_critical:
16444 case OMPD_taskgroup:
16447 case OMPD_target_teams:
16448 case OMPD_requires:
16449 case OMPD_metadirective:
16450 llvm_unreachable(
"Unexpected OpenMP directive with dist_schedule clause");
16453 llvm_unreachable(
"Unknown OpenMP directive");
16456 case OMPC_ompx_dyn_cgroup_mem:
16459 case OMPD_target_simd:
16460 case OMPD_target_teams:
16461 case OMPD_target_parallel:
16462 case OMPD_target_teams_distribute:
16463 case OMPD_target_teams_distribute_simd:
16464 case OMPD_target_parallel_for:
16465 case OMPD_target_parallel_for_simd:
16466 case OMPD_target_parallel_loop:
16467 case OMPD_target_teams_distribute_parallel_for:
16468 case OMPD_target_teams_distribute_parallel_for_simd:
16469 case OMPD_target_teams_loop:
16470 CaptureRegion = OMPD_target;
16473 llvm_unreachable(
"Unknown OpenMP directive");
16478 case OMPD_target_update:
16479 case OMPD_target_enter_data:
16480 case OMPD_target_exit_data:
16482 case OMPD_target_simd:
16483 case OMPD_target_teams:
16484 case OMPD_target_parallel:
16485 case OMPD_target_teams_distribute:
16486 case OMPD_target_teams_distribute_simd:
16487 case OMPD_target_parallel_for:
16488 case OMPD_target_parallel_for_simd:
16489 case OMPD_target_parallel_loop:
16490 case OMPD_target_teams_distribute_parallel_for:
16491 case OMPD_target_teams_distribute_parallel_for_simd:
16492 case OMPD_target_teams_loop:
16493 case OMPD_dispatch:
16494 CaptureRegion = OMPD_task;
16496 case OMPD_target_data:
16500 case OMPD_teams_distribute_parallel_for:
16501 case OMPD_teams_distribute_parallel_for_simd:
16503 case OMPD_teams_distribute:
16504 case OMPD_teams_distribute_simd:
16505 case OMPD_distribute_parallel_for:
16506 case OMPD_distribute_parallel_for_simd:
16508 case OMPD_taskloop:
16509 case OMPD_taskloop_simd:
16510 case OMPD_master_taskloop:
16511 case OMPD_masked_taskloop:
16512 case OMPD_master_taskloop_simd:
16513 case OMPD_masked_taskloop_simd:
16514 case OMPD_parallel_master_taskloop:
16515 case OMPD_parallel_masked_taskloop:
16516 case OMPD_parallel_master_taskloop_simd:
16517 case OMPD_parallel_masked_taskloop_simd:
16519 case OMPD_parallel:
16520 case OMPD_parallel_master:
16521 case OMPD_parallel_masked:
16522 case OMPD_parallel_sections:
16523 case OMPD_parallel_for:
16524 case OMPD_parallel_for_simd:
16525 case OMPD_threadprivate:
16526 case OMPD_allocate:
16527 case OMPD_taskyield:
16530 case OMPD_taskwait:
16531 case OMPD_cancellation_point:
16535 case OMPD_declare_reduction:
16536 case OMPD_declare_mapper:
16537 case OMPD_declare_simd:
16538 case OMPD_declare_variant:
16539 case OMPD_begin_declare_variant:
16540 case OMPD_end_declare_variant:
16541 case OMPD_declare_target:
16542 case OMPD_end_declare_target:
16544 case OMPD_teams_loop:
16545 case OMPD_parallel_loop:
16550 case OMPD_for_simd:
16551 case OMPD_sections:
16556 case OMPD_critical:
16557 case OMPD_taskgroup:
16558 case OMPD_distribute:
16561 case OMPD_distribute_simd:
16562 case OMPD_requires:
16563 case OMPD_metadirective:
16564 llvm_unreachable(
"Unexpected OpenMP directive with device-clause");
16567 llvm_unreachable(
"Unknown OpenMP directive");
16570 case OMPC_grainsize:
16571 case OMPC_num_tasks:
16573 case OMPC_priority:
16576 case OMPD_taskloop:
16577 case OMPD_taskloop_simd:
16578 case OMPD_master_taskloop:
16579 case OMPD_masked_taskloop:
16580 case OMPD_master_taskloop_simd:
16581 case OMPD_masked_taskloop_simd:
16583 case OMPD_parallel_masked_taskloop:
16584 case OMPD_parallel_masked_taskloop_simd:
16585 case OMPD_parallel_master_taskloop:
16586 case OMPD_parallel_master_taskloop_simd:
16587 CaptureRegion = OMPD_parallel;
16589 case OMPD_target_update:
16590 case OMPD_target_enter_data:
16591 case OMPD_target_exit_data:
16593 case OMPD_target_simd:
16594 case OMPD_target_teams:
16595 case OMPD_target_parallel:
16596 case OMPD_target_teams_distribute:
16597 case OMPD_target_teams_distribute_simd:
16598 case OMPD_target_parallel_for:
16599 case OMPD_target_parallel_for_simd:
16600 case OMPD_target_teams_distribute_parallel_for:
16601 case OMPD_target_teams_distribute_parallel_for_simd:
16602 case OMPD_target_data:
16603 case OMPD_teams_distribute_parallel_for:
16604 case OMPD_teams_distribute_parallel_for_simd:
16606 case OMPD_teams_distribute:
16607 case OMPD_teams_distribute_simd:
16608 case OMPD_distribute_parallel_for:
16609 case OMPD_distribute_parallel_for_simd:
16611 case OMPD_parallel:
16612 case OMPD_parallel_master:
16613 case OMPD_parallel_masked:
16614 case OMPD_parallel_sections:
16615 case OMPD_parallel_for:
16616 case OMPD_parallel_for_simd:
16617 case OMPD_threadprivate:
16618 case OMPD_allocate:
16619 case OMPD_taskyield:
16622 case OMPD_taskwait:
16623 case OMPD_cancellation_point:
16627 case OMPD_declare_reduction:
16628 case OMPD_declare_mapper:
16629 case OMPD_declare_simd:
16630 case OMPD_declare_variant:
16631 case OMPD_begin_declare_variant:
16632 case OMPD_end_declare_variant:
16633 case OMPD_declare_target:
16634 case OMPD_end_declare_target:
16636 case OMPD_teams_loop:
16637 case OMPD_target_teams_loop:
16638 case OMPD_parallel_loop:
16639 case OMPD_target_parallel_loop:
16644 case OMPD_for_simd:
16645 case OMPD_sections:
16650 case OMPD_critical:
16651 case OMPD_taskgroup:
16652 case OMPD_distribute:
16655 case OMPD_distribute_simd:
16656 case OMPD_requires:
16657 case OMPD_metadirective:
16658 llvm_unreachable(
"Unexpected OpenMP directive with grainsize-clause");
16661 llvm_unreachable(
"Unknown OpenMP directive");
16664 case OMPC_novariants:
16665 case OMPC_nocontext:
16667 case OMPD_dispatch:
16668 CaptureRegion = OMPD_task;
16671 llvm_unreachable(
"Unexpected OpenMP directive");
16678 if (DKind == OMPD_metadirective) {
16679 CaptureRegion = OMPD_metadirective;
16680 }
else if (DKind == OMPD_unknown) {
16681 llvm_unreachable(
"Unknown OpenMP directive");
16683 llvm_unreachable(
"Unexpected OpenMP directive with when clause");
16686 case OMPC_firstprivate:
16687 case OMPC_lastprivate:
16688 case OMPC_reduction:
16689 case OMPC_task_reduction:
16690 case OMPC_in_reduction:
16693 case OMPC_proc_bind:
16697 case OMPC_allocator:
16698 case OMPC_collapse:
16703 case OMPC_copyprivate:
16707 case OMPC_mergeable:
16708 case OMPC_threadprivate:
16709 case OMPC_allocate:
16728 case OMPC_defaultmap:
16733 case OMPC_use_device_ptr:
16734 case OMPC_use_device_addr:
16735 case OMPC_is_device_ptr:
16736 case OMPC_unified_address:
16737 case OMPC_unified_shared_memory:
16738 case OMPC_reverse_offload:
16739 case OMPC_dynamic_allocators:
16740 case OMPC_atomic_default_mem_order:
16741 case OMPC_device_type:
16743 case OMPC_nontemporal:
16746 case OMPC_severity:
16750 case OMPC_inclusive:
16751 case OMPC_exclusive:
16752 case OMPC_uses_allocators:
16753 case OMPC_affinity:
16756 llvm_unreachable(
"Unexpected OpenMP clause.");
16758 return CaptureRegion;
16766 Stmt *HelperValStmt =
nullptr;
16769 !
Condition->isInstantiationDependent() &&
16770 !
Condition->containsUnexpandedParameterPack()) {
16775 ValExpr = Val.
get();
16779 DKind, OMPC_if,
getLangOpts().OpenMP, NameModifier);
16780 if (CaptureRegion != OMPD_unknown &&
16783 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16784 ValExpr = tryBuildCapture(
SemaRef, ValExpr, Captures).get();
16790 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
16791 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
16799 Stmt *HelperValStmt =
nullptr;
16802 !
Condition->isInstantiationDependent() &&
16803 !
Condition->containsUnexpandedParameterPack()) {
16813 if (CaptureRegion != OMPD_unknown &&
16816 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16817 ValExpr = tryBuildCapture(
SemaRef, ValExpr, Captures).get();
16823 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
16834 IntConvertDiagnoser()
16835 : ICEConvertDiagnoser(
false,
false,
true) {}
16838 return S.
Diag(
Loc, diag::err_omp_not_integral) <<
T;
16842 return S.
Diag(
Loc, diag::err_omp_incomplete_type) <<
T;
16847 return S.
Diag(
Loc, diag::err_omp_explicit_conversion) <<
T << ConvTy;
16856 return S.
Diag(
Loc, diag::err_omp_ambiguous_conversion) <<
T;
16865 llvm_unreachable(
"conversion functions are permitted");
16867 } ConvertDiagnoser;
16873 bool StrictlyPositive,
bool BuildCapture =
false,
16876 Stmt **HelperValStmt =
nullptr) {
16882 if (
Value.isInvalid())
16885 ValExpr =
Value.get();
16887 if (std::optional<llvm::APSInt>
Result =
16889 if (
Result->isSigned() &&
16890 !((!StrictlyPositive &&
Result->isNonNegative()) ||
16891 (StrictlyPositive &&
Result->isStrictlyPositive()))) {
16892 SemaRef.
Diag(
Loc, diag::err_omp_negative_expression_in_clause)
16893 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
16902 if (*CaptureRegion != OMPD_unknown &&
16905 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16906 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
16917 Expr *ValExpr = NumThreads;
16918 Stmt *HelperValStmt =
nullptr;
16929 if (CaptureRegion != OMPD_unknown &&
16932 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16933 ValExpr = tryBuildCapture(
SemaRef, ValExpr, Captures).get();
16938 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
16943 bool SuppressExprDiags) {
16952 if (SuppressExprDiags) {
16956 SuppressedDiagnoser() : VerifyICEDiagnoser(
true) {}
16959 llvm_unreachable(
"Diagnostic suppressed");
16971 if ((StrictlyPositive && !
Result.isStrictlyPositive()) ||
16972 (!StrictlyPositive && !
Result.isNonNegative())) {
16973 Diag(E->
getExprLoc(), diag::err_omp_negative_expression_in_clause)
16974 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
16978 if ((CKind == OMPC_aligned || CKind == OMPC_align) && !
Result.isPowerOf2()) {
16979 Diag(E->
getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
16983 if (CKind == OMPC_collapse &&
DSAStack->getAssociatedLoops() == 1)
16985 else if (CKind == OMPC_ordered)
17020 DSAStackTy *Stack) {
17021 if (!Stack->getOMPAllocatorHandleT().isNull())
17028 S.
Diag(
Loc, diag::err_omp_implied_type_not_found)
17029 <<
"omp_allocator_handle_t";
17034 Stack->setOMPAllocatorHandleT(AllocatorHandleEnumTy);
17037 bool ErrorFound =
false;
17038 for (
int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
17039 auto AllocatorKind =
static_cast<OMPAllocateDeclAttr::AllocatorTypeTy
>(I);
17040 StringRef Allocator =
17041 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
17043 auto *VD = dyn_cast_or_null<ValueDecl>(
17063 Stack->setAllocator(AllocatorKind, Res.
get());
17066 S.
Diag(
Loc, diag::err_omp_implied_type_not_found)
17067 <<
"omp_allocator_handle_t";
17084 if (Allocator.isInvalid())
17087 Allocator.get(),
DSAStack->getOMPAllocatorHandleT(),
17090 if (Allocator.isInvalid())
17116 Expr *NumForLoops) {
17122 if (NumForLoops && LParenLoc.
isValid()) {
17127 NumForLoops = NumForLoopsResult.
get();
17129 NumForLoops =
nullptr;
17133 NumForLoops ?
DSAStack->getAssociatedLoops() : 0,
17134 StartLoc, LParenLoc, EndLoc);
17135 DSAStack->setOrderedRegion(
true, NumForLoops, Clause);
17146 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
17148 case OMPC_proc_bind:
17150 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
17152 case OMPC_atomic_default_mem_order:
17155 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
17160 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
17164 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
17168 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
17172 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
17174 case OMPC_severity:
17177 LParenLoc, EndLoc);
17181 case OMPC_num_threads:
17185 case OMPC_allocator:
17186 case OMPC_collapse:
17187 case OMPC_schedule:
17189 case OMPC_firstprivate:
17190 case OMPC_lastprivate:
17192 case OMPC_reduction:
17193 case OMPC_task_reduction:
17194 case OMPC_in_reduction:
17198 case OMPC_copyprivate:
17202 case OMPC_mergeable:
17203 case OMPC_threadprivate:
17204 case OMPC_allocate:
17221 case OMPC_num_teams:
17222 case OMPC_thread_limit:
17223 case OMPC_priority:
17224 case OMPC_grainsize:
17226 case OMPC_num_tasks:
17228 case OMPC_dist_schedule:
17229 case OMPC_defaultmap:
17234 case OMPC_use_device_ptr:
17235 case OMPC_use_device_addr:
17236 case OMPC_is_device_ptr:
17237 case OMPC_has_device_addr:
17238 case OMPC_unified_address:
17239 case OMPC_unified_shared_memory:
17240 case OMPC_reverse_offload:
17241 case OMPC_dynamic_allocators:
17242 case OMPC_device_type:
17244 case OMPC_nontemporal:
17246 case OMPC_novariants:
17247 case OMPC_nocontext:
17249 case OMPC_inclusive:
17250 case OMPC_exclusive:
17251 case OMPC_uses_allocators:
17252 case OMPC_affinity:
17256 llvm_unreachable(
"Clause is not allowed.");
17265 llvm::raw_svector_ostream Out(Buffer);
17266 unsigned Skipped = Exclude.size();
17267 for (
unsigned I =
First; I <
Last; ++I) {
17268 if (llvm::is_contained(Exclude, I)) {
17273 if (I + Skipped + 2 ==
Last)
17275 else if (I + Skipped + 1 !=
Last)
17278 return std::string(Out.str());
17286 if (Kind == OMP_DEFAULT_unknown) {
17287 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17289 unsigned(OMP_DEFAULT_unknown))
17290 << getOpenMPClauseName(OMPC_default);
17295 case OMP_DEFAULT_none:
17296 DSAStack->setDefaultDSANone(KindKwLoc);
17298 case OMP_DEFAULT_shared:
17299 DSAStack->setDefaultDSAShared(KindKwLoc);
17301 case OMP_DEFAULT_firstprivate:
17302 DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
17304 case OMP_DEFAULT_private:
17305 DSAStack->setDefaultDSAPrivate(KindKwLoc);
17308 llvm_unreachable(
"DSA unexpected in OpenMP default clause");
17320 if (Kind == OMP_PROC_BIND_unknown) {
17321 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17323 unsigned(OMP_PROC_BIND_master),
17326 ? OMP_PROC_BIND_primary
17327 : OMP_PROC_BIND_spread) +
17329 << getOpenMPClauseName(OMPC_proc_bind);
17332 if (Kind == OMP_PROC_BIND_primary &&
getLangOpts().OpenMP < 51)
17333 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17335 unsigned(OMP_PROC_BIND_master),
17337 unsigned(OMP_PROC_BIND_spread) + 1)
17338 << getOpenMPClauseName(OMPC_proc_bind);
17347 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17349 OMPC_atomic_default_mem_order, 0,
17351 << getOpenMPClauseName(OMPC_atomic_default_mem_order);
17355 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
17364 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17367 << getOpenMPClauseName(OMPC_at);
17371 OMPAtClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
17380 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17383 << getOpenMPClauseName(OMPC_severity);
17394 assert(ME &&
"NULL expr in Message clause");
17395 if (!isa<StringLiteral>(ME)) {
17397 << getOpenMPClauseName(OMPC_message);
17408 if (Kind != OMPC_ORDER_concurrent ||
17413 "OMPC_ORDER_unknown not greater than 0");
17415 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
17419 << getOpenMPClauseName(OMPC_order);
17424 Diag(MLoc, diag::err_omp_unexpected_clause_value)
17428 << getOpenMPClauseName(OMPC_order);
17430 DSAStack->setRegionHasOrderConcurrent(
true);
17433 unsigned existingFlags =
DSAStack->getCurScope()->getFlags();
17434 DSAStack->getCurScope()->setFlags(existingFlags |
17440 Kind, KindLoc, StartLoc, LParenLoc, EndLoc, Modifier, MLoc);
17449 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
17451 OMPC_DEPEND_source, OMPC_DEPEND_sink, OMPC_DEPEND_depobj,
17452 OMPC_DEPEND_outallmemory, OMPC_DEPEND_inoutallmemory};
17454 Except.push_back(OMPC_DEPEND_inoutset);
17455 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17458 << getOpenMPClauseName(OMPC_update);
17462 KindKwLoc, Kind, EndLoc);
17471 for (
Expr *&SizeExpr : SanitizedSizeExprs) {
17481 QualType SizeTy = SizeExpr->getType();
17510 if (!SizeExpr->isInstantiationDependent() && !IsValid)
17511 SizeExpr =
nullptr;
17515 SanitizedSizeExprs);
17531 FactorExpr, OMPC_partial,
true);
17534 FactorExpr = FactorResult.
get();
17549 LParenLoc, EndLoc);
17559 case OMPC_schedule:
17560 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
17561 assert(Argument.size() == NumberOfElements &&
17562 ArgumentLoc.size() == NumberOfElements);
17567 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
17568 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
17571 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
17573 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
17576 case OMPC_dist_schedule:
17579 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
17581 case OMPC_defaultmap:
17582 enum { Modifier, DefaultmapKind };
17586 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
17590 enum { OrderModifier, OrderKind };
17594 LParenLoc, ArgumentLoc[OrderModifier], ArgumentLoc[OrderKind], EndLoc);
17597 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
17600 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17602 case OMPC_grainsize:
17603 assert(Argument.size() == 1 && ArgumentLoc.size() == 1 &&
17604 "Modifier for grainsize clause and its location are expected.");
17607 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17609 case OMPC_num_tasks:
17610 assert(Argument.size() == 1 && ArgumentLoc.size() == 1 &&
17611 "Modifier for num_tasks clause and its location are expected.");
17614 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17617 case OMPC_num_threads:
17621 case OMPC_allocator:
17622 case OMPC_collapse:
17624 case OMPC_proc_bind:
17626 case OMPC_firstprivate:
17627 case OMPC_lastprivate:
17629 case OMPC_reduction:
17630 case OMPC_task_reduction:
17631 case OMPC_in_reduction:
17635 case OMPC_copyprivate:
17639 case OMPC_mergeable:
17640 case OMPC_threadprivate:
17641 case OMPC_allocate:
17658 case OMPC_num_teams:
17659 case OMPC_thread_limit:
17660 case OMPC_priority:
17667 case OMPC_use_device_ptr:
17668 case OMPC_use_device_addr:
17669 case OMPC_is_device_ptr:
17670 case OMPC_has_device_addr:
17671 case OMPC_unified_address:
17672 case OMPC_unified_shared_memory:
17673 case OMPC_reverse_offload:
17674 case OMPC_dynamic_allocators:
17675 case OMPC_atomic_default_mem_order:
17676 case OMPC_device_type:
17678 case OMPC_nontemporal:
17680 case OMPC_severity:
17683 case OMPC_novariants:
17684 case OMPC_nocontext:
17686 case OMPC_inclusive:
17687 case OMPC_exclusive:
17688 case OMPC_uses_allocators:
17689 case OMPC_affinity:
17693 llvm_unreachable(
"Clause is not allowed.");
17704 Excluded.push_back(M2);
17705 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
17706 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
17707 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
17708 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
17709 S.
Diag(M1Loc, diag::err_omp_unexpected_clause_value)
17714 << getOpenMPClauseName(OMPC_schedule);
17732 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
17733 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
17734 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
17735 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
17736 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
17742 std::string Values;
17752 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
17753 << Values << getOpenMPClauseName(OMPC_schedule);
17761 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
17762 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
17763 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
17764 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
17765 diag::err_omp_schedule_nonmonotonic_static);
17768 Expr *ValExpr = ChunkSize;
17769 Stmt *HelperValStmt =
nullptr;
17780 ValExpr = Val.
get();
17785 if (std::optional<llvm::APSInt>
Result =
17787 if (
Result->isSigned() && !
Result->isStrictlyPositive()) {
17788 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
17793 DSAStack->getCurrentDirective(), OMPC_schedule,
17797 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17798 ValExpr = tryBuildCapture(
SemaRef, ValExpr, Captures).get();
17806 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
17823 case OMPC_mergeable:
17871 case OMPC_unified_address:
17874 case OMPC_unified_shared_memory:
17877 case OMPC_reverse_offload:
17880 case OMPC_dynamic_allocators:
17894 case OMPC_ompx_bare:
17899 case OMPC_num_threads:
17903 case OMPC_allocator:
17904 case OMPC_collapse:
17905 case OMPC_schedule:
17907 case OMPC_firstprivate:
17908 case OMPC_lastprivate:
17910 case OMPC_reduction:
17911 case OMPC_task_reduction:
17912 case OMPC_in_reduction:
17916 case OMPC_copyprivate:
17918 case OMPC_proc_bind:
17919 case OMPC_threadprivate:
17920 case OMPC_allocate:
17926 case OMPC_num_teams:
17927 case OMPC_thread_limit:
17928 case OMPC_priority:
17929 case OMPC_grainsize:
17930 case OMPC_num_tasks:
17932 case OMPC_dist_schedule:
17933 case OMPC_defaultmap:
17938 case OMPC_use_device_ptr:
17939 case OMPC_use_device_addr:
17940 case OMPC_is_device_ptr:
17941 case OMPC_has_device_addr:
17942 case OMPC_atomic_default_mem_order:
17943 case OMPC_device_type:
17945 case OMPC_nontemporal:
17948 case OMPC_severity:
17950 case OMPC_novariants:
17951 case OMPC_nocontext:
17953 case OMPC_inclusive:
17954 case OMPC_exclusive:
17955 case OMPC_uses_allocators:
17956 case OMPC_affinity:
17958 case OMPC_ompx_dyn_cgroup_mem:
17960 llvm_unreachable(
"Clause is not allowed.");
18019 Diag(KindLoc, diag::err_omp_atomic_fail_wrong_or_no_clauses);
18100 if (!
hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) {
18101 StringRef
Expected =
"'init', 'use', 'destroy', or 'nowait'";
18102 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
18103 <<
Expected << getOpenMPDirectiveName(OMPD_interop);
18116 bool HasInitClause =
false;
18117 bool IsTargetSync =
false;
18121 if (
const auto *InitClause = dyn_cast<OMPInitClause>(
C)) {
18122 HasInitClause =
true;
18123 if (InitClause->getIsTargetSync())
18124 IsTargetSync =
true;
18125 }
else if (
const auto *DC = dyn_cast<OMPDependClause>(
C)) {
18129 if (DependClause && HasInitClause && !IsTargetSync) {
18130 Diag(DependClause->
getBeginLoc(), diag::err_omp_interop_bad_depend_clause);
18144 if (ClauseKind == OMPC_init) {
18145 auto *E = cast<OMPInitClause>(
C)->getInteropVar();
18147 }
else if (ClauseKind == OMPC_use) {
18148 auto *E = cast<OMPUseClause>(
C)->getInteropVar();
18150 }
else if (ClauseKind == OMPC_destroy) {
18151 auto *E = cast<OMPDestroyClause>(
C)->getInteropVar();
18156 if (!InteropVars.insert(
DeclResult.first).second) {
18157 Diag(ELoc, diag::err_omp_interop_var_multiple_actions)
18173 Expr *RefExpr = InteropVarExpr;
18176 false,
"omp_interop_t");
18187 bool HasError =
false;
18193 if (
const auto *TD = dyn_cast<TypeDecl>(ND)) {
18194 InteropType =
QualType(TD->getTypeForDecl(), 0);
18203 SemaRef.
Diag(VarLoc, diag::err_omp_implied_type_not_found)
18204 <<
"omp_interop_t";
18210 SemaRef.
Diag(VarLoc, diag::err_omp_interop_variable_wrong_type);
18216 if ((Kind == OMPC_init || Kind == OMPC_destroy) &&
18218 SemaRef.
Diag(VarLoc, diag::err_omp_interop_variable_expected)
18240 if (isa<StringLiteral>(E))
18247 StartLoc, LParenLoc, VarLoc, EndLoc);
18260 OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
18269 DSAStack->getCurrentDirective() == OMPD_depobj) {
18270 Diag(StartLoc, diag::err_omp_expected_clause_argument)
18271 << getOpenMPClauseName(OMPC_destroy)
18272 << getOpenMPDirectiveName(OMPD_depobj);
18288 Stmt *HelperValStmt =
nullptr;
18291 !
Condition->isInstantiationDependent() &&
18292 !
Condition->containsUnexpandedParameterPack()) {
18302 if (CaptureRegion != OMPD_unknown &&
18305 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18306 ValExpr = tryBuildCapture(
SemaRef, ValExpr, Captures).get();
18312 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
18320 Stmt *HelperValStmt =
nullptr;
18323 !
Condition->isInstantiationDependent() &&
18324 !
Condition->containsUnexpandedParameterPack()) {
18334 if (CaptureRegion != OMPD_unknown &&
18337 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18338 ValExpr = tryBuildCapture(
SemaRef, ValExpr, Captures).get();
18344 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
18351 Expr *ValExpr = ThreadID;
18352 Stmt *HelperValStmt =
nullptr;
18357 if (CaptureRegion != OMPD_unknown &&
18360 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18361 ValExpr = tryBuildCapture(
SemaRef, ValExpr, Captures).get();
18366 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
18377 int ExtraModifier =
Data.ExtraModifier;
18384 case OMPC_firstprivate:
18387 case OMPC_lastprivate:
18389 "Unexpected lastprivate modifier.");
18392 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
18397 case OMPC_reduction:
18399 "Unexpected lastprivate modifier.");
18402 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
18403 Data.ReductionOrMapperIdScopeSpec,
Data.ReductionOrMapperId);
18405 case OMPC_task_reduction:
18407 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
18408 Data.ReductionOrMapperIdScopeSpec,
Data.ReductionOrMapperId);
18410 case OMPC_in_reduction:
18412 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
18413 Data.ReductionOrMapperIdScopeSpec,
Data.ReductionOrMapperId);
18417 "Unexpected linear modifier.");
18419 VarList,
Data.DepModOrTailExpr, StartLoc, LParenLoc,
18421 ColonLoc,
Data.StepModifierLoc, EndLoc);
18425 LParenLoc, ColonLoc, EndLoc);
18430 case OMPC_copyprivate:
18438 "Unexpected depend modifier.");
18441 ColonLoc,
Data.OmpAllMemoryLoc},
18442 Data.DepModOrTailExpr, VarList, StartLoc, LParenLoc, EndLoc);
18446 "Unexpected map modifier.");
18448 Data.IteratorExpr,
Data.MapTypeModifiers,
Data.MapTypeModifiersLoc,
18449 Data.ReductionOrMapperIdScopeSpec,
Data.ReductionOrMapperId,
18451 ExtraModifierLoc, ColonLoc, VarList, Locs);
18456 Data.ReductionOrMapperIdScopeSpec,
18457 Data.ReductionOrMapperId, ColonLoc, VarList, Locs);
18461 Data.ReductionOrMapperIdScopeSpec,
18462 Data.ReductionOrMapperId, ColonLoc, VarList,
18465 case OMPC_use_device_ptr:
18468 case OMPC_use_device_addr:
18471 case OMPC_is_device_ptr:
18474 case OMPC_has_device_addr:
18477 case OMPC_allocate:
18479 LParenLoc, ColonLoc, EndLoc);
18481 case OMPC_nontemporal:
18484 case OMPC_inclusive:
18487 case OMPC_exclusive:
18490 case OMPC_affinity:
18492 Data.DepModOrTailExpr, VarList);
18494 case OMPC_doacross:
18497 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
18502 case OMPC_num_threads:
18506 case OMPC_allocator:
18507 case OMPC_collapse:
18509 case OMPC_proc_bind:
18510 case OMPC_schedule:
18514 case OMPC_mergeable:
18515 case OMPC_threadprivate:
18529 case OMPC_num_teams:
18530 case OMPC_thread_limit:
18531 case OMPC_priority:
18532 case OMPC_grainsize:
18534 case OMPC_num_tasks:
18536 case OMPC_dist_schedule:
18537 case OMPC_defaultmap:
18540 case OMPC_unified_address:
18541 case OMPC_unified_shared_memory:
18542 case OMPC_reverse_offload:
18543 case OMPC_dynamic_allocators:
18544 case OMPC_atomic_default_mem_order:
18545 case OMPC_device_type:
18549 case OMPC_severity:
18552 case OMPC_novariants:
18553 case OMPC_nocontext:
18555 case OMPC_uses_allocators:
18559 llvm_unreachable(
"Clause is not allowed.");
18590 bool IsImplicitClause =
18592 for (
Expr *RefExpr : VarList) {
18593 assert(RefExpr &&
"NULL expr in OpenMP private clause.");
18596 Expr *SimpleRefExpr = RefExpr;
18600 Vars.push_back(RefExpr);
18601 PrivateCopies.push_back(
nullptr);
18608 auto *VD = dyn_cast<VarDecl>(D);
18614 diag::err_omp_private_incomplete_type))
18616 Type =
Type.getNonReferenceType();
18636 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
18637 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
18638 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
18639 << getOpenMPClauseName(OMPC_private);
18648 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18649 << getOpenMPClauseName(OMPC_private) <<
Type
18650 << getOpenMPDirectiveName(CurrDir);
18651 bool IsDecl = !VD || VD->isThisDeclarationADefinition(
getASTContext()) ==
18654 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18669 CurrDir == OMPD_target) {
18671 if (
DSAStack->checkMappableExprComponentListsForDecl(
18675 ConflictKind = WhereFoundClauseKind;
18678 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18679 << getOpenMPClauseName(OMPC_private)
18680 << getOpenMPClauseName(ConflictKind)
18681 << getOpenMPDirectiveName(CurrDir);
18700 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
18709 auto *FD = dyn_cast<FieldDecl>(D);
18713 RefExpr->getExprLoc());
18717 if (!IsImplicitClause)
18718 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
18720 ? RefExpr->IgnoreParens()
18722 PrivateCopies.push_back(VDPrivateRefExpr);
18729 Vars, PrivateCopies);
18740 bool IsImplicitClause =
18744 for (
Expr *RefExpr : VarList) {
18745 assert(RefExpr &&
"NULL expr in OpenMP firstprivate clause.");
18748 Expr *SimpleRefExpr = RefExpr;
18752 Vars.push_back(RefExpr);
18753 PrivateCopies.push_back(
nullptr);
18754 Inits.push_back(
nullptr);
18760 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
18762 auto *VD = dyn_cast<VarDecl>(D);
18768 diag::err_omp_firstprivate_incomplete_type))
18770 Type =
Type.getNonReferenceType();
18780 DSAStackTy::DSAVarData TopDVar;
18781 if (!IsImplicitClause) {
18782 DSAStackTy::DSAVarData DVar =
18794 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
18796 DVar.CKind != OMPC_lastprivate) &&
18798 Diag(ELoc, diag::err_omp_wrong_dsa)
18799 << getOpenMPClauseName(DVar.CKind)
18800 << getOpenMPClauseName(OMPC_firstprivate);
18816 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
18817 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
18818 Diag(ELoc, diag::err_omp_wrong_dsa)
18819 << getOpenMPClauseName(DVar.CKind)
18820 << getOpenMPClauseName(OMPC_firstprivate);
18844 DVar =
DSAStack->getImplicitDSA(D,
true);
18845 if (DVar.CKind != OMPC_shared &&
18848 DVar.DKind == OMPD_unknown)) {
18849 Diag(ELoc, diag::err_omp_required_access)
18850 << getOpenMPClauseName(OMPC_firstprivate)
18851 << getOpenMPClauseName(OMPC_shared);
18871 return C == OMPC_reduction && !AppliedToPointee;
18879 if (DVar.CKind == OMPC_reduction &&
18883 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
18884 << getOpenMPDirectiveName(DVar.DKind);
18900 CurrDir == OMPD_target) {
18902 if (
DSAStack->checkMappableExprComponentListsForDecl(
18907 ConflictKind = WhereFoundClauseKind;
18910 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18911 << getOpenMPClauseName(OMPC_firstprivate)
18912 << getOpenMPClauseName(ConflictKind)
18913 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
18923 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18924 << getOpenMPClauseName(OMPC_firstprivate) <<
Type
18925 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
18926 bool IsDecl = !VD || VD->isThisDeclarationADefinition(
getASTContext()) ==
18929 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18938 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
18944 Expr *VDInitRefExpr =
nullptr;
18954 ElemType,
".firstprivate.temp");
18969 ".firstprivate.temp");
18971 RefExpr->getExprLoc());
18977 if (IsImplicitClause) {
18978 Diag(RefExpr->getExprLoc(),
18979 diag::note_omp_task_predetermined_firstprivate_here);
18986 RefExpr->getExprLoc());
18989 if (TopDVar.CKind == OMPC_lastprivate) {
18990 Ref = TopDVar.PrivateCopy;
18992 auto *FD = dyn_cast<FieldDecl>(D);
18997 RefExpr->getExprLoc());
19001 ExprCaptures.push_back(Ref->
getDecl());
19004 if (!IsImplicitClause)
19005 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
19007 ? RefExpr->IgnoreParens()
19009 PrivateCopies.push_back(VDPrivateRefExpr);
19010 Inits.push_back(VDInitRefExpr);
19017 getASTContext(), StartLoc, LParenLoc, EndLoc, Vars, PrivateCopies, Inits,
19026 assert(ColonLoc.
isValid() &&
"Colon location must be valid.");
19027 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
19030 << getOpenMPClauseName(OMPC_lastprivate);
19040 for (
Expr *RefExpr : VarList) {
19041 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
19044 Expr *SimpleRefExpr = RefExpr;
19048 Vars.push_back(RefExpr);
19049 SrcExprs.push_back(
nullptr);
19050 DstExprs.push_back(
nullptr);
19051 AssignmentOps.push_back(
nullptr);
19058 auto *VD = dyn_cast<VarDecl>(D);
19064 diag::err_omp_lastprivate_incomplete_type))
19066 Type =
Type.getNonReferenceType();
19083 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
19084 bool IsDecl = !VD || VD->isThisDeclarationADefinition(
getASTContext()) ==
19087 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19101 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
19102 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
19104 DVar.CKind != OMPC_firstprivate) &&
19105 (DVar.CKind != OMPC_private || DVar.RefExpr !=
nullptr)) {
19106 Diag(ELoc, diag::err_omp_wrong_dsa)
19107 << getOpenMPClauseName(DVar.CKind)
19108 << getOpenMPClauseName(OMPC_lastprivate);
19119 DSAStackTy::DSAVarData TopDVar = DVar;
19123 DVar =
DSAStack->getImplicitDSA(D,
true);
19124 if (DVar.CKind != OMPC_shared) {
19125 Diag(ELoc, diag::err_omp_required_access)
19126 << getOpenMPClauseName(OMPC_lastprivate)
19127 << getOpenMPClauseName(OMPC_shared);
19143 Type.getUnqualifiedType(),
".lastprivate.src",
19154 PseudoDstExpr, PseudoSrcExpr);
19164 if (TopDVar.CKind == OMPC_firstprivate) {
19165 Ref = TopDVar.PrivateCopy;
19169 ExprCaptures.push_back(Ref->
getDecl());
19171 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
19179 SimpleRefExpr, RefRes.
get());
19182 ExprPostUpdates.push_back(
19186 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
19188 ? RefExpr->IgnoreParens()
19190 SrcExprs.push_back(PseudoSrcExpr);
19191 DstExprs.push_back(PseudoDstExpr);
19192 AssignmentOps.push_back(AssignmentOp.
get());
19199 getASTContext(), StartLoc, LParenLoc, EndLoc, Vars, SrcExprs, DstExprs,
19200 AssignmentOps, LPKind, LPKindLoc, ColonLoc,
19210 for (
Expr *RefExpr : VarList) {
19211 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
19214 Expr *SimpleRefExpr = RefExpr;
19218 Vars.push_back(RefExpr);
19224 auto *VD = dyn_cast<VarDecl>(D);
19232 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
19233 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
19235 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
19236 << getOpenMPClauseName(OMPC_shared);
19245 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
19247 ? RefExpr->IgnoreParens()
19259class DSARefChecker :
public StmtVisitor<DSARefChecker, bool> {
19264 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
19265 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD,
false);
19266 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
19268 if (DVar.CKind != OMPC_unknown)
19270 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
19277 return DVarPrivate.CKind != OMPC_unknown;
19281 bool VisitStmt(
Stmt *S) {
19282 for (
Stmt *Child : S->children()) {
19283 if (Child && Visit(Child))
19288 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
19295class TransformExprToCaptures :
public TreeTransform<TransformExprToCaptures> {
19302 : BaseTransform(SemaRef),
Field(
FieldDecl), CapturedExpr(nullptr) {}
19307 CapturedExpr =
buildCapture(SemaRef, Field, E,
false);
19308 return CapturedExpr;
19310 return BaseTransform::TransformMemberExpr(E);
19312 DeclRefExpr *getCapturedExpr() {
return CapturedExpr; }
19316template <
typename T,
typename U>
19319 for (
U &
Set : Lookups) {
19320 for (
auto *D :
Set) {
19321 if (
T Res = Gen(cast<ValueDecl>(D)))
19331 for (
auto *RD : D->
redecls()) {
19336 auto ND = cast<NamedDecl>(RD);
19354 AssociatedClasses);
19367 for (
auto *NS : AssociatedNamespaces) {
19380 for (
auto *D : R) {
19381 auto *Underlying = D;
19382 if (
auto *USD = dyn_cast<UsingShadowDecl>(D))
19383 Underlying = USD->getTargetDecl();
19385 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
19386 !isa<OMPDeclareMapperDecl>(Underlying))
19393 if (
auto *USD = dyn_cast<UsingShadowDecl>(D))
19394 Underlying = USD->getTargetDecl();
19396 Lookups.emplace_back();
19397 Lookups.back().addDecl(Underlying);
19417 S = S->getParent();
19418 }
while (S && !S->isDeclScope(D));
19420 S = S->getParent();
19421 Lookups.emplace_back();
19422 Lookups.back().append(Lookup.
begin(), Lookup.
end());
19425 }
else if (
auto *ULE =
19426 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
19428 Decl *PrevD =
nullptr;
19432 else if (
auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
19433 Lookups.back().addDecl(DRD);
19440 filterLookupForUDReductionAndMapper<bool>(Lookups, [](
ValueDecl *D) {
19441 return !D->isInvalidDecl() &&
19442 (D->getType()->isDependentType() ||
19443 D->getType()->isInstantiationDependentType() ||
19444 D->getType()->containsUnexpandedParameterPack());
19457 true, ResSet.
begin(), ResSet.
end(),
false);
19478 TyRec->getDecl()->getDefinition()) {
19481 if (Lookup.
empty()) {
19482 Lookups.emplace_back();
19483 Lookups.back().append(Lookup.
begin(), Lookup.
end());
19490 if (
auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
19500 if (
auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
19524 if (ReductionIdScopeSpec.
isSet()) {
19525 SemaRef.
Diag(
Loc, diag::err_omp_not_resolved_reduction_identifier)
19534struct ReductionData {
19559 unsigned RedModifier = 0;
19560 ReductionData() =
delete;
19562 ReductionData(
unsigned Size,
unsigned Modifier = 0) : RedModifier(Modifier) {
19563 Vars.reserve(Size);
19564 Privates.reserve(Size);
19565 LHSs.reserve(Size);
19566 RHSs.reserve(Size);
19567 ReductionOps.reserve(Size);
19568 if (RedModifier == OMPC_REDUCTION_inscan) {
19569 InscanCopyOps.reserve(Size);
19570 InscanCopyArrayTemps.reserve(Size);
19571 InscanCopyArrayElems.reserve(Size);
19573 TaskgroupDescriptors.reserve(Size);
19574 ExprCaptures.reserve(Size);
19575 ExprPostUpdates.reserve(Size);
19579 void push(
Expr *Item,
Expr *ReductionOp) {
19580 Vars.emplace_back(Item);
19581 Privates.emplace_back(
nullptr);
19582 LHSs.emplace_back(
nullptr);
19583 RHSs.emplace_back(
nullptr);
19584 ReductionOps.emplace_back(ReductionOp);
19585 TaskgroupDescriptors.emplace_back(
nullptr);
19586 if (RedModifier == OMPC_REDUCTION_inscan) {
19587 InscanCopyOps.push_back(
nullptr);
19588 InscanCopyArrayTemps.push_back(
nullptr);
19589 InscanCopyArrayElems.push_back(
nullptr);
19594 Expr *TaskgroupDescriptor,
Expr *CopyOp,
Expr *CopyArrayTemp,
19595 Expr *CopyArrayElem) {
19596 Vars.emplace_back(Item);
19597 Privates.emplace_back(Private);
19598 LHSs.emplace_back(LHS);
19599 RHSs.emplace_back(RHS);
19600 ReductionOps.emplace_back(ReductionOp);
19601 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
19602 if (RedModifier == OMPC_REDUCTION_inscan) {
19603 InscanCopyOps.push_back(CopyOp);
19604 InscanCopyArrayTemps.push_back(CopyArrayTemp);
19605 InscanCopyArrayElems.push_back(CopyArrayElem);
19607 assert(CopyOp ==
nullptr && CopyArrayTemp ==
nullptr &&
19608 CopyArrayElem ==
nullptr &&
19609 "Copy operation must be used for inscan reductions only.");
19619 if (Length ==
nullptr) {
19626 SingleElement =
true;
19627 ArraySizes.push_back(llvm::APSInt::get(1));
19630 if (!Length->EvaluateAsInt(
Result, Context))
19633 llvm::APSInt ConstantLengthValue =
Result.Val.getInt();
19634 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
19635 ArraySizes.push_back(ConstantLengthValue);
19643 while (
const auto *TempOASE = dyn_cast<ArraySectionExpr>(
Base)) {
19644 Length = TempOASE->getLength();
19645 if (Length ==
nullptr) {
19652 ArraySizes.push_back(llvm::APSInt::get(1));
19655 if (!Length->EvaluateAsInt(
Result, Context))
19658 llvm::APSInt ConstantLengthValue =
Result.Val.getInt();
19659 if (ConstantLengthValue.getSExtValue() != 1)
19662 ArraySizes.push_back(ConstantLengthValue);
19664 Base = TempOASE->getBase()->IgnoreParenImpCasts();
19668 if (!SingleElement) {
19669 while (
const auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base)) {
19671 ArraySizes.push_back(llvm::APSInt::get(1));
19672 Base = TempASE->getBase()->IgnoreParenImpCasts();
19684 return BO_AddAssign;
19686 return BO_MulAssign;
19688 return BO_AndAssign;
19690 return BO_OrAssign;
19692 return BO_XorAssign;
19748 case OO_Array_Delete:
19757 case OO_GreaterEqual:
19759 case OO_MinusEqual:
19761 case OO_SlashEqual:
19762 case OO_PercentEqual:
19763 case OO_CaretEqual:
19767 case OO_GreaterGreater:
19768 case OO_LessLessEqual:
19769 case OO_GreaterGreaterEqual:
19770 case OO_EqualEqual:
19771 case OO_ExclaimEqual:
19774 case OO_MinusMinus:
19780 case OO_Conditional:
19783 llvm_unreachable(
"Unexpected reduction identifier");
19786 if (II->isStr(
"max"))
19788 else if (II->isStr(
"min"))
19796 if (OOK == OO_Minus && S.
LangOpts.OpenMP == 52)
19797 S.
Diag(ReductionId.
getLoc(), diag::warn_omp_minus_in_reduction_deprecated);
19800 if (ReductionIdScopeSpec.
isValid())
19806 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
19807 bool FirstIter =
true;
19808 for (
Expr *RefExpr : VarList) {
19809 assert(RefExpr &&
"nullptr expr in OpenMP reduction clause.");
19817 if (!FirstIter && IR != ER)
19822 Expr *SimpleRefExpr = RefExpr;
19831 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
19832 ReductionId,
Type, BasePath, IR == ER ?
nullptr : *IR);
19833 Expr *ReductionOp =
nullptr;
19835 (DeclareReductionRef.
isUnset() ||
19836 isa<UnresolvedLookupExpr>(DeclareReductionRef.
get())))
19837 ReductionOp = DeclareReductionRef.
get();
19839 RD.push(RefExpr, ReductionOp);
19845 Expr *TaskgroupDescriptor =
nullptr;
19847 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
19848 auto *OASE = dyn_cast<ArraySectionExpr>(RefExpr->IgnoreParens());
19850 Type = ASE->getType().getNonReferenceType();
19855 Type = ATy->getElementType();
19858 Type =
Type.getNonReferenceType();
19862 auto *VD = dyn_cast<VarDecl>(D);
19868 diag::err_omp_reduction_incomplete_type))
19874 false, ASE || OASE))
19881 if (!ASE && !OASE) {
19883 VarDecl *VDDef = VD->getDefinition();
19885 DSARefChecker Check(Stack);
19886 if (Check.Visit(VDDef->
getInit())) {
19887 S.
Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
19888 << getOpenMPClauseName(ClauseKind) << ERange;
19906 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D,
false);
19907 if (DVar.CKind == OMPC_reduction) {
19908 S.
Diag(ELoc, diag::err_omp_once_referenced)
19909 << getOpenMPClauseName(ClauseKind);
19911 S.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
19914 if (DVar.CKind != OMPC_unknown) {
19915 S.
Diag(ELoc, diag::err_omp_wrong_dsa)
19916 << getOpenMPClauseName(DVar.CKind)
19917 << getOpenMPClauseName(OMPC_reduction);
19929 DVar = Stack->getImplicitDSA(D,
true);
19930 if (DVar.CKind != OMPC_shared) {
19931 S.
Diag(ELoc, diag::err_omp_required_access)
19932 << getOpenMPClauseName(OMPC_reduction)
19933 << getOpenMPClauseName(OMPC_shared);
19941 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D,
false);
19942 if (DVar.CKind == OMPC_threadprivate) {
19943 S.
Diag(ELoc, diag::err_omp_wrong_dsa)
19944 << getOpenMPClauseName(DVar.CKind)
19945 << getOpenMPClauseName(OMPC_reduction);
19955 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
19956 ReductionId,
Type, BasePath, IR == ER ?
nullptr : *IR);
19960 (DeclareReductionRef.
isUnset() ||
19961 isa<UnresolvedLookupExpr>(DeclareReductionRef.
get()))) {
19962 RD.push(RefExpr, DeclareReductionRef.
get());
19965 if (BOK == BO_Comma && DeclareReductionRef.
isUnset()) {
19969 diag::err_omp_unknown_reduction_identifier_since_omp_6_0)
19970 <<
Type << ReductionIdRange;
19973 diag::err_omp_unknown_reduction_identifier_prior_omp_6_0)
19974 <<
Type << ReductionIdRange;
19986 if (DeclareReductionRef.
isUnset()) {
19987 if ((BOK == BO_GT || BOK == BO_LT) &&
19990 S.
Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
19991 << getOpenMPClauseName(ClauseKind) << S.
getLangOpts().CPlusPlus;
19992 if (!ASE && !OASE) {
19993 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19996 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20001 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
20003 S.
Diag(ELoc, diag::err_omp_clause_floating_type_arg)
20004 << getOpenMPClauseName(ClauseKind);
20005 if (!ASE && !OASE) {
20006 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
20009 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20016 Type =
Type.getNonLValueExprType(Context).getUnqualifiedType();
20025 bool ConstantLengthOASE =
false;
20027 bool SingleElement;
20030 Context, OASE, SingleElement, ArraySizes);
20033 if (ConstantLengthOASE && !SingleElement) {
20034 for (llvm::APSInt &Size : ArraySizes)
20041 if ((OASE && !ConstantLengthOASE) ||
20046 S.
Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
20047 S.
Diag(ELoc, diag::note_vla_unsupported);
20050 S.
targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
20051 S.
targetDiag(ELoc, diag::note_vla_unsupported);
20064 }
else if (!ASE && !OASE &&
20072 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
20077 if (DeclareReductionRef.
isUsable()) {
20079 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
20080 if (DRD->getInitializer()) {
20106 Type = ComplexTy->getElementType();
20108 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
20115 llvm::APInt InitValue = llvm::APInt::getAllOnes(Size);
20137 llvm::APInt InitValue =
20138 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
20139 : llvm::APInt::getMinValue(Size)
20140 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
20141 : llvm::APInt::getMaxValue(Size);
20152 llvm::APFloat InitValue = llvm::APFloat::getLargest(
20183 llvm_unreachable(
"Unexpected reduction operation");
20192 }
else if (!
Init) {
20202 S.
Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
20203 <<
Type << ReductionIdRange;
20204 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
20207 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20213 if (DeclareReductionRef.
isUsable()) {
20218 if (!BasePath.empty()) {
20222 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.
get(), &BasePath,
20225 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.
get(), &BasePath,
20229 QualType Params[] = {PtrRedTy, PtrRedTy};
20244 CombBOK, LHSDRE, RHSDRE);
20251 if (BOK != BO_LT && BOK != BO_GT) {
20254 BO_Assign, LHSDRE, ReductionOp.
get());
20256 auto *ConditionalOp =
new (Context)
20261 BO_Assign, LHSDRE, ConditionalOp);
20274 ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
20275 if (ClauseKind == OMPC_reduction &&
20276 RD.RedModifier == OMPC_REDUCTION_inscan) {
20278 CopyOpRes = S.
BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
20288 if (Stack->getCurrentDirective() == OMPD_simd ||
20326 if (ClauseKind == OMPC_in_reduction) {
20329 const Expr *ParentReductionOp =
nullptr;
20330 Expr *ParentBOKTD =
nullptr, *ParentReductionOpTD =
nullptr;
20331 DSAStackTy::DSAVarData ParentBOKDSA =
20332 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
20334 DSAStackTy::DSAVarData ParentReductionOpDSA =
20335 Stack->getTopMostTaskgroupReductionData(
20336 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
20337 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
20338 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
20339 if ((DeclareReductionRef.
isUnset() && IsParentReductionOp) ||
20340 (DeclareReductionRef.
isUsable() && IsParentBOK) ||
20341 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
20342 bool EmitError =
true;
20343 if (IsParentReductionOp && DeclareReductionRef.
isUsable()) {
20344 llvm::FoldingSetNodeID RedId, ParentRedId;
20345 ParentReductionOp->
Profile(ParentRedId, Context,
true);
20346 DeclareReductionRef.
get()->
Profile(RedId, Context,
20348 EmitError = RedId != ParentRedId;
20352 diag::err_omp_reduction_identifier_mismatch)
20353 << ReductionIdRange << RefExpr->getSourceRange();
20355 diag::note_omp_previous_reduction_identifier)
20357 << (IsParentBOK ? ParentBOKDSA.RefExpr
20358 : ParentReductionOpDSA.RefExpr)
20359 ->getSourceRange();
20363 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
20370 TransformExprToCaptures RebuildToCapture(S, D);
20372 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
20373 Ref = RebuildToCapture.getCapturedExpr();
20375 VarsExpr = Ref =
buildCapture(S, D, SimpleRefExpr,
false);
20378 RD.ExprCaptures.emplace_back(Ref->
getDecl());
20384 S.
BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
20389 Stack->getCurrentDirective() == OMPD_taskgroup) {
20390 S.
Diag(RefExpr->getExprLoc(),
20391 diag::err_omp_reduction_non_addressable_expression)
20392 << RefExpr->getSourceRange();
20395 RD.ExprPostUpdates.emplace_back(
20402 unsigned Modifier = RD.RedModifier;
20405 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
20406 Modifier = OMPC_REDUCTION_task;
20407 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
20409 if (Modifier == OMPC_REDUCTION_task &&
20410 (CurrDir == OMPD_taskgroup ||
20414 if (DeclareReductionRef.
isUsable())
20415 Stack->addTaskgroupReductionData(D, ReductionIdRange,
20416 DeclareReductionRef.
get());
20418 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
20420 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.
get(),
20421 TaskgroupDescriptor, CopyOpRes.
get(), TempArrayRes.
get(),
20422 TempArrayElem.
get());
20424 return RD.Vars.empty();
20434 Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
20437 << getOpenMPClauseName(OMPC_reduction);
20445 if (Modifier == OMPC_REDUCTION_inscan &&
20446 (
DSAStack->getCurrentDirective() != OMPD_for &&
20447 DSAStack->getCurrentDirective() != OMPD_for_simd &&
20448 DSAStack->getCurrentDirective() != OMPD_simd &&
20449 DSAStack->getCurrentDirective() != OMPD_parallel_for &&
20450 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) {
20451 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
20455 ReductionData RD(VarList.size(), Modifier);
20457 StartLoc, LParenLoc, ColonLoc, EndLoc,
20458 ReductionIdScopeSpec, ReductionId,
20459 UnresolvedReductions, RD))
20463 getASTContext(), StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc,
20466 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
20467 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
20477 ReductionData RD(VarList.size());
20479 VarList, StartLoc, LParenLoc, ColonLoc,
20480 EndLoc, ReductionIdScopeSpec, ReductionId,
20481 UnresolvedReductions, RD))
20485 getASTContext(), StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
20487 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
20497 ReductionData RD(VarList.size());
20499 StartLoc, LParenLoc, ColonLoc, EndLoc,
20500 ReductionIdScopeSpec, ReductionId,
20501 UnresolvedReductions, RD))
20505 getASTContext(), StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
20507 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
20516 Diag(LinLoc, diag::err_omp_wrong_linear_modifier)
20526 const auto *VD = dyn_cast_or_null<VarDecl>(D);
20529 diag::err_omp_linear_incomplete_type))
20531 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
20533 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
20537 Type =
Type.getNonReferenceType();
20544 if (!IsDeclareSimd &&
20549 Type =
Type.getUnqualifiedType().getCanonicalType();
20550 const auto *Ty =
Type.getTypePtrOrNull();
20551 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
20552 !Ty->isIntegralType(
getASTContext()) && !Ty->isPointerType())) {
20553 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) <<
Type;
20555 bool IsDecl = !VD || VD->isThisDeclarationADefinition(
getASTContext()) ==
20558 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20581 Diag(Step->
getBeginLoc(), diag::err_omp_step_simple_modifier_exclusive);
20583 LinKind = OMPC_LINEAR_val;
20584 for (
Expr *RefExpr : VarList) {
20585 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
20588 Expr *SimpleRefExpr = RefExpr;
20592 Vars.push_back(RefExpr);
20593 Privates.push_back(
nullptr);
20594 Inits.push_back(
nullptr);
20601 auto *VD = dyn_cast<VarDecl>(D);
20607 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
20608 if (DVar.RefExpr) {
20609 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
20610 << getOpenMPClauseName(OMPC_linear);
20617 Type =
Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
20623 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
20632 ExprCaptures.push_back(Ref->
getDecl());
20639 SimpleRefExpr, RefRes.
get());
20642 ExprPostUpdates.push_back(
20647 if (LinKind == OMPC_LINEAR_uval)
20648 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
20650 InitExpr = VD ? SimpleRefExpr : Ref;
20656 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
20658 ? RefExpr->IgnoreParens()
20660 Privates.push_back(PrivateRef);
20661 Inits.push_back(InitRef);
20667 Expr *StepExpr = Step;
20668 Expr *CalcStepExpr =
nullptr;
20676 StepExpr = Val.
get();
20690 if (std::optional<llvm::APSInt>
Result =
20692 if (!
Result->isNegative() && !
Result->isStrictlyPositive())
20693 Diag(StepLoc, diag::warn_omp_linear_step_zero)
20694 << Vars[0] << (Vars.size() > 1);
20698 CalcStepExpr = CalcStep.
get();
20703 LinLoc, ColonLoc, StepModifierLoc, EndLoc,
20704 Vars, Privates, Inits, StepExpr, CalcStepExpr,
20710 Expr *NumIterations,
Sema &SemaRef,
20711 Scope *S, DSAStackTy *Stack) {
20723 Step = cast<BinaryOperator>(CalcStep)->getLHS();
20724 bool HasErrors =
false;
20725 auto CurInit = Clause.
inits().begin();
20726 auto CurPrivate = Clause.
privates().begin();
20731 Expr *SimpleRefExpr = RefExpr;
20732 auto Res =
getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
20734 if (Res.second || !D) {
20735 Updates.push_back(
nullptr);
20736 Finals.push_back(
nullptr);
20740 auto &&Info = Stack->isLoopControlVariable(D);
20747 diag::err_omp_linear_distribute_var_non_loop_iteration);
20748 Updates.push_back(
nullptr);
20749 Finals.push_back(
nullptr);
20753 Expr *InitExpr = *CurInit;
20756 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
20758 if (LinKind == OMPC_LINEAR_uval)
20759 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
20763 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
20770 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
20781 S, RefExpr->getExprLoc(), BO_Assign, CapturedRef,
20784 Final = *CurPrivate;
20788 if (!
Update.isUsable() || !Final.isUsable()) {
20789 Updates.push_back(
nullptr);
20790 Finals.push_back(
nullptr);
20791 UsedExprs.push_back(
nullptr);
20794 Updates.push_back(
Update.get());
20795 Finals.push_back(Final.get());
20797 UsedExprs.push_back(SimpleRefExpr);
20803 UsedExprs.push_back(S);
20805 UsedExprs.append(Clause.
varlist_size() + 1 - UsedExprs.size(),
nullptr);
20816 for (
Expr *RefExpr : VarList) {
20817 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
20820 Expr *SimpleRefExpr = RefExpr;
20824 Vars.push_back(RefExpr);
20831 auto *VD = dyn_cast<VarDecl>(D);
20839 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
20841 bool IsDecl = !VD || VD->isThisDeclarationADefinition(
getASTContext()) ==
20844 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20851 if (
const Expr *PrevRef =
DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
20852 Diag(ELoc, diag::err_omp_used_in_clause_twice)
20853 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
20854 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
20855 << getOpenMPClauseName(OMPC_aligned);
20863 .DefaultFunctionArrayConversion(
20864 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
20873 if (Alignment !=
nullptr) {
20878 Alignment = AlignResult.
get();
20884 ColonLoc, EndLoc, Vars, Alignment);
20895 for (
Expr *RefExpr : VarList) {
20896 assert(RefExpr &&
"NULL expr in OpenMP copyin clause.");
20897 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
20899 Vars.push_back(RefExpr);
20900 SrcExprs.push_back(
nullptr);
20901 DstExprs.push_back(
nullptr);
20902 AssignmentOps.push_back(
nullptr);
20911 auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
20912 if (!DE || !isa<VarDecl>(DE->getDecl())) {
20913 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
20914 << 0 << RefExpr->getSourceRange();
20918 Decl *D = DE->getDecl();
20919 auto *VD = cast<VarDecl>(D);
20924 Vars.push_back(DE);
20925 SrcExprs.push_back(
nullptr);
20926 DstExprs.push_back(
nullptr);
20927 AssignmentOps.push_back(
nullptr);
20933 if (!
DSAStack->isThreadPrivate(VD)) {
20934 Diag(ELoc, diag::err_omp_required_access)
20935 << getOpenMPClauseName(OMPC_copyin)
20936 << getOpenMPDirectiveName(OMPD_threadprivate);
20960 PseudoDstExpr, PseudoSrcExpr);
20969 DSAStack->addDSA(VD, DE, OMPC_copyin);
20970 Vars.push_back(DE);
20971 SrcExprs.push_back(PseudoSrcExpr);
20972 DstExprs.push_back(PseudoDstExpr);
20973 AssignmentOps.push_back(AssignmentOp.
get());
20980 Vars, SrcExprs, DstExprs, AssignmentOps);
20991 for (
Expr *RefExpr : VarList) {
20992 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
20995 Expr *SimpleRefExpr = RefExpr;
20999 Vars.push_back(RefExpr);
21000 SrcExprs.push_back(
nullptr);
21001 DstExprs.push_back(
nullptr);
21002 AssignmentOps.push_back(
nullptr);
21009 auto *VD = dyn_cast<VarDecl>(D);
21014 if (!VD || !
DSAStack->isThreadPrivate(VD)) {
21015 DSAStackTy::DSAVarData DVar =
21017 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
21019 Diag(ELoc, diag::err_omp_wrong_dsa)
21020 << getOpenMPClauseName(DVar.CKind)
21021 << getOpenMPClauseName(OMPC_copyprivate);
21029 if (DVar.CKind == OMPC_unknown) {
21030 DVar =
DSAStack->getImplicitDSA(D,
false);
21031 if (DVar.CKind == OMPC_shared) {
21032 Diag(ELoc, diag::err_omp_required_access)
21033 << getOpenMPClauseName(OMPC_copyprivate)
21034 <<
"threadprivate or private in the enclosing context";
21043 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
21044 << getOpenMPClauseName(OMPC_copyprivate) <<
Type
21045 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
21046 bool IsDecl = !VD || VD->isThisDeclarationADefinition(
getASTContext()) ==
21049 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
21070 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
21082 VD ? RefExpr->IgnoreParens()
21084 SrcExprs.push_back(PseudoSrcExpr);
21085 DstExprs.push_back(PseudoDstExpr);
21086 AssignmentOps.push_back(AssignmentOp.
get());
21093 EndLoc, Vars, SrcExprs, DstExprs,
21101 if (VarList.empty())
21110 bool Diagnose =
true) {
21111 QualType OMPDependT = Stack->getOMPDependT();
21112 if (!OMPDependT.
isNull())
21118 S.
Diag(
Loc, diag::err_omp_implied_type_not_found) <<
"omp_depend_t";
21121 Stack->setOMPDependT(PT.
get());
21142 Diag(Depobj->
getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
21147 Diag(Depobj->
getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
21157struct DoacrossDataInfoTy {
21163 llvm::APSInt TotalDepCount;
21166static DoacrossDataInfoTy
21173 llvm::APSInt DepCounter(32);
21174 llvm::APSInt TotalDepCount(32);
21176 if (
const Expr *OrderedCountExpr =
21177 Stack->getParentOrderedRegionParam().first) {
21178 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(SemaRef.
Context);
21179 TotalDepCount.setIsUnsigned(
true);
21182 for (
Expr *RefExpr : VarList) {
21183 assert(RefExpr &&
"NULL expr in OpenMP doacross clause.");
21184 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
21186 Vars.push_back(RefExpr);
21193 if (Stack->getParentOrderedRegionParam().first &&
21194 DepCounter >= TotalDepCount) {
21195 SemaRef.
Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
21209 Vars.push_back(RefExpr);
21215 Expr *LHS = SimpleExpr;
21216 Expr *RHS =
nullptr;
21217 if (
auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
21219 OOLoc = BO->getOperatorLoc();
21222 }
else if (
auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
21223 OOK = OCE->getOperator();
21224 OOLoc = OCE->getOperatorLoc();
21227 }
else if (
auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
21228 OOK = MCE->getMethodDecl()
21231 .getCXXOverloadedOperator();
21232 OOLoc = MCE->getCallee()->getExprLoc();
21241 Vars.push_back(RefExpr);
21247 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK !=
OO_None)) {
21248 SemaRef.
Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
21254 RHS, OMPC_depend,
false);
21259 Stack->getParentOrderedRegionParam().first &&
21260 DepCounter != Stack->isParentLoopControlVariable(D).first) {
21262 Stack->getParentLoopControlVariable(DepCounter.getZExtValue());
21264 SemaRef.
Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
21267 SemaRef.
Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
21271 OpsOffs.emplace_back(RHS, OOK);
21273 Vars.push_back(RefExpr->IgnoreParenImpCasts());
21276 TotalDepCount > VarList.size() &&
21277 Stack->getParentOrderedRegionParam().first &&
21278 Stack->getParentLoopControlVariable(VarList.size() + 1)) {
21279 SemaRef.
Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
21280 << 1 << Stack->getParentLoopControlVariable(VarList.size() + 1);
21282 return {Vars, OpsOffs, TotalDepCount};
21291 if (
DSAStack->getCurrentDirective() == OMPD_ordered &&
21292 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
21293 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
21294 <<
"'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
21297 if (
DSAStack->getCurrentDirective() == OMPD_taskwait &&
21298 DepKind == OMPC_DEPEND_mutexinoutset) {
21299 Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed);
21302 if ((
DSAStack->getCurrentDirective() != OMPD_ordered ||
21303 DSAStack->getCurrentDirective() == OMPD_depobj) &&
21305 DepKind == OMPC_DEPEND_sink ||
21307 DSAStack->getCurrentDirective() == OMPD_depobj) &&
21308 DepKind == OMPC_DEPEND_depobj))) {
21310 OMPC_DEPEND_outallmemory,
21311 OMPC_DEPEND_inoutallmemory};
21313 DSAStack->getCurrentDirective() == OMPD_depobj)
21314 Except.push_back(OMPC_DEPEND_depobj);
21316 Except.push_back(OMPC_DEPEND_inoutset);
21318 ?
"depend modifier(iterator) or "
21320 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
21324 << getOpenMPClauseName(OMPC_depend);
21328 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
21330 diag::err_omp_depend_sink_source_with_modifier);
21335 Diag(DepModifier->
getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
21339 llvm::APSInt TotalDepCount(32);
21341 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
21344 Vars = VarOffset.Vars;
21345 OpsOffs = VarOffset.OpsOffs;
21346 TotalDepCount = VarOffset.TotalDepCount;
21348 for (
Expr *RefExpr : VarList) {
21349 assert(RefExpr &&
"NULL expr in OpenMP shared clause.");
21350 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
21352 Vars.push_back(RefExpr);
21358 if (DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) {
21359 bool OMPDependTFound =
getLangOpts().OpenMP >= 50;
21360 if (OMPDependTFound)
21362 DepKind == OMPC_DEPEND_depobj);
21363 if (DepKind == OMPC_DEPEND_depobj) {
21367 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
21368 !RefExpr->isInstantiationDependent() &&
21369 !RefExpr->containsUnexpandedParameterPack() &&
21370 (OMPDependTFound &&
21372 DSAStack->getOMPDependT(), RefExpr->getType()))) {
21373 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
21374 << 0 << RefExpr->getType() << RefExpr->getSourceRange();
21377 if (!RefExpr->isLValue()) {
21378 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
21379 << 1 << RefExpr->getType() << RefExpr->getSourceRange();
21386 QualType ExprTy = RefExpr->getType().getNonReferenceType();
21387 const auto *OASE = dyn_cast<ArraySectionExpr>(SimpleExpr);
21394 ExprTy = ATy->getElementType();
21400 const Expr *Length = OASE->getLength();
21402 if (Length && !Length->isValueDependent() &&
21404 Result.Val.getInt().isZero()) {
21406 diag::err_omp_depend_zero_length_array_section_not_allowed)
21416 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
21417 !RefExpr->isInstantiationDependent() &&
21418 !RefExpr->containsUnexpandedParameterPack() &&
21419 (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
21420 (OMPDependTFound &&
DSAStack->getOMPDependT().getTypePtr() ==
21422 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21425 << RefExpr->getSourceRange();
21429 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
21430 if (ASE && !ASE->getBase()->isTypeDependent() &&
21433 .getNonReferenceType()
21434 ->isPointerType() &&
21435 !ASE->getBase()->getType().getNonReferenceType()->isArrayType()) {
21436 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21439 << RefExpr->getSourceRange();
21447 RefExpr->IgnoreParenImpCasts());
21449 if (!Res.
isUsable() && !isa<ArraySectionExpr>(SimpleExpr) &&
21450 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
21451 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21454 << RefExpr->getSourceRange();
21459 Vars.push_back(RefExpr->IgnoreParenImpCasts());
21463 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
21464 DepKind != OMPC_DEPEND_outallmemory &&
21465 DepKind != OMPC_DEPEND_inoutallmemory && Vars.empty())
21470 {DepKind, DepLoc,
Data.ColonLoc,
Data.OmpAllMemoryLoc}, DepModifier, Vars,
21471 TotalDepCount.getZExtValue());
21472 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
21473 DSAStack->isParentOrderedRegion())
21474 DSAStack->addDoacrossDependClause(
C, OpsOffs);
21483 "Unexpected device modifier in OpenMP < 50.");
21485 bool ErrorFound =
false;
21487 std::string Values =
21489 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
21490 << Values << getOpenMPClauseName(OMPC_device);
21495 Stmt *HelperValStmt =
nullptr;
21508 if (Modifier == OMPC_DEVICE_ancestor) {
21512 diag::err_omp_device_ancestor_without_requires_reverse_offload);
21520 if (CaptureRegion != OMPD_unknown &&
21523 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
21524 ValExpr = tryBuildCapture(
SemaRef, ValExpr, Captures).get();
21529 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
21530 LParenLoc, ModifierLoc, EndLoc);
21535 bool FullCheck =
true) {
21540 SemaRef.
Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
21550 const auto *OASE = dyn_cast<ArraySectionExpr>(E);
21555 if (isa<ArraySubscriptExpr>(E) ||
21556 (OASE && OASE->getColonLocFirst().isInvalid())) {
21557 if (
const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
21558 return ATy->getSExtSize() != 1;
21563 assert(OASE &&
"Expecting array section if not an array subscript.");
21564 const Expr *LowerBound = OASE->getLowerBound();
21565 const Expr *Length = OASE->getLength();
21574 llvm::APSInt ConstLowerBound =
Result.Val.getInt();
21575 if (ConstLowerBound.getSExtValue())
21590 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr());
21598 llvm::APSInt ConstLength =
Result.Val.getInt();
21599 return CATy->getSExtSize() != ConstLength.getSExtValue();
21608 const auto *OASE = dyn_cast<ArraySectionExpr>(E);
21612 if (isa<ArraySubscriptExpr>(E) ||
21613 (OASE && OASE->getColonLocFirst().isInvalid()))
21616 assert(OASE &&
"Expecting array section if not an array subscript.");
21617 const Expr *Length = OASE->getLength();
21623 if (
const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
21624 return ATy->getSExtSize() != 1;
21634 llvm::APSInt ConstLength =
Result.Val.getInt();
21635 return ConstLength.getSExtValue() != 1;
21674class MapBaseChecker final :
public StmtVisitor<MapBaseChecker, bool> {
21679 bool IsNonContiguous =
false;
21680 bool NoDiagnose =
false;
21681 const Expr *RelevantExpr =
nullptr;
21682 bool AllowUnitySizeArraySection =
true;
21683 bool AllowWholeSizeArraySection =
true;
21684 bool AllowAnotherPtr =
true;
21688 void emitErrorMsg() {
21690 if (SemaRef.getLangOpts().OpenMP < 50) {
21692 diag::err_omp_expected_named_var_member_or_array_expression)
21695 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
21696 << getOpenMPClauseName(CKind) << ERange;
21702 if (!isa<VarDecl>(DRE->
getDecl())) {
21706 assert(!RelevantExpr &&
"RelevantExpr is expected to be nullptr");
21707 RelevantExpr = DRE;
21709 Components.emplace_back(DRE, DRE->
getDecl(), IsNonContiguous);
21717 if (isa<CXXThisExpr>(BaseE)) {
21718 assert(!RelevantExpr &&
"RelevantExpr is expected to be nullptr");
21727 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
21743 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
21763 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
21767 return RelevantExpr || Visit(E);
21777 AllowUnitySizeArraySection =
false;
21778 AllowWholeSizeArraySection =
false;
21781 Components.emplace_back(ME, FD, IsNonContiguous);
21782 return RelevantExpr || Visit(E);
21790 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
21794 return RelevantExpr || Visit(E);
21801 AllowWholeSizeArraySection =
false;
21807 !Result.Val.getInt().isZero()) {
21809 diag::err_omp_invalid_map_this_expr);
21811 diag::note_omp_invalid_subscript_on_this_ptr_map);
21813 assert(!RelevantExpr &&
"RelevantExpr is expected to be nullptr");
21818 Components.emplace_back(AE,
nullptr, IsNonContiguous);
21820 return RelevantExpr || Visit(E);
21826 assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) &&
21827 "Array sections cannot be implicitly mapped.");
21841 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
21851 if (AllowWholeSizeArraySection) {
21858 if (NotWhole || IsPointer)
21859 AllowWholeSizeArraySection =
false;
21860 }
else if (DKind == OMPD_target_update &&
21861 SemaRef.getLangOpts().OpenMP >= 50) {
21862 if (IsPointer && !AllowAnotherPtr)
21863 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
21866 IsNonContiguous =
true;
21867 }
else if (AllowUnitySizeArraySection && NotUnity) {
21873 diag::err_array_section_does_not_specify_contiguous_storage)
21879 AllowAnotherPtr =
false;
21881 if (
const auto *TE = dyn_cast<CXXThisExpr>(E)) {
21888 diag::err_omp_invalid_map_this_expr);
21890 diag::note_omp_invalid_length_on_this_ptr_mapping);
21894 SemaRef.getASTContext()) &&
21897 diag::err_omp_invalid_map_this_expr);
21899 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
21901 assert(!RelevantExpr &&
"RelevantExpr is expected to be nullptr");
21906 Components.emplace_back(OASE,
nullptr,
false);
21907 return RelevantExpr || Visit(E);
21913 Components.emplace_back(E,
nullptr, IsNonContiguous);
21915 return Visit(
Base->IgnoreParenImpCasts());
21919 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->
isLValue() ||
21924 if (!RelevantExpr) {
21926 Components.emplace_back(UO,
nullptr,
false);
21942 Components.emplace_back(BO,
nullptr,
false);
21945 "Either LHS or RHS have base decl inside");
21947 return RelevantExpr || Visit(LE);
21948 return RelevantExpr || Visit(RE);
21951 assert(!RelevantExpr &&
"RelevantExpr is expected to be nullptr");
21952 RelevantExpr = CTE;
21953 Components.emplace_back(CTE,
nullptr, IsNonContiguous);
21957 assert(!RelevantExpr &&
"RelevantExpr is expected to be nullptr");
21958 Components.emplace_back(COCE,
nullptr, IsNonContiguous);
21967 return Visit(Source);
21969 bool VisitStmt(
Stmt *) {
21973 const Expr *getFoundBase()
const {
return RelevantExpr; }
21974 explicit MapBaseChecker(
21978 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
21979 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
21993 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
21997 if (SemaRef.
getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
21998 (CKind == OMPC_to || CKind == OMPC_from)) {
21999 auto CI = CurComponents.rbegin();
22000 auto CE = CurComponents.rend();
22001 for (; CI != CE; ++CI) {
22003 dyn_cast<ArraySectionExpr>(CI->getAssociatedExpression());
22008 SemaRef.
Diag(ELoc, diag::err_array_section_does_not_specify_length)
22012 return Checker.getFoundBase();
22021 bool CurrentRegionOnly,
22032 assert(!CurComponents.empty() &&
"Map clause expression with no components!");
22033 assert(CurComponents.back().getAssociatedDeclaration() == VD &&
22034 "Map clause expression with unexpected base!");
22037 bool IsEnclosedByDataEnvironmentExpr =
false;
22038 const Expr *EnclosingExpr =
nullptr;
22040 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
22041 VD, CurrentRegionOnly,
22042 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
22043 ERange, CKind, &EnclosingExpr,
22047 if (CKind == Kind && SemaRef.
LangOpts.OpenMP >= 50)
22049 assert(!StackComponents.empty() &&
22050 "Map clause expression with no components!");
22051 assert(StackComponents.back().getAssociatedDeclaration() == VD &&
22052 "Map clause expression with unexpected base!");
22056 const Expr *RE = StackComponents.front().getAssociatedExpression();
22062 auto CI = CurComponents.rbegin();
22063 auto CE = CurComponents.rend();
22064 auto SI = StackComponents.rbegin();
22065 auto SE = StackComponents.rend();
22066 for (; CI != CE && SI != SE; ++CI, ++SI) {
22071 if (CurrentRegionOnly &&
22072 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
22073 isa<ArraySectionExpr>(CI->getAssociatedExpression()) ||
22074 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
22075 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
22076 isa<ArraySectionExpr>(SI->getAssociatedExpression()) ||
22077 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
22078 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
22079 diag::err_omp_multiple_array_items_in_map_clause)
22080 << CI->getAssociatedExpression()->getSourceRange();
22081 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
22082 diag::note_used_here)
22083 << SI->getAssociatedExpression()->getSourceRange();
22088 if (CI->getAssociatedExpression()->getStmtClass() !=
22089 SI->getAssociatedExpression()->getStmtClass())
22093 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
22099 for (; SI != SE; ++SI) {
22101 if (
const auto *ASE =
22102 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
22103 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
22104 }
else if (
const auto *OASE = dyn_cast<ArraySectionExpr>(
22105 SI->getAssociatedExpression())) {
22106 const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
22107 Type = ArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
22108 }
else if (
const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
22109 SI->getAssociatedExpression())) {
22110 Type = OASE->getBase()->getType()->getPointeeType();
22114 SemaRef, SI->getAssociatedExpression(),
Type))
22124 if (CI == CE && SI == SE) {
22125 if (CurrentRegionOnly) {
22126 if (CKind == OMPC_map) {
22127 SemaRef.
Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
22129 assert(CKind == OMPC_to || CKind == OMPC_from);
22130 SemaRef.
Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
22139 IsEnclosedByDataEnvironmentExpr =
true;
22144 std::prev(CI)->getAssociatedDeclaration()->getType();
22146 std::prev(CI)->getAssociatedExpression()->getExprLoc();
22165 if (CI == CE || SI == SE) {
22168 diag::err_omp_pointer_mapped_along_with_derived_section)
22174 if (CI->getAssociatedExpression()->getStmtClass() !=
22175 SI->getAssociatedExpression()->getStmtClass() ||
22176 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
22177 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
22178 assert(CI != CE && SI != SE);
22179 SemaRef.
Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
22192 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
22193 if (CKind == OMPC_map) {
22194 if (CI != CE || SI != SE) {
22198 CI != CE ? CurComponents.begin() : StackComponents.begin();
22199 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
22201 while (It != End && !It->getAssociatedDeclaration())
22202 std::advance(It, 1);
22203 assert(It != End &&
22204 "Expected at least one component with the declaration.");
22205 if (It !=
Begin && It->getAssociatedDeclaration()
22207 .getCanonicalType()
22208 ->isAnyPointerType()) {
22209 IsEnclosedByDataEnvironmentExpr =
false;
22210 EnclosingExpr =
nullptr;
22214 SemaRef.
Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
22216 assert(CKind == OMPC_to || CKind == OMPC_from);
22217 SemaRef.
Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
22227 if (!CurrentRegionOnly && SI != SE)
22228 EnclosingExpr = RE;
22232 IsEnclosedByDataEnvironmentExpr |=
22233 (!CurrentRegionOnly && CI != CE && SI == SE);
22238 if (CurrentRegionOnly)
22252 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
22254 diag::err_omp_original_storage_is_shared_and_does_not_contain)
22270 Expr *UnresolvedMapper) {
22286 while (S && !S->isDeclScope(D))
22287 S = S->getParent();
22289 S = S->getParent();
22290 Lookups.emplace_back();
22291 Lookups.back().append(Lookup.
begin(), Lookup.
end());
22294 }
else if (
auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
22298 auto *DMD = cast<OMPDeclareMapperDecl>(D);
22299 assert(DMD &&
"Expect valid OMPDeclareMapperDecl during instantiation.");
22300 Lookups.back().addDecl(DMD);
22308 filterLookupForUDReductionAndMapper<bool>(Lookups, [](
ValueDecl *D) {
22309 return !D->isInvalidDecl() &&
22310 (D->getType()->isDependentType() ||
22311 D->getType()->isInstantiationDependentType() ||
22312 D->getType()->containsUnexpandedParameterPack());
22323 false, URS.
begin(), URS.
end(),
false);
22330 SemaRef.
Diag(
Loc, diag::err_omp_mapper_wrong_type);
22337 if (
auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
22347 if (
auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
22370 SemaRef.
Diag(
Loc, diag::err_omp_invalid_mapper)
22380struct MappableVarListInfo {
22395 VarComponents.reserve(VarList.size());
22396 VarBaseDeclarations.reserve(VarList.size());
22414 bool IsMapTypeImplicit =
false,
bool NoDiagnose =
false) {
22416 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
22417 "Unexpected clause kind with mappable expressions!");
22425 MapperId.
setName(DeclNames.getIdentifier(
22427 MapperId.
setLoc(StartLoc);
22431 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
22432 bool UpdateUMIt =
false;
22433 Expr *UnresolvedMapper =
nullptr;
22435 bool HasHoldModifier =
22436 llvm::is_contained(Modifiers, OMPC_MAP_MODIFIER_ompx_hold);
22444 for (
Expr *RE : MVLI.VarList) {
22445 assert(RE &&
"Null expr in omp to/from/map clause");
22449 if (UpdateUMIt && UMIt != UMEnd) {
22453 "Expect the size of UnresolvedMappers to match with that of VarList");
22457 UnresolvedMapper = *UMIt;
22466 SemaRef, DSAS->
getCurScope(), MapperIdScopeSpec, MapperId,
22470 MVLI.UDMapperList.push_back(ER.
get());
22473 MVLI.ProcessedVarList.push_back(RE);
22482 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
22485 SemaRef.
Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
22498 DSAS->getCurrentDirective(), NoDiagnose);
22502 assert(!CurComponents.empty() &&
22503 "Invalid mappable expression information.");
22505 if (
const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
22507 DSAS->addMappedClassesQualTypes(TE->getType());
22510 SemaRef, DSAS->
getCurScope(), MapperIdScopeSpec, MapperId,
22514 MVLI.UDMapperList.push_back(ER.
get());
22516 MVLI.ProcessedVarList.push_back(RE);
22517 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22518 MVLI.VarComponents.back().append(CurComponents.begin(),
22519 CurComponents.end());
22520 MVLI.VarBaseDeclarations.push_back(
nullptr);
22527 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
22528 assert(CurDeclaration &&
"Null decl on map clause.");
22531 "Expecting components to have associated only canonical declarations.");
22533 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
22534 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
22536 assert((VD || FD) &&
"Only variables or fields are expected here!");
22543 if (VD && DSAS->isThreadPrivate(VD)) {
22546 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD,
false);
22547 SemaRef.
Diag(ELoc, diag::err_omp_threadprivate_in_clause)
22548 << getOpenMPClauseName(CKind);
22562 true, CurComponents, CKind))
22564 if (CKind == OMPC_map &&
22567 false, CurComponents, CKind))
22574 auto I = llvm::find_if(
22579 assert(I != CurComponents.end() &&
"Null decl on map clause.");
22582 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->
IgnoreParens());
22583 auto *OASE = dyn_cast<ArraySectionExpr>(VE->
IgnoreParens());
22584 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->
IgnoreParens());
22586 Type = ASE->getType().getNonReferenceType();
22591 Type = ATy->getElementType();
22594 Type =
Type.getNonReferenceType();
22595 }
else if (OAShE) {
22609 if (CKind == OMPC_map) {
22616 if (DKind == OMPD_target_enter_data &&
22617 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc ||
22619 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
22620 << (IsMapTypeImplicit ? 1 : 0)
22622 << getOpenMPDirectiveName(DKind);
22631 if (DKind == OMPD_target_exit_data &&
22632 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
22633 MapType == OMPC_MAP_delete || SemaRef.
getLangOpts().OpenMP >= 52)) {
22634 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
22635 << (IsMapTypeImplicit ? 1 : 0)
22637 << getOpenMPDirectiveName(DKind);
22646 if ((DKind == OMPD_target_enter_data || DKind == OMPD_target_exit_data) &&
22648 SemaRef.
Diag(StartLoc,
22649 diag::err_omp_invalid_map_type_modifier_for_directive)
22651 OMPC_MAP_MODIFIER_ompx_hold)
22652 << getOpenMPDirectiveName(DKind);
22660 if ((DKind == OMPD_target_data ||
22662 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
22663 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
22664 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
22665 << (IsMapTypeImplicit ? 1 : 0)
22667 << getOpenMPDirectiveName(DKind);
22679 if (VD && ((SemaRef.
LangOpts.OpenMP <= 45 &&
22681 DKind == OMPD_target)) {
22682 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD,
false);
22684 SemaRef.
Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
22685 << getOpenMPClauseName(DVar.CKind)
22686 << getOpenMPClauseName(OMPC_map)
22687 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
22696 SemaRef, DSAS->
getCurScope(), MapperIdScopeSpec, MapperId,
22697 Type.getCanonicalType(), UnresolvedMapper);
22700 MVLI.UDMapperList.push_back(ER.
get());
22703 MVLI.ProcessedVarList.push_back(RE);
22707 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
22713 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22714 MVLI.VarComponents.back().append(CurComponents.begin(),
22715 CurComponents.end());
22716 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ?
nullptr
22736 BuiltinType::OMPIterator))
22738 diag::err_omp_map_modifier_not_iterator);
22741 unsigned Count = 0;
22742 for (
unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
22744 llvm::is_contained(Modifiers, MapTypeModifiers[I])) {
22745 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
22749 "Modifiers exceed the allowed number of map type modifiers");
22750 Modifiers[Count] = MapTypeModifiers[I];
22751 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
22755 MappableVarListInfo MVLI(VarList);
22757 MapperIdScopeSpec, MapperId, UnresolvedMappers,
22758 MapType, Modifiers, IsMapTypeImplicit,
22764 getASTContext(), Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
22765 MVLI.VarComponents, MVLI.UDMapperList, IteratorModifier, Modifiers,
22767 MapperId, MapType, IsMapTypeImplicit, MapLoc);
22775 if (ReductionType.
isNull())
22783 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
22788 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
22792 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
22796 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
22799 return ReductionType;
22805 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
22808 Decls.reserve(ReductionTypes.size());
22817 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
22819 bool InCompoundScope =
true;
22820 if (S !=
nullptr) {
22829 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
22831 while (Filter.hasNext()) {
22832 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
22833 if (InCompoundScope) {
22834 auto I = UsedAsPrevious.find(PrevDecl);
22835 if (I == UsedAsPrevious.end())
22836 UsedAsPrevious[PrevDecl] =
false;
22838 UsedAsPrevious[D] =
true;
22840 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
22841 PrevDecl->getLocation();
22844 if (InCompoundScope) {
22845 for (
const auto &PrevData : UsedAsPrevious) {
22846 if (!PrevData.second) {
22847 PrevDRD = PrevData.first;
22852 }
else if (PrevDeclInScope !=
nullptr) {
22853 auto *PrevDRDInScope = PrevDRD =
22854 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
22856 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
22857 PrevDRDInScope->getLocation();
22858 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
22859 }
while (PrevDRDInScope !=
nullptr);
22861 for (
const auto &TyData : ReductionTypes) {
22862 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
22864 if (I != PreviousRedeclTypes.end()) {
22865 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
22867 Diag(I->second, diag::note_previous_definition);
22870 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
22872 getASTContext(), DC, TyData.second, Name, TyData.first, PrevDRD);
22874 DRD->setAccess(AS);
22875 Decls.push_back(DRD);
22877 DRD->setInvalidDecl();
22887 auto *DRD = cast<OMPDeclareReductionDecl>(D);
22902 QualType ReductionType = DRD->getType();
22919 if (S !=
nullptr) {
22923 DRD->addDecl(OmpInParm);
22924 DRD->addDecl(OmpOutParm);
22930 DRD->setCombinerData(InE, OutE);
22935 auto *DRD = cast<OMPDeclareReductionDecl>(D);
22942 if (Combiner !=
nullptr)
22943 DRD->setCombiner(Combiner);
22945 DRD->setInvalidDecl();
22950 auto *DRD = cast<OMPDeclareReductionDecl>(D);
22964 QualType ReductionType = DRD->getType();
22981 if (S !=
nullptr) {
22985 DRD->addDecl(OmpPrivParm);
22986 DRD->addDecl(OmpOrigParm);
22992 DRD->setInitializerData(OrigE, PrivE);
22993 return OmpPrivParm;
22998 auto *DRD = cast<OMPDeclareReductionDecl>(D);
23007 }
else if (OmpPrivParm->
hasInit()) {
23008 DRD->setInitializer(OmpPrivParm->
getInit(),
23013 DRD->setInvalidDecl();
23019 for (
Decl *D : DeclReductions.
get()) {
23025 D->setInvalidDecl();
23028 return DeclReductions;
23048 assert(
ParsedType.isUsable() &&
"Expect usable parsed mapper type");
23051 assert(!MapperType.
isNull() &&
"Expect valid mapper type");
23056 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
23073 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
23075 bool InCompoundScope =
true;
23076 if (S !=
nullptr) {
23085 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
23087 while (Filter.hasNext()) {
23088 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
23089 if (InCompoundScope) {
23090 auto I = UsedAsPrevious.find(PrevDecl);
23091 if (I == UsedAsPrevious.end())
23092 UsedAsPrevious[PrevDecl] =
false;
23094 UsedAsPrevious[D] =
true;
23096 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
23097 PrevDecl->getLocation();
23100 if (InCompoundScope) {
23101 for (
const auto &PrevData : UsedAsPrevious) {
23102 if (!PrevData.second) {
23103 PrevDMD = PrevData.first;
23108 }
else if (PrevDeclInScope) {
23109 auto *PrevDMDInScope = PrevDMD =
23110 cast<OMPDeclareMapperDecl>(PrevDeclInScope);
23112 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
23113 PrevDMDInScope->getLocation();
23114 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
23115 }
while (PrevDMDInScope !=
nullptr);
23119 if (I != PreviousRedeclTypes.end()) {
23120 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
23121 << MapperType << Name;
23122 Diag(I->second, diag::note_previous_definition);
23131 ClausesWithImplicit);
23133 MapperType, VN, ClausesWithImplicit,
23139 DMD->setAccess(AS);
23141 DMD->setInvalidDecl();
23143 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
23147 DMD->setMapperVarRef(MapperVarRef);
23163 DSAStack->addDeclareMapperVarRef(E);
23168 if (
DSAStack->getDeclareMapperVarRef())
23173 assert(
getLangOpts().OpenMP &&
"Expected OpenMP mode.");
23175 if (
const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) {
23188 assert(
getLangOpts().OpenMP &&
"Expected OpenMP mode.");
23189 return cast<DeclRefExpr>(
DSAStack->getDeclareMapperVarRef())->getDecl();
23196 Expr *ValExpr = NumTeams;
23197 Stmt *HelperValStmt =
nullptr;
23208 if (CaptureRegion != OMPD_unknown &&
23211 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
23212 ValExpr = tryBuildCapture(
SemaRef, ValExpr, Captures).get();
23217 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
23224 Expr *ValExpr = ThreadLimit;
23225 Stmt *HelperValStmt =
nullptr;
23236 if (CaptureRegion != OMPD_unknown &&
23239 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
23240 ValExpr = tryBuildCapture(
SemaRef, ValExpr, Captures).get();
23245 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
23253 Stmt *HelperValStmt =
nullptr;
23259 ValExpr,
SemaRef, OMPC_priority,
23261 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
23265 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
23273 "Unexpected grainsize modifier in OpenMP < 51.");
23278 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
23279 << Values << getOpenMPClauseName(OMPC_grainsize);
23283 Expr *ValExpr = Grainsize;
23284 Stmt *HelperValStmt =
nullptr;
23294 &CaptureRegion, &HelperValStmt))
23299 StartLoc, LParenLoc, ModifierLoc, EndLoc);
23307 "Unexpected num_tasks modifier in OpenMP < 51.");
23312 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
23313 << Values << getOpenMPClauseName(OMPC_num_tasks);
23317 Expr *ValExpr = NumTasks;
23318 Stmt *HelperValStmt =
nullptr;
23325 ValExpr,
SemaRef, OMPC_num_tasks,
23327 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
23332 StartLoc, LParenLoc, ModifierLoc, EndLoc);
23352 DSAStackTy *Stack) {
23353 QualType OMPEventHandleT = Stack->getOMPEventHandleT();
23354 if (!OMPEventHandleT.
isNull())
23359 S.
Diag(
Loc, diag::err_omp_implied_type_not_found) <<
"omp_event_handle_t";
23362 Stack->setOMPEventHandleT(PT.
get());
23383 auto *VD = dyn_cast_or_null<VarDecl>(Ref->
getDecl());
23393 <<
"omp_event_handle_t" << 1 << VD->
getType()
23400 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(VD,
false);
23401 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
23404 << getOpenMPClauseName(DVar.CKind)
23405 << getOpenMPClauseName(OMPC_firstprivate);
23420 std::string Values;
23424 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23425 << Values << getOpenMPClauseName(OMPC_dist_schedule);
23428 Expr *ValExpr = ChunkSize;
23429 Stmt *HelperValStmt =
nullptr;
23440 ValExpr = Val.
get();
23445 if (std::optional<llvm::APSInt>
Result =
23447 if (
Result->isSigned() && !
Result->isStrictlyPositive()) {
23448 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
23453 DSAStack->getCurrentDirective(), OMPC_dist_schedule,
23457 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
23458 ValExpr = tryBuildCapture(
SemaRef, ValExpr, Captures).get();
23466 Kind, ValExpr, HelperValStmt);
23474 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
23475 Kind != OMPC_DEFAULTMAP_scalar) {
23479 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
23481 OMPC_DEFAULTMAP_MODIFIER_tofrom);
23485 OMPC_DEFAULTMAP_scalar);
23489 Diag(
Loc, diag::err_omp_unexpected_clause_value)
23490 <<
Value << getOpenMPClauseName(OMPC_defaultmap);
23497 if (!isDefaultmapKind || !isDefaultmapModifier) {
23498 StringRef KindValue =
"'scalar', 'aggregate', 'pointer'";
23500 StringRef ModifierValue =
"'alloc', 'from', 'to', 'tofrom', "
23501 "'firstprivate', 'none', 'default'";
23502 if (!isDefaultmapKind && isDefaultmapModifier) {
23503 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23504 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23505 }
else if (isDefaultmapKind && !isDefaultmapModifier) {
23506 Diag(MLoc, diag::err_omp_unexpected_clause_value)
23507 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23509 Diag(MLoc, diag::err_omp_unexpected_clause_value)
23510 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23511 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23512 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23515 StringRef ModifierValue =
23516 "'alloc', 'from', 'to', 'tofrom', "
23517 "'firstprivate', 'none', 'default', 'present'";
23518 if (!isDefaultmapKind && isDefaultmapModifier) {
23519 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23520 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23521 }
else if (isDefaultmapKind && !isDefaultmapModifier) {
23522 Diag(MLoc, diag::err_omp_unexpected_clause_value)
23523 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23525 Diag(MLoc, diag::err_omp_unexpected_clause_value)
23526 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23527 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23528 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23537 if (
DSAStack->checkDefaultmapCategory(Kind)) {
23538 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
23544 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
23545 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
23546 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
23548 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
23561 !isa<CXXRecordDecl>(CurLexicalContext) &&
23562 !isa<ClassTemplateDecl>(CurLexicalContext) &&
23563 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
23564 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
23565 Diag(DTCI.
Loc, diag::err_omp_region_not_file_context);
23571 Diag(DTCI.
Loc, diag::warn_hip_omp_target_directives);
23573 DeclareTargetNesting.push_back(DTCI);
23579 assert(!DeclareTargetNesting.empty() &&
23580 "check isInOpenMPDeclareTargetContext() first!");
23581 return DeclareTargetNesting.pop_back_val();
23591 if (DeclareTargetNesting.empty())
23594 Diag(DTCI.
Loc, diag::warn_omp_unterminated_declare_target)
23595 << getOpenMPDirectiveName(DTCI.
Kind);
23610 VarOrFuncDeclFilterCCC CCC(
SemaRef);
23621 Diag(
Id.getLoc(), diag::err_undeclared_var_use) <<
Id.getName();
23626 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
23627 !isa<FunctionTemplateDecl>(ND)) {
23628 Diag(
Id.getLoc(), diag::err_omp_invalid_target_decl) <<
Id.getName();
23637 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
23638 isa<FunctionTemplateDecl>(ND)) &&
23639 "Expected variable, function or function template.");
23641 if (
auto *VD = dyn_cast<VarDecl>(ND)) {
23643 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
23644 !VD->isStaticDataMember()) {
23645 Diag(
Loc, diag::err_omp_declare_target_has_local_vars)
23654 Diag(
Loc, diag::warn_omp_declare_target_after_first_use);
23658 Diag(
Loc, diag::warn_hip_omp_target_directives);
23661 const unsigned Level = -1;
23663 auto *VD = cast<ValueDecl>(ND);
23664 std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
23665 OMPDeclareTargetDeclAttr::getActiveAttr(VD);
23666 if (ActiveAttr && (*ActiveAttr)->getDevType() != DTCI.
DT &&
23667 (*ActiveAttr)->getLevel() == Level) {
23668 Diag(
Loc, diag::err_omp_device_type_mismatch)
23669 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.
DT)
23670 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(
23671 (*ActiveAttr)->getDevType());
23674 if (ActiveAttr && (*ActiveAttr)->getMapType() != MT &&
23675 (*ActiveAttr)->getLevel() == Level) {
23676 Diag(
Loc, diag::err_omp_declare_target_to_and_link) << ND;
23680 if (ActiveAttr && (*ActiveAttr)->getLevel() == Level)
23683 Expr *IndirectE =
nullptr;
23684 bool IsIndirect =
false;
23690 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
23695 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
23697 if (
auto *VD = dyn_cast<VarDecl>(ND);
23699 VD->hasGlobalStorage())
23705 if (!D || !isa<VarDecl>(D))
23707 auto *VD = cast<VarDecl>(D);
23708 std::optional<OMPDeclareTargetDeclAttr::MapTypeTy>
MapTy =
23709 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
23710 if (SemaRef.
LangOpts.OpenMP >= 50 &&
23713 VD->hasGlobalStorage()) {
23714 if (!
MapTy || (*
MapTy != OMPDeclareTargetDeclAttr::MT_To &&
23715 *
MapTy != OMPDeclareTargetDeclAttr::MT_Enter)) {
23722 diag::err_omp_lambda_capture_in_declare_target_not_to);
23723 SemaRef.
Diag(SL, diag::note_var_explicitly_captured_here)
23730 SemaRef.
Diag(VD->
getLocation(), diag::warn_omp_not_in_target_context);
23731 SemaRef.
Diag(SL, diag::note_used_here) << SR;
23735 Sema &SemaRef, DSAStackTy *Stack,
23737 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
23748 if (
auto *VD = dyn_cast<VarDecl>(D)) {
23750 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
23751 !VD->isStaticDataMember())
23755 if (
DSAStack->isThreadPrivate(VD)) {
23756 Diag(SL, diag::err_omp_threadprivate_in_target);
23761 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
23762 D = FTD->getTemplatedDecl();
23763 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
23764 std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
23765 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
23766 if (IdLoc.
isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
23767 Diag(IdLoc, diag::err_omp_function_in_link_clause);
23772 if (
auto *VD = dyn_cast<ValueDecl>(D)) {
23780 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
23781 isa<FunctionTemplateDecl>(D)) {
23782 std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
23783 OMPDeclareTargetDeclAttr::getActiveAttr(VD);
23784 unsigned Level = DeclareTargetNesting.size();
23785 if (ActiveAttr && (*ActiveAttr)->getLevel() >= Level)
23788 Expr *IndirectE =
nullptr;
23789 bool IsIndirect =
false;
23795 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
23797 getLangOpts().OpenMP >= 52 ? OMPDeclareTargetDeclAttr::MT_Enter
23798 : OMPDeclareTargetDeclAttr::MT_To,
23799 DTCI.
DT, IndirectE, IsIndirect, Level,
23803 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
23824 if (
auto *VD = dyn_cast<VarDecl>(
Node->getDecl())) {
23826 DeclVector.push_back(VD);
23831 for (
auto *Child : Ex->
children()) {
23840 A = TD->
getAttr<OMPDeclareTargetDeclAttr>();
23841 DeclVector.push_back(cast<VarDecl>(TD));
23842 while (!DeclVector.empty()) {
23843 VarDecl *TargetVarDecl = DeclVector.pop_back_val();
23844 if (TargetVarDecl->
hasAttr<OMPDeclareTargetDeclAttr>() &&
23858 if (isa<VarDecl>(TargetDecl))
23873 unsigned Count = 0;
23874 for (
unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
23876 llvm::is_contained(Modifiers, MotionModifiers[I])) {
23877 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
23881 "Modifiers exceed the allowed number of motion modifiers");
23882 Modifiers[Count] = MotionModifiers[I];
23883 ModifiersLoc[Count] = MotionModifiersLoc[I];
23887 MappableVarListInfo MVLI(VarList);
23889 MapperIdScopeSpec, MapperId, UnresolvedMappers);
23890 if (MVLI.ProcessedVarList.empty())
23894 getASTContext(), Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
23895 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
23910 unsigned Count = 0;
23911 for (
unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
23913 llvm::is_contained(Modifiers, MotionModifiers[I])) {
23914 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
23918 "Modifiers exceed the allowed number of motion modifiers");
23919 Modifiers[Count] = MotionModifiers[I];
23920 ModifiersLoc[Count] = MotionModifiersLoc[I];
23924 MappableVarListInfo MVLI(VarList);
23926 MapperIdScopeSpec, MapperId, UnresolvedMappers);
23927 if (MVLI.ProcessedVarList.empty())
23931 getASTContext(), Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
23932 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
23939 MappableVarListInfo MVLI(VarList);
23943 for (
Expr *RefExpr : VarList) {
23944 assert(RefExpr &&
"NULL expr in OpenMP use_device_ptr clause.");
23947 Expr *SimpleRefExpr = RefExpr;
23951 MVLI.ProcessedVarList.push_back(RefExpr);
23952 PrivateCopies.push_back(
nullptr);
23953 Inits.push_back(
nullptr);
23960 Type =
Type.getNonReferenceType().getUnqualifiedType();
23962 auto *VD = dyn_cast<VarDecl>(D);
23966 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
23967 << 0 << RefExpr->getSourceRange();
23975 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
23976 if (VDPrivate->isInvalidDecl())
23981 SemaRef, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
23997 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
23998 PrivateCopies.push_back(VDPrivateRefExpr);
23999 Inits.push_back(VDInitRefExpr);
24004 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
24008 MVLI.VarBaseDeclarations.push_back(D);
24009 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
24010 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
24014 if (MVLI.ProcessedVarList.empty())
24018 getASTContext(), Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
24019 MVLI.VarBaseDeclarations, MVLI.VarComponents);
24025 MappableVarListInfo MVLI(VarList);
24027 for (
Expr *RefExpr : VarList) {
24028 assert(RefExpr &&
"NULL expr in OpenMP use_device_addr clause.");
24031 Expr *SimpleRefExpr = RefExpr;
24036 MVLI.ProcessedVarList.push_back(RefExpr);
24041 auto *VD = dyn_cast<VarDecl>(D);
24048 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
24053 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
24057 MVLI.VarBaseDeclarations.push_back(D);
24058 MVLI.VarComponents.emplace_back();
24059 Expr *Component = SimpleRefExpr;
24060 if (VD && (isa<ArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
24061 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
24064 MVLI.VarComponents.back().emplace_back(Component, D,
24068 if (MVLI.ProcessedVarList.empty())
24072 getASTContext(), Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
24073 MVLI.VarComponents);
24079 MappableVarListInfo MVLI(VarList);
24080 for (
Expr *RefExpr : VarList) {
24081 assert(RefExpr &&
"NULL expr in OpenMP is_device_ptr clause.");
24084 Expr *SimpleRefExpr = RefExpr;
24088 MVLI.ProcessedVarList.push_back(RefExpr);
24098 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
24099 << 0 << RefExpr->getSourceRange();
24105 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
24107 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
24108 << getOpenMPClauseName(DVar.CKind)
24109 << getOpenMPClauseName(OMPC_is_device_ptr)
24110 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
24115 const Expr *ConflictExpr;
24116 if (
DSAStack->checkMappableExprComponentListsForDecl(
24121 ConflictExpr = R.front().getAssociatedExpression();
24124 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
24133 SimpleRefExpr, D,
false);
24134 DSAStack->addMappableExpressionComponents(
24135 D, MC, OMPC_is_device_ptr);
24138 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
24143 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
24144 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
24145 "Unexpected device pointer expression!");
24146 MVLI.VarBaseDeclarations.push_back(
24147 isa<DeclRefExpr>(SimpleRefExpr) ? D :
nullptr);
24148 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
24149 MVLI.VarComponents.back().push_back(MC);
24152 if (MVLI.ProcessedVarList.empty())
24156 getASTContext(), Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
24157 MVLI.VarComponents);
24163 MappableVarListInfo MVLI(VarList);
24164 for (
Expr *RefExpr : VarList) {
24165 assert(RefExpr &&
"NULL expr in OpenMP has_device_addr clause.");
24168 Expr *SimpleRefExpr = RefExpr;
24173 MVLI.ProcessedVarList.push_back(RefExpr);
24181 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
24183 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
24184 << getOpenMPClauseName(DVar.CKind)
24185 << getOpenMPClauseName(OMPC_has_device_addr)
24186 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
24191 const Expr *ConflictExpr;
24192 if (
DSAStack->checkMappableExprComponentListsForDecl(
24197 ConflictExpr = R.front().getAssociatedExpression();
24200 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
24208 Expr *Component = SimpleRefExpr;
24209 auto *VD = dyn_cast<VarDecl>(D);
24210 if (VD && (isa<ArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
24211 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
24215 Component, D,
false);
24216 DSAStack->addMappableExpressionComponents(
24217 D, MC, OMPC_has_device_addr);
24223 assert(Ref &&
"has_device_addr capture failed");
24224 MVLI.ProcessedVarList.push_back(Ref);
24226 MVLI.ProcessedVarList.push_back(RefExpr->IgnoreParens());
24231 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
24232 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
24233 "Unexpected device pointer expression!");
24234 MVLI.VarBaseDeclarations.push_back(
24235 isa<DeclRefExpr>(SimpleRefExpr) ? D :
nullptr);
24236 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
24237 MVLI.VarComponents.back().push_back(MC);
24240 if (MVLI.ProcessedVarList.empty())
24244 getASTContext(), Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
24245 MVLI.VarComponents);
24261 AllocatorRes.
get(),
DSAStack->getOMPAllocatorHandleT(),
24266 Allocator = AllocatorRes.
get();
24279 for (
Expr *RefExpr : VarList) {
24280 assert(RefExpr &&
"NULL expr in OpenMP private clause.");
24283 Expr *SimpleRefExpr = RefExpr;
24287 Vars.push_back(RefExpr);
24293 auto *VD = dyn_cast<VarDecl>(D);
24298 ? RefExpr->IgnoreParens()
24306 DSAStack->addInnerAllocatorExpr(Allocator);
24308 Allocator, ColonLoc, EndLoc, Vars);
24316 for (
Expr *RefExpr : VarList) {
24317 assert(RefExpr &&
"NULL expr in OpenMP nontemporal clause.");
24320 Expr *SimpleRefExpr = RefExpr;
24324 Vars.push_back(RefExpr);
24331 if (
const Expr *PrevRef =
24332 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
24333 Diag(ELoc, diag::err_omp_used_in_clause_twice)
24334 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
24335 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
24336 << getOpenMPClauseName(OMPC_nontemporal);
24340 Vars.push_back(RefExpr);
24368 for (
Expr *RefExpr : VarList) {
24369 assert(RefExpr &&
"NULL expr in OpenMP nontemporal clause.");
24372 Expr *SimpleRefExpr = RefExpr;
24377 Vars.push_back(RefExpr);
24382 const DSAStackTy::DSAVarData DVar =
24388 if (DVar.CKind != OMPC_reduction || DVar.Modifier != OMPC_REDUCTION_inscan)
24389 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
24390 << RefExpr->getSourceRange();
24392 if (
DSAStack->getParentDirective() != OMPD_unknown)
24393 DSAStack->markDeclAsUsedInScanDirective(D);
24394 Vars.push_back(RefExpr);
24409 for (
Expr *RefExpr : VarList) {
24410 assert(RefExpr &&
"NULL expr in OpenMP nontemporal clause.");
24413 Expr *SimpleRefExpr = RefExpr;
24418 Vars.push_back(RefExpr);
24424 DSAStackTy::DSAVarData DVar;
24425 if (ParentDirective != OMPD_unknown)
24426 DVar =
DSAStack->getTopDSA(D,
true);
24431 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
24432 DVar.Modifier != OMPC_REDUCTION_inscan) {
24433 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
24434 << RefExpr->getSourceRange();
24436 DSAStack->markDeclAsUsedInScanDirective(D);
24438 Vars.push_back(RefExpr);
24450 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
24451 if (!OMPAlloctraitT.
isNull())
24456 S.
Diag(
Loc, diag::err_omp_implied_type_not_found) <<
"omp_alloctrait_t";
24459 Stack->setOMPAlloctraitT(PT.
get());
24479 for (
int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
24480 auto AllocatorKind =
static_cast<OMPAllocateDeclAttr::AllocatorTypeTy
>(I);
24481 StringRef Allocator =
24482 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
24490 Expr *AllocatorExpr =
nullptr;
24498 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
24499 bool IsPredefinedAllocator =
false;
24501 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorTy =
24503 IsPredefinedAllocator =
24505 OMPAllocateDeclAttr::AllocatorTypeTy::OMPUserDefinedMemAlloc;
24509 bool IsTypeCompatible = IsPredefinedAllocator;
24510 IsTypeCompatible = IsTypeCompatible ||
24512 OMPAllocatorHandleT);
24514 IsTypeCompatible ||
24516 bool IsNonConstantLValue =
24518 if (!DRE || !IsTypeCompatible ||
24519 (!IsPredefinedAllocator && !IsNonConstantLValue)) {
24521 <<
"omp_allocator_handle_t" << (DRE ? 1 : 0)
24530 diag::err_omp_predefined_allocator_with_traits)
24533 << cast<NamedDecl>(DRE->
getDecl())->getName()
24542 diag::err_omp_nonpredefined_allocator_without_traits);
24550 IsPredefinedAllocator
24551 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
24552 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
24554 Expr *AllocatorTraitsExpr =
nullptr;
24568 if (
const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
24569 TraitTy = ConstArrayTy->getElementType();
24576 diag::err_omp_expected_array_alloctraits)
24577 << AllocatorTraitsExpr->
getType();
24582 if (
auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
24585 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
24602 for (
Expr *RefExpr : Locators) {
24603 assert(RefExpr &&
"NULL expr in OpenMP shared clause.");
24604 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
24606 Vars.push_back(RefExpr);
24614 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
24615 << 1 << 0 << RefExpr->getSourceRange();
24624 if (!Res.
isUsable() && !isa<ArraySectionExpr>(SimpleExpr) &&
24625 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
24626 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
24627 << 1 << 0 << RefExpr->getSourceRange();
24630 Vars.push_back(SimpleExpr);
24634 ColonLoc, EndLoc, Modifier, Vars);
24643 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
24646 << getOpenMPClauseName(OMPC_bind);
24651 LParenLoc, EndLoc);
24658 Expr *ValExpr = Size;
24659 Stmt *HelperValStmt =
nullptr;
24670 DKind, OMPC_ompx_dyn_cgroup_mem,
getLangOpts().OpenMP);
24671 if (CaptureRegion != OMPD_unknown &&
24674 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
24675 ValExpr = tryBuildCapture(
SemaRef, ValExpr, Captures).get();
24680 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
24688 if (
DSAStack->getCurrentDirective() == OMPD_ordered &&
24689 DepType != OMPC_DOACROSS_source && DepType != OMPC_DOACROSS_sink &&
24690 DepType != OMPC_DOACROSS_sink_omp_cur_iteration &&
24691 DepType != OMPC_DOACROSS_source_omp_cur_iteration &&
24692 DepType != OMPC_DOACROSS_source) {
24693 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
24694 <<
"'source' or 'sink'" << getOpenMPClauseName(OMPC_doacross);
24700 llvm::APSInt TotalDepCount(32);
24703 DepType == OMPC_DOACROSS_source ||
24704 DepType == OMPC_DOACROSS_source_omp_cur_iteration ||
24705 DepType == OMPC_DOACROSS_sink_omp_cur_iteration,
24707 Vars = VarOffset.Vars;
24708 OpsOffs = VarOffset.OpsOffs;
24709 TotalDepCount = VarOffset.TotalDepCount;
24711 EndLoc, DepType, DepLoc, ColonLoc, Vars,
24712 TotalDepCount.getZExtValue());
24713 if (
DSAStack->isParentOrderedRegion())
24714 DSAStack->addDoacrossDependClause(
C, OpsOffs);
24736 if (
Base->hasPlaceholderType() &&
24737 !
Base->hasPlaceholderType(BuiltinType::ArraySection)) {
24750 LowerBound =
Result.get();
24752 if (Length && Length->getType()->isNonOverloadPlaceholderType()) {
24772 if (
Base->isTypeDependent() ||
24775 (Length && (Length->isTypeDependent() || Length->isValueDependent())) ||
24779 OK_Ordinary, ColonLocFirst, ColonLocSecond, RBLoc);
24791 Diag(
Base->getExprLoc(), diag::err_omp_typecheck_section_value)
24792 <<
Base->getSourceRange());
24798 if (Res.isInvalid())
24800 diag::err_omp_typecheck_section_not_integer)
24802 LowerBound = Res.get();
24812 if (Res.isInvalid())
24814 diag::err_omp_typecheck_section_not_integer)
24815 << 1 << Length->getSourceRange());
24816 Length = Res.get();
24818 if (Length->getType()->isSpecificBuiltinType(BuiltinType::Char_S) ||
24819 Length->getType()->isSpecificBuiltinType(BuiltinType::Char_U))
24820 Diag(Length->getExprLoc(), diag::warn_omp_section_is_char)
24821 << 1 << Length->getSourceRange();
24828 diag::err_omp_typecheck_section_not_integer)
24830 Stride = Res.
get();
24843 Diag(
Base->getExprLoc(), diag::err_omp_section_function_type)
24844 << ResultTy <<
Base->getSourceRange();
24849 diag::err_omp_section_incomplete_type,
Base))
24857 llvm::APSInt LowerBoundValue =
Result.Val.getInt();
24858 if (LowerBoundValue.isNegative()) {
24860 diag::err_omp_section_not_subset_of_array)
24869 if (Length->EvaluateAsInt(
Result, Context)) {
24872 llvm::APSInt LengthValue =
Result.Val.getInt();
24873 if (LengthValue.isNegative()) {
24874 Diag(Length->getExprLoc(), diag::err_omp_section_length_negative)
24875 <<
toString(LengthValue, 10,
true)
24876 << Length->getSourceRange();
24880 }
else if (ColonLocFirst.
isValid() &&
24886 Diag(ColonLocFirst, diag::err_omp_section_length_undefined)
24896 llvm::APSInt StrideValue =
Result.Val.getInt();
24897 if (!StrideValue.isStrictlyPositive()) {
24898 Diag(Stride->
getExprLoc(), diag::err_omp_section_stride_non_positive)
24899 <<
toString(StrideValue, 10,
true)
24906 if (!
Base->hasPlaceholderType(BuiltinType::ArraySection)) {
24914 OK_Ordinary, ColonLocFirst, ColonLocSecond, RBLoc);
24921 if (
Base->hasPlaceholderType()) {
24935 LParenLoc, RParenLoc, Dims, Brackets);
24937 (!
Base->isTypeDependent() &&
24940 diag::err_omp_non_pointer_type_array_shaping_base)
24941 <<
Base->getSourceRange());
24944 bool ErrorFound =
false;
24945 for (
Expr *Dim : Dims) {
24946 if (Dim->hasPlaceholderType()) {
24948 if (
Result.isInvalid()) {
24953 if (
Result.isInvalid()) {
24959 if (!Dim->isTypeDependent()) {
24962 if (
Result.isInvalid()) {
24964 Diag(Dim->getExprLoc(), diag::err_omp_typecheck_shaping_not_integer)
24965 << Dim->getSourceRange();
24970 if (!Dim->isValueDependent() && Dim->EvaluateAsInt(EvResult, Context)) {
24975 if (!
Value.isStrictlyPositive()) {
24976 Diag(Dim->getExprLoc(), diag::err_omp_shaping_dimension_not_positive)
24978 << Dim->getSourceRange();
24984 NewDims.push_back(Dim);
24989 LParenLoc, RParenLoc, NewDims, Brackets);
24999 bool IsCorrect =
true;
25004 if (!D.Type.getAsOpaquePtr()) {
25008 DeclTy = Context.
IntTy;
25009 StartLoc = D.DeclIdentLoc;
25015 bool IsDeclTyDependent = DeclTy->isDependentType() ||
25016 DeclTy->containsUnexpandedParameterPack() ||
25017 DeclTy->isInstantiationDependentType();
25018 if (!IsDeclTyDependent) {
25019 if (!DeclTy->isIntegralType(Context) && !DeclTy->isAnyPointerType()) {
25022 Diag(StartLoc, diag::err_omp_iterator_not_integral_or_pointer)
25027 if (DeclTy.isConstant(Context)) {
25030 Diag(StartLoc, diag::err_omp_iterator_not_integral_or_pointer)
25038 assert(D.DeclIdent &&
"Identifier expected.");
25043 D.DeclIdent, DeclTy, TInfo,
SC_None);
25049 RedeclarationKind::ForVisibleRedeclaration);
25071 if (!IsDeclTyDependent &&
Begin && !
Begin->isTypeDependent()) {
25076 Expr *End = D.Range.End;
25077 if (!IsDeclTyDependent && End && !End->isTypeDependent()) {
25080 End = EndRes.
get();
25082 Expr *Step = D.Range.Step;
25085 Diag(Step->
getExprLoc(), diag::err_omp_iterator_step_not_integral)
25090 std::optional<llvm::APSInt>
Result =
25096 Diag(Step->
getExprLoc(), diag::err_omp_iterator_step_constant_zero)
25102 if (!
Begin || !End || !IsCorrect) {
25118 if (
Decl *ID = D.IteratorDecl)
25119 ID->setInvalidDecl();
25131 D.Range.End, D.Range.Begin);
25137 if (D.Range.Step) {
25148 D.AssignmentLoc, BO_Sub, Res.
get(),
25165 D.AssignmentLoc, BO_Sub, D.Range.Begin, D.Range.End);
25179 D.AssignmentLoc, BO_Sub, Res1.
get(),
25194 D.AssignmentLoc, BO_GT, D.Range.Step,
25219 CounterVD->setImplicit();
25226 if (D.Range.Step) {
25228 D.AssignmentLoc, BO_Mul,
25238 D.Range.Begin, UpdateRes.
get());
25245 cast<VarDecl>(D.IteratorDecl)->getType(),
25248 VDRes.
get(), UpdateRes.
get());
25260 D.AssignmentLoc, UO_PreInc, RefRes.
get());
25261 if (!CounterUpdateRes.
isUsable()) {
25267 if (!CounterUpdateRes.
isUsable()) {
25278 Helpers.assign(ID.size(), {});
25283 if (
Decl *ID = D.IteratorDecl)
25284 ID->setInvalidDecl();
25289 LLoc, RLoc, ID, Helpers);
25293 :
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)
NonOdrUseReason isNonOdrUse() const
Is this expression a non-odr-use reference, and if so, why?
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.
static OMPSizesClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > Sizes)
Build a 'sizes' AST node.
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...
bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, QualType ObjectType, 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 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
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.
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.
MemberExpr * BuildMemberExpr(Expr *Base, bool IsArrow, SourceLocation OpLoc, NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc, ValueDecl *Member, DeclAccessPair FoundDecl, bool HadMultipleCandidates, const DeclarationNameInfo &MemberNameInfo, QualType Ty, ExprValueKind VK, ExprObjectKind OK, const TemplateArgumentListInfo *TemplateArgs=nullptr)
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.
@ NOUR_Unevaluated
This name appears in an unevaluated operand.
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.