aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-12-18 20:30:12 +0000
committerDimitry Andric <dim@FreeBSD.org>2024-04-06 20:11:55 +0000
commit5f757f3ff9144b609b3c433dfd370cc6bdc191ad (patch)
tree1b4e980b866cd26a00af34c0a653eb640bd09caf /contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp
parent3e1c8a35f741a5d114d0ba670b15191355711fe9 (diff)
parent312c0ed19cc5276a17bacf2120097bec4515b0f1 (diff)
Diffstat (limited to 'contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp342
1 files changed, 298 insertions, 44 deletions
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp b/contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp
index cf805987b378..e400f248d15a 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp
@@ -30,6 +30,7 @@
#include "clang/Sema/EnterExpressionEvaluationContext.h"
#include "clang/Sema/Initialization.h"
#include "clang/Sema/Lookup.h"
+#include "clang/Sema/ParsedAttr.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaInternal.h"
@@ -160,8 +161,12 @@ private:
LoopControlVariablesMapTy LCVMap;
DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
SourceLocation DefaultAttrLoc;
- DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown];
+ DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown + 1];
OpenMPDirectiveKind Directive = OMPD_unknown;
+ /// GenericLoopDirective with bind clause is mapped to other directives,
+ /// like for, distribute and simd. Presently, set MappedDirective to
+ /// OMPLoop. This may also be used in a similar way for other constructs.
+ OpenMPDirectiveKind MappedDirective = OMPD_unknown;
DeclarationNameInfo DirectiveName;
Scope *CurScope = nullptr;
DeclContext *Context = nullptr;
@@ -635,6 +640,24 @@ public:
const SharingMapTy *Top = getTopOfStackOrNull();
return Top ? Top->Directive : OMPD_unknown;
}
+ OpenMPDirectiveKind getMappedDirective() const {
+ const SharingMapTy *Top = getTopOfStackOrNull();
+ return Top ? Top->MappedDirective : OMPD_unknown;
+ }
+ void setCurrentDirective(OpenMPDirectiveKind NewDK) {
+ SharingMapTy *Top = getTopOfStackOrNull();
+ assert(Top &&
+ "Before calling setCurrentDirective Top of Stack not to be NULL.");
+ // Store the old into MappedDirective & assign argument NewDK to Directive.
+ Top->Directive = NewDK;
+ }
+ void setMappedDirective(OpenMPDirectiveKind NewDK) {
+ SharingMapTy *Top = getTopOfStackOrNull();
+ assert(Top &&
+ "Before calling setMappedDirective Top of Stack not to be NULL.");
+ // Store the old into MappedDirective & assign argument NewDK to Directive.
+ Top->MappedDirective = NewDK;
+ }
/// Returns directive kind at specified level.
OpenMPDirectiveKind getDirective(unsigned Level) const {
assert(!isStackEmpty() && "No directive at specified level.");
@@ -1164,9 +1187,7 @@ public:
if (!Top)
return false;
- return llvm::any_of(Top->IteratorVarDecls, [VD](const VarDecl *IteratorVD) {
- return IteratorVD == VD->getCanonicalDecl();
- });
+ return llvm::is_contained(Top->IteratorVarDecls, VD->getCanonicalDecl());
}
/// get captured field from ImplicitDefaultFirstprivateFDs
VarDecl *getImplicitFDCapExprDecl(const FieldDecl *FD) const {
@@ -3668,7 +3689,7 @@ class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
bool ErrorFound = false;
bool TryCaptureCXXThisMembers = false;
CapturedStmt *CS = nullptr;
- const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
+ const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_unknown + 1;
llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
llvm::SmallVector<Expr *, 4> ImplicitPrivate;
llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete];
@@ -3686,6 +3707,7 @@ class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
S->getDirectiveKind() == OMPD_section ||
S->getDirectiveKind() == OMPD_master ||
S->getDirectiveKind() == OMPD_masked ||
+ S->getDirectiveKind() == OMPD_scope ||
isOpenMPLoopTransformationDirective(S->getDirectiveKind())) {
Visit(S->getAssociatedStmt());
return;
@@ -4227,12 +4249,15 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
getCurCapturedRegion()->TheCapturedDecl->addAttr(
AlwaysInlineAttr::CreateImplicit(
Context, {}, AlwaysInlineAttr::Keyword_forceinline));
- Sema::CapturedParamNameType ParamsTarget[] = {
- std::make_pair(StringRef(), QualType()) // __context with shared vars
- };
+ SmallVector<Sema::CapturedParamNameType, 2> ParamsTarget;
+ if (getLangOpts().OpenMPIsTargetDevice)
+ ParamsTarget.push_back(std::make_pair(StringRef("dyn_ptr"), VoidPtrTy));
+ ParamsTarget.push_back(
+ std::make_pair(StringRef(), QualType())); // __context with shared vars;
// Start a captured region for 'target' with no implicit parameters.
ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
- ParamsTarget, /*OpenMPCaptureLevel=*/1);
+ ParamsTarget,
+ /*OpenMPCaptureLevel=*/1);
Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
std::make_pair(".global_tid.", KmpInt32PtrTy),
std::make_pair(".bound_tid.", KmpInt32PtrTy),
@@ -4271,8 +4296,13 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
getCurCapturedRegion()->TheCapturedDecl->addAttr(
AlwaysInlineAttr::CreateImplicit(
Context, {}, AlwaysInlineAttr::Keyword_forceinline));
+ SmallVector<Sema::CapturedParamNameType, 2> ParamsTarget;
+ if (getLangOpts().OpenMPIsTargetDevice)
+ ParamsTarget.push_back(std::make_pair(StringRef("dyn_ptr"), VoidPtrTy));
+ ParamsTarget.push_back(
+ std::make_pair(StringRef(), QualType())); // __context with shared vars;
ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
- std::make_pair(StringRef(), QualType()),
+ ParamsTarget,
/*OpenMPCaptureLevel=*/1);
break;
}
@@ -4296,6 +4326,7 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
case OMPD_distribute:
case OMPD_distribute_simd:
case OMPD_ordered:
+ case OMPD_scope:
case OMPD_target_data:
case OMPD_dispatch: {
Sema::CapturedParamNameType Params[] = {
@@ -4476,9 +4507,11 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
getCurCapturedRegion()->TheCapturedDecl->addAttr(
AlwaysInlineAttr::CreateImplicit(
Context, {}, AlwaysInlineAttr::Keyword_forceinline));
- Sema::CapturedParamNameType ParamsTarget[] = {
- std::make_pair(StringRef(), QualType()) // __context with shared vars
- };
+ SmallVector<Sema::CapturedParamNameType, 2> ParamsTarget;
+ if (getLangOpts().OpenMPIsTargetDevice)
+ ParamsTarget.push_back(std::make_pair(StringRef("dyn_ptr"), VoidPtrTy));
+ ParamsTarget.push_back(
+ std::make_pair(StringRef(), QualType())); // __context with shared vars;
// Start a captured region for 'target' with no implicit parameters.
ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
ParamsTarget, /*OpenMPCaptureLevel=*/1);
@@ -5107,7 +5140,10 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
diag::note_omp_previous_critical_region);
return true;
}
- } else if (CurrentRegion == OMPD_barrier) {
+ } else if (CurrentRegion == OMPD_barrier || CurrentRegion == OMPD_scope) {
+ // OpenMP 5.1 [2.22, Nesting of Regions]
+ // A scope region may not be closely nested inside a worksharing, loop,
+ // task, taskloop, critical, ordered, atomic, or masked region.
// OpenMP 5.1 [2.22, Nesting of Regions]
// A barrier region may not be closely nested inside a worksharing, loop,
// task, taskloop, critical, ordered, atomic, or masked region.
@@ -5678,7 +5714,8 @@ static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy,
// the step size, rounding-up the effective upper bound ensures that the
// last iteration is included.
// Note that the rounding-up may cause an overflow in a temporry that
- // could be avoided, but would have occurred in a C-style for-loop as well.
+ // could be avoided, but would have occurred in a C-style for-loop as
+ // well.
Expr *Divisor = BuildVarRef(NewStep);
if (Rel == BO_GE || Rel == BO_GT)
Divisor =
@@ -6085,10 +6122,95 @@ processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack,
}
}
+bool Sema::mapLoopConstruct(llvm::SmallVector<OMPClause *> &ClausesWithoutBind,
+ ArrayRef<OMPClause *> Clauses,
+ OpenMPBindClauseKind BindKind,
+ OpenMPDirectiveKind &Kind,
+ OpenMPDirectiveKind &PrevMappedDirective) {
+
+ bool UseClausesWithoutBind = false;
+
+ // Restricting to "#pragma omp loop bind"
+ if (getLangOpts().OpenMP >= 50 && Kind == OMPD_loop) {
+ if (BindKind == OMPC_BIND_unknown) {
+ // Setting the enclosing teams or parallel construct for the loop
+ // directive without bind clause.
+ BindKind = OMPC_BIND_thread; // Default bind(thread) if binding is unknown
+
+ const OpenMPDirectiveKind ParentDirective =
+ DSAStack->getParentDirective();
+ if (ParentDirective == OMPD_unknown) {
+ Diag(DSAStack->getDefaultDSALocation(),
+ diag::err_omp_bind_required_on_loop);
+ } else if (ParentDirective == OMPD_parallel ||
+ ParentDirective == OMPD_target_parallel) {
+ BindKind = OMPC_BIND_parallel;
+ } else if (ParentDirective == OMPD_teams ||
+ ParentDirective == OMPD_target_teams) {
+ BindKind = OMPC_BIND_teams;
+ }
+ } else {
+ // bind clause is present, so we should set flag indicating to only
+ // use the clauses that aren't the bind clause for the new directive that
+ // loop is lowered to.
+ UseClausesWithoutBind = true;
+ }
+
+ for (OMPClause *C : Clauses) {
+ // Spec restriction : bind(teams) and reduction not permitted.
+ if (BindKind == OMPC_BIND_teams &&
+ C->getClauseKind() == llvm::omp::Clause::OMPC_reduction)
+ Diag(DSAStack->getDefaultDSALocation(),
+ diag::err_omp_loop_reduction_clause);
+
+ // A new Vector ClausesWithoutBind, which does not contain the bind
+ // clause, for passing to new directive.
+ if (C->getClauseKind() != llvm::omp::Clause::OMPC_bind)
+ ClausesWithoutBind.push_back(C);
+ }
+
+ switch (BindKind) {
+ case OMPC_BIND_parallel:
+ Kind = OMPD_for;
+ DSAStack->setCurrentDirective(OMPD_for);
+ DSAStack->setMappedDirective(OMPD_loop);
+ PrevMappedDirective = OMPD_loop;
+ break;
+ case OMPC_BIND_teams:
+ Kind = OMPD_distribute;
+ DSAStack->setCurrentDirective(OMPD_distribute);
+ DSAStack->setMappedDirective(OMPD_loop);
+ PrevMappedDirective = OMPD_loop;
+ break;
+ case OMPC_BIND_thread:
+ Kind = OMPD_simd;
+ DSAStack->setCurrentDirective(OMPD_simd);
+ DSAStack->setMappedDirective(OMPD_loop);
+ PrevMappedDirective = OMPD_loop;
+ break;
+ case OMPC_BIND_unknown:
+ break;
+ }
+ } else if (PrevMappedDirective == OMPD_loop) {
+ /// An initial pass after recognizing all the statements is done in the
+ /// Parser when the directive OMPD_loop is mapped to OMPD_for,
+ /// OMPD_distribute or OMPD_simd. A second transform pass with call from
+ /// clang::TreeTransform::TransformOMPExecutableDirective() is done
+ /// with the Directive as one of the above mapped directive without
+ /// the bind clause. Then "PrevMappedDirective" stored in the
+ /// OMPExecutableDirective is accessed and hence this else statement.
+
+ DSAStack->setMappedDirective(OMPD_loop);
+ }
+
+ return UseClausesWithoutBind;
+}
+
StmtResult Sema::ActOnOpenMPExecutableDirective(
OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
- Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
+ Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc,
+ OpenMPDirectiveKind PrevMappedDirective) {
StmtResult Res = StmtError();
OpenMPBindClauseKind BindKind = OMPC_BIND_unknown;
if (const OMPBindClause *BC =
@@ -6105,10 +6227,21 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
isOpenMPTargetDataManagementDirective(Kind)))
Diag(StartLoc, diag::warn_hip_omp_target_directives);
+ llvm::SmallVector<OMPClause *> ClausesWithoutBind;
+ bool UseClausesWithoutBind = false;
+
+ UseClausesWithoutBind = mapLoopConstruct(ClausesWithoutBind, Clauses,
+ BindKind, Kind, PrevMappedDirective);
+
llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
VarsWithInheritedDSAType VarsWithInheritedDSA;
bool ErrorFound = false;
- ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
+ if (getLangOpts().OpenMP >= 50 && UseClausesWithoutBind) {
+ ClausesWithImplicit.append(ClausesWithoutBind.begin(),
+ ClausesWithoutBind.end());
+ } else {
+ ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
+ }
if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master &&
Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) {
@@ -6143,7 +6276,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
SmallVector<Expr *, 4> ImplicitPrivates(
DSAChecker.getImplicitPrivate().begin(),
DSAChecker.getImplicitPrivate().end());
- const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
+ const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_unknown + 1;
SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
ImplicitMapModifiers[DefaultmapKindNum];
@@ -6329,6 +6462,10 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
if (LangOpts.OpenMP >= 50)
AllowedNameModifiers.push_back(OMPD_simd);
break;
+ case OMPD_scope:
+ Res =
+ ActOnOpenMPScopeDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
+ break;
case OMPD_parallel_master:
Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
StartLoc, EndLoc);
@@ -6633,6 +6770,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
case OMPD_target_teams_loop:
Res = ActOnOpenMPTargetTeamsGenericLoopDirective(
ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
+ AllowedNameModifiers.push_back(OMPD_target);
break;
case OMPD_parallel_loop:
Res = ActOnOpenMPParallelGenericLoopDirective(
@@ -9201,9 +9339,13 @@ static bool checkOpenMPIterationSpace(
auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
// Ranged for is supported only in OpenMP 5.0.
if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
+ OpenMPDirectiveKind DK = (SemaRef.getLangOpts().OpenMP < 50 ||
+ DSA.getMappedDirective() == OMPD_unknown)
+ ? DKind
+ : DSA.getMappedDirective();
SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
<< (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
- << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
+ << getOpenMPDirectiveName(DK) << TotalNestedLoopCount
<< (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
if (TotalNestedLoopCount > 1) {
if (CollapseLoopCountExpr && OrderedLoopCountExpr)
@@ -10318,6 +10460,24 @@ static bool checkSimdlenSafelenSpecified(Sema &S,
return false;
}
+static bool checkGenericLoopLastprivate(Sema &S, ArrayRef<OMPClause *> Clauses,
+ OpenMPDirectiveKind K,
+ DSAStackTy *Stack);
+
+bool Sema::checkLastPrivateForMappedDirectives(ArrayRef<OMPClause *> Clauses) {
+
+ // Check for syntax of lastprivate
+ // Param of the lastprivate have different meanings in the mapped directives
+ // e.g. "omp loop" Only loop iteration vars are allowed in lastprivate clause
+ // "omp for" lastprivate vars must be shared
+ if (getLangOpts().OpenMP >= 50 &&
+ DSAStack->getMappedDirective() == OMPD_loop &&
+ checkGenericLoopLastprivate(*this, Clauses, OMPD_loop, DSAStack)) {
+ return false;
+ }
+ return true;
+}
+
StmtResult
Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
SourceLocation StartLoc, SourceLocation EndLoc,
@@ -10325,6 +10485,9 @@ Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
if (!AStmt)
return StmtError();
+ if (!checkLastPrivateForMappedDirectives(Clauses))
+ return StmtError();
+
assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
OMPLoopBasedDirective::HelperExprs B;
// In presence of clause 'collapse' or 'ordered' with number of loops, it will
@@ -10353,8 +10516,10 @@ Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
return StmtError();
setFunctionHasBranchProtectedScope();
- return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
- Clauses, AStmt, B);
+ auto *SimdDirective = OMPSimdDirective::Create(
+ Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
+ DSAStack->getMappedDirective());
+ return SimdDirective;
}
StmtResult
@@ -10364,6 +10529,9 @@ Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
if (!AStmt)
return StmtError();
+ if (!checkLastPrivateForMappedDirectives(Clauses))
+ return StmtError();
+
assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
OMPLoopBasedDirective::HelperExprs B;
// In presence of clause 'collapse' or 'ordered' with number of loops, it will
@@ -10388,10 +10556,11 @@ Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
}
}
- setFunctionHasBranchProtectedScope();
- return OMPForDirective::Create(
+ auto *ForDirective = OMPForDirective::Create(
Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
- DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
+ DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion(),
+ DSAStack->getMappedDirective());
+ return ForDirective;
}
StmtResult Sema::ActOnOpenMPForSimdDirective(
@@ -11436,6 +11605,9 @@ class OpenMPAtomicUpdateChecker {
/// RHS binary operation does not have reference to the updated LHS
/// part.
NotAnUpdateExpression,
+ /// An expression contains semantical error not related to
+ /// 'omp atomic [update]'
+ NotAValidExpression,
/// No errors is found.
NoError
};
@@ -11613,6 +11785,10 @@ bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
ErrorFound = NotABinaryOrUnaryExpression;
NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
NoteRange = ErrorRange = AtomicBody->getSourceRange();
+ } else if (AtomicBody->containsErrors()) {
+ ErrorFound = NotAValidExpression;
+ NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
+ NoteRange = ErrorRange = AtomicBody->getSourceRange();
}
} else {
ErrorFound = NotAScalarType;
@@ -12506,6 +12682,14 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
}
break;
}
+ case OMPC_fail: {
+ if (AtomicKind != OMPC_compare) {
+ Diag(C->getBeginLoc(), diag::err_omp_atomic_fail_no_compare)
+ << SourceRange(C->getBeginLoc(), C->getEndLoc());
+ return StmtError();
+ }
+ break;
+ }
case OMPC_seq_cst:
case OMPC_acq_rel:
case OMPC_acquire:
@@ -13938,6 +14122,9 @@ StmtResult Sema::ActOnOpenMPDistributeDirective(
if (!AStmt)
return StmtError();
+ if (!checkLastPrivateForMappedDirectives(Clauses))
+ return StmtError();
+
assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
OMPLoopBasedDirective::HelperExprs B;
// In presence of clause 'collapse' with number of loops, it will
@@ -13953,8 +14140,10 @@ StmtResult Sema::ActOnOpenMPDistributeDirective(
"omp for loop exprs were not built");
setFunctionHasBranchProtectedScope();
- return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
- NestedLoopCount, Clauses, AStmt, B);
+ auto *DistributeDirective = OMPDistributeDirective::Create(
+ Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
+ DSAStack->getMappedDirective());
+ return DistributeDirective;
}
StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
@@ -15741,6 +15930,11 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_target_teams_distribute_parallel_for:
case OMPD_target_teams_distribute_parallel_for_simd:
case OMPD_target_teams_loop:
+ case OMPD_target_simd:
+ case OMPD_target_parallel:
+ case OMPD_target_parallel_for:
+ case OMPD_target_parallel_for_simd:
+ case OMPD_target_parallel_loop:
CaptureRegion = OMPD_target;
break;
case OMPD_teams_distribute_parallel_for:
@@ -15776,11 +15970,6 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_parallel_for:
case OMPD_parallel_for_simd:
case OMPD_parallel_loop:
- case OMPD_target_simd:
- case OMPD_target_parallel:
- case OMPD_target_parallel_for:
- case OMPD_target_parallel_for_simd:
- case OMPD_target_parallel_loop:
case OMPD_threadprivate:
case OMPD_allocate:
case OMPD_taskyield:
@@ -16702,6 +16891,11 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
ArgumentLoc, StartLoc, LParenLoc, EndLoc);
break;
+ case OMPC_fail:
+ Res = ActOnOpenMPFailClause(
+ static_cast<OpenMPClauseKind>(Argument),
+ ArgumentLoc, StartLoc, LParenLoc, EndLoc);
+ break;
case OMPC_update:
Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
ArgumentLoc, StartLoc, LParenLoc, EndLoc);
@@ -17342,6 +17536,9 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
case OMPC_compare:
Res = ActOnOpenMPCompareClause(StartLoc, EndLoc);
break;
+ case OMPC_fail:
+ Res = ActOnOpenMPFailClause(StartLoc, EndLoc);
+ break;
case OMPC_seq_cst:
Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
break;
@@ -17389,6 +17586,9 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
case OMPC_partial:
Res = ActOnOpenMPPartialClause(nullptr, StartLoc, /*LParenLoc=*/{}, EndLoc);
break;
+ case OMPC_ompx_bare:
+ Res = ActOnOpenMPXBareClause(StartLoc, EndLoc);
+ break;
case OMPC_if:
case OMPC_final:
case OMPC_num_threads:
@@ -17499,6 +17699,24 @@ OMPClause *Sema::ActOnOpenMPCompareClause(SourceLocation StartLoc,
return new (Context) OMPCompareClause(StartLoc, EndLoc);
}
+OMPClause *Sema::ActOnOpenMPFailClause(SourceLocation StartLoc,
+ SourceLocation EndLoc) {
+ return new (Context) OMPFailClause(StartLoc, EndLoc);
+}
+
+OMPClause *Sema::ActOnOpenMPFailClause(
+ OpenMPClauseKind Parameter, SourceLocation KindLoc,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+
+ if (!checkFailClauseParameter(Parameter)) {
+ Diag(KindLoc, diag::err_omp_atomic_fail_wrong_or_no_clauses);
+ return nullptr;
+ }
+ return new (Context)
+ OMPFailClause(Parameter, KindLoc, StartLoc, LParenLoc, EndLoc);
+}
+
OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
SourceLocation EndLoc) {
return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
@@ -17882,7 +18100,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
Res = ActOnOpenMPLinearClause(
VarList, Data.DepModOrTailExpr, StartLoc, LParenLoc,
static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
- ColonLoc, EndLoc);
+ ColonLoc, Data.StepModifierLoc, EndLoc);
break;
case OMPC_aligned:
Res = ActOnOpenMPAlignedClause(VarList, Data.DepModOrTailExpr, StartLoc,
@@ -19489,7 +19707,7 @@ static bool actOnOMPReductionKindClause(
if (ConstantLengthOASE && !SingleElement) {
for (llvm::APSInt &Size : ArraySizes)
PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
- ArrayType::Normal,
+ ArraySizeModifier::Normal,
/*IndexTypeQuals=*/0);
}
}
@@ -19516,7 +19734,7 @@ static bool actOnOMPReductionKindClause(
Type,
new (Context)
OpaqueValueExpr(ELoc, Context.getSizeType(), VK_PRValue),
- ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
+ ArraySizeModifier::Normal, /*IndexTypeQuals=*/0, SourceRange());
} else if (!ASE && !OASE &&
Context.getAsArrayType(D->getType().getNonReferenceType())) {
PrivateTy = D->getType().getNonReferenceType();
@@ -19754,9 +19972,9 @@ static bool actOnOMPReductionKindClause(
// Build temp array for prefix sum.
auto *Dim = new (S.Context)
OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
- QualType ArrayTy =
- S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal,
- /*IndexTypeQuals=*/0, {ELoc, ELoc});
+ QualType ArrayTy = S.Context.getVariableArrayType(
+ PrivateTy, Dim, ArraySizeModifier::Normal,
+ /*IndexTypeQuals=*/0, {ELoc, ELoc});
VarDecl *TempArrayVD =
buildVarDecl(S, ELoc, ArrayTy, D->getName(),
D->hasAttrs() ? &D->getAttrs() : nullptr);
@@ -19967,7 +20185,7 @@ OMPClause *Sema::ActOnOpenMPInReductionClause(
bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
SourceLocation LinLoc) {
if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
- LinKind == OMPC_LINEAR_unknown) {
+ LinKind == OMPC_LINEAR_unknown || LinKind == OMPC_LINEAR_step) {
Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
return true;
}
@@ -20019,12 +20237,19 @@ bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
OMPClause *Sema::ActOnOpenMPLinearClause(
ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
- SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
+ SourceLocation LinLoc, SourceLocation ColonLoc,
+ SourceLocation StepModifierLoc, SourceLocation EndLoc) {
SmallVector<Expr *, 8> Vars;
SmallVector<Expr *, 8> Privates;
SmallVector<Expr *, 8> Inits;
SmallVector<Decl *, 4> ExprCaptures;
SmallVector<Expr *, 4> ExprPostUpdates;
+ // OpenMP 5.2 [Section 5.4.6, linear clause]
+ // step-simple-modifier is exclusive, can't be used with 'val', 'uval', or
+ // 'ref'
+ if (LinLoc.isValid() && StepModifierLoc.isInvalid() && Step &&
+ getLangOpts().OpenMP >= 52)
+ Diag(Step->getBeginLoc(), diag::err_omp_step_simple_modifier_exclusive);
if (CheckOpenMPLinearModifier(LinKind, LinLoc))
LinKind = OMPC_LINEAR_val;
for (Expr *RefExpr : VarList) {
@@ -20144,8 +20369,8 @@ OMPClause *Sema::ActOnOpenMPLinearClause(
}
return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
- ColonLoc, EndLoc, Vars, Privates, Inits,
- StepExpr, CalcStepExpr,
+ ColonLoc, StepModifierLoc, EndLoc, Vars,
+ Privates, Inits, StepExpr, CalcStepExpr,
buildPreInits(Context, ExprCaptures),
buildPostUpdate(*this, ExprPostUpdates));
}
@@ -20823,6 +21048,8 @@ Sema::ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data,
if (OASE) {
QualType BaseType =
OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
+ if (BaseType.isNull())
+ return nullptr;
if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
ExprTy = ATy->getElementType();
else
@@ -22427,12 +22654,12 @@ void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
PopFunctionScopeInfo();
if (Initializer != nullptr) {
- DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
+ DRD->setInitializer(Initializer, OMPDeclareReductionInitKind::Call);
} else if (OmpPrivParm->hasInit()) {
DRD->setInitializer(OmpPrivParm->getInit(),
OmpPrivParm->isDirectInit()
- ? OMPDeclareReductionDecl::DirectInit
- : OMPDeclareReductionDecl::CopyInit);
+ ? OMPDeclareReductionInitKind::Direct
+ : OMPDeclareReductionInitKind::Copy);
} else {
DRD->setInvalidDecl();
}
@@ -23100,6 +23327,10 @@ void Sema::ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc,
if (ASTMutationListener *ML = Context.getASTMutationListener())
ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
+ if (auto *VD = dyn_cast<VarDecl>(ND);
+ LangOpts.OpenMP && VD && VD->hasAttr<OMPDeclareTargetDeclAttr>() &&
+ VD->hasGlobalStorage())
+ ActOnOpenMPDeclareTargetInitializer(ND);
}
static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
@@ -23743,6 +23974,17 @@ OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
Vars);
}
+StmtResult Sema::ActOnOpenMPScopeDirective(ArrayRef<OMPClause *> Clauses,
+ Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc) {
+ if (!AStmt)
+ return StmtError();
+
+ setFunctionHasBranchProtectedScope();
+
+ return OMPScopeDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
+}
+
OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
SourceLocation LParenLoc,
@@ -24093,3 +24335,15 @@ OMPClause *Sema::ActOnOpenMPDoacrossClause(
DSAStack->addDoacrossDependClause(C, OpsOffs);
return C;
}
+
+OMPClause *Sema::ActOnOpenMPXAttributeClause(ArrayRef<const Attr *> Attrs,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ return new (Context) OMPXAttributeClause(Attrs, StartLoc, LParenLoc, EndLoc);
+}
+
+OMPClause *Sema::ActOnOpenMPXBareClause(SourceLocation StartLoc,
+ SourceLocation EndLoc) {
+ return new (Context) OMPXBareClause(StartLoc, EndLoc);
+}