diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2019-10-07 18:54:57 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2019-10-07 18:54:57 +0000 |
commit | f8c3d1a886ce2dffb92f17863b576a5f4b08f6f9 (patch) | |
tree | 9e5605124f5478bad11d647e19fb0f68f679ac14 /lib/Sema/SemaOpenMP.cpp | |
parent | b886fe4cb63a677a7ac7a75ee5d2282247b99301 (diff) | |
download | clang-f8c3d1a886ce2dffb92f17863b576a5f4b08f6f9.tar.gz |
[OPENMP50]Treat range-based for as canonical loop.
According to OpenMP 5.0, range-based for is also considered as a
canonical form of loops.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@373939 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOpenMP.cpp')
-rw-r--r-- | lib/Sema/SemaOpenMP.cpp | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 7ec5ba335f..b0fd6aa5fd 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -2008,6 +2008,14 @@ void Sema::startOpenMPLoop() { DSAStack->loopInit(); } +void Sema::startOpenMPCXXRangeFor() { + assert(LangOpts.OpenMP && "OpenMP must be enabled."); + if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { + DSAStack->resetPossibleLoopCounter(); + DSAStack->loopStart(); + } +} + bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { assert(LangOpts.OpenMP && "OpenMP is not allowed"); if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { @@ -6490,10 +6498,13 @@ static bool checkOpenMPIterationSpace( Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { - // OpenMP [2.6, Canonical Loop Form] + // OpenMP [2.9.1, Canonical Loop Form] // for (init-expr; test-expr; incr-expr) structured-block + // for (range-decl: range-expr) structured-block auto *For = dyn_cast_or_null<ForStmt>(S); - if (!For) { + auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); + // Ranged for is supported only in OpenMP 5.0. + if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount @@ -6515,12 +6526,14 @@ static bool checkOpenMPIterationSpace( } return true; } - assert(For->getBody()); + assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && + "No loop body."); - OpenMPIterationSpaceChecker ISC(SemaRef, DSA, For->getForLoc()); + OpenMPIterationSpaceChecker ISC(SemaRef, DSA, + For ? For->getForLoc() : CXXFor->getForLoc()); // Check init. - Stmt *Init = For->getInit(); + Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); if (ISC.checkAndSetInit(Init)) return true; @@ -6556,18 +6569,18 @@ static bool checkOpenMPIterationSpace( assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); // Check test-expr. - HasErrors |= ISC.checkAndSetCond(For->getCond()); + HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); // Check incr-expr. - HasErrors |= ISC.checkAndSetInc(For->getInc()); + HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); } if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) return HasErrors; // Build the loop's iteration space representation. - ResultIterSpaces[CurrentNestedLoopCount].PreCond = - ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures); + ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( + DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); ResultIterSpaces[CurrentNestedLoopCount].NumIterations = ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, (isOpenMPWorksharingDirective(DKind) || @@ -6881,7 +6894,14 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, // All loops associated with the construct must be perfectly nested; that // is, there must be no intervening code nor any OpenMP directive between // any two loops. - CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); + if (auto *For = dyn_cast<ForStmt>(CurStmt)) { + CurStmt = For->getBody(); + } else { + assert(isa<CXXForRangeStmt>(CurStmt) && + "Expected canonical for or range-based for loops."); + CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); + } + CurStmt = CurStmt->IgnoreContainers(); } for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { if (checkOpenMPIterationSpace( @@ -6901,7 +6921,14 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, // All loops associated with the construct must be perfectly nested; that // is, there must be no intervening code nor any OpenMP directive between // any two loops. - CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); + if (auto *For = dyn_cast<ForStmt>(CurStmt)) { + CurStmt = For->getBody(); + } else { + assert(isa<CXXForRangeStmt>(CurStmt) && + "Expected canonical for or range-based for loops."); + CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); + } + CurStmt = CurStmt->IgnoreContainers(); } Built.clear(/* size */ NestedLoopCount); |