Skip to content
4 changes: 2 additions & 2 deletions flang/examples/FeatureList/FeatureList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -473,8 +473,8 @@ struct NodeVisitor {
READ_FEATURE(OmpDependClause::InOut)
READ_FEATURE(OmpDependClause::Sink)
READ_FEATURE(OmpDependClause::Source)
READ_FEATURE(OmpDependenceType)
READ_FEATURE(OmpDependenceType::Type)
READ_FEATURE(OmpTaskDependenceType)
READ_FEATURE(OmpTaskDependenceType::Type)
READ_FEATURE(OmpDependSinkVec)
READ_FEATURE(OmpDependSinkVecLength)
READ_FEATURE(OmpEndAllocators)
Expand Down
4 changes: 2 additions & 2 deletions flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,9 @@ void OpenMPCounterVisitor::Post(const OmpLinearModifier::Type &c) {
clauseDetails +=
"modifier=" + std::string{OmpLinearModifier::EnumToString(c)} + ";";
}
void OpenMPCounterVisitor::Post(const OmpDependenceType::Type &c) {
void OpenMPCounterVisitor::Post(const OmpTaskDependenceType::Type &c) {
clauseDetails +=
"type=" + std::string{OmpDependenceType::EnumToString(c)} + ";";
"type=" + std::string{OmpTaskDependenceType::EnumToString(c)} + ";";
}
void OpenMPCounterVisitor::Post(const OmpMapClause::Type &c) {
clauseDetails += "type=" + std::string{OmpMapClause::EnumToString(c)} + ";";
Expand Down
2 changes: 1 addition & 1 deletion flang/examples/FlangOmpReport/FlangOmpReportVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ struct OpenMPCounterVisitor {
void Post(const OmpDeviceTypeClause::Type &c);
void Post(const OmpScheduleModifierType::ModType &c);
void Post(const OmpLinearModifier::Type &c);
void Post(const OmpDependenceType::Type &c);
void Post(const OmpTaskDependenceType::Type &c);
void Post(const OmpMapClause::Type &c);
void Post(const OmpScheduleClause::ScheduleType &c);
void Post(const OmpIfClause::DirectiveNameModifier &c);
Expand Down
4 changes: 2 additions & 2 deletions flang/include/flang/Parser/dump-parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -513,8 +513,8 @@ class ParseTreeDumper {
NODE(OmpDependClause, InOut)
NODE(OmpDependClause, Sink)
NODE(OmpDependClause, Source)
NODE(parser, OmpDependenceType)
NODE_ENUM(OmpDependenceType, Type)
NODE(parser, OmpTaskDependenceType)
NODE_ENUM(OmpTaskDependenceType, Type)
NODE(parser, OmpDependSinkVec)
NODE(parser, OmpDependSinkVecLength)
NODE(parser, OmpEndAllocators)
Expand Down
32 changes: 22 additions & 10 deletions flang/include/flang/Parser/parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -3439,6 +3439,18 @@ struct OmpObject {

WRAPPER_CLASS(OmpObjectList, std::list<OmpObject>);

// Ref: [4.5:169-170], [5.0:254-256], [5.1:287-289], [5.2:321]
//
// task-dependence-type -> // "dependence-type" in 5.1 and before
// IN | OUT | INOUT | // since 4.5
// SOURCE | SINK | // since 4.5, until 5.1
// MUTEXINOUTSET | DEPOBJ | // since 5.0
// INOUTSET // since 5.2
struct OmpTaskDependenceType {
ENUM_CLASS(Type, In, Out, Inout, Source, Sink)
WRAPPER_CLASS_BOILERPLATE(OmpTaskDependenceType, Type);
};

// [5.0] 2.1.6 iterator-specifier -> type-declaration-stmt = subscript-triple
// iterator-modifier -> iterator-specifier-list
struct OmpIteratorSpecifier {
Expand Down Expand Up @@ -3534,27 +3546,27 @@ struct OmpDependSinkVecLength {
std::tuple<DefinedOperator, ScalarIntConstantExpr> t;
};

// 2.13.9 depend-vec -> iterator [+/- depend-vec-length],...,iterator[...]
// 2.13.9 depend-vec -> induction-variable [depend-vec-length], ...
struct OmpDependSinkVec {
TUPLE_CLASS_BOILERPLATE(OmpDependSinkVec);
std::tuple<Name, std::optional<OmpDependSinkVecLength>> t;
};

// 2.13.9 depend-type -> IN | OUT | INOUT | SOURCE | SINK
struct OmpDependenceType {
ENUM_CLASS(Type, In, Out, Inout, Source, Sink)
WRAPPER_CLASS_BOILERPLATE(OmpDependenceType, Type);
};

// 2.13.9 depend-clause -> DEPEND (((IN | OUT | INOUT) : variable-name-list) |
// SOURCE | SINK : depend-vec)
// Ref: [4.5:169-170], [5.0:255-256], [5.1:288-289], [5.2:323-324]
//
// depend-clause ->
// DEPEND(SOURCE) | // since 4.5, until 5.1
// DEPEND(SINK: depend-vec) | // since 4.5, until 5.1
// DEPEND([depend-modifier,]dependence-type: locator-list) // since 4.5
//
// depend-modifier -> iterator-modifier // since 5.0
struct OmpDependClause {
UNION_CLASS_BOILERPLATE(OmpDependClause);
EMPTY_CLASS(Source);
WRAPPER_CLASS(Sink, std::list<OmpDependSinkVec>);
struct InOut {
TUPLE_CLASS_BOILERPLATE(InOut);
std::tuple<OmpDependenceType, std::list<Designator>> t;
std::tuple<OmpTaskDependenceType, OmpObjectList> t;
};
std::variant<Source, Sink, InOut> u;
};
Expand Down
10 changes: 5 additions & 5 deletions flang/lib/Lower/OpenMP/ClauseProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -798,11 +798,11 @@ bool ClauseProcessor::processDepend(mlir::omp::DependClauseOps &result) const {
return findRepeatableClause<omp::clause::Depend>(
[&](const omp::clause::Depend &clause, const parser::CharBlock &) {
using Depend = omp::clause::Depend;
assert(std::holds_alternative<Depend::WithLocators>(clause.u) &&
"Only the modern form is handled at the moment");
auto &modern = std::get<Depend::WithLocators>(clause.u);
auto kind = std::get<Depend::TaskDependenceType>(modern.t);
auto &objects = std::get<omp::ObjectList>(modern.t);
assert(std::holds_alternative<Depend::DepType>(clause.u) &&
"Only the form with depenence type is handled at the moment");
auto &depType = std::get<Depend::DepType>(clause.u);
auto kind = std::get<Depend::TaskDependenceType>(depType.t);
auto &objects = std::get<omp::ObjectList>(depType.t);

mlir::omp::ClauseTaskDependAttr dependTypeOperand =
genDependKindAttr(firOpBuilder, kind);
Expand Down
18 changes: 7 additions & 11 deletions flang/lib/Lower/OpenMP/Clauses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ Depend make(const parser::OmpClause::Depend &inp,
using Iteration = Doacross::Vector::value_type; // LoopIterationT

CLAUSET_ENUM_CONVERT( //
convert1, parser::OmpDependenceType::Type, Depend::TaskDependenceType,
convert1, parser::OmpTaskDependenceType::Type, Depend::TaskDependenceType,
// clang-format off
MS(In, In)
MS(Out, Out)
Expand Down Expand Up @@ -593,17 +593,13 @@ Depend make(const parser::OmpClause::Depend &inp,
return Doacross{{/*DependenceType=*/Doacross::DependenceType::Sink,
/*Vector=*/makeList(s.v, convert2)}};
},
// Depend::WithLocators
// Depend::DepType
[&](const wrapped::InOut &s) -> Variant {
auto &t0 = std::get<parser::OmpDependenceType>(s.t);
auto &t1 = std::get<std::list<parser::Designator>>(s.t);
auto convert4 = [&](const parser::Designator &t) {
return makeObject(t, semaCtx);
};
return Depend::WithLocators{
{/*TaskDependenceType=*/convert1(t0.v),
/*Iterator=*/std::nullopt,
/*LocatorList=*/makeList(t1, convert4)}};
auto &t0 = std::get<parser::OmpTaskDependenceType>(s.t);
auto &t1 = std::get<parser::OmpObjectList>(s.t);
return Depend::DepType{{/*TaskDependenceType=*/convert1(t0.v),
/*Iterator=*/std::nullopt,
/*LocatorList=*/makeObjects(t1, semaCtx)}};
},
},
inp.v.u)};
Expand Down
10 changes: 5 additions & 5 deletions flang/lib/Parser/openmp-parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,18 +365,18 @@ TYPE_PARSER(construct<OmpDependSinkVecLength>(
TYPE_PARSER(
construct<OmpDependSinkVec>(name, maybe(Parser<OmpDependSinkVecLength>{})))

TYPE_PARSER(
construct<OmpDependenceType>("IN"_id >> pure(OmpDependenceType::Type::In) ||
"INOUT" >> pure(OmpDependenceType::Type::Inout) ||
"OUT" >> pure(OmpDependenceType::Type::Out)))
TYPE_PARSER(construct<OmpTaskDependenceType>(
"IN"_id >> pure(OmpTaskDependenceType::Type::In) ||
"INOUT" >> pure(OmpTaskDependenceType::Type::Inout) ||
"OUT" >> pure(OmpTaskDependenceType::Type::Out)))

TYPE_CONTEXT_PARSER("Omp Depend clause"_en_US,
construct<OmpDependClause>(construct<OmpDependClause::Sink>(
"SINK :" >> nonemptyList(Parser<OmpDependSinkVec>{}))) ||
construct<OmpDependClause>(
construct<OmpDependClause::Source>("SOURCE"_tok)) ||
construct<OmpDependClause>(construct<OmpDependClause::InOut>(
Parser<OmpDependenceType>{}, ":" >> nonemptyList(designator))))
Parser<OmpTaskDependenceType>{}, ":" >> Parser<OmpObjectList>{})))

// 2.15.3.7 LINEAR (linear-list: linear-step)
// linear-list -> list | modifier(list)
Expand Down
6 changes: 3 additions & 3 deletions flang/lib/Parser/unparse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2206,9 +2206,9 @@ class UnparseVisitor {
}
void Unparse(const OmpDependClause::InOut &x) {
Put("(");
Walk(std::get<OmpDependenceType>(x.t));
Walk(std::get<OmpTaskDependenceType>(x.t));
Put(":");
Walk(std::get<std::list<Designator>>(x.t), ",");
Walk(std::get<OmpObjectList>(x.t));
Put(")");
}
bool Pre(const OmpDependClause &x) {
Expand Down Expand Up @@ -2816,7 +2816,7 @@ class UnparseVisitor {
OmpLastprivateClause, LastprivateModifier) // OMP lastprivate-modifier
WALK_NESTED_ENUM(OmpScheduleModifierType, ModType) // OMP schedule-modifier
WALK_NESTED_ENUM(OmpLinearModifier, Type) // OMP linear-modifier
WALK_NESTED_ENUM(OmpDependenceType, Type) // OMP dependence-type
WALK_NESTED_ENUM(OmpTaskDependenceType, Type) // OMP task-dependence-type
WALK_NESTED_ENUM(OmpScheduleClause, ScheduleType) // OMP schedule-type
WALK_NESTED_ENUM(OmpDeviceClause, DeviceModifier) // OMP device modifier
WALK_NESTED_ENUM(OmpDeviceTypeClause, Type) // OMP DEVICE_TYPE
Expand Down
48 changes: 30 additions & 18 deletions flang/lib/Semantics/check-omp-structure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ namespace Fortran::semantics {
CheckAllowedClause(llvm::omp::Y); \
}

std::string ThisVersion(unsigned version) {
std::string tv{
std::to_string(version / 10) + "." + std::to_string(version % 10)};
return "OpenMP v" + tv;
}

std::string TryVersion(unsigned version) {
return "try -fopenmp-version=" + std::to_string(version);
}

// 'OmpWorkshareBlockChecker' is used to check the validity of the assignment
// statements and the expressions enclosed in an OpenMP Workshare construct
class OmpWorkshareBlockChecker {
Expand Down Expand Up @@ -200,14 +210,10 @@ bool OmpStructureChecker::CheckAllowedClause(llvmOmpClause clause) {
auto clauseName{parser::ToUpperCaseLetters(getClauseName(clause).str())};
auto dirName{parser::ToUpperCaseLetters(getDirectiveName(dir).str())};

std::string thisVersion{
std::to_string(version / 10) + "." + std::to_string(version % 10)};
std::string goodVersion{std::to_string(allowedInVersion)};

context_.Say(dirCtx.clauseSource,
"%s clause is not allowed on directive %s in OpenMP v%s, "
"try -fopenmp-version=%d"_err_en_US,
clauseName, dirName, thisVersion, allowedInVersion);
"%s clause is not allowed on directive %s in %s, %s"_err_en_US,
clauseName, dirName, ThisVersion(version),
TryVersion(allowedInVersion));
}
}
return CheckAllowed(clause);
Expand Down Expand Up @@ -3283,15 +3289,21 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Depend &x) {
parser::ToUpperCaseLetters(getDirectiveName(GetContext().directive)));
}
if (const auto *inOut{std::get_if<parser::OmpDependClause::InOut>(&x.v.u)}) {
const auto &designators{std::get<std::list<parser::Designator>>(inOut->t)};
for (const auto &ele : designators) {
if (const auto *dataRef{std::get_if<parser::DataRef>(&ele.u)}) {
CheckDependList(*dataRef);
if (const auto *arr{
std::get_if<common::Indirection<parser::ArrayElement>>(
&dataRef->u)}) {
CheckArraySection(arr->value(), GetLastName(*dataRef),
llvm::omp::Clause::OMPC_depend);
for (const auto &object : std::get<parser::OmpObjectList>(inOut->t).v) {
if (const auto *name{std::get_if<parser::Name>(&object.u)}) {
context_.Say(GetContext().clauseSource,
"Common block name ('%s') cannot appear in a DEPEND "
"clause"_err_en_US,
name->ToString());
} else if (auto *designator{std::get_if<parser::Designator>(&object.u)}) {
if (auto *dataRef{std::get_if<parser::DataRef>(&designator->u)}) {
CheckDependList(*dataRef);
if (const auto *arr{
std::get_if<common::Indirection<parser::ArrayElement>>(
&dataRef->u)}) {
CheckArraySection(arr->value(), GetLastName(*dataRef),
llvm::omp::Clause::OMPC_depend);
}
}
}
}
Expand Down Expand Up @@ -3367,8 +3379,8 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Lastprivate &x) {
std::to_string(version / 10) + "." + std::to_string(version % 10)};
context_.Say(GetContext().clauseSource,
"LASTPRIVATE clause with CONDITIONAL modifier is not "
"allowed in OpenMP v%s, try -fopenmp-version=%d"_err_en_US,
thisVersion, allowedInVersion);
"allowed in %s, %s"_err_en_US,
ThisVersion(version), TryVersion(allowedInVersion));
}
}
}
Expand Down
27 changes: 17 additions & 10 deletions flang/lib/Semantics/resolve-directives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,20 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
bool Pre(const parser::OpenMPAllocatorsConstruct &);
void Post(const parser::OpenMPAllocatorsConstruct &);

void Post(const parser::OmpObjectList &x) {
// The objects from OMP clauses should have already been resolved,
// except common blocks (the ResolveNamesVisitor does not visit
// parser::Name, those are dealt with as members of other structures).
// Iterate over elements of x, and resolve any common blocks that
// are still unresolved.
for (const parser::OmpObject &obj : x.v) {
auto *name{std::get_if<parser::Name>(&obj.u)};
if (name && !name->symbol) {
Resolve(*name, currScope().MakeCommonBlock(name->source));
}
}
}

// 2.15.3 Data-Sharing Attribute Clauses
void Post(const parser::OmpDefaultClause &);
bool Pre(const parser::OmpClause::Shared &x) {
Expand Down Expand Up @@ -531,16 +545,9 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
return false;
}

bool Pre(const parser::OmpDependClause &x) {
if (const auto *dependSink{
std::get_if<parser::OmpDependClause::Sink>(&x.u)}) {
const auto &dependSinkVec{dependSink->v};
for (const auto &dependSinkElement : dependSinkVec) {
const auto &name{std::get<parser::Name>(dependSinkElement.t)};
ResolveName(&name);
}
}
return false;
void Post(const parser::OmpDependSinkVec &x) {
const auto &name{std::get<parser::Name>(x.t)};
ResolveName(&name);
}

bool Pre(const parser::OmpClause::UseDevicePtr &x) {
Expand Down
10 changes: 10 additions & 0 deletions flang/test/Semantics/OpenMP/depend04.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=50

subroutine f00
integer :: x
common /cc/ x
!ERROR: Common block name ('cc') cannot appear in a DEPEND clause
!$omp task depend(in: /cc/)
x = 0
!$omp end task
end
4 changes: 2 additions & 2 deletions llvm/include/llvm/Frontend/OpenMP/ClauseT.h
Original file line number Diff line number Diff line change
Expand Up @@ -503,15 +503,15 @@ struct DependT {
using LocatorList = ObjectListT<I, E>;
using TaskDependenceType = tomp::type::TaskDependenceType;

struct WithLocators { // Modern form
struct DepType { // The form with task dependence type.
using TupleTrait = std::true_type;
// Empty LocatorList means "omp_all_memory".
std::tuple<TaskDependenceType, OPT(Iterator), LocatorList> t;
};

using Doacross = DoacrossT<T, I, E>;
using UnionTrait = std::true_type;
std::variant<Doacross, WithLocators> u; // Doacross form is legacy
std::variant<Doacross, DepType> u; // Doacross form is legacy
};

// V5.2: [3.5] `destroy` clause
Expand Down
Loading