[flang] Semantic checks for OpenMP combined constructs.

Summary:
This includes a refactor of the existing combined construct checks
that were present, as well as adding the remaining combined constructs
that had not been implemented yet.

Reviewers: jdoerfert

Subscribers: yaxunl, guansong, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D77812
This commit is contained in:
David Truby 2020-04-09 18:54:28 +01:00
parent b547e1a4d1
commit 75c31057a7
5 changed files with 785 additions and 94 deletions

View File

@ -111,6 +111,13 @@ public:
return result;
}
constexpr EnumSet operator+(enumerationType v) const {
return {*this | EnumSet{v}};
}
constexpr EnumSet operator-(enumerationType v) const {
return {*this & ~EnumSet{v}};
}
constexpr bool operator==(const EnumSet &that) const {
return bitset_ == that.bitset_;
}

View File

@ -13,6 +13,52 @@
namespace Fortran::semantics {
static constexpr inline OmpClauseSet doAllowedClauses{OmpClause::PRIVATE,
OmpClause::FIRSTPRIVATE, OmpClause::LASTPRIVATE, OmpClause::LINEAR,
OmpClause::REDUCTION};
static constexpr inline OmpClauseSet doAllowedOnceClauses{
OmpClause::SCHEDULE, OmpClause::COLLAPSE, OmpClause::ORDERED};
static constexpr inline OmpClauseSet simdAllowedClauses{OmpClause::LINEAR,
OmpClause::ALIGNED, OmpClause::PRIVATE, OmpClause::LASTPRIVATE,
OmpClause::REDUCTION};
static constexpr inline OmpClauseSet simdAllowedOnceClauses{
OmpClause::COLLAPSE, OmpClause::SAFELEN, OmpClause::SIMDLEN};
static constexpr inline OmpClauseSet parallelAllowedClauses{OmpClause::DEFAULT,
OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE, OmpClause::SHARED,
OmpClause::COPYIN, OmpClause::REDUCTION};
static constexpr inline OmpClauseSet parallelAllowedOnceClauses{
OmpClause::IF, OmpClause::NUM_THREADS, OmpClause::PROC_BIND};
static constexpr inline OmpClauseSet taskloopAllowedClauses{OmpClause::SHARED,
OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE, OmpClause::LASTPRIVATE,
OmpClause::DEFAULT, OmpClause::UNTIED, OmpClause::MERGEABLE,
OmpClause::NOGROUP};
static constexpr inline OmpClauseSet taskloopAllowedOnceClauses{
OmpClause::COLLAPSE, OmpClause::IF, OmpClause::FINAL, OmpClause::PRIORITY};
static constexpr inline OmpClauseSet taskloopAllowedExclusiveClauses{
OmpClause::GRAINSIZE, OmpClause::NUM_TASKS};
static constexpr inline OmpClauseSet distributeAllowedClauses{
OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE, OmpClause::LASTPRIVATE};
static constexpr inline OmpClauseSet distributeAllowedOnceClauses{
OmpClause::COLLAPSE, OmpClause::DIST_SCHEDULE};
static constexpr inline OmpClauseSet targetAllowedClauses{OmpClause::IF,
OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE, OmpClause::MAP,
OmpClause::IS_DEVICE_PTR, OmpClause::DEPEND};
static constexpr inline OmpClauseSet targetAllowedOnceClauses{
OmpClause::DEVICE, OmpClause::DEFAULTMAP, OmpClause::NOWAIT};
static constexpr inline OmpClauseSet teamsAllowedClauses{OmpClause::PRIVATE,
OmpClause::FIRSTPRIVATE, OmpClause::SHARED, OmpClause::REDUCTION};
static constexpr inline OmpClauseSet teamsAllowedOnceClauses{
OmpClause::NUM_TEAMS, OmpClause::THREAD_LIMIT, OmpClause::DEFAULT};
static constexpr inline OmpClauseSet sectionsAllowedClauses{OmpClause::PRIVATE,
OmpClause::FIRSTPRIVATE, OmpClause::LASTPRIVATE, OmpClause::REDUCTION};
std::string OmpStructureChecker::ContextDirectiveAsFortran() {
auto dir{EnumToString(GetContext().directive)};
std::replace(dir.begin(), dir.end(), '_', ' ');
@ -145,26 +191,16 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
OmpDirective::MASTER});
PushContext(beginDir.source, OmpDirective::DO);
OmpClauseSet allowed{OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE,
OmpClause::LASTPRIVATE, OmpClause::LINEAR, OmpClause::REDUCTION};
SetContextAllowed(allowed);
OmpClauseSet allowedOnce{
OmpClause::SCHEDULE, OmpClause::COLLAPSE, OmpClause::ORDERED};
SetContextAllowedOnce(allowedOnce);
SetContextAllowed(doAllowedClauses);
SetContextAllowedOnce(doAllowedOnceClauses);
} break;
// 2.11.1 parallel-do-clause -> parallel-clause |
// do-clause
case parser::OmpLoopDirective::Directive::ParallelDo: {
PushContext(beginDir.source, OmpDirective::PARALLEL_DO);
OmpClauseSet allowed{OmpClause::DEFAULT, OmpClause::PRIVATE,
OmpClause::FIRSTPRIVATE, OmpClause::SHARED, OmpClause::COPYIN,
OmpClause::REDUCTION, OmpClause::LASTPRIVATE, OmpClause::LINEAR};
SetContextAllowed(allowed);
OmpClauseSet allowedOnce{OmpClause::IF, OmpClause::NUM_THREADS,
OmpClause::PROC_BIND, OmpClause::SCHEDULE, OmpClause::COLLAPSE,
OmpClause::ORDERED};
SetContextAllowedOnce(allowedOnce);
SetContextAllowed(parallelAllowedClauses | doAllowedClauses);
SetContextAllowedOnce(parallelAllowedOnceClauses | doAllowedOnceClauses);
} break;
// 2.8.1 simd-clause -> safelen-clause |
@ -177,40 +213,26 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
// collapse-clause
case parser::OmpLoopDirective::Directive::Simd: {
PushContext(beginDir.source, OmpDirective::SIMD);
OmpClauseSet allowed{OmpClause::LINEAR, OmpClause::ALIGNED,
OmpClause::PRIVATE, OmpClause::LASTPRIVATE, OmpClause::REDUCTION};
SetContextAllowed(allowed);
OmpClauseSet allowedOnce{
OmpClause::COLLAPSE, OmpClause::SAFELEN, OmpClause::SIMDLEN};
SetContextAllowedOnce(allowedOnce);
SetContextAllowed(simdAllowedClauses);
SetContextAllowedOnce(simdAllowedOnceClauses);
} break;
// 2.8.3 do-simd-clause -> do-clause |
// simd-clause
case parser::OmpLoopDirective::Directive::DoSimd: {
PushContext(beginDir.source, OmpDirective::DO_SIMD);
OmpClauseSet allowed{OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE,
OmpClause::LASTPRIVATE, OmpClause::LINEAR, OmpClause::REDUCTION,
OmpClause::ALIGNED};
SetContextAllowed(allowed);
OmpClauseSet allowedOnce{OmpClause::SCHEDULE, OmpClause::COLLAPSE,
OmpClause::ORDERED, OmpClause::SAFELEN, OmpClause::SIMDLEN};
SetContextAllowedOnce(allowedOnce);
SetContextAllowed(doAllowedClauses | simdAllowedClauses);
SetContextAllowedOnce(doAllowedOnceClauses | simdAllowedOnceClauses);
} break;
// 2.11.4 parallel-do-simd-clause -> parallel-clause |
// do-simd-clause
case parser::OmpLoopDirective::Directive::ParallelDoSimd: {
PushContext(beginDir.source, OmpDirective::PARALLEL_DO_SIMD);
OmpClauseSet allowed{OmpClause::DEFAULT, OmpClause::PRIVATE,
OmpClause::FIRSTPRIVATE, OmpClause::SHARED, OmpClause::COPYIN,
OmpClause::REDUCTION, OmpClause::LASTPRIVATE, OmpClause::LINEAR,
OmpClause::ALIGNED};
SetContextAllowed(allowed);
OmpClauseSet allowedOnce{OmpClause::IF, OmpClause::NUM_THREADS,
OmpClause::PROC_BIND, OmpClause::SCHEDULE, OmpClause::COLLAPSE,
OmpClause::ORDERED, OmpClause::SAFELEN, OmpClause::SIMDLEN};
SetContextAllowedOnce(allowedOnce);
SetContextAllowed(
parallelAllowedClauses | doAllowedClauses | simdAllowedClauses);
SetContextAllowedOnce(parallelAllowedOnceClauses | doAllowedOnceClauses |
simdAllowedOnceClauses);
} break;
// 2.9.2 taskloop-clause -> if-clause |
@ -229,32 +251,19 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
// nogroup-clause
case parser::OmpLoopDirective::Directive::Taskloop: {
PushContext(beginDir.source, OmpDirective::TASKLOOP);
OmpClauseSet allowed{OmpClause::SHARED, OmpClause::PRIVATE,
OmpClause::FIRSTPRIVATE, OmpClause::LASTPRIVATE, OmpClause::DEFAULT,
OmpClause::UNTIED, OmpClause::MERGEABLE, OmpClause::NOGROUP};
SetContextAllowed(allowed);
OmpClauseSet allowedOnce{OmpClause::COLLAPSE, OmpClause::IF,
OmpClause::FINAL, OmpClause::PRIORITY};
SetContextAllowedOnce(allowedOnce);
OmpClauseSet allowedExclusive{OmpClause::GRAINSIZE, OmpClause::NUM_TASKS};
SetContextAllowedExclusive(allowedExclusive);
SetContextAllowed(taskloopAllowedClauses);
SetContextAllowedOnce(taskloopAllowedOnceClauses);
SetContextAllowedExclusive(taskloopAllowedExclusiveClauses);
} break;
// 2.9.3 taskloop-simd-clause -> taskloop-clause |
// simd-clause
case parser::OmpLoopDirective::Directive::TaskloopSimd: {
PushContext(beginDir.source, OmpDirective::TASKLOOP_SIMD);
OmpClauseSet allowed{OmpClause::LINEAR, OmpClause::ALIGNED,
OmpClause::SHARED, OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE,
OmpClause::LASTPRIVATE, OmpClause::DEFAULT, OmpClause::UNTIED,
OmpClause::MERGEABLE, OmpClause::NOGROUP};
SetContextAllowed(allowed);
OmpClauseSet allowedOnce{OmpClause::COLLAPSE, OmpClause::SAFELEN,
OmpClause::SIMDLEN, OmpClause::IF, OmpClause::FINAL,
OmpClause::PRIORITY};
SetContextAllowedOnce(allowedOnce);
OmpClauseSet allowedExclusive{OmpClause::GRAINSIZE, OmpClause::NUM_TASKS};
SetContextAllowedExclusive(allowedExclusive);
SetContextAllowed(
taskloopAllowedClauses | simdAllowedClauses - OmpClause::REDUCTION);
SetContextAllowedOnce(taskloopAllowedOnceClauses | simdAllowedOnceClauses);
SetContextAllowedExclusive(taskloopAllowedExclusiveClauses);
} break;
// 2.10.8 distribute-clause -> private-clause |
@ -264,16 +273,159 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
// dist-schedule-clause
case parser::OmpLoopDirective::Directive::Distribute: {
PushContext(beginDir.source, OmpDirective::DISTRIBUTE);
OmpClauseSet allowed{
OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE, OmpClause::LASTPRIVATE};
SetContextAllowed(allowed);
OmpClauseSet allowedOnce{OmpClause::COLLAPSE, OmpClause::DIST_SCHEDULE};
SetContextAllowedOnce(allowedOnce);
SetContextAllowed(distributeAllowedClauses);
SetContextAllowedOnce(distributeAllowedOnceClauses);
} break;
default:
// TODO others
break;
// 2.10.9 distribute-simd-clause -> distribute-clause |
// simd-clause
case parser::OmpLoopDirective::Directive::DistributeSimd: {
PushContext(beginDir.source, OmpDirective::DISTRIBUTE_SIMD);
SetContextAllowed(distributeAllowedClauses | simdAllowedClauses);
SetContextAllowedOnce(
distributeAllowedOnceClauses | simdAllowedOnceClauses);
} break;
// 2.10.10 distribute-parallel-do-clause -> distribute-clause |
// parallel-do-clause
case parser::OmpLoopDirective::Directive::DistributeParallelDo: {
PushContext(beginDir.source, OmpDirective::DISTRIBUTE_PARALLEL_DO);
SetContextAllowed(
distributeAllowedClauses | parallelAllowedClauses | doAllowedClauses);
SetContextAllowedOnce(distributeAllowedOnceClauses |
parallelAllowedOnceClauses | doAllowedOnceClauses);
} break;
// 2.10.11 distribute-parallel-do-simd-clause -> distribute-clause |
// parallel-do-simd-clause
case parser::OmpLoopDirective::Directive::DistributeParallelDoSimd: {
PushContext(beginDir.source, OmpDirective::DISTRIBUTE_PARALLEL_DO_SIMD);
SetContextAllowed(distributeAllowedClauses | parallelAllowedClauses |
doAllowedClauses | simdAllowedClauses);
SetContextAllowedOnce(distributeAllowedOnceClauses |
parallelAllowedOnceClauses | doAllowedOnceClauses | simdAllowedClauses);
} break;
// 2.11.6 target-parallel-do-clause -> target-clause |
// parallel-do-clause
case parser::OmpLoopDirective::Directive::TargetParallelDo: {
PushContext(beginDir.source, OmpDirective::TARGET_PARALLEL_DO);
SetContextAllowed(
targetAllowedClauses | parallelAllowedClauses | doAllowedClauses);
SetContextAllowedOnce(
(targetAllowedOnceClauses | parallelAllowedOnceClauses |
doAllowedOnceClauses) -
OmpClause::NOWAIT);
} break;
// 2.11.7 target-parallel-do-simd-clause -> target-clause |
// parallel-do-simd-clause
case parser::OmpLoopDirective::Directive::TargetParallelDoSimd: {
PushContext(beginDir.source, OmpDirective::TARGET_PARALLEL_DO_SIMD);
SetContextAllowed(targetAllowedClauses | parallelAllowedClauses |
doAllowedClauses | simdAllowedClauses);
SetContextAllowedOnce(
(targetAllowedOnceClauses | parallelAllowedOnceClauses |
doAllowedOnceClauses | simdAllowedOnceClauses) -
OmpClause::NOWAIT);
} break;
// 2.11.8 target-simd-clause -> target-clause |
// simd-clause
case parser::OmpLoopDirective::Directive::TargetSimd: {
PushContext(beginDir.source, OmpDirective::TARGET_SIMD);
SetContextAllowed(targetAllowedClauses | simdAllowedClauses);
SetContextAllowedOnce(targetAllowedOnceClauses | simdAllowedOnceClauses);
} break;
// 2.11.10 teams-distribute-clause -> teams-clause |
// distribute-clause
case parser::OmpLoopDirective::Directive::TeamsDistribute: {
PushContext(beginDir.source, OmpDirective::TEAMS_DISTRIBUTE);
SetContextAllowed(teamsAllowedClauses | distributeAllowedClauses);
SetContextAllowedOnce(
teamsAllowedOnceClauses | distributeAllowedOnceClauses);
} break;
// 2.11.11 teams-distribute-simd-clause -> teams-clause |
// distribute-simd-clause
case parser::OmpLoopDirective::Directive::TeamsDistributeSimd: {
PushContext(beginDir.source, OmpDirective::TEAMS_DISTRIBUTE_SIMD);
SetContextAllowed(
teamsAllowedClauses | distributeAllowedClauses | simdAllowedClauses);
SetContextAllowedOnce(teamsAllowedOnceClauses |
distributeAllowedOnceClauses | simdAllowedOnceClauses);
} break;
// 2.11.12 target-teams-distribute-clause -> target-clause |
// teams-distribute-clause
case parser::OmpLoopDirective::Directive::TargetTeamsDistribute: {
PushContext(beginDir.source, OmpDirective::TARGET_TEAMS_DISTRIBUTE);
SetContextAllowed(
targetAllowedClauses | teamsAllowedClauses | distributeAllowedClauses);
SetContextAllowedOnce(targetAllowedOnceClauses | teamsAllowedOnceClauses |
distributeAllowedOnceClauses);
} break;
// 2.11.13 target-teams-distribute-simd-clause -> target-clause |
// teams-distribute-simd-clause
case parser::OmpLoopDirective::Directive::TargetTeamsDistributeSimd: {
PushContext(beginDir.source, OmpDirective::TARGET_TEAMS_DISTRIBUTE_SIMD);
SetContextAllowed(targetAllowedClauses | teamsAllowedClauses |
distributeAllowedClauses | simdAllowedClauses);
SetContextAllowed(targetAllowedOnceClauses | teamsAllowedOnceClauses |
distributeAllowedOnceClauses | simdAllowedOnceClauses);
} break;
// 2.11.14 teams-distribute-parallel-do-clause -> teams-clause |
// distribute-parallel-do-clause
case parser::OmpLoopDirective::Directive::TeamsDistributeParallelDo: {
PushContext(beginDir.source, OmpDirective::TEAMS_DISTRIBUTE_PARALLEL_DO);
SetContextAllowed(teamsAllowedClauses | distributeAllowedClauses |
parallelAllowedClauses | doAllowedClauses);
SetContextAllowedOnce(teamsAllowedOnceClauses |
distributeAllowedOnceClauses | parallelAllowedOnceClauses |
doAllowedOnceClauses);
} break;
// 2.11.15 target-teams-distribute-parallel-do-clause -> target-clause |
// teams-distribute-parallel-do-clause
case parser::OmpLoopDirective::Directive::TargetTeamsDistributeParallelDo: {
PushContext(
beginDir.source, OmpDirective::TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO);
SetContextAllowed(targetAllowedClauses | teamsAllowedClauses |
distributeAllowedClauses | parallelAllowedClauses | doAllowedClauses);
SetContextAllowedOnce(targetAllowedOnceClauses | teamsAllowedOnceClauses |
distributeAllowedOnceClauses | parallelAllowedOnceClauses |
doAllowedOnceClauses);
} break;
// 2.11.16 teams-distribute-parallel-do-clause -> teams-clause |
// distribute-parallel-do-simd-clause
case parser::OmpLoopDirective::Directive::TeamsDistributeParallelDoSimd: {
PushContext(
beginDir.source, OmpDirective::TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD);
SetContextAllowed(teamsAllowedClauses | distributeAllowedClauses |
parallelAllowedClauses | doAllowedClauses | simdAllowedClauses);
SetContextAllowedOnce(teamsAllowedOnceClauses |
distributeAllowedOnceClauses | parallelAllowedOnceClauses |
doAllowedOnceClauses | simdAllowedOnceClauses);
} break;
case parser::OmpLoopDirective::Directive::
TargetTeamsDistributeParallelDoSimd: {
PushContext(beginDir.source,
OmpDirective::TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD);
SetContextAllowed(targetAllowedClauses | teamsAllowedClauses |
distributeAllowedClauses | parallelAllowedClauses | doAllowedClauses |
simdAllowedClauses);
SetContextAllowedOnce(targetAllowedOnceClauses | teamsAllowedOnceClauses |
distributeAllowedOnceClauses | parallelAllowedOnceClauses |
doAllowedOnceClauses | simdAllowedOnceClauses);
}
// TODO others
break;
}
}
@ -320,13 +472,8 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
case parser::OmpBlockDirective::Directive::Parallel: {
// reserve for nesting check
PushContext(beginDir.source, OmpDirective::PARALLEL);
OmpClauseSet allowed{OmpClause::DEFAULT, OmpClause::PRIVATE,
OmpClause::FIRSTPRIVATE, OmpClause::SHARED, OmpClause::COPYIN,
OmpClause::REDUCTION};
SetContextAllowed(allowed);
OmpClauseSet allowedOnce{
OmpClause::IF, OmpClause::NUM_THREADS, OmpClause::PROC_BIND};
SetContextAllowedOnce(allowedOnce);
SetContextAllowed(parallelAllowedClauses);
SetContextAllowedOnce(parallelAllowedOnceClauses);
} break;
// 2.7.3 single-clause -> private-clause |
// firstprivate-clause
@ -338,6 +485,12 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
case parser::OmpBlockDirective::Directive::Workshare:
PushContext(beginDir.source, OmpDirective::WORKSHARE);
break;
// 2.11.3 parallel-workshare-clause -> parallel-clause
case parser::OmpBlockDirective::Directive::ParallelWorkshare: {
PushContext(beginDir.source, OmpDirective::PARALLEL_WORKSHARE);
SetContextAllowed(parallelAllowedClauses);
SetContextAllowedOnce(parallelAllowedOnceClauses);
} break;
// 2.9.1 task-clause -> if-clause |
// final-clause |
// untied-clause |
@ -369,13 +522,8 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
// depend-clause
case parser::OmpBlockDirective::Directive::Target: {
PushContext(beginDir.source, OmpDirective::TARGET);
OmpClauseSet allowed{OmpClause::IF, OmpClause::PRIVATE,
OmpClause::FIRSTPRIVATE, OmpClause::MAP, OmpClause::IS_DEVICE_PTR,
OmpClause::DEPEND};
SetContextAllowed(allowed);
OmpClauseSet allowedOnce{
OmpClause::DEVICE, OmpClause::DEFAULTMAP, OmpClause::NOWAIT};
SetContextAllowedOnce(allowedOnce);
SetContextAllowed(targetAllowedClauses);
SetContextAllowedOnce(targetAllowedOnceClauses);
} break;
// 2.10.7 teams-clause -> num-teams-clause |
// thread-limit-clause |
@ -386,12 +534,15 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
// reduction-clause
case parser::OmpBlockDirective::Directive::Teams: {
PushContext(beginDir.source, OmpDirective::TEAMS);
OmpClauseSet allowed{OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE,
OmpClause::SHARED, OmpClause::REDUCTION};
SetContextAllowed(allowed);
OmpClauseSet allowedOnce{
OmpClause::NUM_TEAMS, OmpClause::THREAD_LIMIT, OmpClause::DEFAULT};
SetContextAllowedOnce(allowedOnce);
SetContextAllowed(teamsAllowedClauses);
SetContextAllowedOnce(teamsAllowedOnceClauses);
} break;
// 2.11.9 target-teams -> target-clause |
// teams-clause
case parser::OmpBlockDirective::Directive::TargetTeams: {
PushContext(beginDir.source, OmpDirective::TARGET_TEAMS);
SetContextAllowed(targetAllowedClauses | teamsAllowedClauses);
SetContextAllowedOnce(targetAllowedOnceClauses | teamsAllowedOnceClauses);
} break;
// 2.10.1 target-data-clause -> if-clause |
// device-clause |
@ -409,6 +560,15 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
case parser::OmpBlockDirective::Directive::Master:
PushContext(beginDir.source, OmpDirective::MASTER);
break;
// 2.11.5 target-parallel-clause -> target-clause |
// parallel-clause
case parser::OmpBlockDirective::Directive::TargetParallel: {
PushContext(beginDir.source, OmpDirective::TARGET_PARALLEL);
SetContextAllowed(
(targetAllowedClauses | parallelAllowedClauses) - OmpClause::COPYIN);
SetContextAllowedOnce(
targetAllowedOnceClauses | parallelAllowedOnceClauses);
} break;
default:
// TODO others
break;
@ -433,19 +593,14 @@ void OmpStructureChecker::Enter(const parser::OpenMPSectionsConstruct &x) {
// reduction-clause
case parser::OmpSectionsDirective::Directive::Sections: {
PushContext(beginDir.source, OmpDirective::SECTIONS);
OmpClauseSet allowed{OmpClause::PRIVATE, OmpClause::FIRSTPRIVATE,
OmpClause::LASTPRIVATE, OmpClause::REDUCTION};
SetContextAllowed(allowed);
SetContextAllowed(sectionsAllowedClauses);
} break;
// 2.11.2 -> parallel-sections-clause -> parallel-clause |
// sections-clause
case parser::OmpSectionsDirective::Directive::ParallelSections: {
PushContext(beginDir.source, OmpDirective::PARALLEL_SECTIONS);
OmpClauseSet allowed{OmpClause::DEFAULT, OmpClause::PRIVATE,
OmpClause::FIRSTPRIVATE, OmpClause::LASTPRIVATE, OmpClause::SHARED,
OmpClause::COPYIN, OmpClause::REDUCTION};
SetContextAllowed(allowed);
OmpClauseSet allowedOnce{
OmpClause::IF, OmpClause::NUM_THREADS, OmpClause::PROC_BIND};
SetContextAllowedOnce(allowedOnce);
SetContextAllowed(parallelAllowedClauses | sectionsAllowedClauses);
SetContextAllowedOnce(parallelAllowedOnceClauses);
} break;
}
}
@ -913,6 +1068,11 @@ void OmpStructureChecker::Enter(const parser::OmpMapClause &x) {
const Type &type{std::get<Type>(maptype->t)};
switch (GetContext().directive) {
case OmpDirective::TARGET:
case OmpDirective::TARGET_TEAMS:
case OmpDirective::TARGET_TEAMS_DISTRIBUTE:
case OmpDirective::TARGET_TEAMS_DISTRIBUTE_SIMD:
case OmpDirective::TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
case OmpDirective::TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
case OmpDirective::TARGET_DATA: {
if (type != Type::To && type != Type::From && type != Type::Tofrom &&
type != Type::Alloc) {

View File

@ -6300,6 +6300,15 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPBlockConstruct &x) {
case parser::OmpBlockDirective::Directive::Workshare:
PushContext(beginDir.source, OmpDirective::WORKSHARE);
break;
case parser::OmpBlockDirective::Directive::ParallelWorkshare:
PushContext(beginDir.source, OmpDirective::PARALLEL_WORKSHARE);
break;
case parser::OmpBlockDirective::Directive::TargetTeams:
PushContext(beginDir.source, OmpDirective::TARGET_TEAMS);
break;
case parser::OmpBlockDirective::Directive::TargetParallel:
PushContext(beginDir.source, OmpDirective::TARGET_PARALLEL);
break;
default:
// TODO others
break;

View File

@ -0,0 +1,509 @@
! RUN: %B/test/Semantics/test_errors.sh %s %flang %t
! OPTIONS: -fopenmp
program main
implicit none
integer :: N
integer :: i
real(8) :: a(256), b(256)
N = 256
!$omp distribute simd
do i = 1, N
a(i) = 3.14
enddo
!$omp end distribute simd
!$omp target parallel device(0)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target parallel
!ERROR: At most one DEVICE clause can appear on the TARGET PARALLEL directive
!$omp target parallel device(0) device(1)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target parallel
!$omp target parallel defaultmap(tofrom:scalar)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target parallel
!ERROR: The argument TOFROM:SCALAR must be specified on the DEFAULTMAP clause
!$omp target parallel defaultmap(tofrom)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target parallel
!ERROR: At most one DEFAULTMAP clause can appear on the TARGET PARALLEL directive
!$omp target parallel defaultmap(tofrom:scalar) defaultmap(tofrom:scalar)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target parallel
!$omp target parallel map(tofrom:a)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target parallel
!ERROR: COPYIN clause is not allowed on the TARGET PARALLEL directive
!$omp target parallel copyin(a)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target parallel
!$omp target parallel do device(0)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target parallel do
!ERROR: At most one DEVICE clause can appear on the TARGET PARALLEL DO directive
!$omp target parallel do device(0) device(1)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target parallel do
!$omp target parallel do defaultmap(tofrom:scalar)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target parallel do
!ERROR: The argument TOFROM:SCALAR must be specified on the DEFAULTMAP clause
!$omp target parallel do defaultmap(tofrom)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target parallel do
!ERROR: At most one DEFAULTMAP clause can appear on the TARGET PARALLEL DO directive
!$omp target parallel do defaultmap(tofrom:scalar) defaultmap(tofrom:scalar)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target parallel do
!$omp target parallel do map(tofrom:a)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target parallel do
!$omp target parallel do copyin(a)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target parallel do
!$omp target teams map(a)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams
!$omp target teams device(0)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams
!ERROR: At most one DEVICE clause can appear on the TARGET TEAMS directive
!$omp target teams device(0) device(1)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams
!ERROR: SCHEDULE clause is not allowed on the TARGET TEAMS directive
!$omp target teams schedule(static)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams
!$omp target teams defaultmap(tofrom:scalar)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams
!ERROR: The argument TOFROM:SCALAR must be specified on the DEFAULTMAP clause
!$omp target teams defaultmap(tofrom)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams
!ERROR: At most one DEFAULTMAP clause can appear on the TARGET TEAMS directive
!$omp target teams defaultmap(tofrom:scalar) defaultmap(tofrom:scalar)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams
!$omp target teams num_teams(3) thread_limit(10) default(shared) private(i) shared(a)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams
!ERROR: At most one NUM_TEAMS clause can appear on the TARGET TEAMS directive
!$omp target teams num_teams(2) num_teams(3)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams
!ERROR: The parameter of the NUM_TEAMS clause must be a positive integer expression
!$omp target teams num_teams(-1)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams
!ERROR: At most one THREAD_LIMIT clause can appear on the TARGET TEAMS directive
!$omp target teams thread_limit(2) thread_limit(3)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams
!ERROR: The parameter of the THREAD_LIMIT clause must be a positive integer expression
!$omp target teams thread_limit(-1)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams
!ERROR: At most one DEFAULT clause can appear on the TARGET TEAMS directive
!$omp target teams default(shared) default(private)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams
!$omp target teams num_teams(2) defaultmap(tofrom:scalar)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams
!$omp target teams map(tofrom:a)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams
!ERROR: Only the TO, FROM, TOFROM, or ALLOC map types are permitted for MAP clauses on the TARGET TEAMS directive
!$omp target teams map(delete:a)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams
!$omp target teams distribute map(a)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute
!$omp target teams distribute device(0)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute
!ERROR: At most one DEVICE clause can appear on the TARGET TEAMS DISTRIBUTE directive
!$omp target teams distribute device(0) device(1)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute
!$omp target teams distribute defaultmap(tofrom:scalar)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute
!ERROR: The argument TOFROM:SCALAR must be specified on the DEFAULTMAP clause
!$omp target teams distribute defaultmap(tofrom)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute
!ERROR: At most one DEFAULTMAP clause can appear on the TARGET TEAMS DISTRIBUTE directive
!$omp target teams distribute defaultmap(tofrom:scalar) defaultmap(tofrom:scalar)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute
!$omp target teams distribute num_teams(3) thread_limit(10) default(shared) private(i) shared(a)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute
!ERROR: At most one NUM_TEAMS clause can appear on the TARGET TEAMS DISTRIBUTE directive
!$omp target teams distribute num_teams(2) num_teams(3)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute
!ERROR: The parameter of the NUM_TEAMS clause must be a positive integer expression
!$omp target teams distribute num_teams(-1)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute
!ERROR: At most one THREAD_LIMIT clause can appear on the TARGET TEAMS DISTRIBUTE directive
!$omp target teams distribute thread_limit(2) thread_limit(3)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute
!ERROR: The parameter of the THREAD_LIMIT clause must be a positive integer expression
!$omp target teams distribute thread_limit(-1)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute
!ERROR: At most one DEFAULT clause can appear on the TARGET TEAMS DISTRIBUTE directive
!$omp target teams distribute default(shared) default(private)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute
!$omp target teams distribute num_teams(2) defaultmap(tofrom:scalar)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute
!$omp target teams distribute map(tofrom:a)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute
!ERROR: Only the TO, FROM, TOFROM, or ALLOC map types are permitted for MAP clauses on the TARGET TEAMS DISTRIBUTE directive
!$omp target teams distribute map(delete:a)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute
!$omp target teams distribute parallel do device(0)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do
!ERROR: At most one DEVICE clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO directive
!$omp target teams distribute parallel do device(0) device(1)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do
!$omp target teams distribute parallel do defaultmap(tofrom:scalar)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do
!ERROR: The argument TOFROM:SCALAR must be specified on the DEFAULTMAP clause
!$omp target teams distribute parallel do defaultmap(tofrom)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do
!ERROR: At most one DEFAULTMAP clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO directive
!$omp target teams distribute parallel do defaultmap(tofrom:scalar) defaultmap(tofrom:scalar)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do
!$omp target teams distribute parallel do num_teams(3) thread_limit(10) default(shared) private(i) shared(a)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do
!ERROR: At most one NUM_TEAMS clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO directive
!$omp target teams distribute parallel do num_teams(2) num_teams(3)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do
!ERROR: The parameter of the NUM_TEAMS clause must be a positive integer expression
!$omp target teams distribute parallel do num_teams(-1)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do
!ERROR: At most one THREAD_LIMIT clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO directive
!$omp target teams distribute parallel do thread_limit(2) thread_limit(3)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do
!ERROR: The parameter of the THREAD_LIMIT clause must be a positive integer expression
!$omp target teams distribute parallel do thread_limit(-1)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do
!ERROR: At most one DEFAULT clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO directive
!$omp target teams distribute parallel do default(shared) default(private)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do
!$omp target teams distribute parallel do num_teams(2) defaultmap(tofrom:scalar)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do
!$omp target teams distribute parallel do map(tofrom:a)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do
!ERROR: Only the TO, FROM, TOFROM, or ALLOC map types are permitted for MAP clauses on the TARGET TEAMS DISTRIBUTE PARALLEL DO directive
!$omp target teams distribute parallel do map(delete:a)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do
!$omp target teams distribute parallel do simd map(a)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do simd
!$omp target teams distribute parallel do simd device(0)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do simd
!ERROR: At most one DEVICE clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD directive
!$omp target teams distribute parallel do simd device(0) device(1)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do simd
!$omp target teams distribute parallel do simd defaultmap(tofrom:scalar)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do simd
!ERROR: The argument TOFROM:SCALAR must be specified on the DEFAULTMAP clause
!$omp target teams distribute parallel do simd defaultmap(tofrom)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do simd
!ERROR: At most one DEFAULTMAP clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD directive
!$omp target teams distribute parallel do simd defaultmap(tofrom:scalar) defaultmap(tofrom:scalar)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do simd
!$omp target teams distribute parallel do simd num_teams(3) thread_limit(10) default(shared) private(i) shared(a)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do simd
!ERROR: At most one NUM_TEAMS clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD directive
!$omp target teams distribute parallel do simd num_teams(2) num_teams(3)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do simd
!ERROR: The parameter of the NUM_TEAMS clause must be a positive integer expression
!$omp target teams distribute parallel do simd num_teams(-1)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do simd
!ERROR: At most one THREAD_LIMIT clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD directive
!$omp target teams distribute parallel do simd thread_limit(2) thread_limit(3)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do simd
!ERROR: The parameter of the THREAD_LIMIT clause must be a positive integer expression
!$omp target teams distribute parallel do simd thread_limit(-1)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do simd
!ERROR: At most one DEFAULT clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD directive
!$omp target teams distribute parallel do simd default(shared) default(private)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do simd
!$omp target teams distribute parallel do simd num_teams(2) defaultmap(tofrom:scalar)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do simd
!$omp target teams distribute parallel do simd map(tofrom:a)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do simd
!ERROR: Only the TO, FROM, TOFROM, or ALLOC map types are permitted for MAP clauses on the TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD directive
!$omp target teams distribute parallel do simd map(delete:a)
do i = 1, N
a(i) = 3.14
enddo
!$omp end target teams distribute parallel do simd
end program main

View File

@ -98,6 +98,12 @@ program main
enddo
!$omp end teams
!$omp target teams num_teams(2) defaultmap(tofrom:scalar)
do i = 1, N
a = 3.14
enddo
!$omp end target teams
!$omp target map(tofrom:a)
do i = 1, N
a = 3.14