diff --git a/flang/include/flang/Parser/openmp-utils.h b/flang/include/flang/Parser/openmp-utils.h index 8fa4a84aff06d..36556f8dd7f4a 100644 --- a/flang/include/flang/Parser/openmp-utils.h +++ b/flang/include/flang/Parser/openmp-utils.h @@ -137,6 +137,8 @@ const T *GetFirstArgument(const OmpDirectiveSpecification &spec) { const BlockConstruct *GetFortranBlockConstruct( const ExecutionPartConstruct &epc); +const Block &GetInnermostExecPart(const Block &block); +bool IsStrictlyStructuredBlock(const Block &block); const OmpCombinerExpression *GetCombinerExpr( const OmpReductionSpecifier &rspec); diff --git a/flang/include/flang/Semantics/openmp-utils.h b/flang/include/flang/Semantics/openmp-utils.h index 14a4f0e93bda5..f5739ab16d643 100644 --- a/flang/include/flang/Semantics/openmp-utils.h +++ b/flang/include/flang/Semantics/openmp-utils.h @@ -97,8 +97,6 @@ const SomeExpr *HasStorageOverlap( const SomeExpr &base, llvm::ArrayRef exprs); bool IsAssignment(const parser::ActionStmt *x); bool IsPointerAssignment(const evaluate::Assignment &x); -const parser::Block &GetInnermostExecPart(const parser::Block &block); -bool IsStrictlyStructuredBlock(const parser::Block &block); } // namespace omp } // namespace Fortran::semantics diff --git a/flang/lib/Parser/openmp-utils.cpp b/flang/lib/Parser/openmp-utils.cpp index b9d3763cdd06d..2424828293c73 100644 --- a/flang/lib/Parser/openmp-utils.cpp +++ b/flang/lib/Parser/openmp-utils.cpp @@ -93,6 +93,34 @@ const BlockConstruct *GetFortranBlockConstruct( return nullptr; } +/// parser::Block is a list of executable constructs, parser::BlockConstruct +/// is Fortran's BLOCK/ENDBLOCK construct. +/// Strip the outermost BlockConstructs, return the reference to the Block +/// in the executable part of the innermost of the stripped constructs. +/// Specifically, if the given `block` has a single entry (it's a list), and +/// the entry is a BlockConstruct, get the Block contained within. Repeat +/// this step as many times as possible. +const Block &GetInnermostExecPart(const Block &block) { + const Block *iter{&block}; + while (iter->size() == 1) { + const ExecutionPartConstruct &ep{iter->front()}; + if (auto *bc{GetFortranBlockConstruct(ep)}) { + iter = &std::get(bc->t); + } else { + break; + } + } + return *iter; +} + +bool IsStrictlyStructuredBlock(const Block &block) { + if (block.size() == 1) { + return GetFortranBlockConstruct(block.front()) != nullptr; + } else { + return false; + } +} + const OmpCombinerExpression *GetCombinerExpr( const OmpReductionSpecifier &rspec) { return addr_if(std::get>(rspec.t)); diff --git a/flang/lib/Semantics/check-omp-atomic.cpp b/flang/lib/Semantics/check-omp-atomic.cpp index ec03e6fe2d920..b9e34ca6e74df 100644 --- a/flang/lib/Semantics/check-omp-atomic.cpp +++ b/flang/lib/Semantics/check-omp-atomic.cpp @@ -19,6 +19,7 @@ #include "flang/Evaluate/rewrite.h" #include "flang/Evaluate/tools.h" #include "flang/Parser/char-block.h" +#include "flang/Parser/openmp-utils.h" #include "flang/Parser/parse-tree.h" #include "flang/Semantics/openmp-utils.h" #include "flang/Semantics/symbol.h" @@ -41,6 +42,7 @@ namespace Fortran::semantics { +using namespace Fortran::parser::omp; using namespace Fortran::semantics::omp; namespace operation = Fortran::evaluate::operation; diff --git a/flang/lib/Semantics/openmp-utils.cpp b/flang/lib/Semantics/openmp-utils.cpp index 4a40d6eec17bb..18a37d64a3b5a 100644 --- a/flang/lib/Semantics/openmp-utils.cpp +++ b/flang/lib/Semantics/openmp-utils.cpp @@ -496,32 +496,4 @@ bool IsPointerAssignment(const evaluate::Assignment &x) { return std::holds_alternative(x.u) || std::holds_alternative(x.u); } - -/// parser::Block is a list of executable constructs, parser::BlockConstruct -/// is Fortran's BLOCK/ENDBLOCK construct. -/// Strip the outermost BlockConstructs, return the reference to the Block -/// in the executable part of the innermost of the stripped constructs. -/// Specifically, if the given `block` has a single entry (it's a list), and -/// the entry is a BlockConstruct, get the Block contained within. Repeat -/// this step as many times as possible. -const parser::Block &GetInnermostExecPart(const parser::Block &block) { - const parser::Block *iter{&block}; - while (iter->size() == 1) { - const parser::ExecutionPartConstruct &ep{iter->front()}; - if (auto *bc{GetFortranBlockConstruct(ep)}) { - iter = &std::get(bc->t); - } else { - break; - } - } - return *iter; -} - -bool IsStrictlyStructuredBlock(const parser::Block &block) { - if (block.size() == 1) { - return GetFortranBlockConstruct(block.front()) != nullptr; - } else { - return false; - } -} } // namespace Fortran::semantics::omp