Index: lib/Parse/ParseOpenMP.cpp =================================================================== --- lib/Parse/ParseOpenMP.cpp +++ lib/Parse/ParseOpenMP.cpp @@ -1690,6 +1690,30 @@ Data.MapType = OMPC_MAP_tofrom; Data.IsMapTypeImplicit = true; } + } else if (IsMapClauseModifierToken(PP.LookAhead(0))) { + if (PP.LookAhead(1).is(tok::colon)) { + Data.MapTypeModifier = Data.MapType; + if (Data.MapTypeModifier != OMPC_MAP_always) { + Diag(Tok, diag::err_omp_unknown_map_type_modifier); + Data.MapTypeModifier = OMPC_MAP_unknown; + } else + MapTypeModifierSpecified = true; + + ConsumeToken(); + + Data.MapType = + IsMapClauseModifierToken(Tok) + ? static_cast( + getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))) + : OMPC_MAP_unknown; + if (Data.MapType == OMPC_MAP_unknown || + Data.MapType == OMPC_MAP_always) + Diag(Tok, diag::err_omp_unknown_map_type); + ConsumeToken(); + } else { + Data.MapType = OMPC_MAP_tofrom; + Data.IsMapTypeImplicit = true; + } } else { Data.MapType = OMPC_MAP_tofrom; Data.IsMapTypeImplicit = true; Index: test/OpenMP/target_ast_print.cpp =================================================================== --- test/OpenMP/target_ast_print.cpp +++ test/OpenMP/target_ast_print.cpp @@ -10,7 +10,7 @@ template T tmain(T argc, T *argv) { - T i, j, a[20]; + T i, j, a[20], always; #pragma omp target foo(); #pragma omp target if (target:argc > 0) @@ -25,6 +25,12 @@ foo(); #pragma omp target map(always,alloc: i) foo(); +#pragma omp target map(always from: i) + foo(); +#pragma omp target map(always) + {always++;} +#pragma omp target map(always,i) + {always++;i++;} #pragma omp target nowait foo(); #pragma omp target depend(in : argc, argv[i:argc], a[:]) @@ -50,6 +56,17 @@ // CHECK-NEXT: foo() // CHECK-NEXT: #pragma omp target map(always,alloc: i) // CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target map(always,from: i) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target map(tofrom: always) +// CHECK-NEXT: { +// CHECK-NEXT: always++; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target map(tofrom: always,i) +// CHECK-NEXT: { +// CHECK-NEXT: always++; +// CHECK-NEXT: i++; +// CHECK-NEXT: } // CHECK-NEXT: #pragma omp target nowait // CHECK-NEXT: foo() // CHECK-NEXT: #pragma omp target depend(in : argc,argv[i:argc],a[:]) @@ -72,6 +89,17 @@ // CHECK-NEXT: foo() // CHECK-NEXT: #pragma omp target map(always,alloc: i) // CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target map(always,from: i) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target map(tofrom: always) +// CHECK-NEXT: { +// CHECK-NEXT: always++; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target map(tofrom: always,i) +// CHECK-NEXT: { +// CHECK-NEXT: always++; +// CHECK-NEXT: i++; +// CHECK-NEXT: } // CHECK-NEXT: #pragma omp target nowait // CHECK-NEXT: foo() // CHECK-NEXT: #pragma omp target depend(in : argc,argv[i:argc],a[:]) @@ -94,6 +122,17 @@ // CHECK-NEXT: foo() // CHECK-NEXT: #pragma omp target map(always,alloc: i) // CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target map(always,from: i) +// CHECK-NEXT: foo() +// CHECK-NEXT: #pragma omp target map(tofrom: always) +// CHECK-NEXT: { +// CHECK-NEXT: always++; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp target map(tofrom: always,i) +// CHECK-NEXT: { +// CHECK-NEXT: always++; +// CHECK-NEXT: i++; +// CHECK-NEXT: } // CHECK-NEXT: #pragma omp target nowait // CHECK-NEXT: foo() // CHECK-NEXT: #pragma omp target depend(in : argc,argv[i:argc],a[:]) @@ -103,7 +142,7 @@ // CHECK-LABEL: int main(int argc, char **argv) { int main (int argc, char **argv) { - int i, j, a[20]; + int i, j, a[20], always; // CHECK-NEXT: int i, j, a[20] #pragma omp target // CHECK-NEXT: #pragma omp target @@ -139,6 +178,26 @@ foo(); // CHECK-NEXT: foo(); +#pragma omp target map(always from: i) +// CHECK-NEXT: #pragma omp target map(always,from: i) + foo(); +// CHECK-NEXT: foo(); + +#pragma omp target map(always) +// CHECK-NEXT: #pragma omp target map(tofrom: always) + {always++;} +// CHECK-NEXT: { +// CHECK-NEXT: always++; +// CHECK-NEXT: } + +#pragma omp target map(always,i) +// CHECK-NEXT: #pragma omp target map(tofrom: always,i) + {always++;i++;} +// CHECK-NEXT: { +// CHECK-NEXT: always++; +// CHECK-NEXT: i++; +// CHECK-NEXT: } + #pragma omp target nowait // CHECK-NEXT: #pragma omp target nowait foo(); Index: test/OpenMP/target_map_messages.cpp =================================================================== --- test/OpenMP/target_map_messages.cpp +++ test/OpenMP/target_map_messages.cpp @@ -66,6 +66,8 @@ {} #pragma omp target map(always, tofrom: c,f[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} {} + #pragma omp target map(always) // expected-error {{use of undeclared identifier 'always'}} + {} return; } };