Skip to content

Commit bde79c0

Browse files
authored
[flang][OpenMP] Use new modifiers in DEPEND/GRAINSIZE/NUM_TASKS (#117917)
The usual changes, added more references to OpenMP specs.
1 parent eaa4eb2 commit bde79c0

File tree

15 files changed

+145
-81
lines changed

15 files changed

+145
-81
lines changed

flang/examples/FeatureList/FeatureList.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,9 @@ struct NodeVisitor {
488488
READ_FEATURE(OmpEndLoopDirective)
489489
READ_FEATURE(OmpEndSectionsDirective)
490490
READ_FEATURE(OmpGrainsizeClause)
491-
READ_FEATURE(OmpGrainsizeClause::Prescriptiveness)
491+
READ_FEATURE(OmpGrainsizeClause::Modifier)
492+
READ_FEATURE(OmpPrescriptiveness)
493+
READ_FEATURE(OmpPrescriptiveness::Value)
492494
READ_FEATURE(OmpIfClause)
493495
READ_FEATURE(OmpIfClause::DirectiveNameModifier)
494496
READ_FEATURE(OmpLinearClause)
@@ -500,7 +502,7 @@ struct NodeVisitor {
500502
READ_FEATURE(OmpMapClause)
501503
READ_FEATURE(OmpMapClause::Modifier)
502504
READ_FEATURE(OmpNumTasksClause)
503-
READ_FEATURE(OmpNumTasksClause::Prescriptiveness)
505+
READ_FEATURE(OmpNumTasksClause::Modifier)
504506
READ_FEATURE(OmpObject)
505507
READ_FEATURE(OmpObjectList)
506508
READ_FEATURE(OmpOrderClause)

flang/include/flang/Parser/dump-parse-tree.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,7 @@ class ParseTreeDumper {
536536
NODE(OmpDoacross, Source)
537537
NODE(parser, OmpDependClause)
538538
NODE(OmpDependClause, TaskDep)
539+
NODE(OmpDependClause::TaskDep, Modifier)
539540
NODE(parser, OmpDetachClause)
540541
NODE(parser, OmpDoacrossClause)
541542
NODE(parser, OmpDestroyClause)
@@ -574,9 +575,11 @@ class ParseTreeDumper {
574575
NODE(parser, OmpOrderModifier)
575576
NODE_ENUM(OmpOrderModifier, Value)
576577
NODE(parser, OmpGrainsizeClause)
577-
NODE_ENUM(OmpGrainsizeClause, Prescriptiveness)
578+
NODE(OmpGrainsizeClause, Modifier)
579+
NODE(parser, OmpPrescriptiveness)
580+
NODE_ENUM(OmpPrescriptiveness, Value)
578581
NODE(parser, OmpNumTasksClause)
579-
NODE_ENUM(OmpNumTasksClause, Prescriptiveness)
582+
NODE(OmpNumTasksClause, Modifier)
580583
NODE(parser, OmpBindClause)
581584
NODE_ENUM(OmpBindClause, Binding)
582585
NODE(parser, OmpProcBindClause)

flang/include/flang/Parser/parse-tree.h

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3642,6 +3642,15 @@ struct OmpOrderModifier {
36423642
WRAPPER_CLASS_BOILERPLATE(OmpOrderModifier, Value);
36433643
};
36443644

3645+
// Ref: [5.1:166-171], [5.2:269-270]
3646+
//
3647+
// prescriptiveness ->
3648+
// STRICT // since 5.1
3649+
struct OmpPrescriptiveness {
3650+
ENUM_CLASS(Value, Strict)
3651+
WRAPPER_CLASS_BOILERPLATE(OmpPrescriptiveness, Value);
3652+
};
3653+
36453654
// Ref: [4.5:201-207], [5.0:293-299], [5.1:325-331], [5.2:124]
36463655
//
36473656
// reduction-identifier ->
@@ -3831,8 +3840,8 @@ struct OmpDependClause {
38313840
struct TaskDep {
38323841
OmpTaskDependenceType::Value GetTaskDepType() const;
38333842
TUPLE_CLASS_BOILERPLATE(TaskDep);
3834-
std::tuple<std::optional<OmpIterator>, OmpTaskDependenceType, OmpObjectList>
3835-
t;
3843+
MODIFIER_BOILERPLATE(OmpIterator, OmpTaskDependenceType);
3844+
std::tuple<MODIFIERS(), OmpObjectList> t;
38363845
};
38373846
std::variant<TaskDep, OmpDoacross> u;
38383847
};
@@ -3893,11 +3902,15 @@ struct OmpFromClause {
38933902
std::tuple<MODIFIERS(), OmpObjectList, bool> t;
38943903
};
38953904

3896-
// OMP 5.2 12.6.1 grainsize-clause -> grainsize ([prescriptiveness :] value)
3905+
// Ref: [4.5:87-91], [5.0:140-146], [5.1:166-171], [5.2:269]
3906+
//
3907+
// grainsize-clause ->
3908+
// GRAINSIZE(grain-size) | // since 4.5
3909+
// GRAINSIZE([prescriptiveness:] grain-size) // since 5.1
38973910
struct OmpGrainsizeClause {
38983911
TUPLE_CLASS_BOILERPLATE(OmpGrainsizeClause);
3899-
ENUM_CLASS(Prescriptiveness, Strict);
3900-
std::tuple<std::optional<Prescriptiveness>, ScalarIntExpr> t;
3912+
MODIFIER_BOILERPLATE(OmpPrescriptiveness);
3913+
std::tuple<MODIFIERS(), ScalarIntExpr> t;
39013914
};
39023915

39033916
// 2.12 if-clause -> IF ([ directive-name-modifier :] scalar-logical-expr)
@@ -3963,6 +3976,17 @@ struct OmpMapClause {
39633976
std::tuple<MODIFIERS(), OmpObjectList, bool> t;
39643977
};
39653978

3979+
// Ref: [4.5:87-91], [5.0:140-146], [5.1:166-171], [5.2:270]
3980+
//
3981+
// num-tasks-clause ->
3982+
// NUM_TASKS(num-tasks) | // since 4.5
3983+
// NUM_TASKS([prescriptiveness:] num-tasks) // since 5.1
3984+
struct OmpNumTasksClause {
3985+
TUPLE_CLASS_BOILERPLATE(OmpNumTasksClause);
3986+
MODIFIER_BOILERPLATE(OmpPrescriptiveness);
3987+
std::tuple<MODIFIERS(), ScalarIntExpr> t;
3988+
};
3989+
39663990
// Ref: [5.0:101-109], [5.1:126-134], [5.2:233-234]
39673991
//
39683992
// order-clause ->
@@ -4030,13 +4054,6 @@ struct OmpToClause {
40304054
std::tuple<MODIFIERS(), OmpObjectList, bool> t;
40314055
};
40324056

4033-
// OMP 5.2 12.6.2 num_tasks-clause -> num_tasks ([prescriptiveness :] value)
4034-
struct OmpNumTasksClause {
4035-
TUPLE_CLASS_BOILERPLATE(OmpNumTasksClause);
4036-
ENUM_CLASS(Prescriptiveness, Strict);
4037-
std::tuple<std::optional<Prescriptiveness>, ScalarIntExpr> t;
4038-
};
4039-
40404057
// Ref: [5.0:254-255], [5.1:287-288], [5.2:321-322]
40414058
//
40424059
// update-clause ->
@@ -4045,6 +4062,7 @@ struct OmpNumTasksClause {
40454062
// UPDATE(task-dependence-type) // since 5.2
40464063
struct OmpUpdateClause {
40474064
UNION_CLASS_BOILERPLATE(OmpUpdateClause);
4065+
// The dependence type is an argument here, not a modifier.
40484066
std::variant<OmpDependenceType, OmpTaskDependenceType> u;
40494067
};
40504068

flang/include/flang/Semantics/openmp-modifiers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ DECLARE_DESCRIPTOR(parser::OmpMapType);
8282
DECLARE_DESCRIPTOR(parser::OmpMapTypeModifier);
8383
DECLARE_DESCRIPTOR(parser::OmpOrderModifier);
8484
DECLARE_DESCRIPTOR(parser::OmpOrderingModifier);
85+
DECLARE_DESCRIPTOR(parser::OmpPrescriptiveness);
8586
DECLARE_DESCRIPTOR(parser::OmpReductionIdentifier);
8687
DECLARE_DESCRIPTOR(parser::OmpReductionModifier);
8788
DECLARE_DESCRIPTOR(parser::OmpTaskDependenceType);

flang/lib/Lower/OpenMP/Clauses.cpp

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,15 @@ clause::DependenceType makeDepType(const parser::OmpTaskDependenceType &inp) {
369369
llvm_unreachable("Unexpected task dependence type");
370370
}
371371

372+
clause::Prescriptiveness
373+
makePrescriptiveness(parser::OmpPrescriptiveness::Value v) {
374+
switch (v) {
375+
case parser::OmpPrescriptiveness::Value::Strict:
376+
return clause::Prescriptiveness::Strict;
377+
}
378+
llvm_unreachable("Unexpected prescriptiveness");
379+
}
380+
372381
// --------------------------------------------------------------------
373382
// Actual clauses. Each T (where tomp::T exists in ClauseT) has its "make".
374383

@@ -615,15 +624,18 @@ Depend make(const parser::OmpClause::Depend &inp,
615624
using Variant = decltype(Depend::u);
616625

617626
auto visitTaskDep = [&](const wrapped::TaskDep &s) -> Variant {
618-
auto &t0 = std::get<std::optional<parser::OmpIterator>>(s.t);
619-
auto &t1 = std::get<parser::OmpTaskDependenceType>(s.t);
620-
auto &t2 = std::get<parser::OmpObjectList>(s.t);
627+
auto &mods = semantics::OmpGetModifiers(s);
628+
auto *m0 = semantics::OmpGetUniqueModifier<parser::OmpIterator>(mods);
629+
auto *m1 =
630+
semantics::OmpGetUniqueModifier<parser::OmpTaskDependenceType>(mods);
631+
auto &t1 = std::get<parser::OmpObjectList>(s.t);
632+
assert(m1 && "expecting task dependence type");
621633

622634
auto &&maybeIter =
623-
maybeApply([&](auto &&s) { return makeIterator(s, semaCtx); }, t0);
624-
return Depend::TaskDep{{/*DependenceType=*/makeDepType(t1),
635+
m0 ? makeIterator(*m0, semaCtx) : std::optional<Iterator>{};
636+
return Depend::TaskDep{{/*DependenceType=*/makeDepType(*m1),
625637
/*Iterator=*/std::move(maybeIter),
626-
/*LocatorList=*/makeObjects(t2, semaCtx)}};
638+
/*LocatorList=*/makeObjects(t1, semaCtx)}};
627639
};
628640

629641
return Depend{common::visit( //
@@ -785,19 +797,12 @@ From make(const parser::OmpClause::From &inp,
785797
Grainsize make(const parser::OmpClause::Grainsize &inp,
786798
semantics::SemanticsContext &semaCtx) {
787799
// inp.v -> parser::OmpGrainsizeClause
788-
using wrapped = parser::OmpGrainsizeClause;
789-
790-
CLAUSET_ENUM_CONVERT( //
791-
convert, parser::OmpGrainsizeClause::Prescriptiveness,
792-
Grainsize::Prescriptiveness,
793-
// clang-format off
794-
MS(Strict, Strict)
795-
// clang-format on
796-
);
797-
auto &t0 = std::get<std::optional<wrapped::Prescriptiveness>>(inp.v.t);
800+
auto &mods = semantics::OmpGetModifiers(inp.v);
801+
auto *m0 = semantics::OmpGetUniqueModifier<parser::OmpPrescriptiveness>(mods);
798802
auto &t1 = std::get<parser::ScalarIntExpr>(inp.v.t);
799-
return Grainsize{{/*Prescriptiveness=*/maybeApply(convert, t0),
800-
/*Grainsize=*/makeExpr(t1, semaCtx)}};
803+
return Grainsize{
804+
{/*Prescriptiveness=*/maybeApplyToV(makePrescriptiveness, m0),
805+
/*Grainsize=*/makeExpr(t1, semaCtx)}};
801806
}
802807

803808
HasDeviceAddr make(const parser::OmpClause::HasDeviceAddr &inp,
@@ -1047,18 +1052,10 @@ Novariants make(const parser::OmpClause::Novariants &inp,
10471052
NumTasks make(const parser::OmpClause::NumTasks &inp,
10481053
semantics::SemanticsContext &semaCtx) {
10491054
// inp.v -> parser::OmpNumTasksClause
1050-
using wrapped = parser::OmpNumTasksClause;
1051-
1052-
CLAUSET_ENUM_CONVERT( //
1053-
convert, parser::OmpNumTasksClause::Prescriptiveness,
1054-
NumTasks::Prescriptiveness,
1055-
// clang-format off
1056-
MS(Strict, Strict)
1057-
// clang-format on
1058-
);
1059-
auto &t0 = std::get<std::optional<wrapped::Prescriptiveness>>(inp.v.t);
1055+
auto &mods = semantics::OmpGetModifiers(inp.v);
1056+
auto *m0 = semantics::OmpGetUniqueModifier<parser::OmpPrescriptiveness>(mods);
10601057
auto &t1 = std::get<parser::ScalarIntExpr>(inp.v.t);
1061-
return NumTasks{{/*Prescriptiveness=*/maybeApply(convert, t0),
1058+
return NumTasks{{/*Prescriptiveness=*/maybeApplyToV(makePrescriptiveness, m0),
10621059
/*NumTasks=*/makeExpr(t1, semaCtx)}};
10631060
}
10641061

flang/lib/Lower/OpenMP/Clauses.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ using DefinedOperator = tomp::type::DefinedOperatorT<IdTy, ExprTy>;
176176
using ProcedureDesignator = tomp::type::ProcedureDesignatorT<IdTy, ExprTy>;
177177
using ReductionOperator = tomp::type::ReductionIdentifierT<IdTy, ExprTy>;
178178
using DependenceType = tomp::type::DependenceType;
179+
using Prescriptiveness = tomp::type::Prescriptiveness;
179180

180181
// "Requires" clauses are handled early on, and the aggregated information
181182
// is stored in the Symbol details of modules, programs, and subprograms.

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ TYPE_PARSER(construct<OmpOrderingModifier>(
176176
"NONMONOTONIC" >> pure(OmpOrderingModifier::Value::Nonmonotonic) ||
177177
"SIMD" >> pure(OmpOrderingModifier::Value::Simd)))
178178

179+
TYPE_PARSER(construct<OmpPrescriptiveness>(
180+
"STRICT" >> pure(OmpPrescriptiveness::Value::Strict)))
181+
179182
TYPE_PARSER(construct<OmpReductionModifier>(
180183
"INSCAN" >> pure(OmpReductionModifier::Value::Inscan) ||
181184
"TASK" >> pure(OmpReductionModifier::Value::Task) ||
@@ -213,6 +216,11 @@ TYPE_PARSER(sourced(construct<OmpAllocateClause::Modifier>(sourced(
213216
TYPE_PARSER(sourced(
214217
construct<OmpDefaultmapClause::Modifier>(Parser<OmpVariableCategory>{})))
215218

219+
TYPE_PARSER(sourced(construct<OmpDependClause::TaskDep::Modifier>(sourced(
220+
construct<OmpDependClause::TaskDep::Modifier>(Parser<OmpIterator>{}) ||
221+
construct<OmpDependClause::TaskDep::Modifier>(
222+
Parser<OmpTaskDependenceType>{})))))
223+
216224
TYPE_PARSER(
217225
sourced(construct<OmpDeviceClause::Modifier>(Parser<OmpDeviceModifier>{})))
218226

@@ -221,6 +229,9 @@ TYPE_PARSER(sourced(construct<OmpFromClause::Modifier>(
221229
construct<OmpFromClause::Modifier>(Parser<OmpMapper>{}) ||
222230
construct<OmpFromClause::Modifier>(Parser<OmpIterator>{})))))
223231

232+
TYPE_PARSER(sourced(
233+
construct<OmpGrainsizeClause::Modifier>(Parser<OmpPrescriptiveness>{})))
234+
224235
TYPE_PARSER(sourced(construct<OmpMapClause::Modifier>(
225236
sourced(construct<OmpMapClause::Modifier>(Parser<OmpMapTypeModifier>{}) ||
226237
construct<OmpMapClause::Modifier>(Parser<OmpMapper>{}) ||
@@ -230,6 +241,9 @@ TYPE_PARSER(sourced(construct<OmpMapClause::Modifier>(
230241
TYPE_PARSER(
231242
sourced(construct<OmpOrderClause::Modifier>(Parser<OmpOrderModifier>{})))
232243

244+
TYPE_PARSER(sourced(
245+
construct<OmpNumTasksClause::Modifier>(Parser<OmpPrescriptiveness>{})))
246+
233247
TYPE_PARSER(sourced(construct<OmpReductionClause::Modifier>(sourced(
234248
construct<OmpReductionClause::Modifier>(Parser<OmpReductionModifier>{}) ||
235249
construct<OmpReductionClause::Modifier>(
@@ -382,10 +396,16 @@ TYPE_PARSER(construct<OmpDoacross>(
382396

383397
TYPE_CONTEXT_PARSER("Omp Depend clause"_en_US,
384398
construct<OmpDependClause>(
399+
// Try to parse OmpDoacross first, because TaskDep will succeed on
400+
// "sink: xxx", interpreting it to not have any modifiers, and "sink"
401+
// being an OmpObject. Parsing of the TaskDep variant will stop right
402+
// after the "sink", leaving the ": xxx" unvisited.
403+
construct<OmpDependClause>(Parser<OmpDoacross>{}) ||
404+
// Parse TaskDep after Doacross.
385405
construct<OmpDependClause>(construct<OmpDependClause::TaskDep>(
386-
maybe(Parser<OmpIterator>{} / ","_tok),
387-
Parser<OmpTaskDependenceType>{} / ":", Parser<OmpObjectList>{})) ||
388-
construct<OmpDependClause>(Parser<OmpDoacross>{})))
406+
maybe(nonemptyList(Parser<OmpDependClause::TaskDep::Modifier>{}) /
407+
": "),
408+
Parser<OmpObjectList>{}))))
389409

390410
TYPE_CONTEXT_PARSER("Omp Doacross clause"_en_US,
391411
construct<OmpDoacrossClause>(Parser<OmpDoacross>{}))
@@ -427,12 +447,12 @@ TYPE_PARSER(construct<OmpOrderClause>(
427447

428448
// OMP 5.2 12.6.1 grainsize([ prescriptiveness :] scalar-integer-expression)
429449
TYPE_PARSER(construct<OmpGrainsizeClause>(
430-
maybe("STRICT" >> pure(OmpGrainsizeClause::Prescriptiveness::Strict) / ":"),
450+
maybe(nonemptyList(Parser<OmpGrainsizeClause::Modifier>{}) / ":"),
431451
scalarIntExpr))
432452

433453
// OMP 5.2 12.6.2 num_tasks([ prescriptiveness :] scalar-integer-expression)
434454
TYPE_PARSER(construct<OmpNumTasksClause>(
435-
maybe("STRICT" >> pure(OmpNumTasksClause::Prescriptiveness::Strict) / ":"),
455+
maybe(nonemptyList(Parser<OmpNumTasksClause::Modifier>{}) / ":"),
436456
scalarIntExpr))
437457

438458
TYPE_PARSER(

flang/lib/Parser/parse-tree.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,18 @@ OmpDependenceType::Value OmpDoacross::GetDepType() const {
267267
}
268268

269269
OmpTaskDependenceType::Value OmpDependClause::TaskDep::GetTaskDepType() const {
270-
return std::get<parser::OmpTaskDependenceType>(t).v;
270+
using Modifier = OmpDependClause::TaskDep::Modifier;
271+
auto &modifiers{std::get<std::optional<std::list<Modifier>>>(t)};
272+
if (modifiers) {
273+
for (auto &m : *modifiers) {
274+
if (auto *dep{std::get_if<OmpTaskDependenceType>(&m.u)}) {
275+
return dep->v;
276+
}
277+
}
278+
llvm_unreachable("expecting OmpTaskDependenceType in TaskDep");
279+
} else {
280+
llvm_unreachable("expecting modifiers on OmpDependClause::TaskDep");
281+
}
271282
}
272283

273284
} // namespace Fortran::parser

flang/lib/Parser/unparse.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2171,13 +2171,13 @@ class UnparseVisitor {
21712171
Walk(std::get<OmpOrderClause::Ordering>(x.t));
21722172
}
21732173
void Unparse(const OmpGrainsizeClause &x) {
2174-
Walk(std::get<std::optional<OmpGrainsizeClause::Prescriptiveness>>(x.t),
2175-
":");
2174+
using Modifier = OmpGrainsizeClause::Modifier;
2175+
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
21762176
Walk(std::get<ScalarIntExpr>(x.t));
21772177
}
21782178
void Unparse(const OmpNumTasksClause &x) {
2179-
Walk(
2180-
std::get<std::optional<OmpNumTasksClause::Prescriptiveness>>(x.t), ":");
2179+
using Modifier = OmpNumTasksClause::Modifier;
2180+
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
21812181
Walk(std::get<ScalarIntExpr>(x.t));
21822182
}
21832183
void Unparse(const OmpDoacross::Sink &x) {
@@ -2186,8 +2186,8 @@ class UnparseVisitor {
21862186
}
21872187
void Unparse(const OmpDoacross::Source &) { Word("SOURCE"); }
21882188
void Unparse(const OmpDependClause::TaskDep &x) {
2189-
Walk(std::get<OmpTaskDependenceType>(x.t));
2190-
Put(":");
2189+
using Modifier = OmpDependClause::TaskDep::Modifier;
2190+
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
21912191
Walk(std::get<OmpObjectList>(x.t));
21922192
}
21932193
void Unparse(const OmpDefaultmapClause &x) {
@@ -2853,9 +2853,7 @@ class UnparseVisitor {
28532853
WALK_NESTED_ENUM(OmpCancelType, Type) // OMP cancel-type
28542854
WALK_NESTED_ENUM(OmpOrderClause, Ordering) // OMP ordering
28552855
WALK_NESTED_ENUM(OmpOrderModifier, Value) // OMP order-modifier
2856-
WALK_NESTED_ENUM(
2857-
OmpGrainsizeClause, Prescriptiveness) // OMP grainsize-modifier
2858-
WALK_NESTED_ENUM(OmpNumTasksClause, Prescriptiveness) // OMP numtasks-modifier
2856+
WALK_NESTED_ENUM(OmpPrescriptiveness, Value) // OMP prescriptiveness
28592857
WALK_NESTED_ENUM(OmpMapType, Value) // OMP map-type
28602858
WALK_NESTED_ENUM(OmpMapTypeModifier, Value) // OMP map-type-modifier
28612859
#undef WALK_NESTED_ENUM

flang/lib/Semantics/check-omp-structure.cpp

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3725,18 +3725,13 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Depend &x) {
37253725
}
37263726
}
37273727
}
3728-
if (std::get<std::optional<parser::OmpIterator>>(taskDep->t)) {
3729-
unsigned allowedInVersion{50};
3730-
if (version < allowedInVersion) {
3731-
context_.Say(GetContext().clauseSource,
3732-
"Iterator modifiers are not supported in %s, %s"_warn_en_US,
3733-
ThisVersion(version), TryVersion(allowedInVersion));
3734-
} else {
3728+
if (OmpVerifyModifiers(*taskDep, llvm::omp::OMPC_depend,
3729+
GetContext().clauseSource, context_)) {
3730+
auto &modifiers{OmpGetModifiers(*taskDep)};
3731+
if (OmpGetUniqueModifier<parser::OmpIterator>(modifiers)) {
37353732
if (dir == llvm::omp::OMPD_depobj) {
37363733
context_.Say(GetContext().clauseSource,
3737-
"An iterator-modifier may specify multiple locators, "
3738-
"a DEPEND clause on a DEPOBJ construct must only specify "
3739-
"one locator"_warn_en_US);
3734+
"An iterator-modifier may specify multiple locators, a DEPEND clause on a DEPOBJ construct must only specify one locator"_warn_en_US);
37403735
}
37413736
}
37423737
}

0 commit comments

Comments
 (0)