diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h index 61499974faf4ddde06776b5e8ab90c00fdc785d0..7e6fb46cfbb496135bfce218d0f9c40a7ef9478f 100644 --- a/include/clang/AST/StmtOpenMP.h +++ b/include/clang/AST/StmtOpenMP.h @@ -92,65 +92,91 @@ public: /// \brief Iterates over a filtered subrange of clauses applied to a /// directive. /// - /// This iterator visits only those declarations that meet some run-time - /// criteria. - template <class FilterPredicate> class filtered_clause_iterator { - protected: + /// This iterator visits only clauses of type SpecificClause. + template <typename SpecificClause> + class specific_clause_iterator + : public std::iterator<std::forward_iterator_tag, const SpecificClause *, + ptrdiff_t, const SpecificClause *, + const SpecificClause *> { ArrayRef<OMPClause *>::const_iterator Current; ArrayRef<OMPClause *>::const_iterator End; - FilterPredicate Pred; + void SkipToNextClause() { - while (Current != End && !Pred(*Current)) + while (Current != End && !isa<SpecificClause>(*Current)) ++Current; } public: - typedef const OMPClause *value_type; - filtered_clause_iterator() : Current(), End() {} - filtered_clause_iterator(ArrayRef<OMPClause *> Arr, FilterPredicate Pred) - : Current(Arr.begin()), End(Arr.end()), Pred(std::move(Pred)) { + explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses) + : Current(Clauses.begin()), End(Clauses.end()) { SkipToNextClause(); } - value_type operator*() const { return *Current; } - value_type operator->() const { return *Current; } - filtered_clause_iterator &operator++() { + + const SpecificClause *operator*() const { + return cast<SpecificClause>(*Current); + } + const SpecificClause *operator->() const { + return cast<SpecificClause>(*Current); + } + + specific_clause_iterator &operator++() { ++Current; SkipToNextClause(); return *this; } - - filtered_clause_iterator operator++(int) { - filtered_clause_iterator tmp(*this); + specific_clause_iterator operator++(int) { + specific_clause_iterator tmp(*this); ++(*this); return tmp; } - bool operator!() { return Current == End; } - explicit operator bool() { return Current != End; } - bool empty() const { return Current == End; } + bool operator==(const specific_clause_iterator &RHS) const { + assert(End == RHS.End && "Comparing iterators of different directives!"); + return Current == RHS.Current; + } + bool operator!=(const specific_clause_iterator &RHS) const { + return !(*this == RHS); + } }; - template <typename Fn> - filtered_clause_iterator<Fn> getFilteredClauses(Fn &&fn) const { - return filtered_clause_iterator<Fn>(clauses(), std::move(fn)); + template <typename SpecificClause> + static llvm::iterator_range<specific_clause_iterator<SpecificClause>> + getClausesOfKind(ArrayRef<OMPClause *> Clauses) { + return {specific_clause_iterator<SpecificClause>(Clauses), + specific_clause_iterator<SpecificClause>( + llvm::makeArrayRef(Clauses.end(), 0))}; } - struct ClauseKindFilter { - OpenMPClauseKind Kind; - bool operator()(const OMPClause *clause) const { - return clause->getClauseKind() == Kind; - } - }; - filtered_clause_iterator<ClauseKindFilter> - getClausesOfKind(OpenMPClauseKind Kind) const { - return getFilteredClauses(ClauseKindFilter{Kind}); + + template <typename SpecificClause> + llvm::iterator_range<specific_clause_iterator<SpecificClause>> + getClausesOfKind() const { + return getClausesOfKind<SpecificClause>(clauses()); } - /// \brief Gets a single clause of the specified kind \a K associated with the + /// Gets a single clause of the specified kind associated with the /// current directive iff there is only one clause of this kind (and assertion /// is fired if there is more than one clause is associated with the - /// directive). Returns nullptr if no clause of kind \a K is associated with + /// directive). Returns nullptr if no clause of this kind is associated with /// the directive. - const OMPClause *getSingleClause(OpenMPClauseKind K) const; + template <typename SpecificClause> + const SpecificClause *getSingleClause() const { + auto Clauses = getClausesOfKind<SpecificClause>(); + + if (Clauses.begin() != Clauses.end()) { + assert(std::next(Clauses.begin()) == Clauses.end() && + "There are at least 2 clauses of the specified kind"); + return *Clauses.begin(); + } + return nullptr; + } + + /// Returns true if the current directive has one or more clauses of a + /// specific kind. + template <typename SpecificClause> + bool hasClausesOfKind() const { + auto Clauses = getClausesOfKind<SpecificClause>(); + return Clauses.begin() != Clauses.end(); + } /// \brief Returns starting location of directive kind. SourceLocation getLocStart() const { return StartLoc; } diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index 22b557dadc64c1fc2fccd927db50c0c8b946cb27..2169da324534e3b07f6e8fe458b5e1111feca4c7 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -1621,18 +1621,6 @@ OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, unsigned N) { return new (Mem) OMPDependClause(N); } -const OMPClause * -OMPExecutableDirective::getSingleClause(OpenMPClauseKind K) const { - auto &&I = getClausesOfKind(K); - - if (I) { - auto *Clause = *I; - assert(!++I && "There are at least 2 clauses of the specified kind"); - return Clause; - } - return nullptr; -} - OMPParallelDirective *OMPParallelDirective::Create( const ASTContext &C, SourceLocation StartLoc, diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp index 4bc5276fcdf00a625e7ade274c52700b6feb611d..572608dfed90315e081f79863568eb7cf9384efe 100644 --- a/lib/CodeGen/CGStmtOpenMP.cpp +++ b/lib/CodeGen/CGStmtOpenMP.cpp @@ -115,8 +115,7 @@ void CodeGenFunction::EmitOMPCopy(CodeGenFunction &CGF, bool CodeGenFunction::EmitOMPFirstprivateClause(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope) { llvm::DenseSet<const VarDecl *> EmittedAsFirstprivate; - for (auto &&I = D.getClausesOfKind(OMPC_firstprivate); I; ++I) { - auto *C = cast<OMPFirstprivateClause>(*I); + for (const auto *C : D.getClausesOfKind<OMPFirstprivateClause>()) { auto IRef = C->varlist_begin(); auto InitsRef = C->inits().begin(); for (auto IInit : C->private_copies()) { @@ -189,8 +188,7 @@ void CodeGenFunction::EmitOMPPrivateClause( const OMPExecutableDirective &D, CodeGenFunction::OMPPrivateScope &PrivateScope) { llvm::DenseSet<const VarDecl *> EmittedAsPrivate; - for (auto &&I = D.getClausesOfKind(OMPC_private); I; ++I) { - auto *C = cast<OMPPrivateClause>(*I); + for (const auto *C : D.getClausesOfKind<OMPPrivateClause>()) { auto IRef = C->varlist_begin(); for (auto IInit : C->private_copies()) { auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); @@ -218,8 +216,7 @@ bool CodeGenFunction::EmitOMPCopyinClause(const OMPExecutableDirective &D) { // __kmpc_barrier(&loc, global_tid); llvm::DenseSet<const VarDecl *> CopiedVars; llvm::BasicBlock *CopyBegin = nullptr, *CopyEnd = nullptr; - for (auto &&I = D.getClausesOfKind(OMPC_copyin); I; ++I) { - auto *C = cast<OMPCopyinClause>(*I); + for (const auto *C : D.getClausesOfKind<OMPCopyinClause>()) { auto IRef = C->varlist_begin(); auto ISrcRef = C->source_exprs().begin(); auto IDestRef = C->destination_exprs().begin(); @@ -279,9 +276,8 @@ bool CodeGenFunction::EmitOMPLastprivateClauseInit( const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope) { bool HasAtLeastOneLastprivate = false; llvm::DenseSet<const VarDecl *> AlreadyEmittedVars; - for (auto &&I = D.getClausesOfKind(OMPC_lastprivate); I; ++I) { + for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) { HasAtLeastOneLastprivate = true; - auto *C = cast<OMPLastprivateClause>(*I); auto IRef = C->varlist_begin(); auto IDestRef = C->destination_exprs().begin(); for (auto *IInit : C->private_copies()) { @@ -359,8 +355,7 @@ void CodeGenFunction::EmitOMPLastprivateClauseFinal( { llvm::DenseSet<const VarDecl *> AlreadyEmittedVars; bool FirstLCV = true; - for (auto &&I = D.getClausesOfKind(OMPC_lastprivate); I; ++I) { - auto *C = cast<OMPLastprivateClause>(*I); + for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) { auto IRef = C->varlist_begin(); auto ISrcRef = C->source_exprs().begin(); auto IDestRef = C->destination_exprs().begin(); @@ -405,8 +400,7 @@ void CodeGenFunction::EmitOMPLastprivateClauseFinal( void CodeGenFunction::EmitOMPReductionClauseInit( const OMPExecutableDirective &D, CodeGenFunction::OMPPrivateScope &PrivateScope) { - for (auto &&I = D.getClausesOfKind(OMPC_reduction); I; ++I) { - auto *C = cast<OMPReductionClause>(*I); + for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) { auto ILHS = C->lhs_exprs().begin(); auto IRHS = C->rhs_exprs().begin(); for (auto IRef : C->varlists()) { @@ -442,9 +436,8 @@ void CodeGenFunction::EmitOMPReductionClauseFinal( llvm::SmallVector<const Expr *, 8> RHSExprs; llvm::SmallVector<const Expr *, 8> ReductionOps; bool HasAtLeastOneReduction = false; - for (auto &&I = D.getClausesOfKind(OMPC_reduction); I; ++I) { + for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) { HasAtLeastOneReduction = true; - auto *C = cast<OMPReductionClause>(*I); LHSExprs.append(C->lhs_exprs().begin(), C->lhs_exprs().end()); RHSExprs.append(C->rhs_exprs().begin(), C->rhs_exprs().end()); ReductionOps.append(C->reduction_ops().begin(), C->reduction_ops().end()); @@ -454,7 +447,7 @@ void CodeGenFunction::EmitOMPReductionClauseFinal( // parallel directive (it always has implicit barrier). CGM.getOpenMPRuntime().emitReduction( *this, D.getLocEnd(), LHSExprs, RHSExprs, ReductionOps, - D.getSingleClause(OMPC_nowait) || + D.getSingleClause<OMPNowaitClause>() || isOpenMPParallelDirective(D.getDirectiveKind()) || D.getDirectiveKind() == OMPD_simd, D.getDirectiveKind() == OMPD_simd); @@ -469,23 +462,21 @@ static void emitCommonOMPParallelDirective(CodeGenFunction &CGF, auto CapturedStruct = CGF.GenerateCapturedStmtArgument(*CS); auto OutlinedFn = CGF.CGM.getOpenMPRuntime().emitParallelOutlinedFunction( S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen); - if (auto C = S.getSingleClause(OMPC_num_threads)) { + if (const auto *NumThreadsClause = S.getSingleClause<OMPNumThreadsClause>()) { CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF); - auto NumThreadsClause = cast<OMPNumThreadsClause>(C); auto NumThreads = CGF.EmitScalarExpr(NumThreadsClause->getNumThreads(), /*IgnoreResultAssign*/ true); CGF.CGM.getOpenMPRuntime().emitNumThreadsClause( CGF, NumThreads, NumThreadsClause->getLocStart()); } - if (auto *C = S.getSingleClause(OMPC_proc_bind)) { + if (const auto *ProcBindClause = S.getSingleClause<OMPProcBindClause>()) { CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF); - auto *ProcBindClause = cast<OMPProcBindClause>(C); CGF.CGM.getOpenMPRuntime().emitProcBindClause( CGF, ProcBindClause->getProcBindKind(), ProcBindClause->getLocStart()); } const Expr *IfCond = nullptr; - if (auto C = S.getSingleClause(OMPC_if)) { - IfCond = cast<OMPIfClause>(C)->getCondition(); + if (const auto *C = S.getSingleClause<OMPIfClause>()) { + IfCond = C->getCondition(); } CGF.CGM.getOpenMPRuntime().emitParallelCall(CGF, S.getLocStart(), OutlinedFn, CapturedStruct, IfCond); @@ -526,8 +517,7 @@ void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D, EmitIgnoredExpr(I); } // Update the linear variables. - for (auto &&I = D.getClausesOfKind(OMPC_linear); I; ++I) { - auto *C = cast<OMPLinearClause>(*I); + for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) { for (auto U : C->updates()) { EmitIgnoredExpr(U); } @@ -596,8 +586,7 @@ void CodeGenFunction::EmitOMPInnerLoop( void CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) { // Emit inits for the linear variables. - for (auto &&I = D.getClausesOfKind(OMPC_linear); I; ++I) { - auto *C = cast<OMPLinearClause>(*I); + for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) { for (auto Init : C->inits()) { auto *VD = cast<VarDecl>(cast<DeclRefExpr>(Init)->getDecl()); auto *OrigVD = cast<VarDecl>( @@ -627,8 +616,7 @@ void CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) { static void emitLinearClauseFinal(CodeGenFunction &CGF, const OMPLoopDirective &D) { // Emit the final values of the linear variables. - for (auto &&I = D.getClausesOfKind(OMPC_linear); I; ++I) { - auto *C = cast<OMPLinearClause>(*I); + for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) { auto IC = C->varlist_begin(); for (auto F : C->finals()) { auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl()); @@ -648,8 +636,7 @@ static void emitLinearClauseFinal(CodeGenFunction &CGF, static void emitAlignedClause(CodeGenFunction &CGF, const OMPExecutableDirective &D) { - for (auto &&I = D.getClausesOfKind(OMPC_aligned); I; ++I) { - auto *Clause = cast<OMPAlignedClause>(*I); + for (const auto *Clause : D.getClausesOfKind<OMPAlignedClause>()) { unsigned ClauseAlignment = 0; if (auto AlignmentExpr = Clause->getAlignment()) { auto AlignmentCI = @@ -719,8 +706,7 @@ static void emitPreCond(CodeGenFunction &CGF, const OMPLoopDirective &S, static void emitPrivateLinearVars(CodeGenFunction &CGF, const OMPExecutableDirective &D, CodeGenFunction::OMPPrivateScope &PrivateScope) { - for (auto &&I = D.getClausesOfKind(OMPC_linear); I; ++I) { - auto *C = cast<OMPLinearClause>(*I); + for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) { auto CurPrivate = C->privates().begin(); for (auto *E : C->varlists()) { auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); @@ -741,8 +727,7 @@ emitPrivateLinearVars(CodeGenFunction &CGF, const OMPExecutableDirective &D, static void emitSimdlenSafelenClause(CodeGenFunction &CGF, const OMPExecutableDirective &D) { - if (auto *C = - cast_or_null<OMPSimdlenClause>(D.getSingleClause(OMPC_simdlen))) { + if (const auto *C = D.getSingleClause<OMPSimdlenClause>()) { RValue Len = CGF.EmitAnyExpr(C->getSimdlen(), AggValueSlot::ignored(), /*ignoreResult=*/true); llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal()); @@ -750,9 +735,8 @@ static void emitSimdlenSafelenClause(CodeGenFunction &CGF, // In presence of finite 'safelen', it may be unsafe to mark all // the memory instructions parallel, because loop-carried // dependences of 'safelen' iterations are possible. - CGF.LoopStack.setParallel(!D.getSingleClause(OMPC_safelen)); - } else if (auto *C = cast_or_null<OMPSafelenClause>( - D.getSingleClause(OMPC_safelen))) { + CGF.LoopStack.setParallel(!D.getSingleClause<OMPSafelenClause>()); + } else if (const auto *C = D.getSingleClause<OMPSafelenClause>()) { RValue Len = CGF.EmitAnyExpr(C->getSafelen(), AggValueSlot::ignored(), /*ignoreResult=*/true); llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal()); @@ -1041,8 +1025,7 @@ emitScheduleClause(CodeGenFunction &CGF, const OMPLoopDirective &S, // Detect the loop schedule kind and chunk. auto ScheduleKind = OMPC_SCHEDULE_unknown; llvm::Value *Chunk = nullptr; - if (auto *C = - cast_or_null<OMPScheduleClause>(S.getSingleClause(OMPC_schedule))) { + if (const auto *C = S.getSingleClause<OMPScheduleClause>()) { ScheduleKind = C->getScheduleKind(); if (const auto *Ch = C->getChunkSize()) { if (auto *ImpRef = cast_or_null<DeclRefExpr>(C->getHelperChunkSize())) { @@ -1143,7 +1126,7 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) { ScheduleKind = ScheduleInfo.second; const unsigned IVSize = getContext().getTypeSize(IVExpr->getType()); const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation(); - const bool Ordered = S.getSingleClause(OMPC_ordered) != nullptr; + const bool Ordered = S.getSingleClause<OMPOrderedClause>() != nullptr; if (RT.isStaticNonchunked(ScheduleKind, /* Chunked */ Chunk != nullptr) && !Ordered) { @@ -1208,7 +1191,7 @@ void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) { CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen); // Emit an implicit barrier at the end. - if (!S.getSingleClause(OMPC_nowait) || HasLastprivates) { + if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates) { CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_for); } } @@ -1222,7 +1205,7 @@ void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &S) { CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen); // Emit an implicit barrier at the end. - if (!S.getSingleClause(OMPC_nowait) || HasLastprivates) { + if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates) { CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_for); } } @@ -1338,7 +1321,7 @@ CodeGenFunction::EmitSections(const OMPExecutableDirective &S) { // Emit barrier for lastprivates only if 'sections' directive has 'nowait' // clause. Otherwise the barrier will be generated by the codegen for the // directive. - if (HasLastprivates && S.getSingleClause(OMPC_nowait)) { + if (HasLastprivates && S.getSingleClause<OMPNowaitClause>()) { // Emit implicit barrier to synchronize threads and avoid data races on // initialization of firstprivate variables. CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), @@ -1351,11 +1334,11 @@ CodeGenFunction::EmitSections(const OMPExecutableDirective &S) { bool HasFirstprivates; // No need to generate reductions for sections with single section region, we // can use original shared variables for all operations. - bool HasReductions = !S.getClausesOfKind(OMPC_reduction).empty(); + bool HasReductions = S.hasClausesOfKind<OMPReductionClause>(); // No need to generate lastprivates for sections with single section region, // we can use original shared variable for all calculations with barrier at // the end of the sections. - bool HasLastprivates = !S.getClausesOfKind(OMPC_lastprivate).empty(); + bool HasLastprivates = S.hasClausesOfKind<OMPLastprivateClause>(); auto &&CodeGen = [Stmt, &S, &HasFirstprivates](CodeGenFunction &CGF) { CodeGenFunction::OMPPrivateScope SingleScope(CGF); HasFirstprivates = CGF.EmitOMPFirstprivateClause(S, SingleScope); @@ -1371,7 +1354,7 @@ CodeGenFunction::EmitSections(const OMPExecutableDirective &S) { // 'sections' directive has 'nowait' clause. Otherwise the barrier will be // generated by the codegen for the directive. if ((HasFirstprivates || HasLastprivates || HasReductions) && - S.getSingleClause(OMPC_nowait)) { + S.getSingleClause<OMPNowaitClause>()) { // Emit implicit barrier to synchronize threads and avoid data races on // initialization of firstprivate variables. CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_unknown); @@ -1383,7 +1366,7 @@ void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) { LexicalScope Scope(*this, S.getSourceRange()); OpenMPDirectiveKind EmittedAs = EmitSections(S); // Emit an implicit barrier at the end. - if (!S.getSingleClause(OMPC_nowait)) { + if (!S.getSingleClause<OMPNowaitClause>()) { CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), EmittedAs); } } @@ -1407,8 +1390,7 @@ void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) { // construct. // Build a list of copyprivate variables along with helper expressions // (<source>, <destination>, <destination>=<source> expressions) - for (auto &&I = S.getClausesOfKind(OMPC_copyprivate); I; ++I) { - auto *C = cast<OMPCopyprivateClause>(*I); + for (const auto *C : S.getClausesOfKind<OMPCopyprivateClause>()) { CopyprivateVars.append(C->varlists().begin(), C->varlists().end()); DestExprs.append(C->destination_exprs().begin(), C->destination_exprs().end()); @@ -1433,11 +1415,11 @@ void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) { AssignmentOps); // Emit an implicit barrier at the end (to avoid data race on firstprivate // init or if no 'nowait' clause was specified and no 'copyprivate' clause). - if ((!S.getSingleClause(OMPC_nowait) || HasFirstprivates) && + if ((!S.getSingleClause<OMPNowaitClause>() || HasFirstprivates) && CopyprivateVars.empty()) { CGM.getOpenMPRuntime().emitBarrierCall( *this, S.getLocStart(), - S.getSingleClause(OMPC_nowait) ? OMPD_unknown : OMPD_single); + S.getSingleClause<OMPNowaitClause>() ? OMPD_unknown : OMPD_single); } } @@ -1521,8 +1503,7 @@ void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) { // Get list of private variables. llvm::SmallVector<const Expr *, 8> PrivateVars; llvm::SmallVector<const Expr *, 8> PrivateCopies; - for (auto &&I = S.getClausesOfKind(OMPC_private); I; ++I) { - auto *C = cast<OMPPrivateClause>(*I); + for (const auto *C : S.getClausesOfKind<OMPPrivateClause>()) { auto IRef = C->varlist_begin(); for (auto *IInit : C->private_copies()) { auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); @@ -1538,8 +1519,7 @@ void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) { llvm::SmallVector<const Expr *, 8> FirstprivateVars; llvm::SmallVector<const Expr *, 8> FirstprivateCopies; llvm::SmallVector<const Expr *, 8> FirstprivateInits; - for (auto &&I = S.getClausesOfKind(OMPC_firstprivate); I; ++I) { - auto *C = cast<OMPFirstprivateClause>(*I); + for (const auto *C : S.getClausesOfKind<OMPFirstprivateClause>()) { auto IRef = C->varlist_begin(); auto IElemInitRef = C->inits().begin(); for (auto *IInit : C->private_copies()) { @@ -1555,8 +1535,7 @@ void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) { // Build list of dependences. llvm::SmallVector<std::pair<OpenMPDependClauseKind, const Expr *>, 8> Dependences; - for (auto &&I = S.getClausesOfKind(OMPC_depend); I; ++I) { - auto *C = cast<OMPDependClause>(*I); + for (const auto *C : S.getClausesOfKind<OMPDependClause>()) { for (auto *IRef : C->varlists()) { Dependences.push_back(std::make_pair(C->getDependencyKind(), IRef)); } @@ -1608,13 +1587,13 @@ void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) { auto OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction( S, *I, OMPD_task, CodeGen); // Check if we should emit tied or untied task. - bool Tied = !S.getSingleClause(OMPC_untied); + bool Tied = !S.getSingleClause<OMPUntiedClause>(); // Check if the task is final llvm::PointerIntPair<llvm::Value *, 1, bool> Final; - if (auto *Clause = S.getSingleClause(OMPC_final)) { + if (const auto *Clause = S.getSingleClause<OMPFinalClause>()) { // If the condition constant folds and can be elided, try to avoid emitting // the condition and the dead arm of the if/else. - auto *Cond = cast<OMPFinalClause>(Clause)->getCondition(); + auto *Cond = Clause->getCondition(); bool CondConstant; if (ConstantFoldsToSimpleInteger(Cond, CondConstant)) Final.setInt(CondConstant); @@ -1626,8 +1605,8 @@ void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) { } auto SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl()); const Expr *IfCond = nullptr; - if (auto C = S.getSingleClause(OMPC_if)) { - IfCond = cast<OMPIfClause>(C)->getCondition(); + if (const auto *C = S.getSingleClause<OMPIfClause>()) { + IfCond = C->getCondition(); } CGM.getOpenMPRuntime().emitTaskCall( *this, S.getLocStart(), S, Tied, Final, OutlinedFn, SharedsTy, @@ -1660,8 +1639,7 @@ void CodeGenFunction::EmitOMPTaskgroupDirective( void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &S) { CGM.getOpenMPRuntime().emitFlush(*this, [&]() -> ArrayRef<const Expr *> { - if (auto C = S.getSingleClause(/*K*/ OMPC_flush)) { - auto FlushClause = cast<OMPFlushClause>(C); + if (const auto *FlushClause = S.getSingleClause<OMPFlushClause>()) { return llvm::makeArrayRef(FlushClause->varlist_begin(), FlushClause->varlist_end()); } @@ -2084,7 +2062,7 @@ static void EmitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, } void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) { - bool IsSeqCst = S.getSingleClause(/*K=*/OMPC_seq_cst); + bool IsSeqCst = S.getSingleClause<OMPSeqCstClause>(); OpenMPClauseKind Kind = OMPC_unknown; for (auto *C : S.clauses()) { // Find first clause (skip seq_cst clause, if it is first). diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 6b092a80de99f13513cbafbc6613db12a95b325c..ea31260cc7a4de1bb06cb6e4364b1ac2d4a9994e 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -3514,24 +3514,18 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, } static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { - auto &&CollapseFilter = [](const OMPClause *C) -> bool { - return C->getClauseKind() == OMPC_collapse; - }; - OMPExecutableDirective::filtered_clause_iterator<decltype(CollapseFilter)> I( - Clauses, std::move(CollapseFilter)); - if (I) - return cast<OMPCollapseClause>(*I)->getNumForLoops(); + auto CollapseClauses = + OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); + if (CollapseClauses.begin() != CollapseClauses.end()) + return (*CollapseClauses.begin())->getNumForLoops(); return nullptr; } static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { - auto &&OrderedFilter = [](const OMPClause *C) -> bool { - return C->getClauseKind() == OMPC_ordered; - }; - OMPExecutableDirective::filtered_clause_iterator<decltype(OrderedFilter)> I( - Clauses, std::move(OrderedFilter)); - if (I) - return cast<OMPOrderedClause>(*I)->getNumForLoops(); + auto OrderedClauses = + OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); + if (OrderedClauses.begin() != OrderedClauses.end()) + return (*OrderedClauses.begin())->getNumForLoops(); return nullptr; }