diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-12-18 20:30:12 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2024-04-06 20:11:55 +0000 |
commit | 5f757f3ff9144b609b3c433dfd370cc6bdc191ad (patch) | |
tree | 1b4e980b866cd26a00af34c0a653eb640bd09caf /contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp | |
parent | 3e1c8a35f741a5d114d0ba670b15191355711fe9 (diff) | |
parent | 312c0ed19cc5276a17bacf2120097bec4515b0f1 (diff) |
Diffstat (limited to 'contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Sema/SemaOpenMP.cpp | 342 |
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); +} |