-
Notifications
You must be signed in to change notification settings - Fork 11.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[flang][OpenMP] Parser support for DEPOBJ plus DEPEND, DESTROY, UPDATE #114074
Conversation
Parse the DEPOBJ construct and the associated clauses, perform basic semantic checks.
@llvm/pr-subscribers-flang-parser @llvm/pr-subscribers-flang-semantics Author: Krzysztof Parzyszek (kparzysz) ChangesParse the DEPOBJ construct and the associated clauses, perform basic semantic checks. Patch is 35.59 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/114074.diff 21 Files Affected:
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 31ad1b7c6ce5b5..67f7e1aac40edb 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -517,6 +517,7 @@ class ParseTreeDumper {
NODE_ENUM(OmpTaskDependenceType, Type)
NODE(parser, OmpDependSinkVec)
NODE(parser, OmpDependSinkVecLength)
+ NODE(parser, OmpDestroyClause)
NODE(parser, OmpEndAllocators)
NODE(parser, OmpEndAtomic)
NODE(parser, OmpEndBlockDirective)
@@ -571,6 +572,7 @@ class ParseTreeDumper {
NODE_ENUM(OmpDeviceClause, DeviceModifier)
NODE(parser, OmpDeviceTypeClause)
NODE_ENUM(OmpDeviceTypeClause, Type)
+ NODE(parser, OmpUpdateClause)
NODE(parser, OmpScheduleModifier)
NODE(OmpScheduleModifier, Modifier1)
NODE(OmpScheduleModifier, Modifier2)
@@ -609,6 +611,7 @@ class ParseTreeDumper {
NODE(parser, OmpAtomicClauseList)
NODE(parser, OmpAtomicDefaultMemOrderClause)
NODE_ENUM(common, OmpAtomicDefaultMemOrderType)
+ NODE(parser, OpenMPDepobjConstruct)
NODE(parser, OpenMPFlushConstruct)
NODE(parser, OpenMPLoopConstruct)
NODE(parser, OpenMPExecutableAllocate)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 174f4c631e9d4c..13c3353512208b 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3447,7 +3447,7 @@ WRAPPER_CLASS(OmpObjectList, std::list<OmpObject>);
// MUTEXINOUTSET | DEPOBJ | // since 5.0
// INOUTSET // since 5.2
struct OmpTaskDependenceType {
- ENUM_CLASS(Type, In, Out, Inout, Source, Sink)
+ ENUM_CLASS(Type, In, Out, Inout, Source, Sink, Depobj)
WRAPPER_CLASS_BOILERPLATE(OmpTaskDependenceType, Type);
};
@@ -3527,19 +3527,6 @@ struct OmpDefaultmapClause {
std::tuple<ImplicitBehavior, std::optional<VariableCategory>> t;
};
-// device([ device-modifier :] scalar-integer-expression)
-struct OmpDeviceClause {
- TUPLE_CLASS_BOILERPLATE(OmpDeviceClause);
- ENUM_CLASS(DeviceModifier, Ancestor, Device_Num)
- std::tuple<std::optional<DeviceModifier>, ScalarIntExpr> t;
-};
-
-// device_type(any | host | nohost)
-struct OmpDeviceTypeClause {
- ENUM_CLASS(Type, Any, Host, Nohost)
- WRAPPER_CLASS_BOILERPLATE(OmpDeviceTypeClause, Type);
-};
-
// 2.13.9 depend-vec-length -> +/- non-negative-constant
struct OmpDependSinkVecLength {
TUPLE_CLASS_BOILERPLATE(OmpDependSinkVecLength);
@@ -3561,6 +3548,8 @@ struct OmpDependSinkVec {
//
// depend-modifier -> iterator-modifier // since 5.0
struct OmpDependClause {
+ OmpTaskDependenceType::Type GetDepType() const;
+
UNION_CLASS_BOILERPLATE(OmpDependClause);
EMPTY_CLASS(Source);
WRAPPER_CLASS(Sink, std::list<OmpDependSinkVec>);
@@ -3573,6 +3562,26 @@ struct OmpDependClause {
std::variant<Source, Sink, InOut> u;
};
+// Ref: [5.0:254-255], [5.1:287-288], [5.2:73]
+//
+// destroy-clause ->
+// DESTROY | // since 5.0, until 5.2
+// DESTROY(variable) // since 5.2
+WRAPPER_CLASS(OmpDestroyClause, OmpObject);
+
+// device([ device-modifier :] scalar-integer-expression)
+struct OmpDeviceClause {
+ TUPLE_CLASS_BOILERPLATE(OmpDeviceClause);
+ ENUM_CLASS(DeviceModifier, Ancestor, Device_Num)
+ std::tuple<std::optional<DeviceModifier>, ScalarIntExpr> t;
+};
+
+// device_type(any | host | nohost)
+struct OmpDeviceTypeClause {
+ ENUM_CLASS(Type, Any, Host, Nohost)
+ WRAPPER_CLASS_BOILERPLATE(OmpDeviceTypeClause, Type);
+};
+
// OMP 5.2 12.6.1 grainsize-clause -> grainsize ([prescriptiveness :] value)
struct OmpGrainsizeClause {
TUPLE_CLASS_BOILERPLATE(OmpGrainsizeClause);
@@ -3716,6 +3725,11 @@ struct OmpNumTasksClause {
std::tuple<std::optional<Prescriptiveness>, ScalarIntExpr> t;
};
+// Ref: [5.0:254-255], [5.1:287-288], [5.2:321-322]
+//
+// update-clause -> UPDATE(task-dependence-type) // since 5.0
+WRAPPER_CLASS(OmpUpdateClause, OmpTaskDependenceType);
+
// OpenMP Clauses
struct OmpClause {
UNION_CLASS_BOILERPLATE(OmpClause);
@@ -4023,6 +4037,18 @@ struct OpenMPCancelConstruct {
std::tuple<Verbatim, OmpCancelType, std::optional<If>> t;
};
+// Ref: [5.0:254-255], [5.1:287-288], [5.2:322-323]
+//
+// depobj-construct -> DEPOBJ(depend-object) depobj-clause // since 5.0
+// depobj-clause -> depend-clause | // until 5.2
+// destroy-clause |
+// update-clause
+struct OpenMPDepobjConstruct {
+ TUPLE_CLASS_BOILERPLATE(OpenMPDepobjConstruct);
+ CharBlock source;
+ std::tuple<Verbatim, OmpObject, OmpClause> t;
+};
+
// 2.17.8 flush -> FLUSH [memory-order-clause] [(variable-name-list)]
struct OpenMPFlushConstruct {
TUPLE_CLASS_BOILERPLATE(OpenMPFlushConstruct);
@@ -4047,7 +4073,8 @@ struct OpenMPStandaloneConstruct {
UNION_CLASS_BOILERPLATE(OpenMPStandaloneConstruct);
CharBlock source;
std::variant<OpenMPSimpleStandaloneConstruct, OpenMPFlushConstruct,
- OpenMPCancelConstruct, OpenMPCancellationPointConstruct>
+ OpenMPCancelConstruct, OpenMPCancellationPointConstruct,
+ OpenMPDepobjConstruct>
u;
};
diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h
index 0767d8ea84bc6b..b9512f33eaacd5 100644
--- a/flang/include/flang/Semantics/symbol.h
+++ b/flang/include/flang/Semantics/symbol.h
@@ -755,7 +755,7 @@ class Symbol {
OmpDeclarativeAllocateDirective, OmpExecutableAllocateDirective,
OmpDeclareSimd, OmpDeclareTarget, OmpThreadprivate, OmpDeclareReduction,
OmpFlushed, OmpCriticalLock, OmpIfSpecified, OmpNone, OmpPreDetermined,
- OmpImplicit);
+ OmpImplicit, OmpDependObject);
using Flags = common::EnumSet<Flag, Flag_enumSize>;
const Scope &owner() const { return *owner_; }
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index 7c254ce673855a..8eb1fdb4709178 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -137,6 +137,8 @@ genDependKindAttr(fir::FirOpBuilder &firOpBuilder,
case omp::clause::Depend::TaskDependenceType::Mutexinoutset:
case omp::clause::Depend::TaskDependenceType::Inoutset:
case omp::clause::Depend::TaskDependenceType::Depobj:
+ case omp::clause::Depend::TaskDependenceType::Sink:
+ case omp::clause::Depend::TaskDependenceType::Source:
llvm_unreachable("unhandled parser task dependence type");
break;
}
diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp
index 9483f643acd55a..4fc910ce4c1e78 100644
--- a/flang/lib/Lower/OpenMP/Clauses.cpp
+++ b/flang/lib/Lower/OpenMP/Clauses.cpp
@@ -338,6 +338,27 @@ ReductionOperator makeReductionOperator(const parser::OmpReductionOperator &inp,
inp.u);
}
+clause::TaskDependenceType
+makeDepType(const parser::OmpTaskDependenceType &inp) {
+ switch (inp.v) {
+ case parser::OmpTaskDependenceType::Type::Depobj:
+ return clause::TaskDependenceType::Depobj;
+ case parser::OmpTaskDependenceType::Type::In:
+ return clause::TaskDependenceType::In;
+ case parser::OmpTaskDependenceType::Type::Inout:
+ return clause::TaskDependenceType::Inout;
+ // Inoutset // missing-in-parser
+ // Mutexinoutset // missing-in-parser
+ case parser::OmpTaskDependenceType::Type::Out:
+ return clause::TaskDependenceType::Out;
+ case parser::OmpTaskDependenceType::Type::Sink:
+ return clause::TaskDependenceType::Sink;
+ case parser::OmpTaskDependenceType::Type::Source:
+ return clause::TaskDependenceType::Source;
+ }
+ llvm_unreachable("Unexpected dependence type");
+}
+
// --------------------------------------------------------------------
// Actual clauses. Each T (where tomp::T exists in ClauseT) has its "make".
@@ -554,18 +575,6 @@ Depend make(const parser::OmpClause::Depend &inp,
// Iteration is the equivalent of parser::OmpDependSinkVec
using Iteration = Doacross::Vector::value_type; // LoopIterationT
- CLAUSET_ENUM_CONVERT( //
- convert1, parser::OmpTaskDependenceType::Type, Depend::TaskDependenceType,
- // clang-format off
- MS(In, In)
- MS(Out, Out)
- MS(Inout, Inout)
- // MS(, Mutexinoutset) // missing-in-parser
- // MS(, Inputset) // missing-in-parser
- // MS(, Depobj) // missing-in-parser
- // clang-format on
- );
-
return Depend{Fortran::common::visit( //
common::visitors{
// Doacross
@@ -602,7 +611,7 @@ Depend make(const parser::OmpClause::Depend &inp,
auto &&maybeIter = maybeApply(
[&](auto &&s) { return makeIterator(s, semaCtx); }, t0);
- return Depend::DepType{{/*TaskDependenceType=*/convert1(t1.v),
+ return Depend::DepType{{/*TaskDependenceType=*/makeDepType(t1),
/*Iterator=*/std::move(maybeIter),
/*LocatorList=*/makeObjects(t2, semaCtx)}};
},
@@ -614,8 +623,14 @@ Depend make(const parser::OmpClause::Depend &inp,
Destroy make(const parser::OmpClause::Destroy &inp,
semantics::SemanticsContext &semaCtx) {
- // inp -> empty
- llvm_unreachable("Empty: destroy");
+ // inp.v -> std::optional<OmpDestroyClause>
+ auto &&maybeObject = maybeApply(
+ [&](const parser::OmpDestroyClause &c) {
+ return makeObject(c.v, semaCtx);
+ },
+ inp.v);
+
+ return Destroy{/*DestroyVar=*/std::move(maybeObject)};
}
Detach make(const parser::OmpClause::Detach &inp,
@@ -1279,8 +1294,8 @@ Uniform make(const parser::OmpClause::Uniform &inp,
Update make(const parser::OmpClause::Update &inp,
semantics::SemanticsContext &semaCtx) {
- // inp -> empty
- return Update{/*TaskDependenceType=*/std::nullopt};
+ // inp.v -> parser::OmpUpdateClause
+ return Update{/*TaskDependenceType=*/makeDepType(inp.v.v)};
}
Use make(const parser::OmpClause::Use &inp,
diff --git a/flang/lib/Lower/OpenMP/Clauses.h b/flang/lib/Lower/OpenMP/Clauses.h
index 1e911a20468575..51180ebfe5745e 100644
--- a/flang/lib/Lower/OpenMP/Clauses.h
+++ b/flang/lib/Lower/OpenMP/Clauses.h
@@ -152,6 +152,7 @@ using IteratorSpecifier = tomp::type::IteratorSpecifierT<TypeTy, IdTy, ExprTy>;
using DefinedOperator = tomp::type::DefinedOperatorT<IdTy, ExprTy>;
using ProcedureDesignator = tomp::type::ProcedureDesignatorT<IdTy, ExprTy>;
using ReductionOperator = tomp::type::ReductionIdentifierT<IdTy, ExprTy>;
+using TaskDependenceType = tomp::type::TaskDependenceType;
// "Requires" clauses are handled early on, and the aggregated information
// is stored in the Symbol details of modules, programs, and subprograms.
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 01a40d6e2204ef..954d6b8d122f46 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -2699,6 +2699,21 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
TODO(converter.getCurrentLocation(), "OpenMPCancelConstruct");
}
+static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
+ semantics::SemanticsContext &semaCtx,
+ lower::pft::Evaluation &eval,
+ const parser::OpenMPDepobjConstruct &construct) {
+ // These values will be ignored until the construct itself is implemented,
+ // but run them anyway for the sake of testing (via a Todo test).
+ auto &ompObj = std::get<parser::OmpObject>(construct.t);
+ const Object &depObj = makeObject(ompObj, semaCtx);
+ Clause clause = makeClause(std::get<parser::OmpClause>(construct.t), semaCtx);
+ (void)depObj;
+ (void)clause;
+
+ TODO(converter.getCurrentLocation(), "OpenMPDepobjConstruct");
+}
+
static void
genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 598439cbee87e6..852898c6623dc6 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -366,9 +366,12 @@ TYPE_PARSER(
construct<OmpDependSinkVec>(name, maybe(Parser<OmpDependSinkVecLength>{})))
TYPE_PARSER(construct<OmpTaskDependenceType>(
+ "DEPOBJ" >> pure(OmpTaskDependenceType::Type::Depobj) ||
"IN"_id >> pure(OmpTaskDependenceType::Type::In) ||
"INOUT" >> pure(OmpTaskDependenceType::Type::Inout) ||
- "OUT" >> pure(OmpTaskDependenceType::Type::Out)))
+ "OUT" >> pure(OmpTaskDependenceType::Type::Out) ||
+ "SINK" >> pure(OmpTaskDependenceType::Type::Sink) ||
+ "SOURCE" >> pure(OmpTaskDependenceType::Type::Source)))
TYPE_CONTEXT_PARSER("Omp Depend clause"_en_US,
construct<OmpDependClause>(construct<OmpDependClause::Sink>(
@@ -454,6 +457,9 @@ TYPE_PARSER(
parenthesized(Parser<OmpDefaultmapClause>{}))) ||
"DEPEND" >> construct<OmpClause>(construct<OmpClause::Depend>(
parenthesized(Parser<OmpDependClause>{}))) ||
+ "DESTROY" >> construct<OmpClause>(construct<OmpClause::Destroy>(
+ maybe(parenthesized(construct<OmpDestroyClause>(
+ Parser<OmpObject>{}))))) ||
"DEVICE" >> construct<OmpClause>(construct<OmpClause::Device>(
parenthesized(Parser<OmpDeviceClause>{}))) ||
"DEVICE_TYPE" >> construct<OmpClause>(construct<OmpClause::DeviceType>(
@@ -560,7 +566,9 @@ TYPE_PARSER(
construct<OmpClause>(construct<OmpClause::UnifiedSharedMemory>()) ||
"UNIFORM" >> construct<OmpClause>(construct<OmpClause::Uniform>(
parenthesized(nonemptyList(name)))) ||
- "UNTIED" >> construct<OmpClause>(construct<OmpClause::Untied>()))
+ "UNTIED" >> construct<OmpClause>(construct<OmpClause::Untied>()) ||
+ "UPDATE" >> construct<OmpClause>(construct<OmpClause::Update>(
+ parenthesized(Parser<OmpTaskDependenceType>{}))))
// [Clause, [Clause], ...]
TYPE_PARSER(sourced(construct<OmpClauseList>(
@@ -673,6 +681,9 @@ TYPE_PARSER(sourced(construct<OmpAtomicClause>(
TYPE_PARSER(sourced(construct<OmpAtomicClauseList>(
many(maybe(","_tok) >> sourced(Parser<OmpAtomicClause>{})))))
+TYPE_PARSER(sourced(construct<OpenMPDepobjConstruct>(verbatim("DEPOBJ"_tok),
+ parenthesized(Parser<OmpObject>{}), sourced(Parser<OmpClause>{}))))
+
TYPE_PARSER(sourced(construct<OpenMPFlushConstruct>(verbatim("FLUSH"_tok),
many(maybe(","_tok) >> sourced(Parser<OmpMemoryOrderClause>{})),
maybe(parenthesized(Parser<OmpObjectList>{})))))
@@ -697,7 +708,8 @@ TYPE_PARSER(
construct<OpenMPStandaloneConstruct>(Parser<OpenMPFlushConstruct>{}) ||
construct<OpenMPStandaloneConstruct>(Parser<OpenMPCancelConstruct>{}) ||
construct<OpenMPStandaloneConstruct>(
- Parser<OpenMPCancellationPointConstruct>{})) /
+ Parser<OpenMPCancellationPointConstruct>{}) ||
+ construct<OpenMPStandaloneConstruct>(Parser<OpenMPDepobjConstruct>{})) /
endOfLine)
// Directives enclosing structured-block
diff --git a/flang/lib/Parser/parse-tree.cpp b/flang/lib/Parser/parse-tree.cpp
index 948ad04a091a8c..60aef1666e9ba7 100644
--- a/flang/lib/Parser/parse-tree.cpp
+++ b/flang/lib/Parser/parse-tree.cpp
@@ -252,6 +252,23 @@ CharBlock Variable::GetSource() const {
llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const Name &x) {
return os << x.ToString();
}
+
+OmpTaskDependenceType::Type OmpDependClause::GetDepType() const {
+ return common::visit(
+ common::visitors{
+ [&](const parser::OmpDependClause::Source &) {
+ return parser::OmpTaskDependenceType::Type::Source;
+ },
+ [&](const parser::OmpDependClause::Sink &) {
+ return parser::OmpTaskDependenceType::Type::Sink;
+ },
+ [&](const parser::OmpDependClause::InOut &y) {
+ return std::get<parser::OmpTaskDependenceType>(y.t).v;
+ },
+ },
+ u);
+}
+
} // namespace Fortran::parser
template <typename C> static llvm::omp::Clause getClauseIdForClass(C &&) {
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 39fcb61609e33b..32fe530e16f634 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2215,11 +2215,9 @@ class UnparseVisitor {
Walk(std::get<std::optional<OmpDependSinkVecLength>>(x.t));
}
void Unparse(const OmpDependClause::InOut &x) {
- Put("(");
Walk(std::get<OmpTaskDependenceType>(x.t));
Put(":");
Walk(std::get<OmpObjectList>(x.t));
- Put(")");
}
bool Pre(const OmpDependClause &x) {
return common::visit(
@@ -2706,6 +2704,16 @@ class UnparseVisitor {
},
x.u);
}
+ void Unparse(const OpenMPDepobjConstruct &x) {
+ BeginOpenMP();
+ Word("!$OMP DEPOBJ");
+ Put("(");
+ Walk(std::get<OmpObject>(x.t));
+ Put(") ");
+ Walk(std::get<OmpClause>(x.t));
+ Put("\n");
+ EndOpenMP();
+ }
void Unparse(const OpenMPFlushConstruct &x) {
BeginOpenMP();
Word("!$OMP FLUSH ");
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 8f3eb9fefee678..64c2254b277502 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1261,6 +1261,39 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareSimdConstruct &) {
dirContext_.pop_back();
}
+void OmpStructureChecker::Enter(const parser::OpenMPDepobjConstruct &x) {
+ const auto &dir{std::get<parser::Verbatim>(x.t)};
+ PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_depobj);
+
+ // [5.2:73:27-28]
+ // If the destroy clause appears on a depobj construct, destroy-var must
+ // refer to the same depend object as the depobj argument of the construct.
+ auto &clause{std::get<parser::OmpClause>(x.t)};
+ if (clause.Id() == llvm::omp::Clause::OMPC_destroy) {
+ auto getSymbol = [&](const parser::OmpObject &obj) {
+ return common::visit(
+ [&](auto &&s) { return GetLastName(s).symbol; }, obj.u);
+ };
+
+ auto &wrapper{std::get<parser::OmpClause::Destroy>(clause.u)};
+ if (const std::optional<parser::OmpDestroyClause> &destroy{wrapper.v}) {
+ const Symbol *constrSym = getSymbol(std::get<parser::OmpObject>(x.t));
+ const Symbol *clauseSym = getSymbol(destroy->v);
+ assert(constrSym && "Unresolved depobj construct symbol");
+ assert(clauseSym && "Unresolved destroy symbol on depobj construct");
+ if (constrSym != clauseSym) {
+ context_.Say(x.source,
+ "The DESTROY clause must refer to the same object as the "
+ "DEPOBJ construct"_err_en_US);
+ }
+ }
+ }
+}
+
+void OmpStructureChecker::Leave(const parser::OpenMPDepobjConstruct &x) {
+ dirContext_.pop_back();
+}
+
void OmpStructureChecker::Enter(const parser::OpenMPRequiresConstruct &x) {
const auto &dir{std::get<parser::Verbatim>(x.t)};
PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_requires);
@@ -2476,7 +2509,6 @@ CHECK_SIMPLE_CLAUSE(Capture, OMPC_capture)
CHECK_SIMPLE_CLAUSE(Contains, OMPC_contains)
CHECK_SIMPLE_CLAUSE(Default, OMPC_default)
CHECK_SIMPLE_CLAUSE(Depobj, OMPC_depobj)
-CHECK_SIMPLE_CLAUSE(Destroy, OMPC_destroy)
CHECK_SIMPLE_CLAUSE(Detach, OMPC_detach)
CHECK_SIMPLE_CLAUSE(DeviceType, OMPC_device_type)
CHECK_SIMPLE_CLAUSE(DistSchedule, OMPC_dist_schedule)
@@ -2519,7 +2551,6 @@ CHECK_SIMPLE_CLAUSE(Uniform, OMPC_uniform)
CHECK_SIMPLE_CLAUSE(Unknown, OMPC_unknown)
CHECK_SIMPLE_CLAUSE(Untied, OMPC_untied)
CHECK_SIMPLE_CLAUSE(UsesAllocators, OMPC_uses_allocators)
-CHECK_SIMPLE_CLAUSE(Update, OMPC_update)
CHECK_SIMPLE_CLAUSE(Write, OMPC_write)
CHECK_SIMPLE_CLAUSE(Init, OMPC_init)
CHECK_SIMPLE_CLAUSE(Use, OMPC_use)
@@ -2555,6 +2586,22 @@ CHECK_REQ_CONSTANT_SCALAR_INT_CLAUSE(Simdlen, OMPC_simdlen)
// Restrictions specific to each clause are implemented apart from the
// generalized restrictions.
+
+void OmpStructureChecker::Enter(const parser::OmpClause::Destroy &x) {
+ CheckAllowedClause(llvm::omp::Clause::OMPC_destroy);
+
+ llvm::omp::Directive dir{GetContext().directive};
+ unsigned version{context_.langOptions().OpenMPVersion};
+ if (dir == llvm::omp::Directive::OMPD_depobj) {
+ if (version < 52) {
+...
[truncated]
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LG. Thanks for the patch.
const Symbol *constrSym = getSymbol(std::get<parser::OmpObject>(x.t)); | ||
const Symbol *clauseSym = getSymbol(destroy->v); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: braced initialization in fronted.
Parse the DEPOBJ construct and the associated clauses, perform basic semantic checks.