diff --git a/flang/include/flang/Lower/OpenMP/Clauses.h b/flang/include/flang/Lower/OpenMP/Clauses.h index 5cd196a7869a2..273e61166fd9d 100644 --- a/flang/include/flang/Lower/OpenMP/Clauses.h +++ b/flang/include/flang/Lower/OpenMP/Clauses.h @@ -282,6 +282,7 @@ using Replayable = tomp::clause::ReplayableT; using ReverseOffload = tomp::clause::ReverseOffloadT; using Safelen = tomp::clause::SafelenT; using Schedule = tomp::clause::ScheduleT; +using SelfMaps = tomp::clause::SelfMapsT; using SeqCst = tomp::clause::SeqCstT; using Severity = tomp::clause::SeverityT; using Shared = tomp::clause::SharedT; diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index 91af92c04a56b..35017909d9091 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -568,6 +568,7 @@ class ParseTreeDumper { NODE(OmpDoacross, Sink) NODE(OmpDoacross, Source) NODE(parser, OmpDoacrossClause) + NODE(parser, OmpDynamicAllocatorsClause) NODE(parser, OmpDynGroupprivateClause) NODE(OmpDynGroupprivateClause, Modifier) NODE(parser, OmpEndDirective) @@ -661,9 +662,11 @@ class ParseTreeDumper { NODE(parser, OmpRefModifier) NODE_ENUM(OmpRefModifier, Value) NODE(parser, OmpReplayableClause) + NODE(parser, OmpReverseOffloadClause) NODE(parser, OmpScheduleClause) NODE(OmpScheduleClause, Modifier) NODE_ENUM(OmpScheduleClause, Kind) + NODE(parser, OmpSelfMapsClause) NODE(parser, OmpSelfModifier) NODE_ENUM(OmpSelfModifier, Value) NODE(parser, OmpSeverityClause) @@ -691,6 +694,8 @@ class ParseTreeDumper { NODE(parser, OmpTransparentClause) NODE(parser, OmpTypeNameList) NODE(parser, OmpTypeSpecifier) + NODE(parser, OmpUnifiedAddressClause) + NODE(parser, OmpUnifiedSharedMemoryClause) NODE(parser, OmpUpdateClause) NODE(parser, OmpUseClause) NODE(parser, OmpVariableCategory) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index f52323c2e79cf..a4f447263fc93 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -337,6 +337,7 @@ using IntConstantExpr = Integer; // R1031 using ScalarLogicalExpr = Scalar; using ScalarIntExpr = Scalar; using ScalarIntConstantExpr = Scalar; +using ScalarLogicalConstantExpr = Scalar>; using ScalarDefaultCharExpr = Scalar; // R1030 default-char-constant-expr is used in the Standard only as part of // scalar-default-char-constant-expr. @@ -4426,6 +4427,16 @@ struct OmpDeviceTypeClause { WRAPPER_CLASS_BOILERPLATE(OmpDeviceTypeClause, DeviceTypeDescription); }; +// Ref: [5.0:60-63], [5.1:83-86], [5.2:212-213], [6.0:356-362] +// +// dynamic-allocators-clause -> +// DYNAMIC_ALLOCATORS // since 5.0 +// [(scalar-logical-const-expr)] // since 6.0 +struct OmpDynamicAllocatorsClause { + WRAPPER_CLASS_BOILERPLATE( + OmpDynamicAllocatorsClause, ScalarLogicalConstantExpr); +}; + struct OmpDynGroupprivateClause { TUPLE_CLASS_BOILERPLATE(OmpDynGroupprivateClause); MODIFIER_BOILERPLATE(OmpAccessGroup, OmpPrescriptiveness); @@ -4703,7 +4714,16 @@ struct OmpReductionClause { // replayable-clause -> // REPLAYABLE[(replayable-expression)] // since 6.0 struct OmpReplayableClause { - WRAPPER_CLASS_BOILERPLATE(OmpReplayableClause, Scalar>); + WRAPPER_CLASS_BOILERPLATE(OmpReplayableClause, ScalarLogicalConstantExpr); +}; + +// Ref: [5.0:60-63], [5.1:83-86], [5.2:212-213], [6.0:356-362] +// +// reverse-offload-clause -> +// REVERSE_OFFLOAD // since 5.0 +// [(scalar-logical-const-expr)] // since 6.0 +struct OmpReverseOffloadClause { + WRAPPER_CLASS_BOILERPLATE(OmpReverseOffloadClause, ScalarLogicalConstantExpr); }; // Ref: [4.5:56-63], [5.0:101-109], [5.1:126-133], [5.2:252-254] @@ -4721,6 +4741,14 @@ struct OmpScheduleClause { std::tuple> t; }; +// ref: [6.0:361-362] +// +// self-maps-clause -> +// SELF_MAPS [(scalar-logical-const-expr)] // since 6.0 +struct OmpSelfMapsClause { + WRAPPER_CLASS_BOILERPLATE(OmpSelfMapsClause, ScalarLogicalConstantExpr); +}; + // REF: [5.2:217] // severity-clause -> // SEVERITY(warning|fatal) @@ -4763,6 +4791,25 @@ struct OmpTransparentClause { WRAPPER_CLASS_BOILERPLATE(OmpTransparentClause, ScalarIntExpr); }; +// Ref: [5.0:60-63], [5.1:83-86], [5.2:212-213], [6.0:356-362] +// +// unified-address-clause -> +// UNIFIED_ADDRESS // since 5.0 +// [(scalar-logical-const-expr)] // since 6.0 +struct OmpUnifiedAddressClause { + WRAPPER_CLASS_BOILERPLATE(OmpUnifiedAddressClause, ScalarLogicalConstantExpr); +}; + +// Ref: [5.0:60-63], [5.1:83-86], [5.2:212-213], [6.0:356-362] +// +// unified-shared-memory-clause -> +// UNIFIED_SHARED_MEMORY // since 5.0 +// [(scalar-logical-const-expr)] // since 6.0 +struct OmpUnifiedSharedMemoryClause { + WRAPPER_CLASS_BOILERPLATE( + OmpUnifiedSharedMemoryClause, ScalarLogicalConstantExpr); +}; + // Ref: [5.0:254-255], [5.1:287-288], [5.2:321-322] // // In ATOMIC construct diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp index 0842c62c69c03..ba34212dddba9 100644 --- a/flang/lib/Lower/OpenMP/Clauses.cpp +++ b/flang/lib/Lower/OpenMP/Clauses.cpp @@ -219,7 +219,6 @@ MAKE_EMPTY_CLASS(AcqRel, AcqRel); MAKE_EMPTY_CLASS(Acquire, Acquire); MAKE_EMPTY_CLASS(Capture, Capture); MAKE_EMPTY_CLASS(Compare, Compare); -MAKE_EMPTY_CLASS(DynamicAllocators, DynamicAllocators); MAKE_EMPTY_CLASS(Full, Full); MAKE_EMPTY_CLASS(Inbranch, Inbranch); MAKE_EMPTY_CLASS(Mergeable, Mergeable); @@ -235,13 +234,9 @@ MAKE_EMPTY_CLASS(OmpxBare, OmpxBare); MAKE_EMPTY_CLASS(Read, Read); MAKE_EMPTY_CLASS(Relaxed, Relaxed); MAKE_EMPTY_CLASS(Release, Release); -MAKE_EMPTY_CLASS(ReverseOffload, ReverseOffload); MAKE_EMPTY_CLASS(SeqCst, SeqCst); -MAKE_EMPTY_CLASS(SelfMaps, SelfMaps); MAKE_EMPTY_CLASS(Simd, Simd); MAKE_EMPTY_CLASS(Threads, Threads); -MAKE_EMPTY_CLASS(UnifiedAddress, UnifiedAddress); -MAKE_EMPTY_CLASS(UnifiedSharedMemory, UnifiedSharedMemory); MAKE_EMPTY_CLASS(Unknown, Unknown); MAKE_EMPTY_CLASS(Untied, Untied); MAKE_EMPTY_CLASS(Weak, Weak); @@ -775,7 +770,18 @@ Doacross make(const parser::OmpClause::Doacross &inp, return makeDoacross(inp.v.v, semaCtx); } -// DynamicAllocators: empty +DynamicAllocators make(const parser::OmpClause::DynamicAllocators &inp, + semantics::SemanticsContext &semaCtx) { + // inp.v -> td::optional + auto &&maybeRequired = maybeApply( + [&](const parser::OmpDynamicAllocatorsClause &c) { + return makeExpr(c.v, semaCtx); + }, + inp.v); + + return DynamicAllocators{/*Required=*/std::move(maybeRequired)}; +} + DynGroupprivate make(const parser::OmpClause::DynGroupprivate &inp, semantics::SemanticsContext &semaCtx) { @@ -1338,7 +1344,18 @@ Reduction make(const parser::OmpClause::Reduction &inp, // Relaxed: empty // Release: empty -// ReverseOffload: empty + +ReverseOffload make(const parser::OmpClause::ReverseOffload &inp, + semantics::SemanticsContext &semaCtx) { + // inp.v -> std::optional + auto &&maybeRequired = maybeApply( + [&](const parser::OmpReverseOffloadClause &c) { + return makeExpr(c.v, semaCtx); + }, + inp.v); + + return ReverseOffload{/*Required=*/std::move(maybeRequired)}; +} Safelen make(const parser::OmpClause::Safelen &inp, semantics::SemanticsContext &semaCtx) { @@ -1391,6 +1408,18 @@ Schedule make(const parser::OmpClause::Schedule &inp, // SeqCst: empty +SelfMaps make(const parser::OmpClause::SelfMaps &inp, + semantics::SemanticsContext &semaCtx) { + // inp.v -> std::optional + auto &&maybeRequired = maybeApply( + [&](const parser::OmpSelfMapsClause &c) { + return makeExpr(c.v, semaCtx); + }, + inp.v); + + return SelfMaps{/*Required=*/std::move(maybeRequired)}; +} + Severity make(const parser::OmpClause::Severity &inp, semantics::SemanticsContext &semaCtx) { // inp -> empty @@ -1480,8 +1509,29 @@ To make(const parser::OmpClause::To &inp, /*LocatorList=*/makeObjects(t3, semaCtx)}}; } -// UnifiedAddress: empty -// UnifiedSharedMemory: empty +UnifiedAddress make(const parser::OmpClause::UnifiedAddress &inp, + semantics::SemanticsContext &semaCtx) { + // inp.v -> std::optional + auto &&maybeRequired = maybeApply( + [&](const parser::OmpUnifiedAddressClause &c) { + return makeExpr(c.v, semaCtx); + }, + inp.v); + + return UnifiedAddress{/*Required=*/std::move(maybeRequired)}; +} + +UnifiedSharedMemory make(const parser::OmpClause::UnifiedSharedMemory &inp, + semantics::SemanticsContext &semaCtx) { + // inp.v -> std::optional + auto &&maybeRequired = maybeApply( + [&](const parser::OmpUnifiedSharedMemoryClause &c) { + return makeExpr(c.v, semaCtx); + }, + inp.v); + + return UnifiedSharedMemory{/*Required=*/std::move(maybeRequired)}; +} Uniform make(const parser::OmpClause::Uniform &inp, semantics::SemanticsContext &semaCtx) { diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index b5771eb785a36..56009db7ec6d4 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -1167,7 +1167,8 @@ TYPE_PARSER( // "DOACROSS" >> construct(parenthesized(Parser{})) || "DYNAMIC_ALLOCATORS" >> - construct(construct()) || + construct(construct( + maybe(parenthesized(scalarLogicalConstantExpr)))) || "DYN_GROUPPRIVATE" >> construct(construct( parenthesized(Parser{}))) || @@ -1279,12 +1280,15 @@ TYPE_PARSER( // "REPLAYABLE" >> construct(construct( maybe(parenthesized(Parser{})))) || "REVERSE_OFFLOAD" >> - construct(construct()) || + construct(construct( + maybe(parenthesized(scalarLogicalConstantExpr)))) || "SAFELEN" >> construct(construct( parenthesized(scalarIntConstantExpr))) || "SCHEDULE" >> construct(construct( parenthesized(Parser{}))) || "SEQ_CST" >> construct(construct()) || + "SELF_MAPS" >> construct(construct( + maybe(parenthesized(scalarLogicalConstantExpr)))) || "SEVERITY" >> construct(construct( parenthesized(Parser{}))) || "SHARED" >> construct(construct( @@ -1312,9 +1316,11 @@ TYPE_PARSER( // construct(construct( parenthesized(Parser{}))) || "UNIFIED_ADDRESS" >> - construct(construct()) || + construct(construct( + maybe(parenthesized(scalarLogicalConstantExpr)))) || "UNIFIED_SHARED_MEMORY" >> - construct(construct()) || + construct(construct( + maybe(parenthesized(scalarLogicalConstantExpr)))) || "UNIFORM" >> construct(construct( parenthesized(nonemptyList(name)))) || "UNTIED" >> construct(construct()) || diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 4b5610ad86610..f894ffc103af8 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -1517,19 +1517,42 @@ void OmpStructureChecker::Leave(const parser::OpenMPDepobjConstruct &x) { void OmpStructureChecker::Enter(const parser::OpenMPRequiresConstruct &x) { const auto &dirName{x.v.DirName()}; PushContextAndClauseSets(dirName.source, dirName.v); + unsigned version{context_.langOptions().OpenMPVersion}; - if (visitedAtomicSource_.empty()) { - return; - } for (const parser::OmpClause &clause : x.v.Clauses().v) { llvm::omp::Clause id{clause.Id()}; if (id == llvm::omp::Clause::OMPC_atomic_default_mem_order) { - parser::MessageFormattedText txt( - "REQUIRES directive with '%s' clause found lexically after atomic operation without a memory order clause"_err_en_US, - parser::ToUpperCaseLetters(llvm::omp::getOpenMPClauseName(id))); - parser::Message message(clause.source, txt); - message.Attach(visitedAtomicSource_, "Previous atomic construct"_en_US); - context_.Say(std::move(message)); + if (!visitedAtomicSource_.empty()) { + parser::MessageFormattedText txt( + "REQUIRES directive with '%s' clause found lexically after atomic operation without a memory order clause"_err_en_US, + parser::ToUpperCaseLetters(llvm::omp::getOpenMPClauseName(id))); + parser::Message message(clause.source, txt); + message.Attach(visitedAtomicSource_, "Previous atomic construct"_en_US); + context_.Say(std::move(message)); + } + } else { + bool hasArgument{common::visit( + [&](auto &&s) { + using TypeS = llvm::remove_cvref_t; + if constexpr ( // + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v) { + return s.v.has_value(); + } else { + return false; + } + }, + clause.u)}; + if (version < 60 && hasArgument) { + context_.Say(clause.source, + "An argument to %s is an %s feature, %s"_warn_en_US, + parser::ToUpperCaseLetters( + llvm::omp::getOpenMPClauseName(clause.Id())), + ThisVersion(60), TryVersion(60)); + } } } } diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index 122849356ca39..7067ed3d99286 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -557,6 +557,21 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor { using RequiresClauses = WithOmpDeclarative::RequiresClauses; PushContext(x.source, llvm::omp::Directive::OMPD_requires); + auto getArgument{[&](auto &&maybeClause) { + if (maybeClause) { + // Scalar>>> + auto &parserExpr{maybeClause->v.thing.thing.thing.value()}; + evaluate::ExpressionAnalyzer ea{context_}; + if (auto &&maybeExpr{ea.Analyze(parserExpr)}) { + if (auto v{omp::GetLogicalValue(*maybeExpr)}) { + return *v; + } + } + } + // If the argument is missing, it is assumed to be true. + return true; + }}; + // Gather information from the clauses. RequiresClauses reqs; const common::OmpMemoryOrderType *memOrder{nullptr}; @@ -573,16 +588,19 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor { if constexpr ( // std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v || std::is_same_v) { - return RequiresClauses{clause.Id()}; - } else { - return RequiresClauses{}; + if (getArgument(s.v)) { + return RequiresClauses{clause.Id()}; + } } + return RequiresClauses{}; }, }, clause.u); } + // Merge clauses into parents' symbols details. AddOmpRequiresToScope(currScope(), &reqs, memOrder); return true; diff --git a/flang/test/Parser/OpenMP/requires.f90 b/flang/test/Parser/OpenMP/requires.f90 index 6cbb06eaf93c0..8169403835705 100644 --- a/flang/test/Parser/OpenMP/requires.f90 +++ b/flang/test/Parser/OpenMP/requires.f90 @@ -30,4 +30,18 @@ !PARSE-TREE: | OmpClause -> ReverseOffload !PARSE-TREE: | Flags = None +!$omp requires self_maps(.true.) unified_address(.false.) + +!UNPARSE: !$OMP REQUIRES SELF_MAPS(.true._4) UNIFIED_ADDRESS(.false._4) + +!PARSE-TREE: OpenMPDeclarativeConstruct -> OpenMPRequiresConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = requires +!PARSE-TREE: | OmpClauseList -> OmpClause -> SelfMaps -> OmpSelfMapsClause -> Scalar -> Logical -> Constant -> Expr = '.true._4' +!PARSE-TREE: | | LiteralConstant -> LogicalLiteralConstant +!PARSE-TREE: | | | bool = 'true' +!PARSE-TREE: | OmpClause -> UnifiedAddress -> OmpUnifiedAddressClause -> Scalar -> Logical -> Constant -> Expr = '.false._4' +!PARSE-TREE: | | LiteralConstant -> LogicalLiteralConstant +!PARSE-TREE: | | | bool = 'false' +!PARSE-TREE: | Flags = None + end diff --git a/flang/test/Semantics/OpenMP/requires-modfile.f90 b/flang/test/Semantics/OpenMP/requires-modfile.f90 index 2f06104e208ef..52a43c2ef37ac 100644 --- a/flang/test/Semantics/OpenMP/requires-modfile.f90 +++ b/flang/test/Semantics/OpenMP/requires-modfile.f90 @@ -1,4 +1,4 @@ -!RUN: %python %S/../test_modfile.py %s %flang_fc1 -fopenmp -fopenmp-version=52 +!RUN: %python %S/../test_modfile.py %s %flang_fc1 -fopenmp -fopenmp-version=60 module req contains @@ -16,8 +16,16 @@ subroutine f01 module user ! The requirements from module req should be propagated to this module. use req + ! This has no effect, and should not be emitted. + !$omp requires unified_shared_memory(.false.) end module +module fold + integer, parameter :: x = 10 + integer, parameter :: y = 33 + ! Make sure we can fold this expression to "true". + !$omp requires dynamic_allocators(x < y) +end module !Expect: req.mod !module req @@ -37,3 +45,10 @@ module user !!$omp requires atomic_default_mem_order(seq_cst) !!$omp requires reverse_offload !end + +!Expect: fold.mod +!module fold +!integer(4),parameter::x=10_4 +!integer(4),parameter::y=33_4 +!!$omp requires dynamic_allocators +!end diff --git a/flang/test/Semantics/OpenMP/requires10.f90 b/flang/test/Semantics/OpenMP/requires10.f90 new file mode 100644 index 0000000000000..9f9832da3726e --- /dev/null +++ b/flang/test/Semantics/OpenMP/requires10.f90 @@ -0,0 +1,13 @@ +!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=52 + +subroutine f00(x) + logical :: x + !ERROR: An argument to REVERSE_OFFLOAD is an OpenMP v6.0 feature, try -fopenmp-version=60 + !ERROR: Must be a constant value + !$omp requires reverse_offload(x) +end + +subroutine f01 + !WARNING: An argument to REVERSE_OFFLOAD is an OpenMP v6.0 feature, try -fopenmp-version=60 + !$omp requires reverse_offload(.true.) +end diff --git a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h index d49bade6afef9..1a01fa66c5379 100644 --- a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h +++ b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h @@ -571,7 +571,9 @@ struct DoacrossT { // V5.2: [8.2.1] `requirement` clauses template // struct DynamicAllocatorsT { - using EmptyTrait = std::true_type; + using Requires = E; + using WrapperTrait = std::true_type; + OPT(Requires) v; }; template // @@ -1056,7 +1058,9 @@ struct ReplayableT { // V5.2: [8.2.1] `requirement` clauses template // struct ReverseOffloadT { - using EmptyTrait = std::true_type; + using Requires = E; + using WrapperTrait = std::true_type; + OPT(Requires) v; }; // V5.2: [10.4.2] `safelen` clause @@ -1078,6 +1082,14 @@ struct ScheduleT { std::tuple t; }; +// [6.0:361] +template // +struct SelfMapsT { + using Requires = E; + using WrapperTrait = std::true_type; + OPT(Requires) v; +}; + // V5.2: [15.8.1] Memory-order clauses template // struct SeqCstT { @@ -1169,18 +1181,17 @@ struct TransparentT { // V5.2: [8.2.1] `requirement` clauses template // struct UnifiedAddressT { - using EmptyTrait = std::true_type; + using Requires = E; + using WrapperTrait = std::true_type; + OPT(Requires) v; }; // V5.2: [8.2.1] `requirement` clauses template // struct UnifiedSharedMemoryT { - using EmptyTrait = std::true_type; -}; - -template // -struct SelfMapsT { - using EmptyTrait = std::true_type; + using Requires = E; + using WrapperTrait = std::true_type; + OPT(Requires) v; }; // V5.2: [5.10] `uniform` clause @@ -1288,14 +1299,12 @@ using ExtensionClausesT = template using EmptyClausesT = std::variant< AcqRelT, AcquireT, CaptureT, CompareT, - DynamicAllocatorsT, FullT, InbranchT, - MergeableT, NogroupT, NoOpenmpRoutinesT, + FullT, InbranchT, MergeableT, NogroupT, + NoOpenmpConstructsT, NoOpenmpRoutinesT, NoOpenmpT, NoParallelismT, NotinbranchT, NowaitT, ReadT, RelaxedT, ReleaseT, - ReverseOffloadT, SeqCstT, SimdT, - ThreadsT, UnifiedAddressT, UnifiedSharedMemoryT, - UnknownT, UntiedT, UseT, WeakT, - WriteT, NoOpenmpConstructsT, SelfMapsT>; + SeqCstT, SimdT, ThreadsT, UnknownT, + UntiedT, UseT, WeakT, WriteT>; template using IncompleteClausesT = @@ -1323,18 +1332,20 @@ using WrapperClausesT = std::variant< AtomicDefaultMemOrderT, AtT, BindT, CollapseT, ContainsT, CopyinT, CopyprivateT, DefaultT, DestroyT, - DetachT, DeviceTypeT, EnterT, - ExclusiveT, FailT, FilterT, FinalT, - FirstprivateT, HasDeviceAddrT, HintT, - HoldsT, InclusiveT, IndirectT, + DetachT, DeviceTypeT, DynamicAllocatorsT, + EnterT, ExclusiveT, FailT, FilterT, + FinalT, FirstprivateT, HasDeviceAddrT, + HintT, HoldsT, InclusiveT, IndirectT, InitializerT, IsDevicePtrT, LinkT, MessageT, NocontextT, NontemporalT, NovariantsT, NumTeamsT, NumThreadsT, OrderedT, PartialT, PriorityT, PrivateT, - ProcBindT, SafelenT, SeverityT, SharedT, - SimdlenT, SizesT, PermutationT, - ThreadLimitT, UniformT, UpdateT, - UseDeviceAddrT, UseDevicePtrT, UsesAllocatorsT>; + ProcBindT, ReverseOffloadT, SafelenT, + SelfMapsT, SeverityT, SharedT, SimdlenT, + SizesT, PermutationT, ThreadLimitT, + UnifiedAddressT, UnifiedSharedMemoryT, UniformT, + UpdateT, UseDeviceAddrT, UseDevicePtrT, + UsesAllocatorsT>; template using UnionOfAllClausesT = typename type::Union< // diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td index 86a9e249054a0..edcf7a92c2a84 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -177,6 +177,8 @@ def OMPC_Doacross : Clause<[Spelling<"doacross">]> { } def OMPC_DynamicAllocators : Clause<[Spelling<"dynamic_allocators">]> { let clangClass = "OMPDynamicAllocatorsClause"; + let flangClass = "OmpDynamicAllocatorsClause"; + let isValueOptional = true; } def OMPC_DynGroupprivate : Clause<[Spelling<"dyn_groupprivate">]> { let flangClass = "OmpDynGroupprivateClause"; @@ -467,6 +469,8 @@ def OMPC_Replayable : Clause<[Spelling<"replayable">]> { } def OMPC_ReverseOffload : Clause<[Spelling<"reverse_offload">]> { let clangClass = "OMPReverseOffloadClause"; + let flangClass = "OmpReverseOffloadClause"; + let isValueOptional = true; } def OMPC_SafeLen : Clause<[Spelling<"safelen">]> { let clangClass = "OMPSafelenClause"; @@ -541,12 +545,18 @@ def OMPC_Transparent : Clause<[Spelling<"transparent">]> { } def OMPC_UnifiedAddress : Clause<[Spelling<"unified_address">]> { let clangClass = "OMPUnifiedAddressClause"; + let flangClass = "OmpUnifiedAddressClause"; + let isValueOptional = true; } def OMPC_UnifiedSharedMemory : Clause<[Spelling<"unified_shared_memory">]> { let clangClass = "OMPUnifiedSharedMemoryClause"; + let flangClass = "OmpUnifiedSharedMemoryClause"; + let isValueOptional = true; } def OMPC_SelfMaps : Clause<[Spelling<"self_maps">]> { let clangClass = "OMPSelfMapsClause"; + let flangClass = "OmpSelfMapsClause"; + let isValueOptional = true; } def OMPC_Uniform : Clause<[Spelling<"uniform">]> { let flangClass = "Name";