-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[flang][OpenMP] Use OmpDirectiveSpecification in standalone directives #131163
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
Conversation
The `OmpDirectiveSpecification` contains directive name, the list of arguments, and the list of clauses. It was introduced to store the directive specification in METADIRECTIVE, and could be reused everywhere a directive representation is needed. In the long term this would unify the handling of common directive properties, as well as creating actual constructs from METADIRECTIVE by linking the contained directive specification with any associated user code.
This uses OmpDirectiveSpecification in the rest of the standalone directives.
@llvm/pr-subscribers-flang-fir-hlfir @llvm/pr-subscribers-flang-semantics Author: Krzysztof Parzyszek (kparzysz) ChangesThis uses OmpDirectiveSpecification in the rest of the standalone directives. Patch is 38.80 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/131163.diff 16 Files Affected:
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 118df6cf2a4ff..9bff2dab974ec 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -484,6 +484,7 @@ class ParseTreeDumper {
NODE(parser, OmpLocatorList)
NODE(parser, OmpReductionSpecifier)
NODE(parser, OmpArgument)
+ NODE(parser, OmpArgumentList)
NODE(parser, OmpMetadirectiveDirective)
NODE(parser, OmpMatchClause)
NODE(parser, OmpOtherwiseClause)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index dfde4ceb787d2..a31018c9abc09 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3557,6 +3557,11 @@ struct OmpArgument {
OmpMapperSpecifier, OmpReductionSpecifier>
u;
};
+
+struct OmpArgumentList {
+ WRAPPER_CLASS_BOILERPLATE(OmpArgumentList, std::list<OmpArgument>);
+ CharBlock source;
+};
} // namespace arguments
inline namespace traits {
@@ -4511,10 +4516,11 @@ struct OmpDirectiveSpecification {
llvm::omp::Directive DirId() const { //
return std::get<OmpDirectiveName>(t).v;
}
+ const OmpArgumentList &Arguments() const;
const OmpClauseList &Clauses() const;
CharBlock source;
- std::tuple<OmpDirectiveName, std::optional<std::list<OmpArgument>>,
+ std::tuple<OmpDirectiveName, std::optional<OmpArgumentList>,
std::optional<OmpClauseList>, Flags>
t;
};
@@ -4865,16 +4871,15 @@ struct OmpLoopDirective {
// 2.14.2 cancellation-point -> CANCELLATION POINT construct-type-clause
struct OpenMPCancellationPointConstruct {
- TUPLE_CLASS_BOILERPLATE(OpenMPCancellationPointConstruct);
+ WRAPPER_CLASS_BOILERPLATE(OpenMPCancellationPointConstruct,
+ OmpDirectiveSpecification);
CharBlock source;
- std::tuple<Verbatim, OmpClauseList> t;
};
// 2.14.1 cancel -> CANCEL construct-type-clause [ [,] if-clause]
struct OpenMPCancelConstruct {
- TUPLE_CLASS_BOILERPLATE(OpenMPCancelConstruct);
+ WRAPPER_CLASS_BOILERPLATE(OpenMPCancelConstruct, OmpDirectiveSpecification);
CharBlock source;
- std::tuple<Verbatim, OmpClauseList> t;
};
// Ref: [5.0:254-255], [5.1:287-288], [5.2:322-323]
@@ -4884,9 +4889,8 @@ struct OpenMPCancelConstruct {
// destroy-clause |
// update-clause
struct OpenMPDepobjConstruct {
- TUPLE_CLASS_BOILERPLATE(OpenMPDepobjConstruct);
+ WRAPPER_CLASS_BOILERPLATE(OpenMPDepobjConstruct, OmpDirectiveSpecification);
CharBlock source;
- std::tuple<Verbatim, OmpObject, OmpClause> t;
};
// Ref: [5.2: 200-201]
@@ -4927,11 +4931,8 @@ struct OpenMPDispatchConstruct {
// ACQ_REL | RELEASE | ACQUIRE | // since 5.0
// SEQ_CST // since 5.1
struct OpenMPFlushConstruct {
- TUPLE_CLASS_BOILERPLATE(OpenMPFlushConstruct);
+ WRAPPER_CLASS_BOILERPLATE(OpenMPFlushConstruct, OmpDirectiveSpecification);
CharBlock source;
- std::tuple<Verbatim, std::optional<OmpObjectList>,
- std::optional<OmpClauseList>, /*TrailingClauses=*/bool>
- t;
};
struct OpenMPSimpleStandaloneConstruct {
diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp
index 9fa9abd9e8ceb..7ad6f7f3da00a 100644
--- a/flang/lib/Lower/OpenMP/Clauses.cpp
+++ b/flang/lib/Lower/OpenMP/Clauses.cpp
@@ -132,6 +132,25 @@ Object makeObject(const parser::OmpObject &object,
return makeObject(std::get<parser::Designator>(object.u), semaCtx);
}
+ObjectList makeObjects(const parser::OmpArgumentList &objects,
+ semantics::SemanticsContext &semaCtx) {
+ return makeList(objects.v, [&](const parser::OmpArgument &arg) {
+ return common::visit(
+ common::visitors{
+ [&](const parser::OmpLocator &locator) -> Object {
+ if (auto *object = std::get_if<parser::OmpObject>(&locator.u)) {
+ return makeObject(*object, semaCtx);
+ }
+ llvm_unreachable("Expecting object");
+ },
+ [](auto &&s) -> Object { //
+ llvm_unreachable("Expecting object");
+ },
+ },
+ arg.u);
+ });
+}
+
std::optional<Object> getBaseObject(const Object &object,
semantics::SemanticsContext &semaCtx) {
// If it's just the symbol, then there is no base.
diff --git a/flang/lib/Lower/OpenMP/Clauses.h b/flang/lib/Lower/OpenMP/Clauses.h
index fe453eb05cde2..e0a642036a58f 100644
--- a/flang/lib/Lower/OpenMP/Clauses.h
+++ b/flang/lib/Lower/OpenMP/Clauses.h
@@ -143,6 +143,9 @@ inline ObjectList makeObjects(const parser::OmpObjectList &objects,
return makeList(objects.v, makeObjectFn(semaCtx));
}
+ObjectList makeObjects(const parser::OmpArgumentList &objects,
+ semantics::SemanticsContext &semaCtx);
+
template <typename FuncTy, //
typename ArgTy, //
typename ResultTy = std::invoke_result_t<FuncTy, ArgTy>>
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 6b50ad733fef4..fc347fa34c66d 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -3310,22 +3310,16 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx,
lower::pft::Evaluation &eval,
- const parser::OpenMPFlushConstruct &flushConstruct) {
- const auto &verbatim = std::get<parser::Verbatim>(flushConstruct.t);
- const auto &objectList =
- std::get<std::optional<parser::OmpObjectList>>(flushConstruct.t);
- const auto &clauseList =
- std::get<std::optional<parser::OmpClauseList>>(flushConstruct.t);
- ObjectList objects =
- objectList ? makeObjects(*objectList, semaCtx) : ObjectList{};
+ const parser::OpenMPFlushConstruct &construct) {
+ const auto &argumentList = construct.v.Arguments();
+ const auto &clauseList = construct.v.Clauses();
+ ObjectList objects = makeObjects(argumentList, semaCtx);
List<Clause> clauses =
- clauseList ? makeList(clauseList->v,
- [&](auto &&s) { return makeClause(s, semaCtx); })
- : List<Clause>{};
- mlir::Location currentLocation = converter.genLocation(verbatim.source);
+ makeList(clauseList.v, [&](auto &&s) { return makeClause(s, semaCtx); });
+ mlir::Location currentLocation = converter.genLocation(construct.source);
ConstructQueue queue{buildConstructQueue(
- converter.getFirOpBuilder().getModule(), semaCtx, eval, verbatim.source,
+ converter.getFirOpBuilder().getModule(), semaCtx, eval, construct.source,
llvm::omp::Directive::OMPD_flush, clauses)};
genFlushOp(converter, symTable, semaCtx, eval, currentLocation, objects,
queue, queue.begin());
@@ -3352,11 +3346,12 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
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;
+ ObjectList objects = makeObjects(construct.v.Arguments(), semaCtx);
+ assert(objects.size() == 1);
+ List<Clause> clauses = makeClauses(construct.v.Clauses(), semaCtx);
+ assert(clauses.size() == 1);
+ (void)objects;
+ (void)clauses;
TODO(converter.getCurrentLocation(), "OpenMPDepobjConstruct");
}
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 2d88571cd0090..a1c2f48145706 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -231,6 +231,9 @@ TYPE_PARSER(sourced( //
TYPE_PARSER(construct<OmpLocatorList>(nonemptyList(Parser<OmpLocator>{})))
+TYPE_PARSER(sourced( //
+ construct<OmpArgumentList>(nonemptyList(Parser<OmpArgument>{}))))
+
TYPE_PARSER( //
construct<OmpTypeSpecifier>(Parser<DeclarationTypeSpec>{}) ||
construct<OmpTypeSpecifier>(Parser<TypeSpec>{}))
@@ -1052,9 +1055,9 @@ TYPE_PARSER(sourced(construct<OmpErrorDirective>(
TYPE_PARSER(sourced(construct<OmpDirectiveName>(OmpDirectiveNameParser{})))
-OmpDirectiveSpecification static makeFlushFromOldSyntax1(Verbatim &&text,
+OmpDirectiveSpecification static makeFlushFromOldSyntax(Verbatim &&text,
std::optional<OmpClauseList> &&clauses,
- std::optional<std::list<OmpArgument>> &&args,
+ std::optional<OmpArgumentList> &&args,
OmpDirectiveSpecification::Flags &&flags) {
return OmpDirectiveSpecification{OmpDirectiveName(text), std::move(args),
std::move(clauses), std::move(flags)};
@@ -1068,15 +1071,15 @@ TYPE_PARSER(sourced(
// lists absent in the parsed result.
// E.g. for FLUSH(x) SEQ_CST it would find no clauses following
// the directive name, parse the argument list "(x)" and stop.
- applyFunction<OmpDirectiveSpecification>(makeFlushFromOldSyntax1,
+ applyFunction<OmpDirectiveSpecification>(makeFlushFromOldSyntax,
verbatim("FLUSH"_tok) / !lookAhead("("_tok),
maybe(Parser<OmpClauseList>{}),
- maybe(parenthesized(nonemptyList(Parser<OmpArgument>{}))),
+ maybe(parenthesized(Parser<OmpArgumentList>{})),
pure(OmpDirectiveSpecification::Flags::DeprecatedSyntax))) ||
// Parse the standard syntax: directive [(arguments)] [clauses]
construct<OmpDirectiveSpecification>( //
sourced(OmpDirectiveNameParser{}),
- maybe(parenthesized(nonemptyList(Parser<OmpArgument>{}))),
+ maybe(parenthesized(Parser<OmpArgumentList>{})),
maybe(Parser<OmpClauseList>{}),
pure(OmpDirectiveSpecification::Flags::None))))
@@ -1152,14 +1155,6 @@ TYPE_PARSER(sourced(construct<OmpLoopDirective>(first(
TYPE_PARSER(sourced(construct<OmpBeginLoopDirective>(
sourced(Parser<OmpLoopDirective>{}), Parser<OmpClauseList>{})))
-// 2.14.2 Cancellation Point construct
-TYPE_PARSER(sourced(construct<OpenMPCancellationPointConstruct>(
- verbatim("CANCELLATION POINT"_tok), Parser<OmpClauseList>{})))
-
-// 2.14.1 Cancel construct
-TYPE_PARSER(sourced(construct<OpenMPCancelConstruct>(
- verbatim("CANCEL"_tok), Parser<OmpClauseList>{})))
-
TYPE_PARSER(sourced(construct<OmpFailClause>(
parenthesized(indirect(Parser<OmpMemoryOrderClause>{})))))
@@ -1200,29 +1195,6 @@ 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>{}))))
-
-static OpenMPFlushConstruct makeFlushFromOldSyntax(Verbatim &&text,
- std::optional<OmpClauseList> &&clauses,
- std::optional<OmpObjectList> &&objects) {
- bool oldSyntax{
- clauses && !clauses->v.empty() && objects && !objects->v.empty()};
- return OpenMPFlushConstruct{std::move(text), std::move(objects),
- std::move(clauses),
- /*TrailingClauses=*/!oldSyntax};
-}
-
-TYPE_PARSER(sourced( //
- construct<OpenMPFlushConstruct>( //
- applyFunction<OpenMPFlushConstruct>(makeFlushFromOldSyntax,
- verbatim("FLUSH"_tok), maybe(Parser<OmpClauseList>{}),
- maybe(parenthesized(Parser<OmpObjectList>{})))) ||
-
- construct<OpenMPFlushConstruct>( //
- verbatim("FLUSH"_tok), maybe(parenthesized(Parser<OmpObjectList>{})),
- Parser<OmpClauseList>{}, pure(/*TrailingClauses=*/true))))
-
static bool IsSimpleStandalone(const OmpDirectiveName &name) {
switch (name.v) {
case llvm::omp::Directive::OMPD_barrier:
@@ -1244,6 +1216,36 @@ TYPE_PARSER(sourced( //
predicated(OmpDirectiveNameParser{}, IsSimpleStandalone) >=
Parser<OmpDirectiveSpecification>{})))
+static inline constexpr auto IsDirective(llvm::omp::Directive dir) {
+ return [dir](const OmpDirectiveName &name) -> bool { return dir == name.v; };
+}
+
+TYPE_PARSER(sourced( //
+ construct<OpenMPFlushConstruct>(
+ predicated(OmpDirectiveNameParser{},
+ IsDirective(llvm::omp::Directive::OMPD_flush)) >=
+ Parser<OmpDirectiveSpecification>{})))
+
+// 2.14.2 Cancellation Point construct
+TYPE_PARSER(sourced( //
+ construct<OpenMPCancellationPointConstruct>(
+ predicated(OmpDirectiveNameParser{},
+ IsDirective(llvm::omp::Directive::OMPD_cancellation_point)) >=
+ Parser<OmpDirectiveSpecification>{})))
+
+// 2.14.1 Cancel construct
+TYPE_PARSER(sourced( //
+ construct<OpenMPCancelConstruct>(
+ predicated(OmpDirectiveNameParser{},
+ IsDirective(llvm::omp::Directive::OMPD_cancel)) >=
+ Parser<OmpDirectiveSpecification>{})))
+
+TYPE_PARSER(sourced( //
+ construct<OpenMPDepobjConstruct>(
+ predicated(OmpDirectiveNameParser{},
+ IsDirective(llvm::omp::Directive::OMPD_depobj)) >=
+ Parser<OmpDirectiveSpecification>{})))
+
// Standalone Constructs
TYPE_PARSER(
sourced( //
diff --git a/flang/lib/Parser/parse-tree.cpp b/flang/lib/Parser/parse-tree.cpp
index 5917f30b3c589..5839e7862b38b 100644
--- a/flang/lib/Parser/parse-tree.cpp
+++ b/flang/lib/Parser/parse-tree.cpp
@@ -337,6 +337,14 @@ llvm::omp::Clause OmpClause::Id() const {
return std::visit([](auto &&s) { return getClauseIdForClass(s); }, u);
}
+const OmpArgumentList &OmpDirectiveSpecification::Arguments() const {
+ static OmpArgumentList empty{decltype(OmpArgumentList::v){}};
+ if (auto &arguments = std::get<std::optional<OmpArgumentList>>(t)) {
+ return *arguments;
+ }
+ return empty;
+}
+
const OmpClauseList &OmpDirectiveSpecification::Clauses() const {
static OmpClauseList empty{decltype(OmpClauseList::v){}};
if (auto &clauses = std::get<std::optional<OmpClauseList>>(t)) {
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 98e02d4f02b9c..9c85f4ec87a15 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2075,6 +2075,8 @@ class UnparseVisitor {
}
// OpenMP Clauses & Directives
+ void Unparse(const OmpArgumentList &x) { Walk(x.v, ", "); }
+
void Unparse(const OmpTypeNameList &x) { //
Walk(x.v, ",");
}
@@ -2095,8 +2097,7 @@ class UnparseVisitor {
}
void Unparse(const OmpDirectiveSpecification &x) {
auto unparseArgs{[&]() {
- using ArgList = std::list<parser::OmpArgument>;
- if (auto &args{std::get<std::optional<ArgList>>(x.t)}) {
+ if (auto &args{std::get<std::optional<OmpArgumentList>>(x.t)}) {
Put("(");
Walk(*args);
Put(")");
@@ -2823,15 +2824,15 @@ class UnparseVisitor {
}
void Unparse(const OpenMPCancellationPointConstruct &x) {
BeginOpenMP();
- Word("!$OMP CANCELLATION POINT ");
- Walk(std::get<OmpClauseList>(x.t));
+ Word("!$OMP ");
+ Walk(x.v);
Put("\n");
EndOpenMP();
}
void Unparse(const OpenMPCancelConstruct &x) {
BeginOpenMP();
- Word("!$OMP CANCEL ");
- Walk(std::get<OmpClauseList>(x.t));
+ Word("!$OMP ");
+ Walk(x.v);
Put("\n");
EndOpenMP();
}
@@ -2859,22 +2860,21 @@ class UnparseVisitor {
void Unparse(const OpenMPDepobjConstruct &x) {
BeginOpenMP();
Word("!$OMP DEPOBJ");
- Put("(");
- Walk(std::get<OmpObject>(x.t));
- Put(") ");
- Walk(std::get<OmpClause>(x.t));
+ Walk("(", std::get<std::optional<OmpArgumentList>>(x.v.t), ")");
+ Walk(" ", std::get<std::optional<OmpClauseList>>(x.v.t));
Put("\n");
EndOpenMP();
}
void Unparse(const OpenMPFlushConstruct &x) {
BeginOpenMP();
Word("!$OMP FLUSH");
- if (std::get</*ClausesTrailing=*/bool>(x.t)) {
- Walk("(", std::get<std::optional<OmpObjectList>>(x.t), ")");
- Walk(" ", std::get<std::optional<OmpClauseList>>(x.t));
+ using Flags = OmpDirectiveSpecification::Flags;
+ if (std::get<Flags>(x.v.t) == Flags::DeprecatedSyntax) {
+ Walk("(", std::get<std::optional<OmpArgumentList>>(x.v.t), ")");
+ Walk(" ", std::get<std::optional<OmpClauseList>>(x.v.t));
} else {
- Walk(" ", std::get<std::optional<OmpClauseList>>(x.t));
- Walk(" (", std::get<std::optional<OmpObjectList>>(x.t), ")");
+ Walk(" ", std::get<std::optional<OmpClauseList>>(x.v.t));
+ Walk(" (", std::get<std::optional<OmpArgumentList>>(x.v.t), ")");
}
Put("\n");
EndOpenMP();
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index c255d1c35ecf7..8a8dc5e571385 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1601,23 +1601,58 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareSimdConstruct &) {
}
void OmpStructureChecker::Enter(const parser::OpenMPDepobjConstruct &x) {
- const auto &dir{std::get<parser::Verbatim>(x.t)};
- PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_depobj);
+ const auto &dirName{std::get<parser::OmpDirectiveName>(x.v.t)};
+ PushContextAndClauseSets(dirName.source, llvm::omp::Directive::OMPD_depobj);
+ unsigned version{context_.langOptions().OpenMPVersion};
+
+ const parser::OmpArgumentList &arguments{x.v.Arguments()};
+ const parser::OmpClauseList &clauses{x.v.Clauses()};
+
+ // Ref: [6.0:505-506]
+
+ if (version < 60) {
+ if (arguments.v.size() != 1) {
+ parser::CharBlock source(
+ arguments.v.empty() ? dirName.source : arguments.source);
+ context_.Say(source,
+ "The DEPOBJ directive requires a single argument"_err_en_US);
+ }
+ }
+ if (clauses.v.size() != 1) {
+ context_.Say(
+ x.source, "The DEPOBJ construct requires a single clause"_err_en_US);
+ return;
+ }
+
+ auto &clause{clauses.v.front()};
+
+ if (version >= 60 && arguments.v.empty()) {
+ context_.Say(x.source,
+ "DEPOBJ syntax with no argument is not handled yet"_err_en_US);
+ return;
+ }
// [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) {
+ auto getObjSymbol{[&](const parser::OmpObject &obj) {
return common::visit(
[&](auto &&s) { return GetLastName(s).symbol; }, obj.u);
}};
+ auto getArgSymbol{[&](const parser::OmpArgument &arg) {
+ if (auto *locator{std::get_if<parser::OmpLocator>(&arg.u)}) {
+ if (auto *object{std::get_if<parser::OmpObject>(&locator->u)}) {
+ return getObjSymbol(*object);
+ }
+ }
+ return static_cast<Symbol *>(nullptr);
+ }};
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)};
+ const Symbol *constrSym{getArgSymbol(arguments.v.front())};
+ const Symbol *clauseSym{getObjSymbol(destroy->v)};
assert(constrSym && "Unresolved depobj construct symbol");
assert(clauseSym && "Unresolved destroy symbol on depobj construct");
if (constrSym != clauseSym) {
@@ -2210,27 +2245,34 @@ void OmpStructureChecker::Leave(
}
void OmpStructureChecker::Enter(const parser::OpenMPFlushConstruct &x) {
- const auto &dir{std::get<parser::Verbatim>(x.t)};
- PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_flush);
+ const auto &dirName{std::get<parser::OmpDirectiveName>(x.v.t)};
+ PushContextAndClauseSets(dirName.source, llvm::omp::Directive::OMPD_flush);
}
void OmpStructureChecker::Leave(const parser::OpenMPFlushConstruct &x) {
- auto &flushList{std::get<std::optional<parser::OmpObjectList>>(x.t)};
+ auto &flushList{std::get<std::optional<parser::OmpArgumentList>>(x.v.t)};
- if (FindClause(llvm::omp::Clause::OMPC_acquire) ||
- ...
[truncated]
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
Prev PR: #131162 |
…arzysz/spr/s02-standalone
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.
LGTM, thanks for the work!
This uses OmpDirectiveSpecification in the rest of the standalone directives.