[OPENMP] Allow 'use_device_ptr' clause in 'target data' alone.

According to OpenMP 5.0 at least one 'map' or 'use_device_ptr' clause
must be specified for 'target data' construct. Patch adds support for
this feature.

llvm-svn: 304216
This commit is contained in:
Alexey Bataev 2017-05-30 16:00:04 +00:00
parent f6d4dc5b4a
commit 95b64a9826
9 changed files with 29 additions and 32 deletions

View File

@ -8749,8 +8749,8 @@ def err_omp_not_mappable_type : Error<
"type %0 is not mappable to target">;
def err_omp_invalid_map_type_for_directive : Error<
"%select{map type '%1' is not allowed|map type must be specified}0 for '#pragma omp %2'">;
def err_omp_no_map_for_directive : Error<
"expected at least one map clause for '#pragma omp %0'">;
def err_omp_no_clause_for_directive : Error<
"expected at least one %0 clause for '#pragma omp %1'">;
def note_omp_polymorphic_in_target : Note<
"mappable type cannot be polymorphic">;
def note_omp_static_member_in_target : Note<

View File

@ -5929,16 +5929,17 @@ StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
B, DSAStack->isCancelRegion());
}
/// \brief Check for existence of a map clause in the list of clauses.
static bool HasMapClause(ArrayRef<OMPClause *> Clauses) {
for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
I != E; ++I) {
if (*I != nullptr && (*I)->getClauseKind() == OMPC_map) {
return true;
}
}
/// Check for existence of a map clause in the list of clauses.
static bool hasClauses(ArrayRef<OMPClause *> Clauses,
const OpenMPClauseKind K) {
return llvm::any_of(
Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
}
return false;
template <typename... Params>
static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
const Params... ClauseTypes) {
return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
}
StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
@ -5952,8 +5953,9 @@ StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
// OpenMP [2.10.1, Restrictions, p. 97]
// At least one map clause must appear on the directive.
if (!HasMapClause(Clauses)) {
Diag(StartLoc, diag::err_omp_no_map_for_directive)
if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) {
Diag(StartLoc, diag::err_omp_no_clause_for_directive)
<< "'map' or 'use_device_ptr'"
<< getOpenMPDirectiveName(OMPD_target_data);
return StmtError();
}
@ -5970,9 +5972,9 @@ Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
SourceLocation EndLoc) {
// OpenMP [2.10.2, Restrictions, p. 99]
// At least one map clause must appear on the directive.
if (!HasMapClause(Clauses)) {
Diag(StartLoc, diag::err_omp_no_map_for_directive)
<< getOpenMPDirectiveName(OMPD_target_enter_data);
if (!hasClauses(Clauses, OMPC_map)) {
Diag(StartLoc, diag::err_omp_no_clause_for_directive)
<< "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
return StmtError();
}
@ -5986,9 +5988,9 @@ Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
SourceLocation EndLoc) {
// OpenMP [2.10.3, Restrictions, p. 102]
// At least one map clause must appear on the directive.
if (!HasMapClause(Clauses)) {
Diag(StartLoc, diag::err_omp_no_map_for_directive)
<< getOpenMPDirectiveName(OMPD_target_exit_data);
if (!hasClauses(Clauses, OMPC_map)) {
Diag(StartLoc, diag::err_omp_no_clause_for_directive)
<< "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
return StmtError();
}
@ -5998,12 +6000,7 @@ Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
SourceLocation StartLoc,
SourceLocation EndLoc) {
bool seenMotionClause = false;
for (auto *C : Clauses) {
if (C->getClauseKind() == OMPC_to || C->getClauseKind() == OMPC_from)
seenMotionClause = true;
}
if (!seenMotionClause) {
if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
return StmtError();
}

View File

@ -4,7 +4,7 @@ void foo() { }
int main(int argc, char **argv) {
int a;
#pragma omp target data // expected-error {{expected at least one map clause for '#pragma omp target data'}}
#pragma omp target data // expected-error {{expected at least one 'map' or 'use_device_ptr' clause for '#pragma omp target data'}}
{}
L1:
foo();

View File

@ -4,7 +4,7 @@
int main(int argc, char **argv) {
int r;
#pragma omp target enter data // expected-error {{expected at least one map clause for '#pragma omp target enter data'}}
#pragma omp target enter data // expected-error {{expected at least one 'map' clause for '#pragma omp target enter data'}}
#pragma omp target enter data map(r) // expected-error {{map type must be specified for '#pragma omp target enter data'}}
#pragma omp target enter data map(tofrom: r) // expected-error {{map type 'tofrom' is not allowed for '#pragma omp target enter data'}}

View File

@ -6,7 +6,7 @@ int main(int argc, char **argv) {
#pragma omp nowait target enter data map(to: i) // expected-error {{expected an OpenMP directive}}
#pragma omp target nowait enter data map(to: i) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}}
#pragma omp target enter nowait data map(to: i) // expected-error {{expected an OpenMP directive}}
#pragma omp target enter data nowait() map(to: i) // expected-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}} expected-error {{expected at least one map clause for '#pragma omp target enter data'}}
#pragma omp target enter data nowait() map(to: i) // expected-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}} expected-error {{expected at least one 'map' clause for '#pragma omp target enter data'}}
#pragma omp target enter data map(to: i) nowait( // expected-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}}
#pragma omp target enter data map(to: i) nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}}
#pragma omp target enter data map(to: i) nowait device (-10u)

View File

@ -4,7 +4,7 @@
int main(int argc, char **argv) {
int r;
#pragma omp target exit data // expected-error {{expected at least one map clause for '#pragma omp target exit data'}}
#pragma omp target exit data // expected-error {{expected at least one 'map' clause for '#pragma omp target exit data'}}
#pragma omp target exit data map(r) // expected-error {{map type must be specified for '#pragma omp target exit data'}}
#pragma omp target exit data map(tofrom: r) // expected-error {{map type 'tofrom' is not allowed for '#pragma omp target exit data'}}

View File

@ -6,7 +6,7 @@ int main(int argc, char **argv) {
#pragma omp nowait target exit data map(from: i) // expected-error {{expected an OpenMP directive}}
#pragma omp target nowait exit data map(from: i) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}}
#pragma omp target exit nowait data map(from: i) // expected-error {{expected an OpenMP directive}}
#pragma omp target exit data nowait() map(from: i) // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}} expected-error {{expected at least one map clause for '#pragma omp target exit data'}}
#pragma omp target exit data nowait() map(from: i) // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}} expected-error {{expected at least one 'map' clause for '#pragma omp target exit data'}}
#pragma omp target exit data map(from: i) nowait( // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}}
#pragma omp target exit data map(from: i) nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}}
#pragma omp target exit data map(from: i) nowait device (-10u)

View File

@ -467,7 +467,7 @@ int main(int argc, char **argv) {
int y;
int to, tofrom, always;
const int (&l)[5] = da;
#pragma omp target data map // expected-error {{expected '(' after 'map'}} expected-error {{expected at least one map clause for '#pragma omp target data'}}
#pragma omp target data map // expected-error {{expected '(' after 'map'}} expected-error {{expected at least one 'map' or 'use_device_ptr' clause for '#pragma omp target data'}}
#pragma omp target data map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
#pragma omp target data map() // expected-error {{expected expression}}
#pragma omp target data map(alloc) // expected-error {{use of undeclared identifier 'alloc'}}

View File

@ -464,7 +464,7 @@ int main(int argc, char **argv) {
int y;
int to, tofrom, always;
const int (&l)[5] = da;
#pragma omp target data map // expected-error {{expected '(' after 'map'}} expected-error {{expected at least one map clause for '#pragma omp target data'}}
#pragma omp target data map // expected-error {{expected '(' after 'map'}} expected-error {{expected at least one 'map' or 'use_device_ptr' clause for '#pragma omp target data'}}
#pragma omp target data map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
#pragma omp target data map() // expected-error {{expected expression}}
#pragma omp target data map(alloc) // expected-error {{use of undeclared identifier 'alloc'}}