diff --git a/flang/include/flang/Parser/openmp-utils.h b/flang/include/flang/Parser/openmp-utils.h index 98e849eef9bbc..19e23e4d9f62b 100644 --- a/flang/include/flang/Parser/openmp-utils.h +++ b/flang/include/flang/Parser/openmp-utils.h @@ -43,7 +43,6 @@ MAKE_CONSTR_ID(OmpErrorDirective, D::OMPD_error); MAKE_CONSTR_ID(OmpMetadirectiveDirective, D::OMPD_metadirective); MAKE_CONSTR_ID(OpenMPDeclarativeAllocate, D::OMPD_allocate); MAKE_CONSTR_ID(OpenMPDeclarativeAssumes, D::OMPD_assumes); -MAKE_CONSTR_ID(OpenMPDeclareMapperConstruct, D::OMPD_declare_mapper); MAKE_CONSTR_ID(OpenMPDeclareReductionConstruct, D::OMPD_declare_reduction); MAKE_CONSTR_ID(OpenMPDeclareSimdConstruct, D::OMPD_declare_simd); MAKE_CONSTR_ID(OpenMPDeclareTargetConstruct, D::OMPD_declare_target); @@ -105,7 +104,6 @@ struct DirectiveNameScope { std::is_same_v || std::is_same_v || std::is_same_v || - std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index bd0debe297916..2063eccf8b7f4 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -4951,20 +4951,18 @@ struct OpenMPDeclareTargetConstruct { // OMP v5.2: 5.8.8 // declare-mapper -> DECLARE MAPPER ([mapper-name :] type :: var) map-clauses struct OpenMPDeclareMapperConstruct { - TUPLE_CLASS_BOILERPLATE(OpenMPDeclareMapperConstruct); + WRAPPER_CLASS_BOILERPLATE( + OpenMPDeclareMapperConstruct, OmpDirectiveSpecification); CharBlock source; - std::tuple t; }; // ref: 5.2: Section 5.5.11 139-141 // 2.16 declare-reduction -> DECLARE REDUCTION (reduction-identifier : type-list // : combiner) [initializer-clause] struct OpenMPDeclareReductionConstruct { - TUPLE_CLASS_BOILERPLATE(OpenMPDeclareReductionConstruct); + WRAPPER_CLASS_BOILERPLATE( + OpenMPDeclareReductionConstruct, OmpDirectiveSpecification); CharBlock source; - std::tuple, - std::optional> - t; }; // 2.8.2 declare-simd -> DECLARE SIMD [(proc-name)] [declare-simd-clause[ [,] diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h index 774fc9873f7bc..e90e9c617805d 100644 --- a/flang/include/flang/Semantics/symbol.h +++ b/flang/include/flang/Semantics/symbol.h @@ -30,8 +30,7 @@ class raw_ostream; } namespace Fortran::parser { struct Expr; -struct OpenMPDeclareReductionConstruct; -struct OmpMetadirectiveDirective; +struct OpenMPDeclarativeConstruct; } namespace Fortran::semantics { @@ -736,9 +735,7 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &, const GenericDetails &); class UserReductionDetails { public: using TypeVector = std::vector; - using DeclInfo = std::variant; - using DeclVector = std::vector; + using DeclVector = std::vector; UserReductionDetails() = default; @@ -756,7 +753,9 @@ class UserReductionDetails { return false; } - void AddDecl(const DeclInfo &decl) { declList_.emplace_back(decl); } + void AddDecl(const parser::OpenMPDeclarativeConstruct *decl) { + declList_.emplace_back(decl); + } const DeclVector &GetDeclList() const { return declList_; } private: diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index 5681be664d450..d2e865b3e1d0c 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -3441,18 +3441,20 @@ genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, TODO(converter.getCurrentLocation(), "OpenMPDeclareSimdConstruct"); } -static void -genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, - semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, - const parser::OpenMPDeclareMapperConstruct &declareMapperConstruct) { - mlir::Location loc = converter.genLocation(declareMapperConstruct.source); +static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, + semantics::SemanticsContext &semaCtx, + lower::pft::Evaluation &eval, + const parser::OpenMPDeclareMapperConstruct &construct) { + mlir::Location loc = converter.genLocation(construct.source); fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); + const parser::OmpArgumentList &args = construct.v.Arguments(); + assert(args.v.size() == 1 && "Expecting single argument"); lower::StatementContext stmtCtx; - const auto &spec = - std::get(declareMapperConstruct.t); - const auto &mapperName{std::get(spec.t)}; - const auto &varType{std::get(spec.t)}; - const auto &varName{std::get(spec.t)}; + const auto *spec = std::get_if(&args.v.front().u); + assert(spec && "Expecting mapper specifier"); + const auto &mapperName{std::get(spec->t)}; + const auto &varType{std::get(spec->t)}; + const auto &varName{std::get(spec->t)}; assert(varType.declTypeSpec->category() == semantics::DeclTypeSpec::Category::TypeDerived && "Expected derived type"); @@ -3476,9 +3478,7 @@ genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, // Populate the declareMapper region with the map information. mlir::omp::DeclareMapperInfoOperands clauseOps; - const auto *clauseList{ - parser::Unwrap(declareMapperConstruct.t)}; - List clauses = makeClauses(*clauseList, semaCtx); + List clauses = makeClauses(construct.v.Clauses(), semaCtx); ClauseProcessor cp(converter, semaCtx, clauses); cp.processMap(loc, stmtCtx, clauseOps); mlir::omp::DeclareMapperInfoOp::create(firOpBuilder, loc, clauseOps.mapVars); diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 8ab9905123135..57b812665073a 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -1708,9 +1708,9 @@ TYPE_PARSER(sourced(construct( // 2.16 Declare Reduction Construct TYPE_PARSER(sourced(construct( - verbatim("DECLARE REDUCTION"_tok) || verbatim("DECLARE_REDUCTION"_tok), - "(" >> indirect(Parser{}) / ")", - maybe(Parser{})))) + predicated(Parser{}, + IsDirective(llvm::omp::Directive::OMPD_declare_reduction)) >= + Parser{}))) // declare-target with list TYPE_PARSER(sourced(construct( @@ -1756,8 +1756,9 @@ TYPE_PARSER(applyFunction(ConstructOmpMapperSpecifier, // OpenMP 5.2: 5.8.8 Declare Mapper Construct TYPE_PARSER(sourced(construct( - verbatim("DECLARE MAPPER"_tok) || verbatim("DECLARE_MAPPER"_tok), - parenthesized(Parser{}), Parser{}))) + predicated(Parser{}, + IsDirective(llvm::omp::Directive::OMPD_declare_mapper)) >= + Parser{}))) TYPE_PARSER(construct(Parser{}) || construct(Parser{})) diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 9d73bcafa0e15..750f1258be2fc 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2495,11 +2495,8 @@ class UnparseVisitor { } void Unparse(const OpenMPDeclareReductionConstruct &x) { BeginOpenMP(); - Word("!$OMP DECLARE REDUCTION "); - Put("("); - Walk(std::get>(x.t)); - Put(")"); - Walk(std::get>(x.t)); + Word("!$OMP "); + Walk(x.v); Put("\n"); EndOpenMP(); } @@ -2547,21 +2544,10 @@ class UnparseVisitor { Put("\n"); EndOpenMP(); } - void Unparse(const OpenMPDeclareMapperConstruct &z) { + void Unparse(const OpenMPDeclareMapperConstruct &x) { BeginOpenMP(); - Word("!$OMP DECLARE MAPPER ("); - const auto &spec{std::get(z.t)}; - const auto &mapperName{std::get(spec.t)}; - if (mapperName.find(llvm::omp::OmpDefaultMapperName) == std::string::npos) { - Walk(mapperName); - Put(":"); - } - Walk(std::get(spec.t)); - Put("::"); - Walk(std::get(spec.t)); - Put(")"); - - Walk(std::get(z.t)); + Word("!$OMP "); + Walk(x.v); Put("\n"); EndOpenMP(); } @@ -3082,11 +3068,7 @@ template void Unparse(llvm::raw_ostream &, const Expr &, const common::LangOptions &, Encoding, bool, bool, preStatementType *, AnalyzedObjectsAsFortran *); -template void Unparse( - llvm::raw_ostream &, const parser::OpenMPDeclareReductionConstruct &, - const common::LangOptions &, Encoding, bool, bool, preStatementType *, - AnalyzedObjectsAsFortran *); -template void Unparse(llvm::raw_ostream &, - const parser::OmpMetadirectiveDirective &, const common::LangOptions &, +template void Unparse(llvm::raw_ostream &, + const parser::OpenMPDeclarativeConstruct &, const common::LangOptions &, Encoding, bool, bool, preStatementType *, AnalyzedObjectsAsFortran *); } // namespace Fortran::parser diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index c39daef6b0ea9..bff5c2498344a 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -629,16 +629,6 @@ template struct DirectiveSpellingVisitor { checker_(std::get(x.t).source, Directive::OMPD_assumes); return false; } - bool Pre(const parser::OpenMPDeclareMapperConstruct &x) { - checker_( - std::get(x.t).source, Directive::OMPD_declare_mapper); - return false; - } - bool Pre(const parser::OpenMPDeclareReductionConstruct &x) { - checker_(std::get(x.t).source, - Directive::OMPD_declare_reduction); - return false; - } bool Pre(const parser::OpenMPDeclareSimdConstruct &x) { checker_( std::get(x.t).source, Directive::OMPD_declare_simd); @@ -1595,13 +1585,25 @@ void OmpStructureChecker::Leave(const parser::OmpDeclareTargetWithClause &x) { } void OmpStructureChecker::Enter(const parser::OpenMPDeclareMapperConstruct &x) { - const auto &dir{std::get(x.t)}; - PushContextAndClauseSets( - dir.source, llvm::omp::Directive::OMPD_declare_mapper); - const auto &spec{std::get(x.t)}; - const auto &type = std::get(spec.t); - if (!std::get_if(&type.u)) { - context_.Say(dir.source, "Type is not a derived type"_err_en_US); + const parser::OmpDirectiveName &dirName{x.v.DirName()}; + PushContextAndClauseSets(dirName.source, dirName.v); + + const parser::OmpArgumentList &args{x.v.Arguments()}; + if (args.v.size() != 1) { + context_.Say(args.source, + "DECLARE_MAPPER directive should have a single argument"_err_en_US); + return; + } + + const parser::OmpArgument &arg{args.v.front()}; + if (auto *spec{std::get_if(&arg.u)}) { + const auto &type = std::get(spec->t); + if (!std::get_if(&type.u)) { + context_.Say(arg.source, "Type is not a derived type"_err_en_US); + } + } else { + context_.Say(arg.source, + "The argument to the DECLARE_MAPPER directive should be a mapper-specifier"_err_en_US); } } @@ -1611,9 +1613,21 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareMapperConstruct &) { void OmpStructureChecker::Enter( const parser::OpenMPDeclareReductionConstruct &x) { - const auto &dir{std::get(x.t)}; - PushContextAndClauseSets( - dir.source, llvm::omp::Directive::OMPD_declare_reduction); + const parser::OmpDirectiveName &dirName{x.v.DirName()}; + PushContextAndClauseSets(dirName.source, dirName.v); + + const parser::OmpArgumentList &args{x.v.Arguments()}; + if (args.v.size() != 1) { + context_.Say(args.source, + "DECLARE_REDUCTION directive should have a single argument"_err_en_US); + return; + } + + const parser::OmpArgument &arg{args.v.front()}; + if (!std::holds_alternative(arg.u)) { + context_.Say(arg.source, + "The argument to the DECLARE_REDUCTION directive should be a reduction-specifier"_err_en_US); + } } void OmpStructureChecker::Leave( diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp index 82c8536902eb2..8074c94b41e1a 100644 --- a/flang/lib/Semantics/mod-file.cpp +++ b/flang/lib/Semantics/mod-file.cpp @@ -1056,19 +1056,8 @@ void ModFileWriter::PutUserReduction( // The module content for a OpenMP Declare Reduction is the OpenMP // declaration. There may be multiple declarations. // Decls are pointers, so do not use a reference. - for (const auto decl : details.GetDeclList()) { - common::visit( // - common::visitors{// - [&](const parser::OpenMPDeclareReductionConstruct *d) { - Unparse(os, *d, context_.langOptions()); - }, - [&](const parser::OmpMetadirectiveDirective *m) { - Unparse(os, *m, context_.langOptions()); - }, - [&](const auto &) { - DIE("Unknown OpenMP DECLARE REDUCTION content"); - }}, - decl); + for (const auto *decl : details.GetDeclList()) { + Unparse(os, *decl, context_.langOptions()); } } diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index 2d1bec9968593..48cd0e54a155a 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -2331,7 +2331,8 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPDeclareTargetConstruct &x) { } bool OmpAttributeVisitor::Pre(const parser::OpenMPDeclareMapperConstruct &x) { - PushContext(x.source, llvm::omp::Directive::OMPD_declare_mapper); + const parser::OmpDirectiveName &dirName{x.v.DirName()}; + PushContext(dirName.source, dirName.v); return true; } diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index cdd8d6ff2f60e..3b6140429f9ed 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -1479,16 +1479,6 @@ class OmpVisitor : public virtual DeclarationVisitor { static bool NeedsScope(const parser::OmpBlockConstruct &); static bool NeedsScope(const parser::OmpClause &); - bool Pre(const parser::OmpMetadirectiveDirective &x) { // - metaDirective_ = &x; - ++metaLevel_; - return true; - } - void Post(const parser::OmpMetadirectiveDirective &) { // - metaDirective_ = nullptr; - --metaLevel_; - } - bool Pre(const parser::OpenMPRequiresConstruct &x) { AddOmpSourceRange(x.source); return true; @@ -1496,34 +1486,16 @@ class OmpVisitor : public virtual DeclarationVisitor { bool Pre(const parser::OmpBlockConstruct &); void Post(const parser::OmpBlockConstruct &); bool Pre(const parser::OmpBeginDirective &x) { - AddOmpSourceRange(x.source); - // Manually resolve names in CRITICAL directives. This is because these - // names do not denote Fortran objects, and the CRITICAL directive causes - // them to be "auto-declared", i.e. inserted into the global scope. - // More specifically, they are not expected to have explicit declarations, - // and if they do the behavior is unspeficied. - if (x.DirName().v == llvm::omp::Directive::OMPD_critical) { - for (const parser::OmpArgument &arg : x.Arguments().v) { - ResolveCriticalName(arg); - } - } - return true; + return Pre(static_cast(x)); } - void Post(const parser::OmpBeginDirective &) { - messageHandler().set_currStmtSource(std::nullopt); + void Post(const parser::OmpBeginDirective &x) { + Post(static_cast(x)); } bool Pre(const parser::OmpEndDirective &x) { - AddOmpSourceRange(x.source); - // Manually resolve names in CRITICAL directives. - if (x.DirName().v == llvm::omp::Directive::OMPD_critical) { - for (const parser::OmpArgument &arg : x.Arguments().v) { - ResolveCriticalName(arg); - } - } - return true; + return Pre(static_cast(x)); } - void Post(const parser::OmpEndDirective &) { - messageHandler().set_currStmtSource(std::nullopt); + void Post(const parser::OmpEndDirective &x) { + Post(static_cast(x)); } bool Pre(const parser::OpenMPLoopConstruct &) { @@ -1532,15 +1504,21 @@ class OmpVisitor : public virtual DeclarationVisitor { } void Post(const parser::OpenMPLoopConstruct &) { PopScope(); } bool Pre(const parser::OmpBeginLoopDirective &x) { - AddOmpSourceRange(x.source); - return true; + return Pre(static_cast(x)); + } + void Post(const parser::OmpBeginLoopDirective &x) { + Post(static_cast(x)); + } + bool Pre(const parser::OmpEndLoopDirective &x) { + return Pre(static_cast(x)); + } + void Post(const parser::OmpEndLoopDirective &x) { + Post(static_cast(x)); } bool Pre(const parser::OpenMPDeclareMapperConstruct &x) { AddOmpSourceRange(x.source); - ProcessMapperSpecifier(std::get(x.t), - std::get(x.t)); - return false; + return true; } bool Pre(const parser::OpenMPDeclareSimdConstruct &x) { @@ -1580,24 +1558,10 @@ class OmpVisitor : public virtual DeclarationVisitor { } bool Pre(const parser::OpenMPDeclareReductionConstruct &x) { - AddOmpSourceRange(x.source); - ProcessReductionSpecifier( - std::get>(x.t).value(), - std::get>(x.t), x); - return false; - } - bool Pre(const parser::OmpMapClause &); - - void Post(const parser::OmpBeginLoopDirective &) { - messageHandler().set_currStmtSource(std::nullopt); - } - bool Pre(const parser::OmpEndLoopDirective &x) { AddOmpSourceRange(x.source); return true; } - void Post(const parser::OmpEndLoopDirective &) { - messageHandler().set_currStmtSource(std::nullopt); - } + bool Pre(const parser::OmpMapClause &); bool Pre(const parser::OpenMPSectionsConstruct &) { PushScope(Scope::Kind::OtherConstruct, nullptr); @@ -1605,18 +1569,16 @@ class OmpVisitor : public virtual DeclarationVisitor { } void Post(const parser::OpenMPSectionsConstruct &) { PopScope(); } bool Pre(const parser::OmpBeginSectionsDirective &x) { - AddOmpSourceRange(x.source); - return true; + return Pre(static_cast(x)); } - void Post(const parser::OmpBeginSectionsDirective &) { - messageHandler().set_currStmtSource(std::nullopt); + void Post(const parser::OmpBeginSectionsDirective &x) { + Post(static_cast(x)); } bool Pre(const parser::OmpEndSectionsDirective &x) { - AddOmpSourceRange(x.source); - return true; + return Pre(static_cast(x)); } - void Post(const parser::OmpEndSectionsDirective &) { - messageHandler().set_currStmtSource(std::nullopt); + void Post(const parser::OmpEndSectionsDirective &x) { + Post(static_cast(x)); } bool Pre(const parser::OpenMPThreadprivate &) { SkipImplicitTyping(true); @@ -1684,9 +1646,11 @@ class OmpVisitor : public virtual DeclarationVisitor { // can implicitly declare variables instead of only using the // ones already declared in the Fortran sources. SkipImplicitTyping(true); + declaratives_.push_back(&x); return true; } void Post(const parser::OpenMPDeclarativeConstruct &) { + declaratives_.pop_back(); SkipImplicitTyping(false); messageHandler().set_currStmtSource(std::nullopt); } @@ -1715,7 +1679,20 @@ class OmpVisitor : public virtual DeclarationVisitor { PopScope(); } } + bool Pre(const parser::OmpMapperSpecifier &x) { + // OmpMapperSpecifier is handled explicitly, and the AST traversal + // should not reach a point where it calls this function. + llvm_unreachable("This function should not be reached by AST traversal"); + } + bool Pre(const parser::OmpReductionSpecifier &x) { + // OmpReductionSpecifier is handled explicitly, and the AST traversal + // should not reach a point where it calls this function. + llvm_unreachable("This function should not be reached by AST traversal"); + } bool Pre(const parser::OmpDirectiveSpecification &x); + void Post(const parser::OmpDirectiveSpecification &) { + messageHandler().set_currStmtSource(std::nullopt); + } bool Pre(const parser::OmpTypeSpecifier &x) { BeginDeclTypeSpec(); @@ -1725,18 +1702,25 @@ class OmpVisitor : public virtual DeclarationVisitor { EndDeclTypeSpec(); } + bool Pre(const parser::OpenMPConstruct &x) { + // Indicate that the current directive is not a declarative one. + declaratives_.push_back(nullptr); + return true; + } + void Post(const parser::OpenMPConstruct &) { + // Pop the null pointer. + declaratives_.pop_back(); + } + private: void ProcessMapperSpecifier(const parser::OmpMapperSpecifier &spec, const parser::OmpClauseList &clauses); - template void ProcessReductionSpecifier(const parser::OmpReductionSpecifier &spec, - const std::optional &clauses, - const T &wholeConstruct); + const parser::OmpClauseList &clauses); void ResolveCriticalName(const parser::OmpArgument &arg); - int metaLevel_{0}; - const parser::OmpMetadirectiveDirective *metaDirective_{nullptr}; + std::vector declaratives_; }; bool OmpVisitor::NeedsScope(const parser::OmpBlockConstruct &x) { @@ -1861,11 +1845,9 @@ std::string MangleDefinedOperator(const parser::CharBlock &name) { return "op" + name.ToString(); } -template void OmpVisitor::ProcessReductionSpecifier( const parser::OmpReductionSpecifier &spec, - const std::optional &clauses, - const T &wholeOmpConstruct) { + const parser::OmpClauseList &clauses) { const parser::Name *name{nullptr}; parser::CharBlock mangledName; UserReductionDetails reductionDetailsTemp; @@ -1952,7 +1934,7 @@ void OmpVisitor::ProcessReductionSpecifier( PopScope(); } - reductionDetails->AddDecl(&wholeOmpConstruct); + reductionDetails->AddDecl(declaratives_.back()); if (!symbol) { symbol = &MakeSymbol(mangledName, Attrs{}, std::move(*reductionDetails)); @@ -1992,42 +1974,43 @@ void OmpVisitor::ResolveCriticalName(const parser::OmpArgument &arg) { bool OmpVisitor::Pre(const parser::OmpDirectiveSpecification &x) { AddOmpSourceRange(x.source); - if (metaLevel_ == 0) { - // Not in METADIRECTIVE. - return true; - } - // If OmpDirectiveSpecification (which contains clauses) is a part of - // METADIRECTIVE, some semantic checks may not be applicable. - // Disable the semantic analysis for it in such cases to allow the compiler - // to parse METADIRECTIVE without flagging errors. - auto &maybeArgs{std::get>(x.t)}; - auto &maybeClauses{std::get>(x.t)}; + const parser::OmpArgumentList &args{x.Arguments()}; + const parser::OmpClauseList &clauses{x.Clauses()}; + bool visitClauses{true}; + + for (const parser::OmpArgument &arg : args.v) { + common::visit( // + common::visitors{ + [&](const parser::OmpMapperSpecifier &spec) { + ProcessMapperSpecifier(spec, clauses); + visitClauses = false; + }, + [&](const parser::OmpReductionSpecifier &spec) { + ProcessReductionSpecifier(spec, clauses); + visitClauses = false; + }, + [&](const parser::OmpLocator &locator) { + // Manually resolve names in CRITICAL directives. This is because + // these names do not denote Fortran objects, and the CRITICAL + // directive causes them to be "auto-declared", i.e. inserted into + // the global scope. More specifically, they are not expected to + // have explicit declarations, and if they do the behavior is + // unspeficied. + if (x.DirId() == llvm::omp::Directive::OMPD_critical) { + ResolveCriticalName(arg); + } else { + Walk(locator); + } + }, + }, + arg.u); + } - switch (x.DirId()) { - case llvm::omp::Directive::OMPD_declare_mapper: - if (maybeArgs && maybeClauses) { - const parser::OmpArgument &first{maybeArgs->v.front()}; - if (auto *spec{std::get_if(&first.u)}) { - ProcessMapperSpecifier(*spec, *maybeClauses); - } - } - break; - case llvm::omp::Directive::OMPD_declare_reduction: - if (maybeArgs && maybeClauses) { - const parser::OmpArgument &first{maybeArgs->v.front()}; - if (auto *spec{std::get_if(&first.u)}) { - CHECK(metaDirective_); - ProcessReductionSpecifier(*spec, maybeClauses, *metaDirective_); - } - } - break; - default: - // Default processing. - Walk(maybeArgs); - Walk(maybeClauses); - break; + if (visitClauses) { + Walk(clauses); } + return false; } diff --git a/flang/test/Parser/OpenMP/declare-mapper-unparse.f90 b/flang/test/Parser/OpenMP/declare-mapper-unparse.f90 index 30d75d02736f3..b53bf5ce10557 100644 --- a/flang/test/Parser/OpenMP/declare-mapper-unparse.f90 +++ b/flang/test/Parser/OpenMP/declare-mapper-unparse.f90 @@ -9,7 +9,7 @@ program main end type ty -!CHECK: !$OMP DECLARE MAPPER (mymapper:ty::mapped) MAP(mapped,mapped%x) +!CHECK: !$OMP DECLARE MAPPER(mymapper:ty::mapped) MAP(mapped,mapped%x) !$omp declare mapper(mymapper : ty :: mapped) map(mapped, mapped%x) !PARSE-TREE: OpenMPDeclareMapperConstruct @@ -24,7 +24,7 @@ program main !PARSE-TREE: DataRef -> Name = 'mapped' !PARSE-TREE: Name = 'x' -!CHECK: !$OMP DECLARE MAPPER (ty::mapped) MAP(mapped,mapped%x) +!CHECK: !$OMP DECLARE MAPPER(ty::mapped) MAP(mapped,mapped%x) !$omp declare mapper(ty :: mapped) map(mapped, mapped%x) !PARSE-TREE: OpenMPDeclareMapperConstruct diff --git a/flang/test/Parser/OpenMP/declare-reduction-multi.f90 b/flang/test/Parser/OpenMP/declare-reduction-multi.f90 index 693e69d8896be..19266aca9db03 100644 --- a/flang/test/Parser/OpenMP/declare-reduction-multi.f90 +++ b/flang/test/Parser/OpenMP/declare-reduction-multi.f90 @@ -26,111 +26,127 @@ program omp_examples type(tt) :: values(n), sum, prod, big, small !$omp declare reduction(+:tt:omp_out%r = omp_out%r + omp_in%r) initializer(omp_priv%r = 0) -!CHECK: !$OMP DECLARE REDUCTION (+:tt: omp_out%r=omp_out%r+omp_in%r +!CHECK: !$OMP DECLARE REDUCTION(+:tt: omp_out%r=omp_out%r+omp_in%r !CHECK-NEXT: ) INITIALIZER(omp_priv%r=0_4) -!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -!PARSE-TREE: Verbatim -!PARSE-TREE: OmpReductionSpecifier -!PARSE-TREE-NEXT: OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add -!PARSE-TREE: OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec -!PARSE-TREE-NEXT: Name = 'tt' -!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out%r=omp_out%r+omp_in%r' -!PARSE-TREE: OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=0._4 + +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction +!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier +!PARSE-TREE: | | OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add +!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec +!PARSE-TREE: | | | Name = 'tt' +!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out%r=omp_out%r+omp_in%r' +!PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=0._4' + !$omp declare reduction(*:tt:omp_out%r = omp_out%r * omp_in%r) initializer(omp_priv%r = 1) -!CHECK-NEXT: !$OMP DECLARE REDUCTION (*:tt: omp_out%r=omp_out%r*omp_in%r +!CHECK-NEXT: !$OMP DECLARE REDUCTION(*:tt: omp_out%r=omp_out%r*omp_in%r !CHECK-NEXT: ) INITIALIZER(omp_priv%r=1_4) -!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -!PARSE-TREE: Verbatim -!PARSE-TREE: OmpReductionSpecifier -!PARSE-TREE: OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Multiply -!PARSE-TREE: OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec -!PARSE-TREE-NEXT: Name = 'tt' -!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out%r=omp_out%r*omp_in%r' -!PARSE-TREE: OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=1._4' + +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction +!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier +!PARSE-TREE: | | OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Multiply +!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec +!PARSE-TREE: | | | Name = 'tt' +!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out%r=omp_out%r*omp_in%r' +!PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=1._4' + !$omp declare reduction(max:tt:omp_out = mymax(omp_out, omp_in)) initializer(omp_priv%r = 0) -!CHECK-NEXT: !$OMP DECLARE REDUCTION (max:tt: omp_out=mymax(omp_out,omp_in) +!CHECK-NEXT: !$OMP DECLARE REDUCTION(max:tt: omp_out=mymax(omp_out,omp_in) !CHECK-NEXT: ) INITIALIZER(omp_priv%r=0_4) -!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -!PARSE-TREE: Verbatim -!PARSE-TREE: OmpReductionSpecifier -!PARSE-TREE: OmpReductionIdentifier -> ProcedureDesignator -> Name = 'max' -!PARSE-TREE: OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec -!PARSE-TREE: Name = 'tt' -!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out=mymax(omp_out,omp_in)' -!PARSE-TREE: OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=0._4' + +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction +!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier +!PARSE-TREE: | | OmpReductionIdentifier -> ProcedureDesignator -> Name = 'max' +!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec +!PARSE-TREE: | | | Name = 'tt' +!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out=mymax(omp_out,omp_in)' +!PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=0._4' + !$omp declare reduction(min:tt:omp_out%r = min(omp_out%r, omp_in%r)) initializer(omp_priv%r = 1) -!CHECK-NEXT: !$OMP DECLARE REDUCTION (min:tt: omp_out%r=min(omp_out%r,omp_in%r) +!CHECK-NEXT: !$OMP DECLARE REDUCTION(min:tt: omp_out%r=min(omp_out%r,omp_in%r) !CHECK-NEXT: ) INITIALIZER(omp_priv%r=1_4) -!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -!PARSE-TREE: Verbatim -!PARSE-TREE: OmpReductionSpecifier -!PARSE-TREE: OmpReductionIdentifier -> ProcedureDesignator -> Name = 'min' -!PARSE-TREE: OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec -!PARSE-TREE: Name = 'tt' -!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out%r=min(omp_out%r,omp_in%r)' -!PARSE-TREE: OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=1._4' + +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction +!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier +!PARSE-TREE: | | OmpReductionIdentifier -> ProcedureDesignator -> Name = 'min' +!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec +!PARSE-TREE: | | | Name = 'tt' +!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out%r=min(omp_out%r,omp_in%r)' +!PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=1._4' + call random_number(values%r) sum%r = 0 !$omp parallel do reduction(+:sum) -!CHECK: !$OMP PARALLEL DO REDUCTION(+: sum) +!CHECK: !$OMP PARALLEL DO REDUCTION(+: sum) + !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct -!PARSE-TREE: OmpBeginLoopDirective -!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = parallel do -!PARSE-TREE: OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause -!PARSE-TREE: Modifier -> OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add -!PARSE-TREE: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'sum -!PARSE-TREE: Flags = None -!PARSE-TREE: DoConstruct +!PARSE-TREE: | OmpBeginLoopDirective +!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = parallel do +!PARSE-TREE: | | OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause +!PARSE-TREE: | | | Modifier -> OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add +!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'sum' +!PARSE-TREE: | | Flags = None +!PARSE-TREE: | DoConstruct + do i = 1, n sum%r = sum%r + values(i)%r end do prod%r = 1 !$omp parallel do reduction(*:prod) -!CHECK: !$OMP PARALLEL DO REDUCTION(*: prod) -!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct -!PARSE-TREE: OmpBeginLoopDirective -!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = parallel do -!PARSE-TREE: OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause -!PARSE-TREE: Modifier -> OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Multiply -!PARSE-TREE: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'prod' -!PARSE-TREE: Flags = None -!PARSE-TREE: DoConstruct +!CHECK: !$OMP PARALLEL DO REDUCTION(*: prod) + +!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct +!PARSE-TREE: | OmpBeginLoopDirective +!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = parallel do +!PARSE-TREE: | | OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause +!PARSE-TREE: | | | Modifier -> OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Multiply +!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'prod' +!PARSE-TREE: | | Flags = None +!PARSE-TREE: | DoConstruct + do i = 1, n prod%r = prod%r * (values(i)%r+0.6) end do big%r = 0 !$omp parallel do reduction(max:big) -!CHECK: $OMP PARALLEL DO REDUCTION(max: big) +!CHECK: $OMP PARALLEL DO REDUCTION(max: big) + !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct -!PARSE-TREE: OmpBeginLoopDirective -!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = parallel do -!PARSE-TREE: OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause -!PARSE-TREE: Modifier -> OmpReductionIdentifier -> ProcedureDesignator -> Name = 'max' -!PARSE-TREE: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'big' -!PARSE-TREE: Flags = None -!PARSE-TREE: DoConstruct +!PARSE-TREE: | OmpBeginLoopDirective +!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = parallel do +!PARSE-TREE: | | OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause +!PARSE-TREE: | | | Modifier -> OmpReductionIdentifier -> ProcedureDesignator -> Name = 'max' +!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'big' +!PARSE-TREE: | | Flags = None +!PARSE-TREE: | DoConstruct + do i = 1, n big = mymax(values(i), big) end do small%r = 1 !$omp parallel do reduction(min:small) -!CHECK: !$OMP PARALLEL DO REDUCTION(min: small) -!CHECK-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct -!CHECK-TREE: OmpBeginLoopDirective -!CHECK-TREE: OmpDirectiveName -> llvm::omp::Directive = parallel do -!CHECK-TREE: OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause -!CHECK-TREE: Modifier -> OmpReductionIdentifier -> ProcedureDesignator -> Name = 'min' -!CHECK-TREE: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'small' -!PARSE-TREE: Flags = None -!CHECK-TREE: DoConstruct +!CHECK: !$OMP PARALLEL DO REDUCTION(min: small) + +!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct +!PARSE-TREE: | OmpBeginLoopDirective +!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = parallel do +!PARSE-TREE: | | OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause +!PARSE-TREE: | | | Modifier -> OmpReductionIdentifier -> ProcedureDesignator -> Name = 'min' +!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'small' +!PARSE-TREE: | | Flags = None +!PARSE-TREE: | DoConstruct + do i = 1, n small%r = min(values(i)%r, small%r) end do - + print *, values%r print *, "sum=", sum%r print *, "prod=", prod%r diff --git a/flang/test/Parser/OpenMP/declare-reduction-operator.f90 b/flang/test/Parser/OpenMP/declare-reduction-operator.f90 index 7bfb78115b10d..c41daa596d2d0 100644 --- a/flang/test/Parser/OpenMP/declare-reduction-operator.f90 +++ b/flang/test/Parser/OpenMP/declare-reduction-operator.f90 @@ -16,27 +16,33 @@ subroutine reduce_1 ( n, tts ) type(tt) :: tts(n) type(tt2) :: tts2(n) -!CHECK: !$OMP DECLARE REDUCTION (+:tt: omp_out=tt(x=omp_out%x-omp_in%x,y=omp_out%y-omp_in%y) +!CHECK: !$OMP DECLARE REDUCTION(+:tt: omp_out=tt(x=omp_out%x-omp_in%x,y=omp_out%y-omp_in%y) !CHECK: ) INITIALIZER(omp_priv=tt(x=0_4,y=0_4)) -!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -!PARSE-TREE: Verbatim -!PARSE-TREE: OmpReductionSpecifier -!PARSE-TREE: OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add -!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out=tt(x=omp_out%x-omp_in%x,y=omp_out%y-omp_in%y)' -!PARSE-TREE: OmpInitializerClause -> AssignmentStmt = 'omp_priv=tt(x=0_4,y=0_4)' - + +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction +!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier +!PARSE-TREE: | | OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add +!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec +!PARSE-TREE: | | | Name = 'tt' +!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out=tt(x=omp_out%x-omp_in%x,y=omp_out%y-omp_in%y)' +!PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv=tt(x=0_4,y=0_4)' + !$omp declare reduction(+ : tt : omp_out = tt(omp_out%x - omp_in%x , omp_out%y - omp_in%y)) initializer(omp_priv = tt(0,0)) -!CHECK: !$OMP DECLARE REDUCTION (+:tt2: omp_out=tt2(x=omp_out%x-omp_in%x,y=omp_out%y-omp_in%y) +!CHECK: !$OMP DECLARE REDUCTION(+:tt2: omp_out=tt2(x=omp_out%x-omp_in%x,y=omp_out%y-omp_in%y) !CHECK: ) INITIALIZER(omp_priv=tt2(x=0._8,y=0._8) -!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -!PARSE-TREE: Verbatim -!PARSE-TREE: OmpReductionSpecifier -!PARSE-TREE: OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add -!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out=tt2(x=omp_out%x-omp_in%x,y=omp_out%y-omp_in%y)' -!PARSE-TREE: OmpInitializerClause -> AssignmentStmt = 'omp_priv=tt2(x=0._8,y=0._8)' - + +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction +!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier +!PARSE-TREE: | | OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add +!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec +!PARSE-TREE: | | | Name = 'tt2' +!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out=tt2(x=omp_out%x-omp_in%x,y=omp_out%y-omp_in%y)' +!PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv=tt2(x=0._8,y=0._8)' + !$omp declare reduction(+ :tt2 : omp_out = tt2(omp_out%x - omp_in%x , omp_out%y - omp_in%y)) initializer(omp_priv = tt2(0,0)) type(tt) :: diffp = tt( 0, 0 ) diff --git a/flang/test/Parser/OpenMP/declare-reduction-unparse-with-symbols.f90 b/flang/test/Parser/OpenMP/declare-reduction-unparse-with-symbols.f90 index fbcd5b62821a3..131a816057d5a 100644 --- a/flang/test/Parser/OpenMP/declare-reduction-unparse-with-symbols.f90 +++ b/flang/test/Parser/OpenMP/declare-reduction-unparse-with-symbols.f90 @@ -8,6 +8,6 @@ subroutine f00 !CHECK: !DEF: /f00 (Subroutine) Subprogram !CHECK: subroutine f00 -!CHECK: !$omp declare reduction (fred:integer,real:omp_out = omp_in+omp_out) +!CHECK: !$omp declare reduction(fred:integer,real:omp_out = omp_in+omp_out) !CHECK: end subroutine diff --git a/flang/test/Parser/OpenMP/declare-reduction-unparse.f90 b/flang/test/Parser/OpenMP/declare-reduction-unparse.f90 index 0ed693e5821d6..7607b3d20b52d 100644 --- a/flang/test/Parser/OpenMP/declare-reduction-unparse.f90 +++ b/flang/test/Parser/OpenMP/declare-reduction-unparse.f90 @@ -18,21 +18,38 @@ subroutine initme(x,n) integer x,n end subroutine initme end interface -!CHECK: !$OMP DECLARE REDUCTION (red_add:INTEGER(KIND=4_4): omp_out=omp_out+omp_in -!CHECK: ) INITIALIZER(initme(omp_priv, 0_4)) !$omp declare reduction(red_add:integer(4):omp_out=omp_out+omp_in) initializer(initme(omp_priv,0)) -!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out=omp_out+omp_in' -!PARSE-TREE: OmpInitializerClause -> OmpInitializerProc -!PARSE-TREE-NEXT: ProcedureDesignator -> Name = 'initme' +!CHECK: !$OMP DECLARE REDUCTION(red_add:INTEGER(KIND=4_4): omp_out=omp_out+omp_in +!CHECK: ) INITIALIZER(initme(omp_priv, 0_4)) + +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction +!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier +!PARSE-TREE: | | OmpReductionIdentifier -> ProcedureDesignator -> Name = 'red_add' +!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec -> KindSelector -> Scalar -> Integer -> Constant -> Expr = '4_4' +!PARSE-TREE: | | | LiteralConstant -> IntLiteralConstant = '4' +!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out=omp_out+omp_in' +!PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> OmpInitializerProc +!PARSE-TREE: | | ProcedureDesignator -> Name = 'initme' + res=init !$omp simd reduction(red_add:res) !CHECK: !$OMP SIMD REDUCTION(red_add: res) + +!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt = 'res=init' +!PARSE-TREE: | Variable = 'res' +!PARSE-TREE: | | Designator -> DataRef -> Name = 'res' +!PARSE-TREE: | Expr = 'init' +!PARSE-TREE: | | Designator -> DataRef -> Name = 'init' !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct -!PARSE-TREE: OmpBeginLoopDirective -!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = simd -!PARSE-TREE: OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause -!PARSE-TREE: Modifier -> OmpReductionIdentifier -> ProcedureDesignator -> Name = 'red_add +!PARSE-TREE: | OmpBeginLoopDirective +!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = simd +!PARSE-TREE: | | OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause +!PARSE-TREE: | | | Modifier -> OmpReductionIdentifier -> ProcedureDesignator -> Name = 'red_add' +!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'res' +!PARSE-TREE: | | Flags = None +!PARSE-TREE: | DoConstruct + do i=1,n res=res+x(i) enddo @@ -43,7 +60,7 @@ end function func !CHECK-LABEL: program main program main integer :: my_var -!CHECK: !$OMP DECLARE REDUCTION (my_add_red:INTEGER: omp_out=omp_out+omp_in +!CHECK: !$OMP DECLARE REDUCTION(my_add_red:INTEGER: omp_out=omp_out+omp_in !CHECK-NEXT: ) INITIALIZER(omp_priv=0_4) !$omp declare reduction (my_add_red : integer : omp_out = omp_out + omp_in) initializer (omp_priv=0) @@ -54,8 +71,10 @@ program main print *, "sum of thread numbers is ", my_var end program main -!PARSE-TREE: OpenMPDeclareReductionConstruct -!PARSE-TREE: OmpReductionIdentifier -> ProcedureDesignator -> Name = 'my_add_red' -!PARSE-TREE: DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec -!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out=omp_out+omp_in' -!PARSE-TREE: OmpInitializerClause -> AssignmentStmt = 'omp_priv=0_4' +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction +!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier +!PARSE-TREE: | | OmpReductionIdentifier -> ProcedureDesignator -> Name = 'my_add_red' +!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec -> +!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out=omp_out+omp_in' +!PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv=0_4' diff --git a/flang/test/Parser/OpenMP/openmp6-directive-spellings.f90 b/flang/test/Parser/OpenMP/openmp6-directive-spellings.f90 index c2498c878f559..c4d9f6ef4618c 100644 --- a/flang/test/Parser/OpenMP/openmp6-directive-spellings.f90 +++ b/flang/test/Parser/OpenMP/openmp6-directive-spellings.f90 @@ -51,12 +51,12 @@ subroutine f01 !UNPARSE: TYPE :: t !UNPARSE: INTEGER :: x !UNPARSE: END TYPE -!UNPARSE: !$OMP DECLARE MAPPER (t::v) MAP(v%x) +!UNPARSE: !$OMP DECLARE_MAPPER(t::v) MAP(v%x) !UNPARSE: END SUBROUTINE -!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareMapperConstruct -!PARSE-TREE: | Verbatim -!PARSE-TREE: | OmpMapperSpecifier +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareMapperConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare mapper +!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpMapperSpecifier !PARSE-TREE: | | string = 't.omp.default.mapper' !PARSE-TREE: | | TypeSpec -> DerivedTypeSpec !PARSE-TREE: | | | Name = 't' @@ -66,6 +66,7 @@ subroutine f01 !PARSE-TREE: | | | DataRef -> Name = 'v' !PARSE-TREE: | | | Name = 'x' !PARSE-TREE: | | bool = 'true' +!PARSE-TREE: | Flags = None subroutine f02 type :: t @@ -78,13 +79,13 @@ subroutine f02 !UNPARSE: TYPE :: t !UNPARSE: INTEGER :: x !UNPARSE: END TYPE -!UNPARSE: !$OMP DECLARE REDUCTION (+:t: omp_out%x=omp_out%x+omp_in%x +!UNPARSE: !$OMP DECLARE_REDUCTION(+:t: omp_out%x=omp_out%x+omp_in%x !UNPARSE: ) !UNPARSE: END SUBROUTINE -!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -!PARSE-TREE: | Verbatim -!PARSE-TREE: | OmpReductionSpecifier +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction +!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier !PARSE-TREE: | | OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add !PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec !PARSE-TREE: | | | Name = 't' @@ -104,6 +105,7 @@ subroutine f02 !PARSE-TREE: | | | | | | | DataRef -> Name = 'omp_in' !PARSE-TREE: | | | | | | | Name = 'x' !PARSE-TREE: | OmpClauseList -> +!PARSE-TREE: | Flags = None subroutine f03 !$omp declare_simd diff --git a/flang/test/Semantics/OpenMP/declare-mapper04.f90 b/flang/test/Semantics/OpenMP/declare-mapper04.f90 new file mode 100644 index 0000000000000..2f45e230c3513 --- /dev/null +++ b/flang/test/Semantics/OpenMP/declare-mapper04.f90 @@ -0,0 +1,18 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=60 + +type :: t1 + integer :: y +end type + +type :: t2 + integer :: y +end type + +!ERROR: DECLARE_MAPPER directive should have a single argument +!$omp declare mapper(m1:t1::x, m2:t2::x) map(x, x%y) + +integer :: x(10) +!ERROR: The argument to the DECLARE_MAPPER directive should be a mapper-specifier +!$omp declare mapper(x) map(to: x) + +end diff --git a/flang/test/Semantics/OpenMP/declare-reduction-modfile.f90 b/flang/test/Semantics/OpenMP/declare-reduction-modfile.f90 index f80eb1097e18a..2fb2cd7c4b89d 100644 --- a/flang/test/Semantics/OpenMP/declare-reduction-modfile.f90 +++ b/flang/test/Semantics/OpenMP/declare-reduction-modfile.f90 @@ -6,13 +6,13 @@ !type::t1 !integer(4)::val !endtype -!!$OMP DECLARE REDUCTION (*:t1:omp_out = omp_out*omp_in) INITIALIZER(omp_priv=t& -!!$OMP&1(1)) +!!$OMP DECLARE REDUCTION(*:t1:omp_out = omp_out*omp_in) INITIALIZER(omp_priv=t1& +!!$OMP&(1)) !!$OMP METADIRECTIVE OTHERWISE(DECLARE REDUCTION(+:INTEGER)) -!!$OMP DECLARE REDUCTION (.fluffy.:t1:omp_out = omp_out.fluffy.omp_in) INITIALI& -!!$OMP&ZER(omp_priv=t1(0)) -!!$OMP DECLARE REDUCTION (.mul.:t1:omp_out = omp_out.mul.omp_in) INITIALIZER(om& -!!$OMP&p_priv=t1(1)) +!!$OMP DECLARE REDUCTION(.fluffy.:t1:omp_out = omp_out.fluffy.omp_in) INITIALIZ& +!!$OMP&ER(omp_priv=t1(0)) +!!$OMP DECLARE REDUCTION(.mul.:t1:omp_out = omp_out.mul.omp_in) INITIALIZER(omp& +!!$OMP&_priv=t1(1)) !interface operator(.mul.) !procedure::mul !end interface