aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaOpenMP.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaOpenMP.cpp')
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp919
1 files changed, 645 insertions, 274 deletions
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index dc1470bf7a9d..c767341d922b 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -39,6 +39,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/Frontend/OpenMP/OMPAssume.h"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
+#include <optional>
#include <set>
using namespace clang;
@@ -172,7 +173,8 @@ private:
/// First argument (Expr *) contains optional argument of the
/// 'ordered' clause, the second one is true if the regions has 'ordered'
/// clause, false otherwise.
- llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
+ std::optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
+ bool RegionHasOrderConcurrent = false;
unsigned AssociatedLoops = 1;
bool HasMutipleLoops = false;
const Decl *PossiblyLoopCounter = nullptr;
@@ -213,6 +215,7 @@ private:
llvm::SmallVector<ImplicitDefaultFDInfoTy, 8>
ImplicitDefaultFirstprivateFDs;
Expr *DeclareMapperVar = nullptr;
+ SmallVector<VarDecl *, 16> IteratorVarDecls;
SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
Scope *CurScope, SourceLocation Loc)
: Directive(DKind), DirectiveName(Name), CurScope(CurScope),
@@ -847,7 +850,7 @@ public:
std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
if (const SharingMapTy *Top = getTopOfStackOrNull())
if (Top->OrderedRegion)
- return Top->OrderedRegion.value();
+ return *Top->OrderedRegion;
return std::make_pair(nullptr, nullptr);
}
/// Returns true, if parent region is ordered (has associated
@@ -862,9 +865,20 @@ public:
getParentOrderedRegionParam() const {
if (const SharingMapTy *Parent = getSecondOnStackOrNull())
if (Parent->OrderedRegion)
- return Parent->OrderedRegion.value();
+ return *Parent->OrderedRegion;
return std::make_pair(nullptr, nullptr);
}
+ /// Marks current region as having an 'order' clause.
+ void setRegionHasOrderConcurrent(bool HasOrderConcurrent) {
+ getTopOfStack().RegionHasOrderConcurrent = HasOrderConcurrent;
+ }
+ /// Returns true, if parent region is order (has associated
+ /// 'order' clause), false - otherwise.
+ bool isParentOrderConcurrent() const {
+ if (const SharingMapTy *Parent = getSecondOnStackOrNull())
+ return Parent->RegionHasOrderConcurrent;
+ return false;
+ }
/// Marks current region as nowait (it has a 'nowait' clause).
void setNowaitRegion(bool IsNowait = true) {
getTopOfStack().NowaitRegion = IsNowait;
@@ -1114,19 +1128,20 @@ public:
}
/// Checks if specified decl is used in uses allocator clause as the
/// allocator.
- Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level,
- const Decl *D) const {
+ std::optional<UsesAllocatorsDeclKind>
+ isUsesAllocatorsDecl(unsigned Level, const Decl *D) const {
const SharingMapTy &StackElem = getTopOfStack();
auto I = StackElem.UsesAllocatorsDecls.find(D);
if (I == StackElem.UsesAllocatorsDecls.end())
- return None;
+ return std::nullopt;
return I->getSecond();
}
- Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const {
+ std::optional<UsesAllocatorsDeclKind>
+ isUsesAllocatorsDecl(const Decl *D) const {
const SharingMapTy &StackElem = getTopOfStack();
auto I = StackElem.UsesAllocatorsDecls.find(D);
if (I == StackElem.UsesAllocatorsDecls.end())
- return None;
+ return std::nullopt;
return I->getSecond();
}
@@ -1138,6 +1153,22 @@ public:
const SharingMapTy *Top = getTopOfStackOrNull();
return Top ? Top->DeclareMapperVar : nullptr;
}
+
+ /// Add a new iterator variable.
+ void addIteratorVarDecl(VarDecl *VD) {
+ SharingMapTy &StackElem = getTopOfStack();
+ StackElem.IteratorVarDecls.push_back(VD->getCanonicalDecl());
+ }
+ /// Check if variable declaration is an iterator VarDecl.
+ bool isIteratorVarDecl(const VarDecl *VD) const {
+ const SharingMapTy *Top = getTopOfStackOrNull();
+ if (!Top)
+ return false;
+
+ return llvm::any_of(Top->IteratorVarDecls, [VD](const VarDecl *IteratorVD) {
+ return IteratorVD == VD->getCanonicalDecl();
+ });
+ }
/// get captured field from ImplicitDefaultFirstprivateFDs
VarDecl *getImplicitFDCapExprDecl(const FieldDecl *FD) const {
const_iterator I = begin();
@@ -2093,7 +2124,7 @@ bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
//
// =========================================================================
// | type | defaultmap | pvt | first | is_device_ptr | map | res. |
- // | |(tofrom:scalar)| | pvt | | | |
+ // | |(tofrom:scalar)| | pvt | |has_dv_adr| |
// =========================================================================
// | scl | | | | - | | bycopy|
// | scl | | - | x | - | - | bycopy|
@@ -2154,10 +2185,11 @@ bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
D](OMPClauseMappableExprCommon::MappableExprComponentListRef
MapExprComponents,
OpenMPClauseKind WhereFoundClauseKind) {
- // Only the map clause information influences how a variable is
- // captured. E.g. is_device_ptr does not require changing the default
- // behavior.
- if (WhereFoundClauseKind != OMPC_map)
+ // Both map and has_device_addr clauses information influences how a
+ // variable is captured. E.g. is_device_ptr does not require changing
+ // the default behavior.
+ if (WhereFoundClauseKind != OMPC_map &&
+ WhereFoundClauseKind != OMPC_has_device_addr)
return false;
auto EI = MapExprComponents.rbegin();
@@ -2270,6 +2302,9 @@ bool Sema::isInOpenMPTargetExecutionDirective() const {
}
bool Sema::isOpenMPRebuildMemberExpr(ValueDecl *D) {
+ // Only rebuild for Field.
+ if (!dyn_cast<FieldDecl>(D))
+ return false;
DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
D,
[](OpenMPClauseKind C, bool AppliedToPointee,
@@ -2661,7 +2696,7 @@ void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
const FunctionDecl *Callee,
SourceLocation Loc) {
assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.");
- Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
+ std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
// Ignore host functions during device analyzis.
if (LangOpts.OpenMPIsDevice &&
@@ -2686,6 +2721,24 @@ void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
}
if (!LangOpts.OpenMPIsDevice && !LangOpts.OpenMPOffloadMandatory && DevTy &&
*DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
+ // In OpenMP 5.2 or later, if the function has a host variant then allow
+ // that to be called instead
+ auto &&HasHostAttr = [](const FunctionDecl *Callee) {
+ for (OMPDeclareVariantAttr *A :
+ Callee->specific_attrs<OMPDeclareVariantAttr>()) {
+ auto *DeclRefVariant = cast<DeclRefExpr>(A->getVariantFuncRef());
+ auto *VariantFD = cast<FunctionDecl>(DeclRefVariant->getDecl());
+ std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
+ OMPDeclareTargetDeclAttr::getDeviceType(
+ VariantFD->getMostRecentDecl());
+ if (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
+ return true;
+ }
+ return false;
+ };
+ if (getLangOpts().OpenMP >= 52 &&
+ Callee->hasAttr<OMPDeclareVariantAttr>() && HasHostAttr(Callee))
+ return;
// Diagnose nohost function called during host codegen.
StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
@@ -2715,7 +2768,8 @@ void Sema::EndOpenMPClause() {
static std::pair<ValueDecl *, bool>
getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
- SourceRange &ERange, bool AllowArraySection = false);
+ SourceRange &ERange, bool AllowArraySection = false,
+ StringRef DiagType = "");
/// Check consistency of the reduction clauses.
static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
@@ -3226,13 +3280,15 @@ getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
Allocator->containsUnexpandedParameterPack())
return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
+ llvm::FoldingSetNodeID AEId;
const Expr *AE = Allocator->IgnoreParenImpCasts();
+ AE->IgnoreImpCasts()->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
- llvm::FoldingSetNodeID AEId, DAEId;
- AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
- DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
+ llvm::FoldingSetNodeID DAEId;
+ DefAllocator->IgnoreImpCasts()->Profile(DAEId, S.getASTContext(),
+ /*Canonical=*/true);
if (AEId == DAEId) {
AllocatorKindRes = AllocatorKind;
break;
@@ -3694,7 +3750,7 @@ public:
return;
// Skip internally declared static variables.
- llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
+ std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
(Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
@@ -3764,9 +3820,8 @@ public:
bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
OMPC_DEFAULTMAP_MODIFIER_present;
if (IsModifierPresent) {
- if (llvm::find(ImplicitMapModifier[ClauseKind],
- OMPC_MAP_MODIFIER_present) ==
- std::end(ImplicitMapModifier[ClauseKind])) {
+ if (!llvm::is_contained(ImplicitMapModifier[ClauseKind],
+ OMPC_MAP_MODIFIER_present)) {
ImplicitMapModifier[ClauseKind].push_back(
OMPC_MAP_MODIFIER_present);
}
@@ -3785,9 +3840,8 @@ public:
// Variable is used if it has been marked as an array, array
// section, array shaping or the variable iself.
return StackComponents.size() == 1 ||
- std::all_of(
- std::next(StackComponents.rbegin()),
- StackComponents.rend(),
+ llvm::all_of(
+ llvm::drop_begin(llvm::reverse(StackComponents)),
[](const OMPClauseMappableExprCommon::
MappableComponent &MC) {
return MC.getAssociatedDeclaration() ==
@@ -4032,9 +4086,13 @@ public:
Visit(C);
}
}
- if (Expr *Callee = S->getCallee())
- if (auto *CE = dyn_cast<MemberExpr>(Callee->IgnoreParenImpCasts()))
+ if (Expr *Callee = S->getCallee()) {
+ auto *CI = Callee->IgnoreParenImpCasts();
+ if (auto *CE = dyn_cast<MemberExpr>(CI))
Visit(CE->getBase());
+ else if (auto *CE = dyn_cast<DeclRefExpr>(CI))
+ Visit(CE);
+ }
}
void VisitStmt(Stmt *S) {
for (Stmt *C : S->children()) {
@@ -4529,6 +4587,7 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
case OMPD_threadprivate:
case OMPD_allocate:
case OMPD_taskyield:
+ case OMPD_error:
case OMPD_barrier:
case OMPD_taskwait:
case OMPD_cancellation_point:
@@ -4674,12 +4733,12 @@ void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
DSAStack->setForceCaptureByReferenceInTargetExecutable(
/*V=*/true);
if (RD->isLambda()) {
- llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
+ llvm::DenseMap<const ValueDecl *, FieldDecl *> Captures;
FieldDecl *ThisCapture;
RD->getCaptureFields(Captures, ThisCapture);
for (const LambdaCapture &LC : RD->captures()) {
if (LC.getCaptureKind() == LCK_ByRef) {
- VarDecl *VD = LC.getCapturedVar();
+ VarDecl *VD = cast<VarDecl>(LC.getCapturedVar());
DeclContext *VDC = VD->getDeclContext();
if (!VDC->Encloses(CurContext))
continue;
@@ -4939,6 +4998,14 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
ShouldBeInTeamsRegion,
ShouldBeInLoopSimdRegion,
} Recommend = NoRecommend;
+ if (SemaRef.LangOpts.OpenMP >= 51 && Stack->isParentOrderConcurrent() &&
+ CurrentRegion != OMPD_simd && CurrentRegion != OMPD_loop &&
+ CurrentRegion != OMPD_parallel &&
+ !isOpenMPCombinedParallelADirective(CurrentRegion)) {
+ SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_order)
+ << getOpenMPDirectiveName(CurrentRegion);
+ return true;
+ }
if (isOpenMPSimdDirective(ParentRegion) &&
((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
(SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
@@ -5277,7 +5344,8 @@ static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
SourceLocation &ELoc,
SourceRange &ERange,
- bool AllowArraySection) {
+ bool AllowArraySection,
+ StringRef DiagType) {
if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
RefExpr->containsUnexpandedParameterPack())
return std::make_pair(nullptr, true);
@@ -5322,6 +5390,12 @@ static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
if (IsArrayExpr != NoArrayExpr) {
S.Diag(ELoc, diag::err_omp_expected_base_var_name)
<< IsArrayExpr << ERange;
+ } else if (!DiagType.empty()) {
+ unsigned DiagSelect = S.getLangOpts().CPlusPlus
+ ? (S.getCurrentThisType().isNull() ? 1 : 2)
+ : 0;
+ S.Diag(ELoc, diag::err_omp_expected_var_name_member_expr_with_type)
+ << DiagSelect << DiagType << ERange;
} else {
S.Diag(ELoc,
AllowArraySection
@@ -6021,7 +6095,7 @@ processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack,
CXXScopeSpec MapperIdScopeSpec;
DeclarationNameInfo MapperId;
if (OMPClause *NewClause = S.ActOnOpenMPMapClause(
- C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
+ nullptr, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
MapperIdScopeSpec, MapperId, C->getMapType(),
/*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
SubExprs, OMPVarListLocTy()))
@@ -6163,8 +6237,8 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
CXXScopeSpec MapperIdScopeSpec;
DeclarationNameInfo MapperId;
if (OMPClause *Implicit = ActOnOpenMPMapClause(
- OMPC_MAP_MODIFIER_unknown, SourceLocation(), MapperIdScopeSpec,
- MapperId, OMPC_MAP_tofrom,
+ nullptr, OMPC_MAP_MODIFIER_unknown, SourceLocation(),
+ MapperIdScopeSpec, MapperId, OMPC_MAP_tofrom,
/*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
Exprs, OMPVarListLocTy(), /*NoDiagnose=*/true))
ClausesWithImplicit.emplace_back(Implicit);
@@ -6180,7 +6254,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
DeclarationNameInfo MapperId;
auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
if (OMPClause *Implicit = ActOnOpenMPMapClause(
- ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
+ nullptr, ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true,
SourceLocation(), SourceLocation(), ImplicitMap,
OMPVarListLocTy())) {
@@ -6295,6 +6369,11 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
"No associated statement allowed for 'omp taskyield' directive");
Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
break;
+ case OMPD_error:
+ assert(AStmt == nullptr &&
+ "No associated statement allowed for 'omp error' directive");
+ Res = ActOnOpenMPErrorDirective(ClausesWithImplicit, StartLoc, EndLoc);
+ break;
case OMPD_barrier:
assert(ClausesWithImplicit.empty() &&
"No clauses are allowed for 'omp barrier' directive");
@@ -6703,6 +6782,9 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
case OMPC_device_type:
case OMPC_match:
case OMPC_when:
+ case OMPC_at:
+ case OMPC_severity:
+ case OMPC_message:
default:
llvm_unreachable("Unexpected clause");
}
@@ -7176,6 +7258,13 @@ ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
if (!CalleeFnDecl)
return Call;
+ if (LangOpts.OpenMP >= 51 && CalleeFnDecl->getIdentifier() &&
+ CalleeFnDecl->getName().startswith_insensitive("omp_")) {
+ // checking for any calls inside an Order region
+ if (Scope && Scope->isOpenMPOrderClauseScope())
+ Diag(LParenLoc, diag::err_omp_unexpected_call_to_omp_runtime_api);
+ }
+
if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
return Call;
@@ -7268,20 +7357,20 @@ ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
}
-Optional<std::pair<FunctionDecl *, Expr *>>
+std::optional<std::pair<FunctionDecl *, Expr *>>
Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
Expr *VariantRef, OMPTraitInfo &TI,
unsigned NumAppendArgs,
SourceRange SR) {
if (!DG || DG.get().isNull())
- return None;
+ return std::nullopt;
const int VariantId = 1;
// Must be applied only to single decl.
if (!DG.get().isSingleDecl()) {
Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
<< VariantId << SR;
- return None;
+ return std::nullopt;
}
Decl *ADecl = DG.get().getSingleDecl();
if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
@@ -7292,7 +7381,7 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
if (!FD) {
Diag(ADecl->getLocation(), diag::err_omp_function_expected)
<< VariantId << SR;
- return None;
+ return std::nullopt;
}
auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
@@ -7304,7 +7393,7 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
if (HasMultiVersionAttributes(FD)) {
Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
<< SR;
- return None;
+ return std::nullopt;
}
// Allow #pragma omp declare variant only if the function is not used.
@@ -7322,7 +7411,7 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
// The VariantRef must point to function.
if (!VariantRef) {
Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
- return None;
+ return std::nullopt;
}
auto ShouldDelayChecks = [](Expr *&E, bool) {
@@ -7357,7 +7446,7 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
return true;
};
if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
- return None;
+ return std::nullopt;
QualType AdjustedFnType = FD->getType();
if (NumAppendArgs) {
@@ -7365,7 +7454,7 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
if (!PTy) {
Diag(FD->getLocation(), diag::err_omp_declare_variant_prototype_required)
<< SR;
- return None;
+ return std::nullopt;
}
// Adjust the function type to account for an extra omp_interop_t for each
// specified in the append_args clause.
@@ -7378,12 +7467,12 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
}
if (!TD) {
Diag(SR.getBegin(), diag::err_omp_interop_type_not_found) << SR;
- return None;
+ return std::nullopt;
}
QualType InteropType = Context.getTypeDeclType(TD);
if (PTy->isVariadic()) {
Diag(FD->getLocation(), diag::err_omp_append_args_with_varargs) << SR;
- return None;
+ return std::nullopt;
}
llvm::SmallVector<QualType, 8> Params;
Params.append(PTy->param_type_begin(), PTy->param_type_end());
@@ -7413,7 +7502,7 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
if (!ER.isUsable()) {
Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
<< VariantId << VariantRef->getSourceRange();
- return None;
+ return std::nullopt;
}
VariantRef = ER.get();
} else {
@@ -7433,12 +7522,12 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
<< VariantRef->getType()
<< ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
<< (NumAppendArgs ? 1 : 0) << VariantRef->getSourceRange();
- return None;
+ return std::nullopt;
}
VariantRefCast = PerformImplicitConversion(
VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
if (!VariantRefCast.isUsable())
- return None;
+ return std::nullopt;
}
// Drop previously built artificial addr_of unary op for member functions.
if (Method && !Method->isStatic()) {
@@ -7454,7 +7543,7 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
!ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
<< VariantId << VariantRef->getSourceRange();
- return None;
+ return std::nullopt;
}
// The VariantRef must point to function.
@@ -7462,20 +7551,20 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
if (!DRE) {
Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
<< VariantId << VariantRef->getSourceRange();
- return None;
+ return std::nullopt;
}
auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
if (!NewFD) {
Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
<< VariantId << VariantRef->getSourceRange();
- return None;
+ return std::nullopt;
}
if (FD->getCanonicalDecl() == NewFD->getCanonicalDecl()) {
Diag(VariantRef->getExprLoc(),
diag::err_omp_declare_variant_same_base_function)
<< VariantRef->getSourceRange();
- return None;
+ return std::nullopt;
}
// Check if function types are compatible in C.
@@ -7487,7 +7576,7 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
diag::err_omp_declare_variant_incompat_types)
<< NewFD->getType() << FD->getType() << (NumAppendArgs ? 1 : 0)
<< VariantRef->getSourceRange();
- return None;
+ return std::nullopt;
}
if (NewType->isFunctionProtoType()) {
if (FD->getType()->isFunctionNoProtoType())
@@ -7505,7 +7594,7 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
SourceRange SR =
NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
- return None;
+ return std::nullopt;
}
enum DoesntSupport {
@@ -7521,38 +7610,38 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
if (CXXFD->isVirtual()) {
Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
<< VirtFuncs;
- return None;
+ return std::nullopt;
}
if (isa<CXXConstructorDecl>(FD)) {
Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
<< Constructors;
- return None;
+ return std::nullopt;
}
if (isa<CXXDestructorDecl>(FD)) {
Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
<< Destructors;
- return None;
+ return std::nullopt;
}
}
if (FD->isDeleted()) {
Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
<< DeletedFuncs;
- return None;
+ return std::nullopt;
}
if (FD->isDefaulted()) {
Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
<< DefaultedFuncs;
- return None;
+ return std::nullopt;
}
if (FD->isConstexpr()) {
Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
<< (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
- return None;
+ return std::nullopt;
}
// Check general compatibility.
@@ -7568,7 +7657,7 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
<< FD->getLocation()),
/*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
/*CLinkageMayDiffer=*/true))
- return None;
+ return std::nullopt;
return std::make_pair(FD, cast<Expr>(DRE));
}
@@ -7576,9 +7665,8 @@ void Sema::ActOnOpenMPDeclareVariantDirective(
FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI,
ArrayRef<Expr *> AdjustArgsNothing,
ArrayRef<Expr *> AdjustArgsNeedDevicePtr,
- ArrayRef<OMPDeclareVariantAttr::InteropType> AppendArgs,
- SourceLocation AdjustArgsLoc, SourceLocation AppendArgsLoc,
- SourceRange SR) {
+ ArrayRef<OMPInteropInfo> AppendArgs, SourceLocation AdjustArgsLoc,
+ SourceLocation AppendArgsLoc, SourceRange SR) {
// OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
// An adjust_args clause or append_args clause can only be specified if the
@@ -7638,8 +7726,7 @@ void Sema::ActOnOpenMPDeclareVariantDirective(
AdjustArgsNothing.size(),
const_cast<Expr **>(AdjustArgsNeedDevicePtr.data()),
AdjustArgsNeedDevicePtr.size(),
- const_cast<OMPDeclareVariantAttr::InteropType *>(AppendArgs.data()),
- AppendArgs.size(), SR);
+ const_cast<OMPInteropInfo *>(AppendArgs.data()), AppendArgs.size(), SR);
FD->addAttr(NewAttr);
}
@@ -7750,7 +7837,7 @@ class OpenMPIterationSpaceChecker {
/// UB > Var
/// UB >= Var
/// This will have no value when the condition is !=
- llvm::Optional<bool> TestIsLessOp;
+ std::optional<bool> TestIsLessOp;
/// This flag is true when condition is strict ( < or > ).
bool TestIsStrictOp = false;
/// This flag is true when step is subtracted on each iteration.
@@ -7759,12 +7846,13 @@ class OpenMPIterationSpaceChecker {
const ValueDecl *DepDecl = nullptr;
/// Contains number of loop (starts from 1) on which loop counter init
/// expression of this loop depends on.
- Optional<unsigned> InitDependOnLC;
+ std::optional<unsigned> InitDependOnLC;
/// Contains number of loop (starts from 1) on which loop counter condition
/// expression of this loop depends on.
- Optional<unsigned> CondDependOnLC;
+ std::optional<unsigned> CondDependOnLC;
/// Checks if the provide statement depends on the loop counter.
- Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
+ std::optional<unsigned> doesDependOnLoopCounter(const Stmt *S,
+ bool IsInitializer);
/// Original condition required for checking of the exit condition for
/// non-rectangular loop.
Expr *Condition = nullptr;
@@ -7847,7 +7935,7 @@ private:
bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
bool EmitDiags);
/// Helper to set upper bound.
- bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
+ bool setUB(Expr *NewUB, std::optional<bool> LessOp, bool StrictOp,
SourceRange SR, SourceLocation SL);
/// Helper to set loop increment.
bool setStep(Expr *NewStep, bool Subtract);
@@ -7885,8 +7973,7 @@ bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
return false;
}
-bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
- llvm::Optional<bool> LessOp,
+bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, std::optional<bool> LessOp,
bool StrictOp, SourceRange SR,
SourceLocation SL) {
// State consistency checking to ensure correct usage.
@@ -7929,7 +8016,7 @@ bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
// loop. If test-expr is of form b relational-op var and relational-op is
// > or >= then incr-expr must cause var to increase on each iteration of
// the loop.
- Optional<llvm::APSInt> Result =
+ std::optional<llvm::APSInt> Result =
NewStep->getIntegerConstantExpr(SemaRef.Context);
bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
bool IsConstNeg =
@@ -7941,19 +8028,18 @@ bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
// != with increment is treated as <; != with decrement is treated as >
if (!TestIsLessOp)
TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
- if (UB &&
- (IsConstZero ||
- (TestIsLessOp.value() ? (IsConstNeg || (IsUnsigned && Subtract))
- : (IsConstPos || (IsUnsigned && !Subtract))))) {
+ if (UB && (IsConstZero ||
+ (*TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
+ : (IsConstPos || (IsUnsigned && !Subtract))))) {
SemaRef.Diag(NewStep->getExprLoc(),
diag::err_omp_loop_incr_not_compatible)
- << LCDecl << TestIsLessOp.value() << NewStep->getSourceRange();
+ << LCDecl << *TestIsLessOp << NewStep->getSourceRange();
SemaRef.Diag(ConditionLoc,
diag::note_omp_loop_cond_requres_compatible_incr)
- << TestIsLessOp.value() << ConditionSrcRange;
+ << *TestIsLessOp << ConditionSrcRange;
return true;
}
- if (TestIsLessOp.value() == Subtract) {
+ if (*TestIsLessOp == Subtract) {
NewStep =
SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
.get();
@@ -8064,7 +8150,7 @@ public:
};
} // namespace
-Optional<unsigned>
+std::optional<unsigned>
OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
bool IsInitializer) {
// Check for the non-rectangular loops.
@@ -8074,7 +8160,7 @@ OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
DepDecl = LoopStmtChecker.getDepDecl();
return LoopStmtChecker.getBaseLoopId();
}
- return llvm::None;
+ return std::nullopt;
}
bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
@@ -8200,10 +8286,10 @@ bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
Condition = S;
S = getExprAsWritten(S);
SourceLocation CondLoc = S->getBeginLoc();
- auto &&CheckAndSetCond = [this, IneqCondIsCanonical](
- BinaryOperatorKind Opcode, const Expr *LHS,
- const Expr *RHS, SourceRange SR,
- SourceLocation OpLoc) -> llvm::Optional<bool> {
+ auto &&CheckAndSetCond =
+ [this, IneqCondIsCanonical](BinaryOperatorKind Opcode, const Expr *LHS,
+ const Expr *RHS, SourceRange SR,
+ SourceLocation OpLoc) -> std::optional<bool> {
if (BinaryOperator::isRelationalOp(Opcode)) {
if (getInitLCDecl(LHS) == LCDecl)
return setUB(const_cast<Expr *>(RHS),
@@ -8215,12 +8301,12 @@ bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
(Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
} else if (IneqCondIsCanonical && Opcode == BO_NE) {
return setUB(const_cast<Expr *>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS),
- /*LessOp=*/llvm::None,
+ /*LessOp=*/std::nullopt,
/*StrictOp=*/true, SR, OpLoc);
}
- return llvm::None;
+ return std::nullopt;
};
- llvm::Optional<bool> Res;
+ std::optional<bool> Res;
if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) {
CXXRewrittenBinaryOperator::DecomposedForm DF = RBO->getDecomposedForm();
Res = CheckAndSetCond(DF.Opcode, DF.LHS, DF.RHS, RBO->getSourceRange(),
@@ -8383,12 +8469,12 @@ calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
return nullptr;
llvm::APSInt LRes, SRes;
bool IsLowerConst = false, IsStepConst = false;
- if (Optional<llvm::APSInt> Res =
+ if (std::optional<llvm::APSInt> Res =
Lower->getIntegerConstantExpr(SemaRef.Context)) {
LRes = *Res;
IsLowerConst = true;
}
- if (Optional<llvm::APSInt> Res =
+ if (std::optional<llvm::APSInt> Res =
Step->getIntegerConstantExpr(SemaRef.Context)) {
SRes = *Res;
IsStepConst = true;
@@ -8427,7 +8513,7 @@ calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
}
llvm::APSInt URes;
bool IsUpperConst = false;
- if (Optional<llvm::APSInt> Res =
+ if (std::optional<llvm::APSInt> Res =
Upper->getIntegerConstantExpr(SemaRef.Context)) {
URes = *Res;
IsUpperConst = true;
@@ -8708,8 +8794,8 @@ Expr *OpenMPIterationSpaceChecker::buildNumIterations(
UBVal = MinUB.get();
}
}
- Expr *UBExpr = TestIsLessOp.value() ? UBVal : LBVal;
- Expr *LBExpr = TestIsLessOp.value() ? LBVal : UBVal;
+ Expr *UBExpr = *TestIsLessOp ? UBVal : LBVal;
+ Expr *LBExpr = *TestIsLessOp ? LBVal : UBVal;
Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
if (!Upper || !Lower)
@@ -8772,12 +8858,12 @@ std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
// init value.
Expr *MinExpr = nullptr;
Expr *MaxExpr = nullptr;
- Expr *LBExpr = TestIsLessOp.value() ? LB : UB;
- Expr *UBExpr = TestIsLessOp.value() ? UB : LB;
- bool LBNonRect = TestIsLessOp.value() ? InitDependOnLC.has_value()
- : CondDependOnLC.has_value();
- bool UBNonRect = TestIsLessOp.value() ? CondDependOnLC.has_value()
- : InitDependOnLC.has_value();
+ Expr *LBExpr = *TestIsLessOp ? LB : UB;
+ Expr *UBExpr = *TestIsLessOp ? UB : LB;
+ bool LBNonRect =
+ *TestIsLessOp ? InitDependOnLC.has_value() : CondDependOnLC.has_value();
+ bool UBNonRect =
+ *TestIsLessOp ? CondDependOnLC.has_value() : InitDependOnLC.has_value();
Expr *Lower =
LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
Expr *Upper =
@@ -8899,11 +8985,11 @@ Expr *OpenMPIterationSpaceChecker::buildPreCond(
if (!NewLB.isUsable() || !NewUB.isUsable())
return nullptr;
- ExprResult CondExpr = SemaRef.BuildBinOp(
- S, DefaultLoc,
- TestIsLessOp.value() ? (TestIsStrictOp ? BO_LT : BO_LE)
- : (TestIsStrictOp ? BO_GT : BO_GE),
- NewLB.get(), NewUB.get());
+ ExprResult CondExpr =
+ SemaRef.BuildBinOp(S, DefaultLoc,
+ *TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
+ : (TestIsStrictOp ? BO_GT : BO_GE),
+ NewLB.get(), NewUB.get());
if (CondExpr.isUsable()) {
if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
SemaRef.Context.BoolTy))
@@ -8979,9 +9065,9 @@ Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
return nullptr;
// Upper - Lower
Expr *Upper =
- TestIsLessOp.value() ? Cnt : tryBuildCapture(SemaRef, LB, Captures).get();
+ *TestIsLessOp ? Cnt : tryBuildCapture(SemaRef, LB, Captures).get();
Expr *Lower =
- TestIsLessOp.value() ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt;
+ *TestIsLessOp ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt;
if (!Upper || !Lower)
return nullptr;
@@ -9383,7 +9469,7 @@ static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
if (E == nullptr)
return false;
- if (Optional<llvm::APSInt> Result =
+ if (std::optional<llvm::APSInt> Result =
E->getIntegerConstantExpr(SemaRef.Context))
return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
return false;
@@ -11012,9 +11098,50 @@ StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
}
+StmtResult Sema::ActOnOpenMPErrorDirective(ArrayRef<OMPClause *> Clauses,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ bool InExContext) {
+ const OMPAtClause *AtC =
+ OMPExecutableDirective::getSingleClause<OMPAtClause>(Clauses);
+
+ if (AtC && !InExContext && AtC->getAtKind() == OMPC_AT_execution) {
+ Diag(AtC->getAtKindKwLoc(), diag::err_omp_unexpected_execution_modifier);
+ return StmtError();
+ }
+
+ const OMPSeverityClause *SeverityC =
+ OMPExecutableDirective::getSingleClause<OMPSeverityClause>(Clauses);
+ const OMPMessageClause *MessageC =
+ OMPExecutableDirective::getSingleClause<OMPMessageClause>(Clauses);
+ Expr *ME = MessageC ? MessageC->getMessageString() : nullptr;
+
+ if (!AtC || AtC->getAtKind() == OMPC_AT_compilation) {
+ if (SeverityC && SeverityC->getSeverityKind() == OMPC_SEVERITY_warning)
+ Diag(SeverityC->getSeverityKindKwLoc(), diag::warn_diagnose_if_succeeded)
+ << (ME ? cast<StringLiteral>(ME)->getString() : "WARNING");
+ else
+ Diag(StartLoc, diag::err_diagnose_if_succeeded)
+ << (ME ? cast<StringLiteral>(ME)->getString() : "ERROR");
+ if (!SeverityC || SeverityC->getSeverityKind() != OMPC_SEVERITY_warning)
+ return StmtError();
+ }
+ return OMPErrorDirective::Create(Context, StartLoc, EndLoc, Clauses);
+}
+
StmtResult Sema::ActOnOpenMPTaskwaitDirective(ArrayRef<OMPClause *> Clauses,
SourceLocation StartLoc,
SourceLocation EndLoc) {
+ const OMPNowaitClause *NowaitC =
+ OMPExecutableDirective::getSingleClause<OMPNowaitClause>(Clauses);
+ bool HasDependC =
+ !OMPExecutableDirective::getClausesOfKind<OMPDependClause>(Clauses)
+ .empty();
+ if (NowaitC && !HasDependC) {
+ Diag(StartLoc, diag::err_omp_nowait_clause_without_depend);
+ return StmtError();
+ }
+
return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc, Clauses);
}
@@ -11569,6 +11696,9 @@ protected:
static bool CheckValue(const Expr *E, ErrorInfoTy &ErrorInfo,
bool ShouldBeLValue, bool ShouldBeInteger = false) {
+ if (E->isInstantiationDependent())
+ return true;
+
if (ShouldBeLValue && !E->isLValue()) {
ErrorInfo.Error = ErrorTy::XNotLValue;
ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
@@ -11576,25 +11706,23 @@ protected:
return false;
}
- if (!E->isInstantiationDependent()) {
- QualType QTy = E->getType();
- if (!QTy->isScalarType()) {
- ErrorInfo.Error = ErrorTy::NotScalar;
- ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
- ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
- return false;
- }
- if (ShouldBeInteger && !QTy->isIntegerType()) {
- ErrorInfo.Error = ErrorTy::NotInteger;
- ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
- ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
- return false;
- }
+ QualType QTy = E->getType();
+ if (!QTy->isScalarType()) {
+ ErrorInfo.Error = ErrorTy::NotScalar;
+ ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
+ ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
+ return false;
+ }
+ if (ShouldBeInteger && !QTy->isIntegerType()) {
+ ErrorInfo.Error = ErrorTy::NotInteger;
+ ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
+ ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
+ return false;
}
return true;
}
-};
+ };
bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(IfStmt *S,
ErrorInfoTy &ErrorInfo) {
@@ -12174,17 +12302,33 @@ bool OpenMPAtomicCompareCaptureChecker::checkStmt(Stmt *S,
Stmt *UpdateStmt = nullptr;
Stmt *CondUpdateStmt = nullptr;
+ Stmt *CondExprStmt = nullptr;
if (auto *BO = dyn_cast<BinaryOperator>(S1)) {
- // { v = x; cond-update-stmt } or form 45.
- UpdateStmt = S1;
- CondUpdateStmt = S2;
- // Check if form 45.
- if (isa<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) &&
- isa<IfStmt>(S2))
- return checkForm45(CS, ErrorInfo);
- // It cannot be set before we the check for form45.
- IsPostfixUpdate = true;
+ // It could be one of the following cases:
+ // { v = x; cond-update-stmt }
+ // { v = x; cond-expr-stmt }
+ // { cond-expr-stmt; v = x; }
+ // form 45
+ if (isa<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) ||
+ isa<ConditionalOperator>(BO->getRHS()->IgnoreImpCasts())) {
+ // check if form 45
+ if (isa<IfStmt>(S2))
+ return checkForm45(CS, ErrorInfo);
+ // { cond-expr-stmt; v = x; }
+ CondExprStmt = S1;
+ UpdateStmt = S2;
+ } else {
+ IsPostfixUpdate = true;
+ UpdateStmt = S1;
+ if (isa<IfStmt>(S2)) {
+ // { v = x; cond-update-stmt }
+ CondUpdateStmt = S2;
+ } else {
+ // { v = x; cond-expr-stmt }
+ CondExprStmt = S2;
+ }
+ }
} else {
// { cond-update-stmt v = x; }
UpdateStmt = S2;
@@ -12200,10 +12344,7 @@ bool OpenMPAtomicCompareCaptureChecker::checkStmt(Stmt *S,
return false;
}
- if (!checkCondUpdateStmt(IS, ErrorInfo))
- return false;
-
- return true;
+ return checkCondUpdateStmt(IS, ErrorInfo);
};
// CheckUpdateStmt has to be called *after* CheckCondUpdateStmt.
@@ -12236,7 +12377,9 @@ bool OpenMPAtomicCompareCaptureChecker::checkStmt(Stmt *S,
return true;
};
- if (!CheckCondUpdateStmt(CondUpdateStmt))
+ if (CondUpdateStmt && !CheckCondUpdateStmt(CondUpdateStmt))
+ return false;
+ if (CondExprStmt && !checkCondExprStmt(CondExprStmt, ErrorInfo))
return false;
if (!CheckUpdateStmt(UpdateStmt))
return false;
@@ -12277,7 +12420,7 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
case OMPC_write:
case OMPC_update:
MutexClauseEncountered = true;
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case OMPC_capture:
case OMPC_compare: {
if (AtomicKind != OMPC_unknown && MutexClauseEncountered) {
@@ -15049,12 +15192,6 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
case OMPC_priority:
Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
break;
- case OMPC_grainsize:
- Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
- break;
- case OMPC_num_tasks:
- Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
- break;
case OMPC_hint:
Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
break;
@@ -15076,9 +15213,17 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
case OMPC_partial:
Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc);
break;
+ case OMPC_message:
+ Res = ActOnOpenMPMessageClause(Expr, StartLoc, LParenLoc, EndLoc);
+ break;
case OMPC_align:
Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc);
break;
+ case OMPC_ompx_dyn_cgroup_mem:
+ Res = ActOnOpenMPXDynCGroupMemClause(Expr, StartLoc, LParenLoc, EndLoc);
+ break;
+ case OMPC_grainsize:
+ case OMPC_num_tasks:
case OMPC_device:
case OMPC_if:
case OMPC_default:
@@ -15135,6 +15280,8 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
case OMPC_match:
case OMPC_nontemporal:
case OMPC_order:
+ case OMPC_at:
+ case OMPC_severity:
case OMPC_destroy:
case OMPC_inclusive:
case OMPC_exclusive:
@@ -15166,7 +15313,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
CaptureRegion = OMPD_parallel;
break;
}
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case OMPD_target_parallel:
case OMPD_target_parallel_for:
case OMPD_target_parallel_loop:
@@ -15181,7 +15328,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
CaptureRegion = OMPD_parallel;
break;
}
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case OMPD_target_teams_distribute_parallel_for:
// If this clause applies to the nested 'parallel' region, capture within
// the 'teams' region, otherwise do not capture.
@@ -15194,7 +15341,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
CaptureRegion = OMPD_parallel;
break;
}
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case OMPD_teams_distribute_parallel_for:
CaptureRegion = OMPD_teams;
break;
@@ -15289,6 +15436,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_threadprivate:
case OMPD_allocate:
case OMPD_taskyield:
+ case OMPD_error:
case OMPD_barrier:
case OMPD_taskwait:
case OMPD_cancellation_point:
@@ -15377,6 +15525,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_threadprivate:
case OMPD_allocate:
case OMPD_taskyield:
+ case OMPD_error:
case OMPD_barrier:
case OMPD_taskwait:
case OMPD_cancellation_point:
@@ -15473,6 +15622,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_threadprivate:
case OMPD_allocate:
case OMPD_taskyield:
+ case OMPD_error:
case OMPD_barrier:
case OMPD_taskwait:
case OMPD_cancellation_point:
@@ -15514,6 +15664,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
break;
case OMPC_thread_limit:
switch (DKind) {
+ case OMPD_target:
case OMPD_target_teams:
case OMPD_target_teams_distribute:
case OMPD_target_teams_distribute_simd:
@@ -15555,7 +15706,6 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_parallel_for:
case OMPD_parallel_for_simd:
case OMPD_parallel_loop:
- case OMPD_target:
case OMPD_target_simd:
case OMPD_target_parallel:
case OMPD_target_parallel_for:
@@ -15564,6 +15714,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_threadprivate:
case OMPD_allocate:
case OMPD_taskyield:
+ case OMPD_error:
case OMPD_barrier:
case OMPD_taskwait:
case OMPD_cancellation_point:
@@ -15652,6 +15803,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_threadprivate:
case OMPD_allocate:
case OMPD_taskyield:
+ case OMPD_error:
case OMPD_barrier:
case OMPD_taskwait:
case OMPD_cancellation_point:
@@ -15743,6 +15895,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_threadprivate:
case OMPD_allocate:
case OMPD_taskyield:
+ case OMPD_error:
case OMPD_barrier:
case OMPD_taskwait:
case OMPD_cancellation_point:
@@ -15785,6 +15938,26 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
llvm_unreachable("Unknown OpenMP directive");
}
break;
+ case OMPC_ompx_dyn_cgroup_mem:
+ switch (DKind) {
+ case OMPD_target:
+ case OMPD_target_simd:
+ case OMPD_target_teams:
+ case OMPD_target_parallel:
+ case OMPD_target_teams_distribute:
+ case OMPD_target_teams_distribute_simd:
+ case OMPD_target_parallel_for:
+ case OMPD_target_parallel_for_simd:
+ case OMPD_target_parallel_loop:
+ case OMPD_target_teams_distribute_parallel_for:
+ case OMPD_target_teams_distribute_parallel_for_simd:
+ case OMPD_target_teams_loop:
+ CaptureRegion = OMPD_target;
+ break;
+ default:
+ llvm_unreachable("Unknown OpenMP directive");
+ }
+ break;
case OMPC_device:
switch (DKind) {
case OMPD_target_update:
@@ -15837,6 +16010,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_threadprivate:
case OMPD_allocate:
case OMPD_taskyield:
+ case OMPD_error:
case OMPD_barrier:
case OMPD_taskwait:
case OMPD_cancellation_point:
@@ -15928,6 +16102,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_threadprivate:
case OMPD_allocate:
case OMPD_taskyield:
+ case OMPD_error:
case OMPD_barrier:
case OMPD_taskwait:
case OMPD_cancellation_point:
@@ -16052,6 +16227,9 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPC_match:
case OMPC_nontemporal:
case OMPC_order:
+ case OMPC_at:
+ case OMPC_severity:
+ case OMPC_message:
case OMPC_destroy:
case OMPC_detach:
case OMPC_inclusive:
@@ -16190,7 +16368,7 @@ isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
ValExpr = Value.get();
// The expression must evaluate to a non-negative integer value.
- if (Optional<llvm::APSInt> Result =
+ if (std::optional<llvm::APSInt> Result =
ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
if (Result->isSigned() &&
!((!StrictlyPositive && Result->isNonNegative()) ||
@@ -16320,10 +16498,22 @@ OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
/// Tries to find omp_allocator_handle_t type.
static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
DSAStackTy *Stack) {
- QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
- if (!OMPAllocatorHandleT.isNull())
+ if (!Stack->getOMPAllocatorHandleT().isNull())
return true;
- // Build the predefined allocator expressions.
+
+ // Set the allocator handle type.
+ IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_allocator_handle_t");
+ ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
+ if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
+ S.Diag(Loc, diag::err_omp_implied_type_not_found)
+ << "omp_allocator_handle_t";
+ return false;
+ }
+ QualType AllocatorHandleEnumTy = PT.get();
+ AllocatorHandleEnumTy.addConst();
+ Stack->setOMPAllocatorHandleT(AllocatorHandleEnumTy);
+
+ // Fill the predefined allocator map.
bool ErrorFound = false;
for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
@@ -16343,9 +16533,10 @@ static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
ErrorFound = true;
break;
}
- if (OMPAllocatorHandleT.isNull())
- OMPAllocatorHandleT = AllocatorType;
- if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
+ Res = S.PerformImplicitConversion(Res.get(), AllocatorHandleEnumTy,
+ Sema::AA_Initializing,
+ /* AllowExplicit */ true);
+ if (!Res.isUsable()) {
ErrorFound = true;
break;
}
@@ -16356,8 +16547,7 @@ static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
<< "omp_allocator_handle_t";
return false;
}
- OMPAllocatorHandleT.addConst();
- Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
+
return true;
}
@@ -16442,10 +16632,6 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
ArgumentLoc, StartLoc, LParenLoc, EndLoc);
break;
- case OMPC_order:
- Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
- ArgumentLoc, StartLoc, LParenLoc, EndLoc);
- break;
case OMPC_update:
Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
ArgumentLoc, StartLoc, LParenLoc, EndLoc);
@@ -16454,6 +16640,15 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
Res = ActOnOpenMPBindClause(static_cast<OpenMPBindClauseKind>(Argument),
ArgumentLoc, StartLoc, LParenLoc, EndLoc);
break;
+ case OMPC_at:
+ Res = ActOnOpenMPAtClause(static_cast<OpenMPAtClauseKind>(Argument),
+ ArgumentLoc, StartLoc, LParenLoc, EndLoc);
+ break;
+ case OMPC_severity:
+ Res = ActOnOpenMPSeverityClause(
+ static_cast<OpenMPSeverityClauseKind>(Argument), ArgumentLoc, StartLoc,
+ LParenLoc, EndLoc);
+ break;
case OMPC_if:
case OMPC_final:
case OMPC_num_threads:
@@ -16529,6 +16724,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
case OMPC_uses_allocators:
case OMPC_affinity:
case OMPC_when:
+ case OMPC_message:
default:
llvm_unreachable("Clause is not allowed.");
}
@@ -16537,13 +16733,12 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
static std::string
getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
- ArrayRef<unsigned> Exclude = llvm::None) {
+ ArrayRef<unsigned> Exclude = std::nullopt) {
SmallString<256> Buffer;
llvm::raw_svector_ostream Out(Buffer);
unsigned Skipped = Exclude.size();
- auto S = Exclude.begin(), E = Exclude.end();
for (unsigned I = First; I < Last; ++I) {
- if (std::find(S, E, I) != E) {
+ if (llvm::is_contained(Exclude, I)) {
--Skipped;
continue;
}
@@ -16633,22 +16828,87 @@ OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
LParenLoc, EndLoc);
}
-OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
- SourceLocation KindKwLoc,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc) {
- if (Kind == OMPC_ORDER_unknown) {
+OMPClause *Sema::ActOnOpenMPAtClause(OpenMPAtClauseKind Kind,
+ SourceLocation KindKwLoc,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ if (Kind == OMPC_AT_unknown) {
+ Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
+ << getListOfPossibleValues(OMPC_at, /*First=*/0,
+ /*Last=*/OMPC_AT_unknown)
+ << getOpenMPClauseName(OMPC_at);
+ return nullptr;
+ }
+ return new (Context)
+ OMPAtClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
+}
+
+OMPClause *Sema::ActOnOpenMPSeverityClause(OpenMPSeverityClauseKind Kind,
+ SourceLocation KindKwLoc,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ if (Kind == OMPC_SEVERITY_unknown) {
+ Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
+ << getListOfPossibleValues(OMPC_severity, /*First=*/0,
+ /*Last=*/OMPC_SEVERITY_unknown)
+ << getOpenMPClauseName(OMPC_severity);
+ return nullptr;
+ }
+ return new (Context)
+ OMPSeverityClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
+}
+
+OMPClause *Sema::ActOnOpenMPMessageClause(Expr *ME, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ assert(ME && "NULL expr in Message clause");
+ if (!isa<StringLiteral>(ME)) {
+ Diag(ME->getBeginLoc(), diag::warn_clause_expected_string)
+ << getOpenMPClauseName(OMPC_message);
+ return nullptr;
+ }
+ return new (Context) OMPMessageClause(ME, StartLoc, LParenLoc, EndLoc);
+}
+
+OMPClause *Sema::ActOnOpenMPOrderClause(
+ OpenMPOrderClauseModifier Modifier, OpenMPOrderClauseKind Kind,
+ SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
+ SourceLocation KindLoc, SourceLocation EndLoc) {
+ if (Kind != OMPC_ORDER_concurrent ||
+ (LangOpts.OpenMP < 51 && MLoc.isValid())) {
+ // Kind should be concurrent,
+ // Modifiers introduced in OpenMP 5.1
static_assert(OMPC_ORDER_unknown > 0,
"OMPC_ORDER_unknown not greater than 0");
- Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
- << getListOfPossibleValues(OMPC_order, /*First=*/0,
+
+ Diag(KindLoc, diag::err_omp_unexpected_clause_value)
+ << getListOfPossibleValues(OMPC_order,
+ /*First=*/0,
/*Last=*/OMPC_ORDER_unknown)
<< getOpenMPClauseName(OMPC_order);
return nullptr;
}
- return new (Context)
- OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
+ if (LangOpts.OpenMP >= 51) {
+ if (Modifier == OMPC_ORDER_MODIFIER_unknown && MLoc.isValid()) {
+ Diag(MLoc, diag::err_omp_unexpected_clause_value)
+ << getListOfPossibleValues(OMPC_order,
+ /*First=*/OMPC_ORDER_MODIFIER_unknown + 1,
+ /*Last=*/OMPC_ORDER_MODIFIER_last)
+ << getOpenMPClauseName(OMPC_order);
+ } else {
+ DSAStack->setRegionHasOrderConcurrent(/*HasOrderConcurrent=*/true);
+ if (DSAStack->getCurScope()) {
+ // mark the current scope with 'order' flag
+ unsigned existingFlags = DSAStack->getCurScope()->getFlags();
+ DSAStack->getCurScope()->setFlags(existingFlags |
+ Scope::OpenMPOrderClauseScope);
+ }
+ }
+ }
+ return new (Context) OMPOrderClause(Kind, KindLoc, StartLoc, LParenLoc,
+ EndLoc, Modifier, MLoc);
}
OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
@@ -16760,12 +17020,33 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
EndLoc);
break;
+ case OMPC_order:
+ enum { OrderModifier, OrderKind };
+ Res = ActOnOpenMPOrderClause(
+ static_cast<OpenMPOrderClauseModifier>(Argument[OrderModifier]),
+ static_cast<OpenMPOrderClauseKind>(Argument[OrderKind]), StartLoc,
+ LParenLoc, ArgumentLoc[OrderModifier], ArgumentLoc[OrderKind], EndLoc);
+ break;
case OMPC_device:
assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
Res = ActOnOpenMPDeviceClause(
static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
break;
+ case OMPC_grainsize:
+ assert(Argument.size() == 1 && ArgumentLoc.size() == 1 &&
+ "Modifier for grainsize clause and its location are expected.");
+ Res = ActOnOpenMPGrainsizeClause(
+ static_cast<OpenMPGrainsizeClauseModifier>(Argument.back()), Expr,
+ StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
+ break;
+ case OMPC_num_tasks:
+ assert(Argument.size() == 1 && ArgumentLoc.size() == 1 &&
+ "Modifier for num_tasks clause and its location are expected.");
+ Res = ActOnOpenMPNumTasksClause(
+ static_cast<OpenMPNumTasksClauseModifier>(Argument.back()), Expr,
+ StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
+ break;
case OMPC_final:
case OMPC_num_threads:
case OMPC_safelen:
@@ -16811,9 +17092,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
case OMPC_num_teams:
case OMPC_thread_limit:
case OMPC_priority:
- case OMPC_grainsize:
case OMPC_nogroup:
- case OMPC_num_tasks:
case OMPC_hint:
case OMPC_unknown:
case OMPC_uniform:
@@ -16831,7 +17110,9 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
case OMPC_device_type:
case OMPC_match:
case OMPC_nontemporal:
- case OMPC_order:
+ case OMPC_at:
+ case OMPC_severity:
+ case OMPC_message:
case OMPC_destroy:
case OMPC_novariants:
case OMPC_nocontext:
@@ -16935,7 +17216,7 @@ OMPClause *Sema::ActOnOpenMPScheduleClause(
// OpenMP [2.7.1, Restrictions]
// chunk_size must be a loop invariant integer expression with a positive
// value.
- if (Optional<llvm::APSInt> Result =
+ if (std::optional<llvm::APSInt> Result =
ValExpr->getIntegerConstantExpr(Context)) {
if (Result->isSigned() && !Result->isStrictlyPositive()) {
Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
@@ -17088,6 +17369,9 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
case OMPC_match:
case OMPC_nontemporal:
case OMPC_order:
+ case OMPC_at:
+ case OMPC_severity:
+ case OMPC_message:
case OMPC_novariants:
case OMPC_nocontext:
case OMPC_detach:
@@ -17096,6 +17380,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
case OMPC_uses_allocators:
case OMPC_affinity:
case OMPC_when:
+ case OMPC_ompx_dyn_cgroup_mem:
default:
llvm_unreachable("Clause is not allowed.");
}
@@ -17247,32 +17532,28 @@ StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses,
// OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
// Each interop-var may be specified for at most one action-clause of each
// interop construct.
- llvm::SmallPtrSet<const VarDecl *, 4> InteropVars;
- for (const OMPClause *C : Clauses) {
+ llvm::SmallPtrSet<const ValueDecl *, 4> InteropVars;
+ for (OMPClause *C : Clauses) {
OpenMPClauseKind ClauseKind = C->getClauseKind();
- const DeclRefExpr *DRE = nullptr;
- SourceLocation VarLoc;
+ std::pair<ValueDecl *, bool> DeclResult;
+ SourceLocation ELoc;
+ SourceRange ERange;
if (ClauseKind == OMPC_init) {
- const auto *IC = cast<OMPInitClause>(C);
- VarLoc = IC->getVarLoc();
- DRE = dyn_cast_or_null<DeclRefExpr>(IC->getInteropVar());
+ auto *E = cast<OMPInitClause>(C)->getInteropVar();
+ DeclResult = getPrivateItem(*this, E, ELoc, ERange);
} else if (ClauseKind == OMPC_use) {
- const auto *UC = cast<OMPUseClause>(C);
- VarLoc = UC->getVarLoc();
- DRE = dyn_cast_or_null<DeclRefExpr>(UC->getInteropVar());
+ auto *E = cast<OMPUseClause>(C)->getInteropVar();
+ DeclResult = getPrivateItem(*this, E, ELoc, ERange);
} else if (ClauseKind == OMPC_destroy) {
- const auto *DC = cast<OMPDestroyClause>(C);
- VarLoc = DC->getVarLoc();
- DRE = dyn_cast_or_null<DeclRefExpr>(DC->getInteropVar());
+ auto *E = cast<OMPDestroyClause>(C)->getInteropVar();
+ DeclResult = getPrivateItem(*this, E, ELoc, ERange);
}
- if (!DRE)
- continue;
-
- if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
- if (!InteropVars.insert(VD->getCanonicalDecl()).second) {
- Diag(VarLoc, diag::err_omp_interop_var_multiple_actions) << VD;
+ if (DeclResult.first) {
+ if (!InteropVars.insert(DeclResult.first).second) {
+ Diag(ELoc, diag::err_omp_interop_var_multiple_actions)
+ << DeclResult.first;
return StmtError();
}
}
@@ -17284,16 +17565,20 @@ StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses,
static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr,
SourceLocation VarLoc,
OpenMPClauseKind Kind) {
- if (InteropVarExpr->isValueDependent() || InteropVarExpr->isTypeDependent() ||
- InteropVarExpr->isInstantiationDependent() ||
- InteropVarExpr->containsUnexpandedParameterPack())
+ SourceLocation ELoc;
+ SourceRange ERange;
+ Expr *RefExpr = InteropVarExpr;
+ auto Res =
+ getPrivateItem(SemaRef, RefExpr, ELoc, ERange,
+ /*AllowArraySection=*/false, /*DiagType=*/"omp_interop_t");
+
+ if (Res.second) {
+ // It will be analyzed later.
return true;
+ }
- const auto *DRE = dyn_cast<DeclRefExpr>(InteropVarExpr);
- if (!DRE || !isa<VarDecl>(DRE->getDecl())) {
- SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) << 0;
+ if (!Res.first)
return false;
- }
// Interop variable should be of type omp_interop_t.
bool HasError = false;
@@ -17335,8 +17620,7 @@ static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr,
}
OMPClause *
-Sema::ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef<Expr *> PrefExprs,
- bool IsTarget, bool IsTargetSync,
+Sema::ActOnOpenMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation VarLoc, SourceLocation EndLoc) {
@@ -17345,7 +17629,7 @@ Sema::ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef<Expr *> PrefExprs,
// Check prefer_type values. These foreign-runtime-id values are either
// string literals or constant integral expressions.
- for (const Expr *E : PrefExprs) {
+ for (const Expr *E : InteropInfo.PreferTypes) {
if (E->isValueDependent() || E->isTypeDependent() ||
E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
continue;
@@ -17357,9 +17641,8 @@ Sema::ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef<Expr *> PrefExprs,
return nullptr;
}
- return OMPInitClause::Create(Context, InteropVar, PrefExprs, IsTarget,
- IsTargetSync, StartLoc, LParenLoc, VarLoc,
- EndLoc);
+ return OMPInitClause::Create(Context, InteropVar, InteropInfo, StartLoc,
+ LParenLoc, VarLoc, EndLoc);
}
OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
@@ -17549,7 +17832,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&
"Unexpected map modifier.");
Res = ActOnOpenMPMapClause(
- Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
+ Data.IteratorExpr, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId,
static_cast<OpenMPMapClauseKind>(ExtraModifier), Data.IsMapTypeImplicit,
ExtraModifierLoc, ColonLoc, VarList, Locs);
@@ -17644,6 +17927,9 @@ OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
case OMPC_device_type:
case OMPC_match:
case OMPC_order:
+ case OMPC_at:
+ case OMPC_severity:
+ case OMPC_message:
case OMPC_destroy:
case OMPC_novariants:
case OMPC_nocontext:
@@ -18417,7 +18703,7 @@ static T filterLookupForUDReductionAndMapper(
static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
- for (auto RD : D->redecls()) {
+ for (auto *RD : D->redecls()) {
// Don't bother with extra checks if we already know this one isn't visible.
if (RD == D)
continue;
@@ -19744,7 +20030,7 @@ OMPClause *Sema::ActOnOpenMPLinearClause(
// Warn about zero linear step (it would be probably better specified as
// making corresponding variables 'const').
- if (Optional<llvm::APSInt> Result =
+ if (std::optional<llvm::APSInt> Result =
StepExpr->getIntegerConstantExpr(Context)) {
if (!Result->isNegative() && !Result->isStrictlyPositive())
Diag(StepLoc, diag::warn_omp_linear_step_zero)
@@ -20927,8 +21213,8 @@ public:
}
// Pointer arithmetic is the only thing we expect to happen here so after we
- // make sure the binary operator is a pointer type, the we only thing need
- // to to is to visit the subtree that has the same type as root (so that we
+ // make sure the binary operator is a pointer type, the only thing we need
+ // to do is to visit the subtree that has the same type as root (so that we
// know the other subtree is just an offset)
Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
@@ -21403,7 +21689,7 @@ static void checkMappableExpressionList(
CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
ArrayRef<Expr *> UnresolvedMappers,
OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
- ArrayRef<OpenMPMapModifierKind> Modifiers = None,
+ ArrayRef<OpenMPMapModifierKind> Modifiers = std::nullopt,
bool IsMapTypeImplicit = false, bool NoDiagnose = false) {
// We only expect mappable expressions in 'to', 'from', and 'map' clauses.
assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
@@ -21603,10 +21889,12 @@ static void checkMappableExpressionList(
// target enter data
// OpenMP [2.10.2, Restrictions, p. 99]
// A map-type must be specified in all map clauses and must be either
- // to or alloc.
+ // to or alloc. Starting with OpenMP 5.2 the default map type is `to` if
+ // no map type is present.
OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
if (DKind == OMPD_target_enter_data &&
- !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
+ !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc ||
+ SemaRef.getLangOpts().OpenMP >= 52)) {
SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
<< (IsMapTypeImplicit ? 1 : 0)
<< getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
@@ -21617,10 +21905,11 @@ static void checkMappableExpressionList(
// target exit_data
// OpenMP [2.10.3, Restrictions, p. 102]
// A map-type must be specified in all map clauses and must be either
- // from, release, or delete.
+ // from, release, or delete. Starting with OpenMP 5.2 the default map
+ // type is `from` if no map type is present.
if (DKind == OMPD_target_exit_data &&
!(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
- MapType == OMPC_MAP_delete)) {
+ MapType == OMPC_MAP_delete || SemaRef.getLangOpts().OpenMP >= 52)) {
SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
<< (IsMapTypeImplicit ? 1 : 0)
<< getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
@@ -21698,7 +21987,7 @@ static void checkMappableExpressionList(
/*WhereFoundClauseKind=*/OMPC_map);
// Save the components and declaration to create the clause. For purposes of
- // the clause creation, any component list that has has base 'this' uses
+ // the clause creation, any component list that has base 'this' uses
// null as base declaration.
MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
MVLI.VarComponents.back().append(CurComponents.begin(),
@@ -21709,7 +21998,7 @@ static void checkMappableExpressionList(
}
OMPClause *Sema::ActOnOpenMPMapClause(
- ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
+ Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
ArrayRef<SourceLocation> MapTypeModifiersLoc,
CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
@@ -21719,9 +22008,14 @@ OMPClause *Sema::ActOnOpenMPMapClause(
OpenMPMapModifierKind Modifiers[] = {
OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
- OMPC_MAP_MODIFIER_unknown};
+ OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
+ if (IteratorModifier && !IteratorModifier->getType()->isSpecificBuiltinType(
+ BuiltinType::OMPIterator))
+ Diag(IteratorModifier->getExprLoc(),
+ diag::err_omp_map_modifier_not_iterator);
+
// Process map-type-modifiers, flag errors for duplicate modifiers.
unsigned Count = 0;
for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
@@ -21745,11 +22039,11 @@ OMPClause *Sema::ActOnOpenMPMapClause(
// We need to produce a map clause even if we don't have variables so that
// other diagnostics related with non-existing map clauses are accurate.
- return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
- MVLI.VarBaseDeclarations, MVLI.VarComponents,
- MVLI.UDMapperList, Modifiers, ModifiersLoc,
- MapperIdScopeSpec.getWithLocInContext(Context),
- MapperId, MapType, IsMapTypeImplicit, MapLoc);
+ return OMPMapClause::Create(
+ Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
+ MVLI.VarComponents, MVLI.UDMapperList, IteratorModifier, Modifiers,
+ ModifiersLoc, MapperIdScopeSpec.getWithLocInContext(Context), MapperId,
+ MapType, IsMapTypeImplicit, MapLoc);
}
QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
@@ -22143,6 +22437,11 @@ Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
return E;
}
+void Sema::ActOnOpenMPIteratorVarDecl(VarDecl *VD) {
+ if (DSAStack->getDeclareMapperVarRef())
+ DSAStack->addIteratorVarDecl(VD);
+}
+
bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
assert(LangOpts.OpenMP && "Expected OpenMP mode.");
const Expr *Ref = DSAStack->getDeclareMapperVarRef();
@@ -22151,6 +22450,8 @@ bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
return true;
if (VD->isUsableInConstantExpressions(Context))
return true;
+ if (LangOpts.OpenMP >= 52 && DSAStack->isIteratorVarDecl(VD))
+ return true;
return false;
}
return true;
@@ -22235,10 +22536,21 @@ OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
StartLoc, LParenLoc, EndLoc);
}
-OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc) {
+OMPClause *Sema::ActOnOpenMPGrainsizeClause(
+ OpenMPGrainsizeClauseModifier Modifier, Expr *Grainsize,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation ModifierLoc, SourceLocation EndLoc) {
+ assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) &&
+ "Unexpected grainsize modifier in OpenMP < 51.");
+
+ if (ModifierLoc.isValid() && Modifier == OMPC_GRAINSIZE_unknown) {
+ std::string Values = getListOfPossibleValues(OMPC_grainsize, /*First=*/0,
+ OMPC_GRAINSIZE_unknown);
+ Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
+ << Values << getOpenMPClauseName(OMPC_grainsize);
+ return nullptr;
+ }
+
Expr *ValExpr = Grainsize;
Stmt *HelperValStmt = nullptr;
OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
@@ -22246,20 +22558,33 @@ OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
// OpenMP [2.9.2, taskloop Constrcut]
// The parameter of the grainsize clause must be a positive integer
// expression.
- if (!isNonNegativeIntegerValue(
- ValExpr, *this, OMPC_grainsize,
- /*StrictlyPositive=*/true, /*BuildCapture=*/true,
- DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
+ if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize,
+ /*StrictlyPositive=*/true,
+ /*BuildCapture=*/true,
+ DSAStack->getCurrentDirective(),
+ &CaptureRegion, &HelperValStmt))
return nullptr;
- return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
- StartLoc, LParenLoc, EndLoc);
+ return new (Context)
+ OMPGrainsizeClause(Modifier, ValExpr, HelperValStmt, CaptureRegion,
+ StartLoc, LParenLoc, ModifierLoc, EndLoc);
}
-OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc) {
+OMPClause *Sema::ActOnOpenMPNumTasksClause(
+ OpenMPNumTasksClauseModifier Modifier, Expr *NumTasks,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation ModifierLoc, SourceLocation EndLoc) {
+ assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) &&
+ "Unexpected num_tasks modifier in OpenMP < 51.");
+
+ if (ModifierLoc.isValid() && Modifier == OMPC_NUMTASKS_unknown) {
+ std::string Values = getListOfPossibleValues(OMPC_num_tasks, /*First=*/0,
+ OMPC_NUMTASKS_unknown);
+ Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
+ << Values << getOpenMPClauseName(OMPC_num_tasks);
+ return nullptr;
+ }
+
Expr *ValExpr = NumTasks;
Stmt *HelperValStmt = nullptr;
OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
@@ -22273,8 +22598,9 @@ OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
return nullptr;
- return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
- StartLoc, LParenLoc, EndLoc);
+ return new (Context)
+ OMPNumTasksClause(Modifier, ValExpr, HelperValStmt, CaptureRegion,
+ StartLoc, LParenLoc, ModifierLoc, EndLoc);
}
OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
@@ -22384,7 +22710,7 @@ OMPClause *Sema::ActOnOpenMPDistScheduleClause(
// OpenMP [2.7.1, Restrictions]
// chunk_size must be a loop invariant integer expression with a positive
// value.
- if (Optional<llvm::APSInt> Result =
+ if (std::optional<llvm::APSInt> Result =
ValExpr->getIntegerConstantExpr(Context)) {
if (Result->isSigned() && !Result->isStrictlyPositive()) {
Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
@@ -22583,29 +22909,29 @@ void Sema::ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc,
const unsigned Level = -1;
auto *VD = cast<ValueDecl>(ND);
- llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
+ std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
OMPDeclareTargetDeclAttr::getActiveAttr(VD);
- if (ActiveAttr && ActiveAttr.value()->getDevType() != DTCI.DT &&
- ActiveAttr.value()->getLevel() == Level) {
+ if (ActiveAttr && (*ActiveAttr)->getDevType() != DTCI.DT &&
+ (*ActiveAttr)->getLevel() == Level) {
Diag(Loc, diag::err_omp_device_type_mismatch)
<< OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.DT)
<< OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(
- ActiveAttr.value()->getDevType());
+ (*ActiveAttr)->getDevType());
return;
}
- if (ActiveAttr && ActiveAttr.value()->getMapType() != MT &&
- ActiveAttr.value()->getLevel() == Level) {
+ if (ActiveAttr && (*ActiveAttr)->getMapType() != MT &&
+ (*ActiveAttr)->getLevel() == Level) {
Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
return;
}
- if (ActiveAttr && ActiveAttr.value()->getLevel() == Level)
+ if (ActiveAttr && (*ActiveAttr)->getLevel() == Level)
return;
Expr *IndirectE = nullptr;
bool IsIndirect = false;
if (DTCI.Indirect) {
- IndirectE = DTCI.Indirect.value();
+ IndirectE = *DTCI.Indirect;
if (!IndirectE)
IsIndirect = true;
}
@@ -22623,13 +22949,14 @@ static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
if (!D || !isa<VarDecl>(D))
return;
auto *VD = cast<VarDecl>(D);
- Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
+ std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
if (SemaRef.LangOpts.OpenMP >= 50 &&
(SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
VD->hasGlobalStorage()) {
- if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
+ if (!MapTy || (*MapTy != OMPDeclareTargetDeclAttr::MT_To &&
+ *MapTy != OMPDeclareTargetDeclAttr::MT_Enter)) {
// OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
// If a lambda declaration and definition appears between a
// declare target directive and the matching end declare target
@@ -22678,7 +23005,7 @@ void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
D = FTD->getTemplatedDecl();
if (auto *FD = dyn_cast<FunctionDecl>(D)) {
- llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
+ std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
Diag(IdLoc, diag::err_omp_function_in_link_clause);
@@ -22696,22 +23023,25 @@ void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
// Checking declaration inside declare target region.
if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
isa<FunctionTemplateDecl>(D)) {
- llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
+ std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
OMPDeclareTargetDeclAttr::getActiveAttr(VD);
unsigned Level = DeclareTargetNesting.size();
- if (ActiveAttr && ActiveAttr.value()->getLevel() >= Level)
+ if (ActiveAttr && (*ActiveAttr)->getLevel() >= Level)
return;
DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
Expr *IndirectE = nullptr;
bool IsIndirect = false;
if (DTCI.Indirect) {
- IndirectE = DTCI.Indirect.value();
+ IndirectE = *DTCI.Indirect;
if (!IndirectE)
IsIndirect = true;
}
auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
- Context, OMPDeclareTargetDeclAttr::MT_To, DTCI.DT, IndirectE,
- IsIndirect, Level, SourceRange(DTCI.Loc, DTCI.Loc));
+ Context,
+ getLangOpts().OpenMP >= 52 ? OMPDeclareTargetDeclAttr::MT_Enter
+ : OMPDeclareTargetDeclAttr::MT_To,
+ DTCI.DT, IndirectE, IsIndirect, Level,
+ SourceRange(DTCI.Loc, DTCI.Loc));
D->addAttr(A);
if (ASTMutationListener *ML = Context.getASTMutationListener())
ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
@@ -23065,13 +23395,17 @@ OMPClause *Sema::ActOnOpenMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
// Store the components in the stack so that they can be used to check
// against other clauses later on.
+ Expr *Component = SimpleRefExpr;
+ auto *VD = dyn_cast<VarDecl>(D);
+ if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
+ isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
+ Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
OMPClauseMappableExprCommon::MappableComponent MC(
- SimpleRefExpr, D, /*IsNonContiguous=*/false);
+ Component, D, /*IsNonContiguous=*/false);
DSAStack->addMappableExpressionComponents(
D, MC, /*WhereFoundClauseKind=*/OMPC_has_device_addr);
// Record the expression we've just processed.
- auto *VD = dyn_cast<VarDecl>(D);
if (!VD && !CurContext->isDependentContext()) {
DeclRefExpr *Ref =
buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
@@ -23336,17 +23670,26 @@ OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
bool IsPredefinedAllocator = false;
- if (DRE)
- IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl());
- if (!DRE ||
- !(Context.hasSameUnqualifiedType(
- AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) ||
- Context.typesAreCompatible(AllocatorExpr->getType(),
- DSAStack->getOMPAllocatorHandleT(),
- /*CompareUnqualified=*/true)) ||
- (!IsPredefinedAllocator &&
- (AllocatorExpr->getType().isConstant(Context) ||
- !AllocatorExpr->isLValue()))) {
+ if (DRE) {
+ OMPAllocateDeclAttr::AllocatorTypeTy AllocatorTy =
+ getAllocatorKind(*this, DSAStack, AllocatorExpr);
+ IsPredefinedAllocator =
+ AllocatorTy !=
+ OMPAllocateDeclAttr::AllocatorTypeTy::OMPUserDefinedMemAlloc;
+ }
+ QualType OMPAllocatorHandleT = DSAStack->getOMPAllocatorHandleT();
+ QualType AllocatorExprType = AllocatorExpr->getType();
+ bool IsTypeCompatible = IsPredefinedAllocator;
+ IsTypeCompatible = IsTypeCompatible ||
+ Context.hasSameUnqualifiedType(AllocatorExprType,
+ OMPAllocatorHandleT);
+ IsTypeCompatible =
+ IsTypeCompatible ||
+ Context.typesAreCompatible(AllocatorExprType, OMPAllocatorHandleT);
+ bool IsNonConstantLValue =
+ !AllocatorExprType.isConstant(Context) && AllocatorExpr->isLValue();
+ if (!DRE || !IsTypeCompatible ||
+ (!IsPredefinedAllocator && !IsNonConstantLValue)) {
Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
<< "omp_allocator_handle_t" << (DRE ? 1 : 0)
<< AllocatorExpr->getType() << D.Allocator->getSourceRange();
@@ -23480,3 +23823,31 @@ OMPClause *Sema::ActOnOpenMPBindClause(OpenMPBindClauseKind Kind,
return OMPBindClause::Create(Context, Kind, KindLoc, StartLoc, LParenLoc,
EndLoc);
}
+
+OMPClause *Sema::ActOnOpenMPXDynCGroupMemClause(Expr *Size,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ Expr *ValExpr = Size;
+ Stmt *HelperValStmt = nullptr;
+
+ // OpenMP [2.5, Restrictions]
+ // The ompx_dyn_cgroup_mem expression must evaluate to a positive integer
+ // value.
+ if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_ompx_dyn_cgroup_mem,
+ /*StrictlyPositive=*/false))
+ return nullptr;
+
+ OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
+ OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
+ DKind, OMPC_ompx_dyn_cgroup_mem, LangOpts.OpenMP);
+ if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
+ ValExpr = MakeFullExpr(ValExpr).get();
+ llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
+ ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
+ HelperValStmt = buildPreInits(Context, Captures);
+ }
+
+ return new (Context) OMPXDynCGroupMemClause(
+ ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
+}