[llvm-branch-commits] [flang] [flang][OpenMP] Resolve all components of OmpDirectiveSpecification (PR #159946)
Krzysztof Parzyszek via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Sep 22 11:05:27 PDT 2025
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/159946
>From e0ae3e5dd4817329f0e104e0ea7fd883754f442f Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Sat, 20 Sep 2025 09:58:43 -0500
Subject: [PATCH 1/2] [flang][OpenMP] Resolve all components of
OmpDirectiveSpecification
Fully resolve all arguments and clauses in OmpDirectiveSpecification
instead of just looking for special cases. Delegate resolution from
nodes that inherit from ODS to use the ODS resolution.
---
flang/lib/Semantics/resolve-names.cpp | 129 +++++++++++++-------------
1 file changed, 62 insertions(+), 67 deletions(-)
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 13edb118a3286..5dd0e1fd5072e 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1486,34 +1486,16 @@ class OmpVisitor : public virtual DeclarationVisitor {
bool Pre(const parser::OmpBlockConstruct &);
void Post(const parser::OmpBlockConstruct &);
bool Pre(const parser::OmpBeginDirective &x) {
- AddOmpSourceRange(x.source);
- // Manually resolve names in CRITICAL directives. This is because these
- // names do not denote Fortran objects, and the CRITICAL directive causes
- // them to be "auto-declared", i.e. inserted into the global scope.
- // More specifically, they are not expected to have explicit declarations,
- // and if they do the behavior is unspeficied.
- if (x.DirName().v == llvm::omp::Directive::OMPD_critical) {
- for (const parser::OmpArgument &arg : x.Arguments().v) {
- ResolveCriticalName(arg);
- }
- }
- return true;
+ return Pre(static_cast<const parser::OmpDirectiveSpecification &>(x));
}
- void Post(const parser::OmpBeginDirective &) {
- messageHandler().set_currStmtSource(std::nullopt);
+ void Post(const parser::OmpBeginDirective &x) {
+ Post(static_cast<const parser::OmpDirectiveSpecification &>(x));
}
bool Pre(const parser::OmpEndDirective &x) {
- AddOmpSourceRange(x.source);
- // Manually resolve names in CRITICAL directives.
- if (x.DirName().v == llvm::omp::Directive::OMPD_critical) {
- for (const parser::OmpArgument &arg : x.Arguments().v) {
- ResolveCriticalName(arg);
- }
- }
- return true;
+ return Pre(static_cast<const parser::OmpDirectiveSpecification &>(x));
}
- void Post(const parser::OmpEndDirective &) {
- messageHandler().set_currStmtSource(std::nullopt);
+ void Post(const parser::OmpEndDirective &x) {
+ Post(static_cast<const parser::OmpDirectiveSpecification &>(x));
}
bool Pre(const parser::OpenMPLoopConstruct &) {
@@ -1522,8 +1504,16 @@ class OmpVisitor : public virtual DeclarationVisitor {
}
void Post(const parser::OpenMPLoopConstruct &) { PopScope(); }
bool Pre(const parser::OmpBeginLoopDirective &x) {
- AddOmpSourceRange(x.source);
- return true;
+ return Pre(static_cast<const parser::OmpDirectiveSpecification &>(x));
+ }
+ void Post(const parser::OmpBeginLoopDirective &x) {
+ Post(static_cast<const parser::OmpDirectiveSpecification &>(x));
+ }
+ bool Pre(const parser::OmpEndLoopDirective &x) {
+ return Pre(static_cast<const parser::OmpDirectiveSpecification &>(x));
+ }
+ void Post(const parser::OmpEndLoopDirective &x) {
+ Post(static_cast<const parser::OmpDirectiveSpecification &>(x));
}
bool Pre(const parser::OpenMPDeclareMapperConstruct &x) {
@@ -1580,35 +1570,22 @@ class OmpVisitor : public virtual DeclarationVisitor {
}
bool Pre(const parser::OmpMapClause &);
- void Post(const parser::OmpBeginLoopDirective &) {
- messageHandler().set_currStmtSource(std::nullopt);
- }
- bool Pre(const parser::OmpEndLoopDirective &x) {
- AddOmpSourceRange(x.source);
- return true;
- }
- void Post(const parser::OmpEndLoopDirective &) {
- messageHandler().set_currStmtSource(std::nullopt);
- }
-
bool Pre(const parser::OpenMPSectionsConstruct &) {
PushScope(Scope::Kind::OtherConstruct, nullptr);
return true;
}
void Post(const parser::OpenMPSectionsConstruct &) { PopScope(); }
bool Pre(const parser::OmpBeginSectionsDirective &x) {
- AddOmpSourceRange(x.source);
- return true;
+ return Pre(static_cast<const parser::OmpDirectiveSpecification &>(x));
}
- void Post(const parser::OmpBeginSectionsDirective &) {
- messageHandler().set_currStmtSource(std::nullopt);
+ void Post(const parser::OmpBeginSectionsDirective &x) {
+ Post(static_cast<const parser::OmpDirectiveSpecification &>(x));
}
bool Pre(const parser::OmpEndSectionsDirective &x) {
- AddOmpSourceRange(x.source);
- return true;
+ return Pre(static_cast<const parser::OmpDirectiveSpecification &>(x));
}
- void Post(const parser::OmpEndSectionsDirective &) {
- messageHandler().set_currStmtSource(std::nullopt);
+ void Post(const parser::OmpEndSectionsDirective &x) {
+ Post(static_cast<const parser::OmpDirectiveSpecification &>(x));
}
bool Pre(const parser::OpenMPThreadprivate &) {
SkipImplicitTyping(true);
@@ -1710,6 +1687,9 @@ class OmpVisitor : public virtual DeclarationVisitor {
}
}
bool Pre(const parser::OmpDirectiveSpecification &x);
+ void Post(const parser::OmpDirectiveSpecification &) {
+ messageHandler().set_currStmtSource(std::nullopt);
+ }
bool Pre(const parser::OmpTypeSpecifier &x) {
BeginDeclTypeSpec();
@@ -1719,6 +1699,16 @@ class OmpVisitor : public virtual DeclarationVisitor {
EndDeclTypeSpec();
}
+ bool Pre(const parser::OpenMPConstruct &x) {
+ // Indicate that the current directive is not a declarative one.
+ declaratives_.push_back(nullptr);
+ return true;
+ }
+ void Post(const parser::OpenMPConstruct &) {
+ // Pop the null pointer.
+ declaratives_.pop_back();
+ }
+
private:
void ProcessMapperSpecifier(const parser::OmpMapperSpecifier &spec,
const parser::OmpClauseList &clauses);
@@ -1987,29 +1977,34 @@ bool OmpVisitor::Pre(const parser::OmpDirectiveSpecification &x) {
const parser::OmpArgumentList &args{x.Arguments()};
const parser::OmpClauseList &clauses{x.Clauses()};
- switch (x.DirId()) {
- case llvm::omp::Directive::OMPD_declare_mapper:
- if (!args.v.empty()) {
- const parser::OmpArgument &first{args.v.front()};
- if (auto *spec{std::get_if<parser::OmpMapperSpecifier>(&first.u)}) {
- ProcessMapperSpecifier(*spec, clauses);
- }
- }
- break;
- case llvm::omp::Directive::OMPD_declare_reduction:
- if (!args.v.empty()) {
- const parser::OmpArgument &first{args.v.front()};
- if (auto *spec{std::get_if<parser::OmpReductionSpecifier>(&first.u)}) {
- ProcessReductionSpecifier(*spec, clauses, declaratives_.back());
- }
- }
- break;
- default:
- // Default processing.
- Walk(args);
- Walk(clauses);
- break;
+ for (const parser::OmpArgument &arg : args.v) {
+ common::visit( //
+ common::visitors{
+ [&](const parser::OmpMapperSpecifier &spec) {
+ ProcessMapperSpecifier(spec, clauses);
+ },
+ [&](const parser::OmpReductionSpecifier &spec) {
+ ProcessReductionSpecifier(spec, clauses, declaratives_.back());
+ },
+ [&](const parser::OmpLocator &locator) {
+ // Manually resolve names in CRITICAL directives. This is because
+ // these names do not denote Fortran objects, and the CRITICAL
+ // directive causes them to be "auto-declared", i.e. inserted into
+ // the global scope. More specifically, they are not expected to
+ // have explicit declarations, and if they do the behavior is
+ // unspeficied.
+ if (x.DirId() == llvm::omp::Directive::OMPD_critical) {
+ ResolveCriticalName(arg);
+ } else {
+ Walk(locator);
+ }
+ },
+ },
+ arg.u);
}
+
+ Walk(clauses);
+
return false;
}
>From bc7d5988383d6404b786013f05fe890a92bcf06c Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Mon, 22 Sep 2025 13:05:06 -0500
Subject: [PATCH 2/2] Don't walk clauses twice
---
flang/lib/Semantics/resolve-names.cpp | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 5dd0e1fd5072e..358bec20f243c 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1976,15 +1976,18 @@ bool OmpVisitor::Pre(const parser::OmpDirectiveSpecification &x) {
const parser::OmpArgumentList &args{x.Arguments()};
const parser::OmpClauseList &clauses{x.Clauses()};
+ bool visitClauses{true};
for (const parser::OmpArgument &arg : args.v) {
common::visit( //
common::visitors{
[&](const parser::OmpMapperSpecifier &spec) {
ProcessMapperSpecifier(spec, clauses);
+ visitClauses = false;
},
[&](const parser::OmpReductionSpecifier &spec) {
ProcessReductionSpecifier(spec, clauses, declaratives_.back());
+ visitClauses = false;
},
[&](const parser::OmpLocator &locator) {
// Manually resolve names in CRITICAL directives. This is because
@@ -2003,7 +2006,9 @@ bool OmpVisitor::Pre(const parser::OmpDirectiveSpecification &x) {
arg.u);
}
- Walk(clauses);
+ if (visitClauses) {
+ Walk(clauses);
+ }
return false;
}
More information about the llvm-branch-commits
mailing list