[Flang] Add parser support for AUTOMAP modifier (#151511)
Add parser support for the new AUTOMAP modifier for OpenMP Declare Target Enter clause introduced in OpenMP 6.0 section 7.9.7.
This commit is contained in:
parent
9e0dc4f737
commit
9fdd1d3d46
@ -581,6 +581,8 @@ public:
|
|||||||
NODE(parser, OmpDependClause)
|
NODE(parser, OmpDependClause)
|
||||||
NODE(OmpDependClause, TaskDep)
|
NODE(OmpDependClause, TaskDep)
|
||||||
NODE(OmpDependClause::TaskDep, Modifier)
|
NODE(OmpDependClause::TaskDep, Modifier)
|
||||||
|
NODE(parser, OmpAutomapModifier)
|
||||||
|
NODE_ENUM(OmpAutomapModifier, Value)
|
||||||
NODE(parser, OmpDetachClause)
|
NODE(parser, OmpDetachClause)
|
||||||
NODE(parser, OmpDoacrossClause)
|
NODE(parser, OmpDoacrossClause)
|
||||||
NODE(parser, OmpDestroyClause)
|
NODE(parser, OmpDestroyClause)
|
||||||
@ -588,6 +590,8 @@ public:
|
|||||||
NODE(parser, OmpEndCriticalDirective)
|
NODE(parser, OmpEndCriticalDirective)
|
||||||
NODE(parser, OmpEndLoopDirective)
|
NODE(parser, OmpEndLoopDirective)
|
||||||
NODE(parser, OmpEndSectionsDirective)
|
NODE(parser, OmpEndSectionsDirective)
|
||||||
|
NODE(parser, OmpEnterClause)
|
||||||
|
NODE(OmpEnterClause, Modifier)
|
||||||
NODE(parser, OmpFailClause)
|
NODE(parser, OmpFailClause)
|
||||||
NODE(parser, OmpFromClause)
|
NODE(parser, OmpFromClause)
|
||||||
NODE(OmpFromClause, Modifier)
|
NODE(OmpFromClause, Modifier)
|
||||||
|
@ -3776,6 +3776,16 @@ struct OmpAlwaysModifier {
|
|||||||
WRAPPER_CLASS_BOILERPLATE(OmpAlwaysModifier, Value);
|
WRAPPER_CLASS_BOILERPLATE(OmpAlwaysModifier, Value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Ref: [6.0:289-290]
|
||||||
|
//
|
||||||
|
// automap-modifier ->
|
||||||
|
// automap // since 6.0
|
||||||
|
//
|
||||||
|
struct OmpAutomapModifier {
|
||||||
|
ENUM_CLASS(Value, Automap);
|
||||||
|
WRAPPER_CLASS_BOILERPLATE(OmpAutomapModifier, Value);
|
||||||
|
};
|
||||||
|
|
||||||
// Ref: [5.2:252-254]
|
// Ref: [5.2:252-254]
|
||||||
//
|
//
|
||||||
// chunk-modifier ->
|
// chunk-modifier ->
|
||||||
@ -4360,6 +4370,17 @@ struct OmpDeviceTypeClause {
|
|||||||
WRAPPER_CLASS_BOILERPLATE(OmpDeviceTypeClause, DeviceTypeDescription);
|
WRAPPER_CLASS_BOILERPLATE(OmpDeviceTypeClause, DeviceTypeDescription);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Ref: [5.2:158-159], [6.0:289-290]
|
||||||
|
//
|
||||||
|
// enter-clause ->
|
||||||
|
// ENTER(locator-list) |
|
||||||
|
// ENTER(automap-modifier: locator-list) | // since 6.0
|
||||||
|
struct OmpEnterClause {
|
||||||
|
TUPLE_CLASS_BOILERPLATE(OmpEnterClause);
|
||||||
|
MODIFIER_BOILERPLATE(OmpAutomapModifier);
|
||||||
|
std::tuple<MODIFIERS(), OmpObjectList> t;
|
||||||
|
};
|
||||||
|
|
||||||
// OMP 5.2 15.8.3 extended-atomic, fail-clause ->
|
// OMP 5.2 15.8.3 extended-atomic, fail-clause ->
|
||||||
// FAIL(memory-order)
|
// FAIL(memory-order)
|
||||||
struct OmpFailClause {
|
struct OmpFailClause {
|
||||||
|
@ -72,6 +72,7 @@ DECLARE_DESCRIPTOR(parser::OmpAlignModifier);
|
|||||||
DECLARE_DESCRIPTOR(parser::OmpAllocatorComplexModifier);
|
DECLARE_DESCRIPTOR(parser::OmpAllocatorComplexModifier);
|
||||||
DECLARE_DESCRIPTOR(parser::OmpAllocatorSimpleModifier);
|
DECLARE_DESCRIPTOR(parser::OmpAllocatorSimpleModifier);
|
||||||
DECLARE_DESCRIPTOR(parser::OmpAlwaysModifier);
|
DECLARE_DESCRIPTOR(parser::OmpAlwaysModifier);
|
||||||
|
DECLARE_DESCRIPTOR(parser::OmpAutomapModifier);
|
||||||
DECLARE_DESCRIPTOR(parser::OmpChunkModifier);
|
DECLARE_DESCRIPTOR(parser::OmpChunkModifier);
|
||||||
DECLARE_DESCRIPTOR(parser::OmpCloseModifier);
|
DECLARE_DESCRIPTOR(parser::OmpCloseModifier);
|
||||||
DECLARE_DESCRIPTOR(parser::OmpContextSelector);
|
DECLARE_DESCRIPTOR(parser::OmpContextSelector);
|
||||||
|
@ -1519,10 +1519,14 @@ bool ClauseProcessor::processTo(
|
|||||||
bool ClauseProcessor::processEnter(
|
bool ClauseProcessor::processEnter(
|
||||||
llvm::SmallVectorImpl<DeclareTargetCapturePair> &result) const {
|
llvm::SmallVectorImpl<DeclareTargetCapturePair> &result) const {
|
||||||
return findRepeatableClause<omp::clause::Enter>(
|
return findRepeatableClause<omp::clause::Enter>(
|
||||||
[&](const omp::clause::Enter &clause, const parser::CharBlock &) {
|
[&](const omp::clause::Enter &clause, const parser::CharBlock &source) {
|
||||||
|
mlir::Location currentLocation = converter.genLocation(source);
|
||||||
|
if (std::get<std::optional<omp::clause::Enter::Modifier>>(clause.t))
|
||||||
|
TODO(currentLocation, "Declare target enter AUTOMAP modifier");
|
||||||
// Case: declare target enter(func, var1, var2)...
|
// Case: declare target enter(func, var1, var2)...
|
||||||
gatherFuncAndVarSyms(
|
gatherFuncAndVarSyms(std::get<ObjectList>(clause.t),
|
||||||
clause.v, mlir::omp::DeclareTargetCaptureClause::enter, result);
|
mlir::omp::DeclareTargetCaptureClause::enter,
|
||||||
|
result);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -772,8 +772,19 @@ Doacross make(const parser::OmpClause::Doacross &inp,
|
|||||||
|
|
||||||
Enter make(const parser::OmpClause::Enter &inp,
|
Enter make(const parser::OmpClause::Enter &inp,
|
||||||
semantics::SemanticsContext &semaCtx) {
|
semantics::SemanticsContext &semaCtx) {
|
||||||
// inp.v -> parser::OmpObjectList
|
// inp.v -> parser::OmpEnterClause
|
||||||
return Enter{makeObjects(/*List=*/inp.v, semaCtx)};
|
CLAUSET_ENUM_CONVERT( //
|
||||||
|
convert, parser::OmpAutomapModifier::Value, Enter::Modifier,
|
||||||
|
// clang-format off
|
||||||
|
MS(Automap, Automap)
|
||||||
|
// clang-format on
|
||||||
|
);
|
||||||
|
auto &mods = semantics::OmpGetModifiers(inp.v);
|
||||||
|
auto *mod = semantics::OmpGetUniqueModifier<parser::OmpAutomapModifier>(mods);
|
||||||
|
auto &objList = std::get<parser::OmpObjectList>(inp.v.t);
|
||||||
|
|
||||||
|
return Enter{{/*Modifier=*/maybeApplyToV(convert, mod),
|
||||||
|
/*List=*/makeObjects(objList, semaCtx)}};
|
||||||
}
|
}
|
||||||
|
|
||||||
Exclusive make(const parser::OmpClause::Exclusive &inp,
|
Exclusive make(const parser::OmpClause::Exclusive &inp,
|
||||||
|
@ -482,6 +482,9 @@ TYPE_PARSER(construct<OmpAllocatorSimpleModifier>(scalarIntExpr))
|
|||||||
TYPE_PARSER(construct<OmpAlwaysModifier>( //
|
TYPE_PARSER(construct<OmpAlwaysModifier>( //
|
||||||
"ALWAYS" >> pure(OmpAlwaysModifier::Value::Always)))
|
"ALWAYS" >> pure(OmpAlwaysModifier::Value::Always)))
|
||||||
|
|
||||||
|
TYPE_PARSER(construct<OmpAutomapModifier>(
|
||||||
|
"AUTOMAP" >> pure(OmpAutomapModifier::Value::Automap)))
|
||||||
|
|
||||||
TYPE_PARSER(construct<OmpChunkModifier>( //
|
TYPE_PARSER(construct<OmpChunkModifier>( //
|
||||||
"SIMD" >> pure(OmpChunkModifier::Value::Simd)))
|
"SIMD" >> pure(OmpChunkModifier::Value::Simd)))
|
||||||
|
|
||||||
@ -636,6 +639,9 @@ TYPE_PARSER(sourced(construct<OmpDependClause::TaskDep::Modifier>(sourced(
|
|||||||
TYPE_PARSER(
|
TYPE_PARSER(
|
||||||
sourced(construct<OmpDeviceClause::Modifier>(Parser<OmpDeviceModifier>{})))
|
sourced(construct<OmpDeviceClause::Modifier>(Parser<OmpDeviceModifier>{})))
|
||||||
|
|
||||||
|
TYPE_PARSER(
|
||||||
|
sourced(construct<OmpEnterClause::Modifier>(Parser<OmpAutomapModifier>{})))
|
||||||
|
|
||||||
TYPE_PARSER(sourced(construct<OmpFromClause::Modifier>(
|
TYPE_PARSER(sourced(construct<OmpFromClause::Modifier>(
|
||||||
sourced(construct<OmpFromClause::Modifier>(Parser<OmpExpectation>{}) ||
|
sourced(construct<OmpFromClause::Modifier>(Parser<OmpExpectation>{}) ||
|
||||||
construct<OmpFromClause::Modifier>(Parser<OmpMapper>{}) ||
|
construct<OmpFromClause::Modifier>(Parser<OmpMapper>{}) ||
|
||||||
@ -771,6 +777,10 @@ TYPE_PARSER(construct<OmpDefaultClause>(
|
|||||||
Parser<OmpDefaultClause::DataSharingAttribute>{}) ||
|
Parser<OmpDefaultClause::DataSharingAttribute>{}) ||
|
||||||
construct<OmpDefaultClause>(indirect(Parser<OmpDirectiveSpecification>{}))))
|
construct<OmpDefaultClause>(indirect(Parser<OmpDirectiveSpecification>{}))))
|
||||||
|
|
||||||
|
TYPE_PARSER(construct<OmpEnterClause>(
|
||||||
|
maybe(nonemptyList(Parser<OmpEnterClause::Modifier>{}) / ":"),
|
||||||
|
Parser<OmpObjectList>{}))
|
||||||
|
|
||||||
TYPE_PARSER(construct<OmpFailClause>(
|
TYPE_PARSER(construct<OmpFailClause>(
|
||||||
"ACQ_REL" >> pure(common::OmpMemoryOrderType::Acq_Rel) ||
|
"ACQ_REL" >> pure(common::OmpMemoryOrderType::Acq_Rel) ||
|
||||||
"ACQUIRE" >> pure(common::OmpMemoryOrderType::Acquire) ||
|
"ACQUIRE" >> pure(common::OmpMemoryOrderType::Acquire) ||
|
||||||
@ -1059,7 +1069,7 @@ TYPE_PARSER( //
|
|||||||
"DYNAMIC_ALLOCATORS" >>
|
"DYNAMIC_ALLOCATORS" >>
|
||||||
construct<OmpClause>(construct<OmpClause::DynamicAllocators>()) ||
|
construct<OmpClause>(construct<OmpClause::DynamicAllocators>()) ||
|
||||||
"ENTER" >> construct<OmpClause>(construct<OmpClause::Enter>(
|
"ENTER" >> construct<OmpClause>(construct<OmpClause::Enter>(
|
||||||
parenthesized(Parser<OmpObjectList>{}))) ||
|
parenthesized(Parser<OmpEnterClause>{}))) ||
|
||||||
"EXCLUSIVE" >> construct<OmpClause>(construct<OmpClause::Exclusive>(
|
"EXCLUSIVE" >> construct<OmpClause>(construct<OmpClause::Exclusive>(
|
||||||
parenthesized(Parser<OmpObjectList>{}))) ||
|
parenthesized(Parser<OmpObjectList>{}))) ||
|
||||||
"FAIL" >> construct<OmpClause>(construct<OmpClause::Fail>(
|
"FAIL" >> construct<OmpClause>(construct<OmpClause::Fail>(
|
||||||
|
@ -2250,6 +2250,11 @@ public:
|
|||||||
Walk(std::get<OmpObjectList>(x.t));
|
Walk(std::get<OmpObjectList>(x.t));
|
||||||
Walk(": ", std::get<std::optional<std::list<Modifier>>>(x.t));
|
Walk(": ", std::get<std::optional<std::list<Modifier>>>(x.t));
|
||||||
}
|
}
|
||||||
|
void Unparse(const OmpEnterClause &x) {
|
||||||
|
using Modifier = OmpEnterClause::Modifier;
|
||||||
|
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
|
||||||
|
Walk(std::get<OmpObjectList>(x.t));
|
||||||
|
}
|
||||||
void Unparse(const OmpFromClause &x) {
|
void Unparse(const OmpFromClause &x) {
|
||||||
using Modifier = OmpFromClause::Modifier;
|
using Modifier = OmpFromClause::Modifier;
|
||||||
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
|
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
|
||||||
@ -2986,6 +2991,7 @@ public:
|
|||||||
WALK_NESTED_ENUM(UseStmt, ModuleNature) // R1410
|
WALK_NESTED_ENUM(UseStmt, ModuleNature) // R1410
|
||||||
WALK_NESTED_ENUM(OmpAdjustArgsClause::OmpAdjustOp, Value) // OMP adjustop
|
WALK_NESTED_ENUM(OmpAdjustArgsClause::OmpAdjustOp, Value) // OMP adjustop
|
||||||
WALK_NESTED_ENUM(OmpAtClause, ActionTime) // OMP at
|
WALK_NESTED_ENUM(OmpAtClause, ActionTime) // OMP at
|
||||||
|
WALK_NESTED_ENUM(OmpAutomapModifier, Value) // OMP automap-modifier
|
||||||
WALK_NESTED_ENUM(OmpBindClause, Binding) // OMP bind
|
WALK_NESTED_ENUM(OmpBindClause, Binding) // OMP bind
|
||||||
WALK_NESTED_ENUM(OmpProcBindClause, AffinityPolicy) // OMP proc_bind
|
WALK_NESTED_ENUM(OmpProcBindClause, AffinityPolicy) // OMP proc_bind
|
||||||
WALK_NESTED_ENUM(OmpDefaultClause, DataSharingAttribute) // OMP default
|
WALK_NESTED_ENUM(OmpDefaultClause, DataSharingAttribute) // OMP default
|
||||||
|
@ -1569,9 +1569,10 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &x) {
|
|||||||
},
|
},
|
||||||
[&](const parser::OmpClause::Enter &enterClause) {
|
[&](const parser::OmpClause::Enter &enterClause) {
|
||||||
enterClauseFound = true;
|
enterClauseFound = true;
|
||||||
CheckSymbolNames(dir.source, enterClause.v);
|
auto &objList{std::get<parser::OmpObjectList>(enterClause.v.t)};
|
||||||
CheckVarIsNotPartOfAnotherVar(dir.source, enterClause.v);
|
CheckSymbolNames(dir.source, objList);
|
||||||
CheckThreadprivateOrDeclareTargetVar(enterClause.v);
|
CheckVarIsNotPartOfAnotherVar(dir.source, objList);
|
||||||
|
CheckThreadprivateOrDeclareTargetVar(objList);
|
||||||
},
|
},
|
||||||
[&](const parser::OmpClause::DeviceType &deviceTypeClause) {
|
[&](const parser::OmpClause::DeviceType &deviceTypeClause) {
|
||||||
deviceTypeClauseFound = true;
|
deviceTypeClauseFound = true;
|
||||||
@ -4029,7 +4030,11 @@ void OmpStructureChecker::Enter(const parser::OmpClause::HasDeviceAddr &x) {
|
|||||||
|
|
||||||
void OmpStructureChecker::Enter(const parser::OmpClause::Enter &x) {
|
void OmpStructureChecker::Enter(const parser::OmpClause::Enter &x) {
|
||||||
CheckAllowedClause(llvm::omp::Clause::OMPC_enter);
|
CheckAllowedClause(llvm::omp::Clause::OMPC_enter);
|
||||||
const parser::OmpObjectList &objList{x.v};
|
if (!OmpVerifyModifiers(
|
||||||
|
x.v, llvm::omp::OMPC_enter, GetContext().clauseSource, context_)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const parser::OmpObjectList &objList{std::get<parser::OmpObjectList>(x.v.t)};
|
||||||
SymbolSourceMap symbols;
|
SymbolSourceMap symbols;
|
||||||
GetSymbolsInObjectList(objList, symbols);
|
GetSymbolsInObjectList(objList, symbols);
|
||||||
for (const auto &[symbol, source] : symbols) {
|
for (const auto &[symbol, source] : symbols) {
|
||||||
@ -4489,17 +4494,18 @@ const parser::OmpObjectList *OmpStructureChecker::GetOmpObjectList(
|
|||||||
const parser::OmpClause &clause) {
|
const parser::OmpClause &clause) {
|
||||||
|
|
||||||
// Clauses with OmpObjectList as its data member
|
// Clauses with OmpObjectList as its data member
|
||||||
using MemberObjectListClauses = std::tuple<parser::OmpClause::Copyprivate,
|
using MemberObjectListClauses =
|
||||||
parser::OmpClause::Copyin, parser::OmpClause::Enter,
|
std::tuple<parser::OmpClause::Copyprivate, parser::OmpClause::Copyin,
|
||||||
parser::OmpClause::Firstprivate, parser::OmpClause::Link,
|
parser::OmpClause::Firstprivate, parser::OmpClause::Link,
|
||||||
parser::OmpClause::Private, parser::OmpClause::Shared,
|
parser::OmpClause::Private, parser::OmpClause::Shared,
|
||||||
parser::OmpClause::UseDevicePtr, parser::OmpClause::UseDeviceAddr>;
|
parser::OmpClause::UseDevicePtr, parser::OmpClause::UseDeviceAddr>;
|
||||||
|
|
||||||
// Clauses with OmpObjectList in the tuple
|
// Clauses with OmpObjectList in the tuple
|
||||||
using TupleObjectListClauses = std::tuple<parser::OmpClause::Aligned,
|
using TupleObjectListClauses =
|
||||||
parser::OmpClause::Allocate, parser::OmpClause::From,
|
std::tuple<parser::OmpClause::Aligned, parser::OmpClause::Allocate,
|
||||||
parser::OmpClause::Lastprivate, parser::OmpClause::Map,
|
parser::OmpClause::From, parser::OmpClause::Lastprivate,
|
||||||
parser::OmpClause::Reduction, parser::OmpClause::To>;
|
parser::OmpClause::Map, parser::OmpClause::Reduction,
|
||||||
|
parser::OmpClause::To, parser::OmpClause::Enter>;
|
||||||
|
|
||||||
// TODO:: Generate the tuples using TableGen.
|
// TODO:: Generate the tuples using TableGen.
|
||||||
// Handle other constructs with OmpObjectList such as OpenMPThreadprivate.
|
// Handle other constructs with OmpObjectList such as OpenMPThreadprivate.
|
||||||
|
@ -156,6 +156,22 @@ const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpAlwaysModifier>() {
|
|||||||
return desc;
|
return desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpAutomapModifier>() {
|
||||||
|
static const OmpModifierDescriptor desc{
|
||||||
|
/*name=*/"automap-modifier",
|
||||||
|
/*props=*/
|
||||||
|
{
|
||||||
|
{60, {OmpProperty::Unique}},
|
||||||
|
},
|
||||||
|
/*clauses=*/
|
||||||
|
{
|
||||||
|
{60, {Clause::OMPC_enter}},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpChunkModifier>() {
|
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpChunkModifier>() {
|
||||||
static const OmpModifierDescriptor desc{
|
static const OmpModifierDescriptor desc{
|
||||||
|
@ -2152,7 +2152,8 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPDeclareTargetConstruct &x) {
|
|||||||
ResolveOmpObjectList(linkClause->v, Symbol::Flag::OmpDeclareTarget);
|
ResolveOmpObjectList(linkClause->v, Symbol::Flag::OmpDeclareTarget);
|
||||||
} else if (const auto *enterClause{
|
} else if (const auto *enterClause{
|
||||||
std::get_if<parser::OmpClause::Enter>(&clause.u)}) {
|
std::get_if<parser::OmpClause::Enter>(&clause.u)}) {
|
||||||
ResolveOmpObjectList(enterClause->v, Symbol::Flag::OmpDeclareTarget);
|
ResolveOmpObjectList(std::get<parser::OmpObjectList>(enterClause->v.t),
|
||||||
|
Symbol::Flag::OmpDeclareTarget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1646,7 +1646,8 @@ public:
|
|||||||
populateDeclareTargetNames(linkClause->v);
|
populateDeclareTargetNames(linkClause->v);
|
||||||
} else if (const auto *enterClause{
|
} else if (const auto *enterClause{
|
||||||
std::get_if<parser::OmpClause::Enter>(&clause.u)}) {
|
std::get_if<parser::OmpClause::Enter>(&clause.u)}) {
|
||||||
populateDeclareTargetNames(enterClause->v);
|
populateDeclareTargetNames(
|
||||||
|
std::get<parser::OmpObjectList>(enterClause->v.t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
16
flang/test/Parser/OpenMP/enter-automap-modifier.f90
Normal file
16
flang/test/Parser/OpenMP/enter-automap-modifier.f90
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=60 %s | FileCheck %s --check-prefix=UNPARSE
|
||||||
|
!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=60 %s | FileCheck %s --check-prefix=PARSE-TREE
|
||||||
|
|
||||||
|
program automap
|
||||||
|
integer :: x
|
||||||
|
!$omp declare target enter(automap: x)
|
||||||
|
end program
|
||||||
|
|
||||||
|
!UNPARSE: PROGRAM AUTOMAP
|
||||||
|
!UNPARSE: INTEGER x
|
||||||
|
!UNPARSE: !$OMP DECLARE TARGET ENTER(AUTOMAP: x)
|
||||||
|
!UNPARSE: END PROGRAM
|
||||||
|
|
||||||
|
!PARSE-TREE: OmpClauseList -> OmpClause -> Enter -> OmpEnterClause
|
||||||
|
!PARSE-TREE-NEXT: | Modifier -> OmpAutomapModifier -> Value = Automap
|
||||||
|
!PARSE-TREE-NEXT: | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
|
@ -578,8 +578,9 @@ struct DynamicAllocatorsT {
|
|||||||
template <typename T, typename I, typename E> //
|
template <typename T, typename I, typename E> //
|
||||||
struct EnterT {
|
struct EnterT {
|
||||||
using List = ObjectListT<I, E>;
|
using List = ObjectListT<I, E>;
|
||||||
using WrapperTrait = std::true_type;
|
ENUM(Modifier, Automap);
|
||||||
List v;
|
using TupleTrait = std::true_type;
|
||||||
|
std::tuple<OPT(Modifier), List> t;
|
||||||
};
|
};
|
||||||
|
|
||||||
// V5.2: [5.6.2] `exclusive` clause
|
// V5.2: [5.6.2] `exclusive` clause
|
||||||
|
@ -179,7 +179,7 @@ def OMPC_DynamicAllocators : Clause<[Spelling<"dynamic_allocators">]> {
|
|||||||
let clangClass = "OMPDynamicAllocatorsClause";
|
let clangClass = "OMPDynamicAllocatorsClause";
|
||||||
}
|
}
|
||||||
def OMPC_Enter : Clause<[Spelling<"enter">]> {
|
def OMPC_Enter : Clause<[Spelling<"enter">]> {
|
||||||
let flangClass = "OmpObjectList";
|
let flangClass = "OmpEnterClause";
|
||||||
}
|
}
|
||||||
def OMPC_Exclusive : Clause<[Spelling<"exclusive">]> {
|
def OMPC_Exclusive : Clause<[Spelling<"exclusive">]> {
|
||||||
let clangClass = "OMPExclusiveClause";
|
let clangClass = "OMPExclusiveClause";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user