-
Notifications
You must be signed in to change notification settings - Fork 13.7k
[flang][OpenMP] Handle directive arguments in OmpDirectiveSpecifier #124278
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
A trait poperty can be one of serveral alternatives, and each property in a list was parsed as if it could be any of these alternatives independently from other properties. This made the parsing vulnerable to certain ambiguities in the trait grammar (provided in the OpenMP spec). At the same time the OpenMP spec gives the expected types of properties for almost every trait: all properties listed for a given trait are usually of the same type, e.g. names, clauses, etc. Incorporate these restrictions into the parser, and additionally use property extensions as the fallback if the parsing of the expected property type failed. This is intended to allow the parser to succeed, and instead let the semantic-checking code emit a more user-friendly message.
Parse METADIRECTIVE as a standalone executable directive at the moment. This will allow testing the parser code. There is no lowering, not even clause conversion yet. There is also no verification of the allowed values for trait sets, trait properties.
…sz/spr/m03-meta-simple
…sz/spr/m03-meta-simple
…sz/spr/m03-meta-simple
This implements checks of the validity of context set selectors and trait selectors, plus the types of trait properties. Clause properties are also validated, but not name or extension properties.
Add METADIRECTIVE to the OpenMP declarative constructs as well. Emit a TODO error for both declarative and executable cases.
Implement parsing and symbol resolution for directives that take arguments. There are a few, and most of them take objects. Special handling is needed for two that take more specialized arguments: DECLARE MAPPER and DECLARE REDUCTION. This only affects directives in METADIRECTIVE's WHEN and OTHERWISE clauses. Parsing and semantic checks of other cases is unaffected.
@llvm/pr-subscribers-flang-parser @llvm/pr-subscribers-flang-openmp Author: Krzysztof Parzyszek (kparzysz) ChangesImplement parsing and symbol resolution for directives that take arguments. There are a few, and most of them take objects. Special handling is needed for two that take more specialized arguments: DECLARE MAPPER and DECLARE REDUCTION. This only affects directives in METADIRECTIVE's WHEN and OTHERWISE clauses. Parsing and semantic checks of other cases is unaffected. Patch is 37.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/124278.diff 9 Files Affected:
diff --git a/flang/examples/FeatureList/FeatureList.cpp b/flang/examples/FeatureList/FeatureList.cpp
index 3a689c335c81c0..e35f120d8661ea 100644
--- a/flang/examples/FeatureList/FeatureList.cpp
+++ b/flang/examples/FeatureList/FeatureList.cpp
@@ -514,7 +514,6 @@ struct NodeVisitor {
READ_FEATURE(OmpReductionClause)
READ_FEATURE(OmpInReductionClause)
READ_FEATURE(OmpReductionCombiner)
- READ_FEATURE(OmpReductionCombiner::FunctionCombiner)
READ_FEATURE(OmpReductionInitializerClause)
READ_FEATURE(OmpReductionIdentifier)
READ_FEATURE(OmpAllocateClause)
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 1323fd695d4439..ce518c7c3edea0 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -476,6 +476,12 @@ class ParseTreeDumper {
NODE(parser, NullInit)
NODE(parser, ObjectDecl)
NODE(parser, OldParameterStmt)
+ NODE(parser, OmpTypeSpecifier)
+ NODE(parser, OmpTypeNameList)
+ NODE(parser, OmpLocator)
+ NODE(parser, OmpLocatorList)
+ NODE(parser, OmpReductionSpecifier)
+ NODE(parser, OmpArgument)
NODE(parser, OmpMetadirectiveDirective)
NODE(parser, OmpMatchClause)
NODE(parser, OmpOtherwiseClause)
@@ -541,7 +547,7 @@ class ParseTreeDumper {
NODE(parser, OmpDeclareTargetSpecifier)
NODE(parser, OmpDeclareTargetWithClause)
NODE(parser, OmpDeclareTargetWithList)
- NODE(parser, OmpDeclareMapperSpecifier)
+ NODE(parser, OmpMapperSpecifier)
NODE(parser, OmpDefaultClause)
NODE_ENUM(OmpDefaultClause, DataSharingAttribute)
NODE(parser, OmpVariableCategory)
@@ -624,7 +630,6 @@ class ParseTreeDumper {
NODE(parser, OmpReductionCombiner)
NODE(parser, OmpTaskReductionClause)
NODE(OmpTaskReductionClause, Modifier)
- NODE(OmpReductionCombiner, FunctionCombiner)
NODE(parser, OmpReductionInitializerClause)
NODE(parser, OmpReductionIdentifier)
NODE(parser, OmpAllocateClause)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 2e27b6ea7eafa1..993c1338f7235b 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3454,15 +3454,7 @@ WRAPPER_CLASS(PauseStmt, std::optional<StopCode>);
// --- Common definitions
struct OmpClause;
-struct OmpClauseList;
-
-struct OmpDirectiveSpecification {
- TUPLE_CLASS_BOILERPLATE(OmpDirectiveSpecification);
- std::tuple<llvm::omp::Directive,
- std::optional<common::Indirection<OmpClauseList>>>
- t;
- CharBlock source;
-};
+struct OmpDirectiveSpecification;
// 2.1 Directives or clauses may accept a list or extended-list.
// A list item is a variable, array section or common block name (enclosed
@@ -3475,15 +3467,76 @@ struct OmpObject {
WRAPPER_CLASS(OmpObjectList, std::list<OmpObject>);
-#define MODIFIER_BOILERPLATE(...) \
- struct Modifier { \
- using Variant = std::variant<__VA_ARGS__>; \
- UNION_CLASS_BOILERPLATE(Modifier); \
- CharBlock source; \
- Variant u; \
- }
+// Ref: [4.5:201-207], [5.0:293-299], [5.1:325-331], [5.2:124]
+//
+// reduction-identifier ->
+// base-language-identifier | // since 4.5
+// - | // since 4.5, until 5.2
+// + | * | .AND. | .OR. | .EQV. | .NEQV. | // since 4.5
+// MIN | MAX | IAND | IOR | IEOR // since 4.5
+struct OmpReductionIdentifier {
+ UNION_CLASS_BOILERPLATE(OmpReductionIdentifier);
+ std::variant<DefinedOperator, ProcedureDesignator> u;
+};
-#define MODIFIERS() std::optional<std::list<Modifier>>
+// Ref: [4.5:222:6], [5.0:305:27], [5.1:337:19], [5.2:126:3-4], [6.0:240:27-28]
+//
+// combiner-expression -> // since 4.5
+// assignment-statement |
+// function-reference
+struct OmpReductionCombiner {
+ UNION_CLASS_BOILERPLATE(OmpReductionCombiner);
+ std::variant<AssignmentStmt, FunctionReference> u;
+};
+
+inline namespace arguments {
+struct OmpTypeSpecifier {
+ UNION_CLASS_BOILERPLATE(OmpTypeSpecifier);
+ std::variant<TypeSpec, DeclarationTypeSpec> u;
+};
+
+WRAPPER_CLASS(OmpTypeNameList, std::list<OmpTypeSpecifier>);
+
+struct OmpLocator {
+ UNION_CLASS_BOILERPLATE(OmpLocator);
+ std::variant<OmpObject, FunctionReference> u;
+};
+
+WRAPPER_CLASS(OmpLocatorList, std::list<OmpLocator>);
+
+// Ref: [5.0:326:10-16], [5.1:359:5-11], [5.2:163:2-7], [6.0:293:16-21]
+//
+// mapper-specifier ->
+// [mapper-identifier :] type :: var | // since 5.0
+// DEFAULT type :: var
+struct OmpMapperSpecifier {
+ // Absent mapper-identifier is equivalent to DEFAULT.
+ TUPLE_CLASS_BOILERPLATE(OmpMapperSpecifier);
+ std::tuple<std::optional<Name>, TypeSpec, Name> t;
+};
+
+// Ref: [4.5:222:1-5], [5.0:305:20-27], [5.1:337:11-19], [5.2:139:18-23],
+// [6.0:260:16-20]
+//
+// reduction-specifier ->
+// reduction-identifier : typename-list
+// : combiner-expression // since 4.5, until 5.2
+// reduction-identifier : typename-list // since 6.0
+struct OmpReductionSpecifier {
+ TUPLE_CLASS_BOILERPLATE(OmpReductionSpecifier);
+ std::tuple<OmpReductionIdentifier, OmpTypeNameList,
+ std::optional<OmpReductionCombiner>>
+ t;
+};
+
+struct OmpArgument {
+ CharBlock source;
+ UNION_CLASS_BOILERPLATE(OmpArgument);
+ std::variant<OmpLocator, // {variable, extended, locator}-list-item
+ OmpMapperSpecifier, OmpReductionSpecifier>
+ u;
+};
+} // namespace arguments
inline namespace traits {
// trait-property-name ->
@@ -3617,6 +3670,16 @@ struct OmpContextSelectorSpecification { // Modifier
};
} // namespace traits
+#define MODIFIER_BOILERPLATE(...) \
+ struct Modifier { \
+ using Variant = std::variant<__VA_ARGS__>; \
+ UNION_CLASS_BOILERPLATE(Modifier); \
+ CharBlock source; \
+ Variant u; \
+ }
+
+#define MODIFIERS() std::optional<std::list<Modifier>>
+
inline namespace modifier {
// For uniformity, in all keyword modifiers the name of the type defined
// by ENUM_CLASS is "Value", e.g.
@@ -3829,18 +3892,6 @@ struct OmpPrescriptiveness {
WRAPPER_CLASS_BOILERPLATE(OmpPrescriptiveness, Value);
};
-// Ref: [4.5:201-207], [5.0:293-299], [5.1:325-331], [5.2:124]
-//
-// reduction-identifier ->
-// base-language-identifier | // since 4.5
-// - | // since 4.5, until 5.2
-// + | * | .AND. | .OR. | .EQV. | .NEQV. | // since 4.5
-// MIN | MAX | IAND | IOR | IEOR // since 4.5
-struct OmpReductionIdentifier {
- UNION_CLASS_BOILERPLATE(OmpReductionIdentifier);
- std::variant<DefinedOperator, ProcedureDesignator> u;
-};
-
// Ref: [5.0:300-302], [5.1:332-334], [5.2:134-137]
//
// reduction-modifier ->
@@ -3983,7 +4034,9 @@ struct OmpBindClause {
struct OmpDefaultClause {
ENUM_CLASS(DataSharingAttribute, Private, Firstprivate, Shared, None)
UNION_CLASS_BOILERPLATE(OmpDefaultClause);
- std::variant<DataSharingAttribute, OmpDirectiveSpecification> u;
+ std::variant<DataSharingAttribute,
+ common::Indirection<OmpDirectiveSpecification>>
+ u;
};
// Ref: [4.5:103-107], [5.0:324-325], [5.1:357-358], [5.2:161-162]
@@ -4248,8 +4301,8 @@ struct OmpOrderClause {
// otherwise-clause ->
// OTHERWISE ([directive-specification])] // since 5.2
struct OmpOtherwiseClause {
- WRAPPER_CLASS_BOILERPLATE(
- OmpOtherwiseClause, std::optional<OmpDirectiveSpecification>);
+ WRAPPER_CLASS_BOILERPLATE(OmpOtherwiseClause,
+ std::optional<common::Indirection<OmpDirectiveSpecification>>);
};
// Ref: [4.5:46-50], [5.0:74-78], [5.1:92-96], [5.2:229-230]
@@ -4345,7 +4398,9 @@ struct OmpUpdateClause {
struct OmpWhenClause {
TUPLE_CLASS_BOILERPLATE(OmpWhenClause);
MODIFIER_BOILERPLATE(OmpContextSelector);
- std::tuple<MODIFIERS(), std::optional<OmpDirectiveSpecification>> t;
+ std::tuple<MODIFIERS(),
+ std::optional<common::Indirection<OmpDirectiveSpecification>>>
+ t;
};
// OpenMP Clauses
@@ -4372,6 +4427,14 @@ struct OmpClauseList {
// --- Directives and constructs
+struct OmpDirectiveSpecification {
+ CharBlock source;
+ TUPLE_CLASS_BOILERPLATE(OmpDirectiveSpecification);
+ std::tuple<llvm::omp::Directive, std::optional<std::list<OmpArgument>>,
+ std::optional<OmpClauseList>>
+ t;
+};
+
struct OmpMetadirectiveDirective {
TUPLE_CLASS_BOILERPLATE(OmpMetadirectiveDirective);
std::tuple<OmpClauseList> t;
@@ -4472,27 +4535,16 @@ struct OpenMPDeclareTargetConstruct {
std::tuple<Verbatim, OmpDeclareTargetSpecifier> t;
};
-struct OmpDeclareMapperSpecifier {
- TUPLE_CLASS_BOILERPLATE(OmpDeclareMapperSpecifier);
- std::tuple<std::optional<Name>, TypeSpec, Name> t;
-};
-
// OMP v5.2: 5.8.8
// declare-mapper -> DECLARE MAPPER ([mapper-name :] type :: var) map-clauses
struct OpenMPDeclareMapperConstruct {
TUPLE_CLASS_BOILERPLATE(OpenMPDeclareMapperConstruct);
CharBlock source;
- std::tuple<Verbatim, OmpDeclareMapperSpecifier, OmpClauseList> t;
+ std::tuple<Verbatim, OmpMapperSpecifier, OmpClauseList> t;
};
// 2.16 declare-reduction -> DECLARE REDUCTION (reduction-identifier : type-list
// : combiner) [initializer-clause]
-struct OmpReductionCombiner {
- UNION_CLASS_BOILERPLATE(OmpReductionCombiner);
- WRAPPER_CLASS(FunctionCombiner, Call);
- std::variant<AssignmentStmt, FunctionCombiner> u;
-};
-
WRAPPER_CLASS(OmpReductionInitializerClause, Expr);
struct OpenMPDeclareReductionConstruct {
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index f5387dcf4b3c3d..e73e0ac2c85ff9 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -68,6 +68,8 @@ void OmpDirectiveNameParser::initTokens(NameWithId *table) const {
[](auto &a, auto &b) { return a.first.size() > b.first.size(); });
}
+// --- Modifier helpers -----------------------------------------------
+
template <typename Clause, typename Separator> struct ModifierList {
constexpr ModifierList(Separator sep) : sep_(sep) {}
constexpr ModifierList(const ModifierList &) = default;
@@ -118,10 +120,8 @@ struct SpecificModifierParser {
}
};
-// OpenMP Clauses
+// --- Iterator helpers -----------------------------------------------
-// [5.0] 2.1.6 iterator-specifier -> type-declaration-stmt = subscript-triple |
-// identifier = subscript-triple
// [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.
@@ -153,8 +153,30 @@ static TypeDeclarationStmt makeIterSpecDecl(std::list<ObjectName> &&names) {
makeEntityList(std::move(names)));
}
-TYPE_PARSER(sourced(construct<OmpDirectiveSpecification>(
- OmpDirectiveNameParser{}, maybe(indirect(Parser<OmpClauseList>{})))))
+// --- Parsers for arguments ------------------------------------------
+
+// At the moment these are only directive arguments. This is needed for
+// parsing directive-specification.
+
+TYPE_PARSER( //
+ construct<OmpLocator>(Parser<OmpObject>{}) ||
+ construct<OmpLocator>(Parser<FunctionReference>{}))
+
+TYPE_PARSER(sourced( //
+ construct<OmpArgument>(Parser<OmpMapperSpecifier>{}) ||
+ construct<OmpArgument>(Parser<OmpReductionSpecifier>{}) ||
+ construct<OmpArgument>(Parser<OmpLocator>{})))
+
+TYPE_PARSER(construct<OmpLocatorList>(nonemptyList(Parser<OmpLocator>{})))
+
+TYPE_PARSER( //
+ construct<OmpTypeSpecifier>(Parser<TypeSpec>{}) ||
+ construct<OmpTypeSpecifier>(Parser<DeclarationTypeSpec>{}))
+
+TYPE_PARSER(construct<OmpReductionSpecifier>( //
+ Parser<OmpReductionIdentifier>{},
+ ":"_tok >> nonemptyList(Parser<OmpTypeSpecifier>{}),
+ maybe(":"_tok >> Parser<OmpReductionCombiner>{})))
// --- Parsers for context traits -------------------------------------
@@ -213,15 +235,11 @@ static constexpr auto propertyListParser(PropParser... pp) {
// the entire list in each of the alternative property parsers. Otherwise,
// the name parser could stop after "foo" in "(foo, bar(1))", without
// allowing the next parser to give the list a try.
- auto listOf{[](auto parser) { //
- return nonemptySeparated(parser, ",");
- }};
-
using P = OmpTraitProperty;
return maybe("(" >> //
construct<OmpTraitSelector::Properties>(
maybe(Parser<OmpTraitScore>{} / ":"),
- (attempt(listOf(sourced(construct<P>(pp))) / ")") || ...)));
+ (attempt(nonemptyList(sourced(construct<P>(pp))) / ")") || ...)));
}
// Parser for OmpTraitSelector
@@ -309,7 +327,7 @@ TYPE_PARSER(sourced(construct<OmpTraitSetSelector>( //
TYPE_PARSER(sourced(construct<OmpContextSelectorSpecification>(
nonemptySeparated(Parser<OmpTraitSetSelector>{}, ","))))
-// Parser<OmpContextSelector> == Parser<traits::OmpContextSelectorSpecification>
+// Note: OmpContextSelector is a type alias.
// --- Parsers for clause modifiers -----------------------------------
@@ -543,7 +561,7 @@ TYPE_PARSER(construct<OmpDefaultClause::DataSharingAttribute>(
TYPE_PARSER(construct<OmpDefaultClause>(
construct<OmpDefaultClause>(
Parser<OmpDefaultClause::DataSharingAttribute>{}) ||
- construct<OmpDefaultClause>(Parser<OmpDirectiveSpecification>{})))
+ construct<OmpDefaultClause>(indirect(Parser<OmpDirectiveSpecification>{}))))
// 2.5 PROC_BIND (MASTER | CLOSE | PRIMARY | SPREAD)
TYPE_PARSER(construct<OmpProcBindClause>(
@@ -713,11 +731,11 @@ TYPE_PARSER(construct<OmpMatchClause>(
Parser<traits::OmpContextSelectorSpecification>{}))
TYPE_PARSER(construct<OmpOtherwiseClause>(
- maybe(sourced(Parser<OmpDirectiveSpecification>{}))))
+ maybe(indirect(sourced(Parser<OmpDirectiveSpecification>{})))))
TYPE_PARSER(construct<OmpWhenClause>(
maybe(nonemptyList(Parser<OmpWhenClause::Modifier>{}) / ":"),
- maybe(sourced(Parser<OmpDirectiveSpecification>{}))))
+ maybe(indirect(sourced(Parser<OmpDirectiveSpecification>{})))))
// OMP 5.2 12.6.1 grainsize([ prescriptiveness :] scalar-integer-expression)
TYPE_PARSER(construct<OmpGrainsizeClause>(
@@ -929,6 +947,13 @@ TYPE_PARSER(construct<OmpObjectList>(nonemptyList(Parser<OmpObject>{})))
TYPE_PARSER(sourced(construct<OmpErrorDirective>(
verbatim("ERROR"_tok), Parser<OmpClauseList>{})))
+// --- Parsers for directives and constructs --------------------------
+
+TYPE_PARSER(sourced(construct<OmpDirectiveSpecification>( //
+ OmpDirectiveNameParser{},
+ maybe(parenthesized(nonemptyList(Parser<OmpArgument>{}))),
+ maybe(Parser<OmpClauseList>{}))))
+
TYPE_PARSER(sourced(construct<OmpNothingDirective>("NOTHING" >> ok)))
TYPE_PARSER(sourced(construct<OpenMPUtilityConstruct>(
@@ -1141,20 +1166,17 @@ TYPE_PARSER(
TYPE_PARSER(sourced(construct<OpenMPDeclareTargetConstruct>(
verbatim("DECLARE TARGET"_tok), Parser<OmpDeclareTargetSpecifier>{})))
-// declare-mapper-specifier
-TYPE_PARSER(construct<OmpDeclareMapperSpecifier>(
+// mapper-specifier
+TYPE_PARSER(construct<OmpMapperSpecifier>(
maybe(name / ":" / !":"_tok), typeSpec / "::", name))
// OpenMP 5.2: 5.8.8 Declare Mapper Construct
-TYPE_PARSER(sourced(construct<OpenMPDeclareMapperConstruct>(
- verbatim("DECLARE MAPPER"_tok),
- "(" >> Parser<OmpDeclareMapperSpecifier>{} / ")", Parser<OmpClauseList>{})))
+TYPE_PARSER(sourced(
+ construct<OpenMPDeclareMapperConstruct>(verbatim("DECLARE MAPPER"_tok),
+ parenthesized(Parser<OmpMapperSpecifier>{}), Parser<OmpClauseList>{})))
TYPE_PARSER(construct<OmpReductionCombiner>(Parser<AssignmentStmt>{}) ||
- construct<OmpReductionCombiner>(
- construct<OmpReductionCombiner::FunctionCombiner>(
- construct<Call>(Parser<ProcedureDesignator>{},
- parenthesized(optionalList(actualArgSpec))))))
+ construct<OmpReductionCombiner>(Parser<FunctionReference>{}))
// 2.17.7 atomic -> ATOMIC [clause [,]] atomic-clause [[,] clause] |
// ATOMIC [clause]
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 7d3b03e5bc27e7..bc1c472f276ea1 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2067,12 +2067,33 @@ class UnparseVisitor {
}
// OpenMP Clauses & Directives
+ void Unparse(const OmpTypeNameList &x) { //
+ Walk(x.v, ",");
+ }
+ void Unparse(const OmpMapperSpecifier &x) {
+ Walk(std::get<std::optional<Name>>(x.t), ":");
+ Walk(std::get<TypeSpec>(x.t));
+ Put("::");
+ Walk(std::get<Name>(x.t));
+ }
+ void Unparse(const OmpReductionSpecifier &x) {
+ Walk(std::get<OmpReductionIdentifier>(x.t));
+ Put(":");
+ Walk(std::get<OmpTypeNameList>(x.t));
+ Walk(":", std::get<std::optional<OmpReductionCombiner>>(x.t));
+ }
void Unparse(const llvm::omp::Directive &x) {
Word(llvm::omp::getOpenMPDirectiveName(x).str());
}
void Unparse(const OmpDirectiveSpecification &x) {
+ using ArgList = std::list<parser::OmpArgument>;
Walk(std::get<llvm::omp::Directive>(x.t));
- Walk(std::get<std::optional<common::Indirection<OmpClauseList>>>(x.t));
+ if (auto &args{std::get<std::optional<ArgList>>(x.t)}) {
+ Put("(");
+ Walk(*args);
+ Put(")");
+ }
+ Walk(std::get<std::optional<OmpClauseList>>(x.t));
}
void Unparse(const OmpTraitScore &x) {
Word("SCORE(");
@@ -2297,8 +2318,9 @@ class UnparseVisitor {
}
void Unparse(const OmpWhenClause &x) {
using Modifier = OmpWhenClause::Modifier;
+ using Directive = common::Indirection<OmpDirectiveSpecification>;
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
- Walk(std::get<std::optional<OmpDirectiveSpecification>>(x.t));
+ Walk(std::get<std::optional<Directive>>(x.t));
}
#define GEN_FLANG_CLAUSE_UNPARSE
#include "llvm/Frontend/OpenMP/OMP.inc"
@@ -2660,18 +2682,6 @@ class UnparseVisitor {
Walk(x.v);
Put(")");
}
- void Unparse(const OmpReductionCombiner::FunctionCombiner &x) {
- const auto &pd = std::get<ProcedureDesignator>(x.v.t);
- const auto &args = std::get<std::list<ActualArgSpec>>(x.v.t);
- Walk(pd);
- if (args.empty()) {
- if (std::holds_alternative<ProcComponentRef>(pd.u)) {
- Put("()");
- }
- } else {
- Walk("(", args, ", ", ")");
- }
- }
void Unparse(const OpenMPDeclareReductionConstruct &x) {
BeginOpenMP();
Word("!$OMP DECLARE REDUCTION ");
@@ -2687,7 +2697,7 @@ class UnparseVisitor {
void Unparse(const OpenMPDeclareMapperConstruct &z) {
BeginOpenMP();
Word("!$OMP DECLARE MAPPER (");
- const auto &spec{std::get<OmpDeclareMapperSpecifier>(z.t)};
+ const auto &spec{std::get<OmpMapperSpecifier>(z.t)};
if (auto mapname{std::get<std::optional<Name>>(spec.t)}) {
Walk(mapname);
Put(":");
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 94886d6b9dfdc9..bde97e0b87e565 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1606,7 +1606,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPDeclareMapperConstruct &x) {
const auto &dir{std::get<parser::Verbatim>(x.t)};
PushContextAndClauseSets(
dir.source, llvm::omp::Directive::OMPD_declare_mapper);
- const auto &spec{std::get<parser::OmpDeclareMapperSpecifier>(x.t)};
+ const auto &spec{std::get<parser::OmpMapperSpecifier>(x.t)};
const auto &type = std::get<parser::TypeSpec>(spec.t);
if (!std::get_if<parser::DerivedTypeSpec>(&type.u)) {
context_.Say(dir.source, "Type is not a derived type"_err_en_US);
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index f3c2a5bf094d04..82bfaa1385fbba 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1471,7 +1471,12 @@ class OmpVisitor : public virtual DeclarationVisitor {
return true;
}
- bool Pre(const parser::OpenMPDeclareMapperConstruct &);
+ bool Pre(const parser::OpenMPDeclareMapperConstruct &x) {
+ AddOmpSourceRange(x.source);
+ ProcessMapperSpecifier(std::get<parser::OmpMapperSpecifier>(x.t),
+ std::get<parser::OmpClauseList>(x.t));
+ return false;
+ }
bool Pre(const parser::OmpMapClause &);
@@ -1573,6 +1578,21 @@ class OmpVisitor : public virtual Declara...
[truncated]
|
Summary of code changes:
|
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!
…lvm#124278) Implement parsing and symbol resolution for directives that take arguments. There are a few, and most of them take objects. Special handling is needed for two that take more specialized arguments: DECLARE MAPPER and DECLARE REDUCTION. This only affects directives in METADIRECTIVE's WHEN and OTHERWISE clauses. Parsing and semantic checks of other cases is unaffected.
Implement parsing and symbol resolution for directives that take arguments. There are a few, and most of them take objects. Special handling is needed for two that take more specialized arguments: DECLARE MAPPER and DECLARE REDUCTION.
This only affects directives in METADIRECTIVE's WHEN and OTHERWISE clauses. Parsing and semantic checks of other cases is unaffected.