[flang][OpenMP] Normalize clause modifiers that exist on their own (#116655)

This is the first part of the effort to make parsing of clause modifiers
more uniform and robust. Currently, when multiple modifiers are allowed,
the parser will expect them to appear in a hard-coded order.
Additionally, modifier properties (such as "ultimate") are checked
separately for each case.

The overall plan is
1. Extract all modifiers into their own top-level classes, and then
equip them with sets of common properties that will allow performing the
property checks generically, without refering to the specific kind of
the modifier.
2. Define a parser (as a separate class) for each modifier.
3. For each clause define a union (std::variant) of all allowable
modifiers, and parse the modifiers as a list of these unions.

The intent is also to isolate parts of the code that could eventually be
auto-generated.

OpenMP modifier overhaul: #1/3
This commit is contained in:
Krzysztof Parzyszek 2024-11-20 08:33:17 -06:00 committed by GitHub
parent b49c4af186
commit cfd67c2149
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 198 additions and 169 deletions

View File

@ -475,9 +475,9 @@ public:
READ_FEATURE(OmpDoacross::Source)
READ_FEATURE(OmpDoacrossClause)
READ_FEATURE(OmpDependenceType)
READ_FEATURE(OmpDependenceType::Type)
READ_FEATURE(OmpDependenceType::Value)
READ_FEATURE(OmpTaskDependenceType)
READ_FEATURE(OmpTaskDependenceType::Type)
READ_FEATURE(OmpTaskDependenceType::Value)
READ_FEATURE(OmpIteration)
READ_FEATURE(OmpIterationOffset)
READ_FEATURE(OmpIterationVector)
@ -495,7 +495,7 @@ public:
READ_FEATURE(OmpLinearClause::WithModifier)
READ_FEATURE(OmpLinearClause::WithoutModifier)
READ_FEATURE(OmpLinearModifier)
READ_FEATURE(OmpLinearModifier::Type)
READ_FEATURE(OmpLinearModifier::Value)
READ_FEATURE(OmpLoopDirective)
READ_FEATURE(OmpMapClause)
READ_FEATURE(OmpMapClause::TypeModifier)
@ -515,7 +515,7 @@ public:
READ_FEATURE(OmpReductionCombiner)
READ_FEATURE(OmpReductionCombiner::FunctionCombiner)
READ_FEATURE(OmpReductionInitializerClause)
READ_FEATURE(OmpReductionOperator)
READ_FEATURE(OmpReductionIdentifier)
READ_FEATURE(OmpAllocateClause)
READ_FEATURE(OmpAllocateClause::AllocateModifier)
READ_FEATURE(OmpAllocateClause::AllocateModifier::Allocator)

View File

@ -218,11 +218,11 @@ void OpenMPCounterVisitor::Post(const OmpScheduleModifierType::ModType &c) {
clauseDetails +=
"modifier=" + std::string{OmpScheduleModifierType::EnumToString(c)} + ";";
}
void OpenMPCounterVisitor::Post(const OmpLinearModifier::Type &c) {
void OpenMPCounterVisitor::Post(const OmpLinearModifier::Value &c) {
clauseDetails +=
"modifier=" + std::string{OmpLinearModifier::EnumToString(c)} + ";";
}
void OpenMPCounterVisitor::Post(const OmpTaskDependenceType::Type &c) {
void OpenMPCounterVisitor::Post(const OmpTaskDependenceType::Value &c) {
clauseDetails +=
"type=" + std::string{OmpTaskDependenceType::EnumToString(c)} + ";";
}

View File

@ -72,8 +72,8 @@ struct OpenMPCounterVisitor {
void Post(const OmpDefaultmapClause::VariableCategory &c);
void Post(const OmpDeviceTypeClause::Type &c);
void Post(const OmpScheduleModifierType::ModType &c);
void Post(const OmpLinearModifier::Type &c);
void Post(const OmpTaskDependenceType::Type &c);
void Post(const OmpLinearModifier::Value &c);
void Post(const OmpTaskDependenceType::Value &c);
void Post(const OmpMapClause::Type &c);
void Post(const OmpScheduleClause::ScheduleType &c);
void Post(const OmpIfClause::DirectiveNameModifier &c);

View File

@ -477,7 +477,7 @@ public:
NODE(parser, ObjectDecl)
NODE(parser, OldParameterStmt)
NODE(parser, OmpIteratorSpecifier)
NODE(parser, OmpIteratorModifier)
NODE(parser, OmpIterator)
NODE(parser, OmpAffinityClause)
NODE(parser, OmpAlignedClause)
NODE(parser, OmpAtomic)
@ -513,9 +513,9 @@ public:
NODE_ENUM(OmpDefaultmapClause, ImplicitBehavior)
NODE_ENUM(OmpDefaultmapClause, VariableCategory)
NODE(parser, OmpDependenceType)
NODE_ENUM(OmpDependenceType, Type)
NODE_ENUM(OmpDependenceType, Value)
NODE(parser, OmpTaskDependenceType)
NODE_ENUM(OmpTaskDependenceType, Type)
NODE_ENUM(OmpTaskDependenceType, Value)
NODE(parser, OmpIterationOffset)
NODE(parser, OmpIteration)
NODE(parser, OmpIterationVector)
@ -543,7 +543,7 @@ public:
NODE(OmpLinearClause, WithModifier)
NODE(OmpLinearClause, WithoutModifier)
NODE(parser, OmpLinearModifier)
NODE_ENUM(OmpLinearModifier, Type)
NODE_ENUM(OmpLinearModifier, Value)
NODE(parser, OmpLoopDirective)
NODE(parser, OmpMapClause)
NODE(parser, OmpMapperIdentifier)
@ -574,7 +574,7 @@ public:
NODE(parser, OmpReductionCombiner)
NODE(OmpReductionCombiner, FunctionCombiner)
NODE(parser, OmpReductionInitializerClause)
NODE(parser, OmpReductionOperator)
NODE(parser, OmpReductionIdentifier)
NODE(parser, OmpAllocateClause)
NODE(OmpAllocateClause, AllocateModifier)
NODE(OmpAllocateClause::AllocateModifier, Allocator)

View File

@ -3440,13 +3440,33 @@ struct OmpObject {
WRAPPER_CLASS(OmpObjectList, std::list<OmpObject>);
inline namespace modifier {
// For uniformity, in all keyword modifiers the name of the type defined
// by ENUM_CLASS is "Value", e.g.
// struct Foo {
// ENUM_CLASS(Value, Keyword1, Keyword2);
// };
// Ref: [5.0:47-49], [5.1:49-51], [5.2:67-69]
//
// iterator-specifier ->
// [iterator-type] iterator-identifier
// = range-specification | // since 5.0
// [iterator-type ::] iterator-identifier
// = range-specification // since 5.2
struct OmpIteratorSpecifier {
TUPLE_CLASS_BOILERPLATE(OmpIteratorSpecifier);
CharBlock source;
std::tuple<TypeDeclarationStmt, SubscriptTriplet> t;
};
// Ref: [4.5:169-170], [5.0:255-256], [5.1:288-289]
//
// dependence-type ->
// SINK | SOURCE | // since 4.5
// IN | OUT | INOUT | // since 4.5, until 5.1
// MUTEXINOUTSET | DEPOBJ | // since 5.0, until 5.1
// INOUTSET // since 5.1, until 5.1
// SINK | SOURCE | // since 4.5
// IN | OUT | INOUT | // since 4.5, until 5.1
// MUTEXINOUTSET | DEPOBJ | // since 5.0, until 5.1
// INOUTSET // since 5.1, until 5.1
//
// All of these, except SINK and SOURCE became task-dependence-type in 5.2.
//
@ -3457,37 +3477,51 @@ WRAPPER_CLASS(OmpObjectList, std::list<OmpObject>);
// vector). This would accept the vector "i, j, k" (although interpreted
// incorrectly), while flagging a syntax error for "i+1, j, k".
struct OmpDependenceType {
ENUM_CLASS(Type, Sink, Source);
WRAPPER_CLASS_BOILERPLATE(OmpDependenceType, Type);
ENUM_CLASS(Value, Sink, Source);
WRAPPER_CLASS_BOILERPLATE(OmpDependenceType, Value);
};
// Ref: [5.0:47-49], [5.1:49-51], [5.2:67-69]
//
// iterator-modifier ->
// ITERATOR(iterator-specifier [, ...]) // since 5.0
struct OmpIterator {
WRAPPER_CLASS_BOILERPLATE(OmpIterator, std::list<OmpIteratorSpecifier>);
};
// Ref: [4.5:207-210], [5.0:290-293], [5.1:323-325], [5.2:117-120]
//
// linear-modifier ->
// REF | UVAL | VAL // since 4.5
struct OmpLinearModifier {
ENUM_CLASS(Value, Ref, Uval, Val);
WRAPPER_CLASS_BOILERPLATE(OmpLinearModifier, Value);
};
// Ref: [4.5:201-207], [5.0:293-299], [5.1:325-331], [5.2:124]
//
// reduction-identifier ->
// base-language-identifier | // since 4.5
// - | // since 4.5, until 5.2
// + | * | .AND. | .OR. | .EQV. | .NEQV. | // since 4.5
// MIN | MAX | IAND | IOR | IEOR // since 4.5
//
struct OmpReductionIdentifier {
UNION_CLASS_BOILERPLATE(OmpReductionIdentifier);
std::variant<DefinedOperator, ProcedureDesignator> u;
};
// 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
// MUTEXINOUTSET | DEPOBJ | // since 5.0
// INOUTSET // since 5.2
// IN | OUT | INOUT | // since 4.5
// MUTEXINOUTSET | DEPOBJ | // since 5.0
// INOUTSET // since 5.2
struct OmpTaskDependenceType {
ENUM_CLASS(Type, In, Out, Inout, Inoutset, Mutexinoutset, Depobj)
WRAPPER_CLASS_BOILERPLATE(OmpTaskDependenceType, Type);
};
// [5.0] 2.1.6 iterator-specifier -> type-declaration-stmt = subscript-triple
// iterator-modifier -> iterator-specifier-list
struct OmpIteratorSpecifier {
TUPLE_CLASS_BOILERPLATE(OmpIteratorSpecifier);
CharBlock source;
std::tuple<TypeDeclarationStmt, SubscriptTriplet> t;
};
WRAPPER_CLASS(OmpIteratorModifier, std::list<OmpIteratorSpecifier>);
// 2.15.3.6 reduction-identifier -> + | - | * | .AND. | .OR. | .EQV. | .NEQV. |
// MAX | MIN | IAND | IOR | IEOR
struct OmpReductionOperator {
UNION_CLASS_BOILERPLATE(OmpReductionOperator);
std::variant<DefinedOperator, ProcedureDesignator> u;
ENUM_CLASS(Value, In, Out, Inout, Inoutset, Mutexinoutset, Depobj)
WRAPPER_CLASS_BOILERPLATE(OmpTaskDependenceType, Value);
};
} // namespace modifier
// --- Clauses
@ -3495,7 +3529,7 @@ struct OmpReductionOperator {
// aff-modifier: interator-modifier
struct OmpAffinityClause {
TUPLE_CLASS_BOILERPLATE(OmpAffinityClause);
std::tuple<std::optional<OmpIteratorModifier>, OmpObjectList> t;
std::tuple<std::optional<OmpIterator>, OmpObjectList> t;
};
// 2.8.1 aligned-clause -> ALIGNED (variable-name-list[ : scalar-constant])
@ -3566,7 +3600,7 @@ WRAPPER_CLASS(OmpIterationVector, std::list<OmpIteration>);
// OmpDoacrossClause), so that the context in TYPE_CONTEXT_PARSER can be set
// separately for OmpDependClause and OmpDoacrossClause.
struct OmpDoacross {
OmpDependenceType::Type GetDepType() const;
OmpDependenceType::Value GetDepType() const;
WRAPPER_CLASS(Sink, OmpIterationVector);
EMPTY_CLASS(Source);
@ -3586,10 +3620,9 @@ struct OmpDoacross {
struct OmpDependClause {
UNION_CLASS_BOILERPLATE(OmpDependClause);
struct TaskDep {
OmpTaskDependenceType::Type GetTaskDepType() const;
OmpTaskDependenceType::Value GetTaskDepType() const;
TUPLE_CLASS_BOILERPLATE(TaskDep);
std::tuple<std::optional<OmpIteratorModifier>, OmpTaskDependenceType,
OmpObjectList>
std::tuple<std::optional<OmpIterator>, OmpTaskDependenceType, OmpObjectList>
t;
};
std::variant<TaskDep, OmpDoacross> u;
@ -3632,7 +3665,7 @@ struct OmpFromClause {
// As in the case of MAP, modifiers are parsed as lists, even if they
// are unique. These restrictions will be checked in semantic checks.
std::tuple<std::optional<std::list<Expectation>>,
std::optional<std::list<OmpIteratorModifier>>, OmpObjectList,
std::optional<std::list<OmpIterator>>, OmpObjectList,
bool> // were the modifiers comma-separated?
t;
};
@ -3661,7 +3694,7 @@ struct OmpDetachClause {
// variable-name-list)
struct OmpInReductionClause {
TUPLE_CLASS_BOILERPLATE(OmpInReductionClause);
std::tuple<OmpReductionOperator, OmpObjectList> t;
std::tuple<OmpReductionIdentifier, OmpObjectList> t;
};
// OMP 5.0 2.19.4.5 lastprivate-clause ->
@ -3673,12 +3706,6 @@ struct OmpLastprivateClause {
std::tuple<std::optional<LastprivateModifier>, OmpObjectList> t;
};
// 2.15.3.7 linear-modifier -> REF | VAL | UVAL
struct OmpLinearModifier {
ENUM_CLASS(Type, Ref, Val, Uval)
WRAPPER_CLASS_BOILERPLATE(OmpLinearModifier, Type);
};
// 2.15.3.7 linear-clause -> LINEAR (linear-list[ : linear-step])
// linear-list -> list | linear-modifier(list)
struct OmpLinearClause {
@ -3723,7 +3750,7 @@ struct OmpMapClause {
// information about separator presence to emit a diagnostic if needed.
std::tuple<OmpMapperIdentifier, // Mapper name
std::optional<std::list<TypeModifier>>,
std::optional<std::list<OmpIteratorModifier>>, // unique
std::optional<std::list<OmpIterator>>, // unique
std::optional<std::list<Type>>, // unique
OmpObjectList,
bool> // were the modifiers comma-separated?
@ -3753,7 +3780,7 @@ struct OmpProcBindClause {
struct OmpReductionClause {
TUPLE_CLASS_BOILERPLATE(OmpReductionClause);
ENUM_CLASS(ReductionModifier, Inscan, Task, Default)
std::tuple<std::optional<ReductionModifier>, OmpReductionOperator,
std::tuple<std::optional<ReductionModifier>, OmpReductionIdentifier,
OmpObjectList>
t;
};
@ -3798,7 +3825,7 @@ struct OmpToClause {
// As in the case of MAP, modifiers are parsed as lists, even if they
// are unique. These restrictions will be checked in semantic checks.
std::tuple<std::optional<std::list<Expectation>>,
std::optional<std::list<OmpIteratorModifier>>, OmpObjectList,
std::optional<std::list<OmpIterator>>, OmpObjectList,
bool> // were the modifiers comma-separated?
t;
};
@ -3946,7 +3973,7 @@ WRAPPER_CLASS(OmpReductionInitializerClause, Expr);
struct OpenMPDeclareReductionConstruct {
TUPLE_CLASS_BOILERPLATE(OpenMPDeclareReductionConstruct);
CharBlock source;
std::tuple<Verbatim, OmpReductionOperator, std::list<DeclarationTypeSpec>,
std::tuple<Verbatim, OmpReductionIdentifier, std::list<DeclarationTypeSpec>,
OmpReductionCombiner, std::optional<OmpReductionInitializerClause>>
t;
};

View File

@ -265,7 +265,7 @@ makeIteratorSpecifiers(const parser::OmpIteratorSpecifier &inp,
return specifiers;
}
Iterator makeIterator(const parser::OmpIteratorModifier &inp,
Iterator makeIterator(const parser::OmpIterator &inp,
semantics::SemanticsContext &semaCtx) {
Iterator iterator;
for (auto &&spec : inp.v)
@ -325,8 +325,9 @@ makeProcedureDesignator(const parser::ProcedureDesignator &inp,
inp.u)};
}
ReductionOperator makeReductionOperator(const parser::OmpReductionOperator &inp,
semantics::SemanticsContext &semaCtx) {
ReductionOperator
makeReductionOperator(const parser::OmpReductionIdentifier &inp,
semantics::SemanticsContext &semaCtx) {
return Fortran::common::visit(
common::visitors{
[&](const parser::DefinedOperator &s) {
@ -341,9 +342,9 @@ ReductionOperator makeReductionOperator(const parser::OmpReductionOperator &inp,
clause::DependenceType makeDepType(const parser::OmpDependenceType &inp) {
switch (inp.v) {
case parser::OmpDependenceType::Type::Sink:
case parser::OmpDependenceType::Value::Sink:
return clause::DependenceType::Sink;
case parser::OmpDependenceType::Type::Source:
case parser::OmpDependenceType::Value::Source:
return clause::DependenceType::Source;
}
llvm_unreachable("Unexpected dependence type");
@ -351,17 +352,17 @@ clause::DependenceType makeDepType(const parser::OmpDependenceType &inp) {
clause::DependenceType makeDepType(const parser::OmpTaskDependenceType &inp) {
switch (inp.v) {
case parser::OmpTaskDependenceType::Type::Depobj:
case parser::OmpTaskDependenceType::Value::Depobj:
return clause::DependenceType::Depobj;
case parser::OmpTaskDependenceType::Type::In:
case parser::OmpTaskDependenceType::Value::In:
return clause::DependenceType::In;
case parser::OmpTaskDependenceType::Type::Inout:
case parser::OmpTaskDependenceType::Value::Inout:
return clause::DependenceType::Inout;
case parser::OmpTaskDependenceType::Type::Inoutset:
case parser::OmpTaskDependenceType::Value::Inoutset:
return clause::DependenceType::Inoutset;
case parser::OmpTaskDependenceType::Type::Mutexinoutset:
case parser::OmpTaskDependenceType::Value::Mutexinoutset:
return clause::DependenceType::Mutexinoutset;
case parser::OmpTaskDependenceType::Type::Out:
case parser::OmpTaskDependenceType::Value::Out:
return clause::DependenceType::Out;
}
llvm_unreachable("Unexpected task dependence type");
@ -382,7 +383,7 @@ Absent make(const parser::OmpClause::Absent &inp,
Affinity make(const parser::OmpClause::Affinity &inp,
semantics::SemanticsContext &semaCtx) {
// inp.v -> parser::OmpAffinityClause
auto &t0 = std::get<std::optional<parser::OmpIteratorModifier>>(inp.v.t);
auto &t0 = std::get<std::optional<parser::OmpIterator>>(inp.v.t);
auto &t1 = std::get<parser::OmpObjectList>(inp.v.t);
auto &&maybeIter =
@ -627,7 +628,7 @@ Depend make(const parser::OmpClause::Depend &inp,
using Variant = decltype(Depend::u);
auto visitTaskDep = [&](const wrapped::TaskDep &s) -> Variant {
auto &t0 = std::get<std::optional<parser::OmpIteratorModifier>>(s.t);
auto &t0 = std::get<std::optional<parser::OmpIterator>>(s.t);
auto &t1 = std::get<parser::OmpTaskDependenceType>(s.t);
auto &t2 = std::get<parser::OmpObjectList>(s.t);
@ -770,8 +771,7 @@ From make(const parser::OmpClause::From &inp,
);
auto &t0 = std::get<std::optional<std::list<wrapped::Expectation>>>(inp.v.t);
auto &t1 =
std::get<std::optional<std::list<parser::OmpIteratorModifier>>>(inp.v.t);
auto &t1 = std::get<std::optional<std::list<parser::OmpIterator>>>(inp.v.t);
auto &t2 = std::get<parser::OmpObjectList>(inp.v.t);
assert((!t0 || t0->size() == 1) && "Only one expectation modifier allowed");
@ -882,7 +882,7 @@ Init make(const parser::OmpClause::Init &inp,
InReduction make(const parser::OmpClause::InReduction &inp,
semantics::SemanticsContext &semaCtx) {
// inp.v -> parser::OmpInReductionClause
auto &t0 = std::get<parser::OmpReductionOperator>(inp.v.t);
auto &t0 = std::get<parser::OmpReductionIdentifier>(inp.v.t);
auto &t1 = std::get<parser::OmpObjectList>(inp.v.t);
return InReduction{
{/*ReductionIdentifiers=*/{makeReductionOperator(t0, semaCtx)},
@ -921,7 +921,7 @@ Linear make(const parser::OmpClause::Linear &inp,
using wrapped = parser::OmpLinearClause;
CLAUSET_ENUM_CONVERT( //
convert, parser::OmpLinearModifier::Type, Linear::LinearModifier,
convert, parser::OmpLinearModifier::Value, Linear::LinearModifier,
// clang-format off
MS(Ref, Ref)
MS(Val, Val)
@ -985,8 +985,7 @@ Map make(const parser::OmpClause::Map &inp,
);
auto &t0 = std::get<std::optional<std::list<wrapped::TypeModifier>>>(inp.v.t);
auto &t1 =
std::get<std::optional<std::list<parser::OmpIteratorModifier>>>(inp.v.t);
auto &t1 = std::get<std::optional<std::list<parser::OmpIterator>>>(inp.v.t);
auto &t2 = std::get<std::optional<std::list<wrapped::Type>>>(inp.v.t);
auto &t3 = std::get<parser::OmpObjectList>(inp.v.t);
auto &t4 = std::get<parser::OmpMapperIdentifier>(inp.v.t);
@ -1193,7 +1192,7 @@ Reduction make(const parser::OmpClause::Reduction &inp,
auto &t0 =
std::get<std::optional<parser::OmpReductionClause::ReductionModifier>>(
inp.v.t);
auto &t1 = std::get<parser::OmpReductionOperator>(inp.v.t);
auto &t1 = std::get<parser::OmpReductionIdentifier>(inp.v.t);
auto &t2 = std::get<parser::OmpObjectList>(inp.v.t);
return Reduction{
{/*ReductionModifier=*/t0
@ -1320,7 +1319,7 @@ Permutation make(const parser::OmpClause::Permutation &inp,
TaskReduction make(const parser::OmpClause::TaskReduction &inp,
semantics::SemanticsContext &semaCtx) {
// inp.v -> parser::OmpReductionClause
auto &t0 = std::get<parser::OmpReductionOperator>(inp.v.t);
auto &t0 = std::get<parser::OmpReductionIdentifier>(inp.v.t);
auto &t1 = std::get<parser::OmpObjectList>(inp.v.t);
return TaskReduction{
{/*ReductionIdentifiers=*/{makeReductionOperator(t0, semaCtx)},
@ -1349,8 +1348,7 @@ To make(const parser::OmpClause::To &inp,
);
auto &t0 = std::get<std::optional<std::list<wrapped::Expectation>>>(inp.v.t);
auto &t1 =
std::get<std::optional<std::list<parser::OmpIteratorModifier>>>(inp.v.t);
auto &t1 = std::get<std::optional<std::list<parser::OmpIterator>>>(inp.v.t);
auto &t2 = std::get<parser::OmpObjectList>(inp.v.t);
assert((!t0 || t0->size() == 1) && "Only one expectation modifier allowed");

View File

@ -97,7 +97,7 @@ template <typename Separator> struct MapModifiers {
// Parsing of mappers is not supported yet.
using TypeModParser = Parser<OmpMapClause::TypeModifier>;
using IterParser = Parser<OmpIteratorModifier>;
using IterParser = Parser<OmpIterator>;
using TypeParser = Parser<OmpMapClause::Type>;
using ModParser =
ConcatSeparated<Separator, TypeModParser, IterParser, TypeParser>;
@ -132,7 +132,7 @@ template <typename Separator> struct MotionModifiers {
constexpr MotionModifiers(MotionModifiers &&) = default;
using ExpParser = Parser<OmpFromClause::Expectation>;
using IterParser = Parser<OmpIteratorModifier>;
using IterParser = Parser<OmpIterator>;
using ModParser = ConcatSeparated<Separator, ExpParser, IterParser>;
using resultType = typename ModParser::resultType;
@ -190,6 +190,8 @@ static TypeDeclarationStmt makeIterSpecDecl(std::list<ObjectName> &&names) {
makeEntityList(std::move(names)));
}
// --- Parsers for clause modifiers -----------------------------------
TYPE_PARSER(construct<OmpIteratorSpecifier>(
// Using Parser<TypeDeclarationStmt> or Parser<EntityDecl> has the problem
// that they will attempt to treat what follows the '=' as initialization.
@ -206,14 +208,40 @@ TYPE_PARSER(construct<OmpIteratorSpecifier>(
makeIterSpecDecl, nonemptyList(Parser<ObjectName>{}) / "="_tok)),
subscriptTriplet))
TYPE_PARSER(construct<OmpDependenceType>(
"SINK" >> pure(OmpDependenceType::Value::Sink) ||
"SOURCE" >> pure(OmpDependenceType::Value::Source)))
// [5.0] 2.1.6 iterator -> iterator-specifier-list
TYPE_PARSER(construct<OmpIteratorModifier>("ITERATOR" >>
TYPE_PARSER(construct<OmpIterator>("ITERATOR" >>
parenthesized(nonemptyList(sourced(Parser<OmpIteratorSpecifier>{})))))
// 2.15.3.7 LINEAR (linear-list: linear-step)
// linear-list -> list | modifier(list)
// linear-modifier -> REF | VAL | UVAL
TYPE_PARSER(construct<OmpLinearModifier>( //
"REF" >> pure(OmpLinearModifier::Value::Ref) ||
"VAL" >> pure(OmpLinearModifier::Value::Val) ||
"UVAL" >> pure(OmpLinearModifier::Value::Uval)))
// 2.15.3.6 REDUCTION (reduction-identifier: variable-name-list)
TYPE_PARSER(construct<OmpReductionIdentifier>(Parser<DefinedOperator>{}) ||
construct<OmpReductionIdentifier>(Parser<ProcedureDesignator>{}))
TYPE_PARSER(construct<OmpTaskDependenceType>(
"DEPOBJ" >> pure(OmpTaskDependenceType::Value::Depobj) ||
"IN"_id >> pure(OmpTaskDependenceType::Value::In) ||
"INOUT"_id >> pure(OmpTaskDependenceType::Value::Inout) ||
"INOUTSET"_id >> pure(OmpTaskDependenceType::Value::Inoutset) ||
"MUTEXINOUTSET" >> pure(OmpTaskDependenceType::Value::Mutexinoutset) ||
"OUT" >> pure(OmpTaskDependenceType::Value::Out)))
// --- Parsers for clauses --------------------------------------------
// [5.0] 2.10.1 affinity([aff-modifier:] locator-list)
// aff-modifier: interator-modifier
TYPE_PARSER(construct<OmpAffinityClause>(
maybe(Parser<OmpIteratorModifier>{} / ":"), Parser<OmpObjectList>{}))
maybe(Parser<OmpIterator>{} / ":"), Parser<OmpObjectList>{}))
// 2.15.3.1 DEFAULT (PRIVATE | FIRSTPRIVATE | SHARED | NONE)
TYPE_PARSER(construct<OmpDefaultClause>(
@ -251,7 +279,7 @@ TYPE_PARSER(
template <bool CommasEverywhere>
static inline OmpMapClause makeMapClause(OmpMapperIdentifier &&mm,
std::tuple<std::optional<std::list<OmpMapClause::TypeModifier>>,
std::optional<std::list<OmpIteratorModifier>>,
std::optional<std::list<OmpIterator>>,
std::optional<std::list<OmpMapClause::Type>>> &&mods,
OmpObjectList &&objs) {
auto &&[tm, it, ty] = std::move(mods);
@ -350,21 +378,17 @@ TYPE_PARSER(construct<OmpIfClause>(
":"),
scalarLogicalExpr))
// 2.15.3.6 REDUCTION (reduction-identifier: variable-name-list)
TYPE_PARSER(construct<OmpReductionOperator>(Parser<DefinedOperator>{}) ||
construct<OmpReductionOperator>(Parser<ProcedureDesignator>{}))
TYPE_PARSER(construct<OmpReductionClause>(
maybe(
("INSCAN" >> pure(OmpReductionClause::ReductionModifier::Inscan) ||
"TASK" >> pure(OmpReductionClause::ReductionModifier::Task) ||
"DEFAULT" >> pure(OmpReductionClause::ReductionModifier::Default)) /
","),
Parser<OmpReductionOperator>{} / ":", Parser<OmpObjectList>{}))
Parser<OmpReductionIdentifier>{} / ":", Parser<OmpObjectList>{}))
// OMP 5.0 2.19.5.6 IN_REDUCTION (reduction-identifier: variable-name-list)
TYPE_PARSER(construct<OmpInReductionClause>(
Parser<OmpReductionOperator>{} / ":", Parser<OmpObjectList>{}))
Parser<OmpReductionIdentifier>{} / ":", Parser<OmpObjectList>{}))
// OMP 5.0 2.11.4 allocate-clause -> ALLOCATE ([allocator:] variable-name-list)
// OMP 5.2 2.13.4 allocate-clause -> ALLOCATE ([allocate-modifier
@ -397,18 +421,6 @@ TYPE_PARSER(construct<OmpAllocateClause>(
":"),
Parser<OmpObjectList>{}))
TYPE_PARSER(construct<OmpDependenceType>(
"SINK" >> pure(OmpDependenceType::Type::Sink) ||
"SOURCE" >> pure(OmpDependenceType::Type::Source)))
TYPE_PARSER(construct<OmpTaskDependenceType>(
"DEPOBJ" >> pure(OmpTaskDependenceType::Type::Depobj) ||
"IN"_id >> pure(OmpTaskDependenceType::Type::In) ||
"INOUT"_id >> pure(OmpTaskDependenceType::Type::Inout) ||
"INOUTSET"_id >> pure(OmpTaskDependenceType::Type::Inoutset) ||
"MUTEXINOUTSET" >> pure(OmpTaskDependenceType::Type::Mutexinoutset) ||
"OUT" >> pure(OmpTaskDependenceType::Type::Out)))
// iteration-offset -> +/- non-negative-constant-expr
TYPE_PARSER(construct<OmpIterationOffset>(
Parser<DefinedOperator>{}, scalarIntConstantExpr))
@ -426,7 +438,7 @@ TYPE_PARSER(construct<OmpDoacross>(
TYPE_CONTEXT_PARSER("Omp Depend clause"_en_US,
construct<OmpDependClause>(
construct<OmpDependClause>(construct<OmpDependClause::TaskDep>(
maybe(Parser<OmpIteratorModifier>{} / ","_tok),
maybe(Parser<OmpIterator>{} / ","_tok),
Parser<OmpTaskDependenceType>{} / ":", Parser<OmpObjectList>{})) ||
construct<OmpDependClause>(Parser<OmpDoacross>{})))
@ -439,7 +451,7 @@ TYPE_PARSER(construct<OmpFromClause::Expectation>(
template <typename MotionClause, bool CommasEverywhere>
static inline MotionClause makeMotionClause(
std::tuple<std::optional<std::list<typename MotionClause::Expectation>>,
std::optional<std::list<OmpIteratorModifier>>> &&mods,
std::optional<std::list<OmpIterator>>> &&mods,
OmpObjectList &&objs) {
auto &&[exp, iter] = std::move(mods);
return MotionClause(
@ -458,14 +470,6 @@ TYPE_PARSER(construct<OmpToClause>(
applyFunction<OmpToClause>(makeMotionClause<OmpToClause, false>,
MotionModifiers(maybe(","_tok)), Parser<OmpObjectList>{})))
// 2.15.3.7 LINEAR (linear-list: linear-step)
// linear-list -> list | modifier(list)
// linear-modifier -> REF | VAL | UVAL
TYPE_PARSER(
construct<OmpLinearModifier>("REF" >> pure(OmpLinearModifier::Type::Ref) ||
"VAL" >> pure(OmpLinearModifier::Type::Val) ||
"UVAL" >> pure(OmpLinearModifier::Type::Uval)))
TYPE_CONTEXT_PARSER("Omp LINEAR clause"_en_US,
construct<OmpLinearClause>(
construct<OmpLinearClause>(construct<OmpLinearClause::WithModifier>(
@ -848,7 +852,7 @@ TYPE_PARSER(construct<OmpReductionInitializerClause>(
// 2.16 Declare Reduction Construct
TYPE_PARSER(sourced(construct<OpenMPDeclareReductionConstruct>(
verbatim("DECLARE REDUCTION"_tok),
"(" >> Parser<OmpReductionOperator>{} / ":",
"(" >> Parser<OmpReductionIdentifier>{} / ":",
nonemptyList(Parser<DeclarationTypeSpec>{}) / ":",
Parser<OmpReductionCombiner>{} / ")",
maybe(Parser<OmpReductionInitializerClause>{}))))

View File

@ -253,20 +253,20 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const Name &x) {
return os << x.ToString();
}
OmpDependenceType::Type OmpDoacross::GetDepType() const {
OmpDependenceType::Value OmpDoacross::GetDepType() const {
return common::visit( //
common::visitors{
[](const OmpDoacross::Sink &) {
return OmpDependenceType::Type::Sink;
return OmpDependenceType::Value::Sink;
},
[](const OmpDoacross::Source &) {
return OmpDependenceType::Type::Source;
return OmpDependenceType::Value::Source;
},
},
u);
}
OmpTaskDependenceType::Type OmpDependClause::TaskDep::GetTaskDepType() const {
OmpTaskDependenceType::Value OmpDependClause::TaskDep::GetTaskDepType() const {
return std::get<parser::OmpTaskDependenceType>(t).v;
}

View File

@ -2079,7 +2079,7 @@ public:
Put(" = ");
Walk(std::get<SubscriptTriplet>(x.t));
}
void Unparse(const OmpIteratorModifier &x) {
void Unparse(const OmpIterator &x) {
Word("ITERATOR(");
Walk(x.v);
Put(")");
@ -2093,7 +2093,7 @@ public:
void Unparse(const OmpMapClause &x) {
auto &typeMod =
std::get<std::optional<std::list<OmpMapClause::TypeModifier>>>(x.t);
auto &iter = std::get<std::optional<std::list<OmpIteratorModifier>>>(x.t);
auto &iter = std::get<std::optional<std::list<OmpIterator>>>(x.t);
auto &type = std::get<std::optional<std::list<OmpMapClause::Type>>>(x.t);
auto &mapper = std::get<OmpMapperIdentifier>(x.t);
@ -2147,7 +2147,7 @@ public:
Walk(std::get<ScalarIntExpr>(x.t));
}
void Unparse(const OmpAffinityClause &x) {
Walk(std::get<std::optional<OmpIteratorModifier>>(x.t), ":");
Walk(std::get<std::optional<OmpIterator>>(x.t), ":");
Walk(std::get<OmpObjectList>(x.t));
}
void Unparse(const OmpAlignedClause &x) {
@ -2158,7 +2158,7 @@ public:
void Unparse(const OmpFromClause &x) {
auto &expect{
std::get<std::optional<std::list<OmpFromClause::Expectation>>>(x.t)};
auto &iter{std::get<std::optional<std::list<OmpIteratorModifier>>>(x.t)};
auto &iter{std::get<std::optional<std::list<OmpIterator>>>(x.t)};
bool needComma{false};
if (expect) {
Walk(*expect);
@ -2191,13 +2191,13 @@ public:
void Unparse(const OmpReductionClause &x) {
Walk(std::get<std::optional<OmpReductionClause::ReductionModifier>>(x.t),
",");
Walk(std::get<OmpReductionOperator>(x.t));
Walk(std::get<OmpReductionIdentifier>(x.t));
Put(":");
Walk(std::get<OmpObjectList>(x.t));
}
void Unparse(const OmpDetachClause &x) { Walk(x.v); }
void Unparse(const OmpInReductionClause &x) {
Walk(std::get<OmpReductionOperator>(x.t));
Walk(std::get<OmpReductionIdentifier>(x.t));
Put(":");
Walk(std::get<OmpObjectList>(x.t));
}
@ -2263,7 +2263,7 @@ public:
void Unparse(const OmpToClause &x) {
auto &expect{
std::get<std::optional<std::list<OmpToClause::Expectation>>>(x.t)};
auto &iter{std::get<std::optional<std::list<OmpIteratorModifier>>>(x.t)};
auto &iter{std::get<std::optional<std::list<OmpIterator>>>(x.t)};
bool needComma{false};
if (expect) {
Walk(*expect);
@ -2645,7 +2645,7 @@ public:
}
void Unparse(const OpenMPDeclareReductionConstruct &x) {
Put("(");
Walk(std::get<OmpReductionOperator>(x.t)), Put(" : ");
Walk(std::get<OmpReductionIdentifier>(x.t)), Put(" : ");
Walk(std::get<std::list<DeclarationTypeSpec>>(x.t), ","), Put(" : ");
Walk(std::get<OmpReductionCombiner>(x.t));
Put(")");
@ -2910,8 +2910,8 @@ public:
WALK_NESTED_ENUM(
OmpLastprivateClause, LastprivateModifier) // OMP lastprivate-modifier
WALK_NESTED_ENUM(OmpScheduleModifierType, ModType) // OMP schedule-modifier
WALK_NESTED_ENUM(OmpLinearModifier, Type) // OMP linear-modifier
WALK_NESTED_ENUM(OmpTaskDependenceType, Type) // OMP task-dependence-type
WALK_NESTED_ENUM(OmpLinearModifier, Value) // OMP linear-modifier
WALK_NESTED_ENUM(OmpTaskDependenceType, Value) // 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

View File

@ -683,8 +683,7 @@ void OmpStructureChecker::CheckIteratorRange(
}
}
void OmpStructureChecker::CheckIteratorModifier(
const parser::OmpIteratorModifier &x) {
void OmpStructureChecker::CheckIteratorModifier(const parser::OmpIterator &x) {
// Check if all iterator variables have integer type.
for (auto &&iterSpec : x.v) {
bool isInteger{true};
@ -1859,21 +1858,21 @@ void OmpStructureChecker::CheckTargetUpdate() {
}
void OmpStructureChecker::CheckTaskDependenceType(
const parser::OmpTaskDependenceType::Type &x) {
const parser::OmpTaskDependenceType::Value &x) {
// Common checks for task-dependence-type (DEPEND and UPDATE clauses).
unsigned version{context_.langOptions().OpenMPVersion};
unsigned since{0};
switch (x) {
case parser::OmpTaskDependenceType::Type::In:
case parser::OmpTaskDependenceType::Type::Out:
case parser::OmpTaskDependenceType::Type::Inout:
case parser::OmpTaskDependenceType::Value::In:
case parser::OmpTaskDependenceType::Value::Out:
case parser::OmpTaskDependenceType::Value::Inout:
break;
case parser::OmpTaskDependenceType::Type::Mutexinoutset:
case parser::OmpTaskDependenceType::Type::Depobj:
case parser::OmpTaskDependenceType::Value::Mutexinoutset:
case parser::OmpTaskDependenceType::Value::Depobj:
since = 50;
break;
case parser::OmpTaskDependenceType::Type::Inoutset:
case parser::OmpTaskDependenceType::Value::Inoutset:
since = 52;
break;
}
@ -1888,14 +1887,14 @@ void OmpStructureChecker::CheckTaskDependenceType(
}
void OmpStructureChecker::CheckDependenceType(
const parser::OmpDependenceType::Type &x) {
const parser::OmpDependenceType::Value &x) {
// Common checks for dependence-type (DEPEND and UPDATE clauses).
unsigned version{context_.langOptions().OpenMPVersion};
unsigned deprecatedIn{~0u};
switch (x) {
case parser::OmpDependenceType::Type::Source:
case parser::OmpDependenceType::Type::Sink:
case parser::OmpDependenceType::Value::Source:
case parser::OmpDependenceType::Value::Sink:
deprecatedIn = 52;
break;
}
@ -2864,7 +2863,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Reduction &x) {
bool OmpStructureChecker::CheckReductionOperators(
const parser::OmpClause::Reduction &x) {
const auto &definedOp{std::get<parser::OmpReductionOperator>(x.v.t)};
const auto &definedOp{std::get<parser::OmpReductionIdentifier>(x.v.t)};
bool ok = false;
common::visit(
common::visitors{
@ -2929,7 +2928,7 @@ bool OmpStructureChecker::CheckIntrinsicOperator(
static bool IsReductionAllowedForType(
const parser::OmpClause::Reduction &x, const DeclTypeSpec &type) {
const auto &definedOp{std::get<parser::OmpReductionOperator>(x.v.t)};
const auto &definedOp{std::get<parser::OmpReductionIdentifier>(x.v.t)};
// TODO: user defined reduction operators. Just allow everything for now.
bool ok{true};
@ -3484,7 +3483,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Map &x) {
CheckAllowedClause(llvm::omp::Clause::OMPC_map);
using TypeMod = parser::OmpMapClause::TypeModifier;
using Type = parser::OmpMapClause::Type;
using IterMod = parser::OmpIteratorModifier;
using IterMod = parser::OmpIterator;
unsigned version{context_.langOptions().OpenMPVersion};
if (auto commas{std::get<bool>(x.v.t)}; !commas && version >= 52) {
@ -3637,7 +3636,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Depend &x) {
if (taskDep) {
if (version == 50) {
invalidDep = taskDep->GetTaskDepType() ==
parser::OmpTaskDependenceType::Type::Depobj;
parser::OmpTaskDependenceType::Value::Depobj;
}
} else {
invalidDep = true;
@ -3684,7 +3683,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Depend &x) {
}
}
}
if (std::get<std::optional<parser::OmpIteratorModifier>>(taskDep->t)) {
if (std::get<std::optional<parser::OmpIterator>>(taskDep->t)) {
unsigned allowedInVersion{50};
if (version < allowedInVersion) {
context_.Say(GetContext().clauseSource,
@ -3923,7 +3922,8 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Update &x) {
if (version >= 51) {
bool invalidDep{false};
if (taskType) {
invalidDep = taskType->v == parser::OmpTaskDependenceType::Type::Depobj;
invalidDep =
taskType->v == parser::OmpTaskDependenceType::Value::Depobj;
} else {
invalidDep = true;
}
@ -4058,7 +4058,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::From &x) {
CheckAllowedClause(llvm::omp::Clause::OMPC_from);
unsigned version{context_.langOptions().OpenMPVersion};
using ExpMod = parser::OmpFromClause::Expectation;
using IterMod = parser::OmpIteratorModifier;
using IterMod = parser::OmpIterator;
if (auto &expMod{std::get<std::optional<std::list<ExpMod>>>(x.v.t)}) {
unsigned allowedInVersion{51};
@ -4122,7 +4122,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::To &x) {
}
assert(GetContext().directive == llvm::omp::OMPD_target_update);
using ExpMod = parser::OmpFromClause::Expectation;
using IterMod = parser::OmpIteratorModifier;
using IterMod = parser::OmpIterator;
if (auto &expMod{std::get<std::optional<std::list<ExpMod>>>(x.v.t)}) {
unsigned allowedInVersion{51};

View File

@ -202,7 +202,7 @@ private:
void CheckWorkshareBlockStmts(const parser::Block &, parser::CharBlock);
void CheckIteratorRange(const parser::OmpIteratorSpecifier &x);
void CheckIteratorModifier(const parser::OmpIteratorModifier &x);
void CheckIteratorModifier(const parser::OmpIterator &x);
void CheckLoopItrVariableIsInt(const parser::OpenMPLoopConstruct &x);
void CheckDoWhile(const parser::OpenMPLoopConstruct &x);
void CheckAssociatedLoopConstraints(const parser::OpenMPLoopConstruct &x);
@ -218,8 +218,8 @@ private:
void CheckSIMDNest(const parser::OpenMPConstruct &x);
void CheckTargetNest(const parser::OpenMPConstruct &x);
void CheckTargetUpdate();
void CheckDependenceType(const parser::OmpDependenceType::Type &x);
void CheckTaskDependenceType(const parser::OmpTaskDependenceType::Type &x);
void CheckDependenceType(const parser::OmpDependenceType::Value &x);
void CheckTaskDependenceType(const parser::OmpTaskDependenceType::Value &x);
void CheckCancellationNest(
const parser::CharBlock &source, const parser::OmpCancelType::Type &type);
std::int64_t GetOrdCollapseLevel(const parser::OpenMPLoopConstruct &x);

View File

@ -518,8 +518,8 @@ public:
}
bool Pre(const parser::OmpClause::Reduction &x) {
const parser::OmpReductionOperator &opr{
std::get<parser::OmpReductionOperator>(x.v.t)};
const parser::OmpReductionIdentifier &opr{
std::get<parser::OmpReductionIdentifier>(x.v.t)};
auto createDummyProcSymbol = [&](const parser::Name *name) {
// If name resolution failed, create a dummy symbol
const auto namePair{

View File

@ -63,7 +63,7 @@ end
!PARSE-TREE: OmpBeginBlockDirective
!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = task
!PARSE-TREE: | OmpClauseList -> OmpClause -> Affinity -> OmpAffinityClause
!PARSE-TREE: | | OmpIteratorModifier -> OmpIteratorSpecifier
!PARSE-TREE: | | OmpIterator -> OmpIteratorSpecifier
!PARSE-TREE: | | | TypeDeclarationStmt
!PARSE-TREE: | | | | DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec ->
!PARSE-TREE: | | | | EntityDecl

View File

@ -15,7 +15,7 @@ end
!PARSE-TREE: | Verbatim
!PARSE-TREE: | OmpObject -> Designator -> DataRef -> Name = 'x'
!PARSE-TREE: | OmpClause -> Depend -> OmpDependClause -> TaskDep
!PARSE-TREE: | | OmpTaskDependenceType -> Type = In
!PARSE-TREE: | | OmpTaskDependenceType -> Value = In
!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'y'
subroutine f01
@ -31,7 +31,7 @@ end
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPDepobjConstruct
!PARSE-TREE: | Verbatim
!PARSE-TREE: | OmpObject -> Designator -> DataRef -> Name = 'x'
!PARSE-TREE: | OmpClause -> Update -> OmpUpdateClause -> OmpTaskDependenceType -> Type = Out
!PARSE-TREE: | OmpClause -> Update -> OmpUpdateClause -> OmpTaskDependenceType -> Value = Out
subroutine f02
integer :: x

View File

@ -45,7 +45,7 @@ end
!PARSE-TREE: OmpSimpleStandaloneDirective -> llvm::omp::Directive = target update
!PARSE-TREE: OmpClauseList -> OmpClause -> From -> OmpFromClause
!PARSE-TREE: | Expectation = Present
!PARSE-TREE: | OmpIteratorModifier -> OmpIteratorSpecifier
!PARSE-TREE: | OmpIterator -> OmpIteratorSpecifier
!PARSE-TREE: | | TypeDeclarationStmt
!PARSE-TREE: | | | DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec ->
!PARSE-TREE: | | | EntityDecl
@ -74,7 +74,7 @@ end
!PARSE-TREE: OmpSimpleStandaloneDirective -> llvm::omp::Directive = target update
!PARSE-TREE: OmpClauseList -> OmpClause -> From -> OmpFromClause
!PARSE-TREE: | Expectation = Present
!PARSE-TREE: | OmpIteratorModifier -> OmpIteratorSpecifier
!PARSE-TREE: | OmpIterator -> OmpIteratorSpecifier
!PARSE-TREE: | | TypeDeclarationStmt
!PARSE-TREE: | | | DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec ->
!PARSE-TREE: | | | EntityDecl

View File

@ -37,14 +37,14 @@ end subroutine omp_in_reduction_taskgroup
!PARSE-TREE-NEXT: OmpBeginBlockDirective
!PARSE-TREE-NEXT: OmpBlockDirective -> llvm::omp::Directive = task
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> InReduction -> OmpInReductionClause
!PARSE-TREE-NEXT: OmpReductionOperator -> DefinedOperator -> IntrinsicOperator = Add
!PARSE-TREE-NEXT: OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add
!PARSE-TREE-NEXT: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'z'
!PARSE-TREE: OpenMPConstruct -> OpenMPLoopConstruct
!PARSE-TREE-NEXT: OmpBeginLoopDirective
!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = taskloop
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> InReduction -> OmpInReductionClause
!PARSE-TREE-NEXT: OmpReductionOperator -> DefinedOperator -> IntrinsicOperator = Add
!PARSE-TREE-NEXT: OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add
!PARSE-TREE-NEXT: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'z'
subroutine omp_in_reduction_parallel()
@ -74,6 +74,6 @@ end subroutine omp_in_reduction_parallel
!PARSE-TREE-NEXT: OmpBeginLoopDirective
!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = taskloop simd
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> InReduction -> OmpInReductionClause
!PARSE-TREE-NEXT: OmpReductionOperator -> DefinedOperator -> IntrinsicOperator = Add
!PARSE-TREE-NEXT: OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add
!PASRE-TREE-NEXT: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'z'

View File

@ -159,7 +159,7 @@ end
!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
!PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
!PARSE-TREE: | | TypeModifier = Present
!PARSE-TREE: | | OmpIteratorModifier -> OmpIteratorSpecifier
!PARSE-TREE: | | OmpIterator -> OmpIteratorSpecifier
!PARSE-TREE: | | | TypeDeclarationStmt
!PARSE-TREE: | | | | DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec ->
!PARSE-TREE: | | | | EntityDecl
@ -194,7 +194,7 @@ end
!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
!PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
!PARSE-TREE: | | TypeModifier = Present
!PARSE-TREE: | | OmpIteratorModifier -> OmpIteratorSpecifier
!PARSE-TREE: | | OmpIterator -> OmpIteratorSpecifier
!PARSE-TREE: | | | TypeDeclarationStmt
!PARSE-TREE: | | | | DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec ->
!PARSE-TREE: | | | | EntityDecl
@ -229,7 +229,7 @@ end
!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
!PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
!PARSE-TREE: | | TypeModifier = Present
!PARSE-TREE: | | OmpIteratorModifier -> OmpIteratorSpecifier
!PARSE-TREE: | | OmpIterator -> OmpIteratorSpecifier
!PARSE-TREE: | | | TypeDeclarationStmt
!PARSE-TREE: | | | | DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec ->
!PARSE-TREE: | | | | EntityDecl
@ -287,7 +287,7 @@ end
!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = target
!PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
!PARSE-TREE: | | TypeModifier = Present
!PARSE-TREE: | | OmpIteratorModifier -> OmpIteratorSpecifier
!PARSE-TREE: | | OmpIterator -> OmpIteratorSpecifier
!PARSE-TREE: | | | TypeDeclarationStmt
!PARSE-TREE: | | | | DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec ->
!PARSE-TREE: | | | | EntityDecl

View File

@ -10,7 +10,7 @@ subroutine foo()
! PARSE-TREE: | | | | OmpLoopDirective -> llvm::omp::Directive = do
! PARSE-TREE: | | | | OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause
! PARSE-TREE: | | | | | ReductionModifier = Task
! PARSE-TREE: | | | | | OmpReductionOperator -> DefinedOperator -> IntrinsicOperator = Multiply
! PARSE-TREE: | | | | | OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Multiply
! PARSE-TREE: | | | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'j
!$omp do reduction (task, *: j)
do i = 1, 10

View File

@ -45,7 +45,7 @@ end
!PARSE-TREE: OmpSimpleStandaloneDirective -> llvm::omp::Directive = target update
!PARSE-TREE: OmpClauseList -> OmpClause -> To -> OmpToClause
!PARSE-TREE: | Expectation = Present
!PARSE-TREE: | OmpIteratorModifier -> OmpIteratorSpecifier
!PARSE-TREE: | OmpIterator -> OmpIteratorSpecifier
!PARSE-TREE: | | TypeDeclarationStmt
!PARSE-TREE: | | | DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec ->
!PARSE-TREE: | | | EntityDecl
@ -74,7 +74,7 @@ end
!PARSE-TREE: OmpSimpleStandaloneDirective -> llvm::omp::Directive = target update
!PARSE-TREE: OmpClauseList -> OmpClause -> To -> OmpToClause
!PARSE-TREE: | Expectation = Present
!PARSE-TREE: | OmpIteratorModifier -> OmpIteratorSpecifier
!PARSE-TREE: | OmpIterator -> OmpIteratorSpecifier
!PARSE-TREE: | | TypeDeclarationStmt
!PARSE-TREE: | | | DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec ->
!PARSE-TREE: | | | EntityDecl