[flang-commits] [flang] OpenMP stylized expressions (PR #164984)
via flang-commits
flang-commits at lists.llvm.org
Fri Oct 24 06:53:21 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-openmp
Author: Krzysztof Parzyszek (kparzysz)
<details>
<summary>Changes</summary>
---
Patch is 25.96 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/164984.diff
11 Files Affected:
- (modified) flang/include/flang/Parser/dump-parse-tree.h (+4)
- (modified) flang/include/flang/Parser/openmp-utils.h (+22)
- (modified) flang/include/flang/Parser/parse-tree.h (+48-5)
- (modified) flang/lib/Parser/openmp-parsers.cpp (+165-16)
- (modified) flang/lib/Parser/openmp-utils.cpp (+12)
- (modified) flang/lib/Parser/parse-tree.cpp (+27)
- (modified) flang/lib/Parser/unparse.cpp (+13-18)
- (modified) flang/lib/Semantics/resolve-names.cpp (+39-48)
- (modified) flang/test/Parser/OpenMP/declare-reduction-unparse-with-symbols.f90 (+1-1)
- (modified) flang/test/Parser/OpenMP/declare-reduction-unparse.f90 (+4-2)
- (modified) flang/test/Parser/OpenMP/openmp6-directive-spellings.f90 (+1-1)
``````````diff
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index af8152deb8a52..4eae6dc53a630 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -674,6 +674,10 @@ class ParseTreeDumper {
NODE_ENUM(OmpSeverityClause, Severity)
NODE(parser, OmpStepComplexModifier)
NODE(parser, OmpStepSimpleModifier)
+ NODE(parser, OmpStylizedDeclaration)
+ NODE(parser, OmpStylizedExpression)
+ NODE(parser, OmpStylizedInstance)
+ NODE(OmpStylizedInstance, Instance)
NODE(parser, OmpTaskDependenceType)
NODE_ENUM(OmpTaskDependenceType, Value)
NODE(parser, OmpTaskReductionClause)
diff --git a/flang/include/flang/Parser/openmp-utils.h b/flang/include/flang/Parser/openmp-utils.h
index f761332c9cfd7..49db091af93a7 100644
--- a/flang/include/flang/Parser/openmp-utils.h
+++ b/flang/include/flang/Parser/openmp-utils.h
@@ -25,6 +25,13 @@
namespace Fortran::parser::omp {
+template <typename T> constexpr auto addr_if(std::optional<T> &x) {
+ return x ? &*x : nullptr;
+}
+template <typename T> constexpr auto addr_if(const std::optional<T> &x) {
+ return x ? &*x : nullptr;
+}
+
namespace detail {
using D = llvm::omp::Directive;
@@ -133,9 +140,24 @@ template <typename T> OmpDirectiveName GetOmpDirectiveName(const T &x) {
}
const OmpObjectList *GetOmpObjectList(const OmpClause &clause);
+
+template <typename T>
+const T *GetFirstArgument(const OmpDirectiveSpecification &spec) {
+ for (const OmpArgument &arg : spec.Arguments().v) {
+ if (auto *t{std::get_if<T>(&arg.u)}) {
+ return t;
+ }
+ }
+ return nullptr;
+}
+
const BlockConstruct *GetFortranBlockConstruct(
const ExecutionPartConstruct &epc);
+const OmpCombinerExpression *GetCombinerExpr(
+ const OmpReductionSpecifier &rspec);
+const OmpInitializerExpression *GetInitializerExpr(const OmpClause &init);
+
} // namespace Fortran::parser::omp
#endif // FORTRAN_PARSER_OPENMP_UTILS_H
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index be64ef3770c60..61a516f3b64c0 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -24,7 +24,9 @@
#include "provenance.h"
#include "flang/Common/idioms.h"
#include "flang/Common/indirection.h"
+#include "flang/Common/reference.h"
#include "flang/Support/Fortran.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/Frontend/OpenACC/ACC.h.inc"
#include "llvm/Frontend/OpenMP/OMP.h"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
@@ -3504,6 +3506,8 @@ struct OmpDirectiveName {
// type-name list item
struct OmpTypeName {
+ CharBlock source;
+ mutable const semantics::DeclTypeSpec *declTypeSpec{nullptr};
UNION_CLASS_BOILERPLATE(OmpTypeName);
std::variant<TypeSpec, DeclarationTypeSpec> u;
};
@@ -3532,6 +3536,32 @@ struct OmpObjectList {
WRAPPER_CLASS_BOILERPLATE(OmpObjectList, std::list<OmpObject>);
};
+struct OmpStylizedDeclaration {
+ COPY_AND_ASSIGN_BOILERPLATE(OmpStylizedDeclaration);
+ using EmptyTrait = std::true_type;
+ common::Reference<const OmpTypeName> type;
+ EntityDecl var;
+};
+
+struct OmpStylizedInstance {
+ struct Instance {
+ UNION_CLASS_BOILERPLATE(Instance);
+ std::variant<AssignmentStmt, CallStmt, common::Indirection<Expr>>
+ u;
+ };
+ TUPLE_CLASS_BOILERPLATE(OmpStylizedInstance);
+ std::tuple<std::list<OmpStylizedDeclaration>, Instance> t;
+};
+
+class ParseState;
+
+struct OmpStylizedExpression {
+ CharBlock source;
+ const ParseState *state{nullptr};
+ WRAPPER_CLASS_BOILERPLATE(
+ OmpStylizedExpression, std::list<OmpStylizedInstance>);
+};
+
// Ref: [4.5:201-207], [5.0:293-299], [5.1:325-331], [5.2:124]
//
// reduction-identifier ->
@@ -3549,9 +3579,22 @@ struct OmpReductionIdentifier {
// combiner-expression -> // since 4.5
// assignment-statement |
// function-reference
-struct OmpCombinerExpression {
- UNION_CLASS_BOILERPLATE(OmpCombinerExpression);
- std::variant<AssignmentStmt, FunctionReference> u;
+struct OmpCombinerExpression : public OmpStylizedExpression {
+ INHERITED_WRAPPER_CLASS_BOILERPLATE(
+ OmpCombinerExpression, OmpStylizedExpression);
+ static llvm::ArrayRef<CharBlock> Variables();
+};
+
+// Ref: [4.5:222:7-8], [5.0:305:28-29], [5.1:337:20-21], [5.2:127:6-8],
+// [6.0:242:3-5]
+//
+// initializer-expression -> // since 4.5
+// OMP_PRIV = expression |
+// subroutine-name(argument-list)
+struct OmpInitializerExpression : public OmpStylizedExpression {
+ INHERITED_WRAPPER_CLASS_BOILERPLATE(
+ OmpInitializerExpression, OmpStylizedExpression);
+ static llvm::ArrayRef<CharBlock> Variables();
};
inline namespace arguments {
@@ -4558,10 +4601,10 @@ struct OmpInitializerProc {
TUPLE_CLASS_BOILERPLATE(OmpInitializerProc);
std::tuple<ProcedureDesignator, std::list<ActualArgSpec>> t;
};
+
// Initialization for declare reduction construct
struct OmpInitializerClause {
- UNION_CLASS_BOILERPLATE(OmpInitializerClause);
- std::variant<OmpInitializerProc, AssignmentStmt> u;
+ WRAPPER_CLASS_BOILERPLATE(OmpInitializerClause, OmpInitializerExpression);
};
// Ref: [4.5:199-201], [5.0:288-290], [5.1:321-322], [5.2:115-117]
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index d1e081cfd1b41..5adaef8b6697f 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -275,6 +275,13 @@ struct SpecificModifierParser {
// --- Iterator helpers -----------------------------------------------
+static EntityDecl MakeEntityDecl(ObjectName &&name) {
+ return EntityDecl(
+ /*ObjectName=*/std::move(name), std::optional<ArraySpec>{},
+ std::optional<CoarraySpec>{}, std::optional<CharLength>{},
+ std::optional<Initialization>{});
+}
+
// [5.0:47:17-18] In an iterator-specifier, if the iterator-type is not
// specified then the type of that iterator is default integer.
// [5.0:49:14] The iterator-type must be an integer type.
@@ -282,11 +289,7 @@ static std::list<EntityDecl> makeEntityList(std::list<ObjectName> &&names) {
std::list<EntityDecl> entities;
for (auto iter = names.begin(), end = names.end(); iter != end; ++iter) {
- EntityDecl entityDecl(
- /*ObjectName=*/std::move(*iter), std::optional<ArraySpec>{},
- std::optional<CoarraySpec>{}, std::optional<CharLength>{},
- std::optional<Initialization>{});
- entities.push_back(std::move(entityDecl));
+ entities.push_back(MakeEntityDecl(std::move(*iter)));
}
return entities;
}
@@ -306,6 +309,157 @@ static TypeDeclarationStmt makeIterSpecDecl(std::list<ObjectName> &&names) {
makeEntityList(std::move(names)));
}
+// --- Stylized expression handling -----------------------------------
+
+template <typename A> struct NeverParser {
+ using resultType = A;
+ std::optional<resultType> Parse(ParseState &state) const {
+ // Always fail, but without any messages.
+ return std::nullopt;
+ }
+};
+
+template <typename A> constexpr auto never() { return NeverParser<A>{}; }
+
+template <typename A, typename B = void> struct NullParser;
+template <typename B> struct NullParser<std::optional<B>> {
+ using resultType = std::optional<B>;
+ std::optional<resultType> Parse(ParseState &) const {
+ return resultType{std::nullopt};
+ }
+};
+
+template <typename A> constexpr auto null() { return NullParser<A>{}; }
+
+// OmpStylizedDeclaration and OmpStylizedInstance are helper classes, and
+// don't correspond to anything in the source. Their parsers should still
+// exist, but they should never be executed.
+TYPE_PARSER(construct<OmpStylizedDeclaration>(never<OmpStylizedDeclaration>()))
+
+TYPE_PARSER( //
+ construct<OmpStylizedInstance::Instance>(Parser<AssignmentStmt>{}) ||
+ construct<OmpStylizedInstance::Instance>(
+ sourced(construct<CallStmt>(Parser<ProcedureDesignator>{},
+ null<std::optional<CallStmt::Chevrons>>(),
+ parenthesized(optionalList(actualArgSpec))))) ||
+ construct<OmpStylizedInstance::Instance>(indirect(expr)))
+
+TYPE_PARSER(construct<OmpStylizedInstance>(never<OmpStylizedInstance>()))
+
+struct OmpStylizedExpressionParser {
+ using resultType = OmpStylizedExpression;
+
+ std::optional<resultType> Parse(ParseState &state) const {
+ auto *saved{new ParseState(state)};
+ auto getSource{verbatim(Parser<OmpStylizedInstance::Instance>{} >> ok)};
+ if (auto &&ok{getSource.Parse(state)}) {
+ OmpStylizedExpression result{std::list<OmpStylizedInstance>{}};
+ result.source = ok->source;
+ result.state = saved;
+ // result.v remains empty
+ return std::move(result);
+ }
+ delete saved;
+ return std::nullopt;
+ }
+};
+
+static void Instantiate(OmpStylizedExpression &ose,
+ llvm::ArrayRef<const OmpTypeName *> types, llvm::ArrayRef<CharBlock> vars) {
+ assert(types.size() == vars.size() && "List size mismatch");
+ ParseState state{DEREF(ose.state)};
+
+ std::list<OmpStylizedDeclaration> decls;
+ for (auto [type, var] : llvm::zip(types, vars)) {
+ decls.emplace_back(OmpStylizedDeclaration{
+ common::Reference(*type), MakeEntityDecl(Name{var})});
+ }
+
+ if (auto &&instance{Parser<OmpStylizedInstance::Instance>{}.Parse(state)}) {
+ ose.v.emplace_back(
+ OmpStylizedInstance{std::move(decls), std::move(*instance)});
+ }
+}
+
+static void InstantiateForTypes(OmpStylizedExpression &ose,
+ const OmpTypeNameList &typeNames, llvm::ArrayRef<CharBlock> vars) {
+ // The variables "vars" need to be declared with the same type.
+ // For each type in the type list, splat the type into a vector of
+ // the same size as the variable list, and pass it to Instantiate.
+ for (const OmpTypeName &t : typeNames.v) {
+ std::vector<const OmpTypeName *> types(vars.size(), &t);
+ Instantiate(ose, types, vars);
+ }
+}
+
+static void InstantiateDeclareReduction(OmpDirectiveSpecification &spec) {
+ // There can be arguments/clauses that don't make sense, that analysis
+ // is left until semantic checks. Tolerate any unexpected stuff.
+ auto *rspec{GetFirstArgument<OmpReductionSpecifier>(spec)};
+ if (!rspec) {
+ return;
+ }
+
+ const OmpTypeNameList *typeNames{nullptr};
+
+ if (auto *cexpr{GetCombinerExpr(*rspec)}) {
+ typeNames = &std::get<OmpTypeNameList>(rspec->t);
+
+ InstantiateForTypes(const_cast<OmpCombinerExpression &>(*cexpr), *typeNames,
+ OmpCombinerExpression::Variables());
+ delete cexpr->state;
+ } else {
+ // If there are no types, there is nothing else to do.
+ return;
+ }
+
+ for (const OmpClause &clause : spec.Clauses().v) {
+ llvm::omp::Clause id{clause.Id()};
+ if (id == llvm::omp::Clause::OMPC_initializer) {
+ if (auto *iexpr{GetInitializerExpr(clause)}) {
+ InstantiateForTypes(const_cast<OmpInitializerExpression &>(*iexpr),
+ *typeNames, OmpInitializerExpression::Variables());
+ delete iexpr->state;
+ }
+ }
+ }
+}
+
+static void InstantiateStylizedDirective(OmpDirectiveSpecification &spec) {
+ const OmpDirectiveName &dirName{spec.DirName()};
+ if (dirName.v == llvm::omp::Directive::OMPD_declare_reduction) {
+ InstantiateDeclareReduction(spec);
+ }
+}
+
+template <typename P,
+ typename = std::enable_if_t<
+ std::is_same_v<typename P::resultType, OmpDirectiveSpecification>>>
+struct OmpStylizedInstanceCreator {
+ using resultType = OmpDirectiveSpecification;
+ constexpr OmpStylizedInstanceCreator(P p) : parser_(p) {}
+
+ std::optional<resultType> Parse(ParseState &state) const {
+ if (auto &&spec{parser_.Parse(state)}) {
+ InstantiateStylizedDirective(*spec);
+ return std::move(spec);
+ }
+ return std::nullopt;
+ }
+
+private:
+ const P parser_;
+};
+
+template <typename P>
+OmpStylizedInstanceCreator(P) -> OmpStylizedInstanceCreator<P>;
+
+// --- Parsers for types ----------------------------------------------
+
+TYPE_PARSER( //
+ sourced(construct<OmpTypeName>(Parser<DeclarationTypeSpec>{})) ||
+ sourced(construct<OmpTypeName>(Parser<TypeSpec>{})))
+
// --- Parsers for arguments ------------------------------------------
// At the moment these are only directive arguments. This is needed for
@@ -366,10 +520,6 @@ struct OmpArgumentListParser {
}
};
-TYPE_PARSER( //
- construct<OmpTypeName>(Parser<DeclarationTypeSpec>{}) ||
- construct<OmpTypeName>(Parser<TypeSpec>{}))
-
// 2.15.3.6 REDUCTION (reduction-identifier: variable-name-list)
TYPE_PARSER(construct<OmpReductionIdentifier>(Parser<DefinedOperator>{}) ||
construct<OmpReductionIdentifier>(Parser<ProcedureDesignator>{}))
@@ -1065,7 +1215,8 @@ TYPE_PARSER(construct<OmpOtherwiseClause>(
TYPE_PARSER(construct<OmpWhenClause>(
maybe(nonemptyList(Parser<OmpWhenClause::Modifier>{}) / ":"),
- maybe(indirect(Parser<OmpDirectiveSpecification>{}))))
+ maybe(indirect(
+ OmpStylizedInstanceCreator(Parser<OmpDirectiveSpecification>{})))))
// OMP 5.2 12.6.1 grainsize([ prescriptiveness :] scalar-integer-expression)
TYPE_PARSER(construct<OmpGrainsizeClause>(
@@ -1780,9 +1931,7 @@ TYPE_PARSER(
TYPE_PARSER(construct<OmpInitializerProc>(Parser<ProcedureDesignator>{},
parenthesized(many(maybe(","_tok) >> Parser<ActualArgSpec>{}))))
-TYPE_PARSER(construct<OmpInitializerClause>(
- construct<OmpInitializerClause>(assignmentStmt) ||
- construct<OmpInitializerClause>(Parser<OmpInitializerProc>{})))
+TYPE_PARSER(construct<OmpInitializerClause>(Parser<OmpInitializerExpression>{}))
// OpenMP 5.2: 7.5.4 Declare Variant directive
TYPE_PARSER(sourced(construct<OmpDeclareVariantDirective>(
@@ -1794,7 +1943,7 @@ TYPE_PARSER(sourced(construct<OmpDeclareVariantDirective>(
TYPE_PARSER(sourced(construct<OpenMPDeclareReductionConstruct>(
predicated(Parser<OmpDirectiveName>{},
IsDirective(llvm::omp::Directive::OMPD_declare_reduction)) >=
- Parser<OmpDirectiveSpecification>{})))
+ OmpStylizedInstanceCreator(Parser<OmpDirectiveSpecification>{}))))
// 2.10.6 Declare Target Construct
TYPE_PARSER(sourced(construct<OpenMPDeclareTargetConstruct>(
@@ -1832,8 +1981,8 @@ TYPE_PARSER(sourced(construct<OpenMPDeclareMapperConstruct>(
IsDirective(llvm::omp::Directive::OMPD_declare_mapper)) >=
Parser<OmpDirectiveSpecification>{})))
-TYPE_PARSER(construct<OmpCombinerExpression>(Parser<AssignmentStmt>{}) ||
- construct<OmpCombinerExpression>(Parser<FunctionReference>{}))
+TYPE_PARSER(construct<OmpCombinerExpression>(OmpStylizedExpressionParser{}))
+TYPE_PARSER(construct<OmpInitializerExpression>(OmpStylizedExpressionParser{}))
TYPE_PARSER(sourced(construct<OpenMPCriticalConstruct>(
OmpBlockConstructParser{llvm::omp::Directive::OMPD_critical})))
diff --git a/flang/lib/Parser/openmp-utils.cpp b/flang/lib/Parser/openmp-utils.cpp
index 937a17f29f221..95ad3f60770f5 100644
--- a/flang/lib/Parser/openmp-utils.cpp
+++ b/flang/lib/Parser/openmp-utils.cpp
@@ -74,4 +74,16 @@ const BlockConstruct *GetFortranBlockConstruct(
return nullptr;
}
+const OmpCombinerExpression *GetCombinerExpr(
+ const OmpReductionSpecifier &rspec) {
+ return addr_if(std::get<std::optional<OmpCombinerExpression>>(rspec.t));
+}
+
+const OmpInitializerExpression *GetInitializerExpr(const OmpClause &init) {
+ if (auto *wrapped{std::get_if<OmpClause::Initializer>(&init.u)}) {
+ return &wrapped->v.v;
+ }
+ return nullptr;
+}
+
} // namespace Fortran::parser::omp
diff --git a/flang/lib/Parser/parse-tree.cpp b/flang/lib/Parser/parse-tree.cpp
index 8cbaa399c4763..d418a73a0c256 100644
--- a/flang/lib/Parser/parse-tree.cpp
+++ b/flang/lib/Parser/parse-tree.cpp
@@ -11,6 +11,7 @@
#include "flang/Common/indirection.h"
#include "flang/Parser/tools.h"
#include "flang/Parser/user-state.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/Frontend/OpenMP/OMP.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -430,4 +431,30 @@ const OmpClauseList &OmpDirectiveSpecification::Clauses() const {
}
return empty;
}
+
+static bool InitCharBlocksFromStrings(llvm::MutableArrayRef<CharBlock> blocks,
+ llvm::ArrayRef<std::string> strings) {
+ for (auto [i, n] : llvm::enumerate(strings)) {
+ blocks[i] = CharBlock(n);
+ }
+ return true;
+}
+
+// The names should have static storage duration. Keep these names
+// in a sigle place.
+llvm::ArrayRef<CharBlock> OmpCombinerExpression::Variables() {
+ static std::string names[] {"omp_in", "omp_out"};
+ static CharBlock vars[std::size(names)];
+
+ [[maybe_unused]] static bool init = InitCharBlocksFromStrings(vars, names);
+ return vars;
+}
+
+llvm::ArrayRef<CharBlock> OmpInitializerExpression::Variables() {
+ static std::string names[] {"omp_orig", "omp_priv"};
+ static CharBlock vars[std::size(names)];
+
+ [[maybe_unused]] static bool init = InitCharBlocksFromStrings(vars, names);
+ return vars;
+}
} // namespace Fortran::parser
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 2f86c76c5fe03..6e6d6a6fa9f9f 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2088,15 +2088,13 @@ class UnparseVisitor {
// OpenMP Clauses & Directives
void Unparse(const OmpArgumentList &x) { Walk(x.v, ", "); }
+ void Unparse(const OmpTypeNameList &x) { Walk(x.v, ", "); }
void Unparse(const OmpBaseVariantNames &x) {
Walk(std::get<0>(x.t)); // OmpObject
Put(":");
Walk(std::get<1>(x.t)); // OmpObject
}
- void Unparse(const OmpTypeNameList &x) { //
- Walk(x.v, ",");
- }
void Unparse(const OmpMapperSpecifier &x) {
const auto &mapperName{std::get<std::string>(x.t)};
if (mapperName.find(llvm::omp::OmpDefaultMapperName) == std::string::npos) {
@@ -2195,6 +2193,15 @@ class UnparseVisitor {
unsigned ompVersion{langOpts_.OpenMPVersion};
Word(llvm::omp::getOpenMPDirectiveName(x.v, ompVersion));
}
+ void Unparse(const OmpStylizedDeclaration &x) {
+ // empty
+ }
+ void Unparse(const OmpStylizedExpression &x) {
+ Put(x.source.ToString());
+ }
+ void Unparse(const OmpStylizedInstance &x) {
+ // empty
+ }
void Unparse(const OmpIteratorSpecifier &x) {
Walk(std::get<TypeDeclarationStmt>(x.t));
Put(" = ");
@@ -2510,23 +2517,11 @@ class UnparseVisitor {
Walk(std::get<std::list<ActualArgSpec>>(x.t));
Put(")");
}
- void Unparse(const OmpInitializerClause &x) {
- // Don't let the visitor go to the normal AssignmentStmt Unparse function,
- // it adds an extra newline that we don't want.
- if (const auto *assignment{std::get_if<AssignmentStmt>(&x.u)}) {
- Walk(assignment->t, " = ");
- } else {
- Walk(x.u);
- }
+ void Unparse(const OmpInitializerExpression &x) {
+ Unparse(static_cast<const OmpStylizedExpression &>(x));
}
void Unparse(const OmpCombinerExpression &x) {
- // Don't let the visitor go to the normal AssignmentStmt Unparse function,
- // it adds an extra newline that we don't want.
- if (const auto *assignment{std::get_if<AssignmentStmt>(&x.u)}) {
- Walk(assignment->t, " = ");
- } else {
- Walk(x.u);
- }
+ Unparse(static_cast<const OmpStylizedExpression &>(x));
}
void Unparse(const OpenMPDeclareReductionConstruct &x) {
BeginOpenMP();
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 4af6cf6a91239..6dc8bd3473b20 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1605,6 +1605,12 @@ class OmpVisitor : public virtual DeclarationVisitor {
Post(static_cast<const parser::OmpDirectiveSpecification &>(x));
}
+ void Post(const parser::OmpTypeName &);
+ bool Pre(const parser::OmpStylizedDeclaration &);
+ void Post(const parser::OmpStylizedDeclaration &);
+ bool Pre(const parser::OmpStylizedInstance &);
+ void Post(const parser::OmpStylizedInstance &);
+
bool Pre(const parser::OpenMPDeclareMapperConstruct &x) {
AddOmpSourceRange(x.source);
return true;
@@ -1772,14 +1778,6 @@ class OmpVisitor : public virtual DeclarationVisitor {
messageHandler().set_currStmtSource(std::nullopt);
}
- bool Pre(const parser::OmpTypeName &x) {
- BeginDeclTypeSpec();
- return true;
- }
- void Post(const parser::OmpTypeName &x) { //
- EndDeclTypeSpec();
- }
-
bool Pre(const parser::OpenMPConstruct &x) {
// Indicate that the current...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/164984
More information about the flang-commits
mailing list