https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/160573
>From 525f12fa0da6c22dded6c19e2338b6bcc3c2da6f Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek <krzysztof.parzys...@amd.com> Date: Wed, 24 Sep 2025 07:59:16 -0500 Subject: [PATCH 1/4] [flang][OpenMP] Use OmpDirectiveSpecification in DECLARE_TARGET --- flang/include/flang/Parser/openmp-utils.h | 2 - flang/include/flang/Parser/parse-tree.h | 10 +- flang/lib/Lower/OpenMP/OpenMP.cpp | 14 +- flang/lib/Parser/openmp-parsers.cpp | 18 +- flang/lib/Parser/unparse.cpp | 4 +- flang/lib/Semantics/check-omp-structure.cpp | 245 +++++++++--------- flang/lib/Semantics/check-omp-structure.h | 3 - flang/lib/Semantics/resolve-directives.cpp | 27 +- flang/lib/Semantics/resolve-names.cpp | 77 +++--- .../OpenMP/declare-target-indirect-tree.f90 | 28 +- .../OpenMP/declare-target-to-clause.f90 | 14 +- .../OpenMP/declare_target-device_type.f90 | 108 ++++++-- .../Parser/OpenMP/enter-automap-modifier.f90 | 11 +- .../OpenMP/openmp6-directive-spellings.f90 | 9 +- .../Semantics/OpenMP/blank-common-block.f90 | 1 + ...lare-target-function-name-with-symbols.f90 | 2 +- 16 files changed, 319 insertions(+), 254 deletions(-) diff --git a/flang/include/flang/Parser/openmp-utils.h b/flang/include/flang/Parser/openmp-utils.h index 4b8fe6a5b49f0..bf54f970a7d3a 100644 --- a/flang/include/flang/Parser/openmp-utils.h +++ b/flang/include/flang/Parser/openmp-utils.h @@ -41,7 +41,6 @@ struct ConstructId { 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(OpenMPDeclareTargetConstruct, D::OMPD_declare_target); MAKE_CONSTR_ID(OpenMPExecutableAllocate, D::OMPD_allocate); MAKE_CONSTR_ID(OpenMPRequiresConstruct, D::OMPD_requires); @@ -97,7 +96,6 @@ struct DirectiveNameScope { } 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, OpenMPDeclareTargetConstruct> || std::is_same_v<T, OpenMPExecutableAllocate> || std::is_same_v<T, OpenMPRequiresConstruct>) { return MakeName(std::get<Verbatim>(x.t).source, ConstructId<T>::id); diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index be30a95763208..e7593d9875097 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -4961,10 +4961,16 @@ struct 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 diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index d2e865b3e1d0c..1cb3335abbd06 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -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(); diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 0085576292ff5..bd080386c0aea 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -1773,23 +1773,11 @@ TYPE_PARSER(sourced(construct<OpenMPDeclareReductionConstruct>( 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) { diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index c9774dd137d2b..be166bcb743ba 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2582,8 +2582,8 @@ class UnparseVisitor { } 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(); } diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index cf89d305e3cb2..05ff541657b1a 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -624,11 +624,6 @@ template <typename Checker> struct DirectiveSpellingVisitor { checker_(std::get<parser::Verbatim>(x.t).source, Directive::OMPD_assumes); return false; } - bool Pre(const parser::OpenMPDeclareTargetConstruct &x) { - checker_( - std::get<parser::Verbatim>(x.t).source, Directive::OMPD_declare_target); - return false; - } bool Pre(const parser::OpenMPGroupprivate &x) { checker_(x.v.DirName().source, Directive::OMPD_groupprivate); return false; @@ -1615,38 +1610,6 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Allocate &x) { } } -void OmpStructureChecker::Enter(const parser::OmpDeclareTargetWithClause &x) { - SetClauseSets(llvm::omp::Directive::OMPD_declare_target); -} - -void OmpStructureChecker::Leave(const parser::OmpDeclareTargetWithClause &x) { - if (x.v.v.size() > 0) { - const parser::OmpClause *enterClause = - FindClause(llvm::omp::Clause::OMPC_enter); - const parser::OmpClause *toClause = FindClause(llvm::omp::Clause::OMPC_to); - const parser::OmpClause *linkClause = - FindClause(llvm::omp::Clause::OMPC_link); - const parser::OmpClause *indirectClause = - FindClause(llvm::omp::Clause::OMPC_indirect); - if (!enterClause && !toClause && !linkClause) { - context_.Say(x.source, - "If the DECLARE TARGET directive has a clause, it must contain at least one ENTER clause or LINK clause"_err_en_US); - } - if (indirectClause && !enterClause) { - context_.Say(x.source, - "The INDIRECT clause cannot be used without the ENTER clause with the DECLARE TARGET directive."_err_en_US); - } - unsigned version{context_.langOptions().OpenMPVersion}; - if (toClause && version >= 52) { - context_.Warn(common::UsageWarning::OpenMPUsage, toClause->source, - "The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead."_warn_en_US); - } - if (indirectClause) { - CheckAllowedClause(llvm::omp::Clause::OMPC_indirect); - } - } -} - void OmpStructureChecker::Enter(const parser::OpenMPDeclareMapperConstruct &x) { const parser::OmpDirectiveName &dirName{x.v.DirName()}; PushContextAndClauseSets(dirName.source, dirName.v); @@ -1698,42 +1661,6 @@ void OmpStructureChecker::Leave( dirContext_.pop_back(); } -void OmpStructureChecker::Enter(const parser::OpenMPDeclareTargetConstruct &x) { - const auto &dir{std::get<parser::Verbatim>(x.t)}; - PushContext(dir.source, llvm::omp::Directive::OMPD_declare_target); -} - -void OmpStructureChecker::Enter(const parser::OmpDeclareTargetWithList &x) { - SymbolSourceMap symbols; - GetSymbolsInObjectList(x.v, symbols); - for (auto &[symbol, source] : symbols) { - const GenericDetails *genericDetails = symbol->detailsIf<GenericDetails>(); - if (genericDetails) { - context_.Say(source, - "The procedure '%s' in DECLARE TARGET construct cannot be a generic name."_err_en_US, - symbol->name()); - genericDetails->specific(); - } - if (IsProcedurePointer(*symbol)) { - context_.Say(source, - "The procedure '%s' in DECLARE TARGET construct cannot be a procedure pointer."_err_en_US, - symbol->name()); - } - const SubprogramDetails *entryDetails = - symbol->detailsIf<SubprogramDetails>(); - if (entryDetails && entryDetails->entryScope()) { - context_.Say(source, - "The procedure '%s' in DECLARE TARGET construct cannot be an entry name."_err_en_US, - symbol->name()); - } - if (IsStmtFunction(*symbol)) { - context_.Say(source, - "The procedure '%s' in DECLARE TARGET construct cannot be a statement function."_err_en_US, - symbol->name()); - } - } -} - void OmpStructureChecker::CheckSymbolName( const parser::CharBlock &source, const parser::OmpObject &object) { common::visit( @@ -1766,62 +1693,138 @@ void OmpStructureChecker::CheckSymbolNames( } } +void OmpStructureChecker::Enter(const parser::OpenMPDeclareTargetConstruct &x) { + const parser::OmpDirectiveName &dirName{x.v.DirName()}; + PushContext(dirName.source, dirName.v); + + // Check if arguments are extended-list-items. + for (const parser::OmpArgument &arg : x.v.Arguments().v) { + const Symbol *symbol{GetArgumentSymbol(arg)}; + if (!symbol) { + context_.Say(arg.source, + "An argument to the DECLARE TARGET directive should be an extended-list-item"_err_en_US); + continue; + } + const GenericDetails *genericDetails = symbol->detailsIf<GenericDetails>(); + if (genericDetails) { + context_.Say(arg.source, + "The procedure '%s' in DECLARE TARGET construct cannot be a generic name."_err_en_US, + symbol->name()); + genericDetails->specific(); + } + if (IsProcedurePointer(*symbol)) { + context_.Say(arg.source, + "The procedure '%s' in DECLARE TARGET construct cannot be a procedure pointer."_err_en_US, + symbol->name()); + } + const SubprogramDetails *entryDetails = + symbol->detailsIf<SubprogramDetails>(); + if (entryDetails && entryDetails->entryScope()) { + context_.Say(arg.source, + "The procedure '%s' in DECLARE TARGET construct cannot be an entry name."_err_en_US, + symbol->name()); + } + if (IsStmtFunction(*symbol)) { + context_.Say(arg.source, + "The procedure '%s' in DECLARE TARGET construct cannot be a statement function."_err_en_US, + symbol->name()); + } + } + + // Check if there are arguments or clauses, but not both. + if (!x.v.Clauses().v.empty()) { + if (!x.v.Arguments().v.empty()) { + context_.Say(x.source, + "DECLARE TARGET directive can have argument or clauses, but not both"_err_en_US); + } + SetClauseSets(llvm::omp::Directive::OMPD_declare_target); + } +} + void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &x) { - const auto &dir{std::get<parser::Verbatim>(x.t)}; - const auto &spec{std::get<parser::OmpDeclareTargetSpecifier>(x.t)}; + const parser::OmpDirectiveName &dirName{x.v.DirName()}; + // Handle both forms of DECLARE TARGET. // - Extended list: It behaves as if there was an ENTER/TO clause with the // list of objects as argument. It accepts no explicit clauses. // - With clauses. - if (const auto *objectList{parser::Unwrap<parser::OmpObjectList>(spec.u)}) { - deviceConstructFound_ = true; - CheckSymbolNames(dir.source, *objectList); - CheckVarIsNotPartOfAnotherVar(dir.source, *objectList); - CheckThreadprivateOrDeclareTargetVar(*objectList); - } else if (const auto *clauseList{ - parser::Unwrap<parser::OmpClauseList>(spec.u)}) { - bool toClauseFound{false}, deviceTypeClauseFound{false}, - enterClauseFound{false}; - for (const auto &clause : clauseList->v) { - common::visit( - common::visitors{ - [&](const parser::OmpClause::To &toClause) { - toClauseFound = true; - auto &objList{std::get<parser::OmpObjectList>(toClause.v.t)}; - CheckSymbolNames(dir.source, objList); - CheckVarIsNotPartOfAnotherVar(dir.source, objList); - CheckThreadprivateOrDeclareTargetVar(objList); - }, - [&](const parser::OmpClause::Link &linkClause) { - CheckSymbolNames(dir.source, linkClause.v); - CheckVarIsNotPartOfAnotherVar(dir.source, linkClause.v); - CheckThreadprivateOrDeclareTargetVar(linkClause.v); - }, - [&](const parser::OmpClause::Enter &enterClause) { - enterClauseFound = true; - auto &objList{std::get<parser::OmpObjectList>(enterClause.v.t)}; - CheckSymbolNames(dir.source, objList); - CheckVarIsNotPartOfAnotherVar(dir.source, objList); - CheckThreadprivateOrDeclareTargetVar(objList); - }, - [&](const parser::OmpClause::DeviceType &deviceTypeClause) { - deviceTypeClauseFound = true; - if (deviceTypeClause.v.v != - parser::OmpDeviceTypeClause::DeviceTypeDescription::Host) { - // Function / subroutine explicitly marked as runnable by the - // target device. - deviceConstructFound_ = true; - } - }, - [&](const auto &) {}, - }, - clause.u); + for (const parser::OmpArgument &arg : x.v.Arguments().v) { + if (auto *object{GetArgumentObject(arg)}) { + deviceConstructFound_ = true; + CheckSymbolName(dirName.source, *object); + CheckVarIsNotPartOfAnotherVar(dirName.source, *object); + CheckThreadprivateOrDeclareTargetVar(*object); + } + } - if ((toClauseFound || enterClauseFound) && !deviceTypeClauseFound) { - deviceConstructFound_ = true; - } + if (!x.v.Clauses().v.empty()) { + const parser::OmpClause *enterClause = + FindClause(llvm::omp::Clause::OMPC_enter); + const parser::OmpClause *toClause = FindClause(llvm::omp::Clause::OMPC_to); + const parser::OmpClause *linkClause = + FindClause(llvm::omp::Clause::OMPC_link); + const parser::OmpClause *indirectClause = + FindClause(llvm::omp::Clause::OMPC_indirect); + if (!enterClause && !toClause && !linkClause) { + context_.Say(x.source, + "If the DECLARE TARGET directive has a clause, it must contain at least one ENTER clause or LINK clause"_err_en_US); + } + if (indirectClause && !enterClause) { + context_.Say(x.source, + "The INDIRECT clause cannot be used without the ENTER clause with the DECLARE TARGET directive."_err_en_US); + } + unsigned version{context_.langOptions().OpenMPVersion}; + if (toClause && version >= 52) { + context_.Warn(common::UsageWarning::OpenMPUsage, toClause->source, + "The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead."_warn_en_US); + } + if (indirectClause) { + CheckAllowedClause(llvm::omp::Clause::OMPC_indirect); } } + + bool toClauseFound{false}, deviceTypeClauseFound{false}, + enterClauseFound{false}; + for (const parser::OmpClause &clause : x.v.Clauses().v) { + common::visit( + common::visitors{ + [&](const parser::OmpClause::To &toClause) { + toClauseFound = true; + auto &objList{std::get<parser::OmpObjectList>(toClause.v.t)}; + CheckSymbolNames(dirName.source, objList); + CheckVarIsNotPartOfAnotherVar(dirName.source, objList); + CheckThreadprivateOrDeclareTargetVar(objList); + }, + [&](const parser::OmpClause::Link &linkClause) { + CheckSymbolNames(dirName.source, linkClause.v); + CheckVarIsNotPartOfAnotherVar(dirName.source, linkClause.v); + CheckThreadprivateOrDeclareTargetVar(linkClause.v); + }, + [&](const parser::OmpClause::Enter &enterClause) { + enterClauseFound = true; + auto &objList{std::get<parser::OmpObjectList>(enterClause.v.t)}; + CheckSymbolNames(dirName.source, objList); + CheckVarIsNotPartOfAnotherVar(dirName.source, objList); + CheckThreadprivateOrDeclareTargetVar(objList); + }, + [&](const parser::OmpClause::DeviceType &deviceTypeClause) { + deviceTypeClauseFound = true; + if (deviceTypeClause.v.v != + parser::OmpDeviceTypeClause::DeviceTypeDescription::Host) { + // Function / subroutine explicitly marked as runnable by the + // target device. + deviceConstructFound_ = true; + } + }, + [&](const auto &) {}, + }, + clause.u); + + if ((toClauseFound || enterClauseFound) && !deviceTypeClauseFound) { + deviceConstructFound_ = true; + } + } + dirContext_.pop_back(); } diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h index 176f6568814c5..193784555a887 100644 --- a/flang/lib/Semantics/check-omp-structure.h +++ b/flang/lib/Semantics/check-omp-structure.h @@ -113,9 +113,6 @@ class OmpStructureChecker void Leave(const parser::OpenMPDeclareTargetConstruct &); void Enter(const parser::OpenMPDepobjConstruct &); void Leave(const parser::OpenMPDepobjConstruct &); - void Enter(const parser::OmpDeclareTargetWithList &); - void Enter(const parser::OmpDeclareTargetWithClause &); - void Leave(const parser::OmpDeclareTargetWithClause &); void Enter(const parser::OpenMPDispatchConstruct &); void Leave(const parser::OpenMPDispatchConstruct &); void Enter(const parser::OmpErrorDirective &); diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index 218e3e7266ca9..7ef211c8b428c 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -2324,22 +2324,17 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPCriticalConstruct &x) { bool OmpAttributeVisitor::Pre(const parser::OpenMPDeclareTargetConstruct &x) { PushContext(x.source, llvm::omp::Directive::OMPD_declare_target); - const auto &spec{std::get<parser::OmpDeclareTargetSpecifier>(x.t)}; - if (const auto *objectList{parser::Unwrap<parser::OmpObjectList>(spec.u)}) { - ResolveOmpObjectList(*objectList, Symbol::Flag::OmpDeclareTarget); - } else if (const auto *clauseList{ - parser::Unwrap<parser::OmpClauseList>(spec.u)}) { - for (const auto &clause : clauseList->v) { - if (const auto *toClause{std::get_if<parser::OmpClause::To>(&clause.u)}) { - auto &objList{std::get<parser::OmpObjectList>(toClause->v.t)}; - ResolveOmpObjectList(objList, Symbol::Flag::OmpDeclareTarget); - } else if (const auto *linkClause{ - std::get_if<parser::OmpClause::Link>(&clause.u)}) { - ResolveOmpObjectList(linkClause->v, Symbol::Flag::OmpDeclareTarget); - } else if (const auto *enterClause{ - std::get_if<parser::OmpClause::Enter>(&clause.u)}) { - ResolveOmpObjectList(std::get<parser::OmpObjectList>(enterClause->v.t), - Symbol::Flag::OmpDeclareTarget); + + for (const parser::OmpArgument &arg : x.v.Arguments().v) { + if (auto *object{omp::GetArgumentObject(arg)}) { + ResolveOmpObject(*object, Symbol::Flag::OmpDeclareTarget); + } + } + + for (const parser::OmpClause &clause : x.v.Clauses().v) { + if (auto *objects{parser::omp::GetOmpObjectList(clause)}) { + for (const parser::OmpObject &object : objects->v) { + ResolveOmpObject(object, Symbol::Flag::OmpDeclareTarget); } } } diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index 3a6115dae2da5..9b728d6b70deb 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -24,6 +24,7 @@ #include "flang/Evaluate/intrinsics.h" #include "flang/Evaluate/tools.h" #include "flang/Evaluate/type.h" +#include "flang/Parser/openmp-utils.h" #include "flang/Parser/parse-tree-visitor.h" #include "flang/Parser/parse-tree.h" #include "flang/Parser/tools.h" @@ -1572,51 +1573,41 @@ class OmpVisitor : public virtual DeclarationVisitor { } void Post(const parser::OpenMPThreadprivate &) { SkipImplicitTyping(false); } bool Pre(const parser::OpenMPDeclareTargetConstruct &x) { - const auto &spec{std::get<parser::OmpDeclareTargetSpecifier>(x.t)}; - auto populateDeclareTargetNames{[this](const parser::OmpObjectList - &objectList) { - for (const auto &ompObject : objectList.v) { - common::visit( - common::visitors{ - [&](const parser::Designator &designator) { - if (const auto *name{ - semantics::getDesignatorNameIfDataRef(designator)}) { - specPartState_.declareTargetNames.insert(name->source); - } - }, - [&](const parser::Name &name) { - specPartState_.declareTargetNames.insert(name.source); - }, - [&](const parser::OmpObject::Invalid &invalid) { - switch (invalid.v) { - SWITCH_COVERS_ALL_CASES - case parser::OmpObject::Invalid::Kind::BlankCommonBlock: - context().Say(invalid.source, - "Blank common blocks are not allowed as directive or clause arguments"_err_en_US); - break; - } - }, - }, - ompObject.u); - } + auto addObjectName{[&](const parser::OmpObject &object) { + common::visit( + common::visitors{ + [&](const parser::Designator &designator) { + if (const auto *name{ + semantics::getDesignatorNameIfDataRef(designator)}) { + specPartState_.declareTargetNames.insert(name->source); + } + }, + [&](const parser::Name &name) { + specPartState_.declareTargetNames.insert(name.source); + }, + [&](const parser::OmpObject::Invalid &invalid) { + switch (invalid.v) { + SWITCH_COVERS_ALL_CASES + case parser::OmpObject::Invalid::Kind::BlankCommonBlock: + context().Say(invalid.source, + "Blank common blocks are not allowed as directive or clause arguments"_err_en_US); + break; + } + }, + }, + object.u); }}; - if (const auto *objectList{parser::Unwrap<parser::OmpObjectList>(spec.u)}) { - populateDeclareTargetNames(*objectList); - } else if (const auto *clauseList{ - parser::Unwrap<parser::OmpClauseList>(spec.u)}) { - for (const auto &clause : clauseList->v) { - if (const auto *toClause{ - std::get_if<parser::OmpClause::To>(&clause.u)}) { - populateDeclareTargetNames( - std::get<parser::OmpObjectList>(toClause->v.t)); - } else if (const auto *linkClause{ - std::get_if<parser::OmpClause::Link>(&clause.u)}) { - populateDeclareTargetNames(linkClause->v); - } else if (const auto *enterClause{ - std::get_if<parser::OmpClause::Enter>(&clause.u)}) { - populateDeclareTargetNames( - std::get<parser::OmpObjectList>(enterClause->v.t)); + for (const parser::OmpArgument &arg : x.v.Arguments().v) { + if (auto *object{omp::GetArgumentObject(arg)}) { + addObjectName(*object); + } + } + + for (const parser::OmpClause &clause : x.v.Clauses().v) { + if (auto *objects{parser::omp::GetOmpObjectList(clause)}) { + for (const parser::OmpObject &object : objects->v) { + addObjectName(object); } } } diff --git a/flang/test/Parser/OpenMP/declare-target-indirect-tree.f90 b/flang/test/Parser/OpenMP/declare-target-indirect-tree.f90 index 916bd66017ce0..16dc4eb44e6fd 100644 --- a/flang/test/Parser/OpenMP/declare-target-indirect-tree.f90 +++ b/flang/test/Parser/OpenMP/declare-target-indirect-tree.f90 @@ -1,5 +1,3 @@ -! REQUIRES: openmp_runtime - ! RUN: %flang_fc1 %openmp_flags -fopenmp-version=52 -fdebug-dump-parse-tree %s | FileCheck %s ! RUN: %flang_fc1 %openmp_flags -fdebug-unparse -fopenmp-version=52 %s | FileCheck %s --check-prefix="UNPARSE" @@ -15,11 +13,14 @@ function func() result(i) contains function func1() result(i) !$omp declare target enter(func1) indirect(.true.) - !CHECK: | | | | | OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> Enter -> OmpEnterClause - !CHECK-NEXT: | | | | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'func1' - !CHECK-NEXT: | | | | | OmpClause -> Indirect -> OmpIndirectClause -> Scalar -> Logical -> Expr = '.true._4' - !CHECK-NEXT: | | | | | | LiteralConstant -> LogicalLiteralConstant - !CHECK-NEXT: | | | | | | | bool = 'true' + !CHECK: OpenMPDeclarativeConstruct -> OpenMPDeclareTargetConstruct -> OmpDirectiveSpecification + !CHECK-NEXT: | OmpDirectiveName -> llvm::omp::Directive = declare target + !CHECK-NEXT: | OmpClauseList -> OmpClause -> Enter -> OmpEnterClause + !CHECK-NEXT: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'func1' + !CHECK-NEXT: | OmpClause -> Indirect -> OmpIndirectClause -> Scalar -> Logical -> Expr = '.true._4' + !CHECK-NEXT: | | LiteralConstant -> LogicalLiteralConstant + !CHECK-NEXT: | | | bool = 'true' + !CHECK-NEXT: | Flags = None character(1) :: i i = 'a' return @@ -27,9 +28,12 @@ function func1() result(i) function func2() result(i) !$omp declare target enter(func2) indirect - !CHECK: | | | | | OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> Enter -> OmpEnterClause - !CHECK-NEXT: | | | | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'func2' - !CHECK-NEXT: | | | | | OmpClause -> Indirect -> OmpIndirectClause -> + !CHECK: OpenMPDeclarativeConstruct -> OpenMPDeclareTargetConstruct -> OmpDirectiveSpecification + !CHECK-NEXT: | OmpDirectiveName -> llvm::omp::Directive = declare target + !CHECK-NEXT: | OmpClauseList -> OmpClause -> Enter -> OmpEnterClause + !CHECK-NEXT: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'func2' + !CHECK-NEXT: | OmpClause -> Indirect -> OmpIndirectClause -> + !CHECK-NEXT: | Flags = None character(1) :: i i = 'b' return @@ -51,5 +55,5 @@ program main end program -!UNPARSE: !$OMP DECLARE TARGET ENTER(func1) INDIRECT(.true._4) -!UNPARSE: !$OMP DECLARE TARGET ENTER(func2) INDIRECT() +!UNPARSE: !$OMP DECLARE TARGET ENTER(func1) INDIRECT(.true._4) +!UNPARSE: !$OMP DECLARE TARGET ENTER(func2) INDIRECT() diff --git a/flang/test/Parser/OpenMP/declare-target-to-clause.f90 b/flang/test/Parser/OpenMP/declare-target-to-clause.f90 index bcb23f821e403..8198f44bcec18 100644 --- a/flang/test/Parser/OpenMP/declare-target-to-clause.f90 +++ b/flang/test/Parser/OpenMP/declare-target-to-clause.f90 @@ -9,11 +9,13 @@ module m !UNPARSE: MODULE m !UNPARSE: INTEGER x, y -!UNPARSE: !$OMP DECLARE TARGET TO(x,y) +!UNPARSE: !$OMP DECLARE TARGET TO(x,y) !UNPARSE: END MODULE -!PARSE-TREE: OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> To -> OmpToClause -!PARSE-TREE: | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' -!PARSE-TREE: | OmpObject -> Designator -> DataRef -> Name = 'y' -!PARSE-TREE: | bool = 'true' - +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareTargetConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare target +!PARSE-TREE: | OmpClauseList -> OmpClause -> To -> OmpToClause +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: | | OmpObject -> Designator -> DataRef -> Name = 'y' +!PARSE-TREE: | | bool = 'true' +!PARSE-TREE: | Flags = None diff --git a/flang/test/Parser/OpenMP/declare_target-device_type.f90 b/flang/test/Parser/OpenMP/declare_target-device_type.f90 index b6903614a628e..7df796288f4d4 100644 --- a/flang/test/Parser/OpenMP/declare_target-device_type.f90 +++ b/flang/test/Parser/OpenMP/declare_target-device_type.f90 @@ -3,35 +3,113 @@ subroutine openmp_declare_target integer, save :: x, y - !CHECK: !$omp declare target device_type(host) enter(x) +!CHECK: !$omp declare target device_type(host) enter(x) + +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareTargetConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare target +!PARSE-TREE: | OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> DeviceTypeDescription = Host +!PARSE-TREE: | OmpClause -> Enter -> OmpEnterClause +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: | Flags = None !$omp declare target device_type(host) enter(x) - !CHECK: !$omp declare target device_type(nohost) enter(x) + +!CHECK: !$omp declare target device_type(nohost) enter(x) + +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareTargetConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare target +!PARSE-TREE: | OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> DeviceTypeDescription = Nohost +!PARSE-TREE: | OmpClause -> Enter -> OmpEnterClause +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: | Flags = None !$omp declare target device_type(nohost) enter(x) - !CHECK: !$omp declare target device_type(any) enter(x) + +!CHECK: !$omp declare target device_type(any) enter(x) + +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareTargetConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare target +!PARSE-TREE: | OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> DeviceTypeDescription = Any +!PARSE-TREE: | OmpClause -> Enter -> OmpEnterClause +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: | Flags = None !$omp declare target device_type(any) enter(x) - !CHECK: !$omp declare target device_type(host) to(x) +!CHECK: !$omp declare target device_type(host) to(x) + +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareTargetConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare target +!PARSE-TREE: | OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> DeviceTypeDescription = Host +!PARSE-TREE: | OmpClause -> To -> OmpToClause +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: | | bool = 'true' +!PARSE-TREE: | Flags = None !$omp declare target device_type(host) to(x) - !CHECK: !$omp declare target device_type(nohost) to(x) + +!CHECK: !$omp declare target device_type(nohost) to(x) + +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareTargetConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare target +!PARSE-TREE: | OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> DeviceTypeDescription = Nohost +!PARSE-TREE: | OmpClause -> To -> OmpToClause +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: | | bool = 'true' +!PARSE-TREE: | Flags = None !$omp declare target device_type(nohost) to(x) - !CHECK: !$omp declare target device_type(any) to(x) + +!CHECK: !$omp declare target device_type(any) to(x) + +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareTargetConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare target +!PARSE-TREE: | OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> DeviceTypeDescription = Any +!PARSE-TREE: | OmpClause -> To -> OmpToClause +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: | | bool = 'true' +!PARSE-TREE: | Flags = None !$omp declare target device_type(any) to(x) - !CHECK: !$omp declare target device_type(host) enter(y) to(x) +!CHECK: !$omp declare target device_type(host) enter(y) to(x) + +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareTargetConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare target +!PARSE-TREE: | OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> DeviceTypeDescription = Host +!PARSE-TREE: | OmpClause -> Enter -> OmpEnterClause +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'y' +!PARSE-TREE: | OmpClause -> To -> OmpToClause +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: | | bool = 'true' +!PARSE-TREE: | Flags = None !$omp declare target device_type(host) enter(y) to(x) - !CHECK: !$omp declare target device_type(nohost) enter(y) to(x) + +!CHECK: !$omp declare target device_type(nohost) enter(y) to(x) + +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareTargetConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare target +!PARSE-TREE: | OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> DeviceTypeDescription = Nohost +!PARSE-TREE: | OmpClause -> Enter -> OmpEnterClause +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'y' +!PARSE-TREE: | OmpClause -> To -> OmpToClause +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: | | bool = 'true' +!PARSE-TREE: | Flags = None !$omp declare target device_type(nohost) enter(y) to(x) - !CHECK: !$omp declare target device_type(any) enter(y) to(x) + +!CHECK: !$omp declare target device_type(any) enter(y) to(x) + +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareTargetConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare target +!PARSE-TREE: | OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> DeviceTypeDescription = Any +!PARSE-TREE: | OmpClause -> Enter -> OmpEnterClause +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'y' +!PARSE-TREE: | OmpClause -> To -> OmpToClause +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: | | bool = 'true' +!PARSE-TREE: | Flags = None !$omp declare target device_type(any) enter(y) to(x) + integer :: a(1024), i - !CHECK: do +!CHECK: do do i = 1, 1024 a(i) = i - !CHECK: end do +!CHECK: end do end do -!PARSE-TREE: OpenMPDeclarativeConstruct -> OpenMPDeclareTargetConstruct -!PARSE-TREE: OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> DeviceTypeDescription = Host -!PARSE-TREE: OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> DeviceTypeDescription = Nohost -!PARSE-TREE: OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> DeviceTypeDescription = Any END subroutine openmp_declare_target diff --git a/flang/test/Parser/OpenMP/enter-automap-modifier.f90 b/flang/test/Parser/OpenMP/enter-automap-modifier.f90 index 1f361ca5c2f06..bc5b5eb3e7ef3 100644 --- a/flang/test/Parser/OpenMP/enter-automap-modifier.f90 +++ b/flang/test/Parser/OpenMP/enter-automap-modifier.f90 @@ -8,9 +8,12 @@ program automap !UNPARSE: PROGRAM AUTOMAP !UNPARSE: INTEGER x -!UNPARSE: !$OMP DECLARE TARGET ENTER(AUTOMAP: x) +!UNPARSE: !$OMP DECLARE_TARGET ENTER(AUTOMAP: x) !UNPARSE: END PROGRAM -!PARSE-TREE: OmpClauseList -> OmpClause -> Enter -> OmpEnterClause -!PARSE-TREE-NEXT: | Modifier -> OmpAutomapModifier -> Value = Automap -!PARSE-TREE-NEXT: | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareTargetConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare target +!PARSE-TREE: | OmpClauseList -> OmpClause -> Enter -> OmpEnterClause +!PARSE-TREE: | | Modifier -> OmpAutomapModifier -> Value = Automap +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: | Flags = None diff --git a/flang/test/Parser/OpenMP/openmp6-directive-spellings.f90 b/flang/test/Parser/OpenMP/openmp6-directive-spellings.f90 index b72c5a2c1c086..f4cdd556bd4e5 100644 --- a/flang/test/Parser/OpenMP/openmp6-directive-spellings.f90 +++ b/flang/test/Parser/OpenMP/openmp6-directive-spellings.f90 @@ -124,12 +124,13 @@ subroutine f04 end !UNPARSE: SUBROUTINE f04 -!UNPARSE: !$OMP DECLARE TARGET +!UNPARSE: !$OMP DECLARE_TARGET !UNPARSE: END SUBROUTINE -!PARSE-TREE: OpenMPDeclarativeConstruct -> OpenMPDeclareTargetConstruct -!PARSE-TREE: | Verbatim -!PARSE-TREE: | OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> +!PARSE-TREE: OpenMPDeclarativeConstruct -> OpenMPDeclareTargetConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare target +!PARSE-TREE: | OmpClauseList -> +!PARSE-TREE: | Flags = None subroutine f05 implicit none diff --git a/flang/test/Semantics/OpenMP/blank-common-block.f90 b/flang/test/Semantics/OpenMP/blank-common-block.f90 index 4a217fced0ff7..e410f0c56d1c0 100644 --- a/flang/test/Semantics/OpenMP/blank-common-block.f90 +++ b/flang/test/Semantics/OpenMP/blank-common-block.f90 @@ -4,6 +4,7 @@ module m integer :: a common // a !ERROR: Blank common blocks are not allowed as directive or clause arguments + !ERROR: An argument to the DECLARE TARGET directive should be an extended-list-item !$omp declare_target(//) !ERROR: Blank common blocks are not allowed as directive or clause arguments !$omp threadprivate(//) diff --git a/flang/test/Semantics/OpenMP/declare-target-function-name-with-symbols.f90 b/flang/test/Semantics/OpenMP/declare-target-function-name-with-symbols.f90 index 9a0acdb3dd100..3439e6fd13981 100644 --- a/flang/test/Semantics/OpenMP/declare-target-function-name-with-symbols.f90 +++ b/flang/test/Semantics/OpenMP/declare-target-function-name-with-symbols.f90 @@ -19,7 +19,7 @@ end module test !CHECK: !DEF: /test/ex/b ObjectEntity INTEGER(4) !CHECK: !DEF: /test/ex/c ObjectEntity INTEGER(4) !CHECK: function ex(a, b, c) -!CHECK: !$omp declare target (ex) +!CHECK: !$omp declare target(ex) !CHECK: !REF: /test/ex/a !CHECK: !REF: /test/ex/b !CHECK: !REF: /test/ex/c >From 0f8c8248ca815c1de700e93d7df1d753c10d215e Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek <krzysztof.parzys...@amd.com> Date: Wed, 24 Sep 2025 12:58:20 -0500 Subject: [PATCH 2/4] Remove unused AST classes --- flang/include/flang/Parser/dump-parse-tree.h | 3 --- flang/include/flang/Parser/parse-tree.h | 18 ------------------ flang/lib/Parser/unparse.cpp | 3 --- 3 files changed, 24 deletions(-) diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index 7540d38baa584..fadca0a3876f4 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -538,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) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index e7593d9875097..486be8b60ff8c 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -4943,24 +4943,6 @@ struct OmpDeclareVariantDirective { CharBlock source; }; -// 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); - 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] // diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index be166bcb743ba..a2b0b9ef3196c 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2492,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("("); >From f5eb99ffbc20b6d787b62d620471e556cf71ab57 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek <krzysztof.parzys...@amd.com> Date: Wed, 24 Sep 2025 14:12:44 -0500 Subject: [PATCH 3/4] Fix example --- flang/examples/FeatureList/FeatureList.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/flang/examples/FeatureList/FeatureList.cpp b/flang/examples/FeatureList/FeatureList.cpp index 569d2b2307f36..daa012e3eb08b 100644 --- a/flang/examples/FeatureList/FeatureList.cpp +++ b/flang/examples/FeatureList/FeatureList.cpp @@ -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) >From eb12400ffc25b62205183f3102a1e0afdb785510 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek <krzysztof.parzys...@amd.com> Date: Wed, 24 Sep 2025 14:38:40 -0500 Subject: [PATCH 4/4] [flang][OpenMP] Use OmpDirectiveSpecification in ASSUMES --- flang/include/flang/Parser/openmp-utils.h | 2 -- flang/include/flang/Parser/parse-tree.h | 4 ++-- flang/lib/Parser/openmp-parsers.cpp | 6 ++++-- flang/lib/Parser/unparse.cpp | 4 ++-- flang/lib/Semantics/check-omp-structure.cpp | 4 ---- flang/test/Parser/OpenMP/assumption.f90 | 8 +++++--- 6 files changed, 13 insertions(+), 15 deletions(-) diff --git a/flang/include/flang/Parser/openmp-utils.h b/flang/include/flang/Parser/openmp-utils.h index bf54f970a7d3a..77c31b939e522 100644 --- a/flang/include/flang/Parser/openmp-utils.h +++ b/flang/include/flang/Parser/openmp-utils.h @@ -39,7 +39,6 @@ struct ConstructId { } 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(OpenMPExecutableAllocate, D::OMPD_allocate); MAKE_CONSTR_ID(OpenMPRequiresConstruct, D::OMPD_requires); @@ -94,7 +93,6 @@ struct DirectiveNameScope { if constexpr (std::is_base_of_v<OmpBlockConstruct, T>) { return std::get<OmpBeginDirective>(x.t).DirName(); } 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, OpenMPExecutableAllocate> || std::is_same_v<T, OpenMPRequiresConstruct>) { diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 486be8b60ff8c..bd55166eb9f80 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -4877,8 +4877,8 @@ struct OpenMPUtilityConstruct { // ASSUMES absent-clause | contains-clause | holds-clause | no-openmp-clause | // no-openmp-routines-clause | no-parallelism-clause struct OpenMPDeclarativeAssumes { - TUPLE_CLASS_BOILERPLATE(OpenMPDeclarativeAssumes); - std::tuple<Verbatim, OmpClauseList> t; + WRAPPER_CLASS_BOILERPLATE( + OpenMPDeclarativeAssumes, OmpDirectiveSpecification); CharBlock source; }; diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index bd080386c0aea..12e89e8c35456 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -1852,8 +1852,10 @@ TYPE_PARSER( lookAhead(endOmpLine / !statement(allocateStmt))) // Assumes Construct -TYPE_PARSER(sourced(construct<OpenMPDeclarativeAssumes>( - verbatim("ASSUMES"_tok), Parser<OmpClauseList>{}))) +TYPE_PARSER(construct<OpenMPDeclarativeAssumes>( + predicated(OmpDirectiveNameParser{}, + IsDirective(llvm::omp::Directive::OMPD_assumes)) >= + Parser<OmpDirectiveSpecification>{})) // Declarative constructs TYPE_PARSER( diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index a2b0b9ef3196c..9812a656092ac 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2558,8 +2558,8 @@ class UnparseVisitor { void Unparse(const OpenMPDeclarativeAssumes &x) { BeginOpenMP(); - Word("!$OMP ASSUMES "); - Walk(std::get<OmpClauseList>(x.t)); + Word("!$OMP "); + Walk(x.v); Put("\n"); EndOpenMP(); } diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 05ff541657b1a..6538e0b794791 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -620,10 +620,6 @@ template <typename Checker> struct DirectiveSpellingVisitor { checker_(GetDirName(x.t).source, Directive::OMPD_allocators); return false; } - bool Pre(const parser::OpenMPDeclarativeAssumes &x) { - checker_(std::get<parser::Verbatim>(x.t).source, Directive::OMPD_assumes); - return false; - } bool Pre(const parser::OpenMPGroupprivate &x) { checker_(x.v.DirName().source, Directive::OMPD_groupprivate); return false; diff --git a/flang/test/Parser/OpenMP/assumption.f90 b/flang/test/Parser/OpenMP/assumption.f90 index 0f333f99f9085..86cbad9e42f78 100644 --- a/flang/test/Parser/OpenMP/assumption.f90 +++ b/flang/test/Parser/OpenMP/assumption.f90 @@ -141,9 +141,11 @@ program p end program p !UNPARSE: PROGRAM p -!UNPARSE: !$OMP ASSUMES NO_OPENMP +!UNPARSE: !$OMP ASSUMES NO_OPENMP !UNPARSE: END PROGRAM p -!PARSE-TREE: OpenMPDeclarativeConstruct -> OpenMPDeclarativeAssumes -!PARSE-TREE: | Verbatim +!PARSE-TREE: OpenMPDeclarativeConstruct -> OpenMPDeclarativeAssumes -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = assumes !PARSE-TREE: | OmpClauseList -> OmpClause -> NoOpenmp +!PARSE-TREE: | Flags = None +!PARSE-TREE: ImplicitPart -> _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits