Skip to content
3 changes: 0 additions & 3 deletions flang/examples/FeatureList/FeatureList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -451,9 +451,6 @@ struct NodeVisitor {
READ_FEATURE(OmpBlockConstruct)
READ_FEATURE(OmpClause)
READ_FEATURE(OmpClauseList)
READ_FEATURE(OmpDeclareTargetSpecifier)
READ_FEATURE(OmpDeclareTargetWithClause)
READ_FEATURE(OmpDeclareTargetWithList)
READ_FEATURE(OmpDefaultClause)
READ_FEATURE(OmpDefaultClause::DataSharingAttribute)
READ_FEATURE(OmpDefaultmapClause)
Expand Down
4 changes: 1 addition & 3 deletions flang/include/flang/Parser/dump-parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,7 @@ class ParseTreeDumper {
NODE(parser, OmpAtomicDefaultMemOrderClause)
NODE(parser, OmpAutomapModifier)
NODE_ENUM(OmpAutomapModifier, Value)
NODE(parser, OmpBaseVariantNames)
NODE(parser, OmpBeginDirective)
NODE(parser, OmpBeginLoopDirective)
NODE(parser, OmpBeginSectionsDirective)
Expand All @@ -537,9 +538,6 @@ class ParseTreeDumper {
NODE_ENUM(OmpCloseModifier, Value)
NODE(parser, OmpContainsClause)
NODE(parser, OmpContextSelectorSpecification)
NODE(parser, OmpDeclareTargetSpecifier)
NODE(parser, OmpDeclareTargetWithClause)
NODE(parser, OmpDeclareTargetWithList)
NODE(parser, OmpDeclareVariantDirective)
NODE(parser, OmpDefaultClause)
NODE_ENUM(OmpDefaultClause, DataSharingAttribute)
Expand Down
12 changes: 5 additions & 7 deletions flang/include/flang/Parser/openmp-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,9 @@ struct ConstructId {
static constexpr llvm::omp::Directive id{Id}; \
}

MAKE_CONSTR_ID(OmpDeclareVariantDirective, D::OMPD_declare_variant);
MAKE_CONSTR_ID(OpenMPDeclarativeAllocate, D::OMPD_allocate);
MAKE_CONSTR_ID(OpenMPDeclarativeAssumes, D::OMPD_assumes);
MAKE_CONSTR_ID(OpenMPDeclareReductionConstruct, D::OMPD_declare_reduction);
MAKE_CONSTR_ID(OpenMPDeclareSimdConstruct, D::OMPD_declare_simd);
MAKE_CONSTR_ID(OpenMPDeclareTargetConstruct, D::OMPD_declare_target);
MAKE_CONSTR_ID(OpenMPExecutableAllocate, D::OMPD_allocate);
MAKE_CONSTR_ID(OpenMPRequiresConstruct, D::OMPD_requires);

Expand All @@ -58,6 +55,10 @@ struct DirectiveNameScope {
return name;
}

static OmpDirectiveName GetOmpDirectiveName(const OmpDirectiveName &x) {
return x;
}

static OmpDirectiveName GetOmpDirectiveName(const OmpBeginLoopDirective &x) {
return x.DirName();
}
Expand Down Expand Up @@ -92,12 +93,9 @@ struct DirectiveNameScope {
} else if constexpr (TupleTrait<T>) {
if constexpr (std::is_base_of_v<OmpBlockConstruct, T>) {
return std::get<OmpBeginDirective>(x.t).DirName();
} else if constexpr (std::is_same_v<T, OmpDeclareVariantDirective> ||
std::is_same_v<T, OpenMPDeclarativeAllocate> ||
} else if constexpr (std::is_same_v<T, OpenMPDeclarativeAllocate> ||
std::is_same_v<T, OpenMPDeclarativeAssumes> ||
std::is_same_v<T, OpenMPDeclareReductionConstruct> ||
std::is_same_v<T, OpenMPDeclareSimdConstruct> ||
std::is_same_v<T, OpenMPDeclareTargetConstruct> ||
std::is_same_v<T, OpenMPExecutableAllocate> ||
std::is_same_v<T, OpenMPRequiresConstruct>) {
return MakeName(std::get<Verbatim>(x.t).source, ConstructId<T>::id);
Expand Down
53 changes: 29 additions & 24 deletions flang/include/flang/Parser/parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -3555,6 +3555,18 @@ struct OmpLocator {

WRAPPER_CLASS(OmpLocatorList, std::list<OmpLocator>);

// Ref: [4.5:58-60], [5.0:58-60], [5.1:63-68], [5.2:197-198], [6.0:334-336]
//
// Argument to DECLARE VARIANT with the base-name present. (When only
// variant-name is present, it is a simple OmpObject).
//
// base-name-variant-name -> // since 4.5
// base-name : variant-name
struct OmpBaseVariantNames {
TUPLE_CLASS_BOILERPLATE(OmpBaseVariantNames);
std::tuple<OmpObject, OmpObject> t;
};

// Ref: [5.0:326:10-16], [5.1:359:5-11], [5.2:163:2-7], [6.0:293:16-21]
//
// mapper-specifier ->
Expand Down Expand Up @@ -3584,6 +3596,7 @@ struct OmpArgument {
CharBlock source;
UNION_CLASS_BOILERPLATE(OmpArgument);
std::variant<OmpLocator, // {variable, extended, locator}-list-item
OmpBaseVariantNames, // base-name:variant-name
OmpMapperSpecifier, OmpReductionSpecifier>
u;
};
Expand Down Expand Up @@ -4920,34 +4933,26 @@ struct OpenMPSectionsConstruct {
t;
};

// Ref: [4.5:58-60], [5.0:58-60], [5.1:63-68], [5.2:197-198], [6.0:334-336]
//
// declare-variant-directive ->
// DECLARE_VARIANT([base-name:]variant-name) // since 4.5
struct OmpDeclareVariantDirective {
TUPLE_CLASS_BOILERPLATE(OmpDeclareVariantDirective);
CharBlock source;
std::tuple<Verbatim, std::optional<Name>, Name, OmpClauseList> t;
};

// 2.10.6 declare-target -> DECLARE TARGET (extended-list) |
// DECLARE TARGET [declare-target-clause[ [,]
// declare-target-clause]...]
struct OmpDeclareTargetWithList {
WRAPPER_CLASS_BOILERPLATE(OmpDeclareTargetWithList, OmpObjectList);
CharBlock source;
};

struct OmpDeclareTargetWithClause {
WRAPPER_CLASS_BOILERPLATE(OmpDeclareTargetWithClause, OmpClauseList);
WRAPPER_CLASS_BOILERPLATE(
OmpDeclareVariantDirective, OmpDirectiveSpecification);
CharBlock source;
};

struct OmpDeclareTargetSpecifier {
UNION_CLASS_BOILERPLATE(OmpDeclareTargetSpecifier);
std::variant<OmpDeclareTargetWithList, OmpDeclareTargetWithClause> u;
};

// Ref: [4.5:110-113], [5.0:180-185], [5.1:210-216], [5.2:206-207],
// [6.0:346-348]
//
// declare-target-directive -> // since 4.5
// DECLARE_TARGET[(extended-list)] |
// DECLARE_TARGET clause-list
struct OpenMPDeclareTargetConstruct {
TUPLE_CLASS_BOILERPLATE(OpenMPDeclareTargetConstruct);
WRAPPER_CLASS_BOILERPLATE(
OpenMPDeclareTargetConstruct, OmpDirectiveSpecification);
CharBlock source;
std::tuple<Verbatim, OmpDeclareTargetSpecifier> t;
};

// OMP v5.2: 5.8.8
Expand All @@ -4970,9 +4975,9 @@ struct OpenMPDeclareReductionConstruct {
// 2.8.2 declare-simd -> DECLARE SIMD [(proc-name)] [declare-simd-clause[ [,]
// declare-simd-clause]...]
struct OpenMPDeclareSimdConstruct {
TUPLE_CLASS_BOILERPLATE(OpenMPDeclareSimdConstruct);
WRAPPER_CLASS_BOILERPLATE(
OpenMPDeclareSimdConstruct, OmpDirectiveSpecification);
CharBlock source;
std::tuple<Verbatim, std::optional<Name>, OmpClauseList> t;
};

// ref: [6.0:301-303]
Expand Down
14 changes: 6 additions & 8 deletions flang/lib/Lower/OpenMP/OpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -761,19 +761,17 @@ static void promoteNonCPtrUseDevicePtrArgsToUseDeviceAddr(
static void getDeclareTargetInfo(
lower::AbstractConverter &converter, semantics::SemanticsContext &semaCtx,
lower::pft::Evaluation &eval,
const parser::OpenMPDeclareTargetConstruct &declareTargetConstruct,
const parser::OpenMPDeclareTargetConstruct &construct,
mlir::omp::DeclareTargetOperands &clauseOps,
llvm::SmallVectorImpl<DeclareTargetCaptureInfo> &symbolAndClause) {
const auto &spec =
std::get<parser::OmpDeclareTargetSpecifier>(declareTargetConstruct.t);
if (const auto *objectList{parser::Unwrap<parser::OmpObjectList>(spec.u)}) {
ObjectList objects{makeObjects(*objectList, semaCtx)};

if (!construct.v.Arguments().v.empty()) {
ObjectList objects{makeObjects(construct.v.Arguments(), semaCtx)};
// Case: declare target(func, var1, var2)
gatherFuncAndVarSyms(objects, mlir::omp::DeclareTargetCaptureClause::to,
symbolAndClause, /*automap=*/false);
} else if (const auto *clauseList{
parser::Unwrap<parser::OmpClauseList>(spec.u)}) {
List<Clause> clauses = makeClauses(*clauseList, semaCtx);
} else {
List<Clause> clauses = makeClauses(construct.v.Clauses(), semaCtx);
if (clauses.empty()) {
Fortran::lower::pft::FunctionLikeUnit *owningProc =
eval.getOwningProcedure();
Expand Down
96 changes: 69 additions & 27 deletions flang/lib/Parser/openmp-parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,15 +315,56 @@ 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<OmpBaseVariantNames>(
Parser<OmpObject>{} / ":", Parser<OmpObject>{}))

// Make the parsing of OmpArgument directive-sensitive. The issue is that
// name1:name2 can match either OmpBaseVariantNames or OmpReductionSpecifier.
// In the former case, "name2" is a name of a function, in the latter, of a
// type. To resolve the conflict we need information provided by name
// resolution, but by that time we can't modify the AST anymore, and the
// name resolution may have implicitly declared a symbol, or issued a message.
template <llvm::omp::Directive Id = llvm::omp::Directive::OMPD_unknown>
struct OmpArgumentParser {
using resultType = OmpArgument;

std::optional<resultType> Parse(ParseState &state) const {
constexpr auto parser{sourced(first( //
construct<OmpArgument>(Parser<OmpMapperSpecifier>{}),
// By default, prefer OmpReductionSpecifier over OmpBaseVariantNames.
construct<OmpArgument>(Parser<OmpReductionSpecifier>{}),
construct<OmpArgument>(Parser<OmpLocator>{})))};
return parser.Parse(state);
}
};

template <>
struct OmpArgumentParser<llvm::omp::Directive::OMPD_declare_variant> {
using resultType = OmpArgument;

std::optional<resultType> Parse(ParseState &state) const {
constexpr auto parser{sourced(first( //
construct<OmpArgument>(Parser<OmpMapperSpecifier>{}),
// In DECLARE_VARIANT parse OmpBaseVariantNames instead of
// OmpReductionSpecifier.
construct<OmpArgument>(Parser<OmpBaseVariantNames>{}),
construct<OmpArgument>(Parser<OmpLocator>{})))};
return parser.Parse(state);
}
};

TYPE_PARSER(construct<OmpLocatorList>(nonemptyList(Parser<OmpLocator>{})))

TYPE_PARSER(sourced( //
construct<OmpArgumentList>(nonemptyList(Parser<OmpArgument>{}))))
template <llvm::omp::Directive Id = llvm::omp::Directive::OMPD_unknown>
struct OmpArgumentListParser {
using resultType = OmpArgumentList;

std::optional<resultType> Parse(ParseState &state) const {
return sourced(
construct<OmpArgumentList>(nonemptyList(OmpArgumentParser<Id>{})))
.Parse(state);
}
};

TYPE_PARSER( //
construct<OmpTypeSpecifier>(Parser<DeclarationTypeSpec>{}) ||
Expand Down Expand Up @@ -1312,12 +1353,23 @@ TYPE_PARSER(
applyFunction<OmpDirectiveSpecification>(makeFlushFromOldSyntax,
verbatim("FLUSH"_tok) / !lookAhead("("_tok),
maybe(Parser<OmpClauseList>{}),
maybe(parenthesized(Parser<OmpArgumentList>{})),
maybe(parenthesized(
OmpArgumentListParser<llvm::omp::Directive::OMPD_flush>{})),
pure(OmpDirectiveSpecification::Flags::DeprecatedSyntax)))) ||
// Parse DECLARE_VARIANT individually, because the "[base:]variant"
// argument will conflict with DECLARE_REDUCTION's "ident:types...".
predicated(Parser<OmpDirectiveName>{},
IsDirective(llvm::omp::Directive::OMPD_declare_variant)) >=
sourced(construct<OmpDirectiveSpecification>(
sourced(OmpDirectiveNameParser{}),
maybe(parenthesized(OmpArgumentListParser<
llvm::omp::Directive::OMPD_declare_variant>{})),
maybe(Parser<OmpClauseList>{}),
pure(OmpDirectiveSpecification::Flags::None))) ||
// Parse the standard syntax: directive [(arguments)] [clauses]
sourced(construct<OmpDirectiveSpecification>( //
sourced(OmpDirectiveNameParser{}),
maybe(parenthesized(Parser<OmpArgumentList>{})),
maybe(parenthesized(OmpArgumentListParser<>{})),
maybe(Parser<OmpClauseList>{}),
pure(OmpDirectiveSpecification::Flags::None))))

Expand Down Expand Up @@ -1711,32 +1763,21 @@ TYPE_PARSER(construct<OmpInitializerClause>(

// OpenMP 5.2: 7.5.4 Declare Variant directive
TYPE_PARSER(sourced(construct<OmpDeclareVariantDirective>(
verbatim("DECLARE VARIANT"_tok) || verbatim("DECLARE_VARIANT"_tok),
"(" >> maybe(name / ":"), name / ")", Parser<OmpClauseList>{})))
predicated(Parser<OmpDirectiveName>{},
IsDirective(llvm::omp::Directive::OMPD_declare_variant)) >=
Parser<OmpDirectiveSpecification>{})))

// 2.16 Declare Reduction Construct
TYPE_PARSER(sourced(construct<OpenMPDeclareReductionConstruct>(
predicated(Parser<OmpDirectiveName>{},
IsDirective(llvm::omp::Directive::OMPD_declare_reduction)) >=
Parser<OmpDirectiveSpecification>{})))

// declare-target with list
TYPE_PARSER(sourced(construct<OmpDeclareTargetWithList>(
parenthesized(Parser<OmpObjectList>{}))))

// declare-target with clause
TYPE_PARSER(
sourced(construct<OmpDeclareTargetWithClause>(Parser<OmpClauseList>{})))

// declare-target-specifier
TYPE_PARSER(
construct<OmpDeclareTargetSpecifier>(Parser<OmpDeclareTargetWithList>{}) ||
construct<OmpDeclareTargetSpecifier>(Parser<OmpDeclareTargetWithClause>{}))

// 2.10.6 Declare Target Construct
TYPE_PARSER(sourced(construct<OpenMPDeclareTargetConstruct>(
verbatim("DECLARE TARGET"_tok) || verbatim("DECLARE_TARGET"_tok),
Parser<OmpDeclareTargetSpecifier>{})))
predicated(Parser<OmpDirectiveName>{},
IsDirective(llvm::omp::Directive::OMPD_declare_target)) >=
Parser<OmpDirectiveSpecification>{})))

static OmpMapperSpecifier ConstructOmpMapperSpecifier(
std::optional<Name> &&mapperName, TypeSpec &&typeSpec, Name &&varName) {
Expand Down Expand Up @@ -1783,8 +1824,9 @@ TYPE_PARSER(

// 2.8.2 Declare Simd construct
TYPE_PARSER(sourced(construct<OpenMPDeclareSimdConstruct>(
verbatim("DECLARE SIMD"_tok) || verbatim("DECLARE_SIMD"_tok),
maybe(parenthesized(name)), Parser<OmpClauseList>{})))
predicated(Parser<OmpDirectiveName>{},
IsDirective(llvm::omp::Directive::OMPD_declare_simd)) >=
Parser<OmpDirectiveSpecification>{})))

TYPE_PARSER(sourced( //
construct<OpenMPGroupprivate>(
Expand Down
27 changes: 12 additions & 15 deletions flang/lib/Parser/unparse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2089,6 +2089,11 @@ class UnparseVisitor {
// OpenMP Clauses & Directives
void Unparse(const OmpArgumentList &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, ",");
}
Expand Down Expand Up @@ -2487,9 +2492,6 @@ class UnparseVisitor {
void Unparse(const OpenMPCriticalConstruct &x) {
Unparse(static_cast<const OmpBlockConstruct &>(x));
}
void Unparse(const OmpDeclareTargetWithList &x) {
Put("("), Walk(x.v), Put(")");
}
void Unparse(const OmpInitializerProc &x) {
Walk(std::get<ProcedureDesignator>(x.t));
Put("(");
Expand Down Expand Up @@ -2534,12 +2536,8 @@ class UnparseVisitor {
}
void Unparse(const OmpDeclareVariantDirective &x) {
BeginOpenMP();
Word("!$OMP DECLARE VARIANT ");
Put("(");
Walk(std::get<std::optional<Name>>(x.t), ":");
Walk(std::get<Name>(x.t));
Put(")");
Walk(std::get<OmpClauseList>(x.t));
Word("!$OMP ");
Walk(x.v);
Put("\n");
EndOpenMP();
}
Expand Down Expand Up @@ -2572,18 +2570,17 @@ class UnparseVisitor {
Put("\n");
EndOpenMP();
}
void Unparse(const OpenMPDeclareSimdConstruct &y) {
void Unparse(const OpenMPDeclareSimdConstruct &x) {
BeginOpenMP();
Word("!$OMP DECLARE SIMD ");
Walk("(", std::get<std::optional<Name>>(y.t), ")");
Walk(std::get<OmpClauseList>(y.t));
Word("!$OMP ");
Walk(x.v);
Put("\n");
EndOpenMP();
}
void Unparse(const OpenMPDeclareTargetConstruct &x) {
BeginOpenMP();
Word("!$OMP DECLARE TARGET ");
Walk(std::get<parser::OmpDeclareTargetSpecifier>(x.t));
Word("!$OMP ");
Walk(x.v);
Put("\n");
EndOpenMP();
}
Expand Down
Loading