[flang-commits] [flang] 727aad1 - [flang][OpenMP] Use OmpDirectiveSpecification in DECLARE_TARGET (#160573)
via flang-commits
flang-commits at lists.llvm.org
Fri Sep 26 13:47:35 PDT 2025
Author: Krzysztof Parzyszek
Date: 2025-09-26T15:47:31-05:00
New Revision: 727aad15f0a897826fc9102b5a090b977c554097
URL: https://github.com/llvm/llvm-project/commit/727aad15f0a897826fc9102b5a090b977c554097
DIFF: https://github.com/llvm/llvm-project/commit/727aad15f0a897826fc9102b5a090b977c554097.diff
LOG: [flang][OpenMP] Use OmpDirectiveSpecification in DECLARE_TARGET (#160573)
Added:
Modified:
flang/examples/FeatureList/FeatureList.cpp
flang/include/flang/Parser/dump-parse-tree.h
flang/include/flang/Parser/openmp-utils.h
flang/include/flang/Parser/parse-tree.h
flang/lib/Lower/OpenMP/OpenMP.cpp
flang/lib/Parser/openmp-parsers.cpp
flang/lib/Parser/unparse.cpp
flang/lib/Semantics/check-omp-structure.cpp
flang/lib/Semantics/check-omp-structure.h
flang/lib/Semantics/resolve-directives.cpp
flang/lib/Semantics/resolve-names.cpp
flang/test/Parser/OpenMP/declare-target-indirect-tree.f90
flang/test/Parser/OpenMP/declare-target-to-clause.f90
flang/test/Parser/OpenMP/declare_target-device_type.f90
flang/test/Parser/OpenMP/enter-automap-modifier.f90
flang/test/Parser/OpenMP/openmp6-directive-spellings.f90
flang/test/Semantics/OpenMP/blank-common-block.f90
flang/test/Semantics/OpenMP/declare-target-function-name-with-symbols.f90
Removed:
################################################################################
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)
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/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..486be8b60ff8c 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4943,28 +4943,16 @@ 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]
+//
+// 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..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("(");
@@ -2582,8 +2579,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 57bc53cfe8561..9c1c614654b51 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 43b49e01c89c7..2f350f016c1f5 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
More information about the flang-commits
mailing list