diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -12,6 +12,30 @@ namespace Fortran::semantics { +// Use when clause falls under 'struct OmpClause' in 'parse-tree.h'. +#define CHECK_SIMPLE_CLAUSE(X, Y) \ + void OmpStructureChecker::Enter(const parser::OmpClause::X &) { \ + CheckAllowed(llvm::omp::Clause::Y); \ + } + +#define CHECK_REQ_CONSTANT_SCALAR_INT_CLAUSE(X, Y) \ + void OmpStructureChecker::Enter(const parser::OmpClause::X &c) { \ + CheckAllowed(llvm::omp::Clause::Y); \ + RequiresConstantPositiveParameter(llvm::omp::Clause::Y, c.v); \ + } + +#define CHECK_REQ_SCALAR_INT_CLAUSE(X, Y) \ + void OmpStructureChecker::Enter(const parser::OmpClause::X &c) { \ + CheckAllowed(llvm::omp::Clause::Y); \ + RequiresPositiveParameter(llvm::omp::Clause::Y, c.v); \ + } + +// Use when clause don't falls under 'struct OmpClause' in 'parse-tree.h'. +#define CHECK_SIMPLE_PARSER_CLAUSE(X, Y) \ + void OmpStructureChecker::Enter(const parser::X &) { \ + CheckAllowed(llvm::omp::Y); \ + } + bool OmpStructureChecker::HasInvalidWorksharingNesting( const parser::CharBlock &source, const OmpDirectiveSet &set) { // set contains all the invalid closely nested directives @@ -242,6 +266,12 @@ } } +// Clauses +// Mainly categorized as +// 1. Checks on 'OmpClauseList' from 'parse-tree.h'. +// 2. Checks on clauses which fall under 'struct OmpClause' from parse-tree.h. +// 3. Checks on clauses which are not in 'struct OmpClause' from parse-tree.h. + void OmpStructureChecker::Leave(const parser::OmpClauseList &) { // 2.7 Loop Construct Restriction if (llvm::omp::doSet.test(GetContext().directive)) { @@ -340,73 +370,41 @@ SetContextClause(x); } -void OmpStructureChecker::Enter(const parser::OmpNowait &) { - CheckAllowed(llvm::omp::Clause::OMPC_nowait); -} -void OmpStructureChecker::Enter(const parser::OmpClause::Inbranch &) { - CheckAllowed(llvm::omp::Clause::OMPC_inbranch); -} -void OmpStructureChecker::Enter(const parser::OmpClause::Mergeable &) { - CheckAllowed(llvm::omp::Clause::OMPC_mergeable); -} -void OmpStructureChecker::Enter(const parser::OmpClause::Nogroup &) { - CheckAllowed(llvm::omp::Clause::OMPC_nogroup); -} -void OmpStructureChecker::Enter(const parser::OmpClause::Notinbranch &) { - CheckAllowed(llvm::omp::Clause::OMPC_notinbranch); -} -void OmpStructureChecker::Enter(const parser::OmpClause::Untied &) { - CheckAllowed(llvm::omp::Clause::OMPC_untied); -} - -void OmpStructureChecker::Enter(const parser::OmpClause::Collapse &x) { - CheckAllowed(llvm::omp::Clause::OMPC_collapse); - // collapse clause must have a parameter - RequiresConstantPositiveParameter(llvm::omp::Clause::OMPC_collapse, x.v); -} - -void OmpStructureChecker::Enter(const parser::OmpClause::Copyin &) { - CheckAllowed(llvm::omp::Clause::OMPC_copyin); -} -void OmpStructureChecker::Enter(const parser::OmpClause::Copyprivate &) { - CheckAllowed(llvm::omp::Clause::OMPC_copyprivate); -} -void OmpStructureChecker::Enter(const parser::OmpClause::Device &) { - CheckAllowed(llvm::omp::Clause::OMPC_device); -} -void OmpStructureChecker::Enter(const parser::OmpDistScheduleClause &) { - CheckAllowed(llvm::omp::Clause::OMPC_dist_schedule); -} -void OmpStructureChecker::Enter(const parser::OmpClause::Final &) { - CheckAllowed(llvm::omp::Clause::OMPC_final); -} -void OmpStructureChecker::Enter(const parser::OmpClause::Firstprivate &) { - CheckAllowed(llvm::omp::Clause::OMPC_firstprivate); -} -void OmpStructureChecker::Enter(const parser::OmpClause::From &) { - CheckAllowed(llvm::omp::Clause::OMPC_from); -} -void OmpStructureChecker::Enter(const parser::OmpClause::Grainsize &x) { - CheckAllowed(llvm::omp::Clause::OMPC_grainsize); - RequiresPositiveParameter(llvm::omp::Clause::OMPC_grainsize, x.v); -} -void OmpStructureChecker::Enter(const parser::OmpClause::Lastprivate &) { - CheckAllowed(llvm::omp::Clause::OMPC_lastprivate); -} -void OmpStructureChecker::Enter(const parser::OmpClause::NumTasks &x) { - CheckAllowed(llvm::omp::Clause::OMPC_num_tasks); - RequiresPositiveParameter(llvm::omp::Clause::OMPC_num_tasks, x.v); -} -void OmpStructureChecker::Enter(const parser::OmpClause::NumTeams &x) { - CheckAllowed(llvm::omp::Clause::OMPC_num_teams); - RequiresPositiveParameter(llvm::omp::Clause::OMPC_num_teams, x.v); -} -void OmpStructureChecker::Enter(const parser::OmpClause::NumThreads &x) { - CheckAllowed(llvm::omp::Clause::OMPC_num_threads); - RequiresPositiveParameter(llvm::omp::Clause::OMPC_num_threads, x.v); - // if parameter is variable, defer to Expression Analysis -} - +// Following clauses do not have a seperate node in parse-tree.h. +// They fall under 'struct OmpClause' in parse-tree.h. +CHECK_SIMPLE_CLAUSE(Copyin, OMPC_copyin) +CHECK_SIMPLE_CLAUSE(Copyprivate, OMPC_copyprivate) +CHECK_SIMPLE_CLAUSE(Device, OMPC_device) +CHECK_SIMPLE_CLAUSE(Final, OMPC_final) +CHECK_SIMPLE_CLAUSE(Firstprivate, OMPC_firstprivate) +CHECK_SIMPLE_CLAUSE(From, OMPC_from) +CHECK_SIMPLE_CLAUSE(Inbranch, OMPC_inbranch) +CHECK_SIMPLE_CLAUSE(IsDevicePtr, OMPC_is_device_ptr) +CHECK_SIMPLE_CLAUSE(Lastprivate, OMPC_lastprivate) +CHECK_SIMPLE_CLAUSE(Link, OMPC_link) +CHECK_SIMPLE_CLAUSE(Mergeable, OMPC_mergeable) +CHECK_SIMPLE_CLAUSE(Nogroup, OMPC_nogroup) +CHECK_SIMPLE_CLAUSE(Notinbranch, OMPC_notinbranch) +CHECK_SIMPLE_CLAUSE(Private, OMPC_private) +CHECK_SIMPLE_CLAUSE(Shared, OMPC_shared) +CHECK_SIMPLE_CLAUSE(To, OMPC_to) +CHECK_SIMPLE_CLAUSE(Uniform, OMPC_uniform) +CHECK_SIMPLE_CLAUSE(Untied, OMPC_untied) +CHECK_SIMPLE_CLAUSE(UseDevicePtr, OMPC_use_device_ptr) + +CHECK_REQ_SCALAR_INT_CLAUSE(Grainsize, OMPC_grainsize) +CHECK_REQ_SCALAR_INT_CLAUSE(NumTasks, OMPC_num_tasks) +CHECK_REQ_SCALAR_INT_CLAUSE(NumTeams, OMPC_num_teams) +CHECK_REQ_SCALAR_INT_CLAUSE(NumThreads, OMPC_num_threads) +CHECK_REQ_SCALAR_INT_CLAUSE(Priority, OMPC_priority) +CHECK_REQ_SCALAR_INT_CLAUSE(ThreadLimit, OMPC_thread_limit) + +CHECK_REQ_CONSTANT_SCALAR_INT_CLAUSE(Collapse, OMPC_collapse) +CHECK_REQ_CONSTANT_SCALAR_INT_CLAUSE(Safelen, OMPC_safelen) +CHECK_REQ_CONSTANT_SCALAR_INT_CLAUSE(Simdlen, OMPC_simdlen) + +// Restrictions specific to each clause are implemented apart from the +// generalized restrictions. void OmpStructureChecker::Enter(const parser::OmpClause::Ordered &x) { CheckAllowed(llvm::omp::Clause::OMPC_ordered); // the parameter of ordered clause is optional @@ -422,44 +420,18 @@ } } } -void OmpStructureChecker::Enter(const parser::OmpClause::Priority &x) { - CheckAllowed(llvm::omp::Clause::OMPC_priority); - RequiresPositiveParameter(llvm::omp::Clause::OMPC_priority, x.v); -} -void OmpStructureChecker::Enter(const parser::OmpClause::Private &) { - CheckAllowed(llvm::omp::Clause::OMPC_private); -} -void OmpStructureChecker::Enter(const parser::OmpClause::Safelen &x) { - CheckAllowed(llvm::omp::Clause::OMPC_safelen); - RequiresConstantPositiveParameter(llvm::omp::Clause::OMPC_safelen, x.v); -} -void OmpStructureChecker::Enter(const parser::OmpClause::Shared &) { - CheckAllowed(llvm::omp::Clause::OMPC_shared); -} -void OmpStructureChecker::Enter(const parser::OmpClause::Simdlen &x) { - CheckAllowed(llvm::omp::Clause::OMPC_simdlen); - RequiresConstantPositiveParameter(llvm::omp::Clause::OMPC_simdlen, x.v); -} -void OmpStructureChecker::Enter(const parser::OmpClause::ThreadLimit &x) { - CheckAllowed(llvm::omp::Clause::OMPC_thread_limit); - RequiresPositiveParameter(llvm::omp::Clause::OMPC_thread_limit, x.v); -} -void OmpStructureChecker::Enter(const parser::OmpClause::To &) { - CheckAllowed(llvm::omp::Clause::OMPC_to); -} -void OmpStructureChecker::Enter(const parser::OmpClause::Link &) { - CheckAllowed(llvm::omp::Clause::OMPC_link); -} -void OmpStructureChecker::Enter(const parser::OmpClause::Uniform &) { - CheckAllowed(llvm::omp::Clause::OMPC_uniform); -} -void OmpStructureChecker::Enter(const parser::OmpClause::UseDevicePtr &) { - CheckAllowed(llvm::omp::Clause::OMPC_use_device_ptr); -} -void OmpStructureChecker::Enter(const parser::OmpClause::IsDevicePtr &) { - CheckAllowed(llvm::omp::Clause::OMPC_is_device_ptr); -} +// Following clauses have a seperate node in parse-tree.h. +CHECK_SIMPLE_PARSER_CLAUSE(OmpAllocateClause, OMPC_allocate) +CHECK_SIMPLE_PARSER_CLAUSE(OmpDefaultClause, OMPC_default) +CHECK_SIMPLE_PARSER_CLAUSE(OmpDependClause, OMPC_depend) +CHECK_SIMPLE_PARSER_CLAUSE(OmpDistScheduleClause, OMPC_dist_schedule) +CHECK_SIMPLE_PARSER_CLAUSE(OmpNowait, OMPC_nowait) +CHECK_SIMPLE_PARSER_CLAUSE(OmpProcBindClause, OMPC_proc_bind) +CHECK_SIMPLE_PARSER_CLAUSE(OmpReductionClause, OMPC_reduction) + +// Restrictions specific to each clause are implemented apart from the +// generalized restrictions. void OmpStructureChecker::Enter(const parser::OmpAlignedClause &x) { CheckAllowed(llvm::omp::Clause::OMPC_aligned); @@ -475,12 +447,6 @@ } // 2.8.1 TODO: list-item attribute check } -void OmpStructureChecker::Enter(const parser::OmpAllocateClause &) { - CheckAllowed(llvm::omp::Clause::OMPC_allocate); -} -void OmpStructureChecker::Enter(const parser::OmpDefaultClause &) { - CheckAllowed(llvm::omp::Clause::OMPC_default); -} void OmpStructureChecker::Enter(const parser::OmpDefaultmapClause &x) { CheckAllowed(llvm::omp::Clause::OMPC_defaultmap); using VariableCategory = parser::OmpDefaultmapClause::VariableCategory; @@ -490,10 +456,6 @@ "clause"_err_en_US); } } -void OmpStructureChecker::Enter(const parser::OmpDependClause &) { - CheckAllowed(llvm::omp::Clause::OMPC_depend); -} - void OmpStructureChecker::Enter(const parser::OmpIfClause &x) { CheckAllowed(llvm::omp::Clause::OMPC_if); @@ -582,12 +544,6 @@ } } } -void OmpStructureChecker::Enter(const parser::OmpProcBindClause &) { - CheckAllowed(llvm::omp::Clause::OMPC_proc_bind); -} -void OmpStructureChecker::Enter(const parser::OmpReductionClause &) { - CheckAllowed(llvm::omp::Clause::OMPC_reduction); -} bool OmpStructureChecker::ScheduleModifierHasType( const parser::OmpScheduleClause &x,