summaryrefslogtreecommitdiff
path: root/test/OpenMP
diff options
context:
space:
mode:
Diffstat (limited to 'test/OpenMP')
-rw-r--r--test/OpenMP/critical_codegen.cpp6
-rw-r--r--test/OpenMP/declare_reduction_ast_print.c42
-rw-r--r--test/OpenMP/declare_reduction_ast_print.cpp69
-rw-r--r--test/OpenMP/declare_reduction_codegen.c158
-rw-r--r--test/OpenMP/declare_reduction_codegen.cpp182
-rw-r--r--test/OpenMP/declare_reduction_messages.c52
-rw-r--r--test/OpenMP/declare_reduction_messages.cpp124
-rw-r--r--test/OpenMP/declare_simd_ast_print.c21
-rw-r--r--test/OpenMP/declare_simd_ast_print.cpp146
-rw-r--r--test/OpenMP/declare_simd_codegen.cpp288
-rw-r--r--test/OpenMP/declare_simd_messages.cpp231
-rw-r--r--test/OpenMP/declare_target_ast_print.cpp138
-rw-r--r--test/OpenMP/declare_target_messages.cpp101
-rw-r--r--test/OpenMP/distribute_ast_print.cpp69
-rw-r--r--test/OpenMP/distribute_codegen.cpp263
-rw-r--r--test/OpenMP/distribute_dist_schedule_ast_print.cpp106
-rw-r--r--test/OpenMP/distribute_dist_schedule_messages.cpp63
-rw-r--r--test/OpenMP/distribute_parallel_for_ast_print.cpp139
-rw-r--r--test/OpenMP/distribute_parallel_for_collapse_messages.cpp154
-rw-r--r--test/OpenMP/distribute_parallel_for_copyin_messages.cpp190
-rw-r--r--test/OpenMP/distribute_parallel_for_default_messages.cpp100
-rw-r--r--test/OpenMP/distribute_parallel_for_dist_schedule_messages.cpp103
-rw-r--r--test/OpenMP/distribute_parallel_for_firstprivate_messages.cpp359
-rw-r--r--test/OpenMP/distribute_parallel_for_if_messages.cpp179
-rw-r--r--test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp333
-rw-r--r--test/OpenMP/distribute_parallel_for_num_threads_messages.cpp107
-rw-r--r--test/OpenMP/distribute_parallel_for_private_messages.cpp315
-rw-r--r--test/OpenMP/distribute_parallel_for_proc_bind_messages.cpp101
-rw-r--r--test/OpenMP/distribute_parallel_for_reduction_messages.cpp441
-rw-r--r--test/OpenMP/distribute_parallel_for_schedule_messages.cpp151
-rw-r--r--test/OpenMP/distribute_parallel_for_shared_messages.cpp396
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_aligned_messages.cpp306
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_ast_print.cpp152
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_collapse_messages.cpp154
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_copyin_messages.cpp190
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_default_messages.cpp100
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_dist_schedule_messages.cpp103
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_firstprivate_messages.cpp359
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_if_messages.cpp179
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_lastprivate_messages.cpp333
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp338
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp816
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_misc_messages.c971
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_num_threads_messages.cpp107
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_private_messages.cpp315
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_proc_bind_messages.cpp101
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp441
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_safelen_messages.cpp177
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_schedule_messages.cpp151
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_shared_messages.cpp396
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_simdlen_messages.cpp181
-rw-r--r--test/OpenMP/distribute_private_messages.cpp17
-rw-r--r--test/OpenMP/distribute_simd_aligned_messages.cpp306
-rw-r--r--test/OpenMP/distribute_simd_ast_print.cpp146
-rw-r--r--test/OpenMP/distribute_simd_collapse_messages.cpp154
-rw-r--r--test/OpenMP/distribute_simd_dist_schedule_messages.cpp120
-rw-r--r--test/OpenMP/distribute_simd_firstprivate_messages.cpp359
-rw-r--r--test/OpenMP/distribute_simd_lastprivate_messages.cpp333
-rw-r--r--test/OpenMP/distribute_simd_linear_messages.cpp338
-rw-r--r--test/OpenMP/distribute_simd_loop_messages.cpp782
-rw-r--r--test/OpenMP/distribute_simd_misc_messages.c1108
-rw-r--r--test/OpenMP/distribute_simd_private_messages.cpp315
-rw-r--r--test/OpenMP/distribute_simd_reduction_messages.cpp441
-rw-r--r--test/OpenMP/distribute_simd_safelen_messages.cpp177
-rw-r--r--test/OpenMP/distribute_simd_simdlen_messages.cpp177
-rw-r--r--test/OpenMP/driver.c19
-rw-r--r--test/OpenMP/dump.cpp68
-rw-r--r--test/OpenMP/for_ast_print.cpp88
-rw-r--r--test/OpenMP/for_codegen.cpp32
-rw-r--r--test/OpenMP/for_collapse_messages.cpp37
-rw-r--r--test/OpenMP/for_firstprivate_codegen.cpp31
-rw-r--r--test/OpenMP/for_firstprivate_messages.cpp2
-rw-r--r--test/OpenMP/for_lastprivate_codegen.cpp275
-rw-r--r--test/OpenMP/for_linear_codegen.cpp231
-rw-r--r--test/OpenMP/for_linear_messages.cpp2
-rw-r--r--test/OpenMP/for_loop_messages.cpp23
-rw-r--r--test/OpenMP/for_ordered_clause.cpp37
-rw-r--r--test/OpenMP/for_private_messages.cpp56
-rw-r--r--test/OpenMP/for_reduction_codegen.cpp340
-rw-r--r--test/OpenMP/for_reduction_codegen_UDR.cpp984
-rw-r--r--test/OpenMP/for_reduction_messages.cpp32
-rw-r--r--test/OpenMP/for_simd_aligned_messages.cpp1
-rw-r--r--test/OpenMP/for_simd_ast_print.cpp51
-rw-r--r--test/OpenMP/for_simd_codegen.cpp17
-rw-r--r--test/OpenMP/for_simd_collapse_messages.cpp37
-rw-r--r--test/OpenMP/for_simd_firstprivate_messages.cpp2
-rw-r--r--test/OpenMP/for_simd_linear_messages.cpp2
-rw-r--r--test/OpenMP/for_simd_loop_messages.cpp6
-rw-r--r--test/OpenMP/for_simd_private_messages.cpp56
-rw-r--r--test/OpenMP/for_simd_reduction_messages.cpp32
-rw-r--r--test/OpenMP/for_simd_safelen_messages.cpp37
-rw-r--r--test/OpenMP/for_simd_simdlen_messages.cpp37
-rw-r--r--test/OpenMP/loops_explicit_clauses_codegen.cpp162
-rw-r--r--test/OpenMP/nesting_of_regions.cpp3695
-rw-r--r--test/OpenMP/nvptx_target_codegen.cpp581
-rw-r--r--test/OpenMP/nvptx_target_firstprivate_codegen.cpp223
-rw-r--r--test/OpenMP/nvptx_teams_codegen.cpp132
-rw-r--r--test/OpenMP/ordered_doacross_codegen.cpp124
-rw-r--r--test/OpenMP/parallel_ast_print.cpp110
-rw-r--r--test/OpenMP/parallel_copyin_codegen.cpp16
-rw-r--r--test/OpenMP/parallel_firstprivate_codegen.cpp306
-rw-r--r--test/OpenMP/parallel_for_ast_print.cpp51
-rw-r--r--test/OpenMP/parallel_for_collapse_messages.cpp37
-rw-r--r--test/OpenMP/parallel_for_linear_messages.cpp2
-rw-r--r--test/OpenMP/parallel_for_loop_messages.cpp6
-rw-r--r--test/OpenMP/parallel_for_ordered_messages.cpp37
-rw-r--r--test/OpenMP/parallel_for_private_messages.cpp56
-rw-r--r--test/OpenMP/parallel_for_reduction_messages.cpp38
-rw-r--r--test/OpenMP/parallel_for_simd_aligned_messages.cpp1
-rw-r--r--test/OpenMP/parallel_for_simd_ast_print.cpp52
-rw-r--r--test/OpenMP/parallel_for_simd_collapse_messages.cpp37
-rw-r--r--test/OpenMP/parallel_for_simd_linear_messages.cpp2
-rw-r--r--test/OpenMP/parallel_for_simd_loop_messages.cpp6
-rw-r--r--test/OpenMP/parallel_for_simd_private_messages.cpp56
-rw-r--r--test/OpenMP/parallel_for_simd_reduction_messages.cpp32
-rw-r--r--test/OpenMP/parallel_for_simd_safelen_messages.cpp37
-rw-r--r--test/OpenMP/parallel_for_simd_simdlen_messages.cpp37
-rw-r--r--test/OpenMP/parallel_num_threads_codegen.cpp4
-rw-r--r--test/OpenMP/parallel_private_codegen.cpp163
-rw-r--r--test/OpenMP/parallel_reduction_codegen.cpp184
-rw-r--r--test/OpenMP/parallel_reduction_messages.cpp38
-rw-r--r--test/OpenMP/parallel_sections_ast_print.cpp3
-rw-r--r--test/OpenMP/parallel_sections_private_messages.cpp68
-rw-r--r--test/OpenMP/parallel_sections_reduction_messages.cpp38
-rw-r--r--test/OpenMP/predefined_macro.c2
-rw-r--r--test/OpenMP/sections_firstprivate_codegen.cpp25
-rw-r--r--test/OpenMP/sections_private_messages.cpp68
-rw-r--r--test/OpenMP/sections_reduction_messages.cpp32
-rw-r--r--test/OpenMP/simd_aligned_messages.cpp1
-rw-r--r--test/OpenMP/simd_ast_print.cpp52
-rw-r--r--test/OpenMP/simd_codegen.cpp91
-rw-r--r--test/OpenMP/simd_collapse_messages.cpp37
-rw-r--r--test/OpenMP/simd_lastprivate_messages.cpp2
-rw-r--r--test/OpenMP/simd_private_messages.cpp56
-rw-r--r--test/OpenMP/simd_reduction_messages.cpp32
-rw-r--r--test/OpenMP/simd_safelen_messages.cpp37
-rw-r--r--test/OpenMP/simd_simdlen_messages.cpp37
-rw-r--r--test/OpenMP/single_ast_print.cpp33
-rw-r--r--test/OpenMP/single_codegen.cpp252
-rw-r--r--test/OpenMP/single_firstprivate_codegen.cpp17
-rw-r--r--test/OpenMP/single_private_messages.cpp56
-rw-r--r--test/OpenMP/target_ast_print.cpp39
-rw-r--r--test/OpenMP/target_codegen.cpp40
-rw-r--r--test/OpenMP/target_codegen_global_capture.cpp187
-rw-r--r--test/OpenMP/target_codegen_registration.cpp104
-rw-r--r--test/OpenMP/target_codegen_registration_naming.cpp48
-rw-r--r--test/OpenMP/target_data_ast_print.cpp36
-rw-r--r--test/OpenMP/target_data_codegen.cpp248
-rw-r--r--test/OpenMP/target_data_device_messages.cpp25
-rw-r--r--test/OpenMP/target_data_if_messages.cpp33
-rw-r--r--test/OpenMP/target_data_messages.c9
-rw-r--r--test/OpenMP/target_data_use_device_ptr_ast_print.cpp154
-rw-r--r--test/OpenMP/target_data_use_device_ptr_messages.cpp206
-rw-r--r--test/OpenMP/target_defaultmap_messages.cpp56
-rw-r--r--test/OpenMP/target_depend_messages.cpp89
-rw-r--r--test/OpenMP/target_device_messages.cpp13
-rw-r--r--test/OpenMP/target_enter_data_ast_print.cpp228
-rw-r--r--test/OpenMP/target_enter_data_codegen.cpp249
-rw-r--r--test/OpenMP/target_enter_data_depend_messages.cpp166
-rw-r--r--test/OpenMP/target_enter_data_device_messages.cpp29
-rw-r--r--test/OpenMP/target_enter_data_if_messages.cpp35
-rw-r--r--test/OpenMP/target_enter_data_map_messages.c19
-rw-r--r--test/OpenMP/target_enter_data_nowait_messages.cpp17
-rw-r--r--test/OpenMP/target_exit_data_ast_print.cpp244
-rw-r--r--test/OpenMP/target_exit_data_codegen.cpp221
-rw-r--r--test/OpenMP/target_exit_data_depend_messages.cpp166
-rw-r--r--test/OpenMP/target_exit_data_device_messages.cpp29
-rw-r--r--test/OpenMP/target_exit_data_if_messages.cpp35
-rw-r--r--test/OpenMP/target_exit_data_map_messages.c19
-rw-r--r--test/OpenMP/target_exit_data_nowait_messages.cpp17
-rw-r--r--test/OpenMP/target_firstprivate_codegen.cpp580
-rw-r--r--test/OpenMP/target_firstprivate_messages.cpp198
-rw-r--r--test/OpenMP/target_if_messages.cpp33
-rw-r--r--test/OpenMP/target_is_device_ptr_ast_print.cpp294
-rw-r--r--test/OpenMP/target_is_device_ptr_messages.cpp234
-rw-r--r--test/OpenMP/target_map_codegen.cpp3771
-rw-r--r--test/OpenMP/target_map_messages.cpp444
-rw-r--r--test/OpenMP/target_messages.cpp6
-rw-r--r--test/OpenMP/target_nowait_messages.cpp17
-rw-r--r--test/OpenMP/target_parallel_ast_print.cpp233
-rw-r--r--test/OpenMP/target_parallel_default_messages.cpp27
-rw-r--r--test/OpenMP/target_parallel_defaultmap_messages.cpp56
-rw-r--r--test/OpenMP/target_parallel_depend_messages.cpp89
-rw-r--r--test/OpenMP/target_parallel_device_messages.cpp39
-rw-r--r--test/OpenMP/target_parallel_firstprivate_messages.cpp112
-rw-r--r--test/OpenMP/target_parallel_for_ast_print.cpp252
-rw-r--r--test/OpenMP/target_parallel_for_collapse_messages.cpp83
-rw-r--r--test/OpenMP/target_parallel_for_default_messages.cpp36
-rw-r--r--test/OpenMP/target_parallel_for_defaultmap_messages.cpp58
-rw-r--r--test/OpenMP/target_parallel_for_depend_messages.cpp90
-rw-r--r--test/OpenMP/target_parallel_for_device_messages.cpp40
-rw-r--r--test/OpenMP/target_parallel_for_firstprivate_messages.cpp261
-rw-r--r--test/OpenMP/target_parallel_for_if_messages.cpp105
-rw-r--r--test/OpenMP/target_parallel_for_lastprivate_messages.cpp238
-rw-r--r--test/OpenMP/target_parallel_for_linear_messages.cpp269
-rw-r--r--test/OpenMP/target_parallel_for_loop_messages.cpp627
-rw-r--r--test/OpenMP/target_parallel_for_map_messages.cpp273
-rw-r--r--test/OpenMP/target_parallel_for_messages.cpp92
-rw-r--r--test/OpenMP/target_parallel_for_misc_messages.c314
-rw-r--r--test/OpenMP/target_parallel_for_nowait_messages.cpp18
-rw-r--r--test/OpenMP/target_parallel_for_num_threads_messages.cpp65
-rw-r--r--test/OpenMP/target_parallel_for_ordered_messages.cpp104
-rw-r--r--test/OpenMP/target_parallel_for_private_messages.cpp231
-rw-r--r--test/OpenMP/target_parallel_for_proc_bind_messages.cpp35
-rw-r--r--test/OpenMP/target_parallel_for_reduction_messages.cpp313
-rw-r--r--test/OpenMP/target_parallel_for_schedule_messages.cpp91
-rw-r--r--test/OpenMP/target_parallel_for_simd_aligned_messages.cpp203
-rw-r--r--test/OpenMP/target_parallel_for_simd_ast_print.cpp308
-rw-r--r--test/OpenMP/target_parallel_for_simd_collapse_messages.cpp101
-rw-r--r--test/OpenMP/target_parallel_for_simd_default_messages.cpp36
-rw-r--r--test/OpenMP/target_parallel_for_simd_defaultmap_messages.cpp58
-rw-r--r--test/OpenMP/target_parallel_for_simd_depend_messages.cpp90
-rw-r--r--test/OpenMP/target_parallel_for_simd_device_messages.cpp40
-rw-r--r--test/OpenMP/target_parallel_for_simd_firstprivate_messages.cpp261
-rw-r--r--test/OpenMP/target_parallel_for_simd_if_messages.cpp105
-rw-r--r--test/OpenMP/target_parallel_for_simd_lastprivate_messages.cpp238
-rw-r--r--test/OpenMP/target_parallel_for_simd_linear_messages.cpp269
-rw-r--r--test/OpenMP/target_parallel_for_simd_loop_messages.cpp627
-rw-r--r--test/OpenMP/target_parallel_for_simd_map_messages.cpp273
-rw-r--r--test/OpenMP/target_parallel_for_simd_messages.cpp92
-rw-r--r--test/OpenMP/target_parallel_for_simd_misc_messages.c495
-rw-r--r--test/OpenMP/target_parallel_for_simd_nowait_messages.cpp18
-rw-r--r--test/OpenMP/target_parallel_for_simd_num_threads_messages.cpp65
-rw-r--r--test/OpenMP/target_parallel_for_simd_ordered_messages.cpp122
-rw-r--r--test/OpenMP/target_parallel_for_simd_private_messages.cpp231
-rw-r--r--test/OpenMP/target_parallel_for_simd_proc_bind_messages.cpp35
-rw-r--r--test/OpenMP/target_parallel_for_simd_reduction_messages.cpp313
-rw-r--r--test/OpenMP/target_parallel_for_simd_safelen_messages.cpp102
-rw-r--r--test/OpenMP/target_parallel_for_simd_schedule_messages.cpp91
-rw-r--r--test/OpenMP/target_parallel_for_simd_simdlen_messages.cpp142
-rw-r--r--test/OpenMP/target_parallel_if_messages.cpp103
-rw-r--r--test/OpenMP/target_parallel_map_messages.cpp272
-rw-r--r--test/OpenMP/target_parallel_messages.cpp73
-rw-r--r--test/OpenMP/target_parallel_nowait_messages.cpp17
-rw-r--r--test/OpenMP/target_parallel_num_threads_messages.cpp69
-rw-r--r--test/OpenMP/target_parallel_private_messages.cpp222
-rw-r--r--test/OpenMP/target_parallel_proc_bind_messages.cpp27
-rw-r--r--test/OpenMP/target_parallel_reduction_messages.cpp263
-rw-r--r--test/OpenMP/target_parallel_shared_messages.cpp110
-rw-r--r--test/OpenMP/target_private_codegen.cpp264
-rw-r--r--test/OpenMP/target_private_messages.cpp198
-rw-r--r--test/OpenMP/target_update_ast_print.cpp52
-rw-r--r--test/OpenMP/target_update_codegen.cpp245
-rw-r--r--test/OpenMP/target_update_depend_messages.cpp112
-rw-r--r--test/OpenMP/target_update_device_messages.cpp43
-rw-r--r--test/OpenMP/target_update_from_messages.cpp176
-rw-r--r--test/OpenMP/target_update_if_messages.cpp58
-rw-r--r--test/OpenMP/target_update_messages.cpp32
-rw-r--r--test/OpenMP/target_update_nowait_messages.cpp17
-rw-r--r--test/OpenMP/target_update_to_messages.cpp175
-rw-r--r--test/OpenMP/task_ast_print.cpp54
-rw-r--r--test/OpenMP/task_codegen.cpp95
-rw-r--r--test/OpenMP/task_firstprivate_codegen.cpp62
-rw-r--r--test/OpenMP/task_firstprivate_messages.cpp11
-rw-r--r--test/OpenMP/task_if_codegen.cpp20
-rw-r--r--test/OpenMP/task_messages.cpp10
-rw-r--r--test/OpenMP/task_private_codegen.cpp29
-rw-r--r--test/OpenMP/taskgroup_codegen.cpp1
-rw-r--r--test/OpenMP/taskloop_codegen.cpp192
-rw-r--r--test/OpenMP/taskloop_collapse_messages.cpp37
-rw-r--r--test/OpenMP/taskloop_firstprivate_codegen.cpp511
-rw-r--r--test/OpenMP/taskloop_firstprivate_messages.cpp6
-rw-r--r--test/OpenMP/taskloop_lastprivate_codegen.cpp519
-rw-r--r--test/OpenMP/taskloop_loop_messages.cpp6
-rw-r--r--test/OpenMP/taskloop_private_codegen.cpp420
-rw-r--r--test/OpenMP/taskloop_private_messages.cpp56
-rw-r--r--test/OpenMP/taskloop_simd_aligned_messages.cpp1
-rw-r--r--test/OpenMP/taskloop_simd_codegen.cpp203
-rw-r--r--test/OpenMP/taskloop_simd_collapse_messages.cpp37
-rw-r--r--test/OpenMP/taskloop_simd_firstprivate_codegen.cpp511
-rw-r--r--test/OpenMP/taskloop_simd_firstprivate_messages.cpp6
-rw-r--r--test/OpenMP/taskloop_simd_lastprivate_codegen.cpp519
-rw-r--r--test/OpenMP/taskloop_simd_loop_messages.cpp6
-rw-r--r--test/OpenMP/taskloop_simd_private_codegen.cpp420
-rw-r--r--test/OpenMP/taskloop_simd_private_messages.cpp56
-rw-r--r--test/OpenMP/taskloop_simd_safelen_messages.cpp37
-rw-r--r--test/OpenMP/taskloop_simd_simdlen_messages.cpp37
-rw-r--r--test/OpenMP/teams_ast_print.cpp2
-rw-r--r--test/OpenMP/teams_codegen.cpp353
-rw-r--r--test/OpenMP/teams_firstprivate_codegen.cpp283
-rw-r--r--test/OpenMP/teams_private_codegen.cpp298
-rw-r--r--test/OpenMP/teams_reduction_messages.cpp36
-rw-r--r--test/OpenMP/threadprivate_ast_print.cpp1
-rw-r--r--test/OpenMP/threadprivate_codegen.cpp16
-rw-r--r--test/OpenMP/threadprivate_messages.cpp2
285 files changed, 48693 insertions, 961 deletions
diff --git a/test/OpenMP/critical_codegen.cpp b/test/OpenMP/critical_codegen.cpp
index e44e2202e9a2e..be749a65f0cb7 100644
--- a/test/OpenMP/critical_codegen.cpp
+++ b/test/OpenMP/critical_codegen.cpp
@@ -39,7 +39,11 @@ int main() {
#pragma omp critical(the_name1) hint(23)
foo();
// CHECK: call {{.*}}void @__kmpc_critical([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[THE_NAME_LOCK]])
+// CHECK: br label
// CHECK-NOT: call {{.*}}void @__kmpc_end_critical(
+// CHECK: br label
+// CHECK-NOT: call {{.*}}void @__kmpc_end_critical(
+// CHECK: br label
if (a)
#pragma omp critical(the_name)
while (1)
@@ -60,6 +64,8 @@ void critical_ref(S &s) {
// CHECK: [[S_REF:%.+]] = load %struct.S*, %struct.S** [[S_ADDR]],
// CHECK: [[S_A_REF:%.+]] = getelementptr inbounds %struct.S, %struct.S* [[S_REF]], i32 0, i32 0
++s.a;
+ // CHECK: [[S_REF:%.+]] = load %struct.S*, %struct.S** [[S_ADDR]],
+ // CHECK: store %struct.S* [[S_REF]], %struct.S** [[S_ADDR:%.+]],
// CHECK: call void @__kmpc_critical(
#pragma omp critical
// CHECK: [[S_REF:%.+]] = load %struct.S*, %struct.S** [[S_ADDR]],
diff --git a/test/OpenMP/declare_reduction_ast_print.c b/test/OpenMP/declare_reduction_ast_print.c
new file mode 100644
index 0000000000000..7b97a7c1da7c3
--- /dev/null
+++ b/test/OpenMP/declare_reduction_ast_print.c
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+#pragma omp declare reduction(+ : int, char : omp_out *= omp_in)
+// CHECK: #pragma omp declare reduction (+ : int : omp_out *= omp_in)
+// CHECK-NEXT: #pragma omp declare reduction (+ : char : omp_out *= omp_in)
+
+#pragma omp declare reduction(fun : float : omp_out += omp_in) initializer(omp_priv = omp_orig + 15)
+// CHECK: #pragma omp declare reduction (fun : float : omp_out += omp_in) initializer(omp_priv = omp_orig + 15)
+
+// CHECK: struct SSS {
+struct SSS {
+ int field;
+#pragma omp declare reduction(+ : int, char : omp_out *= omp_in)
+ // CHECK: #pragma omp declare reduction (+ : int : omp_out *= omp_in)
+ // CHECK-NEXT: #pragma omp declare reduction (+ : char : omp_out *= omp_in)
+};
+// CHECK: };
+
+void init(struct SSS *priv, struct SSS orig);
+
+#pragma omp declare reduction(fun : struct SSS : omp_out = omp_in) initializer(init(&omp_priv, omp_orig))
+// CHECK: #pragma omp declare reduction (fun : struct SSS : omp_out = omp_in) initializer(init(&omp_priv, omp_orig))
+
+// CHECK: int main() {
+int main() {
+#pragma omp declare reduction(fun : struct SSS : omp_out = omp_in) initializer(init(&omp_priv, omp_orig))
+ // CHECK: #pragma omp declare reduction (fun : struct SSS : omp_out = omp_in) initializer(init(&omp_priv, omp_orig))
+ {
+#pragma omp declare reduction(fun : struct SSS : omp_out = omp_in) initializer(init(&omp_priv, omp_orig))
+ // CHECK: #pragma omp declare reduction (fun : struct SSS : omp_out = omp_in) initializer(init(&omp_priv, omp_orig))
+ }
+ return 0;
+}
+// CHECK: }
+
+#endif
diff --git a/test/OpenMP/declare_reduction_ast_print.cpp b/test/OpenMP/declare_reduction_ast_print.cpp
new file mode 100644
index 0000000000000..26b2ff96ac022
--- /dev/null
+++ b/test/OpenMP/declare_reduction_ast_print.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+#pragma omp declare reduction(+ : int, char : omp_out *= omp_in)
+// CHECK: #pragma omp declare reduction (+ : int : omp_out *= omp_in)
+// CHECK-NEXT: #pragma omp declare reduction (+ : char : omp_out *= omp_in)
+
+// CHECK: #pragma omp declare reduction (fun : int : omp_out += omp_in) initializer(omp_priv = omp_orig + 15)
+
+template <class T>
+class SSS {
+public:
+#pragma omp declare reduction(fun : T : omp_out += omp_in) initializer(omp_priv = omp_orig + 15)
+ // CHECK: #pragma omp declare reduction (fun : T : omp_out += omp_in) initializer(omp_priv = omp_orig + 15)
+};
+
+SSS<int> d;
+
+void init(SSS<int> &lhs, SSS<int> rhs);
+
+#pragma omp declare reduction(fun : SSS < int > : omp_out = omp_in) initializer(init(omp_priv, omp_orig))
+// CHECK: #pragma omp declare reduction (fun : SSS<int> : omp_out = omp_in) initializer(init(omp_priv, omp_orig))
+
+// CHECK: template <typename T = int> int foo(int a) {
+// CHECK: #pragma omp declare reduction (fun : int : omp_out += omp_in) initializer(omp_priv = omp_orig + 15);
+// CHECK: {
+// CHECK: #pragma omp declare reduction (fun : int : omp_out += omp_in) initializer(omp_priv = omp_orig + 15);
+// CHECK: }
+// CHECK: return a;
+// CHECK: }
+
+// CHECK: template <typename T> T foo(T a) {
+// CHECK: #pragma omp declare reduction (fun : T : omp_out += omp_in) initializer(omp_priv = omp_orig + 15);
+// CHECK: {
+// CHECK: #pragma omp declare reduction (fun : T : omp_out += omp_in) initializer(omp_priv = omp_orig + 15);
+// CHECK: }
+// CHECK: return a;
+// CHECK: }
+template <typename T>
+T foo(T a) {
+#pragma omp declare reduction(fun : T : omp_out += omp_in) initializer(omp_priv = omp_orig + 15)
+ {
+#pragma omp declare reduction(fun : T : omp_out += omp_in) initializer(omp_priv = omp_orig + 15)
+ }
+ return a;
+}
+
+int main() {
+ int i = 0;
+ SSS<int> sss;
+ // TODO: Add support for scoped reduction identifiers
+ // #pragma omp parallel reduction(SSS<int>::fun : i)
+ // TODO-CHECK: #pragma omp parallel reduction(SSS<int>::fun: i)
+ {
+ i += 1;
+ }
+ // #pragma omp parallel reduction(::fun:sss)
+ // TODO-CHECK: #pragma omp parallel reduction(::fun: sss)
+ {
+ }
+ return foo(15);
+}
+
+#endif
diff --git a/test/OpenMP/declare_reduction_codegen.c b/test/OpenMP/declare_reduction_codegen.c
new file mode 100644
index 0000000000000..ecb97269d4db5
--- /dev/null
+++ b/test/OpenMP/declare_reduction_codegen.c
@@ -0,0 +1,158 @@
+// RUN: %clang_cc1 -verify -fopenmp -x c -emit-llvm %s -triple %itanium_abi_triple -o - -femit-all-decls -disable-llvm-optzns | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c -triple %itanium_abi_triple -emit-pch -o %t %s -femit-all-decls -disable-llvm-optzns
+// RUN: %clang_cc1 -fopenmp -x c -triple %itanium_abi_triple -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-optzns | FileCheck --check-prefix=CHECK-LOAD %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+// CHECK: [[SSS_INT:.+]] = type { i32 }
+// CHECK-LOAD: [[SSS_INT:.+]] = type { i32 }
+
+#pragma omp declare reduction(+ : int, char : omp_out *= omp_in)
+// CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
+// CHECK: [[MUL:%.+]] = mul nsw i32
+// CHECK-NEXT: store i32 [[MUL]], i32*
+// CHECK-NEXT: ret void
+// CHECK-NEXT: }
+// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
+// CHECK-LOAD: [[MUL:%.+]] = mul nsw i32
+// CHECK-LOAD-NEXT: store i32 [[MUL]], i32*
+// CHECK-LOAD-NEXT: ret void
+// CHECK-LOAD-NEXT: }
+
+// CHECK: define internal {{.*}}void @{{[^(]+}}(i8* noalias, i8* noalias)
+// CHECK: sext i8
+// CHECK: sext i8
+// CHECK: [[MUL:%.+]] = mul nsw i32
+// CHECK-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i8
+// CHECK-NEXT: store i8 [[TRUNC]], i8*
+// CHECK-NEXT: ret void
+// CHECK-NEXT: }
+// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i8* noalias, i8* noalias)
+// CHECK-LOAD: sext i8
+// CHECK-LOAD: sext i8
+// CHECK-LOAD: [[MUL:%.+]] = mul nsw i32
+// CHECK-LOAD-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i8
+// CHECK-LOAD-NEXT: store i8 [[TRUNC]], i8*
+// CHECK-LOAD-NEXT: ret void
+// CHECK-LOAD-NEXT: }
+
+#pragma omp declare reduction(fun : float : omp_out += omp_in) initializer(omp_priv = 15 + omp_orig)
+// CHECK: define internal {{.*}}void @{{[^(]+}}(float* noalias, float* noalias)
+// CHECK: [[ADD:%.+]] = fadd float
+// CHECK-NEXT: store float [[ADD]], float*
+// CHECK-NEXT: ret void
+// CHECK-NEXT: }
+// CHECK: define internal {{.*}}void @{{[^(]+}}(float* noalias, float* noalias)
+// CHECK: [[ADD:%.+]] = fadd float 1.5
+// CHECK-NEXT: store float [[ADD]], float*
+// CHECK-NEXT: ret void
+// CHECK-NEXT: }
+// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(float* noalias, float* noalias)
+// CHECK-LOAD: [[ADD:%.+]] = fadd float
+// CHECK-LOAD-NEXT: store float [[ADD]], float*
+// CHECK-LOAD-NEXT: ret void
+// CHECK-LOAD-NEXT: }
+// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(float* noalias, float* noalias)
+// CHECK-LOAD: [[ADD:%.+]] = fadd float 1.5
+// CHECK-LOAD-NEXT: store float [[ADD]], float*
+// CHECK-LOAD-NEXT: ret void
+// CHECK-LOAD-NEXT: }
+
+struct SSS {
+ int field;
+#pragma omp declare reduction(+ : int, char : omp_out *= omp_in)
+ // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
+ // CHECK: [[MUL:%.+]] = mul nsw i32
+ // CHECK-NEXT: store i32 [[MUL]], i32*
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+
+ // CHECK: define internal {{.*}}void @{{[^(]+}}(i8* noalias, i8* noalias)
+ // CHECK: sext i8
+ // CHECK: sext i8
+ // CHECK: [[MUL:%.+]] = mul nsw i32
+ // CHECK-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i8
+ // CHECK-NEXT: store i8 [[TRUNC]], i8*
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+};
+
+void init(struct SSS *priv, struct SSS orig);
+
+#pragma omp declare reduction(fun : struct SSS : omp_out = omp_in) initializer(init(&omp_priv, omp_orig))
+// CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias)
+// CHECK: call void @llvm.memcpy
+// CHECK-NEXT: ret void
+// CHECK-NEXT: }
+// CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias)
+// CHECK: call void @init(
+// CHECK-NEXT: ret void
+// CHECK-NEXT: }
+// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias)
+// CHECK-LOAD: call void @llvm.memcpy
+// CHECK-LOAD-NEXT: ret void
+// CHECK-LOAD-NEXT: }
+// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias)
+// CHECK-LOAD: call void @init(
+// CHECK-LOAD-NEXT: ret void
+// CHECK-LOAD-NEXT: }
+
+// CHECK-LABEL: @main
+// CHECK-LOAD-LABEL: @main
+int main() {
+#pragma omp declare reduction(fun : struct SSS : omp_out = omp_in) initializer(init(&omp_priv, omp_orig))
+ // CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias)
+ // CHECK: call void @llvm.memcpy
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+ // CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias)
+ // CHECK: call void @init(
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+ // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias)
+ // CHECK-LOAD: call void @llvm.memcpy
+ // CHECK-LOAD-NEXT: ret void
+ // CHECK-LOAD-NEXT: }
+ // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias)
+ // CHECK-LOAD: call void @init(
+ // CHECK-LOAD-NEXT: ret void
+ // CHECK-LOAD-NEXT: }
+ {
+#pragma omp declare reduction(fun : struct SSS : omp_out = omp_in) initializer(init(&omp_priv, omp_orig))
+ // CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias)
+ // CHECK: call void @llvm.memcpy
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+ // CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias)
+ // CHECK: call void @init(
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+ // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias)
+ // CHECK-LOAD: call void @llvm.memcpy
+ // CHECK-LOAD-NEXT: ret void
+ // CHECK-LOAD-NEXT: }
+ // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias)
+ // CHECK-LOAD: call void @init(
+ // CHECK-LOAD-NEXT: ret void
+ // CHECK-LOAD-NEXT: }
+ }
+ return 0;
+}
+
+// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
+// CHECK-LOAD: [[MUL:%.+]] = mul nsw i32
+// CHECK-LOAD-NEXT: store i32 [[MUL]], i32*
+// CHECK-LOAD-NEXT: ret void
+// CHECK-LOAD-NEXT: }
+
+// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i8* noalias, i8* noalias)
+// CHECK-LOAD: sext i8
+// CHECK-LOAD: sext i8
+// CHECK-LOAD: [[MUL:%.+]] = mul nsw i32
+// CHECK-LOAD-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i8
+// CHECK-LOAD-NEXT: store i8 [[TRUNC]], i8*
+// CHECK-LOAD-NEXT: ret void
+// CHECK-LOAD-NEXT: }
+#endif
diff --git a/test/OpenMP/declare_reduction_codegen.cpp b/test/OpenMP/declare_reduction_codegen.cpp
new file mode 100644
index 0000000000000..a18e73f8a10f7
--- /dev/null
+++ b/test/OpenMP/declare_reduction_codegen.cpp
@@ -0,0 +1,182 @@
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -emit-llvm %s -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -o - -femit-all-decls -disable-llvm-optzns | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -emit-pch -o %t %s -femit-all-decls -disable-llvm-optzns
+// RUN: %clang_cc1 -fopenmp -x c++ -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-optzns | FileCheck --check-prefix=CHECK-LOAD %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+// CHECK: [[SSS_INT:.+]] = type { i32 }
+// CHECK-LOAD: [[SSS_INT:.+]] = type { i32 }
+
+#pragma omp declare reduction(+ : int, char : omp_out *= omp_in)
+// CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
+// CHECK: [[MUL:%.+]] = mul nsw i32
+// CHECK-NEXT: store i32 [[MUL]], i32*
+// CHECK-NEXT: ret void
+// CHECK-NEXT: }
+// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
+// CHECK-LOAD: [[MUL:%.+]] = mul nsw i32
+// CHECK-LOAD-NEXT: store i32 [[MUL]], i32*
+// CHECK-LOAD-NEXT: ret void
+// CHECK-LOAD-NEXT: }
+
+// CHECK: define internal {{.*}}void @{{[^(]+}}(i8* noalias, i8* noalias)
+// CHECK: sext i8
+// CHECK: sext i8
+// CHECK: [[MUL:%.+]] = mul nsw i32
+// CHECK-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i8
+// CHECK-NEXT: store i8 [[TRUNC]], i8*
+// CHECK-NEXT: ret void
+// CHECK-NEXT: }
+
+// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i8* noalias, i8* noalias)
+// CHECK-LOAD: sext i8
+// CHECK-LOAD: sext i8
+// CHECK-LOAD: [[MUL:%.+]] = mul nsw i32
+// CHECK-LOAD-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i8
+// CHECK-LOAD-NEXT: store i8 [[TRUNC]], i8*
+// CHECK-LOAD-NEXT: ret void
+// CHECK-LOAD-NEXT: }
+
+template <class T>
+struct SSS {
+ T a;
+ SSS() : a() {}
+#pragma omp declare reduction(fun : T : omp_out ^= omp_in) initializer(omp_priv = 24 + omp_orig)
+};
+
+SSS<int> d;
+
+// CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
+// CHECK: [[XOR:%.+]] = xor i32
+// CHECK-NEXT: store i32 [[XOR]], i32*
+// CHECK-NEXT: ret void
+// CHECK-NEXT: }
+
+// CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
+// CHECK: [[ADD:%.+]] = add nsw i32 24,
+// CHECK-NEXT: store i32 [[ADD]], i32*
+// CHECK-NEXT: ret void
+// CHECK-NEXT: }
+
+// CHECK: define {{.*}}void [[INIT:@[^(]+]]([[SSS_INT]]*
+// CHECK-LOAD: define {{.*}}void [[INIT:@[^(]+]]([[SSS_INT]]*
+void init(SSS<int> &lhs, SSS<int> &rhs) {}
+
+#pragma omp declare reduction(fun : SSS < int > : omp_out = omp_in) initializer(init(omp_priv, omp_orig))
+// CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias)
+// CHECK: call void @llvm.memcpy
+// CHECK-NEXT: ret void
+// CHECK-NEXT: }
+// CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias)
+// CHECK: call {{.*}}void [[INIT]](
+// CHECK-NEXT: ret void
+// CHECK-NEXT: }
+
+// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias)
+// CHECK-LOAD: call void @llvm.memcpy
+// CHECK-LOAD-NEXT: ret void
+// CHECK-LOAD-NEXT: }
+// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias)
+// CHECK-LOAD: call {{.*}}void [[INIT]](
+// CHECK-LOAD-NEXT: ret void
+// CHECK-LOAD-NEXT: }
+
+template <typename T>
+T foo(T a) {
+#pragma omp declare reduction(fun : T : omp_out += omp_in) initializer(omp_priv = 15 * omp_orig)
+ {
+#pragma omp declare reduction(fun : T : omp_out /= omp_in) initializer(omp_priv = 11 - omp_orig)
+ }
+ return a;
+}
+
+// CHECK-LABEL: @main
+int main() {
+ int i = 0;
+ SSS<int> sss;
+#pragma omp parallel reduction(SSS < int > ::fun : i)
+ {
+ i += 1;
+ }
+#pragma omp parallel reduction(::fun : sss)
+ {
+ }
+#pragma omp declare reduction(fun : SSS < int > : init(omp_out, omp_in))
+#pragma omp parallel reduction(fun : sss)
+ {
+ }
+ // CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
+ // CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
+ // CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call({{[^@]*}} @{{[^@]*}}[[REGION:@[^ ]+]]
+ // CHECK-LABEL: foo
+ return foo(15);
+}
+
+// CHECK: define internal {{.*}}void [[REGION]](
+// CHECK: [[SSS_PRIV:%.+]] = alloca %struct.SSS,
+// CHECK: invoke {{.*}} @_ZN3SSSIiEC1Ev(%struct.SSS* [[SSS_PRIV]])
+// CHECK-NOT: {{call |invoke }}
+// CHECK: call {{.*}}i32 @__kmpc_reduce_nowait(
+
+// CHECK-LABEL: i32 @{{.+}}foo{{[^(].+}}(i32
+// CHECK-LOAD-LABEL: i32 @{{.+}}foo{{[^(].+}}(i32
+
+// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
+// CHECK-LOAD: [[XOR:%.+]] = xor i32
+// CHECK-LOAD-NEXT: store i32 [[XOR]], i32*
+// CHECK-LOAD-NEXT: ret void
+// CHECK-LOAD-NEXT: }
+
+// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
+// CHECK-LOAD: [[ADD:%.+]] = add nsw i32 24,
+// CHECK-LOAD-NEXT: store i32 [[ADD]], i32*
+// CHECK-LOAD-NEXT: ret void
+// CHECK-LOAD-NEXT: }
+
+// CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
+// CHECK: [[ADD:%.+]] = add nsw i32
+// CHECK-NEXT: store i32 [[ADD]], i32*
+// CHECK-NEXT: ret void
+// CHECK-NEXT: }
+// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
+// CHECK-LOAD: [[ADD:%.+]] = add nsw i32
+// CHECK-LOAD-NEXT: store i32 [[ADD]], i32*
+// CHECK-LOAD-NEXT: ret void
+// CHECK-LOAD-NEXT: }
+
+// CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
+// CHECK: [[MUL:%.+]] = mul nsw i32 15,
+// CHECK-NEXT: store i32 [[MUL]], i32*
+// CHECK-NEXT: ret void
+// CHECK-NEXT: }
+// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
+// CHECK-LOAD: [[MUL:%.+]] = mul nsw i32 15,
+// CHECK-LOAD-NEXT: store i32 [[MUL]], i32*
+// CHECK-LOAD-NEXT: ret void
+// CHECK-LOAD-NEXT: }
+
+// CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
+// CHECK: [[DIV:%.+]] = sdiv i32
+// CHECK-NEXT: store i32 [[DIV]], i32*
+// CHECK-NEXT: ret void
+// CHECK-NEXT: }
+// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
+// CHECK-LOAD: [[DIV:%.+]] = sdiv i32
+// CHECK-LOAD-NEXT: store i32 [[DIV]], i32*
+// CHECK-LOAD-NEXT: ret void
+// CHECK-LOAD-NEXT: }
+
+// CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
+// CHECK: [[SUB:%.+]] = sub nsw i32 11,
+// CHECK-NEXT: store i32 [[SUB]], i32*
+// CHECK-NEXT: ret void
+// CHECK-NEXT: }
+// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
+// CHECK-LOAD: [[SUB:%.+]] = sub nsw i32 11,
+// CHECK-LOAD-NEXT: store i32 [[SUB]], i32*
+// CHECK-LOAD-NEXT: ret void
+// CHECK-LOAD-NEXT: }
+
+#endif
diff --git a/test/OpenMP/declare_reduction_messages.c b/test/OpenMP/declare_reduction_messages.c
new file mode 100644
index 0000000000000..fb9eacc90aa26
--- /dev/null
+++ b/test/OpenMP/declare_reduction_messages.c
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+int temp; // expected-note 6 {{'temp' declared here}}
+
+#pragma omp declare reduction // expected-error {{expected '(' after 'declare reduction'}}
+#pragma omp declare reduction { // expected-error {{expected '(' after 'declare reduction'}}
+#pragma omp declare reduction( // expected-error {{expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'}}
+#pragma omp declare reduction(# // expected-error {{expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'}}
+#pragma omp declare reduction(/ // expected-error {{expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'}}
+#pragma omp declare reduction(+ // expected-error {{expected ':'}}
+#pragma omp declare reduction(for // expected-error {{expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'}}
+#pragma omp declare reduction(if: // expected-error {{expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'}} expected-error {{expected a type}}
+#pragma omp declare reduction(oper: // expected-error {{expected a type}}
+#pragma omp declare reduction(oper; // expected-error {{expected ':'}} expected-error {{expected a type}}
+#pragma omp declare reduction(fun : int // expected-error {{expected ':'}} expected-error {{expected expression}}
+#pragma omp declare reduction(+ : const int: // expected-error {{reduction type cannot be qualified with 'const', 'volatile' or 'restrict'}}
+#pragma omp declare reduction(- : volatile int: // expected-error {{reduction type cannot be qualified with 'const', 'volatile' or 'restrict'}}
+#pragma omp declare reduction(* : int; // expected-error {{expected ','}} expected-error {{expected a type}}
+#pragma omp declare reduction(& : double char: // expected-error {{cannot combine with previous 'double' declaration specifier}} expected-error {{expected expression}}
+#pragma omp declare reduction(^ : double, char, : // expected-error {{expected a type}} expected-error {{expected expression}}
+#pragma omp declare reduction(&& : int, S: // expected-error {{unknown type name 'S'}} expected-error {{expected expression}}
+#pragma omp declare reduction(|| : int, double : temp += omp_in) // expected-error 2 {{only 'omp_in' or 'omp_out' variables are allowed in combiner expression}}
+#pragma omp declare reduction(| : char, float : omp_out += temp) // expected-error 2 {{only 'omp_in' or 'omp_out' variables are allowed in combiner expression}}
+#pragma omp declare reduction(fun : long : omp_out += omp_in) { // expected-error {{expected 'initializer'}} expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}}
+#pragma omp declare reduction(fun : unsigned : omp_out += temp)) // expected-error {{expected 'initializer'}} expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}} expected-error {{only 'omp_in' or 'omp_out' variables are allowed in combiner expression}}
+#pragma omp declare reduction(fun : long(void) : omp_out += omp_in) // expected-error {{reduction type cannot be a function type}}
+#pragma omp declare reduction(fun : long[3] : omp_out += omp_in) // expected-error {{reduction type cannot be an array type}}
+#pragma omp declare reduction(fun23 : long, int, long : omp_out += omp_in) // expected-error {{redefinition of user-defined reduction for type 'long'}} expected-note {{previous definition is here}}
+
+#pragma omp declare reduction(fun222 : long : omp_out += omp_in)
+#pragma omp declare reduction(fun1 : long : omp_out += omp_in) initializer // expected-error {{expected '(' after 'initializer'}}
+#pragma omp declare reduction(fun2 : long : omp_out += omp_in) initializer { // expected-error {{expected '(' after 'initializer'}} expected-error {{expected expression}} expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}}
+#pragma omp declare reduction(fun3 : long : omp_out += omp_in) initializer[ // expected-error {{expected '(' after 'initializer'}} expected-error {{expected expression}} expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}}
+#pragma omp declare reduction(fun4 : long : omp_out += omp_in) initializer() // expected-error {{expected expression}}
+#pragma omp declare reduction(fun5 : long : omp_out += omp_in) initializer(temp) // expected-error {{only 'omp_priv' or 'omp_orig' variables are allowed in initializer expression}}
+#pragma omp declare reduction(fun6 : long : omp_out += omp_in) initializer(omp_orig // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp declare reduction(fun7 : long : omp_out += omp_in) initializer(omp_priv 12) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp declare reduction(fun8 : long : omp_out += omp_in) initializer(omp_priv = 23) // expected-note {{previous definition is here}}
+#pragma omp declare reduction(fun8 : long : omp_out += omp_in) initializer(omp_priv = 23)) // expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}} expected-error {{redefinition of user-defined reduction for type 'long'}}
+#pragma omp declare reduction(fun9 : long : omp_out += omp_in) initializer(omp_priv = ) // expected-error {{expected expression}}
+
+int fun(int arg) {
+#pragma omp declare reduction(red : int : omp_out++)
+ {
+#pragma omp declare reduction(red : int : omp_out++) // expected-note {{previous definition is here}}
+#pragma omp declare reduction(red : int : omp_out++) // expected-error {{redefinition of user-defined reduction for type 'int'}}
+ {
+#pragma omp declare reduction(red : int : omp_out++)
+ }
+ }
+ return arg;
+}
diff --git a/test/OpenMP/declare_reduction_messages.cpp b/test/OpenMP/declare_reduction_messages.cpp
new file mode 100644
index 0000000000000..a1373b1dcb9bd
--- /dev/null
+++ b/test/OpenMP/declare_reduction_messages.cpp
@@ -0,0 +1,124 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+int temp; // expected-note 7 {{'temp' declared here}}
+
+#pragma omp declare reduction // expected-error {{expected '(' after 'declare reduction'}}
+#pragma omp declare reduction { // expected-error {{expected '(' after 'declare reduction'}}
+#pragma omp declare reduction( // expected-error {{expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'}}
+#pragma omp declare reduction(# // expected-error {{expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'}}
+#pragma omp declare reduction(/ // expected-error {{expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'}}
+#pragma omp declare reduction(+ // expected-error {{expected ':'}}
+#pragma omp declare reduction(operator // expected-error {{expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'}}
+#pragma omp declare reduction(operator: // expected-error {{expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'}} expected-error {{expected a type}}
+#pragma omp declare reduction(oper: // expected-error {{expected a type}}
+#pragma omp declare reduction(oper; // expected-error {{expected ':'}} expected-error {{expected a type}}
+#pragma omp declare reduction(fun : int // expected-error {{expected ':'}} expected-error {{expected expression}}
+#pragma omp declare reduction(+ : const int: // expected-error {{reduction type cannot be qualified with 'const', 'volatile' or 'restrict'}}
+#pragma omp declare reduction(- : volatile int: // expected-error {{reduction type cannot be qualified with 'const', 'volatile' or 'restrict'}}
+#pragma omp declare reduction(* : int; // expected-error {{expected ','}} expected-error {{expected a type}}
+#pragma omp declare reduction(& : double char: // expected-error {{cannot combine with previous 'double' declaration specifier}} expected-error {{expected expression}}
+#pragma omp declare reduction(^ : double, char, : // expected-error {{expected a type}} expected-error {{expected expression}}
+#pragma omp declare reduction(&& : int, S: // expected-error {{unknown type name 'S'}} expected-error {{expected expression}}
+#pragma omp declare reduction(|| : int, double : temp += omp_in) // expected-error 2 {{only 'omp_in' or 'omp_out' variables are allowed in combiner expression}}
+#pragma omp declare reduction(| : char, float : omp_out += ::temp) // expected-error 2 {{only 'omp_in' or 'omp_out' variables are allowed in combiner expression}}
+#pragma omp declare reduction(fun : long : omp_out += omp_in) { // expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}} expected-error {{expected 'initializer'}}
+#pragma omp declare reduction(fun : unsigned : omp_out += ::temp)) // expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}} expected-error {{expected 'initializer'}} expected-error {{only 'omp_in' or 'omp_out' variables are allowed in combiner expression}}
+#pragma omp declare reduction(fun : long & : omp_out += omp_in) // expected-error {{reduction type cannot be a reference type}}
+#pragma omp declare reduction(fun : long(void) : omp_out += omp_in) // expected-error {{reduction type cannot be a function type}}
+#pragma omp declare reduction(fun : long[3] : omp_out += omp_in) // expected-error {{reduction type cannot be an array type}}
+#pragma omp declare reduction(fun23 : long, int, long : omp_out += omp_in) // expected-error {{redefinition of user-defined reduction for type 'long'}} expected-note {{previous definition is here}}
+
+template <class T>
+class Class1 {
+ T a;
+public:
+ Class1() : a() {}
+#pragma omp declare reduction(fun : T : temp) // expected-error {{only 'omp_in' or 'omp_out' variables are allowed in combiner expression}}
+#pragma omp declare reduction(fun1 : T : omp_out++) // expected-note {{previous definition is here}} expected-error {{reduction type cannot be a reference type}}
+#pragma omp declare reduction(fun1 : T : omp_out += omp_in) // expected-error {{redefinition of user-defined reduction for type 'T'}}
+#pragma omp declare reduction(fun2 : T, T : omp_out++) // expected-error {{reduction type cannot be a reference type}} expected-error {{redefinition of user-defined reduction for type 'T'}} expected-note {{previous definition is here}}
+#pragma omp declare reduction(foo : T : omp_out += this->a) // expected-error {{invalid use of 'this' outside of a non-static member function}}
+};
+
+Class1<char &> e; // expected-note {{in instantiation of template class 'Class1<char &>' requested here}}
+
+template <class T>
+class Class2 : public Class1<T> {
+#pragma omp declare reduction(fun : T : omp_out += omp_in)
+};
+
+#pragma omp declare reduction(fun222 : long : omp_out += omp_in) // expected-note {{previous definition is here}}
+#pragma omp declare reduction(fun222 : long : omp_out += omp_in) // expected-error {{redefinition of user-defined reduction for type 'long'}}
+#pragma omp declare reduction(fun1 : long : omp_out += omp_in) initializer // expected-error {{expected '(' after 'initializer'}}
+#pragma omp declare reduction(fun2 : long : omp_out += omp_in) initializer { // expected-error {{expected '(' after 'initializer'}} expected-error {{expected expression}} expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}}
+#pragma omp declare reduction(fun3 : long : omp_out += omp_in) initializer[ // expected-error {{expected '(' after 'initializer'}} expected-error {{expected expression}} expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}}
+#pragma omp declare reduction(fun4 : long : omp_out += omp_in) initializer() // expected-error {{expected expression}}
+#pragma omp declare reduction(fun5 : long : omp_out += omp_in) initializer(temp) // expected-error {{only 'omp_priv' or 'omp_orig' variables are allowed in initializer expression}}
+#pragma omp declare reduction(fun6 : long : omp_out += omp_in) initializer(omp_orig // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp declare reduction(fun7 : long : omp_out += omp_in) initializer(omp_priv Class1 < int > ()) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp declare reduction(fun77 : long : omp_out += omp_in) initializer(omp_priv Class2 < int > ()) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp declare reduction(fun8 : long : omp_out += omp_in) initializer(omp_priv 23) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp declare reduction(fun88 : long : omp_out += omp_in) initializer(omp_priv 23)) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}}
+#pragma omp declare reduction(fun9 : long : omp_out += omp_priv) initializer(omp_in = 23) // expected-error {{use of undeclared identifier 'omp_priv'; did you mean 'omp_in'?}} expected-note {{'omp_in' declared here}}
+#pragma omp declare reduction(fun10 : long : omp_out += omp_in) initializer(omp_priv = 23)
+
+template <typename T>
+T fun(T arg) {
+#pragma omp declare reduction(red : T : omp_out++)
+ {
+#pragma omp declare reduction(red : T : omp_out++) // expected-note {{previous definition is here}}
+#pragma omp declare reduction(red : T : omp_out++) // expected-error {{redefinition of user-defined reduction for type 'T'}}
+#pragma omp declare reduction(fun : T : omp_out += omp_in) initializer(omp_priv = 23)
+ }
+ return arg;
+}
+
+template <typename T>
+T foo(T arg) {
+ T i;
+ {
+#pragma omp declare reduction(red : T : omp_out++)
+#pragma omp declare reduction(red1 : T : omp_out++) // expected-note {{previous definition is here}}
+#pragma omp declare reduction(red1 : int : omp_out++) // expected-error {{redefinition of user-defined reduction for type 'int'}}
+ #pragma omp parallel reduction (red : i)
+ {
+ }
+ #pragma omp parallel reduction (red1 : i)
+ {
+ }
+ #pragma omp parallel reduction (red2 : i) // expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
+ {
+ }
+ }
+ {
+#pragma omp declare reduction(red1 : int : omp_out++) // expected-note {{previous definition is here}}
+#pragma omp declare reduction(red : T : omp_out++)
+#pragma omp declare reduction(red1 : T : omp_out++) // expected-error {{redefinition of user-defined reduction for type 'int'}}
+ #pragma omp parallel reduction (red : i)
+ {
+ }
+ #pragma omp parallel reduction (red1 : i)
+ {
+ }
+ #pragma omp parallel reduction (red2 : i) // expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
+ {
+ }
+ }
+ return arg;
+}
+
+#pragma omp declare reduction(foo : int : ({int a = omp_in; a = a * 2; omp_out += a; }))
+int main() {
+ Class1<int> c1;
+ int i;
+ #pragma omp parallel reduction (::fun : c1)
+ {
+ }
+ #pragma omp parallel reduction (::Class1<int>::fun : c1)
+ {
+ }
+ #pragma omp parallel reduction (::Class2<int>::fun : i) // expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
+ {
+ }
+ return fun(15) + foo(15); // expected-note {{in instantiation of function template specialization 'foo<int>' requested here}}
+}
diff --git a/test/OpenMP/declare_simd_ast_print.c b/test/OpenMP/declare_simd_ast_print.c
new file mode 100644
index 0000000000000..04fd73f272d8b
--- /dev/null
+++ b/test/OpenMP/declare_simd_ast_print.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+#pragma omp declare simd aligned(b : 64)
+#pragma omp declare simd simdlen(32) aligned(d, b)
+#pragma omp declare simd inbranch, uniform(d) linear(val(s1, s2) : 32)
+#pragma omp declare simd notinbranch simdlen(2), uniform(s1, s2) linear(d: s1)
+void add_1(float *d, int s1, float *s2, double b[]) __attribute__((cold));
+
+// CHECK: #pragma omp declare simd notinbranch simdlen(2) uniform(s1, s2) linear(val(d): s1)
+// CHECK-NEXT: #pragma omp declare simd inbranch uniform(d) linear(val(s1): 32) linear(val(s2): 32)
+// CHECK-NEXT: #pragma omp declare simd simdlen(32) aligned(d) aligned(b)
+// CHECK-NEXT: #pragma omp declare simd aligned(b: 64)
+// CHECK-NEXT: void add_1(float *d, int s1, float *s2, double b[]) __attribute__((cold))
+
+#endif
diff --git a/test/OpenMP/declare_simd_ast_print.cpp b/test/OpenMP/declare_simd_ast_print.cpp
new file mode 100644
index 0000000000000..5a32e61d9922f
--- /dev/null
+++ b/test/OpenMP/declare_simd_ast_print.cpp
@@ -0,0 +1,146 @@
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+#pragma omp declare simd linear(d: 8)
+#pragma omp declare simd inbranch simdlen(32)
+#pragma omp declare simd notinbranch
+void add_1(float *d) __attribute__((cold));
+
+// CHECK: #pragma omp declare simd notinbranch
+// CHECK-NEXT: #pragma omp declare simd inbranch simdlen(32)
+// CHECK-NEXT: #pragma omp declare simd linear(val(d): 8)
+// CHECK-NEXT: void add_1(float *d) __attribute__((cold));
+//
+
+#pragma omp declare simd aligned(hp, hp2)
+template <class C> void h(C *hp, C *hp2, C *hq, C *lin) {
+}
+
+// CHECK: #pragma omp declare simd aligned(hp) aligned(hp2)
+// CHECK-NEXT: template <class C = int> void h(int *hp, int *hp2, int *hq, int *lin) {
+// CHECK-NEXT: h((float *)hp, (float *)hp2, (float *)hq, (float *)lin);
+// CHECK-NEXT: }
+
+// CHECK: #pragma omp declare simd aligned(hp) aligned(hp2)
+// CHECK-NEXT: template <class C = float> void h(float *hp, float *hp2, float *hq, float *lin) {
+// CHECK-NEXT: }
+
+// CHECK: #pragma omp declare simd aligned(hp) aligned(hp2)
+// CHECK: template <class C> void h(C *hp, C *hp2, C *hq, C *lin) {
+// CHECK-NEXT: }
+//
+
+// Explicit specialization with <C=int>.
+// Pragmas need to be same, otherwise standard says that's undefined behavior.
+#pragma omp declare simd aligned(hp, hp2)
+template <>
+void h(int *hp, int *hp2, int *hq, int *lin)
+{
+ // Implicit specialization with <C=float>.
+ // This is special case where the directive is stored by Sema and is
+ // generated together with the (pending) function instatiation.
+ h((float*) hp, (float*) hp2, (float*) hq, (float*) lin);
+}
+
+class VV {
+ // CHECK: #pragma omp declare simd uniform(this, a) linear(val(b): a)
+ // CHECK-NEXT: int add(int a, int b) __attribute__((cold)) {
+ // CHECK-NEXT: return a + b;
+ // CHECK-NEXT: }
+ #pragma omp declare simd uniform(this, a) linear(val(b): a)
+ int add(int a, int b) __attribute__((cold)) { return a + b; }
+
+ // CHECK: #pragma omp declare simd aligned(b: 4) aligned(a) linear(ref(b): 4) linear(val(this)) linear(val(a))
+ // CHECK-NEXT: float taddpf(float *a, float *&b) {
+ // CHECK-NEXT: return *a + *b;
+ // CHECK-NEXT: }
+ #pragma omp declare simd aligned (b: 4) aligned(a) linear(ref(b): 4) linear(this, a)
+ float taddpf(float *a, float *&b) { return *a + *b; }
+
+// CHECK: #pragma omp declare simd aligned(b: 8)
+// CHECK-NEXT: #pragma omp declare simd linear(uval(c): 8)
+// CHECK-NEXT: int tadd(int (&b)[], int &c) {
+// CHECK-NEXT: return this->x[b[0]] + b[0];
+// CHECK-NEXT: }
+ #pragma omp declare simd linear(uval(c): 8)
+ #pragma omp declare simd aligned(b : 8)
+ int tadd(int (&b)[], int &c) { return x[b[0]] + b[0]; }
+
+private:
+ int x[10];
+};
+
+// CHECK: template <int X = 16, typename T = float> class TVV {
+// CHECK: #pragma omp declare simd
+// CHECK-NEXT: int tadd(int a, int b);
+// CHECK: #pragma omp declare simd aligned(a: 16 * 2) aligned(b) linear(ref(b): 16)
+// CHECK-NEXT: float taddpf(float *a, float *&b) {
+// CHECK-NEXT: return *a + *b;
+// CHECK-NEXT: }
+// CHECK: #pragma omp declare simd
+// CHECK-NEXT: #pragma omp declare simd
+// CHECK-NEXT: int tadd(int b) {
+// CHECK-NEXT: return this->x[b] + b;
+// CHECK-NEXT: }
+// CHECK: }
+template <int X, typename T>
+class TVV {
+public:
+// CHECK: template <int X, typename T> class TVV {
+ #pragma omp declare simd simdlen(X)
+ int tadd(int a, int b) { return a + b; }
+
+// CHECK: #pragma omp declare simd simdlen(X)
+// CHECK-NEXT: int tadd(int a, int b) {
+// CHECK-NEXT: return a + b;
+// CHECK-NEXT: }
+
+ #pragma omp declare simd aligned(a : X * 2) aligned(b) linear(ref(b): X)
+ float taddpf(float *a, T *&b) { return *a + *b; }
+
+// CHECK: #pragma omp declare simd aligned(a: X * 2) aligned(b)
+// CHECK-NEXT: float taddpf(float *a, T *&b) {
+// CHECK-NEXT: return *a + *b;
+// CHECK-NEXT: }
+
+ #pragma omp declare simd
+ #pragma omp declare simd uniform(this, b)
+ int tadd(int b) { return x[b] + b; }
+
+// CHECK: #pragma omp declare simd uniform(this, b)
+// CHECK-NEXT: #pragma omp declare simd
+// CHECK-NEXT: int tadd(int b) {
+// CHECK-NEXT: return this->x[b] + b;
+// CHECK-NEXT: }
+
+private:
+ int x[X];
+};
+// CHECK: };
+
+// CHECK: #pragma omp declare simd simdlen(64) aligned(b: 64 * 2) linear(uval(c): 64)
+// CHECK: template <int N = 64> void foo(int (&b)[64], float *&c)
+// CHECK: #pragma omp declare simd simdlen(N) aligned(b: N * 2) linear(uval(c): N)
+// CHECK: template <int N> void foo(int (&b)[N], float *&c)
+#pragma omp declare simd simdlen(N) aligned(b : N * 2) linear(uval(c): N)
+template <int N>
+void foo(int (&b)[N], float *&c);
+
+// CHECK: TVV<16, float> t16;
+TVV<16, float> t16;
+
+void f() {
+ float a = 1.0f, b = 2.0f;
+ float *p = &b;
+ float r = t16.taddpf(&a, p);
+ int res = t16.tadd(b);
+ int c[64];
+ foo(c, p);
+}
+
+#endif
diff --git a/test/OpenMP/declare_simd_codegen.cpp b/test/OpenMP/declare_simd_codegen.cpp
new file mode 100644
index 0000000000000..4ed7fb2801b8f
--- /dev/null
+++ b/test/OpenMP/declare_simd_codegen.cpp
@@ -0,0 +1,288 @@
+// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c++ -emit-llvm %s -o - -femit-all-decls | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls | FileCheck %s
+// expected-no-diagnostics
+// REQUIRES: x86-registered-target
+#ifndef HEADER
+#define HEADER
+
+#pragma omp declare simd linear(d : 8)
+#pragma omp declare simd inbranch simdlen(32)
+#pragma omp declare simd notinbranch
+void add_1(float *d) {}
+
+#pragma omp declare simd aligned(hp, hp2)
+template <class C>
+void h(C *hp, C *hp2, C *hq, C *lin) {
+}
+
+// Explicit specialization with <C=int>.
+// Pragmas need to be same, otherwise standard says that's undefined behavior.
+#pragma omp declare simd aligned(hp, hp2)
+template <>
+void h(int *hp, int *hp2, int *hq, int *lin) {
+ // Implicit specialization with <C=float>.
+ // This is special case where the directive is stored by Sema and is
+ // generated together with the (pending) function instatiation.
+ h((float *)hp, (float *)hp2, (float *)hq, (float *)lin);
+}
+
+class VV {
+public:
+#pragma omp declare simd uniform(this, a) linear(val(b) : a)
+ int add(int a, int b) __attribute__((cold)) { return a + b; }
+
+#pragma omp declare simd aligned(b : 4) aligned(a) linear(ref(b) : 4) linear(this, a)
+ float taddpf(float *a, float *&b) { return *a + *b; }
+
+#pragma omp declare simd linear(uval(c) : 8)
+#pragma omp declare simd aligned(b : 8)
+ int tadd(int (&b)[], int &c) { return x[b[0]] + b[0]; }
+
+private:
+ int x[10];
+} vv;
+
+template <int X, typename T>
+class TVV {
+public:
+#pragma omp declare simd simdlen(X)
+ int tadd(int a, int b) { return a + b; }
+
+#pragma omp declare simd aligned(a : X * 2) aligned(b) linear(ref(b) : X)
+ float taddpf(float *a, T *&b) { return *a + *b; }
+
+#pragma omp declare simd
+#pragma omp declare simd uniform(this, b)
+ int tadd(int b) { return x[b] + b; }
+
+private:
+ int x[X];
+};
+
+#pragma omp declare simd simdlen(N) aligned(b : N * 2) linear(uval(c) : N)
+template <int N>
+void foo(int (&b)[N], float *&c) {}
+
+TVV<16, float> t16;
+
+void f(int (&g)[]) {
+ float a = 1.0f, b = 2.0f;
+ float *p = &b;
+ float r = t16.taddpf(&a, p);
+ int res = t16.tadd(b);
+ int c[64];
+ vv.add(res, res);
+ vv.taddpf(p, p);
+ vv.tadd(g, res);
+ foo(c, p);
+}
+
+#pragma omp declare simd
+#pragma omp declare simd notinbranch aligned(a : 32)
+int bar(VV v, float *a) { return 0; }
+#pragma omp declare simd
+#pragma omp declare simd notinbranch aligned(a)
+float baz(VV v, int a[]) { return 0; }
+#pragma omp declare simd
+#pragma omp declare simd notinbranch aligned(a)
+double bay(VV v, double *&a) { return 0; }
+#pragma omp declare simd
+#pragma omp declare simd inbranch linear(a : b) uniform(v, b)
+void bax(VV v, double *a, int b) {}
+#pragma omp declare simd uniform(q) aligned(q : 16) linear(k : 1)
+float foo(float *q, float x, int k) { return 0; }
+#pragma omp declare simd notinbranch
+double foo(double x) { return 0; }
+
+// CHECK-DAG: define {{.+}}@_Z5add_1Pf(
+// CHECK-DAG: define {{.+}}@_Z1hIiEvPT_S1_S1_S1_(
+// CHECK-DAG: define {{.+}}@_Z1hIfEvPT_S1_S1_S1_(
+// CHECK-DAG: define {{.+}}@_ZN2VV3addEii(
+// CHECK-DAG: define {{.+}}@_ZN2VV6taddpfEPfRS0_(
+// CHECK-DAG: define {{.+}}@_ZN2VV4taddERA_iRi(
+// CHECK-DAG: define {{.+}}@_Z1fRA_i(
+// CHECK-DAG: define {{.+}}@_ZN3TVVILi16EfE6taddpfEPfRS1_(
+// CHECK-DAG: define {{.+}}@_ZN3TVVILi16EfE4taddEi(
+// CHECK-DAG: define {{.+}}@_Z3fooILi64EEvRAT__iRPf(
+// CHECK-DAG: define {{.+}}@_Z3bar2VVPf(
+// CHECK-DAG: define {{.+}}@_Z3baz2VVPi(
+// CHECK-DAG: define {{.+}}@_Z3bay2VVRPd(
+// CHECK-DAG: define {{.+}}@_Z3bax2VVPdi(
+// CHECK-DAG: define {{.+}}@_Z3fooPffi(
+// CHECK-DAG: define {{.+}}@_Z3food(
+
+// CHECK-DAG: "_ZGVbM4l8__Z5add_1Pf"
+// CHECK-DAG: "_ZGVbN4l8__Z5add_1Pf"
+// CHECK-DAG: "_ZGVcM8l8__Z5add_1Pf"
+// CHECK-DAG: "_ZGVcN8l8__Z5add_1Pf"
+// CHECK-DAG: "_ZGVdM8l8__Z5add_1Pf"
+// CHECK-DAG: "_ZGVdN8l8__Z5add_1Pf"
+// CHECK-DAG: "_ZGVeM16l8__Z5add_1Pf"
+// CHECK-DAG: "_ZGVeN16l8__Z5add_1Pf"
+// CHECK-DAG: "_ZGVbM32v__Z5add_1Pf"
+// CHECK-DAG: "_ZGVcM32v__Z5add_1Pf"
+// CHECK-DAG: "_ZGVdM32v__Z5add_1Pf"
+// CHECK-DAG: "_ZGVeM32v__Z5add_1Pf"
+// CHECK-DAG: "_ZGVbN2v__Z5add_1Pf"
+// CHECK-DAG: "_ZGVcN4v__Z5add_1Pf"
+// CHECK-DAG: "_ZGVdN4v__Z5add_1Pf"
+// CHECK-DAG: "_ZGVeN8v__Z5add_1Pf"
+
+// CHECK-DAG: "_ZGVbM2va16va16vv__Z1hIiEvPT_S1_S1_S1_"
+// CHECK-DAG: "_ZGVbN2va16va16vv__Z1hIiEvPT_S1_S1_S1_"
+// CHECK-DAG: "_ZGVcM4va16va16vv__Z1hIiEvPT_S1_S1_S1_"
+// CHECK-DAG: "_ZGVcN4va16va16vv__Z1hIiEvPT_S1_S1_S1_"
+// CHECK-DAG: "_ZGVdM4va16va16vv__Z1hIiEvPT_S1_S1_S1_"
+// CHECK-DAG: "_ZGVdN4va16va16vv__Z1hIiEvPT_S1_S1_S1_"
+// CHECK-DAG: "_ZGVeM8va16va16vv__Z1hIiEvPT_S1_S1_S1_"
+// CHECK-DAG: "_ZGVeN8va16va16vv__Z1hIiEvPT_S1_S1_S1_"
+
+// CHECK-DAG: "_ZGVbM2va16va16vv__Z1hIfEvPT_S1_S1_S1_"
+// CHECK-DAG: "_ZGVbN2va16va16vv__Z1hIfEvPT_S1_S1_S1_"
+// CHECK-DAG: "_ZGVcM4va16va16vv__Z1hIfEvPT_S1_S1_S1_"
+// CHECK-DAG: "_ZGVcN4va16va16vv__Z1hIfEvPT_S1_S1_S1_"
+// CHECK-DAG: "_ZGVdM4va16va16vv__Z1hIfEvPT_S1_S1_S1_"
+// CHECK-DAG: "_ZGVdN4va16va16vv__Z1hIfEvPT_S1_S1_S1_"
+// CHECK-DAG: "_ZGVeM8va16va16vv__Z1hIfEvPT_S1_S1_S1_"
+// CHECK-DAG: "_ZGVeN8va16va16vv__Z1hIfEvPT_S1_S1_S1_"
+
+// CHECK-DAG: "_ZGVbM4uus1__ZN2VV3addEii"
+// CHECK-DAG: "_ZGVbN4uus1__ZN2VV3addEii"
+// CHECK-DAG: "_ZGVcM8uus1__ZN2VV3addEii"
+// CHECK-DAG: "_ZGVcN8uus1__ZN2VV3addEii"
+// CHECK-DAG: "_ZGVdM8uus1__ZN2VV3addEii"
+// CHECK-DAG: "_ZGVdN8uus1__ZN2VV3addEii"
+// CHECK-DAG: "_ZGVeM16uus1__ZN2VV3addEii"
+// CHECK-DAG: "_ZGVeN16uus1__ZN2VV3addEii"
+
+// CHECK-DAG: "_ZGVbM4lla16l4a4__ZN2VV6taddpfEPfRS0_"
+// CHECK-DAG: "_ZGVbN4lla16l4a4__ZN2VV6taddpfEPfRS0_"
+// CHECK-DAG: "_ZGVcM8lla16l4a4__ZN2VV6taddpfEPfRS0_"
+// CHECK-DAG: "_ZGVcN8lla16l4a4__ZN2VV6taddpfEPfRS0_"
+// CHECK-DAG: "_ZGVdM8lla16l4a4__ZN2VV6taddpfEPfRS0_"
+// CHECK-DAG: "_ZGVdN8lla16l4a4__ZN2VV6taddpfEPfRS0_"
+// CHECK-DAG: "_ZGVeM16lla16l4a4__ZN2VV6taddpfEPfRS0_"
+// CHECK-DAG: "_ZGVeN16lla16l4a4__ZN2VV6taddpfEPfRS0_"
+
+// CHECK-DAG: "_ZGVbM4vvl8__ZN2VV4taddERA_iRi"
+// CHECK-DAG: "_ZGVbN4vvl8__ZN2VV4taddERA_iRi"
+// CHECK-DAG: "_ZGVcM8vvl8__ZN2VV4taddERA_iRi"
+// CHECK-DAG: "_ZGVcN8vvl8__ZN2VV4taddERA_iRi"
+// CHECK-DAG: "_ZGVdM8vvl8__ZN2VV4taddERA_iRi"
+// CHECK-DAG: "_ZGVdN8vvl8__ZN2VV4taddERA_iRi"
+// CHECK-DAG: "_ZGVeM16vvl8__ZN2VV4taddERA_iRi"
+// CHECK-DAG: "_ZGVeN16vvl8__ZN2VV4taddERA_iRi"
+// CHECK-DAG: "_ZGVbM4vva8v__ZN2VV4taddERA_iRi"
+// CHECK-DAG: "_ZGVbN4vva8v__ZN2VV4taddERA_iRi"
+// CHECK-DAG: "_ZGVcM8vva8v__ZN2VV4taddERA_iRi"
+// CHECK-DAG: "_ZGVcN8vva8v__ZN2VV4taddERA_iRi"
+// CHECK-DAG: "_ZGVdM8vva8v__ZN2VV4taddERA_iRi"
+// CHECK-DAG: "_ZGVdN8vva8v__ZN2VV4taddERA_iRi"
+// CHECK-DAG: "_ZGVeM16vva8v__ZN2VV4taddERA_iRi"
+// CHECK-DAG: "_ZGVeN16vva8v__ZN2VV4taddERA_iRi"
+
+// CHECK-DAG: "_ZGVbM4vva32l16a16__ZN3TVVILi16EfE6taddpfEPfRS1_"
+// CHECK-DAG: "_ZGVbN4vva32l16a16__ZN3TVVILi16EfE6taddpfEPfRS1_"
+// CHECK-DAG: "_ZGVcM8vva32l16a16__ZN3TVVILi16EfE6taddpfEPfRS1_"
+// CHECK-DAG: "_ZGVcN8vva32l16a16__ZN3TVVILi16EfE6taddpfEPfRS1_"
+// CHECK-DAG: "_ZGVdM8vva32l16a16__ZN3TVVILi16EfE6taddpfEPfRS1_"
+// CHECK-DAG: "_ZGVdN8vva32l16a16__ZN3TVVILi16EfE6taddpfEPfRS1_"
+// CHECK-DAG: "_ZGVeM16vva32l16a16__ZN3TVVILi16EfE6taddpfEPfRS1_"
+// CHECK-DAG: "_ZGVeN16vva32l16a16__ZN3TVVILi16EfE6taddpfEPfRS1_"
+
+// CHECK-DAG: "_ZGVbM4uu__ZN3TVVILi16EfE4taddEi"
+// CHECK-DAG: "_ZGVbN4uu__ZN3TVVILi16EfE4taddEi"
+// CHECK-DAG: "_ZGVcM8uu__ZN3TVVILi16EfE4taddEi"
+// CHECK-DAG: "_ZGVcN8uu__ZN3TVVILi16EfE4taddEi"
+// CHECK-DAG: "_ZGVdM8uu__ZN3TVVILi16EfE4taddEi"
+// CHECK-DAG: "_ZGVdN8uu__ZN3TVVILi16EfE4taddEi"
+// CHECK-DAG: "_ZGVeM16uu__ZN3TVVILi16EfE4taddEi"
+// CHECK-DAG: "_ZGVeN16uu__ZN3TVVILi16EfE4taddEi"
+// CHECK-DAG: "_ZGVbM4vv__ZN3TVVILi16EfE4taddEi"
+// CHECK-DAG: "_ZGVbN4vv__ZN3TVVILi16EfE4taddEi"
+// CHECK-DAG: "_ZGVcM8vv__ZN3TVVILi16EfE4taddEi"
+// CHECK-DAG: "_ZGVcN8vv__ZN3TVVILi16EfE4taddEi"
+// CHECK-DAG: "_ZGVdM8vv__ZN3TVVILi16EfE4taddEi"
+// CHECK-DAG: "_ZGVdN8vv__ZN3TVVILi16EfE4taddEi"
+// CHECK-DAG: "_ZGVeM16vv__ZN3TVVILi16EfE4taddEi"
+// CHECK-DAG: "_ZGVeN16vv__ZN3TVVILi16EfE4taddEi"
+
+// CHECK-DAG: "_ZGVbM64va128l64__Z3fooILi64EEvRAT__iRPf"
+// CHECK-DAG: "_ZGVbN64va128l64__Z3fooILi64EEvRAT__iRPf"
+// CHECK-DAG: "_ZGVcM64va128l64__Z3fooILi64EEvRAT__iRPf"
+// CHECK-DAG: "_ZGVcN64va128l64__Z3fooILi64EEvRAT__iRPf"
+// CHECK-DAG: "_ZGVdM64va128l64__Z3fooILi64EEvRAT__iRPf"
+// CHECK-DAG: "_ZGVdN64va128l64__Z3fooILi64EEvRAT__iRPf"
+// CHECK-DAG: "_ZGVeM64va128l64__Z3fooILi64EEvRAT__iRPf"
+// CHECK-DAG: "_ZGVeN64va128l64__Z3fooILi64EEvRAT__iRPf"
+
+// CHECK-DAG: "_ZGVbM4vv__Z3bar2VVPf"
+// CHECK-DAG: "_ZGVbN4vv__Z3bar2VVPf"
+// CHECK-DAG: "_ZGVcM8vv__Z3bar2VVPf"
+// CHECK-DAG: "_ZGVcN8vv__Z3bar2VVPf"
+// CHECK-DAG: "_ZGVdM8vv__Z3bar2VVPf"
+// CHECK-DAG: "_ZGVdN8vv__Z3bar2VVPf"
+// CHECK-DAG: "_ZGVeM16vv__Z3bar2VVPf"
+// CHECK-DAG: "_ZGVeN16vv__Z3bar2VVPf"
+// CHECK-DAG: "_ZGVbN4vva32__Z3bar2VVPf"
+// CHECK-DAG: "_ZGVcN8vva32__Z3bar2VVPf"
+// CHECK-DAG: "_ZGVdN8vva32__Z3bar2VVPf"
+// CHECK-DAG: "_ZGVeN16vva32__Z3bar2VVPf"
+
+// CHECK-DAG: "_ZGVbM4vv__Z3baz2VVPi"
+// CHECK-DAG: "_ZGVbN4vv__Z3baz2VVPi"
+// CHECK-DAG: "_ZGVcM8vv__Z3baz2VVPi"
+// CHECK-DAG: "_ZGVcN8vv__Z3baz2VVPi"
+// CHECK-DAG: "_ZGVdM8vv__Z3baz2VVPi"
+// CHECK-DAG: "_ZGVdN8vv__Z3baz2VVPi"
+// CHECK-DAG: "_ZGVeM16vv__Z3baz2VVPi"
+// CHECK-DAG: "_ZGVeN16vv__Z3baz2VVPi"
+// CHECK-DAG: "_ZGVbN4vva16__Z3baz2VVPi"
+// CHECK-DAG: "_ZGVcN8vva16__Z3baz2VVPi"
+// CHECK-DAG: "_ZGVdN8vva16__Z3baz2VVPi"
+// CHECK-DAG: "_ZGVeN16vva16__Z3baz2VVPi"
+
+// CHECK-DAG: "_ZGVbM2vv__Z3bay2VVRPd"
+// CHECK-DAG: "_ZGVbN2vv__Z3bay2VVRPd"
+// CHECK-DAG: "_ZGVcM4vv__Z3bay2VVRPd"
+// CHECK-DAG: "_ZGVcN4vv__Z3bay2VVRPd"
+// CHECK-DAG: "_ZGVdM4vv__Z3bay2VVRPd"
+// CHECK-DAG: "_ZGVdN4vv__Z3bay2VVRPd"
+// CHECK-DAG: "_ZGVeM8vv__Z3bay2VVRPd"
+// CHECK-DAG: "_ZGVeN8vv__Z3bay2VVRPd"
+// CHECK-DAG: "_ZGVbN2vva16__Z3bay2VVRPd"
+// CHECK-DAG: "_ZGVcN4vva16__Z3bay2VVRPd"
+// CHECK-DAG: "_ZGVdN4vva16__Z3bay2VVRPd"
+// CHECK-DAG: "_ZGVeN8vva16__Z3bay2VVRPd"
+
+// CHECK-DAG: "_ZGVbM4us2u__Z3bax2VVPdi"
+// CHECK-DAG: "_ZGVcM8us2u__Z3bax2VVPdi"
+// CHECK-DAG: "_ZGVdM8us2u__Z3bax2VVPdi"
+// CHECK-DAG: "_ZGVeM16us2u__Z3bax2VVPdi"
+// CHECK-DAG: "_ZGVbM4vvv__Z3bax2VVPdi"
+// CHECK-DAG: "_ZGVbN4vvv__Z3bax2VVPdi"
+// CHECK-DAG: "_ZGVcM8vvv__Z3bax2VVPdi"
+// CHECK-DAG: "_ZGVcN8vvv__Z3bax2VVPdi"
+// CHECK-DAG: "_ZGVdM8vvv__Z3bax2VVPdi"
+// CHECK-DAG: "_ZGVdN8vvv__Z3bax2VVPdi"
+// CHECK-DAG: "_ZGVeM16vvv__Z3bax2VVPdi"
+// CHECK-DAG: "_ZGVeN16vvv__Z3bax2VVPdi"
+
+// CHECK-DAG: "_ZGVbM4ua16vl1__Z3fooPffi"
+// CHECK-DAG: "_ZGVbN4ua16vl1__Z3fooPffi"
+// CHECK-DAG: "_ZGVcM8ua16vl1__Z3fooPffi"
+// CHECK-DAG: "_ZGVcN8ua16vl1__Z3fooPffi"
+// CHECK-DAG: "_ZGVdM8ua16vl1__Z3fooPffi"
+// CHECK-DAG: "_ZGVdN8ua16vl1__Z3fooPffi"
+// CHECK-DAG: "_ZGVeM16ua16vl1__Z3fooPffi"
+// CHECK-DAG: "_ZGVeN16ua16vl1__Z3fooPffi"
+
+// CHECK-DAG: "_ZGVbN2v__Z3food"
+// CHECK-DAG: "_ZGVcN4v__Z3food"
+// CHECK-DAG: "_ZGVdN4v__Z3food"
+// CHECK-DAG: "_ZGVeN8v__Z3food"
+
+// CHECK-NOT: "_ZGV{{.+}}__Z1fRA_i
+
+#endif
diff --git a/test/OpenMP/declare_simd_messages.cpp b/test/OpenMP/declare_simd_messages.cpp
new file mode 100644
index 0000000000000..15971eb14de5a
--- /dev/null
+++ b/test/OpenMP/declare_simd_messages.cpp
@@ -0,0 +1,231 @@
+// RUN: %clang_cc1 -triple=x86_64-pc-win32 -verify -fopenmp -x c++ -std=c++11 -fms-extensions %s
+
+// expected-error@+1 {{expected an OpenMP directive}}
+#pragma omp declare
+
+// expected-error@+2 {{'#pragma omp declare simd' can only be applied to functions}}
+#pragma omp declare simd
+int a;
+// expected-error@+2 {{'#pragma omp declare simd' can only be applied to functions}}
+#pragma omp declare simd
+#pragma omp threadprivate(a)
+int var;
+#pragma omp threadprivate(var)
+
+// expected-error@+2 {{expected an OpenMP directive}} expected-error@+1 {{function declaration is expected after 'declare simd' directive}}
+#pragma omp declare simd
+#pragma omp declare
+
+// expected-error@+3 {{function declaration is expected after 'declare simd' directive}}
+// expected-error@+1 {{function declaration is expected after 'declare simd' directive}}
+#pragma omp declare simd
+#pragma omp declare simd
+#pragma options align=packed
+int main();
+
+// expected-error@+3 {{function declaration is expected after 'declare simd' directive}}
+// expected-error@+1 {{function declaration is expected after 'declare simd' directive}}
+#pragma omp declare simd
+#pragma omp declare simd
+#pragma init_seg(compiler)
+int main();
+
+// expected-error@+1 {{single declaration is expected after 'declare simd' directive}}
+#pragma omp declare simd
+// expected-note@+1 {{declared here}}
+int b, c;
+
+// expected-error@+1 {{'C' does not refer to a value}}
+#pragma omp declare simd simdlen(C)
+// expected-note@+1 {{declared here}}
+template <class C>
+void h(C *hp, C *hp2, C *hq, C *lin) {
+ b = 0;
+}
+
+#pragma omp declare simd
+template <>
+void h(int *hp, int *hp2, int *hq, int *lin) {
+ h((float *)hp, (float *)hp2, (float *)hq, (float *)lin);
+}
+
+#pragma omp declare simd inbranch inbranch
+#pragma omp declare simd notinbranch notinbranch
+#pragma omp declare simd inbranch inbranch notinbranch // expected-error {{unexpected 'notinbranch' clause, 'inbranch' is specified already}}
+#pragma omp declare simd notinbranch notinbranch inbranch // expected-error {{unexpected 'inbranch' clause, 'notinbranch' is specified already}}
+// expected-note@+2 {{read of non-const variable 'b' is not allowed in a constant expression}}
+// expected-error@+1 {{expression is not an integral constant expression}}
+#pragma omp declare simd simdlen(b)
+// expected-error@+1 {{directive '#pragma omp declare simd' cannot contain more than one 'simdlen' clause}}
+#pragma omp declare simd simdlen(32) simdlen(c)
+// expected-error@+1 {{expected '(' after 'simdlen'}}
+#pragma omp declare simd simdlen
+// expected-note@+3 {{to match this '('}}
+// expected-error@+2 {{expected ')'}}
+// expected-error@+1 {{expected expression}}
+#pragma omp declare simd simdlen(
+// expected-error@+2 {{expected '(' after 'simdlen'}}
+// expected-error@+1 {{expected expression}}
+#pragma omp declare simd simdlen(), simdlen
+// expected-error@+1 2 {{expected expression}}
+#pragma omp declare simd simdlen(), simdlen()
+// expected-warning@+3 {{extra tokens at the end of '#pragma omp declare simd' are ignored}}
+// expected-error@+2 {{expected '(' after 'simdlen'}}
+// expected-error@+1 {{expected expression}}
+#pragma omp declare simd simdlen() simdlen)
+void foo();
+
+// expected-error@+3 4 {{expected reference to one of the parameters of function 'foo'}}
+// expected-error@+2 {{invalid use of 'this' outside of a non-static member function}}
+// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+#pragma omp declare simd simdlen(N) uniform(this, var) aligned(var)
+template<int N>
+void foo() {}
+
+void test() {
+ // expected-note@+1 {{in instantiation of function template specialization 'foo<-3>' requested here}}
+ foo<-3>();
+}
+
+// expected-error@+1 {{expected '(' after 'uniform'}}
+#pragma omp declare simd uniform
+// expected-note@+3 {{to match this '('}}
+// expected-error@+2 {{expected ')'}}
+// expected-error@+1 {{expected expression}}
+#pragma omp declare simd uniform(
+// expected-error@+1 {{expected expression}}
+#pragma omp declare simd uniform()
+// expected-note@+3 {{to match this '('}}
+// expected-error@+2 {{expected ')'}}
+// expected-error@+1 {{invalid use of 'this' outside of a non-static member function}}
+#pragma omp declare simd uniform(this
+// expected-note@+3 {{to match this '('}}
+// expected-error@+2 {{expected ')'}}
+// expected-error@+1 {{invalid use of 'this' outside of a non-static member function}}
+#pragma omp declare simd uniform(this,a
+// expected-error@+1 {{expected expression}}
+#pragma omp declare simd uniform(,a)
+// expected-error@+1 {{expected '(' after 'aligned'}}
+#pragma omp declare simd aligned
+// expected-note@+3 {{to match this '('}}
+// expected-error@+2 {{expected ')'}}
+// expected-error@+1 {{expected expression}}
+#pragma omp declare simd aligned(
+// expected-error@+1 {{expected expression}}
+#pragma omp declare simd aligned()
+// expected-note@+3 {{to match this '('}}
+// expected-error@+2 {{expected ')'}}
+// expected-error@+1 {{expected expression}}
+#pragma omp declare simd aligned(a:
+// expected-error@+1 {{expected expression}}
+#pragma omp declare simd aligned(a:)
+// expected-warning@+2 {{extra tokens at the end of '#pragma omp declare simd' are ignored}}
+// expected-error@+1 {{expected '(' after 'aligned'}}
+#pragma omp declare simd aligned :)
+// expected-note@+3 {{to match this '('}}
+// expected-error@+2 {{expected ')'}}
+// expected-error@+1 {{invalid use of 'this' outside of a non-static member function}}
+#pragma omp declare simd aligned(this
+// expected-note@+3 {{to match this '('}}
+// expected-error@+2 {{expected ')'}}
+// expected-error@+1 {{invalid use of 'this' outside of a non-static member function}}
+#pragma omp declare simd aligned(this,b
+// expected-error@+1 {{expected expression}}
+#pragma omp declare simd aligned(, b)
+// expected-note@+4 {{defined as aligned}}
+// expected-error@+3 {{a parameter cannot appear in more than one aligned clause}}
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected ',' or ')' in 'aligned' clause}}
+#pragma omp declare simd aligned(b) aligned(b ; 64)
+// expected-note@+2 {{defined as aligned}}
+// expected-error@+1 {{a parameter cannot appear in more than one aligned clause}}
+#pragma omp declare simd aligned(b) aligned(b: 64)
+// expected-error@+1 {{argument to 'aligned' clause must be a strictly positive integer value}}
+#pragma omp declare simd aligned(b: -1)
+// expected-warning@+1 {{aligned clause will be ignored because the requested alignment is not a power of 2}}
+#pragma omp declare simd aligned(b: 3)
+// expected-error@+1 {{expected '(' after 'linear'}}
+#pragma omp declare simd linear
+// expected-note@+3 {{to match this '('}}
+// expected-error@+2 {{expected ')'}}
+// expected-error@+1 {{expected expression}}
+#pragma omp declare simd linear(
+// expected-error@+1 {{expected expression}}
+#pragma omp declare simd linear()
+// expected-note@+3 {{to match this '('}}
+// expected-error@+2 {{expected ')'}}
+// expected-error@+1 {{expected expression}}
+#pragma omp declare simd linear(a:
+// expected-error@+1 {{expected expression}}
+#pragma omp declare simd linear(a:)
+// expected-warning@+2 {{extra tokens at the end of '#pragma omp declare simd' are ignored}}
+// expected-error@+1 {{expected '(' after 'linear'}}
+#pragma omp declare simd linear :)
+// expected-note@+3 {{to match this '('}}
+// expected-error@+2 {{expected ')'}}
+// expected-error@+1 {{invalid use of 'this' outside of a non-static member function}}
+#pragma omp declare simd linear(this
+// expected-note@+3 {{to match this '('}}
+// expected-error@+2 {{expected ')'}}
+// expected-error@+1 {{invalid use of 'this' outside of a non-static member function}}
+#pragma omp declare simd linear(this,b
+// expected-error@+1 {{expected expression}}
+#pragma omp declare simd linear(, b)
+// expected-note@+4 {{defined as linear}}
+// expected-error@+3 {{linear variable cannot be linear}}
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected ',' or ')' in 'linear' clause}}
+#pragma omp declare simd linear(b) linear(b ; 64)
+// expected-note@+2 {{defined as linear}}
+// expected-error@+1 {{linear variable cannot be linear}}
+#pragma omp declare simd linear(b) linear(b: 64)
+#pragma omp declare simd linear(b: -1)
+#pragma omp declare simd linear(b: 3)
+// expected-error@+1 {{expected a reference to a parameter specified in a 'uniform' clause}}
+#pragma omp declare simd linear(b: a)
+// expected-note@+2 {{defined as uniform}}
+// expected-error@+1 {{linear variable cannot be uniform}}
+#pragma omp declare simd uniform(a), linear(a: 4)
+// expected-note@+2 {{defined as uniform}}
+// expected-error@+1 {{linear variable cannot be uniform}}
+#pragma omp declare simd linear(a: 4) uniform(a)
+// expected-error@+1 {{variable of non-reference type 'int *' can be used only with 'val' modifier, but used with 'uval'}}
+#pragma omp declare simd linear(uval(b))
+// expected-error@+1 {{variable of non-reference type 'int *' can be used only with 'val' modifier, but used with 'ref'}}
+#pragma omp declare simd linear(ref(b))
+// expected-error@+1 {{expected one of 'ref', val' or 'uval' modifiers}}
+#pragma omp declare simd linear(uref(b))
+void bar(int a, int *b);
+
+template <class T>
+struct St {
+// expected-error@+2 {{function declaration is expected after 'declare simd' directive}}
+#pragma init_seg(compiler)
+#pragma omp declare simd
+#pragma init_seg(compiler)
+// expected-note@+7 {{defined as uniform}}
+// expected-error@+6 {{expected a reference to a parameter specified in a 'uniform' clause}}
+// expected-error@+5 {{linear variable cannot be uniform}}
+// expected-note@+4 {{defined as aligned}}
+// expected-error@+3 {{argument to 'aligned' clause must be a strictly positive integer value}}
+// expected-error@+2 {{'this' cannot appear in more than one aligned clause}}
+// expected-error@+1 {{use of undeclared identifier 't'}}
+#pragma omp declare simd uniform(this, t) aligned(this: 4) aligned(this: -4) linear(this: hp)
+ void h(T *hp) {
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp declare simd'}}
+#pragma omp declare simd
+ *hp = *t;
+ }
+
+private:
+ T t;
+};
+
+namespace N {
+ // expected-error@+1 {{function declaration is expected after 'declare simd' directive}}
+ #pragma omp declare simd
+}
+// expected-error@+1 {{function declaration is expected after 'declare simd' directive}}
+#pragma omp declare simd
+// expected-error@+1 {{function declaration is expected after 'declare simd' directive}}
+#pragma omp declare simd
diff --git a/test/OpenMP/declare_target_ast_print.cpp b/test/OpenMP/declare_target_ast_print.cpp
new file mode 100644
index 0000000000000..78a9cf634af89
--- /dev/null
+++ b/test/OpenMP/declare_target_ast_print.cpp
@@ -0,0 +1,138 @@
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+#pragma omp declare target
+// CHECK: #pragma omp declare target
+void foo() {}
+// CHECK-NEXT: void foo()
+#pragma omp end declare target
+// CHECK: #pragma omp end declare target
+
+extern "C" {
+#pragma omp declare target
+// CHECK: #pragma omp declare target
+void foo_c() {}
+// CHECK-NEXT: void foo_c()
+#pragma omp end declare target
+// CHECK: #pragma omp end declare target
+}
+
+extern "C++" {
+#pragma omp declare target
+// CHECK: #pragma omp declare target
+void foo_cpp() {}
+// CHECK-NEXT: void foo_cpp()
+#pragma omp end declare target
+// CHECK: #pragma omp end declare target
+}
+
+#pragma omp declare target
+template <class T>
+struct C {
+// CHECK: template <class T = int> struct C
+ T t;
+// CHECK-NEXT: int t;
+ static T ts;
+// CHECK-NEXT: #pragma omp declare target
+// CHECK-NEXT: static int ts;
+// CHECK: #pragma omp end declare target
+
+ C(T t) : t(t) {
+ }
+// CHECK: #pragma omp declare target
+// CHECK-NEXT: C(int t) : t(t) {
+// CHECK-NEXT: }
+// CHECK: #pragma omp end declare target
+
+ T foo() {
+ return t;
+ }
+// CHECK: #pragma omp declare target
+// CHECK-NEXT: int foo() {
+// CHECK-NEXT: return this->t;
+// CHECK-NEXT: }
+// CHECK: #pragma omp end declare target
+};
+
+// CHECK: template <class T> struct C {
+// CHECK: #pragma omp declare target
+// CHECK-NEXT: static T ts;
+// CHECK-NEXT: #pragma omp end declare target
+
+template<class T>
+T C<T>::ts = 1;
+// CHECK: #pragma omp declare target
+// CHECK: T ts = 1;
+// CHECK: #pragma omp end declare target
+
+// CHECK: #pragma omp declare target
+// CHECK: int test1()
+int test1() {
+ C<int> c(1);
+ return c.foo() + c.ts;
+}
+#pragma omp end declare target
+// CHECK: #pragma omp end declare target
+
+int a1;
+void f1() {
+}
+#pragma omp declare target (a1, f1)
+// CHECK: #pragma omp declare target
+// CHECK: int a1;
+// CHECK: #pragma omp end declare target
+// CHECK: #pragma omp declare target
+// CHECK: void f1()
+// CHECK: #pragma omp end declare target
+
+int b1, b2, b3;
+void f2() {
+}
+#pragma omp declare target to(b1) to(b2), to(b3, f2)
+// CHECK: #pragma omp declare target
+// CHECK: int b1;
+// CHECK: #pragma omp end declare target
+// CHECK: #pragma omp declare target
+// CHECK: int b2;
+// CHECK: #pragma omp end declare target
+// CHECK: #pragma omp declare target
+// CHECK: int b3;
+// CHECK: #pragma omp end declare target
+// CHECK: #pragma omp declare target
+// CHECK: void f2()
+// CHECK: #pragma omp end declare target
+
+int c1, c2, c3;
+void f3() {
+}
+#pragma omp declare target link(c1) link(c2), link(c3, f3)
+// CHECK: #pragma omp declare target link
+// CHECK: int c1;
+// CHECK: #pragma omp end declare target
+// CHECK: #pragma omp declare target link
+// CHECK: int c2;
+// CHECK: #pragma omp end declare target
+// CHECK: #pragma omp declare target link
+// CHECK: int c3;
+// CHECK: #pragma omp end declare target
+// CHECK: #pragma omp declare target link
+// CHECK: void f3()
+// CHECK: #pragma omp end declare target
+
+int main (int argc, char **argv) {
+ foo();
+ foo_c();
+ foo_cpp();
+ test1();
+ return (0);
+}
+
+// CHECK: #pragma omp declare target
+// CHECK-NEXT: int ts = 1;
+// CHECK-NEXT: #pragma omp end declare target
+#endif
diff --git a/test/OpenMP/declare_target_messages.cpp b/test/OpenMP/declare_target_messages.cpp
new file mode 100644
index 0000000000000..b858d53c1ecf5
--- /dev/null
+++ b/test/OpenMP/declare_target_messages.cpp
@@ -0,0 +1,101 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -fnoopenmp-use-tls -ferror-limit 100 -o - %s
+
+#pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}}
+
+int a, b; // expected-warning {{declaration is not declared in any declare target region}}
+__thread int t; // expected-note {{defined as threadprivate or thread local}}
+
+#pragma omp declare target . // expected-error {{expected '(' after 'declare target'}}
+
+#pragma omp declare target
+void f();
+#pragma omp end declare target shared(a) // expected-warning {{extra tokens at the end of '#pragma omp end declare target' are ignored}}
+
+#pragma omp declare target map(a) // expected-error {{unexpected 'map' clause, only 'to' or 'link' clauses expected}}
+
+void c(); // expected-warning {{declaration is not declared in any declare target region}}
+
+extern int b;
+
+struct NonT {
+ int a;
+};
+
+typedef int sint;
+
+#pragma omp declare target // expected-note {{to match this '#pragma omp declare target'}}
+#pragma omp threadprivate(a) // expected-note {{defined as threadprivate or thread local}}
+extern int b;
+int g;
+
+struct T { // expected-note {{mappable type cannot be polymorphic}}
+ int a;
+ virtual int method();
+};
+
+class VC { // expected-note {{mappable type cannot be polymorphic}}
+ T member;
+ NonT member1;
+ public:
+ virtual int method() { T a; return 0; } // expected-error {{type 'T' is not mappable to target}}
+};
+
+struct C {
+ NonT a;
+ sint b;
+ int method();
+ int method1();
+};
+
+int C::method1() {
+ return 0;
+}
+
+void foo() {
+ a = 0; // expected-error {{threadprivate variables cannot be used in target constructs}}
+ b = 0; // expected-note {{used here}}
+ t = 1; // expected-error {{threadprivate variables cannot be used in target constructs}}
+ C object;
+ VC object1; // expected-error {{type 'VC' is not mappable to target}}
+ g = object.method();
+ g += object.method1();
+ g += object1.method();
+ f();
+ c(); // expected-note {{used here}}
+}
+#pragma omp declare target // expected-error {{expected '#pragma omp end declare target'}}
+void foo1() {}
+#pragma omp end declare target
+#pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}}
+
+int C::method() {
+ return 0;
+}
+
+struct S {
+#pragma omp declare target // expected-error {{directive must be at file or namespace scope}}
+ int v;
+#pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}}
+};
+
+int main (int argc, char **argv) {
+#pragma omp declare target // expected-error {{unexpected OpenMP directive '#pragma omp declare target'}}
+ int v;
+#pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}}
+ foo();
+ return (0);
+}
+
+namespace {
+#pragma omp declare target // expected-note {{to match this '#pragma omp declare target'}}
+ int x;
+} // expected-error {{expected '#pragma omp end declare target'}}
+#pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}}
+
+#pragma omp declare target link(S) // expected-error {{'S' used in declare target directive is not a variable or a function name}}
+
+#pragma omp declare target (x, x) // expected-error {{'x' appears multiple times in clauses on the same declare target directive}}
+#pragma omp declare target to(x) to(x) // expected-error {{'x' appears multiple times in clauses on the same declare target directive}}
+#pragma omp declare target link(x) // expected-error {{'x' must not appear in both clauses 'to' and 'link'}}
+
+#pragma omp declare target // expected-error {{expected '#pragma omp end declare target'}} expected-note {{to match this '#pragma omp declare target'}}
diff --git a/test/OpenMP/distribute_ast_print.cpp b/test/OpenMP/distribute_ast_print.cpp
index c3a175a5e5e84..5748fc79ed67f 100644
--- a/test/OpenMP/distribute_ast_print.cpp
+++ b/test/OpenMP/distribute_ast_print.cpp
@@ -8,6 +8,75 @@
void foo() {}
+struct S {
+ S(): a(0) {}
+ S(int v) : a(v) {}
+ int a;
+ typedef int type;
+};
+
+template <typename T>
+class S7 : public T {
+protected:
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(typename T::type v) : a(v) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute private(a) private(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp target
+// CHECK-NEXT: #pragma omp teams
+// CHECK-NEXT: #pragma omp distribute private(this->a) private(this->a) private(this->S::a)
+// CHECK: #pragma omp target
+// CHECK-NEXT: #pragma omp teams
+// CHECK-NEXT: #pragma omp distribute private(this->a) private(this->a) private(T::a)
+// CHECK: #pragma omp target
+// CHECK-NEXT: #pragma omp teams
+// CHECK-NEXT: #pragma omp distribute private(this->a) private(this->a)
+
+class S8 : public S7<S> {
+ S8() {}
+
+public:
+ S8(int v) : S7<S>(v){
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute private(a) private(this->a) private(S7<S>::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S8 &operator=(S8 &s) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute private(a) private(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp target
+// CHECK-NEXT: #pragma omp teams
+// CHECK-NEXT: #pragma omp distribute private(this->a) private(this->a) private(this->S7<S>::a)
+// CHECK: #pragma omp target
+// CHECK-NEXT: #pragma omp teams
+// CHECK-NEXT: #pragma omp distribute private(this->a) private(this->a)
+
template <class T, int N>
T tmain(T argc) {
T b = argc, c, d, e, f, g;
diff --git a/test/OpenMP/distribute_codegen.cpp b/test/OpenMP/distribute_codegen.cpp
new file mode 100644
index 0000000000000..37f00f09178b0
--- /dev/null
+++ b/test/OpenMP/distribute_codegen.cpp
@@ -0,0 +1,263 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix HCHECK
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix HCHECK
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix HCHECK
+
+// Test target codegen - host bc file has to be created first. (no significant differences with host version of target region)
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK-DAG: %ident_t = type { i32, i32, i32, i32, i8* }
+// CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
+// CHECK-DAG: [[DEF_LOC_0:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
+
+// CHECK-LABEL: define {{.*void}} @{{.*}}without_schedule_clause{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}})
+void without_schedule_clause(float *a, float *b, float *c, float *d) {
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute
+ for (int i = 33; i < 32000000; i += 7) {
+ a[i] = b[i] * c[i] * d[i];
+ }
+}
+
+// CHECK: define {{.*}}void @.omp_outlined.(i32* noalias [[GBL_TIDP:%.+]], i32* noalias [[BND_TID:%.+]], float** dereferenceable({{[0-9]+}}) [[APTR:%.+]], float** dereferenceable({{[0-9]+}}) [[BPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[CPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[DPTR:%.+]])
+// CHECK: [[TID_ADDR:%.+]] = alloca i32*
+// CHECK: [[IV:%.+iv]] = alloca i32
+// CHECK: [[LB:%.+lb]] = alloca i32
+// CHECK: [[UB:%.+ub]] = alloca i32
+// CHECK: [[ST:%.+stride]] = alloca i32
+// CHECK: [[LAST:%.+last]] = alloca i32
+// CHECK-DAG: store i32* [[GBL_TIDP]], i32** [[TID_ADDR]]
+// CHECK-DAG: store i32 0, i32* [[LB]]
+// CHECK-DAG: store i32 4571423, i32* [[UB]]
+// CHECK-DAG: store i32 1, i32* [[ST]]
+// CHECK-DAG: store i32 0, i32* [[LAST]]
+// CHECK-DAG: [[GBL_TID:%.+]] = load i32*, i32** [[TID_ADDR]]
+// CHECK-DAG: [[GBL_TIDV:%.+]] = load i32, i32* [[GBL_TID]]
+// CHECK: call void @__kmpc_for_static_init_{{.+}}(%ident_t* [[DEF_LOC_0]], i32 [[GBL_TIDV]], i32 92, i32* %.omp.is_last, i32* %.omp.lb, i32* %.omp.ub, i32* %.omp.stride, i32 1, i32 1)
+// CHECK-DAG: [[UBV0:%.+]] = load i32, i32* [[UB]]
+// CHECK-DAG: [[USWITCH:%.+]] = icmp sgt i32 [[UBV0]], 4571423
+// CHECK: br i1 [[USWITCH]], label %[[BBCT:.+]], label %[[BBCF:.+]]
+// CHECK-DAG: [[BBCT]]:
+// CHECK-DAG: br label %[[BBCE:.+]]
+// CHECK-DAG: [[BBCF]]:
+// CHECK-DAG: [[UBV1:%.+]] = load i32, i32* [[UB]]
+// CHECK-DAG: br label %[[BBCE]]
+// CHECK: [[BBCE]]:
+// CHECK: [[SELUB:%.+]] = phi i32 [ 4571423, %[[BBCT]] ], [ [[UBV1]], %[[BBCF]] ]
+// CHECK: store i32 [[SELUB]], i32* [[UB]]
+// CHECK: [[LBV0:%.+]] = load i32, i32* [[LB]]
+// CHECK: store i32 [[LBV0]], i32* [[IV]]
+// CHECK: br label %[[BBINNFOR:.+]]
+// CHECK: [[BBINNFOR]]:
+// CHECK: [[IVVAL0:%.+]] = load i32, i32* [[IV]]
+// CHECK: [[UBV2:%.+]] = load i32, i32* [[UB]]
+// CHECK: [[IVLEUB:%.+]] = icmp sle i32 [[IVVAL0]], [[UBV2]]
+// CHECK: br i1 [[IVLEUB]], label %[[BBINNBODY:.+]], label %[[BBINNEND:.+]]
+// CHECK: [[BBINNBODY]]:
+// CHECK: {{.+}} = load i32, i32* [[IV]]
+// ... loop body ...
+// CHECK: br label %[[BBBODYCONT:.+]]
+// CHECK: [[BBBODYCONT]]:
+// CHECK: br label %[[BBINNINC:.+]]
+// CHECK: [[BBINNINC]]:
+// CHECK: [[IVVAL1:%.+]] = load i32, i32* [[IV]]
+// CHECK: [[IVINC:%.+]] = add nsw i32 [[IVVAL1]], 1
+// CHECK: store i32 [[IVINC]], i32* [[IV]]
+// CHECK: br label %[[BBINNFOR]]
+// CHECK: [[BBINNEND]]:
+// CHECK: br label %[[LPEXIT:.+]]
+// CHECK: [[LPEXIT]]:
+// CHECK: call void @__kmpc_for_static_fini(%ident_t* [[DEF_LOC_0]], i32 [[GBL_TIDV]])
+// CHECK: ret void
+
+
+// CHECK-LABEL: define {{.*void}} @{{.*}}static_not_chunked{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}})
+void static_not_chunked(float *a, float *b, float *c, float *d) {
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute dist_schedule(static)
+ for (int i = 32000000; i > 33; i += -7) {
+ a[i] = b[i] * c[i] * d[i];
+ }
+}
+
+// CHECK: define {{.*}}void @.omp_outlined.{{.*}}(i32* noalias [[GBL_TIDP:%.+]], i32* noalias [[BND_TID:%.+]], float** dereferenceable({{[0-9]+}}) [[APTR:%.+]], float** dereferenceable({{[0-9]+}}) [[BPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[CPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[DPTR:%.+]])
+// CHECK: [[TID_ADDR:%.+]] = alloca i32*
+// CHECK: [[IV:%.+iv]] = alloca i32
+// CHECK: [[LB:%.+lb]] = alloca i32
+// CHECK: [[UB:%.+ub]] = alloca i32
+// CHECK: [[ST:%.+stride]] = alloca i32
+// CHECK: [[LAST:%.+last]] = alloca i32
+// CHECK-DAG: store i32* [[GBL_TIDP]], i32** [[TID_ADDR]]
+// CHECK-DAG: store i32 0, i32* [[LB]]
+// CHECK-DAG: store i32 4571423, i32* [[UB]]
+// CHECK-DAG: store i32 1, i32* [[ST]]
+// CHECK-DAG: store i32 0, i32* [[LAST]]
+// CHECK-DAG: [[GBL_TID:%.+]] = load i32*, i32** [[TID_ADDR]]
+// CHECK-DAG: [[GBL_TIDV:%.+]] = load i32, i32* [[GBL_TID]]
+// CHECK: call void @__kmpc_for_static_init_{{.+}}(%ident_t* [[DEF_LOC_0]], i32 [[GBL_TIDV]], i32 92, i32* %.omp.is_last, i32* %.omp.lb, i32* %.omp.ub, i32* %.omp.stride, i32 1, i32 1)
+// CHECK-DAG: [[UBV0:%.+]] = load i32, i32* [[UB]]
+// CHECK-DAG: [[USWITCH:%.+]] = icmp sgt i32 [[UBV0]], 4571423
+// CHECK: br i1 [[USWITCH]], label %[[BBCT:.+]], label %[[BBCF:.+]]
+// CHECK-DAG: [[BBCT]]:
+// CHECK-DAG: br label %[[BBCE:.+]]
+// CHECK-DAG: [[BBCF]]:
+// CHECK-DAG: [[UBV1:%.+]] = load i32, i32* [[UB]]
+// CHECK-DAG: br label %[[BBCE]]
+// CHECK: [[BBCE]]:
+// CHECK: [[SELUB:%.+]] = phi i32 [ 4571423, %[[BBCT]] ], [ [[UBV1]], %[[BBCF]] ]
+// CHECK: store i32 [[SELUB]], i32* [[UB]]
+// CHECK: [[LBV0:%.+]] = load i32, i32* [[LB]]
+// CHECK: store i32 [[LBV0]], i32* [[IV]]
+// CHECK: br label %[[BBINNFOR:.+]]
+// CHECK: [[BBINNFOR]]:
+// CHECK: [[IVVAL0:%.+]] = load i32, i32* [[IV]]
+// CHECK: [[UBV2:%.+]] = load i32, i32* [[UB]]
+// CHECK: [[IVLEUB:%.+]] = icmp sle i32 [[IVVAL0]], [[UBV2]]
+// CHECK: br i1 [[IVLEUB]], label %[[BBINNBODY:.+]], label %[[BBINNEND:.+]]
+// CHECK: [[BBINNBODY]]:
+// CHECK: {{.+}} = load i32, i32* [[IV]]
+// ... loop body ...
+// CHECK: br label %[[BBBODYCONT:.+]]
+// CHECK: [[BBBODYCONT]]:
+// CHECK: br label %[[BBINNINC:.+]]
+// CHECK: [[BBINNINC]]:
+// CHECK: [[IVVAL1:%.+]] = load i32, i32* [[IV]]
+// CHECK: [[IVINC:%.+]] = add nsw i32 [[IVVAL1]], 1
+// CHECK: store i32 [[IVINC]], i32* [[IV]]
+// CHECK: br label %[[BBINNFOR]]
+// CHECK: [[BBINNEND]]:
+// CHECK: br label %[[LPEXIT:.+]]
+// CHECK: [[LPEXIT]]:
+// CHECK: call void @__kmpc_for_static_fini(%ident_t* [[DEF_LOC_0]], i32 [[GBL_TIDV]])
+// CHECK: ret void
+
+
+// CHECK-LABEL: define {{.*void}} @{{.*}}static_chunked{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}})
+void static_chunked(float *a, float *b, float *c, float *d) {
+ #pragma omp target
+ #pragma omp teams
+#pragma omp distribute dist_schedule(static, 5)
+ for (unsigned i = 131071; i <= 2147483647; i += 127) {
+ a[i] = b[i] * c[i] * d[i];
+ }
+}
+
+// CHECK: define {{.*}}void @.omp_outlined.{{.*}}(i32* noalias [[GBL_TIDP:%.+]], i32* noalias [[BND_TID:%.+]], float** dereferenceable({{[0-9]+}}) [[APTR:%.+]], float** dereferenceable({{[0-9]+}}) [[BPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[CPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[DPTR:%.+]])
+// CHECK: [[TID_ADDR:%.+]] = alloca i32*
+// CHECK: [[IV:%.+iv]] = alloca i32
+// CHECK: [[LB:%.+lb]] = alloca i32
+// CHECK: [[UB:%.+ub]] = alloca i32
+// CHECK: [[ST:%.+stride]] = alloca i32
+// CHECK: [[LAST:%.+last]] = alloca i32
+// CHECK-DAG: store i32* [[GBL_TIDP]], i32** [[TID_ADDR]]
+// CHECK-DAG: store i32 0, i32* [[LB]]
+// CHECK-DAG: store i32 16908288, i32* [[UB]]
+// CHECK-DAG: store i32 1, i32* [[ST]]
+// CHECK-DAG: store i32 0, i32* [[LAST]]
+// CHECK-DAG: [[GBL_TID:%.+]] = load i32*, i32** [[TID_ADDR]]
+// CHECK-DAG: [[GBL_TIDV:%.+]] = load i32, i32* [[GBL_TID]]
+// CHECK: call void @__kmpc_for_static_init_{{.+}}(%ident_t* [[DEF_LOC_0]], i32 [[GBL_TIDV]], i32 91, i32* %.omp.is_last, i32* %.omp.lb, i32* %.omp.ub, i32* %.omp.stride, i32 1, i32 5)
+// CHECK-DAG: [[UBV0:%.+]] = load i32, i32* [[UB]]
+// CHECK-DAG: [[USWITCH:%.+]] = icmp ugt i32 [[UBV0]], 16908288
+// CHECK: br i1 [[USWITCH]], label %[[BBCT:.+]], label %[[BBCF:.+]]
+// CHECK-DAG: [[BBCT]]:
+// CHECK-DAG: br label %[[BBCE:.+]]
+// CHECK-DAG: [[BBCF]]:
+// CHECK-DAG: [[UBV1:%.+]] = load i32, i32* [[UB]]
+// CHECK-DAG: br label %[[BBCE]]
+// CHECK: [[BBCE]]:
+// CHECK: [[SELUB:%.+]] = phi i32 [ 16908288, %[[BBCT]] ], [ [[UBV1]], %[[BBCF]] ]
+// CHECK: store i32 [[SELUB]], i32* [[UB]]
+// CHECK: [[LBV0:%.+]] = load i32, i32* [[LB]]
+// CHECK: store i32 [[LBV0]], i32* [[IV]]
+// CHECK: br label %[[BBINNFOR:.+]]
+// CHECK: [[BBINNFOR]]:
+// CHECK: [[IVVAL0:%.+]] = load i32, i32* [[IV]]
+// CHECK: [[UBV2:%.+]] = load i32, i32* [[UB]]
+// CHECK: [[IVLEUB:%.+]] = icmp ule i32 [[IVVAL0]], [[UBV2]]
+// CHECK: br i1 [[IVLEUB]], label %[[BBINNBODY:.+]], label %[[BBINNEND:.+]]
+// CHECK: [[BBINNBODY]]:
+// CHECK: {{.+}} = load i32, i32* [[IV]]
+// ... loop body ...
+// CHECK: br label %[[BBBODYCONT:.+]]
+// CHECK: [[BBBODYCONT]]:
+// CHECK: br label %[[BBINNINC:.+]]
+// CHECK: [[BBINNINC]]:
+// CHECK: [[IVVAL1:%.+]] = load i32, i32* [[IV]]
+// CHECK: [[IVINC:%.+]] = add i32 [[IVVAL1]], 1
+// CHECK: store i32 [[IVINC]], i32* [[IV]]
+// CHECK: br label %[[BBINNFOR]]
+// CHECK: [[BBINNEND]]:
+// CHECK: br label %[[LPEXIT:.+]]
+// CHECK: [[LPEXIT]]:
+// CHECK: call void @__kmpc_for_static_fini(%ident_t* [[DEF_LOC_0]], i32 [[GBL_TIDV]])
+// CHECK: ret void
+
+// CHECK-LABEL: test_precond
+void test_precond() {
+ char a = 0;
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute
+ for(char i = a; i < 10; ++i);
+}
+
+// a is passed as a parameter to the outlined functions
+// CHECK: define {{.*}}void @.omp_outlined.{{.*}}(i32* noalias [[GBL_TIDP:%.+]], i32* noalias [[BND_TID:%.+]], i8* dereferenceable({{[0-9]+}}) [[APARM:%.+]])
+// CHECK: store i8* [[APARM]], i8** [[APTRADDR:%.+]]
+// ..many loads of %0..
+// CHECK: [[A2:%.+]] = load i8*, i8** [[APTRADDR]]
+// CHECK: [[AVAL0:%.+]] = load i8, i8* [[A2]]
+// CHECK: store i8 [[AVAL0]], i8* [[CAP_EXPR:%.+]],
+// CHECK: [[AVAL1:%.+]] = load i8, i8* [[CAP_EXPR]]
+// CHECK: load i8, i8* [[CAP_EXPR]]
+// CHECK: [[AVAL2:%.+]] = load i8, i8* [[CAP_EXPR]]
+// CHECK: [[ACONV:%.+]] = sext i8 [[AVAL2]] to i32
+// CHECK: [[ACMP:%.+]] = icmp slt i32 [[ACONV]], 10
+// CHECK: br i1 [[ACMP]], label %[[PRECOND_THEN:.+]], label %[[PRECOND_END:.+]]
+// CHECK: [[PRECOND_THEN]]
+// CHECK: call void @__kmpc_for_static_init_4
+// CHECK: call void @__kmpc_for_static_fini
+// CHECK: [[PRECOND_END]]
+
+// no templates for now, as these require special handling in target regions and/or declare target
+
+// HCHECK-LABEL: fint
+// HCHECK: call {{.*}}i32 {{.+}}ftemplate
+// HCHECK: ret i32
+
+// HCHECK: load i16, i16*
+// HCHECK: store i16 %
+// HCHECK: call i32 @__tgt_target_teams(
+// HCHECK: call void @__kmpc_for_static_init_4(
+template <typename T>
+T ftemplate() {
+ short aa = 0;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute dist_schedule(static, aa)
+ for (int i = 0; i < 100; i++) {
+ }
+ return T();
+}
+
+int fint(void) { return ftemplate<int>(); }
+
+#endif
diff --git a/test/OpenMP/distribute_dist_schedule_ast_print.cpp b/test/OpenMP/distribute_dist_schedule_ast_print.cpp
new file mode 100644
index 0000000000000..32389ef1496e1
--- /dev/null
+++ b/test/OpenMP/distribute_dist_schedule_ast_print.cpp
@@ -0,0 +1,106 @@
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+template <class T, int N>
+T tmain(T argc) {
+ T b = argc, c, d, e, f, g;
+ static T a;
+// CHECK: static T a;
+#pragma omp distribute dist_schedule(static,10)
+// CHECK-NEXT: #pragma omp distribute dist_schedule(static, 10)
+ for (int i=0; i < 2; ++i)a=2;
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp distribute dist_schedule(static,a)
+// CHECK-NEXT: #pragma omp distribute dist_schedule(static, a)
+ for (int i=0; i < 2; ++i)a=2;
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute dist_schedule(static,2)
+ for (int i = 0; i < 10; ++i)
+ for (int j = 0; j < 10; ++j)foo();
+// CHECK-NEXT: #pragma omp target
+// CHECK-NEXT: #pragma omp teams
+// CHECK-NEXT: #pragma omp distribute dist_schedule(static, 2)
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: for (int j = 0; j < 10; ++j)
+// CHECK-NEXT: foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute dist_schedule(static,a)
+ for (int i = 0; i < 10; ++i)
+ for (int j = 0; j < 10; ++j)foo();
+// CHECK-NEXT: #pragma omp target
+// CHECK-NEXT: #pragma omp teams
+// CHECK-NEXT: #pragma omp distribute dist_schedule(static, a)
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: for (int j = 0; j < 10; ++j)
+// CHECK-NEXT: foo();
+ for (int i = 0; i < 10; ++i)foo();
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: foo();
+#pragma omp distribute
+// CHECK: #pragma omp distribute
+ for (int i = 0; i < 10; ++i)foo();
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: foo();
+ return T();
+}
+
+int main (int argc, char **argv) {
+ int b = argc, c, d, e, f, g;
+ static int a;
+// CHECK: static int a;
+#pragma omp distribute dist_schedule(static,10)
+// CHECK-NEXT: #pragma omp distribute dist_schedule(static, 10)
+ for (int i=0; i < 2; ++i)a=2;
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp distribute dist_schedule(static,b)
+// CHECK-NEXT: #pragma omp distribute dist_schedule(static, b)
+ for (int i=0; i < 2; ++i)a=2;
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute dist_schedule(static,2)
+ for (int i = 0; i < 10; ++i)
+ for (int j = 0; j < 10; ++j)foo();
+// CHECK-NEXT: #pragma omp target
+// CHECK-NEXT: #pragma omp teams
+// CHECK-NEXT: #pragma omp distribute dist_schedule(static, 2)
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: for (int j = 0; j < 10; ++j)
+// CHECK-NEXT: foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute dist_schedule(static,a)
+ for (int i = 0; i < 10; ++i)
+ for (int j = 0; j < 10; ++j)foo();
+// CHECK-NEXT: #pragma omp target
+// CHECK-NEXT: #pragma omp teams
+// CHECK-NEXT: #pragma omp distribute dist_schedule(static, a)
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: for (int j = 0; j < 10; ++j)
+// CHECK-NEXT: foo();
+ for (int i = 0; i < 10; ++i)foo();
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: foo();
+#pragma omp distribute
+// CHECK: #pragma omp distribute
+ for (int i = 0; i < 10; ++i)foo();
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: foo();
+ return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0]));
+}
+
+#endif
diff --git a/test/OpenMP/distribute_dist_schedule_messages.cpp b/test/OpenMP/distribute_dist_schedule_messages.cpp
new file mode 100644
index 0000000000000..98652a20034ea
--- /dev/null
+++ b/test/OpenMP/distribute_dist_schedule_messages.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note {{declared here}}
+
+template <class T, int N>
+T tmain(T argc) {
+ T b = argc, c, d, e, f, g;
+ char ** argv;
+ static T a;
+// CHECK: static T a;
+ #pragma omp distribute dist_schedule // expected-error {{expected '(' after 'dist_schedule'}}
+ for (int i = 0; i < 10; ++i) foo();
+ #pragma omp distribute dist_schedule ( // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+ #pragma omp distribute dist_schedule () // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}}
+ for (int i = 0; i < 10; ++i) foo();
+ #pragma omp distribute dist_schedule (static // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+ #pragma omp distribute dist_schedule (static, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+ #pragma omp distribute dist_schedule (argc)) // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-warning {{extra tokens at the end of '#pragma omp distribute' are ignored}}
+ for (int i = 0; i < 10; ++i) foo();
+ #pragma omp distribute dist_schedule (static, argc > 0 ? argv[1] : argv[2]) // expected-error2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (int i = 0; i < 10; ++i) foo();
+ #pragma omp distribute dist_schedule (static), dist_schedule (static, 1) // expected-error {{directive '#pragma omp distribute' cannot contain more than one 'dist_schedule' clause}}
+ for (int i = 0; i < 10; ++i) foo();
+ #pragma omp distribute dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 0; i < 10; ++i) foo();
+ #pragma omp distribute dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (int i = 0; i < 10; ++i) foo();
+ return T();
+}
+
+int main(int argc, char **argv) {
+ #pragma omp distribute dist_schedule // expected-error {{expected '(' after 'dist_schedule'}}
+ for (int i = 0; i < 10; ++i) foo();
+ #pragma omp distribute dist_schedule ( // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+ #pragma omp distribute dist_schedule () // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}}
+ for (int i = 0; i < 10; ++i) foo();
+ #pragma omp distribute dist_schedule (static // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+ #pragma omp distribute dist_schedule (static, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+ #pragma omp distribute dist_schedule (argc)) // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-warning {{extra tokens at the end of '#pragma omp distribute' are ignored}}
+ for (int i = 0; i < 10; ++i) foo();
+ #pragma omp distribute dist_schedule (static, argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (int i = 0; i < 10; ++i) foo();
+ #pragma omp distribute dist_schedule (static), dist_schedule (static, 1) // expected-error {{directive '#pragma omp distribute' cannot contain more than one 'dist_schedule' clause}}
+ for (int i = 0; i < 10; ++i) foo();
+ #pragma omp distribute dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 0; i < 10; ++i) foo();
+ #pragma omp distribute dist_schedule (static, argv[1]=2) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+ return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0])); // expected-note {{in instantiation of function template specialization 'tmain<int, 5>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<char, 1>' requested here}}
+}
diff --git a/test/OpenMP/distribute_parallel_for_ast_print.cpp b/test/OpenMP/distribute_parallel_for_ast_print.cpp
new file mode 100644
index 0000000000000..993cc2a7151f7
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_ast_print.cpp
@@ -0,0 +1,139 @@
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+struct S {
+ S(): a(0) {}
+ S(int v) : a(v) {}
+ int a;
+ typedef int type;
+};
+
+template <typename T>
+class S7 : public T {
+protected:
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(typename T::type v) : a(v) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(a) private(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp distribute parallel for private(this->a) private(this->a) private(this->S::a)
+// CHECK: #pragma omp distribute parallel for private(this->a) private(this->a) private(T::a)
+// CHECK: #pragma omp distribute parallel for private(this->a) private(this->a)
+
+class S8 : public S7<S> {
+ S8() {}
+
+public:
+ S8(int v) : S7<S>(v){
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(a) private(this->a) private(S7<S>::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S8 &operator=(S8 &s) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(a) private(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp distribute parallel for private(this->a) private(this->a) private(this->S7<S>::a)
+// CHECK: #pragma omp distribute parallel for private(this->a) private(this->a)
+
+template <class T, int N>
+T tmain(T argc) {
+ T b = argc, c, d, e, f, h;
+ static T a;
+// CHECK: static T a;
+ static T g;
+#pragma omp threadprivate(g)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for dist_schedule(static, a) schedule(dynamic) default(none) copyin(g) firstprivate(a)
+ // CHECK: #pragma omp distribute parallel for dist_schedule(static, a) schedule(dynamic) default(none) copyin(g)
+ for (int i = 0; i < 2; ++i)
+ a = 2;
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) if (parallel :argc) num_threads(N) default(shared) shared(e) reduction(+ : h) dist_schedule(static,N)
+ for (int i = 0; i < 2; ++i)
+ for (int j = 0; j < 2; ++j)
+ for (int j = 0; j < 2; ++j)
+ for (int j = 0; j < 2; ++j)
+ for (int j = 0; j < 2; ++j)
+ for (int i = 0; i < 2; ++i)
+ for (int j = 0; j < 2; ++j)
+ for (int j = 0; j < 2; ++j)
+ for (int j = 0; j < 2; ++j)
+ for (int j = 0; j < 2; ++j)
+ a++;
+ // CHECK: #pragma omp distribute parallel for private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) if(parallel: argc) num_threads(N) default(shared) shared(e) reduction(+: h) dist_schedule(static, N)
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: a++;
+ return T();
+}
+
+int main(int argc, char **argv) {
+ int b = argc, c, d, e, f, h;
+ static int a;
+// CHECK: static int a;
+ static float g;
+#pragma omp threadprivate(g)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a)
+ // CHECK: #pragma omp distribute parallel for schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a)
+ for (int i = 0; i < 2; ++i)
+ a = 2;
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) if (argc) num_threads(a) default(shared) shared(e) reduction(+ : h) dist_schedule(static, b)
+ for (int i = 0; i < 10; ++i)
+ for (int j = 0; j < 10; ++j)
+ a++;
+ // CHECK: #pragma omp distribute parallel for private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) if(argc) num_threads(a) default(shared) shared(e) reduction(+: h) dist_schedule(static, b)
+ // CHECK-NEXT: for (int i = 0; i < 10; ++i)
+ // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+ // CHECK-NEXT: a++;
+ return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0]));
+}
+
+#endif
diff --git a/test/OpenMP/distribute_parallel_for_collapse_messages.cpp b/test/OpenMP/distribute_parallel_for_collapse_messages.cpp
new file mode 100644
index 0000000000000..41976a69ee2c9
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_collapse_messages.cpp
@@ -0,0 +1,154 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for collapse // expected-error {{expected '(' after 'collapse'}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for collapse () // expected-error {{expected expression}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+ // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+ // expected-error@+2 2 {{expression is not an integral constant expression}}
+ // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}}
+#pragma omp distribute parallel for collapse (argc
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+ // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp distribute parallel for collapse (ST // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp distribute parallel for', but found only 1}}
+ // expected-error@+8 2 {{directive '#pragma omp distribute parallel for' cannot contain more than one 'collapse' clause}}
+ // expected-error@+7 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+6 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+4 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for collapse (foobool(argc)), collapse (true), collapse (-5)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for collapse (S) // expected-error {{'S' does not refer to a value}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#if __cplusplus <= 199711L
+ // expected-error@+6 2 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+4 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for collapse (1)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for collapse (N) // expected-error {{argument to 'collapse' clause must be a strictly positive integer value}}
+ for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for collapse (2) // expected-note {{as specified in 'collapse' clause}}
+ foo(); // expected-error {{expected 2 for loops after '#pragma omp distribute parallel for'}}
+ return argc;
+}
+
+int main(int argc, char **argv) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for collapse // expected-error {{expected '(' after 'collapse'}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for collapse () // expected-error {{expected expression}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for collapse (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'collapse' clause}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp distribute parallel for', but found only 1}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}} expected-note {{as specified in 'collapse' clause}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp distribute parallel for', but found only 1}}
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for collapse (foobool(1) > 0 ? 1 : 2)
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+8 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+6{{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+ // expected-error@+4 2 {{directive '#pragma omp distribute parallel for' cannot contain more than one 'collapse' clause}}
+ // expected-error@+3 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for collapse (foobool(argc)), collapse (true), collapse (-5)
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for collapse (S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+#if __cplusplus <= 199711L
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+4 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+5 {{statement after '#pragma omp distribute parallel for' must be a for loop}}
+ // expected-note@+3 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for collapse(collapse(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for collapse (2) // expected-note {{as specified in 'collapse' clause}}
+ foo(); // expected-error {{expected 2 for loops after '#pragma omp distribute parallel for'}}
+ // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
+ return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/distribute_parallel_for_copyin_messages.cpp b/test/OpenMP/distribute_parallel_for_copyin_messages.cpp
new file mode 100644
index 0000000000000..7d703413488df
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_copyin_messages.cpp
@@ -0,0 +1,190 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+class S2 {
+ mutable int a;
+
+public:
+ S2() : a(0) {}
+ S2 &operator=(S2 &s2) { return *this; }
+};
+class S3 {
+ int a;
+
+public:
+ S3() : a(0) {}
+ S3 &operator=(S3 &s3) { return *this; }
+};
+class S4 {
+ int a;
+ S4();
+ S4 &operator=(const S4 &s4); // expected-note 3 {{implicitly declared private here}}
+
+public:
+ S4(int v) : a(v) {}
+};
+class S5 {
+ int a;
+ S5() : a(0) {}
+ S5 &operator=(const S5 &s5) { return *this; } // expected-note 3 {{implicitly declared private here}}
+
+public:
+ S5(int v) : a(v) {}
+};
+template <class T>
+class ST {
+public:
+ static T s;
+};
+
+S2 k;
+S3 h;
+S4 l(3);
+S5 m(4);
+#pragma omp threadprivate(h, k, l, m)
+
+namespace A {
+double x;
+#pragma omp threadprivate(x)
+}
+namespace B {
+using A::x;
+}
+
+template <class T, typename S, int N>
+T tmain(T argc, S **argv) {
+ T i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for copyin // expected-error {{expected '(' after 'copyin'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for copyin( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for copyin() // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for copyin(k // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for copyin(h, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for copyin(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for copyin(l) // expected-error 2 {{'operator=' is a private member of 'S4'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for copyin(S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for copyin(argv[1]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for copyin(i) // expected-error {{copyin variable must be threadprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for copyin(m) // expected-error 2 {{'operator=' is a private member of 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for copyin(ST<int>::s, B::x) // expected-error {{copyin variable must be threadprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+}
+
+int main(int argc, char **argv) {
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for copyin // expected-error {{expected '(' after 'copyin'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for copyin( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for copyin() // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for copyin(k // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for copyin(h, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for copyin(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for copyin(l) // expected-error {{'operator=' is a private member of 'S4'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for copyin(S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for copyin(argv[1]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for copyin(i) // expected-error {{copyin variable must be threadprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for copyin(m) // expected-error {{'operator=' is a private member of 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for copyin(ST<int>::s, B::x) // expected-error {{copyin variable must be threadprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+
+ return tmain<int, char, 3>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char, 3>' requested here}}
+}
diff --git a/test/OpenMP/distribute_parallel_for_default_messages.cpp b/test/OpenMP/distribute_parallel_for_default_messages.cpp
new file mode 100644
index 0000000000000..3437bd55cf3fb
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_default_messages.cpp
@@ -0,0 +1,100 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo();
+
+template <class T, int N>
+T tmain(T argc) {
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for default // expected-error {{expected '(' after 'default'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for default(none // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) // expected-error 2 {{variable 'argc' must have explicitly specified data sharing attributes}}
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for default(shared), default(shared) // expected-error {{directive '#pragma omp distribute parallel for' cannot contain more than one 'default' clause}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for default(none)
+ for (i = 0; i < argc; ++i) // expected-error 2 {{variable 'argc' must have explicitly specified data sharing attributes}}
+ foo();
+
+#pragma omp parallel default(none)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for default(shared)
+ for (i = 0; i < argc; ++i)
+ foo();
+
+ return T();
+}
+
+int main(int argc, char **argv) {
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for default // expected-error {{expected '(' after 'default'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for default(none // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for default(shared), default(shared) // expected-error {{directive '#pragma omp distribute parallel for' cannot contain more than one 'default' clause}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for default(none)
+ for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+ foo();
+
+#pragma omp parallel default(none)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for default(shared)
+ for (i = 0; i < argc; ++i)
+ foo();
+
+ return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0])); // expected-note {{in instantiation of function template specialization 'tmain<int, 5>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<char, 1>' requested here}}
+}
diff --git a/test/OpenMP/distribute_parallel_for_dist_schedule_messages.cpp b/test/OpenMP/distribute_parallel_for_dist_schedule_messages.cpp
new file mode 100644
index 0000000000000..0f5820ed4bbb8
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_dist_schedule_messages.cpp
@@ -0,0 +1,103 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note {{declared here}}
+
+template <class T, int N>
+T tmain(T argc) {
+ T b = argc, c, d, e, f, g;
+ char ** argv;
+ static T a;
+// CHECK: static T a;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for dist_schedule // expected-error {{expected '(' after 'dist_schedule'}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for dist_schedule ( // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for dist_schedule () // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for dist_schedule (static // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for dist_schedule (static, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for dist_schedule (argc)) // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for dist_schedule (static, argc > 0 ? argv[1] : argv[2]) // expected-error2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for dist_schedule (static), dist_schedule (static, 1) // expected-error {{directive '#pragma omp distribute parallel for' cannot contain more than one 'dist_schedule' clause}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (int i = 0; i < 10; ++i) foo();
+ return T();
+}
+
+int main(int argc, char **argv) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for dist_schedule // expected-error {{expected '(' after 'dist_schedule'}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for dist_schedule ( // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for dist_schedule () // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for dist_schedule (static // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for dist_schedule (static, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for dist_schedule (argc)) // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for dist_schedule (static, argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for dist_schedule (static), dist_schedule (static, 1) // expected-error {{directive '#pragma omp distribute parallel for' cannot contain more than one 'dist_schedule' clause}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for dist_schedule (static, argv[1]=2) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+ return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0])); // expected-note {{in instantiation of function template specialization 'tmain<int, 5>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<char, 1>' requested here}}
+}
diff --git a/test/OpenMP/distribute_parallel_for_firstprivate_messages.cpp b/test/OpenMP/distribute_parallel_for_firstprivate_messages.cpp
new file mode 100644
index 0000000000000..3e288c37d42ce
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_firstprivate_messages.cpp
@@ -0,0 +1,359 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+
+public:
+ S2() : a(0) {}
+ S2(const S2 &s2) : a(s2.a) {}
+ static float S2s;
+ static const float S2sc;
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+ S3 &operator=(const S3 &s3);
+
+public:
+ S3() : a(0) {}
+ S3(const S3 &s3) : a(s3.a) {}
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 {
+ int a;
+ S4();
+ S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}}
+
+public:
+ S4(int v) : a(v) {}
+};
+class S5 {
+ int a;
+ S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}}
+
+public:
+ S5() : a(0) {}
+ S5(int v) : a(v) {}
+};
+class S6 {
+ int a;
+ S6() : a(0) {}
+
+public:
+ S6(const S6 &s6) : a(s6.a) {}
+ S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+ I e(4);
+ C g(5);
+ int i;
+ int &j = i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate() // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(argc)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp parallel
+ {
+ int v = 0;
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(i)
+ for (int k = 0; k < argc; ++k) {
+ i = k;
+ v += i;
+ }
+ }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(j)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp parallel private(i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute parallel for' directive may not be firstprivate, predetermined as private}}
+ foo();
+#pragma omp parallel reduction(+ : i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute parallel for' directive may not be firstprivate, predetermined as private}}
+ foo();
+ return 0;
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5;
+ const int da[5] = {0};
+ S4 e(4);
+ S5 g(5);
+ S3 m;
+ S6 n(2);
+ int i;
+ int &j = i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate() // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(argc)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(argv[1]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(2 * 2) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(ba) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(ca) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(da) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+ int xa;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(xa) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(S2::S2s) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(S2::S2sc) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp distribute parallel for'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(m) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be firstprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute parallel for' directive may not be firstprivate, predetermined as private}}
+ foo();
+#pragma omp parallel shared(xa)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(xa) // OK: may be firstprivate
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(j)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(n) firstprivate(n) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp parallel
+ {
+ int v = 0;
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(i)
+ for (int k = 0; k < argc; ++k) {
+ i = k;
+ v += i;
+ }
+ }
+#pragma omp parallel private(i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute parallel for' directive may not be firstprivate, predetermined as private}}
+ foo();
+#pragma omp parallel reduction(+ : i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute parallel for' directive may not be firstprivate, predetermined as private}}
+ foo();
+ static int si;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(si) // OK
+ for (i = 0; i < argc; ++i)
+ si = i + 1;
+
+ return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/distribute_parallel_for_if_messages.cpp b/test/OpenMP/distribute_parallel_for_if_messages.cpp
new file mode 100644
index 0000000000000..c864340a46bfb
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_if_messages.cpp
@@ -0,0 +1,179 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, class S> // expected-note {{declared here}}
+int tmain(T argc, S **argv) {
+ T i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if // expected-error {{expected '(' after 'if'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if () // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if (argc > 0 ? argv[1] : argv[2])
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp distribute parallel for' cannot contain more than one 'if' clause}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if (S) // expected-error {{'S' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if(argc)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if(parallel : argc)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp distribute parallel for'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp distribute parallel for' cannot contain more than one 'if' clause with 'parallel' name modifier}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if(distribute : argc) // expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp distribute parallel for'}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if // expected-error {{expected '(' after 'if'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if () // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if (argc > 0 ? argv[1] : argv[2])
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp distribute parallel for' cannot contain more than one 'if' clause}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if (S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if(parallel : argc)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp distribute parallel for'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp distribute parallel for' cannot contain more than one 'if' clause with 'parallel' name modifier}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for if(distribute : argc) // expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp distribute parallel for'}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return tmain(argc, argv);
+}
diff --git a/test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp b/test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp
new file mode 100644
index 0000000000000..745007fc48a8d
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp
@@ -0,0 +1,333 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+
+public:
+ S2() : a(0) {}
+ S2(S2 &s2) : a(s2.a) {}
+ const S2 &operator =(const S2&) const;
+ S2 &operator =(const S2&);
+ static float S2s; // expected-note {{static data member is predetermined as shared}}
+ static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+ S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}}
+
+public:
+ S3() : a(0) {}
+ S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c; // expected-note {{global variable is predetermined as shared}}
+const S3 ca[5]; // expected-note {{global variable is predetermined as shared}}
+extern const int f; // expected-note {{global variable is predetermined as shared}}
+class S4 {
+ int a;
+ S4(); // expected-note 3 {{implicitly declared private here}}
+ S4(const S4 &s4);
+
+public:
+ S4(int v) : a(v) {}
+};
+class S5 {
+ int a;
+ S5() : a(0) {} // expected-note {{implicitly declared private here}}
+
+public:
+ S5(const S5 &s5) : a(s5.a) {}
+ S5(int v) : a(v) {}
+};
+class S6 {
+ int a;
+ S6() : a(0) {}
+
+public:
+ S6(const S6 &s6) : a(s6.a) {}
+ S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+ I e(4);
+ I g(5);
+ int i;
+ int &j = i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate() // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(argc)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+
+ int v = 0;
+#pragma omp target
+#pragma omp teams
+ {
+#pragma omp distribute parallel for lastprivate(i)
+ for (int k = 0; k < argc; ++k) {
+ i = k;
+ v += i;
+ }
+ }
+#pragma omp target
+#pragma omp teams private(i)
+#pragma omp distribute parallel for lastprivate(j)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+ return 0;
+}
+
+void bar(S4 a[2]) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(a)
+ for (int i = 0; i < 2; ++i)
+ foo();
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5; // expected-note {{constant variable is predetermined as shared}}
+ const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+ S4 e(4);
+ S5 g(5);
+ S3 m;
+ S6 n(2);
+ int i;
+ int &j = i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate() // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(argc)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(argv[1]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(2 * 2) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(ba)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+ int xa;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(xa) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp distribute parallel for'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(i)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(xa)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(xa)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(j)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(n) firstprivate(n) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+ static int si;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for lastprivate(si) // OK
+ for (i = 0; i < argc; ++i)
+ si = i + 1;
+ return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/distribute_parallel_for_num_threads_messages.cpp b/test/OpenMP/distribute_parallel_for_num_threads_messages.cpp
new file mode 100644
index 0000000000000..7939514249a07
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_num_threads_messages.cpp
@@ -0,0 +1,107 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N> // expected-note {{declared here}}
+T tmain(T argc, S **argv) {
+ T i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for num_threads // expected-error {{expected '(' after 'num_threads'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for num_threads () // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for num_threads ((argc > 0) ? argv[1] : argv[2]) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp distribute parallel for' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for num_threads (S) // expected-error {{'S' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for num_threads (argc)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for num_threads (N) // expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return argc;
+}
+
+int main(int argc, char **argv) {
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for num_threads // expected-error {{expected '(' after 'num_threads'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for num_threads () // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for num_threads (argc > 0 ? argv[1] : argv[2]) // expected-error {{integral }}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp distribute parallel for' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for num_threads (S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for num_threads (num_threads(tmain<int, char, -1>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} expected-note {{in instantiation of function template specialization 'tmain<int, char, -1>' requested here}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return tmain<int, char, 3>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char, 3>' requested here}}
+}
diff --git a/test/OpenMP/distribute_parallel_for_private_messages.cpp b/test/OpenMP/distribute_parallel_for_private_messages.cpp
new file mode 100644
index 0000000000000..465357a433886
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_private_messages.cpp
@@ -0,0 +1,315 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+
+public:
+ S2() : a(0) {}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+
+public:
+ S3() : a(0) {}
+};
+const S3 ca[5];
+class S4 {
+ int a;
+ S4(); // expected-note {{implicitly declared private here}}
+
+public:
+ S4(int v) : a(v) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+};
+class S5 {
+ int a;
+ S5() : a(0) {} // expected-note {{implicitly declared private here}}
+
+public:
+ S5(int v) : a(v) {}
+ S5 &operator=(S5 &s) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S6 {
+public:
+ T a;
+
+ S6() : a(0) {}
+ S6(T v) : a(v) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+ S6 &operator=(S6 &s) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S7 : public T {
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(T v) : a(v) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(I argc, C **argv) {
+ I e(4);
+ I g(5);
+ int i;
+ int &j = i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private // expected-error {{expected '(' after 'private'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private() // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(argc)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(e, g)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp distribute parallel for'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp parallel
+ {
+ int v = 0;
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(i)
+ for (int k = 0; k < argc; ++k) {
+ i = k;
+ v += i;
+ }
+ }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(j)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+ return 0;
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ S4 e(4);
+ S5 g(5);
+ S6<float> s6(0.0) , s6_0(1.0);
+ S7<S6<float> > s7(0.0) , s7_0(1.0);
+ int i;
+ int &j = i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private // expected-error {{expected '(' after 'private'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private() // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(argc)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp distribute parallel for'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp parallel
+ {
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+ }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(j)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+ static int m;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(m)
+ for (int k = 0; k < argc; ++k)
+ m = k + 2;
+
+ s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}}
+ s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}}
+ return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
+}
+
diff --git a/test/OpenMP/distribute_parallel_for_proc_bind_messages.cpp b/test/OpenMP/distribute_parallel_for_proc_bind_messages.cpp
new file mode 100644
index 0000000000000..9898f9dc65b69
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_proc_bind_messages.cpp
@@ -0,0 +1,101 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo();
+
+template <class T, typename S, int N>
+T tmain(T argc, S **argv) {
+ T i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for proc_bind // expected-error {{expected '(' after 'proc_bind'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for proc_bind( // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for proc_bind() // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for proc_bind(master // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for proc_bind(close), proc_bind(spread) // expected-error {{directive '#pragma omp distribute parallel for' cannot contain more than one 'proc_bind' clause}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for proc_bind(x) // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for proc_bind(master)
+ for (i = 0; i < argc; ++i)
+ foo();
+
+#pragma omp parallel proc_bind(close)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for proc_bind(spread)
+ for (i = 0; i < argc; ++i)
+ foo();
+
+ return T();
+}
+
+int main(int argc, char **argv) {
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for proc_bind // expected-error {{expected '(' after 'proc_bind'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for proc_bind( // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for proc_bind() // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for proc_bind(master // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for proc_bind(close), proc_bind(spread) // expected-error {{directive '#pragma omp distribute parallel for' cannot contain more than one 'proc_bind' clause}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for proc_bind(x) // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for proc_bind(master)
+ for (i = 0; i < argc; ++i)
+ foo();
+
+#pragma omp parallel proc_bind(close)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for proc_bind(spread)
+ for (i = 0; i < argc; ++i)
+ foo();
+ return tmain<int, char, 3>(argc, argv);
+}
diff --git a/test/OpenMP/distribute_parallel_for_reduction_messages.cpp b/test/OpenMP/distribute_parallel_for_reduction_messages.cpp
new file mode 100644
index 0000000000000..f23a25e28c029
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_reduction_messages.cpp
@@ -0,0 +1,441 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+ S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}}
+
+public:
+ S2() : a(0) {}
+ S2(S2 &s2) : a(s2.a) {}
+ static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
+ static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+S2 b; // expected-note 3 {{'b' defined here}}
+const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
+class S3 {
+ int a;
+
+public:
+ int b;
+ S3() : a(0) {}
+ S3(const S3 &s3) : a(s3.a) {}
+ S3 operator+(const S3 &arg1) { return arg1; }
+};
+int operator+(const S3 &arg1, const S3 &arg2) { return 5; }
+S3 c; // expected-note 3 {{'c' defined here}}
+const S3 ca[5]; // expected-note 2 {{'ca' defined here}}
+extern const int f; // expected-note 4 {{'f' declared here}}
+class S4 {
+ int a;
+ S4(); // expected-note {{implicitly declared private here}}
+ S4(const S4 &s4);
+ S4 &operator+(const S4 &arg) { return (*this); }
+
+public:
+ S4(int v) : a(v) {}
+};
+S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; }
+class S5 {
+ int a;
+ S5() : a(0) {} // expected-note {{implicitly declared private here}}
+ S5(const S5 &s5) : a(s5.a) {}
+ S5 &operator+(const S5 &arg);
+
+public:
+ S5(int v) : a(v) {}
+};
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+#if __cplusplus >= 201103L // C++11 or later
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
+#endif
+ int a;
+
+public:
+ S6() : a(6) {}
+ operator int() { return 6; }
+} o;
+
+S3 h, k;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class T> // expected-note {{declared here}}
+T tmain(T argc) {
+ const T d = T(); // expected-note 4 {{'d' defined here}}
+ const T da[5] = {T()}; // expected-note 2 {{'da' defined here}}
+ T qa[5] = {T()};
+ T i;
+ T &j = i; // expected-note 4 {{'j' defined here}}
+ S3 &p = k; // expected-note 2 {{'p' defined here}}
+ const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}}
+ T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}}
+ T fl;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction // expected-error {{expected '(' after 'reduction'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(&& : argc)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel private(k)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel private(fl)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(+ : fl)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel reduction(* : fl)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(+ : fl)
+ for (int i = 0; i < 10; ++i)
+ foo();
+
+ return T();
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5; // expected-note 2 {{'d' defined here}}
+ const int da[5] = {0}; // expected-note {{'da' defined here}}
+ int qa[5] = {0};
+ S4 e(4);
+ S5 g(5);
+ int i;
+ int &j = i; // expected-note 2 {{'j' defined here}}
+ S3 &p = k; // expected-note 2 {{'p' defined here}}
+ const int &r = da[i]; // expected-note {{'r' defined here}}
+ int &q = qa[i]; // expected-note {{'q' defined here}}
+ float fl;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction // expected-error {{expected '(' after 'reduction'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(~ : argc) // expected-error {{expected unqualified-id}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(&& : argc)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(+ : o) // expected-error {{no viable overloaded '='}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel private(k)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel private(fl)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(+ : fl)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel reduction(* : fl)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(+ : fl)
+ for (int i = 0; i < 10; ++i)
+ foo();
+ static int m;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for reduction(+ : m) // OK
+ for (int i = 0; i < 10; ++i)
+ m++;
+
+ return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}}
+}
diff --git a/test/OpenMP/distribute_parallel_for_schedule_messages.cpp b/test/OpenMP/distribute_parallel_for_schedule_messages.cpp
new file mode 100644
index 0000000000000..6363cd7caef01
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_schedule_messages.cpp
@@ -0,0 +1,151 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule // expected-error {{expected '(' after 'schedule'}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule (runtime, 3) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule (guided argc
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-error@+3 2 {{argument to 'schedule' clause must be a strictly positive integer value}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule (static, ST // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule (dynamic, 1)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule (guided, (ST > 0) ? 1 + ST : 2)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-error@+4 2 {{directive '#pragma omp distribute parallel for' cannot contain more than one 'schedule' clause}}
+ // expected-error@+3 {{argument to 'schedule' clause must be a strictly positive integer value}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule (static, S) // expected-error {{'S' does not refer to a value}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-error@+3 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule (dynamic, 1)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule (static, N) // expected-error {{argument to 'schedule' clause must be a strictly positive integer value}}
+ for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ return argc;
+}
+
+int main(int argc, char **argv) {
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule // expected-error {{expected '(' after 'schedule'}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule (runtime, 3) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule (guided, 4 // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule (static, 2+2)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for' are ignored}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule (dynamic, foobool(1) > 0 ? 1 : 2)
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+4 2 {{directive '#pragma omp distribute parallel for' cannot contain more than one 'schedule' clause}}
+ // expected-error@+3 {{argument to 'schedule' clause must be a strictly positive integer value}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5)
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule (guided, S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+5 {{statement after '#pragma omp distribute parallel for' must be a for loop}}
+ // expected-note@+3 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+ foo();
+ // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
+ return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/distribute_parallel_for_shared_messages.cpp b/test/OpenMP/distribute_parallel_for_shared_messages.cpp
new file mode 100644
index 0000000000000..d5725e7f1b09d
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_shared_messages.cpp
@@ -0,0 +1,396 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+
+struct S1; // expected-note 2 {{declared here}}
+extern S1 a;
+class S2 {
+ mutable int a;
+public:
+ S2():a(0) { }
+ S2(S2 &s2):a(s2.a) { }
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+public:
+ S3():a(0) { }
+ S3(S3 &s3):a(s3.a) { }
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 {
+ int a;
+ S4();
+ S4(const S4 &s4);
+public:
+ S4(int v):a(v) { }
+};
+class S5 {
+ int a;
+ S5():a(0) {}
+ S5(const S5 &s5):a(s5.a) { }
+public:
+ S5(int v):a(v) { }
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note 2 {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+template <class T, typename S, int N>
+T tmain(T argc, S **argv) {
+ const int d = 5;
+ const int da[5] = { 0 };
+ S4 e(4);
+ S5 g(5);
+ int i;
+ int &j = i;
+ int acc = 0;
+ int n = 1000;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared // expected-error {{expected '(' after 'shared'}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared () // expected-error {{expected expression}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared (argc)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared (S1) // expected-error {{'S1' does not refer to a value}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared (a, b, c, d, f)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared (argv[1]) // expected-error {{expected variable name}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared(ba)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared(ca)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared(da)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared(e, g)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be shared}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(i), shared(i) // expected-error {{private variable cannot be shared}} expected-note {{defined as private}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(i), shared(i) // expected-error {{firstprivate variable cannot be shared}} expected-note {{defined as firstprivate}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(i)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared(i)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared(j)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(i)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared(i)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared(j)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+return T();
+}
+
+
+int main(int argc, char **argv) {
+ const int d = 5;
+ const int da[5] = { 0 };
+ S4 e(4);
+ S5 g(5);
+ int i;
+ int &j = i;
+ int acc = 0;
+ int n = argc;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared // expected-error {{expected '(' after 'shared'}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared () // expected-error {{expected expression}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared (argc)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared (S1) // expected-error {{'S1' does not refer to a value}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared (a, b, c, d, f)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared (argv[1]) // expected-error {{expected variable name}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared(ba)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared(ca)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared(da)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared(e, g)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be shared}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(i), shared(i) // expected-error {{private variable cannot be shared}} expected-note {{defined as private}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(i), shared(i) // expected-error {{firstprivate variable cannot be shared}} expected-note {{defined as firstprivate}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for private(i)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared(i)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared(j)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for firstprivate(i)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared(i)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for shared(j)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+return tmain<int, char, 1000>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char, 1000>' requested here}}
+}
diff --git a/test/OpenMP/distribute_parallel_for_simd_aligned_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_aligned_messages.cpp
new file mode 100644
index 0000000000000..9c9f3dda281ab
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_aligned_messages.cpp
@@ -0,0 +1,306 @@
+// RUN: %clang_cc1 -x c++ -std=c++11 -verify -fopenmp %s
+
+struct B {
+ static int ib[20]; // expected-note 0 {{'B::ib' declared here}}
+ static constexpr int bfoo() { return 8; }
+};
+namespace X {
+ B x; // expected-note {{'x' defined here}}
+};
+constexpr int bfoo() { return 4; }
+
+int **z;
+const int C1 = 1;
+const int C2 = 2;
+void test_aligned_colons(int *&rp)
+{
+ int *B = 0;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned(B:bfoo())
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'}}
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned(B:B::bfoo())
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned(z:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}}
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned(B:B::bfoo())
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned(X::x : ::z) // expected-error {{integral constant expression must have integral or unscoped enumeration type, not 'int **'}} expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'B'}}
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned(B,rp,::z: X::x) // expected-error {{integral constant expression must have integral or unscoped enumeration type, not 'B'}}
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned(::z)
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp distribute parallel for simd aligned(B::bfoo()) // expected-error {{expected variable name}}
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned(B::ib,B:C1+C2) // expected-warning {{aligned clause will be ignored because the requested alignment is not a power of 2}}
+ for (int i = 0; i < 10; ++i) ;
+}
+
+// expected-note@+1 {{'num' defined here}}
+template<int L, class T, class N> T test_template(T* arr, N num) {
+ N i;
+ T sum = (T)0;
+ T ind2 = - num * L;
+ // Negative number is passed as L.
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned(arr:L) // expected-error {{argument to 'aligned' clause must be a strictly positive integer value}}
+ for (i = 0; i < num; ++i) {
+ T cur = arr[(int)ind2];
+ ind2 += L;
+ sum += cur;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned(num:4) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+ for (i = 0; i < num; ++i);
+
+ return T();
+}
+
+template<int LEN> int test_warn() {
+ int *ind2 = 0;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned(ind2:LEN) // expected-error {{argument to 'aligned' clause must be a strictly positive integer value}}
+ for (int i = 0; i < 100; i++) {
+ ind2 += LEN;
+ }
+ return 0;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+extern S1 a; // expected-note {{'a' declared here}}
+class S2 {
+ mutable int a;
+public:
+ S2():a(0) { }
+};
+const S2 b; // expected-note 1 {{'b' defined here}}
+const S2 ba[5];
+class S3 {
+ int a;
+public:
+ S3():a(0) { }
+};
+const S3 ca[5];
+class S4 {
+ int a;
+ S4();
+public:
+ S4(int v):a(v) { }
+};
+class S5 {
+ int a;
+ S5():a(0) {}
+public:
+ S5(int v):a(v) { }
+};
+
+S3 h; // expected-note 2 {{'h' defined here}}
+#pragma omp threadprivate(h)
+
+template<class I, class C> int foomain(I argc, C **argv) {
+ I e(argc);
+ I g(argc);
+ int i; // expected-note {{declared here}} expected-note {{'i' defined here}}
+ // expected-note@+2 {{declared here}}
+ // expected-note@+1 {{reference to 'i' is not a constant expression}}
+ int &j = i;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned // expected-error {{expected '(' after 'aligned'}}
+ for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned () // expected-error {{expected expression}}
+ for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned (argc : 5) // expected-warning {{aligned clause will be ignored because the requested alignment is not a power of 2}}
+ for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned (S1) // expected-error {{'S1' does not refer to a value}}
+ for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned (argv[1]) // expected-error {{expected variable name}}
+ for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned(e, g)
+ for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned(h) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}}
+ for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned(i) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+ for (I k = 0; k < argc; ++k) ++k;
+
+ #pragma omp parallel
+ {
+ int *v = 0;
+ I i;
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute parallel for simd aligned(v:16)
+ for (I k = 0; k < argc; ++k) { i = k; v += 2; }
+ }
+ float *f;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned(f)
+ for (I k = 0; k < argc; ++k) ++k;
+
+ int v = 0;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned(f:j) // expected-note {{initializer of 'j' is not a constant expression}} expected-error {{expression is not an integral constant expression}}
+
+ for (I k = 0; k < argc; ++k) { ++k; v += j; }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned(f)
+ for (I k = 0; k < argc; ++k) ++k;
+
+ return 0;
+}
+
+// expected-note@+1 2 {{'argc' defined here}}
+int main(int argc, char **argv) {
+ double darr[100];
+ // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}}
+ test_template<-4>(darr, 4);
+ test_warn<4>(); // ok
+ // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}}
+ test_warn<0>();
+
+ int i;
+ int &j = i;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned // expected-error {{expected '(' after 'aligned'}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned () // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned (argv // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned (argc) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned (S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned (a, b) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S1'}} expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S2'}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned (argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned(h) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+ int *pargc = &argc;
+ // expected-note@+1 {{in instantiation of function template specialization 'foomain<int *, char>' requested here}}
+ foomain<int*,char>(pargc,argv);
+ return 0;
+}
+
diff --git a/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp b/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp
new file mode 100644
index 0000000000000..56809dcd8bd29
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp
@@ -0,0 +1,152 @@
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+struct S {
+ S(): a(0) {}
+ S(int v) : a(v) {}
+ int a;
+ typedef int type;
+};
+
+template <typename T>
+class S7 : public T {
+protected:
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(typename T::type v) : a(v) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(a) private(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp distribute parallel for simd private(this->a) private(this->a) private(this->S::a)
+// CHECK: #pragma omp distribute parallel for simd private(this->a) private(this->a) private(T::a)
+// CHECK: #pragma omp distribute parallel for simd private(this->a) private(this->a)
+
+class S8 : public S7<S> {
+ S8() {}
+
+public:
+ S8(int v) : S7<S>(v){
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(a) private(this->a) private(S7<S>::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S8 &operator=(S8 &s) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(a) private(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp distribute parallel for simd private(this->a) private(this->a) private(this->S7<S>::a)
+// CHECK: #pragma omp distribute parallel for simd private(this->a) private(this->a)
+
+template <class T, int N>
+T tmain(T argc) {
+ T b = argc, c, d, e, f, h;
+ static T a;
+// CHECK: static T a;
+ static T g;
+#pragma omp threadprivate(g)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd dist_schedule(static, a) schedule(dynamic) default(none) copyin(g) firstprivate(a)
+ // CHECK: #pragma omp distribute parallel for simd dist_schedule(static, a) schedule(dynamic) default(none) copyin(g)
+ for (int i = 0; i < 2; ++i)
+ a = 2;
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) if (parallel :argc) num_threads(N) default(shared) shared(e) reduction(+ : h) dist_schedule(static,N)
+ for (int i = 0; i < 2; ++i)
+ for (int j = 0; j < 2; ++j)
+ for (int j = 0; j < 2; ++j)
+ for (int j = 0; j < 2; ++j)
+ for (int j = 0; j < 2; ++j)
+ for (int i = 0; i < 2; ++i)
+ for (int j = 0; j < 2; ++j)
+ for (int j = 0; j < 2; ++j)
+ for (int j = 0; j < 2; ++j)
+ for (int j = 0; j < 2; ++j)
+ a++;
+ // CHECK: #pragma omp distribute parallel for simd private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) if(parallel: argc) num_threads(N) default(shared) shared(e) reduction(+: h) dist_schedule(static, N)
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: a++;
+ return T();
+}
+
+int main(int argc, char **argv) {
+ int b = argc, c, d, e, f, h;
+ int x[200];
+ static int a;
+// CHECK: static int a;
+ static float g;
+#pragma omp threadprivate(g)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a)
+ // CHECK: #pragma omp distribute parallel for simd schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a)
+ for (int i = 0; i < 2; ++i)
+ a = 2;
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) if (argc) num_threads(a) default(shared) shared(e) reduction(+ : h) dist_schedule(static, b)
+ for (int i = 0; i < 10; ++i)
+ for (int j = 0; j < 10; ++j)
+ a++;
+ // CHECK: #pragma omp distribute parallel for simd private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) if(argc) num_threads(a) default(shared) shared(e) reduction(+: h) dist_schedule(static, b)
+ // CHECK-NEXT: for (int i = 0; i < 10; ++i)
+ // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+ // CHECK-NEXT: a++;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned(x:8) linear(h:2) safelen(8) simdlen(8)
+ for (int i = 0; i < 100; i++)
+ for (int j = 0; j < 200; j++)
+ a += h + x[j];
+ // CHECK: #pragma omp distribute parallel for simd aligned(x: 8) linear(h: 2) safelen(8) simdlen(8)
+ // CHECK-NEXT: for (int i = 0; i < 100; i++)
+ // CHECK-NEXT: for (int j = 0; j < 200; j++)
+ // CHECK-NEXT: a += h + x[j];
+
+ return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0]));
+}
+
+#endif
diff --git a/test/OpenMP/distribute_parallel_for_simd_collapse_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_collapse_messages.cpp
new file mode 100644
index 0000000000000..8690b4aac432a
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_collapse_messages.cpp
@@ -0,0 +1,154 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse // expected-error {{expected '(' after 'collapse'}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse () // expected-error {{expected expression}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+ // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+ // expected-error@+2 2 {{expression is not an integral constant expression}}
+ // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}}
+#pragma omp distribute parallel for simd collapse (argc
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+ // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp distribute parallel for simd collapse (ST // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp distribute parallel for simd', but found only 1}}
+ // expected-error@+8 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'collapse' clause}}
+ // expected-error@+7 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+6 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+4 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse (foobool(argc)), collapse (true), collapse (-5)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse (S) // expected-error {{'S' does not refer to a value}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#if __cplusplus <= 199711L
+ // expected-error@+6 2 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+4 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse (1)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse (N) // expected-error {{argument to 'collapse' clause must be a strictly positive integer value}}
+ for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse (2) // expected-note {{as specified in 'collapse' clause}}
+ foo(); // expected-error {{expected 2 for loops after '#pragma omp distribute parallel for simd'}}
+ return argc;
+}
+
+int main(int argc, char **argv) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse // expected-error {{expected '(' after 'collapse'}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse () // expected-error {{expected expression}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'collapse' clause}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp distribute parallel for simd', but found only 1}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}} expected-note {{as specified in 'collapse' clause}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp distribute parallel for simd', but found only 1}}
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse (foobool(1) > 0 ? 1 : 2)
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+8 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+6{{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+ // expected-error@+4 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'collapse' clause}}
+ // expected-error@+3 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse (foobool(argc)), collapse (true), collapse (-5)
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse (S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+#if __cplusplus <= 199711L
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+4 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+5 {{statement after '#pragma omp distribute parallel for simd' must be a for loop}}
+ // expected-note@+3 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse(collapse(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse (2) // expected-note {{as specified in 'collapse' clause}}
+ foo(); // expected-error {{expected 2 for loops after '#pragma omp distribute parallel for simd'}}
+ // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
+ return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/distribute_parallel_for_simd_copyin_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_copyin_messages.cpp
new file mode 100644
index 0000000000000..2d1a3dc5124b8
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_copyin_messages.cpp
@@ -0,0 +1,190 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+class S2 {
+ mutable int a;
+
+public:
+ S2() : a(0) {}
+ S2 &operator=(S2 &s2) { return *this; }
+};
+class S3 {
+ int a;
+
+public:
+ S3() : a(0) {}
+ S3 &operator=(S3 &s3) { return *this; }
+};
+class S4 {
+ int a;
+ S4();
+ S4 &operator=(const S4 &s4); // expected-note 3 {{implicitly declared private here}}
+
+public:
+ S4(int v) : a(v) {}
+};
+class S5 {
+ int a;
+ S5() : a(0) {}
+ S5 &operator=(const S5 &s5) { return *this; } // expected-note 3 {{implicitly declared private here}}
+
+public:
+ S5(int v) : a(v) {}
+};
+template <class T>
+class ST {
+public:
+ static T s;
+};
+
+S2 k;
+S3 h;
+S4 l(3);
+S5 m(4);
+#pragma omp threadprivate(h, k, l, m)
+
+namespace A {
+double x;
+#pragma omp threadprivate(x)
+}
+namespace B {
+using A::x;
+}
+
+template <class T, typename S, int N>
+T tmain(T argc, S **argv) {
+ T i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd copyin // expected-error {{expected '(' after 'copyin'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd copyin( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd copyin() // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd copyin(k // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd copyin(h, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd copyin(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd copyin(l) // expected-error 2 {{'operator=' is a private member of 'S4'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd copyin(S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd copyin(argv[1]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd copyin(i) // expected-error {{copyin variable must be threadprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd copyin(m) // expected-error 2 {{'operator=' is a private member of 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd copyin(ST<int>::s, B::x) // expected-error {{copyin variable must be threadprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+}
+
+int main(int argc, char **argv) {
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd copyin // expected-error {{expected '(' after 'copyin'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd copyin( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd copyin() // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd copyin(k // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd copyin(h, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd copyin(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd copyin(l) // expected-error {{'operator=' is a private member of 'S4'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd copyin(S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd copyin(argv[1]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd copyin(i) // expected-error {{copyin variable must be threadprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd copyin(m) // expected-error {{'operator=' is a private member of 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd copyin(ST<int>::s, B::x) // expected-error {{copyin variable must be threadprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+
+ return tmain<int, char, 3>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char, 3>' requested here}}
+}
diff --git a/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp
new file mode 100644
index 0000000000000..5c32306d96d16
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp
@@ -0,0 +1,100 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo();
+
+template <class T, int N>
+T tmain(T argc) {
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd default // expected-error {{expected '(' after 'default'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd default(none // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) // expected-error 2 {{variable 'argc' must have explicitly specified data sharing attributes}}
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd default(shared), default(shared) // expected-error {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'default' clause}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd default(none)
+ for (i = 0; i < argc; ++i) // expected-error 2 {{variable 'argc' must have explicitly specified data sharing attributes}}
+ foo();
+
+#pragma omp parallel default(none)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd default(shared)
+ for (i = 0; i < argc; ++i)
+ foo();
+
+ return T();
+}
+
+int main(int argc, char **argv) {
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd default // expected-error {{expected '(' after 'default'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd default(none // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd default(shared), default(shared) // expected-error {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'default' clause}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd default(none)
+ for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+ foo();
+
+#pragma omp parallel default(none)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd default(shared)
+ for (i = 0; i < argc; ++i)
+ foo();
+
+ return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0])); // expected-note {{in instantiation of function template specialization 'tmain<int, 5>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<char, 1>' requested here}}
+}
diff --git a/test/OpenMP/distribute_parallel_for_simd_dist_schedule_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_dist_schedule_messages.cpp
new file mode 100644
index 0000000000000..2e3ee2b1d50e4
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_dist_schedule_messages.cpp
@@ -0,0 +1,103 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note {{declared here}}
+
+template <class T, int N>
+T tmain(T argc) {
+ T b = argc, c, d, e, f, g;
+ char ** argv;
+ static T a;
+// CHECK: static T a;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd dist_schedule // expected-error {{expected '(' after 'dist_schedule'}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd dist_schedule ( // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd dist_schedule () // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd dist_schedule (static // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd dist_schedule (static, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd dist_schedule (argc)) // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd dist_schedule (static, argc > 0 ? argv[1] : argv[2]) // expected-error2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd dist_schedule (static), dist_schedule (static, 1) // expected-error {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'dist_schedule' clause}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (int i = 0; i < 10; ++i) foo();
+ return T();
+}
+
+int main(int argc, char **argv) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd dist_schedule // expected-error {{expected '(' after 'dist_schedule'}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd dist_schedule ( // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd dist_schedule () // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd dist_schedule (static // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd dist_schedule (static, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd dist_schedule (argc)) // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd dist_schedule (static, argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd dist_schedule (static), dist_schedule (static, 1) // expected-error {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'dist_schedule' clause}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd dist_schedule (static, argv[1]=2) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+ return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0])); // expected-note {{in instantiation of function template specialization 'tmain<int, 5>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<char, 1>' requested here}}
+}
diff --git a/test/OpenMP/distribute_parallel_for_simd_firstprivate_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_firstprivate_messages.cpp
new file mode 100644
index 0000000000000..07d30e48312bf
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_firstprivate_messages.cpp
@@ -0,0 +1,359 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+
+public:
+ S2() : a(0) {}
+ S2(const S2 &s2) : a(s2.a) {}
+ static float S2s;
+ static const float S2sc;
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+ S3 &operator=(const S3 &s3);
+
+public:
+ S3() : a(0) {}
+ S3(const S3 &s3) : a(s3.a) {}
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 {
+ int a;
+ S4();
+ S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}}
+
+public:
+ S4(int v) : a(v) {}
+};
+class S5 {
+ int a;
+ S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}}
+
+public:
+ S5() : a(0) {}
+ S5(int v) : a(v) {}
+};
+class S6 {
+ int a;
+ S6() : a(0) {}
+
+public:
+ S6(const S6 &s6) : a(s6.a) {}
+ S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+ I e(4);
+ C g(5);
+ int i;
+ int &j = i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate() // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(argc)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp parallel
+ {
+ int v = 0;
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(i)
+ for (int k = 0; k < argc; ++k) {
+ i = k;
+ v += i;
+ }
+ }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(j)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp parallel private(i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute parallel for simd' directive may not be firstprivate, predetermined as linear}}
+ foo();
+#pragma omp parallel reduction(+ : i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute parallel for simd' directive may not be firstprivate, predetermined as linear}}
+ foo();
+ return 0;
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5;
+ const int da[5] = {0};
+ S4 e(4);
+ S5 g(5);
+ S3 m;
+ S6 n(2);
+ int i;
+ int &j = i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate() // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(argc)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(argv[1]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(2 * 2) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(ba) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(ca) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(da) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+ int xa;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(xa) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(S2::S2s) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(S2::S2sc) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd safelen(5) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(m) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be firstprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute parallel for simd' directive may not be firstprivate, predetermined as linear}}
+ foo();
+#pragma omp parallel shared(xa)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(xa) // OK: may be firstprivate
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(j)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(n) firstprivate(n) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp parallel
+ {
+ int v = 0;
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(i)
+ for (int k = 0; k < argc; ++k) {
+ i = k;
+ v += i;
+ }
+ }
+#pragma omp parallel private(i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute parallel for simd' directive may not be firstprivate, predetermined as linear}}
+ foo();
+#pragma omp parallel reduction(+ : i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute parallel for simd' directive may not be firstprivate, predetermined as linear}}
+ foo();
+ static int si;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(si) // OK
+ for (i = 0; i < argc; ++i)
+ si = i + 1;
+
+ return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/distribute_parallel_for_simd_if_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_if_messages.cpp
new file mode 100644
index 0000000000000..01236b5563aba
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_if_messages.cpp
@@ -0,0 +1,179 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, class S> // expected-note {{declared here}}
+int tmain(T argc, S **argv) {
+ T i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if // expected-error {{expected '(' after 'if'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if () // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if (argc > 0 ? argv[1] : argv[2])
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'if' clause}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if (S) // expected-error {{'S' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if(argc)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if(parallel : argc)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp distribute parallel for simd'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'if' clause with 'parallel' name modifier}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if(distribute : argc) // expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp distribute parallel for simd'}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if // expected-error {{expected '(' after 'if'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if () // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if (argc > 0 ? argv[1] : argv[2])
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'if' clause}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if (S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if(parallel : argc)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp distribute parallel for simd'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'if' clause with 'parallel' name modifier}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd if(distribute : argc) // expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp distribute parallel for simd'}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return tmain(argc, argv);
+}
diff --git a/test/OpenMP/distribute_parallel_for_simd_lastprivate_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_lastprivate_messages.cpp
new file mode 100644
index 0000000000000..109fde0577c40
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_lastprivate_messages.cpp
@@ -0,0 +1,333 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+
+public:
+ S2() : a(0) {}
+ S2(S2 &s2) : a(s2.a) {}
+ const S2 &operator =(const S2&) const;
+ S2 &operator =(const S2&);
+ static float S2s; // expected-note {{static data member is predetermined as shared}}
+ static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+ S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}}
+
+public:
+ S3() : a(0) {}
+ S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c; // expected-note {{global variable is predetermined as shared}}
+const S3 ca[5]; // expected-note {{global variable is predetermined as shared}}
+extern const int f; // expected-note {{global variable is predetermined as shared}}
+class S4 {
+ int a;
+ S4(); // expected-note 3 {{implicitly declared private here}}
+ S4(const S4 &s4);
+
+public:
+ S4(int v) : a(v) {}
+};
+class S5 {
+ int a;
+ S5() : a(0) {} // expected-note {{implicitly declared private here}}
+
+public:
+ S5(const S5 &s5) : a(s5.a) {}
+ S5(int v) : a(v) {}
+};
+class S6 {
+ int a;
+ S6() : a(0) {}
+
+public:
+ S6(const S6 &s6) : a(s6.a) {}
+ S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+ I e(4);
+ I g(5);
+ int i;
+ int &j = i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate() // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(argc)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+
+ int v = 0;
+#pragma omp target
+#pragma omp teams
+ {
+#pragma omp distribute parallel for simd lastprivate(i)
+ for (int k = 0; k < argc; ++k) {
+ i = k;
+ v += i;
+ }
+ }
+#pragma omp target
+#pragma omp teams private(i)
+#pragma omp distribute parallel for simd lastprivate(j)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+ return 0;
+}
+
+void bar(S4 a[2]) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(a)
+ for (int i = 0; i < 2; ++i)
+ foo();
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5; // expected-note {{constant variable is predetermined as shared}}
+ const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+ S4 e(4);
+ S5 g(5);
+ S3 m;
+ S6 n(2);
+ int i;
+ int &j = i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate() // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(argc)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(argv[1]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(2 * 2) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(ba)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+ int xa;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(xa) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd safelen(5) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(i) // expected-note {{defined as lastprivate}}
+ for (i = 0; i < argc; ++i) // expected-error{{loop iteration variable in the associated loop of 'omp distribute parallel for simd' directive may not be lastprivate, predetermined as linear}}
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(xa)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(xa)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(j)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(n) firstprivate(n) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+ static int si;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(si) // OK
+ for (i = 0; i < argc; ++i)
+ si = i + 1;
+ return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp
new file mode 100644
index 0000000000000..632ef066c0fac
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp
@@ -0,0 +1,338 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+namespace X {
+ int x;
+};
+
+struct B {
+ static int ib; // expected-note {{'B::ib' declared here}}
+ static int bfoo() { return 8; }
+};
+
+int bfoo() { return 4; }
+
+int z;
+const int C1 = 1;
+const int C2 = 2;
+void test_linear_colons()
+{
+ int B = 0;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear(B:bfoo())
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'}}
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear(z:B:ib) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}}
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear(B:B::bfoo())
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear(X::x : ::z)
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear(B,::z, X::x)
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear(::z)
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear(B::bfoo()) // expected-error {{expected variable name}}
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear(B::ib,B:C1+C2)
+ for (int i = 0; i < 10; ++i) ;
+}
+
+template<int L, class T, class N> T test_template(T* arr, N num) {
+ N i;
+ T sum = (T)0;
+ T ind2 = - num * L; // expected-note {{'ind2' defined here}}
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear(ind2:L) // expected-error {{argument of a linear clause should be of integral or pointer type}}
+ for (i = 0; i < num; ++i) {
+ T cur = arr[(int)ind2];
+ ind2 += L;
+ sum += cur;
+ }
+ return T();
+}
+
+template<int LEN> int test_warn() {
+ int ind2 = 0;
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp parallel for simd linear(ind2:LEN) // expected-warning {{zero linear step (ind2 should probably be const)}}
+ for (int i = 0; i < 100; i++) {
+ ind2 += LEN;
+ }
+ return ind2;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+public:
+ S2():a(0) { }
+};
+const S2 b; // expected-note 2 {{'b' defined here}}
+const S2 ba[5];
+class S3 {
+ int a;
+public:
+ S3():a(0) { }
+};
+const S3 ca[5];
+class S4 {
+ int a;
+ S4();
+public:
+ S4(int v):a(v) { }
+};
+class S5 {
+ int a;
+ S5():a(0) {}
+public:
+ S5(int v):a(v) { }
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template<class I, class C> int foomain(I argc, C **argv) {
+ I e(4);
+ I g(5);
+ int i;
+ int &j = i;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear // expected-error {{expected '(' after 'linear'}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear () // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear (argc : 5)
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear (S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear (a, b:B::ib) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear (argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear(e, g)
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear(i)
+ for (int k = 0; k < argc; ++k) ++k;
+
+ #pragma omp parallel
+ {
+ int v = 0;
+ int i;
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute parallel for simd linear(v:i)
+ for (int k = 0; k < argc; ++k) { i = k; v += i; }
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd linear(j)
+ for (int k = 0; k < argc; ++k) ++k;
+
+ int v = 0;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear(v:j)
+ for (int k = 0; k < argc; ++k) { ++k; v += j; }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear(i)
+ for (int k = 0; k < argc; ++k) ++k;
+ return 0;
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace C {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ double darr[100];
+ // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}}
+ test_template<-4>(darr, 4);
+ // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}}
+ test_warn<0>();
+
+ S4 e(4); // expected-note {{'e' defined here}}
+ S5 g(5); // expected-note {{'g' defined here}}
+ int i;
+ int &j = i;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear // expected-error {{expected '(' after 'linear'}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear () // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear (argc)
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear (S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear (a, b) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear (argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear(e, g) // expected-error {{argument of a linear clause should be of integral or pointer type, not 'S4'}} expected-error {{argument of a linear clause should be of integral or pointer type, not 'S5'}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+ #pragma omp parallel
+ {
+ int i;
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute parallel for simd linear(i)
+ for (int k = 0; k < argc; ++k) ++k;
+
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute parallel for simd linear(i : 4)
+ for (int k = 0; k < argc; ++k) { ++k; i += 4; }
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear(j)
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear(i)
+ for (int k = 0; k < argc; ++k) ++k;
+
+ foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
+ return 0;
+}
+
diff --git a/test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp
new file mode 100644
index 0000000000000..6c322e6f60be0
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp
@@ -0,0 +1,816 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s
+
+class S {
+ int a;
+ S() : a(0) {}
+
+public:
+ S(int v) : a(v) {}
+ S(const S &s) : a(s.a) {}
+};
+
+static int sii;
+// expected-note@+1 {{defined as threadprivate or thread local}}
+#pragma omp threadprivate(sii)
+static int globalii;
+
+int test_iteration_spaces() {
+ const int N = 100;
+ float a[N], b[N], c[N];
+ int ii, jj, kk;
+ float fii;
+ double dii;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; i += 1) {
+ c[i] = a[i] + b[i];
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (char i = 0; i < 10; i++) {
+ c[i] = a[i] + b[i];
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (char i = 0; i < 10; i += '\1') {
+ c[i] = a[i] + b[i];
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (long long i = 0; i < 10; i++) {
+ c[i] = a[i] + b[i];
+ }
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}}
+#pragma omp distribute parallel for simd
+ for (long long i = 0; i < 10; i += 1.5) {
+ c[i] = a[i] + b[i];
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (long long i = 0; i < 'z'; i += 1u) {
+ c[i] = a[i] + b[i];
+ }
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{variable must be of integer or random access iterator type}}
+#pragma omp distribute parallel for simd
+ for (float fi = 0; fi < 10.0; fi++) {
+ c[(int)fi] = a[(int)fi] + b[(int)fi];
+ }
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{variable must be of integer or random access iterator type}}
+#pragma omp distribute parallel for simd
+ for (double fi = 0; fi < 10.0; fi++) {
+ c[(int)fi] = a[(int)fi] + b[(int)fi];
+ }
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp distribute parallel for simd
+ for (int &ref = ii; ref < 10; ref++) {
+ }
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp distribute parallel for simd
+ for (int i; i < 10; i++)
+ c[i] = a[i];
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp distribute parallel for simd
+ for (int i = 0, j = 0; i < 10; ++i)
+ c[i] = a[i];
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp distribute parallel for simd
+ for (; ii < 10; ++ii)
+ c[ii] = a[ii];
+
+#pragma omp target
+#pragma omp teams
+// expected-warning@+3 {{expression result unused}}
+// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp distribute parallel for simd
+ for (ii + 1; ii < 10; ++ii)
+ c[ii] = a[ii];
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp distribute parallel for simd
+ for (c[ii] = 0; ii < 10; ++ii)
+ c[ii] = a[ii];
+
+#pragma omp target
+#pragma omp teams
+// Ok to skip parenthesises.
+#pragma omp distribute parallel for simd
+ for (((ii)) = 0; ii < 10; ++ii)
+ c[ii] = a[ii];
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp distribute parallel for simd
+ for (int i = 0; i; i++)
+ c[i] = a[i];
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+3 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}}
+#pragma omp distribute parallel for simd
+ for (int i = 0; jj < kk; ii++)
+ c[i] = a[i];
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp distribute parallel for simd
+ for (int i = 0; !!i; i++)
+ c[i] = a[i];
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp distribute parallel for simd
+ for (int i = 0; i != 1; i++)
+ c[i] = a[i];
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp distribute parallel for simd
+ for (int i = 0;; i++)
+ c[i] = a[i];
+
+// Ok.
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 11; i > 10; i--)
+ c[i] = a[i];
+
+// Ok.
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i)
+ c[i] = a[i];
+
+// Ok.
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (ii = 0; ii < 10; ++ii)
+ c[ii] = a[ii];
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp distribute parallel for simd
+ for (ii = 0; ii < 10; ++jj)
+ c[ii] = a[jj];
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp distribute parallel for simd
+ for (ii = 0; ii < 10; ++++ii)
+ c[ii] = a[ii];
+
+// Ok but undefined behavior (in general, cannot check that incr
+// is really loop-invariant).
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (ii = 0; ii < 10; ii = ii + ii)
+ c[ii] = a[ii];
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'float'}}
+#pragma omp distribute parallel for simd
+ for (ii = 0; ii < 10; ii = ii + 1.0f)
+ c[ii] = a[ii];
+
+// Ok - step was converted to integer type.
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (ii = 0; ii < 10; ii = ii + (int)1.1f)
+ c[ii] = a[ii];
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp distribute parallel for simd
+ for (ii = 0; ii < 10; jj = ii + 2)
+ c[ii] = a[ii];
+
+#pragma omp target
+#pragma omp teams
+// expected-warning@+3 {{relational comparison result unused}}
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp distribute parallel for simd
+ for (ii = 0; ii<10; jj> kk + 2)
+ c[ii] = a[ii];
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp distribute parallel for simd
+ for (ii = 0; ii < 10;)
+ c[ii] = a[ii];
+
+#pragma omp target
+#pragma omp teams
+// expected-warning@+3 {{expression result unused}}
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp distribute parallel for simd
+ for (ii = 0; ii < 10; !ii)
+ c[ii] = a[ii];
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp distribute parallel for simd
+ for (ii = 0; ii < 10; ii ? ++ii : ++jj)
+ c[ii] = a[ii];
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp distribute parallel for simd
+ for (ii = 0; ii < 10; ii = ii < 10)
+ c[ii] = a[ii];
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp distribute parallel for simd
+ for (ii = 0; ii < 10; ii = ii + 0)
+ c[ii] = a[ii];
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp distribute parallel for simd
+ for (ii = 0; ii < 10; ii = ii + (int)(0.8 - 0.45))
+ c[ii] = a[ii];
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp distribute parallel for simd
+ for (ii = 0; (ii) < 10; ii -= 25)
+ c[ii] = a[ii];
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp distribute parallel for simd
+ for (ii = 0; (ii < 10); ii -= 0)
+ c[ii] = a[ii];
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+#pragma omp distribute parallel for simd
+ for (ii = 0; ii > 10; (ii += 0))
+ c[ii] = a[ii];
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp distribute parallel for simd
+ for (ii = 0; ii < 10; (ii) = (1 - 1) + (ii))
+ c[ii] = a[ii];
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+#pragma omp distribute parallel for simd
+ for ((ii = 0); ii > 10; (ii -= 0))
+ c[ii] = a[ii];
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp distribute parallel for simd
+ for (ii = 0; (ii < 10); (ii -= 0))
+ c[ii] = a[ii];
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+2 {{defined as firstprivate}}
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp distribute parallel for simd' directive may not be firstprivate, predetermined as linear}}
+#pragma omp distribute parallel for simd firstprivate(ii)
+ for (ii = 0; ii < 10; ii++)
+ c[ii] = a[ii];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear(ii)
+ for (ii = 0; ii < 10; ii++)
+ c[ii] = a[ii];
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+2 {{defined as private}}
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp distribute parallel for simd' directive may not be private, predetermined as linear}}
+#pragma omp distribute parallel for simd private(ii)
+ for (ii = 0; ii < 10; ii++)
+ c[ii] = a[ii];
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+2 {{defined as lastprivate}}
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp distribute parallel for simd' directive may not be lastprivate, predetermined as linear}}
+#pragma omp distribute parallel for simd lastprivate(ii)
+ for (ii = 0; ii < 10; ii++)
+ c[ii] = a[ii];
+
+ {
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp distribute parallel for simd' directive may not be threadprivate or thread local, predetermined as linear}}
+#pragma omp distribute parallel for simd
+ for (sii = 0; sii < 10; sii += 1)
+ c[sii] = a[sii];
+ }
+
+ {
+#pragma omp distribute parallel for simd
+ for (globalii = 0; globalii < 10; globalii += 1)
+ c[globalii] = a[globalii];
+ }
+
+ {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse(2)
+ for (ii = 0; ii < 10; ii += 1)
+ for (globalii = 0; globalii < 10; globalii += 1)
+ c[globalii] += a[globalii] + ii;
+ }
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{statement after '#pragma omp distribute parallel for simd' must be a for loop}}
+#pragma omp distribute parallel for simd
+ for (auto &item : a) {
+ item = item + 1;
+ }
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'i' to increase on each iteration of OpenMP for loop}}
+#pragma omp distribute parallel for simd
+ for (unsigned i = 9; i < 10; i--) {
+ c[i] = a[i] + b[i];
+ }
+
+ int(*lb)[4] = nullptr;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int(*p)[4] = lb; p < lb + 8; ++p) {
+ }
+
+#pragma omp target
+#pragma omp teams
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp distribute parallel for simd
+ for (int a{0}; a < 10; ++a) {
+ }
+
+ return 0;
+}
+
+// Iterators allowed in openmp for-loops.
+namespace std {
+struct random_access_iterator_tag {};
+template <class Iter>
+struct iterator_traits {
+ typedef typename Iter::difference_type difference_type;
+ typedef typename Iter::iterator_category iterator_category;
+};
+template <class Iter>
+typename iterator_traits<Iter>::difference_type
+distance(Iter first, Iter last) { return first - last; }
+}
+class Iter0 {
+public:
+ Iter0() {}
+ Iter0(const Iter0 &) {}
+ Iter0 operator++() { return *this; }
+ Iter0 operator--() { return *this; }
+ bool operator<(Iter0 a) { return true; }
+};
+// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'Iter0' for 1st argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'Iter0' for 1st argument}}
+int operator-(Iter0 a, Iter0 b) { return 0; }
+class Iter1 {
+public:
+ Iter1(float f = 0.0f, double d = 0.0) {}
+ Iter1(const Iter1 &) {}
+ Iter1 operator++() { return *this; }
+ Iter1 operator--() { return *this; }
+ bool operator<(Iter1 a) { return true; }
+ bool operator>=(Iter1 a) { return false; }
+};
+class GoodIter {
+public:
+ GoodIter() {}
+ GoodIter(const GoodIter &) {}
+ GoodIter(int fst, int snd) {}
+ GoodIter &operator=(const GoodIter &that) { return *this; }
+ GoodIter &operator=(const Iter0 &that) { return *this; }
+ GoodIter &operator+=(int x) { return *this; }
+ explicit GoodIter(void *) {}
+ GoodIter operator++() { return *this; }
+ GoodIter operator--() { return *this; }
+ bool operator!() { return true; }
+ bool operator<(GoodIter a) { return true; }
+ bool operator<=(GoodIter a) { return true; }
+ bool operator>=(GoodIter a) { return false; }
+ typedef int difference_type;
+ typedef std::random_access_iterator_tag iterator_category;
+};
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
+int operator-(GoodIter a, GoodIter b) { return 0; }
+// expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}}
+GoodIter operator-(GoodIter a) { return a; }
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
+GoodIter operator-(GoodIter a, int v) { return GoodIter(); }
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}}
+GoodIter operator+(GoodIter a, int v) { return GoodIter(); }
+// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'int' for 1st argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'int' for 1st argument}}
+GoodIter operator-(int v, GoodIter a) { return GoodIter(); }
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 1st argument}}
+GoodIter operator+(int v, GoodIter a) { return GoodIter(); }
+
+int test_with_random_access_iterator() {
+ GoodIter begin, end;
+ Iter0 begin0, end0;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (GoodIter I = begin; I < end; ++I)
+ ++I;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp distribute parallel for simd
+ for (GoodIter &I = begin; I < end; ++I)
+ ++I;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (GoodIter I = begin; I >= end; --I)
+ ++I;
+#pragma omp target
+#pragma omp teams
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp distribute parallel for simd
+ for (GoodIter I(begin); I < end; ++I)
+ ++I;
+#pragma omp target
+#pragma omp teams
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp distribute parallel for simd
+ for (GoodIter I(nullptr); I < end; ++I)
+ ++I;
+#pragma omp target
+#pragma omp teams
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp distribute parallel for simd
+ for (GoodIter I(0); I < end; ++I)
+ ++I;
+#pragma omp target
+#pragma omp teams
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp distribute parallel for simd
+ for (GoodIter I(1, 2); I < end; ++I)
+ ++I;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (begin = GoodIter(0); begin < end; ++begin)
+ ++begin;
+#pragma omp target
+#pragma omp teams
+// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}}
+// expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
+#pragma omp distribute parallel for simd
+ for (begin = begin0; begin < end; ++begin)
+ ++begin;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp distribute parallel for simd
+ for (++begin; begin < end; ++begin)
+ ++begin;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (begin = end; begin < end; ++begin)
+ ++begin;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+#pragma omp distribute parallel for simd
+ for (GoodIter I = begin; I - I; ++I)
+ ++I;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+#pragma omp distribute parallel for simd
+ for (GoodIter I = begin; begin < end; ++I)
+ ++I;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+#pragma omp distribute parallel for simd
+ for (GoodIter I = begin; !I; ++I)
+ ++I;
+#pragma omp target
+#pragma omp teams
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp distribute parallel for simd
+ for (GoodIter I = begin; I >= end; I = I + 1)
+ ++I;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (GoodIter I = begin; I >= end; I = I - 1)
+ ++I;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+#pragma omp distribute parallel for simd
+ for (GoodIter I = begin; I >= end; I = -I)
+ ++I;
+#pragma omp target
+#pragma omp teams
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp distribute parallel for simd
+ for (GoodIter I = begin; I >= end; I = 2 + I)
+ ++I;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+#pragma omp distribute parallel for simd
+ for (GoodIter I = begin; I >= end; I = 2 - I)
+ ++I;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{invalid operands to binary expression ('Iter0' and 'int')}}
+#pragma omp distribute parallel for simd
+ for (Iter0 I = begin0; I < end0; ++I)
+ ++I;
+#pragma omp target
+#pragma omp teams
+// Initializer is constructor without params.
+// expected-error@+3 {{invalid operands to binary expression ('Iter0' and 'int')}}
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp distribute parallel for simd
+ for (Iter0 I; I < end0; ++I)
+ ++I;
+ Iter1 begin1, end1;
+#pragma omp target
+#pragma omp teams
+// expected-error@+3 {{invalid operands to binary expression ('Iter1' and 'Iter1')}}
+// expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
+#pragma omp distribute parallel for simd
+ for (Iter1 I = begin1; I < end1; ++I)
+ ++I;
+#pragma omp target
+#pragma omp teams
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp distribute parallel for simd
+ for (Iter1 I = begin1; I >= end1; ++I)
+ ++I;
+#pragma omp target
+#pragma omp teams
+// expected-error@+5 {{invalid operands to binary expression ('Iter1' and 'float')}}
+// expected-error@+4 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
+// Initializer is constructor with all default params.
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp distribute parallel for simd
+ for (Iter1 I; I < end1; ++I) {
+ }
+ return 0;
+}
+
+template <typename IT, int ST>
+class TC {
+public:
+ int dotest_lt(IT begin, IT end) {
+#pragma omp target
+#pragma omp teams
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+#pragma omp distribute parallel for simd
+ for (IT I = begin; I < end; I = I + ST) {
+ ++I;
+ }
+#pragma omp target
+#pragma omp teams
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+#pragma omp distribute parallel for simd
+ for (IT I = begin; I <= end; I += ST) {
+ ++I;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (IT I = begin; I < end; ++I) {
+ ++I;
+ }
+ }
+
+ static IT step() {
+ return IT(ST);
+ }
+};
+template <typename IT, int ST = 0>
+int dotest_gt(IT begin, IT end) {
+#pragma omp target
+#pragma omp teams
+// expected-note@+3 2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp distribute parallel for simd
+ for (IT I = begin; I >= end; I = I + ST) {
+ ++I;
+ }
+#pragma omp target
+#pragma omp teams
+// expected-note@+3 2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp distribute parallel for simd
+ for (IT I = begin; I >= end; I += ST) {
+ ++I;
+ }
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp distribute parallel for simd
+ for (IT I = begin; I >= end; ++I) {
+ ++I;
+ }
+
+#pragma omp distribute parallel for simd
+ for (IT I = begin; I < end; I += TC<int, ST>::step()) {
+ ++I;
+ }
+}
+
+void test_with_template() {
+ GoodIter begin, end;
+ TC<GoodIter, 100> t1;
+ TC<GoodIter, -100> t2;
+ t1.dotest_lt(begin, end);
+ t2.dotest_lt(begin, end); // expected-note {{in instantiation of member function 'TC<GoodIter, -100>::dotest_lt' requested here}}
+ dotest_gt(begin, end); // expected-note {{in instantiation of function template specialization 'dotest_gt<GoodIter, 0>' requested here}}
+ dotest_gt<unsigned, -10>(0, 100); // expected-note {{in instantiation of function template specialization 'dotest_gt<unsigned int, -10>' requested here}}
+}
+
+void test_loop_break() {
+ const int N = 100;
+ float a[N], b[N], c[N];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; i++) {
+ c[i] = a[i] + b[i];
+ for (int j = 0; j < 10; ++j) {
+ if (a[i] > b[j])
+ break; // OK in nested loop
+ }
+ switch (i) {
+ case 1:
+ b[i]++;
+ break;
+ default:
+ break;
+ }
+ if (c[i] > 10)
+ break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+
+ if (c[i] > 11)
+ break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; i++) {
+ for (int j = 0; j < 10; j++) {
+ c[i] = a[i] + b[i];
+ if (c[i] > 10) {
+ if (c[i] < 20) {
+ break; // OK
+ }
+ }
+ }
+ }
+}
+
+void test_loop_eh() {
+ const int N = 100;
+ float a[N], b[N], c[N];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; i++) {
+ c[i] = a[i] + b[i];
+ try { // expected-error {{'try' statement cannot be used in OpenMP simd region}}
+ for (int j = 0; j < 10; ++j) {
+ if (a[i] > b[j])
+ throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
+ }
+ throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
+ } catch (float f) {
+ if (f > 0.1)
+ throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
+ return; // expected-error {{cannot return from OpenMP region}}
+ }
+ switch (i) {
+ case 1:
+ b[i]++;
+ break;
+ default:
+ break;
+ }
+ for (int j = 0; j < 10; j++) {
+ if (c[i] > 10)
+ throw c[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
+ }
+ }
+ if (c[9] > 10)
+ throw c[9]; // OK
+
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+ struct S {
+ void g() { throw 0; }
+ };
+ }
+}
+
+void test_loop_firstprivate_lastprivate() {
+ S s(4);
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(s) firstprivate(s)
+ for (int i = 0; i < 16; ++i)
+ ;
+}
+
+void test_ordered() {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd ordered // expected-error {{unexpected OpenMP clause 'ordered' in directive '#pragma omp distribute parallel for simd'}}
+ for (int i = 0; i < 16; ++i)
+ ;
+}
+
+void test_nowait() {
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 2 {{unexpected OpenMP clause 'nowait' in directive '#pragma omp distribute parallel for simd'}}
+#pragma omp distribute parallel for simd nowait nowait // expected-error {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'nowait' clause}}
+ for (int i = 0; i < 16; ++i)
+ ;
+}
+
diff --git a/test/OpenMP/distribute_parallel_for_simd_misc_messages.c b/test/OpenMP/distribute_parallel_for_simd_misc_messages.c
new file mode 100644
index 0000000000000..01c079e3dac13
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_misc_messages.c
@@ -0,0 +1,971 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp -verify %s
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp distribute parallel for simd'}}
+#pragma omp distribute parallel for simd
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp distribute parallel for simd'}}
+#pragma omp distribute parallel for simd foo
+
+void test_no_clause() {
+ int i;
+#pragma omp distribute parallel for simd
+ for (i = 0; i < 16; ++i)
+ ;
+
+// expected-error@+2 {{statement after '#pragma omp distribute parallel for simd' must be a for loop}}
+#pragma omp distribute parallel for simd
+ ++i;
+}
+
+void test_branch_protected_scope() {
+ int i = 0;
+L1:
+ ++i;
+
+ int x[24];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (i = 0; i < 16; ++i) {
+ if (i == 5)
+ goto L1; // expected-error {{use of undeclared label 'L1'}}
+ else if (i == 6)
+ return; // expected-error {{cannot return from OpenMP region}}
+ else if (i == 7)
+ goto L2;
+ else if (i == 8) {
+ L2:
+ x[i]++;
+ }
+ }
+
+ if (x[0] == 0)
+ goto L2; // expected-error {{use of undeclared label 'L2'}}
+ else if (x[1] == 1)
+ goto L1;
+}
+
+void test_invalid_clause() {
+ int i;
+#pragma omp target
+#pragma omp teams
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}}
+#pragma omp distribute parallel for simd foo bar
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+void test_non_identifiers() {
+ int i, x;
+
+#pragma omp target
+#pragma omp teams
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}}
+#pragma omp distribute parallel for simd;
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}}
+#pragma omp distribute parallel for simd linear(x);
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}}
+#pragma omp distribute parallel for simd private(x);
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}}
+#pragma omp distribute parallel for simd, private(x);
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+extern int foo();
+void test_safelen() {
+ int i;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected '('}}
+#pragma omp distribute parallel for simd safelen
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd safelen(
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute parallel for simd safelen()
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd safelen(,
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd safelen(, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-warning@+2 {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}}
+// expected-error@+1 {{expected '('}}
+#pragma omp distribute parallel for simd safelen 4)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd safelen(4
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd safelen(4,
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd safelen(4, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd safelen(4)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd safelen(4 4)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd safelen(4, , 4)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd safelen(4)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd safelen(4, 8)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp distribute parallel for simd safelen(2.5)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp distribute parallel for simd safelen(foo())
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}}
+#pragma omp distribute parallel for simd safelen(-5)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}}
+#pragma omp distribute parallel for simd safelen(0)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}}
+#pragma omp distribute parallel for simd safelen(5 - 5)
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+void test_simdlen() {
+ int i;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected '('}}
+#pragma omp distribute parallel for simd simdlen
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd simdlen(
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute parallel for simd simdlen()
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd simdlen(,
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd simdlen(, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-warning@+2 {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}}
+// expected-error@+1 {{expected '('}}
+#pragma omp distribute parallel for simd simdlen 4)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd simdlen(4
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd simdlen(4,
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd simdlen(4, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd simdlen(4)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd simdlen(4 4)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd simdlen(4, , 4)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd simdlen(4)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd simdlen(4, 8)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp distribute parallel for simd simdlen(2.5)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp distribute parallel for simd simdlen(foo())
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+#pragma omp distribute parallel for simd simdlen(-5)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+#pragma omp distribute parallel for simd simdlen(0)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+#pragma omp distribute parallel for simd simdlen(5 - 5)
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+void test_safelen_simdlen() {
+ int i;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}}
+#pragma omp distribute parallel for simd simdlen(6) safelen(5)
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}}
+#pragma omp distribute parallel for simd safelen(5) simdlen(6)
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+void test_collapse() {
+ int i;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected '('}}
+#pragma omp distribute parallel for simd collapse
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd collapse(
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute parallel for simd collapse()
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd collapse(,
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd collapse(, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-warning@+2 {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}}
+// expected-error@+1 {{expected '('}}
+#pragma omp distribute parallel for simd collapse 4)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp distribute parallel for simd collapse(4
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp distribute parallel for simd', but found only 1}}
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp distribute parallel for simd collapse(4,
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp distribute parallel for simd', but found only 1}}
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp distribute parallel for simd collapse(4, )
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp distribute parallel for simd', but found only 1}}
+#pragma omp target
+#pragma omp teams
+// expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp distribute parallel for simd collapse(4)
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp distribute parallel for simd', but found only 1}}
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp distribute parallel for simd collapse(4 4)
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp distribute parallel for simd', but found only 1}}
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp distribute parallel for simd collapse(4, , 4)
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp distribute parallel for simd', but found only 1}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse(4)
+ for (int i1 = 0; i1 < 16; ++i1)
+ for (int i2 = 0; i2 < 16; ++i2)
+ for (int i3 = 0; i3 < 16; ++i3)
+ for (int i4 = 0; i4 < 16; ++i4)
+ foo();
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp distribute parallel for simd collapse(4, 8)
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp distribute parallel for simd', but found only 1}}
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp distribute parallel for simd collapse(2.5)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp distribute parallel for simd collapse(foo())
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp distribute parallel for simd collapse(-5)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp distribute parallel for simd collapse(0)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp distribute parallel for simd collapse(5 - 5)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd collapse(2)
+ for (i = 0; i < 16; ++i)
+ for (int j = 0; j < 16; ++j)
+// expected-error@+1 {{OpenMP constructs may not be nested inside a simd region}}
+#pragma omp distribute parallel for simd reduction(+ : i, j)
+ for (int k = 0; k < 16; ++k)
+ i += j;
+}
+
+void test_linear() {
+ int i;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd linear(
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd linear(,
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute parallel for simd linear(, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute parallel for simd linear()
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute parallel for simd linear(int)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected variable name}}
+#pragma omp distribute parallel for simd linear(0)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{use of undeclared identifier 'x'}}
+#pragma omp distribute parallel for simd linear(x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{use of undeclared identifier 'x'}}
+// expected-error@+1 {{use of undeclared identifier 'y'}}
+#pragma omp distribute parallel for simd linear(x, y)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+3 {{use of undeclared identifier 'x'}}
+// expected-error@+2 {{use of undeclared identifier 'y'}}
+// expected-error@+1 {{use of undeclared identifier 'z'}}
+#pragma omp distribute parallel for simd linear(x, y, z)
+ for (i = 0; i < 16; ++i)
+ ;
+
+ int x, y;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute parallel for simd linear(x :)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd linear(x :, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear(x : 1)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd linear(x : 2 * 2)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd linear(x : 1, y)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd linear(x : 1, y, z : 1)
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+2 {{defined as linear}}
+// expected-error@+1 {{linear variable cannot be linear}}
+#pragma omp distribute parallel for simd linear(x) linear(x)
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+2 {{defined as private}}
+// expected-error@+1 {{private variable cannot be linear}}
+#pragma omp distribute parallel for simd private(x) linear(x)
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+2 {{defined as linear}}
+// expected-error@+1 {{linear variable cannot be private}}
+#pragma omp distribute parallel for simd linear(x) private(x)
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-warning@+1 {{zero linear step (x and other variables in clause should probably be const)}}
+#pragma omp distribute parallel for simd linear(x, y : 0)
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+2 {{defined as linear}}
+// expected-error@+1 {{linear variable cannot be lastprivate}}
+#pragma omp distribute parallel for simd linear(x) lastprivate(x)
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+2 {{defined as lastprivate}}
+// expected-error@+1 {{lastprivate variable cannot be linear}}
+#pragma omp distribute parallel for simd lastprivate(x) linear(x)
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+void test_aligned() {
+ int i;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd aligned(
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd aligned(,
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute parallel for simd aligned(, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute parallel for simd aligned()
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute parallel for simd aligned(int)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected variable name}}
+#pragma omp distribute parallel for simd aligned(0)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{use of undeclared identifier 'x'}}
+#pragma omp distribute parallel for simd aligned(x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{use of undeclared identifier 'x'}}
+// expected-error@+1 {{use of undeclared identifier 'y'}}
+#pragma omp distribute parallel for simd aligned(x, y)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+3 {{use of undeclared identifier 'x'}}
+// expected-error@+2 {{use of undeclared identifier 'y'}}
+// expected-error@+1 {{use of undeclared identifier 'z'}}
+#pragma omp distribute parallel for simd aligned(x, y, z)
+ for (i = 0; i < 16; ++i)
+ ;
+
+ int *x, y, z[25]; // expected-note 4 {{'y' defined here}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned(x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned(z)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute parallel for simd aligned(x :)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd aligned(x :, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned(x : 1)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd aligned(x : 2 * 2)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd aligned(x : 1, y)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd aligned(x : 1, y, z : 1)
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{argument of aligned clause should be array or pointer, not 'int'}}
+#pragma omp distribute parallel for simd aligned(x, y)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{argument of aligned clause should be array or pointer, not 'int'}}
+#pragma omp distribute parallel for simd aligned(x, y, z)
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+2 {{defined as aligned}}
+// expected-error@+1 {{a variable cannot appear in more than one aligned clause}}
+#pragma omp distribute parallel for simd aligned(x) aligned(z, x)
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+3 {{defined as aligned}}
+// expected-error@+2 {{a variable cannot appear in more than one aligned clause}}
+// expected-error@+1 2 {{argument of aligned clause should be array or pointer, not 'int'}}
+#pragma omp distribute parallel for simd aligned(x, y, z) aligned(y, z)
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+
+void test_private() {
+ int i;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute parallel for simd private(
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp distribute parallel for simd private(,
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 2 {{expected expression}}
+#pragma omp distribute parallel for simd private(, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute parallel for simd private()
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute parallel for simd private(int)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected variable name}}
+#pragma omp distribute parallel for simd private(0)
+ for (i = 0; i < 16; ++i)
+ ;
+
+ int x, y, z;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(x, y)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(x, y, z)
+ for (i = 0; i < 16; ++i) {
+ x = y * i + z;
+ }
+}
+
+void test_lastprivate() {
+ int i;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute parallel for simd lastprivate(
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp distribute parallel for simd lastprivate(,
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 2 {{expected expression}}
+#pragma omp distribute parallel for simd lastprivate(, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute parallel for simd lastprivate()
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute parallel for simd lastprivate(int)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected variable name}}
+#pragma omp distribute parallel for simd lastprivate(0)
+ for (i = 0; i < 16; ++i)
+ ;
+
+ int x, y, z;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(x, y)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(x, y, z)
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+void test_firstprivate() {
+ int i;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute parallel for simd firstprivate(
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp distribute parallel for simd firstprivate(,
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 2 {{expected expression}}
+#pragma omp distribute parallel for simd firstprivate(, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute parallel for simd firstprivate()
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute parallel for simd firstprivate(int)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected variable name}}
+#pragma omp distribute parallel for simd firstprivate(0)
+ for (i = 0; i < 16; ++i)
+ ;
+
+ int x, y, z;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(x) firstprivate(x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(x, y) firstprivate(x, y)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd lastprivate(x, y, z) firstprivate(x, y, z)
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+void test_loop_messages() {
+ float a[100], b[100], c[100];
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{variable must be of integer or pointer type}}
+#pragma omp distribute parallel for simd
+ for (float fi = 0; fi < 10.0; fi++) {
+ c[(int)fi] = a[(int)fi] + b[(int)fi];
+ }
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{variable must be of integer or pointer type}}
+#pragma omp distribute parallel for simd
+ for (double fi = 0; fi < 10.0; fi++) {
+ c[(int)fi] = a[(int)fi] + b[(int)fi];
+ }
+}
+
diff --git a/test/OpenMP/distribute_parallel_for_simd_num_threads_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_num_threads_messages.cpp
new file mode 100644
index 0000000000000..0d6376d76b7ba
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_num_threads_messages.cpp
@@ -0,0 +1,107 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N> // expected-note {{declared here}}
+T tmain(T argc, S **argv) {
+ T i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd num_threads // expected-error {{expected '(' after 'num_threads'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd num_threads () // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd num_threads ((argc > 0) ? argv[1] : argv[2]) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd num_threads (S) // expected-error {{'S' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd num_threads (argc)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd num_threads (N) // expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return argc;
+}
+
+int main(int argc, char **argv) {
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd num_threads // expected-error {{expected '(' after 'num_threads'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd num_threads () // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd num_threads (argc > 0 ? argv[1] : argv[2]) // expected-error {{integral }}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd num_threads (S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd num_threads (num_threads(tmain<int, char, -1>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} expected-note {{in instantiation of function template specialization 'tmain<int, char, -1>' requested here}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return tmain<int, char, 3>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char, 3>' requested here}}
+}
diff --git a/test/OpenMP/distribute_parallel_for_simd_private_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_private_messages.cpp
new file mode 100644
index 0000000000000..9df368890c8d5
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_private_messages.cpp
@@ -0,0 +1,315 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+
+public:
+ S2() : a(0) {}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+
+public:
+ S3() : a(0) {}
+};
+const S3 ca[5];
+class S4 {
+ int a;
+ S4(); // expected-note {{implicitly declared private here}}
+
+public:
+ S4(int v) : a(v) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+};
+class S5 {
+ int a;
+ S5() : a(0) {} // expected-note {{implicitly declared private here}}
+
+public:
+ S5(int v) : a(v) {}
+ S5 &operator=(S5 &s) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S6 {
+public:
+ T a;
+
+ S6() : a(0) {}
+ S6(T v) : a(v) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+ S6 &operator=(S6 &s) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S7 : public T {
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(T v) : a(v) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(I argc, C **argv) {
+ I e(4);
+ I g(5);
+ int i;
+ int &j = i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private // expected-error {{expected '(' after 'private'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private() // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(argc)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(e, g)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp distribute parallel for simd'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp parallel
+ {
+ int v = 0;
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(i)
+ for (int k = 0; k < argc; ++k) {
+ i = k;
+ v += i;
+ }
+ }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(j)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+ return 0;
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ S4 e(4);
+ S5 g(5);
+ S6<float> s6(0.0) , s6_0(1.0);
+ S7<S6<float> > s7(0.0) , s7_0(1.0);
+ int i;
+ int &j = i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private // expected-error {{expected '(' after 'private'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private() // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(argc)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp distribute parallel for simd'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp parallel
+ {
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+ }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(j)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+ static int m;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(m)
+ for (int k = 0; k < argc; ++k)
+ m = k + 2;
+
+ s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}}
+ s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}}
+ return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
+}
+
diff --git a/test/OpenMP/distribute_parallel_for_simd_proc_bind_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_proc_bind_messages.cpp
new file mode 100644
index 0000000000000..6b64cc3879ea4
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_proc_bind_messages.cpp
@@ -0,0 +1,101 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo();
+
+template <class T, typename S, int N>
+T tmain(T argc, S **argv) {
+ T i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd proc_bind // expected-error {{expected '(' after 'proc_bind'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd proc_bind( // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd proc_bind() // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd proc_bind(master // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd proc_bind(close), proc_bind(spread) // expected-error {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'proc_bind' clause}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd proc_bind(x) // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd proc_bind(master)
+ for (i = 0; i < argc; ++i)
+ foo();
+
+#pragma omp parallel proc_bind(close)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd proc_bind(spread)
+ for (i = 0; i < argc; ++i)
+ foo();
+
+ return T();
+}
+
+int main(int argc, char **argv) {
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd proc_bind // expected-error {{expected '(' after 'proc_bind'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd proc_bind( // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd proc_bind() // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd proc_bind(master // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd proc_bind(close), proc_bind(spread) // expected-error {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'proc_bind' clause}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd proc_bind(x) // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd proc_bind(master)
+ for (i = 0; i < argc; ++i)
+ foo();
+
+#pragma omp parallel proc_bind(close)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd proc_bind(spread)
+ for (i = 0; i < argc; ++i)
+ foo();
+ return tmain<int, char, 3>(argc, argv);
+}
diff --git a/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp
new file mode 100644
index 0000000000000..7b7e9ea53ccb4
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp
@@ -0,0 +1,441 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+ S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}}
+
+public:
+ S2() : a(0) {}
+ S2(S2 &s2) : a(s2.a) {}
+ static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
+ static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+S2 b; // expected-note 3 {{'b' defined here}}
+const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
+class S3 {
+ int a;
+
+public:
+ int b;
+ S3() : a(0) {}
+ S3(const S3 &s3) : a(s3.a) {}
+ S3 operator+(const S3 &arg1) { return arg1; }
+};
+int operator+(const S3 &arg1, const S3 &arg2) { return 5; }
+S3 c; // expected-note 3 {{'c' defined here}}
+const S3 ca[5]; // expected-note 2 {{'ca' defined here}}
+extern const int f; // expected-note 4 {{'f' declared here}}
+class S4 {
+ int a;
+ S4(); // expected-note {{implicitly declared private here}}
+ S4(const S4 &s4);
+ S4 &operator+(const S4 &arg) { return (*this); }
+
+public:
+ S4(int v) : a(v) {}
+};
+S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; }
+class S5 {
+ int a;
+ S5() : a(0) {} // expected-note {{implicitly declared private here}}
+ S5(const S5 &s5) : a(s5.a) {}
+ S5 &operator+(const S5 &arg);
+
+public:
+ S5(int v) : a(v) {}
+};
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+#if __cplusplus >= 201103L // C++11 or later
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
+#endif
+ int a;
+
+public:
+ S6() : a(6) {}
+ operator int() { return 6; }
+} o;
+
+S3 h, k;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class T> // expected-note {{declared here}}
+T tmain(T argc) {
+ const T d = T(); // expected-note 4 {{'d' defined here}}
+ const T da[5] = {T()}; // expected-note 2 {{'da' defined here}}
+ T qa[5] = {T()};
+ T i;
+ T &j = i; // expected-note 4 {{'j' defined here}}
+ S3 &p = k; // expected-note 2 {{'p' defined here}}
+ const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}}
+ T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}}
+ T fl;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction // expected-error {{expected '(' after 'reduction'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(&& : argc)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel private(k)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel private(fl)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(+ : fl)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel reduction(* : fl)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(+ : fl)
+ for (int i = 0; i < 10; ++i)
+ foo();
+
+ return T();
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5; // expected-note 2 {{'d' defined here}}
+ const int da[5] = {0}; // expected-note {{'da' defined here}}
+ int qa[5] = {0};
+ S4 e(4);
+ S5 g(5);
+ int i;
+ int &j = i; // expected-note 2 {{'j' defined here}}
+ S3 &p = k; // expected-note 2 {{'p' defined here}}
+ const int &r = da[i]; // expected-note {{'r' defined here}}
+ int &q = qa[i]; // expected-note {{'q' defined here}}
+ float fl;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction // expected-error {{expected '(' after 'reduction'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(~ : argc) // expected-error {{expected unqualified-id}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(&& : argc)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(+ : o) // expected-error {{no viable overloaded '='}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel private(k)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel private(fl)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(+ : fl)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel reduction(* : fl)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(+ : fl)
+ for (int i = 0; i < 10; ++i)
+ foo();
+ static int m;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd reduction(+ : m) // OK
+ for (int i = 0; i < 10; ++i)
+ m++;
+
+ return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}}
+}
diff --git a/test/OpenMP/distribute_parallel_for_simd_safelen_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_safelen_messages.cpp
new file mode 100644
index 0000000000000..a5fd1aeb8436a
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_safelen_messages.cpp
@@ -0,0 +1,177 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd safelen // expected-error {{expected '(' after 'safelen'}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd safelen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd safelen () // expected-error {{expected expression}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd safelen (argc // expected-note {{to match this '('}} expected-error 2 {{expression is not an integral constant expression}} expected-note 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} expected-error {{expected ')'}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd safelen (ST // expected-error {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd safelen (1)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd safelen ((ST > 0) ? 1 + ST : 2)
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#if __cplusplus >= 201103L
+ // expected-note@+4 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'safelen' clause}} expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{expression is not an integral constant expression}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd safelen (S) // expected-error {{'S' does not refer to a value}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#if __cplusplus <= 199711L
+ // expected-error@+6 2 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+4 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd safelen (4)
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd safelen (N) // expected-error {{argument to 'safelen' clause must be a strictly positive integer value}}
+ for (T i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+ return argc;
+}
+
+int main(int argc, char **argv) {
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd safelen // expected-error {{expected '(' after 'safelen'}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd safelen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd safelen () // expected-error {{expected expression}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd safelen (4 // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd safelen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd safelen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'safelen' clause}} expected-error {{expression is not an integral constant expression}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd safelen (S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#if __cplusplus <= 199711L
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+4 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+ // expected-note@+3 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd safelen(safelen(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+ foo(); // expected-error {{statement after '#pragma omp distribute parallel for simd' must be a for loop}}
+
+ // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 12, 4>' requested here}}
+ return tmain<int, char, 12, 4>(argc, argv);
+}
+
diff --git a/test/OpenMP/distribute_parallel_for_simd_schedule_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_schedule_messages.cpp
new file mode 100644
index 0000000000000..b3003dd9f2a1b
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_schedule_messages.cpp
@@ -0,0 +1,151 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule // expected-error {{expected '(' after 'schedule'}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule (runtime, 3) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule (guided argc
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-error@+3 2 {{argument to 'schedule' clause must be a strictly positive integer value}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule (static, ST // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule (dynamic, 1)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule (guided, (ST > 0) ? 1 + ST : 2)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-error@+4 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'schedule' clause}}
+ // expected-error@+3 {{argument to 'schedule' clause must be a strictly positive integer value}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule (static, S) // expected-error {{'S' does not refer to a value}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-error@+3 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule (dynamic, 1)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule (static, N) // expected-error {{argument to 'schedule' clause must be a strictly positive integer value}}
+ for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ return argc;
+}
+
+int main(int argc, char **argv) {
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule // expected-error {{expected '(' after 'schedule'}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule (runtime, 3) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule (guided, 4 // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule (static, 2+2)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule (dynamic, foobool(1) > 0 ? 1 : 2)
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+4 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'schedule' clause}}
+ // expected-error@+3 {{argument to 'schedule' clause must be a strictly positive integer value}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5)
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule (guided, S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ #pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+5 {{statement after '#pragma omp distribute parallel for simd' must be a for loop}}
+ // expected-note@+3 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+ foo();
+ // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
+ return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/distribute_parallel_for_simd_shared_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_shared_messages.cpp
new file mode 100644
index 0000000000000..134b852579333
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_shared_messages.cpp
@@ -0,0 +1,396 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+
+struct S1; // expected-note 2 {{declared here}}
+extern S1 a;
+class S2 {
+ mutable int a;
+public:
+ S2():a(0) { }
+ S2(S2 &s2):a(s2.a) { }
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+public:
+ S3():a(0) { }
+ S3(S3 &s3):a(s3.a) { }
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 {
+ int a;
+ S4();
+ S4(const S4 &s4);
+public:
+ S4(int v):a(v) { }
+};
+class S5 {
+ int a;
+ S5():a(0) {}
+ S5(const S5 &s5):a(s5.a) { }
+public:
+ S5(int v):a(v) { }
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note 2 {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+template <class T, typename S, int N>
+T tmain(T argc, S **argv) {
+ const int d = 5;
+ const int da[5] = { 0 };
+ S4 e(4);
+ S5 g(5);
+ int i;
+ int &j = i;
+ int acc = 0;
+ int n = 1000;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared // expected-error {{expected '(' after 'shared'}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared () // expected-error {{expected expression}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared (argc)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared (S1) // expected-error {{'S1' does not refer to a value}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared (a, b, c, d, f)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared (argv[1]) // expected-error {{expected variable name}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared(ba)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared(ca)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared(da)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared(e, g)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be shared}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(i), shared(i) // expected-error {{private variable cannot be shared}} expected-note {{defined as private}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(i), shared(i) // expected-error {{firstprivate variable cannot be shared}} expected-note {{defined as firstprivate}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(i)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared(i)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared(j)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(i)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared(i)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared(j)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+return T();
+}
+
+
+int main(int argc, char **argv) {
+ const int d = 5;
+ const int da[5] = { 0 };
+ S4 e(4);
+ S5 g(5);
+ int i;
+ int &j = i;
+ int acc = 0;
+ int n = argc;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared // expected-error {{expected '(' after 'shared'}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared () // expected-error {{expected expression}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared (argc)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared (S1) // expected-error {{'S1' does not refer to a value}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared (a, b, c, d, f)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared (argv[1]) // expected-error {{expected variable name}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared(ba)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared(ca)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared(da)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared(e, g)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be shared}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(i), shared(i) // expected-error {{private variable cannot be shared}} expected-note {{defined as private}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(i), shared(i) // expected-error {{firstprivate variable cannot be shared}} expected-note {{defined as firstprivate}}
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd private(i)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared(i)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared(j)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd firstprivate(i)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared(i)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd shared(j)
+ for(int k = 0 ; k < n ; k++) {
+ acc++;
+ }
+
+return tmain<int, char, 1000>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char, 1000>' requested here}}
+}
diff --git a/test/OpenMP/distribute_parallel_for_simd_simdlen_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_simdlen_messages.cpp
new file mode 100644
index 0000000000000..2d813ec232adc
--- /dev/null
+++ b/test/OpenMP/distribute_parallel_for_simd_simdlen_messages.cpp
@@ -0,0 +1,181 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd simdlen // expected-error {{expected '(' after 'simdlen'}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd simdlen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd simdlen () // expected-error {{expected expression}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+// expected-error@+5 {{expected ')'}} expected-note@+5 {{to match this '('}}
+// expected-error@+4 2 {{expression is not an integral constant expression}}
+// expected-note@+3 2 {{read of non-const variable 'argc' is not allowed in a constant expression}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd simdlen (argc
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+// expected-error@+3 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd simdlen (ST // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd simdlen (1)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd simdlen ((ST > 0) ? 1 + ST : 2)
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#if __cplusplus >= 201103L
+ // expected-note@+4 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5) // expected-error 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'simdlen' clause}} expected-error 2 {{argument to 'simdlen' clause must be a strictly positive integer value}} expected-error 2 {{expression is not an integral constant expression}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd simdlen (S) // expected-error {{'S' does not refer to a value}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#if __cplusplus <= 199711L
+ // expected-error@+6 2 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+4 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd simdlen (4)
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd simdlen (N) // expected-error {{argument to 'simdlen' clause must be a strictly positive integer value}}
+ for (T i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+ return argc;
+}
+
+int main(int argc, char **argv) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd simdlen // expected-error {{expected '(' after 'simdlen'}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd simdlen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd simdlen () // expected-error {{expected expression}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd simdlen (4 // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd simdlen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp distribute parallel for simd' are ignored}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd simdlen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5) // expected-error {{expression is not an integral constant expression}} expected-error 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'simdlen' clause}} expected-error 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd simdlen (S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#if __cplusplus <= 199711L
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+4 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd simdlen(simdlen(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} expected-note {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+ foo(); // expected-error {{statement after '#pragma omp distribute parallel for simd' must be a for loop}}
+
+ // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 12, 4>' requested here}}
+ return tmain<int, char, 12, 4>(argc, argv);
+}
+
diff --git a/test/OpenMP/distribute_private_messages.cpp b/test/OpenMP/distribute_private_messages.cpp
index 94ba4659c6841..518b64d9e9ca0 100644
--- a/test/OpenMP/distribute_private_messages.cpp
+++ b/test/OpenMP/distribute_private_messages.cpp
@@ -98,6 +98,7 @@ int main(int argc, char **argv) {
#pragma omp target
#pragma omp teams firstprivate(i)
#pragma omp parallel private(i)
+ {}
#pragma omp target
#pragma omp teams reduction(+:i)
#pragma omp distribute private(i)
@@ -113,20 +114,20 @@ int main(int argc, char **argv) {
#pragma omp teams
#pragma omp distribute firstprivate(i)
for (int k = 0; k < 10; ++k) {
- #pragma omp target
- #pragma omp teams firstprivate(i)
- #pragma omp distribute private(i)
- for (int x = 0; x < 10; ++x) foo();
}
#pragma omp target
+ #pragma omp teams firstprivate(i)
+ #pragma omp distribute private(i)
+ for (int x = 0; x < 10; ++x) foo();
+ #pragma omp target
#pragma omp teams reduction(+:i)
#pragma omp distribute
for (int k = 0; k < 10; ++k) {
- #pragma omp target
- #pragma omp teams reduction(+:i)
- #pragma omp distribute private(i)
- for (int x = 0; x < 10; ++x) foo();
}
+ #pragma omp target
+ #pragma omp teams reduction(+:i)
+ #pragma omp distribute private(i)
+ for (int x = 0; x < 10; ++x) foo();
return 0;
}
diff --git a/test/OpenMP/distribute_simd_aligned_messages.cpp b/test/OpenMP/distribute_simd_aligned_messages.cpp
new file mode 100644
index 0000000000000..59e5be271d0bd
--- /dev/null
+++ b/test/OpenMP/distribute_simd_aligned_messages.cpp
@@ -0,0 +1,306 @@
+// RUN: %clang_cc1 -x c++ -std=c++11 -verify -fopenmp %s
+
+struct B {
+ static int ib[20]; // expected-note 0 {{'B::ib' declared here}}
+ static constexpr int bfoo() { return 8; }
+};
+namespace X {
+ B x; // expected-note {{'x' defined here}}
+};
+constexpr int bfoo() { return 4; }
+
+int **z;
+const int C1 = 1;
+const int C2 = 2;
+void test_aligned_colons(int *&rp)
+{
+ int *B = 0;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned(B:bfoo())
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'}}
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned(B:B::bfoo())
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned(z:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}}
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned(B:B::bfoo())
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned(X::x : ::z) // expected-error {{integral constant expression must have integral or unscoped enumeration type, not 'int **'}} expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'B'}}
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned(B,rp,::z: X::x) // expected-error {{integral constant expression must have integral or unscoped enumeration type, not 'B'}}
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned(::z)
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp distribute simd aligned(B::bfoo()) // expected-error {{expected variable name}}
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned(B::ib,B:C1+C2) // expected-warning {{aligned clause will be ignored because the requested alignment is not a power of 2}}
+ for (int i = 0; i < 10; ++i) ;
+}
+
+// expected-note@+1 {{'num' defined here}}
+template<int L, class T, class N> T test_template(T* arr, N num) {
+ N i;
+ T sum = (T)0;
+ T ind2 = - num * L;
+ // Negative number is passed as L.
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned(arr:L) // expected-error {{argument to 'aligned' clause must be a strictly positive integer value}}
+ for (i = 0; i < num; ++i) {
+ T cur = arr[(int)ind2];
+ ind2 += L;
+ sum += cur;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned(num:4) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+ for (i = 0; i < num; ++i);
+
+ return T();
+}
+
+template<int LEN> int test_warn() {
+ int *ind2 = 0;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned(ind2:LEN) // expected-error {{argument to 'aligned' clause must be a strictly positive integer value}}
+ for (int i = 0; i < 100; i++) {
+ ind2 += LEN;
+ }
+ return 0;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+extern S1 a; // expected-note {{'a' declared here}}
+class S2 {
+ mutable int a;
+public:
+ S2():a(0) { }
+};
+const S2 b; // expected-note 1 {{'b' defined here}}
+const S2 ba[5];
+class S3 {
+ int a;
+public:
+ S3():a(0) { }
+};
+const S3 ca[5];
+class S4 {
+ int a;
+ S4();
+public:
+ S4(int v):a(v) { }
+};
+class S5 {
+ int a;
+ S5():a(0) {}
+public:
+ S5(int v):a(v) { }
+};
+
+S3 h; // expected-note 2 {{'h' defined here}}
+#pragma omp threadprivate(h)
+
+template<class I, class C> int foomain(I argc, C **argv) {
+ I e(argc);
+ I g(argc);
+ int i; // expected-note {{declared here}} expected-note {{'i' defined here}}
+ // expected-note@+2 {{declared here}}
+ // expected-note@+1 {{reference to 'i' is not a constant expression}}
+ int &j = i;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned // expected-error {{expected '(' after 'aligned'}}
+ for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned () // expected-error {{expected expression}}
+ for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned (argc : 5) // expected-warning {{aligned clause will be ignored because the requested alignment is not a power of 2}}
+ for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned (S1) // expected-error {{'S1' does not refer to a value}}
+ for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned (argv[1]) // expected-error {{expected variable name}}
+ for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned(e, g)
+ for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned(h) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}}
+ for (I k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned(i) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+ for (I k = 0; k < argc; ++k) ++k;
+
+ #pragma omp parallel
+ {
+ int *v = 0;
+ I i;
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd aligned(v:16)
+ for (I k = 0; k < argc; ++k) { i = k; v += 2; }
+ }
+ float *f;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned(f)
+ for (I k = 0; k < argc; ++k) ++k;
+
+ int v = 0;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned(f:j) // expected-note {{initializer of 'j' is not a constant expression}} expected-error {{expression is not an integral constant expression}}
+
+ for (I k = 0; k < argc; ++k) { ++k; v += j; }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned(f)
+ for (I k = 0; k < argc; ++k) ++k;
+
+ return 0;
+}
+
+// expected-note@+1 2 {{'argc' defined here}}
+int main(int argc, char **argv) {
+ double darr[100];
+ // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}}
+ test_template<-4>(darr, 4);
+ test_warn<4>(); // ok
+ // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}}
+ test_warn<0>();
+
+ int i;
+ int &j = i;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned // expected-error {{expected '(' after 'aligned'}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned () // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned (argv // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned (argc) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned (S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned (a, b) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S1'}} expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S2'}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned (argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned(h) // expected-error {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+ int *pargc = &argc;
+ // expected-note@+1 {{in instantiation of function template specialization 'foomain<int *, char>' requested here}}
+ foomain<int*,char>(pargc,argv);
+ return 0;
+}
+
diff --git a/test/OpenMP/distribute_simd_ast_print.cpp b/test/OpenMP/distribute_simd_ast_print.cpp
new file mode 100644
index 0000000000000..04358150b994a
--- /dev/null
+++ b/test/OpenMP/distribute_simd_ast_print.cpp
@@ -0,0 +1,146 @@
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+struct S {
+ S(): a(0) {}
+ S(int v) : a(v) {}
+ int a;
+ typedef int type;
+};
+
+template <typename T>
+class S7 : public T {
+protected:
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(typename T::type v) : a(v) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(a) private(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp distribute simd private(this->a) private(this->a) private(this->S::a)
+// CHECK: #pragma omp distribute simd private(this->a) private(this->a) private(T::a)
+// CHECK: #pragma omp distribute simd private(this->a) private(this->a)
+
+class S8 : public S7<S> {
+ S8() {}
+
+public:
+ S8(int v) : S7<S>(v){
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(a) private(this->a) private(S7<S>::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S8 &operator=(S8 &s) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(a) private(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp distribute simd private(this->a) private(this->a) private(this->S7<S>::a)
+// CHECK: #pragma omp distribute simd private(this->a) private(this->a)
+
+template <class T, int N>
+T tmain(T argc) {
+ T b = argc, c, d, e, f, h;
+ static T a;
+// CHECK: static T a;
+ static T g;
+#pragma omp threadprivate(g)
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd dist_schedule(static, a) firstprivate(a)
+ for (int i = 0; i < 2; ++i)
+ a = 2;
+// CHECK: #pragma omp distribute simd dist_schedule(static, a) firstprivate(a)
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) reduction(+ : h) dist_schedule(static,N)
+ for (int i = 0; i < 2; ++i)
+ for (int j = 0; j < 2; ++j)
+ for (int k = 0; k < 10; ++k)
+ for (int m = 0; m < 10; ++m)
+ for (int n = 0; n < 10; ++n)
+ a++;
+// CHECK: #pragma omp distribute simd private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) reduction(+: h) dist_schedule(static, N)
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: for (int j = 0; j < 2; ++j)
+// CHECK-NEXT: for (int k = 0; k < 10; ++k)
+// CHECK-NEXT: for (int m = 0; m < 10; ++m)
+// CHECK-NEXT: for (int n = 0; n < 10; ++n)
+// CHECK-NEXT: a++;
+ return T();
+}
+
+int main(int argc, char **argv) {
+ int b = argc, c, d, e, f, h;
+ int x[200];
+ static int a;
+// CHECK: static int a;
+ static float g;
+#pragma omp threadprivate(g)
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd dist_schedule(static, a) private(a)
+ for (int i = 0; i < 2; ++i)
+ a = 2;
+// CHECK: #pragma omp distribute simd dist_schedule(static, a) private(a)
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) reduction(+ : h) dist_schedule(static, b)
+ for (int i = 0; i < 10; ++i)
+ for (int j = 0; j < 10; ++j)
+ a++;
+// CHECK: #pragma omp distribute simd private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) reduction(+: h) dist_schedule(static, b)
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: for (int j = 0; j < 10; ++j)
+// CHECK-NEXT: a++;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned(x:8) linear(h:2) safelen(8) simdlen(8)
+ for (int i = 0; i < 100; i++)
+ for (int j = 0; j < 200; j++)
+ a += h + x[j];
+// CHECK: #pragma omp distribute simd aligned(x: 8) linear(h: 2) safelen(8) simdlen(8)
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK-NEXT: for (int j = 0; j < 200; j++)
+// CHECK-NEXT: a += h + x[j];
+
+ return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0]));
+}
+
+#endif
diff --git a/test/OpenMP/distribute_simd_collapse_messages.cpp b/test/OpenMP/distribute_simd_collapse_messages.cpp
new file mode 100644
index 0000000000000..182a09a92b6c8
--- /dev/null
+++ b/test/OpenMP/distribute_simd_collapse_messages.cpp
@@ -0,0 +1,154 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse // expected-error {{expected '(' after 'collapse'}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse () // expected-error {{expected expression}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+ // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+ // expected-error@+2 2 {{expression is not an integral constant expression}}
+ // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}}
+#pragma omp distribute simd collapse (argc
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+ // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp distribute simd collapse (ST // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp distribute simd' are ignored}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp distribute simd', but found only 1}}
+ // expected-error@+8 2 {{directive '#pragma omp distribute simd' cannot contain more than one 'collapse' clause}}
+ // expected-error@+7 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+6 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+4 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse (foobool(argc)), collapse (true), collapse (-5)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse (S) // expected-error {{'S' does not refer to a value}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#if __cplusplus <= 199711L
+ // expected-error@+6 2 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+4 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse (1)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse (N) // expected-error {{argument to 'collapse' clause must be a strictly positive integer value}}
+ for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse (2) // expected-note {{as specified in 'collapse' clause}}
+ foo(); // expected-error {{expected 2 for loops after '#pragma omp distribute simd'}}
+ return argc;
+}
+
+int main(int argc, char **argv) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse // expected-error {{expected '(' after 'collapse'}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse () // expected-error {{expected expression}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'collapse' clause}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp distribute simd' are ignored}} expected-note {{as specified in 'collapse' clause}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}}
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse (foobool(1) > 0 ? 1 : 2)
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+8 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+6{{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+ // expected-error@+4 2 {{directive '#pragma omp distribute simd' cannot contain more than one 'collapse' clause}}
+ // expected-error@+3 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse (foobool(argc)), collapse (true), collapse (-5)
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse (S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+#if __cplusplus <= 199711L
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+4 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+5 {{statement after '#pragma omp distribute simd' must be a for loop}}
+ // expected-note@+3 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse(collapse(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse (2) // expected-note {{as specified in 'collapse' clause}}
+ foo(); // expected-error {{expected 2 for loops after '#pragma omp distribute simd'}}
+ // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
+ return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/distribute_simd_dist_schedule_messages.cpp b/test/OpenMP/distribute_simd_dist_schedule_messages.cpp
new file mode 100644
index 0000000000000..6a8482d8be09b
--- /dev/null
+++ b/test/OpenMP/distribute_simd_dist_schedule_messages.cpp
@@ -0,0 +1,120 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note {{declared here}}
+
+template <class T, int N>
+T tmain(T argc) {
+ T b = argc, c, d, e, f, g;
+ char ** argv;
+ static T a;
+// CHECK: static T a;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd dist_schedule // expected-error {{expected '(' after 'dist_schedule'}}
+ for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd dist_schedule ( // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd dist_schedule () // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}}
+ for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd dist_schedule (static // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd dist_schedule (static, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd dist_schedule (argc)) // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-warning {{extra tokens at the end of '#pragma omp distribute simd' are ignored}}
+ for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd dist_schedule (static, argc > 0 ? argv[1] : argv[2]) // expected-error2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd dist_schedule (static), dist_schedule (static, 1) // expected-error {{directive '#pragma omp distribute simd' cannot contain more than one 'dist_schedule' clause}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 0; i < 10; ++i) foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (int i = 0; i < 10; ++i) foo();
+ return T();
+}
+
+int main(int argc, char **argv) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd dist_schedule // expected-error {{expected '(' after 'dist_schedule'}}
+ for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd dist_schedule ( // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd dist_schedule () // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}}
+ for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd dist_schedule (static // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd dist_schedule (static, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd dist_schedule (argc)) // expected-error {{expected 'static' in OpenMP clause 'dist_schedule'}} expected-warning {{extra tokens at the end of '#pragma omp distribute simd' are ignored}}
+ for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd dist_schedule (static, argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd dist_schedule (static), dist_schedule (static, 1) // expected-error {{directive '#pragma omp distribute simd' cannot contain more than one 'dist_schedule' clause}}
+ for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 0; i < 10; ++i) foo();
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd dist_schedule (static, argv[1]=2) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i) foo();
+ return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0])); // expected-note {{in instantiation of function template specialization 'tmain<int, 5>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<char, 1>' requested here}}
+}
diff --git a/test/OpenMP/distribute_simd_firstprivate_messages.cpp b/test/OpenMP/distribute_simd_firstprivate_messages.cpp
new file mode 100644
index 0000000000000..b9267a3037f0b
--- /dev/null
+++ b/test/OpenMP/distribute_simd_firstprivate_messages.cpp
@@ -0,0 +1,359 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+
+public:
+ S2() : a(0) {}
+ S2(const S2 &s2) : a(s2.a) {}
+ static float S2s;
+ static const float S2sc;
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+ S3 &operator=(const S3 &s3);
+
+public:
+ S3() : a(0) {}
+ S3(const S3 &s3) : a(s3.a) {}
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 {
+ int a;
+ S4();
+ S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}}
+
+public:
+ S4(int v) : a(v) {}
+};
+class S5 {
+ int a;
+ S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}}
+
+public:
+ S5() : a(0) {}
+ S5(int v) : a(v) {}
+};
+class S6 {
+ int a;
+ S6() : a(0) {}
+
+public:
+ S6(const S6 &s6) : a(s6.a) {}
+ S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+ I e(4);
+ C g(5);
+ int i;
+ int &j = i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate() // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(argc)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp parallel
+ {
+ int v = 0;
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(i)
+ for (int k = 0; k < argc; ++k) {
+ i = k;
+ v += i;
+ }
+ }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(j)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp parallel private(i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute simd' directive may not be firstprivate, predetermined as linear}}
+ foo();
+#pragma omp parallel reduction(+ : i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute simd' directive may not be firstprivate, predetermined as linear}}
+ foo();
+ return 0;
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5;
+ const int da[5] = {0};
+ S4 e(4);
+ S5 g(5);
+ S3 m;
+ S6 n(2);
+ int i;
+ int &j = i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate() // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(argc)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(argv[1]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(2 * 2) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(ba) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(ca) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(da) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+ int xa;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(xa) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(S2::S2s) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(S2::S2sc) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen(5) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(m) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be firstprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute simd' directive may not be firstprivate, predetermined as linear}}
+ foo();
+#pragma omp parallel shared(xa)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(xa) // OK: may be firstprivate
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(j)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(n) firstprivate(n) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp parallel
+ {
+ int v = 0;
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(i)
+ for (int k = 0; k < argc; ++k) {
+ i = k;
+ v += i;
+ }
+ }
+#pragma omp parallel private(i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute simd' directive may not be firstprivate, predetermined as linear}}
+ foo();
+#pragma omp parallel reduction(+ : i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp distribute simd' directive may not be firstprivate, predetermined as linear}}
+ foo();
+ static int si;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(si) // OK
+ for (i = 0; i < argc; ++i)
+ si = i + 1;
+
+ return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/distribute_simd_lastprivate_messages.cpp b/test/OpenMP/distribute_simd_lastprivate_messages.cpp
new file mode 100644
index 0000000000000..0f96cb4c3ec82
--- /dev/null
+++ b/test/OpenMP/distribute_simd_lastprivate_messages.cpp
@@ -0,0 +1,333 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+
+public:
+ S2() : a(0) {}
+ S2(S2 &s2) : a(s2.a) {}
+ const S2 &operator =(const S2&) const;
+ S2 &operator =(const S2&);
+ static float S2s; // expected-note {{static data member is predetermined as shared}}
+ static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+ S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}}
+
+public:
+ S3() : a(0) {}
+ S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c; // expected-note {{global variable is predetermined as shared}}
+const S3 ca[5]; // expected-note {{global variable is predetermined as shared}}
+extern const int f; // expected-note {{global variable is predetermined as shared}}
+class S4 {
+ int a;
+ S4(); // expected-note 3 {{implicitly declared private here}}
+ S4(const S4 &s4);
+
+public:
+ S4(int v) : a(v) {}
+};
+class S5 {
+ int a;
+ S5() : a(0) {} // expected-note {{implicitly declared private here}}
+
+public:
+ S5(const S5 &s5) : a(s5.a) {}
+ S5(int v) : a(v) {}
+};
+class S6 {
+ int a;
+ S6() : a(0) {}
+
+public:
+ S6(const S6 &s6) : a(s6.a) {}
+ S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+ I e(4);
+ I g(5);
+ int i;
+ int &j = i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate() // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(argc)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+
+ int v = 0;
+#pragma omp target
+#pragma omp teams
+ {
+#pragma omp distribute simd lastprivate(i)
+ for (int k = 0; k < argc; ++k) {
+ i = k;
+ v += i;
+ }
+ }
+#pragma omp target
+#pragma omp teams private(i)
+#pragma omp distribute simd lastprivate(j)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+ return 0;
+}
+
+void bar(S4 a[2]) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(a)
+ for (int i = 0; i < 2; ++i)
+ foo();
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5; // expected-note {{constant variable is predetermined as shared}}
+ const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+ S4 e(4);
+ S5 g(5);
+ S3 m;
+ S6 n(2);
+ int i;
+ int &j = i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate() // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(argc)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(argv[1]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(2 * 2) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(ba)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+ int xa;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(xa) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen(5) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(i) // expected-note {{defined as lastprivate}}
+ for (i = 0; i < argc; ++i) // expected-error{{loop iteration variable in the associated loop of 'omp distribute simd' directive may not be lastprivate, predetermined as linear}}
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(xa)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(xa)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(j)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(n) firstprivate(n) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+ static int si;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(si) // OK
+ for (i = 0; i < argc; ++i)
+ si = i + 1;
+ return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/distribute_simd_linear_messages.cpp b/test/OpenMP/distribute_simd_linear_messages.cpp
new file mode 100644
index 0000000000000..c60e0a2470710
--- /dev/null
+++ b/test/OpenMP/distribute_simd_linear_messages.cpp
@@ -0,0 +1,338 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+namespace X {
+ int x;
+};
+
+struct B {
+ static int ib; // expected-note {{'B::ib' declared here}}
+ static int bfoo() { return 8; }
+};
+
+int bfoo() { return 4; }
+
+int z;
+const int C1 = 1;
+const int C2 = 2;
+void test_linear_colons()
+{
+ int B = 0;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(B:bfoo())
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(B::ib:B:bfoo()) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'}}
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(B:ib) // expected-error {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(z:B:ib) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}}
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(B:B::bfoo())
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(X::x : ::z)
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(B,::z, X::x)
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(::z)
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(B::bfoo()) // expected-error {{expected variable name}}
+ for (int i = 0; i < 10; ++i) ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(B::ib,B:C1+C2)
+ for (int i = 0; i < 10; ++i) ;
+}
+
+template<int L, class T, class N> T test_template(T* arr, N num) {
+ N i;
+ T sum = (T)0;
+ T ind2 = - num * L; // expected-note {{'ind2' defined here}}
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(ind2:L) // expected-error {{argument of a linear clause should be of integral or pointer type}}
+ for (i = 0; i < num; ++i) {
+ T cur = arr[(int)ind2];
+ ind2 += L;
+ sum += cur;
+ }
+ return T();
+}
+
+template<int LEN> int test_warn() {
+ int ind2 = 0;
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp parallel for simd linear(ind2:LEN) // expected-warning {{zero linear step (ind2 should probably be const)}}
+ for (int i = 0; i < 100; i++) {
+ ind2 += LEN;
+ }
+ return ind2;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+public:
+ S2():a(0) { }
+};
+const S2 b; // expected-note 2 {{'b' defined here}}
+const S2 ba[5];
+class S3 {
+ int a;
+public:
+ S3():a(0) { }
+};
+const S3 ca[5];
+class S4 {
+ int a;
+ S4();
+public:
+ S4(int v):a(v) { }
+};
+class S5 {
+ int a;
+ S5():a(0) {}
+public:
+ S5(int v):a(v) { }
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template<class I, class C> int foomain(I argc, C **argv) {
+ I e(4);
+ I g(5);
+ int i;
+ int &j = i;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear // expected-error {{expected '(' after 'linear'}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear () // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear (argc : 5)
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear (S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear (a, b:B::ib) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear (argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(e, g)
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(i)
+ for (int k = 0; k < argc; ++k) ++k;
+
+ #pragma omp parallel
+ {
+ int v = 0;
+ int i;
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd linear(v:i)
+ for (int k = 0; k < argc; ++k) { i = k; v += i; }
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd linear(j)
+ for (int k = 0; k < argc; ++k) ++k;
+
+ int v = 0;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(v:j)
+ for (int k = 0; k < argc; ++k) { ++k; v += j; }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(i)
+ for (int k = 0; k < argc; ++k) ++k;
+ return 0;
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace C {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ double darr[100];
+ // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}}
+ test_template<-4>(darr, 4);
+ // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}}
+ test_warn<0>();
+
+ S4 e(4); // expected-note {{'e' defined here}}
+ S5 g(5); // expected-note {{'g' defined here}}
+ int i;
+ int &j = i;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear // expected-error {{expected '(' after 'linear'}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear () // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear (argc)
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear (S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear (a, b) // expected-error {{linear variable with incomplete type 'S1'}} expected-error {{const-qualified variable cannot be linear}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear (argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(e, g) // expected-error {{argument of a linear clause should be of integral or pointer type, not 'S4'}} expected-error {{argument of a linear clause should be of integral or pointer type, not 'S5'}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}}
+ for (int k = 0; k < argc; ++k) ++k;
+
+ #pragma omp parallel
+ {
+ int i;
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd linear(i)
+ for (int k = 0; k < argc; ++k) ++k;
+
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd linear(i : 4)
+ for (int k = 0; k < argc; ++k) { ++k; i += 4; }
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(j)
+ for (int k = 0; k < argc; ++k) ++k;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(i)
+ for (int k = 0; k < argc; ++k) ++k;
+
+ foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
+ return 0;
+}
+
diff --git a/test/OpenMP/distribute_simd_loop_messages.cpp b/test/OpenMP/distribute_simd_loop_messages.cpp
new file mode 100644
index 0000000000000..b69005578f493
--- /dev/null
+++ b/test/OpenMP/distribute_simd_loop_messages.cpp
@@ -0,0 +1,782 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s
+
+static int sii;
+// expected-note@+1 {{defined as threadprivate or thread local}}
+#pragma omp threadprivate(sii)
+static int globalii;
+
+int test_iteration_spaces() {
+ const int N = 100;
+ float a[N], b[N], c[N];
+ int ii, jj, kk;
+ float fii;
+ double dii;
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (int i = 0; i < 10; i+=1) {
+ c[i] = a[i] + b[i];
+ }
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (char i = 0; i < 10; i++) {
+ c[i] = a[i] + b[i];
+ }
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (char i = 0; i < 10; i+='\1') {
+ c[i] = a[i] + b[i];
+ }
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (long long i = 0; i < 10; i++) {
+ c[i] = a[i] + b[i];
+ }
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}}
+ #pragma omp distribute simd
+ for (long long i = 0; i < 10; i+=1.5) {
+ c[i] = a[i] + b[i];
+ }
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (long long i = 0; i < 'z'; i+=1u) {
+ c[i] = a[i] + b[i];
+ }
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{variable must be of integer or random access iterator type}}
+ #pragma omp distribute simd
+ for (float fi = 0; fi < 10.0; fi++) {
+ c[(int)fi] = a[(int)fi] + b[(int)fi];
+ }
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{variable must be of integer or random access iterator type}}
+ #pragma omp distribute simd
+ for (double fi = 0; fi < 10.0; fi++) {
+ c[(int)fi] = a[(int)fi] + b[(int)fi];
+ }
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp distribute simd
+ for (int &ref = ii; ref < 10; ref++) {
+ }
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp distribute simd
+ for (int i; i < 10; i++)
+ c[i] = a[i];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp distribute simd
+ for (int i = 0, j = 0; i < 10; ++i)
+ c[i] = a[i];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp distribute simd
+ for (;ii < 10; ++ii)
+ c[ii] = a[ii];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-warning@+3 {{expression result unused}}
+ // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp distribute simd
+ for (ii + 1;ii < 10; ++ii)
+ c[ii] = a[ii];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp distribute simd
+ for (c[ii] = 0;ii < 10; ++ii)
+ c[ii] = a[ii];
+
+ // Ok to skip parenthesises.
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (((ii)) = 0;ii < 10; ++ii)
+ c[ii] = a[ii];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+ #pragma omp distribute simd
+ for (int i = 0; i; i++)
+ c[i] = a[i];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+3 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+ // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}}
+ #pragma omp distribute simd
+ for (int i = 0; jj < kk; ii++)
+ c[i] = a[i];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+ #pragma omp distribute simd
+ for (int i = 0; !!i; i++)
+ c[i] = a[i];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+ #pragma omp distribute simd
+ for (int i = 0; i != 1; i++)
+ c[i] = a[i];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+ #pragma omp distribute simd
+ for (int i = 0; ; i++)
+ c[i] = a[i];
+
+ // Ok.
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (int i = 11; i > 10; i--)
+ c[i] = a[i];
+
+ // Ok.
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (int i = 0; i < 10; ++i)
+ c[i] = a[i];
+
+ // Ok.
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (ii = 0; ii < 10; ++ii)
+ c[ii] = a[ii];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+ #pragma omp distribute simd
+ for (ii = 0; ii < 10; ++jj)
+ c[ii] = a[jj];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+ #pragma omp distribute simd
+ for (ii = 0; ii < 10; ++ ++ ii)
+ c[ii] = a[ii];
+
+ // Ok but undefined behavior (in general, cannot check that incr
+ // is really loop-invariant).
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (ii = 0; ii < 10; ii = ii + ii)
+ c[ii] = a[ii];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'float'}}
+ #pragma omp distribute simd
+ for (ii = 0; ii < 10; ii = ii + 1.0f)
+ c[ii] = a[ii];
+
+ // Ok - step was converted to integer type.
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (ii = 0; ii < 10; ii = ii + (int)1.1f)
+ c[ii] = a[ii];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+ #pragma omp distribute simd
+ for (ii = 0; ii < 10; jj = ii + 2)
+ c[ii] = a[ii];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-warning@+3 {{relational comparison result unused}}
+ // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+ #pragma omp distribute simd
+ for (ii = 0; ii < 10; jj > kk + 2)
+ c[ii] = a[ii];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+ #pragma omp distribute simd
+ for (ii = 0; ii < 10;)
+ c[ii] = a[ii];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-warning@+3 {{expression result unused}}
+ // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+ #pragma omp distribute simd
+ for (ii = 0; ii < 10; !ii)
+ c[ii] = a[ii];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+ #pragma omp distribute simd
+ for (ii = 0; ii < 10; ii ? ++ii : ++jj)
+ c[ii] = a[ii];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+ #pragma omp distribute simd
+ for (ii = 0; ii < 10; ii = ii < 10)
+ c[ii] = a[ii];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+ // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+ #pragma omp distribute simd
+ for (ii = 0; ii < 10; ii = ii + 0)
+ c[ii] = a[ii];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+ // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+ #pragma omp distribute simd
+ for (ii = 0; ii < 10; ii = ii + (int)(0.8 - 0.45))
+ c[ii] = a[ii];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+ // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+ #pragma omp distribute simd
+ for (ii = 0; (ii) < 10; ii-=25)
+ c[ii] = a[ii];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+ // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+ #pragma omp distribute simd
+ for (ii = 0; (ii < 10); ii-=0)
+ c[ii] = a[ii];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-note@+3 {{loop step is expected to be negative due to this condition}}
+ // expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+ #pragma omp distribute simd
+ for (ii = 0; ii > 10; (ii+=0))
+ c[ii] = a[ii];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+ // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+ #pragma omp distribute simd
+ for (ii = 0; ii < 10; (ii) = (1-1)+(ii))
+ c[ii] = a[ii];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-note@+3 {{loop step is expected to be negative due to this condition}}
+ // expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+ #pragma omp distribute simd
+ for ((ii = 0); ii > 10; (ii-=0))
+ c[ii] = a[ii];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+ // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+ #pragma omp distribute simd
+ for (ii = 0; (ii < 10); (ii-=0))
+ c[ii] = a[ii];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-note@+2 {{defined as private}}
+ // expected-error@+2 {{loop iteration variable in the associated loop of 'omp distribute simd' directive may not be private, predetermined as linear}}
+ #pragma omp distribute simd private(ii)
+ for (ii = 0; ii < 10; ii++)
+ c[ii] = a[ii];
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+3 {{unexpected OpenMP clause 'shared' in directive '#pragma omp distribute simd'}}
+ // expected-note@+2 {{defined as shared}}
+ // expected-error@+2 {{loop iteration variable in the associated loop of 'omp distribute simd' directive may not be shared, predetermined as linear}}
+ #pragma omp distribute simd shared(ii)
+ for (ii = 0; ii < 10; ii++)
+ c[ii] = a[ii];
+
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd linear(ii)
+ for (ii = 0; ii < 10; ii++)
+ c[ii] = a[ii];
+
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd lastprivate(ii) linear(jj) collapse(2) // expected-note {{defined as linear}}
+ for (ii = 0; ii < 10; ii++)
+ for (jj = 0; jj < 10; jj++) // expected-error {{loop iteration variable in the associated loop of 'omp distribute simd' directive may not be linear, predetermined as lastprivate}}
+ c[ii] = a[jj];
+
+
+ #pragma omp parallel
+ {
+ #pragma omp target
+ #pragma omp teams
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp distribute simd' directive may not be threadprivate or thread local, predetermined as linear}}
+ #pragma omp distribute simd
+ for (sii = 0; sii < 10; sii+=1)
+ c[sii] = a[sii];
+ }
+
+ #pragma omp parallel
+ {
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (globalii = 0; globalii < 10; globalii+=1)
+ c[globalii] = a[globalii];
+ }
+
+ #pragma omp parallel
+ {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse(2)
+ for (ii = 0; ii < 10; ii += 1)
+ for (globalii = 0; globalii < 10; globalii += 1)
+ c[globalii] += a[globalii] + ii;
+ }
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{statement after '#pragma omp distribute simd' must be a for loop}}
+ #pragma omp distribute simd
+ for (auto &item : a) {
+ item = item + 1;
+ }
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+ // expected-error@+2 {{increment expression must cause 'i' to increase on each iteration of OpenMP for loop}}
+ #pragma omp distribute simd
+ for (unsigned i = 9; i < 10; i--) {
+ c[i] = a[i] + b[i];
+ }
+
+ int (*lb)[4] = nullptr;
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (int (*p)[4] = lb; p < lb + 8; ++p) {
+ }
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp distribute simd
+ for (int a{0}; a<10; ++a) {
+ }
+
+ return 0;
+}
+
+// Iterators allowed in openmp for-loops.
+namespace std {
+struct random_access_iterator_tag { };
+template <class Iter> struct iterator_traits {
+ typedef typename Iter::difference_type difference_type;
+ typedef typename Iter::iterator_category iterator_category;
+};
+template <class Iter>
+typename iterator_traits<Iter>::difference_type
+distance(Iter first, Iter last) { return first - last; }
+}
+class Iter0 {
+ public:
+ Iter0() { }
+ Iter0(const Iter0 &) { }
+ Iter0 operator ++() { return *this; }
+ Iter0 operator --() { return *this; }
+ Iter0 operator + (int delta) { return *this; }
+ bool operator <(Iter0 a) { return true; }
+};
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'Iter0' for 1st argument}}
+int operator -(Iter0 a, Iter0 b) { return 0; }
+class Iter1 {
+ public:
+ Iter1(float f=0.0f, double d=0.0) { }
+ Iter1(const Iter1 &) { }
+ Iter1 operator ++() { return *this; }
+ Iter1 operator --() { return *this; }
+ bool operator <(Iter1 a) { return true; }
+ bool operator >=(Iter1 a) { return false; }
+};
+class GoodIter {
+ public:
+ GoodIter() { }
+ GoodIter(const GoodIter &) { }
+ GoodIter(int fst, int snd) { }
+ GoodIter &operator =(const GoodIter &that) { return *this; }
+ GoodIter &operator =(const Iter0 &that) { return *this; }
+ GoodIter &operator +=(int x) { return *this; }
+ explicit GoodIter(void *) { }
+ GoodIter operator ++() { return *this; }
+ GoodIter operator --() { return *this; }
+ bool operator !() { return true; }
+ bool operator <(GoodIter a) { return true; }
+ bool operator <=(GoodIter a) { return true; }
+ bool operator >=(GoodIter a) { return false; }
+ typedef int difference_type;
+ typedef std::random_access_iterator_tag iterator_category;
+};
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
+int operator -(GoodIter a, GoodIter b) { return 0; }
+// expected-note@+1 2 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}}
+GoodIter operator -(GoodIter a) { return a; }
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
+GoodIter operator -(GoodIter a, int v) { return GoodIter(); }
+GoodIter operator +(GoodIter a, int v) { return GoodIter(); }
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'int' for 1st argument}}
+GoodIter operator -(int v, GoodIter a) { return GoodIter(); }
+GoodIter operator +(int v, GoodIter a) { return GoodIter(); }
+
+int test_with_random_access_iterator() {
+ GoodIter begin, end;
+ Iter0 begin0, end0;
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (GoodIter I = begin; I < end; ++I)
+ ++I;
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp distribute simd
+ for (GoodIter &I = begin; I < end; ++I)
+ ++I;
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (GoodIter I = begin; I >= end; --I)
+ ++I;
+ #pragma omp target
+ #pragma omp teams
+ // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp distribute simd
+ for (GoodIter I(begin); I < end; ++I)
+ ++I;
+ #pragma omp target
+ #pragma omp teams
+ // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp distribute simd
+ for (GoodIter I(nullptr); I < end; ++I)
+ ++I;
+ #pragma omp target
+ #pragma omp teams
+ // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp distribute simd
+ for (GoodIter I(0); I < end; ++I)
+ ++I;
+ #pragma omp target
+ #pragma omp teams
+ // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp distribute simd
+ for (GoodIter I(1,2); I < end; ++I)
+ ++I;
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (begin = GoodIter(0); begin < end; ++begin)
+ ++begin;
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (begin = GoodIter(1,2); begin < end; ++begin)
+ ++begin;
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp distribute simd
+ for (++begin; begin < end; ++begin)
+ ++begin;
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (begin = end; begin < end; ++begin)
+ ++begin;
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+ #pragma omp distribute simd
+ for (GoodIter I = begin; I - I; ++I)
+ ++I;
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+ #pragma omp distribute simd
+ for (GoodIter I = begin; begin < end; ++I)
+ ++I;
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+ #pragma omp distribute simd
+ for (GoodIter I = begin; !I; ++I)
+ ++I;
+ #pragma omp target
+ #pragma omp teams
+ // expected-note@+3 {{loop step is expected to be negative due to this condition}}
+ // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+ #pragma omp distribute simd
+ for (GoodIter I = begin; I >= end; I = I + 1)
+ ++I;
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (GoodIter I = begin; I >= end; I = I - 1)
+ ++I;
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+ #pragma omp distribute simd
+ for (GoodIter I = begin; I >= end; I = -I)
+ ++I;
+ #pragma omp target
+ #pragma omp teams
+ // expected-note@+3 {{loop step is expected to be negative due to this condition}}
+ // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+ #pragma omp distribute simd
+ for (GoodIter I = begin; I >= end; I = 2 + I)
+ ++I;
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+ #pragma omp distribute simd
+ for (GoodIter I = begin; I >= end; I = 2 - I)
+ ++I;
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (Iter0 I = begin0; I < end0; ++I)
+ ++I;
+
+ #pragma omp target
+ #pragma omp teams
+ // Initializer is constructor without params.
+ // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp distribute simd
+ for (Iter0 I; I < end0; ++I)
+ ++I;
+
+ Iter1 begin1, end1;
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+3 {{invalid operands to binary expression ('Iter1' and 'Iter1')}}
+ // expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
+ #pragma omp distribute simd
+ for (Iter1 I = begin1; I < end1; ++I)
+ ++I;
+ #pragma omp target
+ #pragma omp teams
+ // expected-note@+3 {{loop step is expected to be negative due to this condition}}
+ // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+ #pragma omp distribute simd
+ for (Iter1 I = begin1; I >= end1; ++I)
+ ++I;
+
+ // Initializer is constructor with all default params.
+ #pragma omp target
+ #pragma omp teams
+ // expected-error@+4 {{invalid operands to binary expression ('Iter1' and 'float')}}
+ // expected-error@+3 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
+ // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+ #pragma omp distribute simd
+ for (Iter1 I; I < end1; ++I) {
+ }
+
+ return 0;
+}
+
+template <typename IT, int ST> class TC {
+ public:
+ int dotest_lt(IT begin, IT end) {
+ // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+ // expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+ #pragma omp distribute simd
+ for (IT I = begin; I < end; I = I + ST) {
+ ++I;
+ }
+ #pragma omp target
+ #pragma omp teams
+ // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+ // expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+ #pragma omp distribute simd
+ for (IT I = begin; I <= end; I += ST) {
+ ++I;
+ }
+ #pragma omp distribute simd
+ for (IT I = begin; I < end; ++I) {
+ ++I;
+ }
+ }
+
+ static IT step() {
+ return IT(ST);
+ }
+};
+template <typename IT, int ST=0> int dotest_gt(IT begin, IT end) {
+ #pragma omp target
+ #pragma omp teams
+ // expected-note@+3 2 {{loop step is expected to be negative due to this condition}}
+ // expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+ #pragma omp distribute simd
+ for (IT I = begin; I >= end; I = I + ST) {
+ ++I;
+ }
+ #pragma omp target
+ #pragma omp teams
+ // expected-note@+3 2 {{loop step is expected to be negative due to this condition}}
+ // expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+ #pragma omp distribute simd
+ for (IT I = begin; I >= end; I += ST) {
+ ++I;
+ }
+
+ #pragma omp target
+ #pragma omp teams
+ // expected-note@+3 {{loop step is expected to be negative due to this condition}}
+ // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+ #pragma omp distribute simd
+ for (IT I = begin; I >= end; ++I) {
+ ++I;
+ }
+
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (IT I = begin; I < end; I+=TC<int,ST>::step()) {
+ ++I;
+ }
+}
+
+void test_with_template() {
+ GoodIter begin, end;
+ TC<GoodIter, 100> t1;
+ TC<GoodIter, -100> t2;
+ t1.dotest_lt(begin, end);
+ t2.dotest_lt(begin, end); // expected-note {{in instantiation of member function 'TC<GoodIter, -100>::dotest_lt' requested here}}
+ dotest_gt(begin, end); // expected-note {{in instantiation of function template specialization 'dotest_gt<GoodIter, 0>' requested here}}
+ dotest_gt<unsigned, -10>(0, 100); // expected-note {{in instantiation of function template specialization 'dotest_gt<unsigned int, -10>' requested here}}
+}
+
+void test_loop_break() {
+ const int N = 100;
+ float a[N], b[N], c[N];
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (int i = 0; i < 10; i++) {
+ c[i] = a[i] + b[i];
+ for (int j = 0; j < 10; ++j) {
+ if (a[i] > b[j])
+ break; // OK in nested loop
+ }
+ switch(i) {
+ case 1:
+ b[i]++;
+ break;
+ default:
+ break;
+ }
+ if (c[i] > 10)
+ break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+
+ if (c[i] > 11)
+ break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+ }
+
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (int i = 0; i < 10; i++) {
+ for (int j = 0; j < 10; j++) {
+ c[i] = a[i] + b[i];
+ if (c[i] > 10) {
+ if (c[i] < 20) {
+ break; // OK
+ }
+ }
+ }
+ }
+}
+
+void test_loop_eh() {
+ const int N = 100;
+ float a[N], b[N], c[N];
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (int i = 0; i < 10; i++) {
+ c[i] = a[i] + b[i];
+ try { // expected-error {{'try' statement cannot be used in OpenMP simd region}}
+ for (int j = 0; j < 10; ++j) {
+ if (a[i] > b[j])
+ throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
+ }
+ throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
+ }
+ catch (float f) {
+ if (f > 0.1)
+ throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
+ return; // expected-error {{cannot return from OpenMP region}}
+ }
+ switch(i) {
+ case 1:
+ b[i]++;
+ break;
+ default:
+ break;
+ }
+ for (int j = 0; j < 10; j++) {
+ if (c[i] > 10)
+ throw c[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
+ }
+ }
+ if (c[9] > 10)
+ throw c[9]; // OK
+
+ #pragma omp target
+ #pragma omp teams
+ #pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+ struct S {
+ void g() { throw 0; }
+ };
+ }
+}
+
diff --git a/test/OpenMP/distribute_simd_misc_messages.c b/test/OpenMP/distribute_simd_misc_messages.c
new file mode 100644
index 0000000000000..5fc2cb64cc62b
--- /dev/null
+++ b/test/OpenMP/distribute_simd_misc_messages.c
@@ -0,0 +1,1108 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp -verify %s
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp distribute simd'}}
+#pragma omp distribute simd
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp distribute simd'}}
+#pragma omp distribute simd foo
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp distribute simd'}}
+#pragma omp distribute simd safelen(4)
+
+void test_no_clause() {
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{statement after '#pragma omp distribute simd' must be a for loop}}
+#pragma omp distribute simd
+ ++i;
+}
+
+void test_branch_protected_scope() {
+ int i = 0;
+L1:
+ ++i;
+
+ int x[24];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (i = 0; i < 16; ++i) {
+ if (i == 5)
+ goto L1; // expected-error {{use of undeclared label 'L1'}}
+ else if (i == 6)
+ return; // expected-error {{cannot return from OpenMP region}}
+ else if (i == 7)
+ goto L2;
+ else if (i == 8) {
+ L2:
+ x[i]++;
+ }
+ }
+
+ if (x[0] == 0)
+ goto L2; // expected-error {{use of undeclared label 'L2'}}
+ else if (x[1] == 1)
+ goto L1;
+}
+
+void test_invalid_clause() {
+ int i;
+#pragma omp target
+#pragma omp teams
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp distribute simd' are ignored}}
+#pragma omp distribute simd foo bar
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+void test_non_identifiers() {
+ int i, x;
+
+#pragma omp target
+#pragma omp teams
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp distribute simd' are ignored}}
+#pragma omp distribute simd;
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp distribute simd' are ignored}}
+#pragma omp distribute simd private(x);
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp distribute simd' are ignored}}
+#pragma omp distribute simd, private(x);
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+extern int foo();
+void test_safelen() {
+ int i;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected '('}}
+#pragma omp distribute simd safelen
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd safelen(
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute simd safelen()
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd safelen(,
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd safelen(, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-warning@+2 {{extra tokens at the end of '#pragma omp distribute simd' are ignored}}
+// expected-error@+1 {{expected '('}}
+#pragma omp distribute simd safelen 4)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd safelen(4
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd safelen(4,
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd safelen(4, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// xxpected-error@+1 {{expected expression}}
+#pragma omp distribute simd safelen(4)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd safelen(4 4)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd safelen(4, , 4)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen(4)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd safelen(4, 8)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp distribute simd safelen(2.5)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp distribute simd safelen(foo())
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}}
+#pragma omp distribute simd safelen(-5)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}}
+#pragma omp distribute simd safelen(0)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}}
+#pragma omp distribute simd safelen(5 - 5)
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+void test_simdlen() {
+ int i;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected '('}}
+#pragma omp distribute simd simdlen
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd simdlen(
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute simd simdlen()
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd simdlen(,
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd simdlen(, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-warning@+2 {{extra tokens at the end of '#pragma omp distribute simd' are ignored}}
+// expected-error@+1 {{expected '('}}
+#pragma omp distribute simd simdlen 4)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd simdlen(4
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd simdlen(4,
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd simdlen(4, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd simdlen(4)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd simdlen(4 4)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd simdlen(4, , 4)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd simdlen(4)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd simdlen(4, 8)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp distribute simd simdlen(2.5)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp distribute simd simdlen(foo())
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+#pragma omp distribute simd simdlen(-5)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+#pragma omp distribute simd simdlen(0)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+#pragma omp distribute simd simdlen(5 - 5)
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+void test_safelen_simdlen() {
+ int i;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}}
+#pragma omp distribute simd simdlen(6) safelen(5)
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}}
+#pragma omp distribute simd safelen(5) simdlen(6)
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+void test_collapse() {
+ int i;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected '('}}
+#pragma omp distribute simd collapse
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd collapse(
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute simd collapse()
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd collapse(,
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd collapse(, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-warning@+2 {{extra tokens at the end of '#pragma omp distribute simd' are ignored}}
+// expected-error@+1 {{expected '('}}
+#pragma omp distribute simd collapse 4)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp distribute simd collapse(4
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}}
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp distribute simd collapse(4,
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}}
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp distribute simd collapse(4, )
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}}
+#pragma omp target
+#pragma omp teams
+// xxpected-error@+1 {{expected expression}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp distribute simd collapse(4)
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}}
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp distribute simd collapse(4 4)
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}}
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp distribute simd collapse(4, , 4)
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse(4)
+ for (int i1 = 0; i1 < 16; ++i1)
+ for (int i2 = 0; i2 < 16; ++i2)
+ for (int i3 = 0; i3 < 16; ++i3)
+ for (int i4 = 0; i4 < 16; ++i4)
+ foo();
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp distribute simd collapse(4, 8)
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}}
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp distribute simd collapse(2.5)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp distribute simd collapse(foo())
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp distribute simd collapse(-5)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp distribute simd collapse(0)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp distribute simd collapse(5 - 5)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-note@+3 {{defined as reduction}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd collapse(2) reduction(+ : i)
+ for (i = 0; i < 16; ++i)
+ // expected-note@+1 {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp for' directive into a parallel or another task region?}}
+ for (int j = 0; j < 16; ++j)
+// expected-error@+2 2 {{reduction variable must be shared}}
+// expected-error@+1 {{OpenMP constructs may not be nested inside a simd region}}
+#pragma omp for reduction(+ : i, j)
+ for (int k = 0; k < 16; ++k)
+ i += j;
+
+#pragma omp target
+#pragma omp teams
+ for (i = 0; i < 16; ++i)
+ for (int j = 0; j < 16; ++j)
+#pragma omp distribute simd reduction(+ : i, j)
+ for (int k = 0; k < 16; ++k)
+ i += j;
+}
+
+void test_linear() {
+ int i;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd linear(
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd linear(,
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute simd linear(, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute simd linear()
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute simd linear(int)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected variable name}}
+#pragma omp distribute simd linear(0)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{use of undeclared identifier 'x'}}
+#pragma omp distribute simd linear(x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{use of undeclared identifier 'x'}}
+// expected-error@+1 {{use of undeclared identifier 'y'}}
+#pragma omp distribute simd linear(x, y)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+3 {{use of undeclared identifier 'x'}}
+// expected-error@+2 {{use of undeclared identifier 'y'}}
+// expected-error@+1 {{use of undeclared identifier 'z'}}
+#pragma omp distribute simd linear(x, y, z)
+ for (i = 0; i < 16; ++i)
+ ;
+
+ int x, y;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute simd linear(x :)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd linear(x :, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(x : 1)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(x : 2 * 2)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd linear(x : 1, y)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd linear(x : 1, y, z : 1)
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+2 {{defined as linear}}
+// expected-error@+1 {{linear variable cannot be linear}}
+#pragma omp distribute simd linear(x) linear(x)
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+2 {{defined as private}}
+// expected-error@+1 {{private variable cannot be linear}}
+#pragma omp distribute simd private(x) linear(x)
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+2 {{defined as linear}}
+// expected-error@+1 {{linear variable cannot be private}}
+#pragma omp distribute simd linear(x) private(x)
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-warning@+1 {{zero linear step (x and other variables in clause should probably be const)}}
+#pragma omp distribute simd linear(x, y : 0)
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+2 {{defined as linear}}
+// expected-error@+1 {{linear variable cannot be lastprivate}}
+#pragma omp distribute simd linear(x) lastprivate(x)
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+2 {{defined as lastprivate}}
+// expected-error@+1 {{lastprivate variable cannot be linear}}
+#pragma omp distribute simd lastprivate(x) linear(x)
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+void test_aligned() {
+ int i;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd aligned(
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd aligned(,
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute simd aligned(, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute simd aligned()
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute simd aligned(int)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected variable name}}
+#pragma omp distribute simd aligned(0)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{use of undeclared identifier 'x'}}
+#pragma omp distribute simd aligned(x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{use of undeclared identifier 'x'}}
+// expected-error@+1 {{use of undeclared identifier 'y'}}
+#pragma omp distribute simd aligned(x, y)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+3 {{use of undeclared identifier 'x'}}
+// expected-error@+2 {{use of undeclared identifier 'y'}}
+// expected-error@+1 {{use of undeclared identifier 'z'}}
+#pragma omp distribute simd aligned(x, y, z)
+ for (i = 0; i < 16; ++i)
+ ;
+
+ int *x, y, z[25]; // expected-note 4 {{'y' defined here}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned(x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned(z)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute simd aligned(x :)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd aligned(x :, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned(x : 1)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd aligned(x : 2 * 2)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd aligned(x : 1, y)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd aligned(x : 1, y, z : 1)
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{argument of aligned clause should be array or pointer, not 'int'}}
+#pragma omp distribute simd aligned(x, y)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{argument of aligned clause should be array or pointer, not 'int'}}
+#pragma omp distribute simd aligned(x, y, z)
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+2 {{defined as aligned}}
+// expected-error@+1 {{a variable cannot appear in more than one aligned clause}}
+#pragma omp distribute simd aligned(x) aligned(z, x)
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-note@+3 {{defined as aligned}}
+// expected-error@+2 {{a variable cannot appear in more than one aligned clause}}
+// expected-error@+1 2 {{argument of aligned clause should be array or pointer, not 'int'}}
+#pragma omp distribute simd aligned(x, y, z) aligned(y, z)
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+void test_private() {
+ int i;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp distribute simd private(
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp distribute simd private(,
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 2 {{expected expression}}
+#pragma omp distribute simd private(, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute simd private()
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute simd private(int)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected variable name}}
+#pragma omp distribute simd private(0)
+ for (i = 0; i < 16; ++i)
+ ;
+
+ int x, y, z;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(x, y)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(x, y, z)
+ for (i = 0; i < 16; ++i) {
+ x = y * i + z;
+ }
+}
+
+void test_firstprivate() {
+ int i;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute simd firstprivate(
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+void test_lastprivate() {
+ int i;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute simd lastprivate(
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp distribute simd lastprivate(,
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 2 {{expected expression}}
+#pragma omp distribute simd lastprivate(, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute simd lastprivate()
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute simd lastprivate(int)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected variable name}}
+#pragma omp distribute simd lastprivate(0)
+ for (i = 0; i < 16; ++i)
+ ;
+
+ int x, y, z;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(x, y)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd lastprivate(x, y, z)
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+void test_reduction() {
+ int i, x, y;
+#pragma omp target
+#pragma omp teams
+// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+// expected-error@+2 {{expected identifier}}
+// expected-warning@+1 {{missing ':' after reduction identifier - ignoring}}
+#pragma omp distribute simd reduction(
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected identifier}}
+// expected-warning@+1 {{missing ':' after reduction identifier - ignoring}}
+#pragma omp distribute simd reduction()
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{expected expression}}
+// expected-warning@+1 {{missing ':' after reduction identifier - ignoring}}
+#pragma omp distribute simd reduction(x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected identifier}}
+#pragma omp distribute simd reduction( : x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+// expected-error@+2 {{expected identifier}}
+// expected-warning@+1 {{missing ':' after reduction identifier - ignoring}}
+#pragma omp distribute simd reduction(,
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+// expected-error@+2 {{expected expression}}
+// expected-warning@+1 {{missing ':' after reduction identifier - ignoring}}
+#pragma omp distribute simd reduction(+
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+//
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute simd reduction(+:
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute simd reduction(+ :)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute simd reduction(+ :, y)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected expression}}
+#pragma omp distribute simd reduction(+ : x, + : y)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected identifier}}
+#pragma omp distribute simd reduction(% : x)
+ for (i = 0; i < 16; ++i)
+ ;
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(+ : x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(* : x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(- : x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(& : x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(| : x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(^ : x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(&& : x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(|| : x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(max : x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(min : x)
+ for (i = 0; i < 16; ++i)
+ ;
+ struct X {
+ int x;
+ };
+ struct X X;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected variable name}}
+#pragma omp distribute simd reduction(+ : X.x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+// expected-error@+1 {{expected variable name}}
+#pragma omp distribute simd reduction(+ : x + x)
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+void test_loop_messages() {
+ float a[100], b[100], c[100];
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{variable must be of integer or pointer type}}
+#pragma omp distribute simd
+ for (float fi = 0; fi < 10.0; fi++) {
+ c[(int)fi] = a[(int)fi] + b[(int)fi];
+ }
+#pragma omp target
+#pragma omp teams
+// expected-error@+2 {{variable must be of integer or pointer type}}
+#pragma omp distribute simd
+ for (double fi = 0; fi < 10.0; fi++) {
+ c[(int)fi] = a[(int)fi] + b[(int)fi];
+ }
+}
+
+void linear_modifiers(int argc) {
+ int f;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(f)
+ for (int k = 0; k < argc; ++k) ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(val(f))
+ for (int k = 0; k < argc; ++k) ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(uval(f)) // expected-error {{expected 'val' modifier}}
+ for (int k = 0; k < argc; ++k) ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(ref(f)) // expected-error {{expected 'val' modifier}}
+ for (int k = 0; k < argc; ++k) ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd linear(foo(f)) // expected-error {{expected 'val' modifier}}
+ for (int k = 0; k < argc; ++k) ++k;
+}
+
diff --git a/test/OpenMP/distribute_simd_private_messages.cpp b/test/OpenMP/distribute_simd_private_messages.cpp
new file mode 100644
index 0000000000000..c777c9971d4b5
--- /dev/null
+++ b/test/OpenMP/distribute_simd_private_messages.cpp
@@ -0,0 +1,315 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+
+public:
+ S2() : a(0) {}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+
+public:
+ S3() : a(0) {}
+};
+const S3 ca[5];
+class S4 {
+ int a;
+ S4(); // expected-note {{implicitly declared private here}}
+
+public:
+ S4(int v) : a(v) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+};
+class S5 {
+ int a;
+ S5() : a(0) {} // expected-note {{implicitly declared private here}}
+
+public:
+ S5(int v) : a(v) {}
+ S5 &operator=(S5 &s) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S6 {
+public:
+ T a;
+
+ S6() : a(0) {}
+ S6(T v) : a(v) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+ S6 &operator=(S6 &s) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S7 : public T {
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(T v) : a(v) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(I argc, C **argv) {
+ I e(4);
+ I g(5);
+ int i;
+ int &j = i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private // expected-error {{expected '(' after 'private'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private() // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(argc)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(e, g)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp distribute simd'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp parallel
+ {
+ int v = 0;
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(i)
+ for (int k = 0; k < argc; ++k) {
+ i = k;
+ v += i;
+ }
+ }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(j)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+ return 0;
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ S4 e(4);
+ S5 g(5);
+ S6<float> s6(0.0) , s6_0(1.0);
+ S7<S6<float> > s7(0.0) , s7_0(1.0);
+ int i;
+ int &j = i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private // expected-error {{expected '(' after 'private'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private() // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(argc)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp distribute simd'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp parallel
+ {
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+ }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(j)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+ static int m;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(m)
+ for (int k = 0; k < argc; ++k)
+ m = k + 2;
+
+ s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}}
+ s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}}
+ return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
+}
+
diff --git a/test/OpenMP/distribute_simd_reduction_messages.cpp b/test/OpenMP/distribute_simd_reduction_messages.cpp
new file mode 100644
index 0000000000000..e03b852928082
--- /dev/null
+++ b/test/OpenMP/distribute_simd_reduction_messages.cpp
@@ -0,0 +1,441 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+ S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}}
+
+public:
+ S2() : a(0) {}
+ S2(S2 &s2) : a(s2.a) {}
+ static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
+ static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+S2 b; // expected-note 3 {{'b' defined here}}
+const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
+class S3 {
+ int a;
+
+public:
+ int b;
+ S3() : a(0) {}
+ S3(const S3 &s3) : a(s3.a) {}
+ S3 operator+(const S3 &arg1) { return arg1; }
+};
+int operator+(const S3 &arg1, const S3 &arg2) { return 5; }
+S3 c; // expected-note 3 {{'c' defined here}}
+const S3 ca[5]; // expected-note 2 {{'ca' defined here}}
+extern const int f; // expected-note 4 {{'f' declared here}}
+class S4 {
+ int a;
+ S4(); // expected-note {{implicitly declared private here}}
+ S4(const S4 &s4);
+ S4 &operator+(const S4 &arg) { return (*this); }
+
+public:
+ S4(int v) : a(v) {}
+};
+S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; }
+class S5 {
+ int a;
+ S5() : a(0) {} // expected-note {{implicitly declared private here}}
+ S5(const S5 &s5) : a(s5.a) {}
+ S5 &operator+(const S5 &arg);
+
+public:
+ S5(int v) : a(v) {}
+};
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+#if __cplusplus >= 201103L // C++11 or later
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
+#endif
+ int a;
+
+public:
+ S6() : a(6) {}
+ operator int() { return 6; }
+} o;
+
+S3 h, k;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class T> // expected-note {{declared here}}
+T tmain(T argc) {
+ const T d = T(); // expected-note 4 {{'d' defined here}}
+ const T da[5] = {T()}; // expected-note 2 {{'da' defined here}}
+ T qa[5] = {T()};
+ T i;
+ T &j = i; // expected-note 4 {{'j' defined here}}
+ S3 &p = k; // expected-note 2 {{'p' defined here}}
+ const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}}
+ T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}}
+ T fl;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction // expected-error {{expected '(' after 'reduction'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp distribute simd' are ignored}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(&& : argc)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel private(k)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel private(fl)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(+ : fl)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel reduction(* : fl)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(+ : fl)
+ for (int i = 0; i < 10; ++i)
+ foo();
+
+ return T();
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5; // expected-note 2 {{'d' defined here}}
+ const int da[5] = {0}; // expected-note {{'da' defined here}}
+ int qa[5] = {0};
+ S4 e(4);
+ S5 g(5);
+ int i;
+ int &j = i; // expected-note 2 {{'j' defined here}}
+ S3 &p = k; // expected-note 2 {{'p' defined here}}
+ const int &r = da[i]; // expected-note {{'r' defined here}}
+ int &q = qa[i]; // expected-note {{'q' defined here}}
+ float fl;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction // expected-error {{expected '(' after 'reduction'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp distribute simd' are ignored}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(~ : argc) // expected-error {{expected unqualified-id}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(&& : argc)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(+ : o) // expected-error {{no viable overloaded '='}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel private(k)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel private(fl)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(+ : fl)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel reduction(* : fl)
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(+ : fl)
+ for (int i = 0; i < 10; ++i)
+ foo();
+ static int m;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd reduction(+ : m) // OK
+ for (int i = 0; i < 10; ++i)
+ m++;
+
+ return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}}
+}
diff --git a/test/OpenMP/distribute_simd_safelen_messages.cpp b/test/OpenMP/distribute_simd_safelen_messages.cpp
new file mode 100644
index 0000000000000..4ae35fb2334da
--- /dev/null
+++ b/test/OpenMP/distribute_simd_safelen_messages.cpp
@@ -0,0 +1,177 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen // expected-error {{expected '(' after 'safelen'}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen () // expected-error {{expected expression}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen (argc // expected-note {{to match this '('}} expected-error 2 {{expression is not an integral constant expression}} expected-note 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} expected-error {{expected ')'}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen (ST // expected-error {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen (1)) // expected-warning {{extra tokens at the end of '#pragma omp distribute simd' are ignored}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen ((ST > 0) ? 1 + ST : 2)
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#if __cplusplus >= 201103L
+ // expected-note@+4 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{directive '#pragma omp distribute simd' cannot contain more than one 'safelen' clause}} expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{expression is not an integral constant expression}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen (S) // expected-error {{'S' does not refer to a value}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#if __cplusplus <= 199711L
+ // expected-error@+6 2 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+4 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen (4)
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen (N) // expected-error {{argument to 'safelen' clause must be a strictly positive integer value}}
+ for (T i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+ return argc;
+}
+
+int main(int argc, char **argv) {
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd safelen // expected-error {{expected '(' after 'safelen'}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd safelen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd safelen () // expected-error {{expected expression}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd safelen (4 // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd safelen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd safelen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'safelen' clause}} expected-error {{expression is not an integral constant expression}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd safelen (S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#if __cplusplus <= 199711L
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+4 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+ // expected-note@+3 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen(safelen(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+ foo(); // expected-error {{statement after '#pragma omp distribute simd' must be a for loop}}
+
+ // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 12, 4>' requested here}}
+ return tmain<int, char, 12, 4>(argc, argv);
+}
+
diff --git a/test/OpenMP/distribute_simd_simdlen_messages.cpp b/test/OpenMP/distribute_simd_simdlen_messages.cpp
new file mode 100644
index 0000000000000..4ae35fb2334da
--- /dev/null
+++ b/test/OpenMP/distribute_simd_simdlen_messages.cpp
@@ -0,0 +1,177 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen // expected-error {{expected '(' after 'safelen'}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen () // expected-error {{expected expression}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen (argc // expected-note {{to match this '('}} expected-error 2 {{expression is not an integral constant expression}} expected-note 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} expected-error {{expected ')'}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen (ST // expected-error {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen (1)) // expected-warning {{extra tokens at the end of '#pragma omp distribute simd' are ignored}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen ((ST > 0) ? 1 + ST : 2)
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#if __cplusplus >= 201103L
+ // expected-note@+4 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{directive '#pragma omp distribute simd' cannot contain more than one 'safelen' clause}} expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{expression is not an integral constant expression}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen (S) // expected-error {{'S' does not refer to a value}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#if __cplusplus <= 199711L
+ // expected-error@+6 2 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+4 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen (4)
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen (N) // expected-error {{argument to 'safelen' clause must be a strictly positive integer value}}
+ for (T i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+ return argc;
+}
+
+int main(int argc, char **argv) {
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd safelen // expected-error {{expected '(' after 'safelen'}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd safelen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd safelen () // expected-error {{expected expression}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd safelen (4 // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd safelen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd safelen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'safelen' clause}} expected-error {{expression is not an integral constant expression}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target
+#pragma omp teams
+#pragma omp parallel for simd safelen (S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#if __cplusplus <= 199711L
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+4 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i-4];
+
+ // expected-note@+3 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd safelen(safelen(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+ foo(); // expected-error {{statement after '#pragma omp distribute simd' must be a for loop}}
+
+ // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 12, 4>' requested here}}
+ return tmain<int, char, 12, 4>(argc, argv);
+}
+
diff --git a/test/OpenMP/driver.c b/test/OpenMP/driver.c
index f84541bef8ba0..74aaea5071966 100644
--- a/test/OpenMP/driver.c
+++ b/test/OpenMP/driver.c
@@ -8,3 +8,22 @@
// CHECK-NO-TLS: -cc1
// CHECK-NO-TLS-SAME: -fnoopenmp-use-tls
//
+// RUN: %clang %s -c -E -dM -fopenmp=libomp | FileCheck --check-prefix=CHECK-DEFAULT-VERSION %s
+// RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=1 | FileCheck --check-prefix=CHECK-DEFAULT-VERSION %s
+// RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=0 | FileCheck --check-prefix=CHECK-DEFAULT-VERSION %s
+// RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=100 | FileCheck --check-prefix=CHECK-DEFAULT-VERSION %s
+// RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=31 | FileCheck --check-prefix=CHECK-DEFAULT-VERSION %s
+// CHECK-DEFAULT-VERSION: #define _OPENMP 201107
+
+// RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=40 | FileCheck --check-prefix=CHECK-40-VERSION %s
+// CHECK-40-VERSION: #define _OPENMP 201307
+
+// RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=45 | FileCheck --check-prefix=CHECK-45-VERSION %s
+// CHECK-45-VERSION: #define _OPENMP 201511
+
+// RUN: %clang %s -c -E -dM -fopenmp-version=1 | FileCheck --check-prefix=CHECK-VERSION %s
+// RUN: %clang %s -c -E -dM -fopenmp-version=31 | FileCheck --check-prefix=CHECK-VERSION %s
+// RUN: %clang %s -c -E -dM -fopenmp-version=40 | FileCheck --check-prefix=CHECK-VERSION %s
+// RUN: %clang %s -c -E -dM -fopenmp-version=45 | FileCheck --check-prefix=CHECK-VERSION %s
+// CHECK-VERSION-NOT: #define _OPENMP
+
diff --git a/test/OpenMP/dump.cpp b/test/OpenMP/dump.cpp
new file mode 100644
index 0000000000000..378b53ce5bf19
--- /dev/null
+++ b/test/OpenMP/dump.cpp
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -verify -fopenmp -ast-dump %s | FileCheck %s
+// expected-no-diagnostics
+
+int ga, gb;
+#pragma omp threadprivate(ga, gb)
+
+// CHECK: |-OMPThreadPrivateDecl {{.+}} <col:9> col:9
+// CHECK-NEXT: | |-DeclRefExpr {{.+}} <col:27> 'int' lvalue Var {{.+}} 'ga' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.+}} <col:31> 'int' lvalue Var {{.+}} 'gb' 'int'
+
+#pragma omp declare reduction(+ : int, char : omp_out *= omp_in)
+
+#pragma omp declare reduction(fun : float : omp_out += omp_in) initializer(omp_priv = omp_orig + 15)
+
+// CHECK: |-OMPDeclareReductionDecl {{.+}} <line:11:35> col:35 operator+ 'int' combiner
+// CHECK-NEXT: | |-CompoundAssignOperator {{.+}} <col:47, col:58> 'int' lvalue '*=' ComputeLHSTy='int' ComputeResultTy='int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.+}} <col:47> 'int' lvalue Var {{.+}} 'omp_out' 'int'
+// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:58> 'int' <LValueToRValue>
+// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:58> 'int' lvalue Var {{.+}} 'omp_in' 'int'
+// CHECK-NEXT: | |-VarDecl {{.+}} <col:35> col:35 implicit used omp_in 'int'
+// CHECK-NEXT: | `-VarDecl {{.+}} <col:35> col:35 implicit used omp_out 'int'
+// CHECK-NEXT: |-OMPDeclareReductionDecl {{.+}} <col:40> col:40 operator+ 'char' combiner
+// CHECK-NEXT: | |-CompoundAssignOperator {{.+}} <col:47, col:58> 'char' lvalue '*=' ComputeLHSTy='int' ComputeResultTy='int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.+}} <col:47> 'char' lvalue Var {{.+}} 'omp_out' 'char'
+// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:58> 'int' <IntegralCast>
+// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:58> 'char' <LValueToRValue>
+// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:58> 'char' lvalue Var {{.+}} 'omp_in' 'char'
+// CHECK-NEXT: | |-VarDecl {{.+}} <col:40> col:40 implicit used omp_in 'char'
+// CHECK-NEXT: | `-VarDecl {{.+}} <col:40> col:40 implicit used omp_out 'char'
+// CHECK-NEXT: |-OMPDeclareReductionDecl {{.+}} <line:13:37> col:37 fun 'float' combiner initializer
+// CHECK-NEXT: | |-CompoundAssignOperator {{.+}} <col:45, col:56> 'float' lvalue '+=' ComputeLHSTy='float' ComputeResultTy='float'
+// CHECK-NEXT: | | |-DeclRefExpr {{.+}} <col:45> 'float' lvalue Var {{.+}} 'omp_out' 'float'
+// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:56> 'float' <LValueToRValue>
+// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:56> 'float' lvalue Var {{.+}} 'omp_in' 'float'
+
+struct S {
+ int a, b;
+ S() {
+#pragma omp parallel for default(none) private(a) shared(b) schedule(static, a)
+ for (int i = 0; i < 0; ++i)
+ ++a;
+ }
+};
+
+// CHECK: | `-OMPParallelForDirective {{.+}} <line:39:9, col:80>
+// CHECK-NEXT: | |-OMPDefaultClause {{.+}} <col:26, col:40>
+// CHECK-NEXT: | |-OMPPrivateClause {{.+}} <col:40, col:51>
+// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:48> 'int' lvalue OMPCapturedExpr {{.+}} 'a' 'int &'
+// CHECK-NEXT: | |-OMPSharedClause {{.+}} <col:51, col:61>
+// CHECK-NEXT: | | `-MemberExpr {{.+}} <col:58> 'int' lvalue ->b
+// CHECK-NEXT: | | `-CXXThisExpr {{.+}} <col:58> 'struct S *' this
+// CHECK-NEXT: | |-OMPScheduleClause {{.+}} <col:61, col:79>
+// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:78> 'int' <LValueToRValue>
+// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:78> 'int' lvalue OMPCapturedExpr {{.+}} '.capture_expr.' 'int'
+// CHECK-NEXT: | |-CapturedStmt {{.+}} <line:40:5, <invalid sloc>>
+// CHECK-NEXT: | | |-CapturedDecl {{.+}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | | |-ForStmt {{.+}} <col:5, <invalid sloc>>
+// CHECK: | | | | `-UnaryOperator {{.+}} <line:41:7, <invalid sloc>> 'int' lvalue prefix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.+}} <<invalid sloc>> 'int' lvalue OMPCapturedExpr {{.+}} 'a' 'int &'
+
+#pragma omp declare simd
+#pragma omp declare simd inbranch
+void foo();
+
+// CHECK: `-FunctionDecl {{.+}} <line:63:1, col:10> col:6 foo 'void (void)'
+// CHECK-NEXT: |-OMPDeclareSimdDeclAttr {{.+}} <line:62:9, col:34> Implicit BS_Inbranch
+// CHECK: `-OMPDeclareSimdDeclAttr {{.+}} <line:61:9, col:25> Implicit BS_Undefined
+
diff --git a/test/OpenMP/for_ast_print.cpp b/test/OpenMP/for_ast_print.cpp
index 3510b904b1c76..182b395c13ca1 100644
--- a/test/OpenMP/for_ast_print.cpp
+++ b/test/OpenMP/for_ast_print.cpp
@@ -8,6 +8,94 @@
void foo() {}
+struct S {
+ S(): a(0) {}
+ S(int v) : a(v) {}
+ int a;
+ typedef int type;
+};
+
+template <typename T>
+class S7 : public T {
+protected:
+ T a;
+ T &b;
+ typename T::type c:12;
+ typename T::type &d;
+ S7() : a(0), b(a), c(0), d(a.a) {}
+
+public:
+ S7(typename T::type v) : a(v), b(a), c(v), d(a.a) {
+#pragma omp for private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+#pragma omp for lastprivate(a) lastprivate(this->a) lastprivate(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+#pragma omp for linear(val(c))
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp for private(a) private(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+#pragma omp for lastprivate(a) lastprivate(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+#pragma omp for linear(uval(this->b))
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp for private(this->a) private(this->a) private(this->S::a)
+// CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a) lastprivate(this->S::a)
+// CHECK: #pragma omp for linear(val(this->c))
+// CHECK: #pragma omp for private(this->a) private(this->a) private(T::a)
+// CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a) lastprivate(T::a)
+// CHECK: #pragma omp for linear(val(this->c))
+// CHECK: #pragma omp for private(this->a) private(this->a)
+// CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a)
+// CHECK: #pragma omp for linear(uval(this->b))
+
+class S8 : public S7<S> {
+ S8() {}
+
+public:
+ S8(int v) : S7<S>(v){
+#pragma omp for private(a) private(this->a) private(S7<S>::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+#pragma omp for lastprivate(a) lastprivate(this->a) lastprivate(S7<S>::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+#pragma omp for linear(ref(S7<S>::d))
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S8 &operator=(S8 &s) {
+#pragma omp for private(a) private(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+#pragma omp for lastprivate(a) lastprivate(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+#pragma omp for linear(this->c)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp for private(this->a) private(this->a) private(this->S7<S>::a)
+// CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a) lastprivate(this->S7<S>::a)
+// CHECK: #pragma omp for linear(ref(this->S7<S>::d))
+// CHECK: #pragma omp for private(this->a) private(this->a)
+// CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a)
+// CHECK: #pragma omp for linear(this->c)
+
template <class T, int N>
T tmain(T argc) {
T b = argc, c, d, e, f, g;
diff --git a/test/OpenMP/for_codegen.cpp b/test/OpenMP/for_codegen.cpp
index 98761f56c7620..1d24403a09fbf 100644
--- a/test/OpenMP/for_codegen.cpp
+++ b/test/OpenMP/for_codegen.cpp
@@ -98,8 +98,8 @@ void static_not_chunked(float *a, float *b, float *c, float *d) {
// CHECK-LABEL: define {{.*void}} @{{.*}}static_chunked{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}})
void static_chunked(float *a, float *b, float *c, float *d) {
// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]])
- #pragma omp for schedule(static, 5)
-// CHECK: call void @__kmpc_for_static_init_4u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 33, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 5)
+ #pragma omp for schedule(monotonic: static, 5)
+// CHECK: call void @__kmpc_for_static_init_4u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 536870945, i32* [[IS_LAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 5)
// UB = min(UB, GlobalUB)
// CHECK: [[UB:%.+]] = load i32, i32* [[OMP_UB]]
// CHECK-NEXT: [[UBCMP:%.+]] = icmp ugt i32 [[UB]], 16908288
@@ -158,8 +158,8 @@ void static_chunked(float *a, float *b, float *c, float *d) {
// CHECK-LABEL: define {{.*void}} @{{.*}}dynamic1{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}})
void dynamic1(float *a, float *b, float *c, float *d) {
// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]])
- #pragma omp for schedule(dynamic)
-// CHECK: call void @__kmpc_dispatch_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 35, i64 0, i64 16908287, i64 1, i64 1)
+ #pragma omp for schedule(nonmonotonic: dynamic)
+// CHECK: call void @__kmpc_dispatch_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 1073741859, i64 0, i64 16908287, i64 1, i64 1)
//
// CHECK: [[HASWORK:%.+]] = call i32 @__kmpc_dispatch_next_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32* [[OMP_ISLAST:%[^,]+]], i64* [[OMP_LB:%[^,]+]], i64* [[OMP_UB:%[^,]+]], i64* [[OMP_ST:%[^,]+]])
// CHECK-NEXT: [[O_CMP:%.+]] = icmp ne i32 [[HASWORK]], 0
@@ -327,12 +327,13 @@ void runtime(float *a, float *b, float *c, float *d) {
// CHECK-LABEL: test_precond
void test_precond() {
// CHECK: [[A_ADDR:%.+]] = alloca i8,
+ // CHECK: [[CAP:%.+]] = alloca i8,
// CHECK: [[I_ADDR:%.+]] = alloca i8,
char a = 0;
// CHECK: store i8 0,
// CHECK: store i32
// CHECK: store i8
- // CHECK: [[A:%.+]] = load i8, i8* [[A_ADDR]],
+ // CHECK: [[A:%.+]] = load i8, i8* [[CAP]],
// CHECK: [[CONV:%.+]] = sext i8 [[A]] to i32
// CHECK: [[CMP:%.+]] = icmp slt i32 [[CONV]], 10
// CHECK: br i1 [[CMP]], label %[[PRECOND_THEN:[^,]+]], label %[[PRECOND_END:[^,]+]]
@@ -491,4 +492,25 @@ void loop_with_stmt_expr() {
// CHECK: call void @__kmpc_for_static_init_4(
// CHECK: call void @__kmpc_for_static_fini(
+
+// CHECK-LABEL: fint
+// CHECK: call {{.*}}i32 {{.*}}ftemplate
+// CHECK: ret i32
+
+// CHECK: load i16, i16*
+// CHECK: store i16 %
+// CHECK: call void {{.+}}@__kmpc_fork_call(
+// CHECK: call void @__kmpc_for_static_init_4(
+template <typename T>
+T ftemplate() {
+ short aa = 0;
+
+#pragma omp parallel for schedule(static, aa)
+ for (int i = 0; i < 100; i++) {
+ }
+ return T();
+}
+
+int fint(void) { return ftemplate<int>(); }
+
#endif // HEADER
diff --git a/test/OpenMP/for_collapse_messages.cpp b/test/OpenMP/for_collapse_messages.cpp
index d40c305c6271b..a6fdf0066592c 100644
--- a/test/OpenMP/for_collapse_messages.cpp
+++ b/test/OpenMP/for_collapse_messages.cpp
@@ -1,8 +1,13 @@
// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
void foo() {
}
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
bool foobool(int argc) {
return argc;
}
@@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp for collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp for', but found only 1}}
- // expected-error@+3 2 {{directive '#pragma omp for' cannot contain more than one 'collapse' clause}}
- // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+ // expected-error@+6 2 {{directive '#pragma omp for' cannot contain more than one 'collapse' clause}}
+ // expected-error@+5 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
#pragma omp for collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp for collapse (S) // expected-error {{'S' does not refer to a value}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp for collapse (1)
@@ -59,16 +71,27 @@ int main(int argc, char **argv) {
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}}
#pragma omp for collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}} expected-note {{as specified in 'collapse' clause}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}}
- #pragma omp for collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+ #pragma omp for collapse (foobool(1) > 0 ? 1 : 2)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+3 {{expression is not an integral constant expression}}
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
// expected-error@+2 2 {{directive '#pragma omp for' cannot contain more than one 'collapse' clause}}
// expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp for collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp for collapse (S1) // expected-error {{'S1' does not refer to a value}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+1 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
// expected-error@+3 {{statement after '#pragma omp for' must be a for loop}}
diff --git a/test/OpenMP/for_firstprivate_codegen.cpp b/test/OpenMP/for_firstprivate_codegen.cpp
index 01a93559451a0..3c6f37229f22e 100644
--- a/test/OpenMP/for_firstprivate_codegen.cpp
+++ b/test/OpenMP/for_firstprivate_codegen.cpp
@@ -95,7 +95,7 @@ int main() {
// LAMBDA: [[SIVAR2_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR2_PRIVATE_ADDR_REF]]
// LAMBDA: store i{{[0-9]+}} [[SIVAR2_VAL]], i{{[0-9]+}}* [[SIVAR2_PRIVATE_ADDR]]
- // LAMBDA: call void @__kmpc_barrier(
+ // LAMBDA-NOT: call void @__kmpc_barrier(
g = 1;
g1 = 1;
sivar = 2;
@@ -158,7 +158,7 @@ int main() {
// BLOCKS: [[SIVAR2_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF_ADDRR]]
// BLOCKS: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[SIVAR2_PRIVATE_ADDR]]
- // BLOCKS: call void @__kmpc_barrier(
+ // BLOCKS-NOT: call void @__kmpc_barrier(
g = 1;
g1 =1;
sivar = 2;
@@ -246,7 +246,7 @@ int main() {
// CHECK: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIV]]
// Synchronization for initialization.
-// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK-NOT: call void @__kmpc_barrier(
// CHECK: call void @__kmpc_for_static_init_4(
// CHECK: call void @__kmpc_for_static_fini(
@@ -262,31 +262,38 @@ int main() {
// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[TVAR:%.+]] = alloca i32,
+// CHECK: [[TVAR_CAST:%.+]] = alloca i64,
// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
-// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i32*, [2 x i32]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void
+// CHECK: [[TVAR_VAL:%.+]] = load i32, i32* [[TVAR]],
+// CHECK: [[TVAR_CONV:%.+]] = bitcast i64* [[TVAR_CAST]] to i32*
+// CHECK: store i32 [[TVAR_VAL]], i32* [[TVAR_CONV]],
+// CHECK: [[PVT_CASTVAL:%[^,]+]] = load i64, i64* [[TVAR_CAST]],
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, [2 x i32]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void (i32*, i32*, ...)*), i64 [[PVT_CASTVAL]],
// CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
// CHECK: ret
//
-// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(8) %{{.+}}, [[S_INT_TY]]* dereferenceable(4) %{{.+}})
+// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 {{.*}}%{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(8) %{{.+}}, [[S_INT_TY]]* dereferenceable(4) %{{.+}})
// Skip temp vars for loop
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
-// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+// CHECK: %{{.+}} = bitcast i64* [[T_VAR_PRIV]] to i32*
-// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %
+// CHECK-NOT: load i{{[0-9]+}}*, i{{[0-9]+}}** %
// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** %
// CHECK: [[S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** %
+// CHECK: [[VAR:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** %
// firstprivate t_var(t_var)
-// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]],
-// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK-NOT: load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]],
// firstprivate vec(vec)
// CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
@@ -310,10 +317,8 @@ int main() {
// CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]])
// CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]])
-// Synchronization for initialization.
-// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
-// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
-// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// No synchronization for initialization.
+// CHECK-NOT: call void @__kmpc_barrier(
// CHECK: call void @__kmpc_for_static_init_4(
// CHECK: call void @__kmpc_for_static_fini(
diff --git a/test/OpenMP/for_firstprivate_messages.cpp b/test/OpenMP/for_firstprivate_messages.cpp
index 1933de25850e6..60be4f5f2a2b1 100644
--- a/test/OpenMP/for_firstprivate_messages.cpp
+++ b/test/OpenMP/for_firstprivate_messages.cpp
@@ -143,7 +143,7 @@ int foomain(int argc, char **argv) {
foo();
#pragma omp parallel reduction(+ : i) // expected-note {{defined as reduction}}
#pragma omp for firstprivate(i) // expected-error {{firstprivate variable must be shared}}
- for (i = 0; i < argc; ++i)
+ for (int k = 0; k < argc; ++k)
foo();
return 0;
}
diff --git a/test/OpenMP/for_lastprivate_codegen.cpp b/test/OpenMP/for_lastprivate_codegen.cpp
index ea559b08eae0c..2b1d6c3cf97f4 100644
--- a/test/OpenMP/for_lastprivate_codegen.cpp
+++ b/test/OpenMP/for_lastprivate_codegen.cpp
@@ -8,6 +8,115 @@
#ifndef HEADER
#define HEADER
+struct SS {
+ int a;
+ int b : 4;
+ int &c;
+ SS(int &d) : a(0), b(0), c(d) {
+#pragma omp parallel
+#pragma omp for lastprivate(a, b, c)
+ for (int i = 0; i < 2; ++i)
+#ifdef LAMBDA
+ [&]() {
+ ++this->a, --b, (this)->c /= 1;
+#pragma omp parallel
+#pragma omp for lastprivate(a, b, c)
+ for (int i = 0; i < 2; ++i)
+ ++(this)->a, --b, this->c /= 1;
+ }();
+#elif defined(BLOCKS)
+ ^{
+ ++a;
+ --this->b;
+ (this)->c /= 1;
+#pragma omp parallel
+#pragma omp for lastprivate(a, b, c)
+ for (int i = 0; i < 2; ++i)
+ ++(this)->a, --b, this->c /= 1;
+ }();
+#else
+ ++this->a, --b, c /= 1;
+#endif
+#pragma omp for
+ for (a = 0; a < 2; ++a)
+#ifdef LAMBDA
+ [&]() {
+ ++this->a, --b, (this)->c /= 1;
+#pragma omp parallel
+#pragma omp for lastprivate(b)
+ for (b = 0; b < 2; ++b)
+ ++(this)->a, --b, this->c /= 1;
+ }();
+#elif defined(BLOCKS)
+ ^{
+ ++a;
+ --this->b;
+ (this)->c /= 1;
+#pragma omp parallel
+#pragma omp for
+ for (c = 0; c < 2; ++c)
+ ++(this)->a, --b, this->c /= 1;
+ }();
+#else
+ ++this->a, --b, c /= 1;
+#endif
+ }
+};
+
+template <typename T>
+struct SST {
+ T a;
+ SST() : a(T()) {
+#pragma omp parallel
+#pragma omp for lastprivate(a)
+ for (int i = 0; i < 2; ++i)
+#ifdef LAMBDA
+ [&]() {
+ [&]() {
+ ++this->a;
+#pragma omp parallel
+#pragma omp for lastprivate(a)
+ for (int i = 0; i < 2; ++i)
+ ++(this)->a;
+ }();
+ }();
+#elif defined(BLOCKS)
+ ^{
+ ^{
+ ++a;
+#pragma omp parallel
+#pragma omp for lastprivate(a)
+ for (int i = 0; i < 2; ++i)
+ ++(this)->a;
+ }();
+ }();
+#else
+ ++(this)->a;
+#endif
+#pragma omp for
+ for (a = 0; a < 2; ++a)
+#ifdef LAMBDA
+ [&]() {
+ ++this->a;
+#pragma omp parallel
+#pragma omp for
+ for (a = 0; a < 2; ++(this)->a)
+ ++(this)->a;
+ }();
+#elif defined(BLOCKS)
+ ^{
+ ++a;
+#pragma omp parallel
+#pragma omp for
+ for (this->a = 0; a < 2; ++a)
+ ++(this)->a;
+ }();
+#else
+ ++(this)->a;
+#endif
+ }
+};
+
template <class T>
struct S {
T f;
@@ -23,6 +132,9 @@ volatile int &g1 = g;
float f;
char cnt;
+// CHECK: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8
+// LAMBDA: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8
+// BLOCKS: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8
// CHECK: [[S_FLOAT_TY:%.+]] = type { float }
// CHECK: [[S_INT_TY:%.+]] = type { i32 }
// CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8*
@@ -32,6 +144,7 @@ char cnt;
template <typename T>
T tmain() {
S<T> test;
+ SST<T> sst;
T t_var __attribute__((aligned(128))) = T();
T vec[] __attribute__((aligned(128))) = {1, 2};
S<T> s_arr[] __attribute__((aligned(128))) = {1, 2};
@@ -54,17 +167,75 @@ using A::x;
int main() {
static int sivar;
+ SS ss(sivar);
#ifdef LAMBDA
// LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
// LAMBDA: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0,
// LAMBDA-LABEL: @main
- // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ // LAMBDA: alloca [[SS_TY]],
+ // LAMBDA: alloca [[CAP_TY:%.+]],
+ // LAMBDA: call void [[OUTER_LAMBDA:@.+]]([[CAP_TY]]*
[&]() {
// LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
// LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* %{{.+}})
#pragma omp parallel
#pragma omp for lastprivate(g, g1, sivar)
for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define {{.+}} @{{.+}}([[SS_TY]]*
+ // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
+ // LAMBDA: store i{{[0-9]+}} 0, i{{[0-9]+}}* %
+ // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
+ // LAMBDA: store i8
+ // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
+ // LAMBDA: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA-NOT: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
+ // LAMBDA: call void {{.+}} [[SS_LAMBDA:@[^ ]+]]
+ // LAMBDA: call void @__kmpc_for_static_fini(%
+ // LAMBDA: ret
+
+ // LAMBDA: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}})
+ // LAMBDA: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 0
+ // LAMBDA-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1
+ // LAMBDA: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 2
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]*
+ // LAMBDA: call{{.*}} void
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ // LAMBDA: br i1
+ // LAMBDA: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1
+ // LAMBDA: store i8 %{{.+}}, i8* [[B_REF]],
+ // LAMBDA: br label
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, i32* {{.+}}, i32* {{.+}}, i32* {{.+}})
+ // LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]],
+ // LAMBDA: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]],
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]],
+ // LAMBDA-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]],
+ // LAMBDA-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1
+ // LAMBDA-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]],
+ // LAMBDA-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]],
+ // LAMBDA-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1
+ // LAMBDA-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]],
+ // LAMBDA-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]],
+ // LAMBDA-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]],
+ // LAMBDA-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1
+ // LAMBDA-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]],
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ // LAMBDA: br i1
+ // LAMBDA: br label
+ // LAMBDA: ret void
+
// LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) [[SIVAR:%.+]])
// LAMBDA: alloca i{{[0-9]+}},
// LAMBDA: alloca i{{[0-9]+}},
@@ -128,6 +299,7 @@ int main() {
#elif defined(BLOCKS)
// BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212,
// BLOCKS-LABEL: @main
+ // BLOCKS: call
// BLOCKS: call void {{%.+}}(i8
^{
// BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
@@ -191,6 +363,60 @@ int main() {
}
}();
return 0;
+// BLOCKS: define {{.+}} @{{.+}}([[SS_TY]]*
+// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
+// BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* %
+// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
+// BLOCKS: store i8
+// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
+// BLOCKS: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void
+// BLOCKS: call void @__kmpc_for_static_init_4(
+// BLOCKS-NOT: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
+// BLOCKS: call void
+// BLOCKS: call void @__kmpc_for_static_fini(%
+// BLOCKS: ret
+
+// BLOCKS: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}})
+// BLOCKS: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 0
+// BLOCKS-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1
+// BLOCKS: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 2
+// BLOCKS: call void @__kmpc_for_static_init_4(
+// BLOCKS-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]*
+// BLOCKS: call{{.*}} void
+// BLOCKS: call void @__kmpc_for_static_fini(
+// BLOCKS: br i1
+// BLOCKS: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1
+// BLOCKS: store i8 %{{.+}}, i8* [[B_REF]],
+// BLOCKS: br label
+// BLOCKS: ret void
+
+// BLOCKS: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, i32* {{.+}}, i32* {{.+}}, i32* {{.+}})
+// BLOCKS: alloca i{{[0-9]+}},
+// BLOCKS: alloca i{{[0-9]+}},
+// BLOCKS: alloca i{{[0-9]+}},
+// BLOCKS: alloca i{{[0-9]+}},
+// BLOCKS: alloca i{{[0-9]+}},
+// BLOCKS: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
+// BLOCKS: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
+// BLOCKS: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
+// BLOCKS: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]],
+// BLOCKS: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]],
+// BLOCKS: call void @__kmpc_for_static_init_4(
+// BLOCKS: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]],
+// BLOCKS-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]],
+// BLOCKS-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1
+// BLOCKS-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]],
+// BLOCKS-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]],
+// BLOCKS-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1
+// BLOCKS-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]],
+// BLOCKS-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]],
+// BLOCKS-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]],
+// BLOCKS-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1
+// BLOCKS-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]],
+// BLOCKS: call void @__kmpc_for_static_fini(
+// BLOCKS: br i1
+// BLOCKS: br label
+// BLOCKS: ret void
#else
S<float> test;
int t_var = 0;
@@ -414,7 +640,52 @@ int main() {
// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i32*, [2 x i32]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void
// CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
// CHECK: ret
-//
+
+// CHECK: define {{.+}} @{{.+}}([[SS_TY]]*
+// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
+// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* %
+// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
+// CHECK: store i8
+// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-NOT: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
+// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
+// CHECK: call void @__kmpc_for_static_fini(%
+// CHECK: ret
+
+// CHECK: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}})
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]],
+// CHECK: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]],
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]],
+// CHECK-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]],
+// CHECK-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1
+// CHECK-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]],
+// CHECK-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]],
+// CHECK-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1
+// CHECK-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]],
+// CHECK-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]],
+// CHECK-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]],
+// CHECK-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1
+// CHECK-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]],
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: br i1
+// CHECK: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1
+// CHECK: store i8 %{{.+}}, i8* [[B_REF]],
+// CHECK: br label
+// CHECK: ret void
+
// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(8) %{{.+}}, [[S_INT_TY]]* dereferenceable(4) %{{.+}})
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
diff --git a/test/OpenMP/for_linear_codegen.cpp b/test/OpenMP/for_linear_codegen.cpp
index db9788361dd0f..0ad45f5b7054f 100644
--- a/test/OpenMP/for_linear_codegen.cpp
+++ b/test/OpenMP/for_linear_codegen.cpp
@@ -23,6 +23,74 @@ volatile int &g1 = g;
float f;
char cnt;
+struct SS {
+ int a;
+ int b : 4;
+ int &c;
+ SS(int &d) : a(0), b(0), c(d) {
+#pragma omp parallel
+#pragma omp for linear(a, b, c)
+ for (int i = 0; i < 2; ++i)
+#ifdef LAMBDA
+ [&]() {
+ ++this->a, --b, (this)->c /= 1;
+#pragma omp parallel
+#pragma omp for linear(a, b) linear(ref(c))
+ for (int i = 0; i < 2; ++i)
+ ++(this)->a, --b, this->c /= 1;
+ }();
+#elif defined(BLOCKS)
+ ^{
+ ++a;
+ --this->b;
+ (this)->c /= 1;
+#pragma omp parallel
+#pragma omp for linear(a, b) linear(uval(c))
+ for (int i = 0; i < 2; ++i)
+ ++(this)->a, --b, this->c /= 1;
+ }();
+#else
+ ++this->a, --b, c /= 1;
+#endif
+ }
+};
+
+template <typename T>
+struct SST {
+ T a;
+ SST() : a(T()) {
+#pragma omp parallel
+#pragma omp for linear(a)
+ for (int i = 0; i < 2; ++i)
+#ifdef LAMBDA
+ [&]() {
+ [&]() {
+ ++this->a;
+#pragma omp parallel
+#pragma omp for linear(a)
+ for (int i = 0; i < 2; ++i)
+ ++(this)->a;
+ }();
+ }();
+#elif defined(BLOCKS)
+ ^{
+ ^{
+ ++a;
+#pragma omp parallel
+#pragma omp for linear(a)
+ for (int i = 0; i < 2; ++i)
+ ++(this)->a;
+ }();
+ }();
+#else
+ ++(this)->a;
+#endif
+ }
+};
+
+// CHECK: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8
+// LAMBDA: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8
+// BLOCKS: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8
// CHECK: [[S_FLOAT_TY:%.+]] = type { float }
// CHECK: [[S_INT_TY:%.+]] = type { i32 }
// CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8*
@@ -31,6 +99,7 @@ char cnt;
template <typename T>
T tmain() {
S<T> test;
+ SST<T> sst;
T *pvar = &test.f;
T &lvar = test.f;
#pragma omp parallel
@@ -42,16 +111,75 @@ T tmain() {
}
int main() {
+ static int sivar;
+ SS ss(sivar);
#ifdef LAMBDA
// LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
// LAMBDA-LABEL: @main
- // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ // LAMBDA: alloca [[SS_TY]],
+ // LAMBDA: alloca [[CAP_TY:%.+]],
+ // LAMBDA: call void [[OUTER_LAMBDA:@.+]]([[CAP_TY]]*
[&]() {
// LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
// LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, {{.+}}* [[OMP_REGION:@.+]] to {{.+}})
#pragma omp parallel
#pragma omp for linear(g, g1:5)
for (int i = 0; i < 2; ++i) {
+ // LAMBDA: define {{.+}} @{{.+}}([[SS_TY]]*
+ // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
+ // LAMBDA: store i{{[0-9]+}} 0, i{{[0-9]+}}* %
+ // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
+ // LAMBDA: store i8
+ // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
+ // LAMBDA: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void
+ // LAMBDA: ret
+
+ // LAMBDA: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}})
+ // LAMBDA: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 0
+ // LAMBDA-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1
+ // LAMBDA: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 2
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]*
+ // LAMBDA: call{{.*}} void
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ // LAMBDA: br i1
+ // LAMBDA: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1
+ // LAMBDA: store i8 %{{.+}}, i8* [[B_REF]],
+ // LAMBDA: br label
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, i32* {{.+}}, i32* {{.+}}, i32* {{.+}})
+ // LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: alloca i{{[0-9]+}},
+ // LAMBDA: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]],
+ // LAMBDA: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]],
+ // LAMBDA: call void @__kmpc_for_static_init_4(
+ // LAMBDA: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]],
+ // LAMBDA-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]],
+ // LAMBDA-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1
+ // LAMBDA-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]],
+ // LAMBDA-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]],
+ // LAMBDA-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1
+ // LAMBDA-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]],
+ // LAMBDA-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]],
+ // LAMBDA-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]],
+ // LAMBDA-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1
+ // LAMBDA-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]],
+ // LAMBDA: call void @__kmpc_for_static_fini(
+ // LAMBDA: br i1
+ // LAMBDA: br label
+ // LAMBDA: ret void
+
// LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}})
// LAMBDA: alloca i{{[0-9]+}},
// LAMBDA: [[G_START_ADDR:%.+]] = alloca i{{[0-9]+}},
@@ -96,6 +224,7 @@ int main() {
#elif defined(BLOCKS)
// BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212,
// BLOCKS-LABEL: @main
+ // BLOCKS: call
// BLOCKS: call void {{%.+}}(i8
^{
// BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
@@ -146,6 +275,60 @@ int main() {
}
}();
return 0;
+// BLOCKS: define {{.+}} @{{.+}}([[SS_TY]]*
+// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
+// BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* %
+// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
+// BLOCKS: store i8
+// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
+// BLOCKS: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void
+// BLOCKS: ret
+
+// BLOCKS: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}})
+// BLOCKS: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 0
+// BLOCKS-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1
+// BLOCKS: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 2
+// BLOCKS: call void @__kmpc_for_static_init_4(
+// BLOCKS-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]*
+// BLOCKS: call{{.*}} void
+// BLOCKS: call void @__kmpc_for_static_fini(
+// BLOCKS: br i1
+// BLOCKS: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1
+// BLOCKS: store i8 %{{.+}}, i8* [[B_REF]],
+// BLOCKS: br label
+// BLOCKS: ret void
+
+// BLOCKS: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, i32* {{.+}}, i32* {{.+}}, i32* {{.+}})
+// BLOCKS: alloca i{{[0-9]+}},
+// BLOCKS: alloca i{{[0-9]+}},
+// BLOCKS: alloca i{{[0-9]+}},
+// BLOCKS: alloca i{{[0-9]+}},
+// BLOCKS: alloca i{{[0-9]+}},
+// BLOCKS: alloca i{{[0-9]+}},
+// BLOCKS: alloca i{{[0-9]+}},
+// BLOCKS: alloca i{{[0-9]+}},
+// BLOCKS: alloca i{{[0-9]+}},
+// BLOCKS: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
+// BLOCKS: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
+// BLOCKS: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
+// BLOCKS: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]],
+// BLOCKS: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]],
+// BLOCKS: call void @__kmpc_for_static_init_4(
+// BLOCKS: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]],
+// BLOCKS-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]],
+// BLOCKS-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1
+// BLOCKS-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]],
+// BLOCKS-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]],
+// BLOCKS-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1
+// BLOCKS-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]],
+// BLOCKS-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]],
+// BLOCKS-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]],
+// BLOCKS-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1
+// BLOCKS-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]],
+// BLOCKS: call void @__kmpc_for_static_fini(
+// BLOCKS: br i1
+// BLOCKS: br label
+// BLOCKS: ret void
#else
S<float> test;
float *pvar = &test.f;
@@ -216,7 +399,51 @@ int main() {
// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 2, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i32**, i32*)* [[TMAIN_MICROTASK:@.+]] to void
// CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
// CHECK: ret
-//
+
+// CHECK: define {{.+}} @{{.+}}([[SS_TY]]*
+// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
+// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* %
+// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
+// CHECK: store i8
+// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void
+// CHECK: ret
+
+// CHECK: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}})
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]],
+// CHECK: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]],
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]],
+// CHECK-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]],
+// CHECK-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1
+// CHECK-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]],
+// CHECK-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]],
+// CHECK-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1
+// CHECK-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]],
+// CHECK-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]],
+// CHECK-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]],
+// CHECK-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1
+// CHECK-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]],
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: br i1
+// CHECK: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1
+// CHECK: store i8 %{{.+}}, i8* [[B_REF]],
+// CHECK: br label
+// CHECK: ret void
+
// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i32** dereferenceable(8) %{{.+}}, i32* dereferenceable(4) %{{.+}})
// CHECK: alloca i{{[0-9]+}},
// CHECK: [[PVAR_START:%.+]] = alloca i32*,
diff --git a/test/OpenMP/for_linear_messages.cpp b/test/OpenMP/for_linear_messages.cpp
index 39fb21ef7be0a..ab8934979ac30 100644
--- a/test/OpenMP/for_linear_messages.cpp
+++ b/test/OpenMP/for_linear_messages.cpp
@@ -212,7 +212,7 @@ int main(int argc, char **argv) {
#pragma omp for linear(i) ordered(1) // expected-error {{'linear' clause cannot be specified along with 'ordered' clause with a parameter}}
for (int k = 0; k < argc; ++k) ++k;
- foomain<int,char>(argc,argv);
+ foomain<int,char>(argc,argv); // expected-note {{n instantiation of function template specialization 'foomain<int, char>' requested here}}
return 0;
}
diff --git a/test/OpenMP/for_loop_messages.cpp b/test/OpenMP/for_loop_messages.cpp
index 895baf57e9ccc..bb58a77e5adeb 100644
--- a/test/OpenMP/for_loop_messages.cpp
+++ b/test/OpenMP/for_loop_messages.cpp
@@ -426,12 +426,25 @@ public:
typedef int difference_type;
typedef std::random_access_iterator_tag iterator_category;
};
-// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 2nd argument}}
+class GoodIter1 {
+public:
+ GoodIter1() {}
+ GoodIter1(const GoodIter1 &) {}
+ GoodIter1 &operator++(int) { return *this; }
+ GoodIter1 &operator=(const GoodIter1 &that) { return *this; }
+ GoodIter1 &operator+=(int x) { return *this; }
+ friend long operator-(const GoodIter1 &, const GoodIter1 &);
+ GoodIter1 &operator-(int) { return *this; }
+ bool operator<(GoodIter1 a) { return true; }
+ typedef int difference_type;
+ typedef std::random_access_iterator_tag iterator_category;
+};
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}}
// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
int operator-(GoodIter a, GoodIter b) { return 0; }
// expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}}
GoodIter operator-(GoodIter a) { return a; }
-// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 2nd argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}}
// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
GoodIter operator-(GoodIter a, int v) { return GoodIter(); }
// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}}
@@ -482,7 +495,7 @@ int test_with_random_access_iterator() {
#pragma omp for
for (begin = GoodIter(0); begin < end; ++begin)
++begin;
-// expected-error@+4 {{invalid operands to binary expression ('GoodIter' and 'Iter0')}}
+// expected-error@+4 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}}
// expected-error@+3 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
#pragma omp parallel
#pragma omp for
@@ -572,6 +585,10 @@ int test_with_random_access_iterator() {
#pragma omp for
for (Iter1 I; I < end1; ++I) {
}
+ GoodIter1 I1, E1;
+#pragma omp for
+ for (GoodIter1 I = I1; I < E1; I++)
+ ;
return 0;
}
diff --git a/test/OpenMP/for_ordered_clause.cpp b/test/OpenMP/for_ordered_clause.cpp
index 8af509ab9aa87..3335f4046f571 100644
--- a/test/OpenMP/for_ordered_clause.cpp
+++ b/test/OpenMP/for_ordered_clause.cpp
@@ -1,8 +1,13 @@
// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
void foo() {
}
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
bool foobool(int argc) {
return argc;
}
@@ -36,16 +41,23 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}
#pragma omp for ordered((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'ordered' clause}}
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i - ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp for', but found only 1}}
-// expected-error@+3 2 {{directive '#pragma omp for' cannot contain more than one 'ordered' clause}}
-// expected-error@+2 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
-// expected-error@+1 2 {{expression is not an integral constant expression}}
+// expected-error@+6 2 {{directive '#pragma omp for' cannot contain more than one 'ordered' clause}}
+// expected-error@+5 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
+// expected-error@+4 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
#pragma omp for ordered(foobool(argc)), ordered(true), ordered(-5)
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i - ST];
#pragma omp for ordered(S) // expected-error {{'S' does not refer to a value}}
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i - ST];
-// expected-error@+1 2 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+// expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+// expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp for ordered(argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i - ST];
@@ -84,10 +96,17 @@ int main(int argc, char **argv) {
#pragma omp for ordered(2 + 2)) // expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}} expected-note {{as specified in 'ordered' clause}}
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i - 4]; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}}
-#pragma omp for ordered(foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+// expected-error@+4 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+// expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp for ordered(foobool(1) > 0 ? 1 : 2)
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i - 4];
-// expected-error@+3 {{expression is not an integral constant expression}}
+// expected-error@+6 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+// expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
// expected-error@+2 2 {{directive '#pragma omp for' cannot contain more than one 'ordered' clause}}
// expected-error@+1 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
#pragma omp for ordered(foobool(argc)), ordered(true), ordered(-5)
@@ -96,7 +115,11 @@ int main(int argc, char **argv) {
#pragma omp for ordered(S1) // expected-error {{'S1' does not refer to a value}}
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i - 4];
-// expected-error@+1 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+// expected-error@+4 {{expression is not an integral constant expression}}
+#else
+// expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp for ordered(argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i - 4];
diff --git a/test/OpenMP/for_private_messages.cpp b/test/OpenMP/for_private_messages.cpp
index 3015f819b5447..4045c5b56ff5c 100644
--- a/test/OpenMP/for_private_messages.cpp
+++ b/test/OpenMP/for_private_messages.cpp
@@ -29,7 +29,11 @@ class S4 {
S4(); // expected-note {{implicitly declared private here}}
public:
- S4(int v) : a(v) {}
+ S4(int v) : a(v) {
+#pragma omp for private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
};
class S5 {
int a;
@@ -37,6 +41,50 @@ class S5 {
public:
S5(int v) : a(v) {}
+ S5 &operator=(S5 &s) {
+#pragma omp for private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S6 {
+public:
+ T a;
+
+ S6() : a(0) {}
+ S6(T v) : a(v) {
+#pragma omp for private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+ S6 &operator=(S6 &s) {
+#pragma omp for private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S7 : public T {
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(T v) : a(v) {
+#pragma omp for private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp for private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
};
S3 h;
@@ -126,6 +174,8 @@ using A::x;
int main(int argc, char **argv) {
S4 e(4);
S5 g(5);
+ S6<float> s6(0.0) , s6_0(1.0);
+ S7<S6<float> > s7(0.0) , s7_0(1.0);
int i;
int &j = i;
#pragma omp for private // expected-error {{expected '(' after 'private'}}
@@ -190,6 +240,8 @@ int main(int argc, char **argv) {
for(int k = 0; k < argc; ++k)
si = k + 1;
- return 0;
+ s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}}
+ s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}}
+ return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
}
diff --git a/test/OpenMP/for_reduction_codegen.cpp b/test/OpenMP/for_reduction_codegen.cpp
index 423ab3ce76d0a..6997d8138842c 100644
--- a/test/OpenMP/for_reduction_codegen.cpp
+++ b/test/OpenMP/for_reduction_codegen.cpp
@@ -52,6 +52,8 @@ T tmain() {
return T();
}
+extern S<float> **foo();
+
int main() {
#ifdef LAMBDA
// LAMBDA: [[G:@.+]] = global double
@@ -182,6 +184,9 @@ int main() {
S<float> s_arr[] = {1, 2};
S<float> &var = test;
S<float> var1, arrs[10][4];
+ S<float> **var2 = foo();
+ S<float> vvar2[2];
+ S<float> (&var3)[2] = s_arr;
#pragma omp parallel
#pragma omp for reduction(+:t_var) reduction(&:var) reduction(&& : var1) reduction(min: t_var1)
for (int i = 0; i < 2; ++i) {
@@ -192,6 +197,26 @@ int main() {
#pragma omp parallel for reduction(+:arr[1][:vec[1]]) reduction(&:arrs[1:vec[1]][1:2])
for (int i = 0; i < 10; ++i)
++arr[1][i];
+#pragma omp parallel
+#pragma omp for reduction(+:arr) reduction(&:arrs)
+ for (int i = 0; i < 10; ++i)
+ ++arr[1][i];
+#pragma omp parallel
+#pragma omp for reduction(& : var2[0 : 5][1 : 6])
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp parallel
+#pragma omp for reduction(& : vvar2[0 : 5])
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp parallel
+#pragma omp for reduction(& : var3[1 : 2])
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp parallel
+#pragma omp for reduction(& : var3)
+ for (int i = 0; i < 10; ++i)
+ ;
return tmain<int>();
#endif
}
@@ -201,6 +226,11 @@ int main() {
// CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 6, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, float*, [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]*, float*, [2 x i32]*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK:@.+]] to void
// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, i64, i32*, [2 x i32]*, [10 x [4 x [[S_FLOAT_TY]]]]*)* [[MAIN_MICROTASK1:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, i64, i32*, [10 x [4 x [[S_FLOAT_TY]]]]*)* [[MAIN_MICROTASK2:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[S_FLOAT_TY]]***)* [[MAIN_MICROTASK3:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK4:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK5:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK6:@.+]] to void
// CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]()
// CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]*
// CHECK: ret
@@ -666,6 +696,316 @@ int main() {
// CHECK: ret void
+// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* nonnull %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(160) %{{.+}})
+
+// CHECK: [[ARRS_PRIV:%.+]] = alloca [10 x [4 x [[S_FLOAT_TY]]]],
+
+// Reduction list for runtime.
+// CHECK: [[RED_LIST:%.+]] = alloca [3 x i8*],
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+
+// CHECK: [[ARR_SIZE:%.+]] = mul nuw i64 %{{.+}}, 4
+// CHECK: call i8* @llvm.stacksave()
+// CHECK: [[ARR_PRIV:%.+]] = alloca i32, i64 [[ARR_SIZE]],
+
+// Check initialization of private copy.
+// CHECK: [[END:%.+]] = getelementptr i32, i32* [[ARR_PRIV]], i64 [[ARR_SIZE]]
+// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[ARR_PRIV]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi i32*
+// CHECK: store i32 0, i32* %
+// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]]
+// CHECK: br i1 [[DONE]],
+
+// Check initialization of private copy.
+// CHECK: [[LHS_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* %{{.+}} to [[S_FLOAT_TY]]*
+// CHECK: [[BEGIN:%.+]] = getelementptr inbounds [10 x [4 x [[S_FLOAT_TY]]]], [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]], i32 0, i32 0, i32 0
+// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[BEGIN]], i64 40
+// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[BEGIN]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi [[S_FLOAT_TY]]*
+// CHECK: call void @_ZN1SIfEC1Ev([[S_FLOAT_TY]]* %
+// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]]
+// CHECK: br i1 [[DONE]],
+// CHECK: [[ARRS_PRIV_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]] to [[S_FLOAT_TY]]*
+
+// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
+// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
+// CHECK: call void @__kmpc_for_static_init_4(
+// Skip checks for internal operations.
+// CHECK: call void @__kmpc_for_static_fini(
+
+// void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
+
+// CHECK: [[ARR_PRIV_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST]], i64 0, i64 0
+// CHECK: [[BITCAST:%.+]] = bitcast i32* [[ARR_PRIV]] to i8*
+// CHECK: store i8* [[BITCAST]], i8** [[ARR_PRIV_REF]],
+// CHECK: [[ARR_SIZE_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST]], i64 0, i64 1
+// CHECK: [[BITCAST:%.+]] = inttoptr i64 [[ARR_SIZE]] to i8*
+// CHECK: store i8* [[BITCAST]], i8** [[ARR_SIZE_REF]],
+// CHECK: [[ARRS_PRIV_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST]], i64 0, i64 2
+// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[ARRS_PRIV_BEGIN]] to i8*
+// CHECK: store i8* [[BITCAST]], i8** [[ARRS_PRIV_REF]],
+
+// res = __kmpc_reduce(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>);
+
+// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
+// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
+// CHECK: [[BITCAST:%.+]] = bitcast [3 x i8*]* [[RED_LIST]] to i8*
+// CHECK: [[RES:%.+]] = call i32 @__kmpc_reduce(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], i32 2, i64 24, i8* [[BITCAST]], void (i8*, i8*)* [[REDUCTION_FUNC:@.+]], [8 x i32]* [[REDUCTION_LOCK]])
+
+// switch(res)
+// CHECK: switch i32 [[RES]], label %[[RED_DONE:.+]] [
+// CHECK: i32 1, label %[[CASE1:.+]]
+// CHECK: i32 2, label %[[CASE2:.+]]
+// CHECK: ]
+
+// case 1:
+// CHECK: [[CASE1]]
+
+// arr[:] += arr_reduction[:];
+// CHECK: [[END:%.+]] = getelementptr i32, i32* [[LB1_0:%.+]], i64 [[ARR_SIZE]]
+// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[LB1_0]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi i32*
+// CHECK: [[ADD:%.+]] = add nsw i32 %
+// CHECK: store i32 [[ADD]], i32* %
+// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]]
+// CHECK: br i1 [[DONE]],
+
+// arrs[:] = var.operator &(arrs_reduction[:]);
+// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[LHS_BEGIN]], i64 40
+// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[LHS_BEGIN]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi [[S_FLOAT_TY]]*
+// CHECK: [[AND:%.+]] = call dereferenceable(4) [[S_FLOAT_TY]]* @_ZN1SIfEanERKS0_([[S_FLOAT_TY]]* %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}})
+// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[AND]] to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.+}}, i8* [[BITCAST]], i64 4, i32 4, i1 false)
+// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]]
+// CHECK: br i1 [[DONE]],
+
+// __kmpc_end_reduce(<loc>, <gtid>, &<lock>);
+// CHECK: call void @__kmpc_end_reduce(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]])
+
+// break;
+// CHECK: br label %[[RED_DONE]]
+
+// case 2:
+// CHECK: [[CASE2]]
+
+// arr[:] += arr_reduction[:];
+// CHECK: [[END:%.+]] = getelementptr i32, i32* [[LB1_0]], i64 [[ARR_SIZE]]
+// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[LB1_0]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi i32*
+// CHECK: atomicrmw add i32* %{{.+}}, i32 %{{.+}} monotonic
+// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]]
+// CHECK: br i1 [[DONE]],
+
+// arrs[:] = var.operator &(arrs_reduction[:]);
+// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[LHS_BEGIN]], i64 40
+// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[LHS_BEGIN]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi [[S_FLOAT_TY]]*
+// CHECK: call void @__kmpc_critical(
+// CHECK: [[AND:%.+]] = call dereferenceable(4) [[S_FLOAT_TY]]* @_ZN1SIfEanERKS0_([[S_FLOAT_TY]]* %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}})
+// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[AND]] to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.+}}, i8* [[BITCAST]], i64 4, i32 4, i1 false)
+// CHECK: call void @__kmpc_end_critical(
+// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]]
+// CHECK: br i1 [[DONE]],
+
+// break;
+// CHECK: br label %[[RED_DONE]]
+// CHECK: [[RED_DONE]]
+
+// Check destruction of private copy.
+// CHECK: [[BEGIN:%.+]] = getelementptr inbounds [10 x [4 x [[S_FLOAT_TY]]]], [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]], i32 0, i32 0, i32 0
+// CHECK: [[END:%.+]] = getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[BEGIN]], i64 40
+// CHECK: br
+// CHECK: phi [[S_FLOAT_TY]]*
+// CHECK: call void @_ZN1SIfED1Ev([[S_FLOAT_TY]]* %
+// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[BEGIN]]
+// CHECK: br i1 [[DONE]],
+// CHECK: call void @llvm.stackrestore(i8*
+// CHECK: call void @__kmpc_barrier(
+
+// CHECK: ret void
+
+// void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
+// *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]);
+// ...
+// *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1],
+// *(Type<n>-1*)rhs[<n>-1]);
+// }
+// CHECK: define internal void [[REDUCTION_FUNC]](i8*, i8*)
+// arr_rhs = (int*)rhs[0];
+// CHECK: [[ARR_RHS_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_RHS:%.+]], i64 0, i64 0
+// CHECK: [[ARR_RHS_VOID:%.+]] = load i8*, i8** [[ARR_RHS_REF]],
+// CHECK: [[ARR_RHS:%.+]] = bitcast i8* [[ARR_RHS_VOID]] to i32*
+// arr_lhs = (int*)lhs[0];
+// CHECK: [[ARR_LHS_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_LHS:%.+]], i64 0, i64 0
+// CHECK: [[ARR_LHS_VOID:%.+]] = load i8*, i8** [[ARR_LHS_REF]],
+// CHECK: [[ARR_LHS:%.+]] = bitcast i8* [[ARR_LHS_VOID]] to i32*
+
+// arr_size = (size_t)lhs[1];
+// CHECK: [[ARR_SIZE_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_LHS]], i64 0, i64 1
+// CHECK: [[ARR_SIZE_VOID:%.+]] = load i8*, i8** [[ARR_SIZE_REF]],
+// CHECK: [[ARR_SIZE:%.+]] = ptrtoint i8* [[ARR_SIZE_VOID]] to i64
+
+// arrs_rhs = (S<float>*)rhs[2];
+// CHECK: [[ARRS_RHS_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_RHS]], i64 0, i64 2
+// CHECK: [[ARRS_RHS_VOID:%.+]] = load i8*, i8** [[ARRS_RHS_REF]],
+// CHECK: [[ARRS_RHS:%.+]] = bitcast i8* [[ARRS_RHS_VOID]] to [[S_FLOAT_TY]]*
+// arrs_lhs = (S<float>*)lhs[2];
+// CHECK: [[ARRS_LHS_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_LHS]], i64 0, i64 2
+// CHECK: [[ARRS_LHS_VOID:%.+]] = load i8*, i8** [[ARRS_LHS_REF]],
+// CHECK: [[ARRS_LHS:%.+]] = bitcast i8* [[ARRS_LHS_VOID]] to [[S_FLOAT_TY]]*
+
+// arr_lhs[:] += arr_rhs[:];
+// CHECK: [[END:%.+]] = getelementptr i32, i32* [[ARR_LHS]], i64 [[ARR_SIZE]]
+// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[ARR_LHS]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi i32*
+// CHECK: [[ADD:%.+]] = add nsw i32 %
+// CHECK: store i32 [[ADD]], i32* %
+// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]]
+// CHECK: br i1 [[DONE]],
+
+// arrs_lhs = arrs_lhs.operator &(arrs_rhs);
+// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[ARRS_LB:%.+]], i64 40
+// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[ARRS_LB]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi [[S_FLOAT_TY]]*
+// CHECK: [[AND:%.+]] = call dereferenceable(4) [[S_FLOAT_TY]]* @_ZN1SIfEanERKS0_([[S_FLOAT_TY]]* %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}})
+// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[AND]] to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.+}}, i8* [[BITCAST]], i64 4, i32 4, i1 false)
+// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]]
+// CHECK: br i1 [[DONE]],
+
+// CHECK: ret void
+
+// CHECK: define internal void [[MAIN_MICROTASK3]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[S_FLOAT_TY]]*** dereferenceable(8) %{{.+}})
+
+// CHECK: [[VAR2_ORIG_ADDR:%.+]] = alloca [[S_FLOAT_TY]]***,
+
+// Reduction list for runtime.
+// CHECK: [[RED_LIST:%.+]] = alloca [2 x i8*],
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+// CHECK: [[VAR2_ORIG:%.+]] = load [[S_FLOAT_TY]]***, [[S_FLOAT_TY]]**** [[VAR2_ORIG_ADDR]],
+
+// CHECK: load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],
+// CHECK: getelementptr inbounds [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %{{.+}}, i64 0
+// CHECK: load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %
+// CHECK: [[LOW:%.+]] = getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 1
+// CHECK: load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],
+// CHECK: getelementptr inbounds [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %{{.+}}, i64 4
+// CHECK: load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %
+// CHECK: getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 6
+// CHECK: [[LD:%.+]] = load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],
+// CHECK: [[ORIG_START:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[LD]],
+// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64
+// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
+// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]]
+// CHECK: [[DIF:%.+]] = sdiv exact i64 [[BYTE_DIF]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64)
+// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1
+// CHECK: call i8* @llvm.stacksave()
+// CHECK: [[VAR2_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]],
+// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64
+// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
+// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]
+// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64)
+// CHECK: [[PSEUDO_VAR2_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VAR2_PRIV]], i64 [[OFFSET]]
+// CHECK: store [[S_FLOAT_TY]]** [[REF:.+]], [[S_FLOAT_TY]]*** %
+// CHECK: store [[S_FLOAT_TY]]* [[PSEUDO_VAR2_PRIV]], [[S_FLOAT_TY]]** [[REF]]
+// CHECK: ret void
+
+// CHECK: define internal void [[MAIN_MICROTASK4]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(8) %{{.+}})
+
+// CHECK: [[VVAR2_ORIG_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+
+// Reduction list for runtime.
+// CHECK: [[RED_LIST:%.+]] = alloca [2 x i8*],
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+// CHECK: [[VVAR2_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VVAR2_ORIG_ADDR]],
+
+// CHECK: [[LOW:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]], i64 0, i64 0
+// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]], i64 0, i64 4
+// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]] to [[S_FLOAT_TY]]*
+// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64
+// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
+// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]]
+// CHECK: [[DIF:%.+]] = sdiv exact i64 [[BYTE_DIF]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64)
+// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1
+// CHECK: call i8* @llvm.stacksave()
+// CHECK: [[VVAR2_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]],
+// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64
+// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
+// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]
+// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64)
+// CHECK: [[PSEUDO_VVAR2_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VVAR2_PRIV]], i64 [[OFFSET]]
+// CHECK: [[VVAR2_PRIV:%.+]] = bitcast [[S_FLOAT_TY]]* [[PSEUDO_VVAR2_PRIV]] to [2 x [[S_FLOAT_TY]]]*
+// CHECK: ret void
+
+// CHECK: define internal void [[MAIN_MICROTASK5]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(8) %{{.+}})
+
+// CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+
+// Reduction list for runtime.
+// CHECK: [[RED_LIST:%.+]] = alloca [2 x i8*],
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+
+// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]],
+// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: [[LOW:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], i64 0, i64 1
+// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], i64 0, i64 2
+// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*
+// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64
+// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
+// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]]
+// CHECK: [[DIF:%.+]] = sdiv exact i64 [[BYTE_DIF]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64)
+// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1
+// CHECK: call i8* @llvm.stacksave()
+// CHECK: [[VAR3_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]],
+// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64
+// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
+// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]
+// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64)
+// CHECK: [[PSEUDO_VAR3_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VAR3_PRIV]], i64 [[OFFSET]]
+// CHECK: [[VAR3_PRIV:%.+]] = bitcast [[S_FLOAT_TY]]* [[PSEUDO_VAR3_PRIV]] to [2 x [[S_FLOAT_TY]]]*
+
+// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [2 x [[S_FLOAT_TY]]]** %
+
+// CHECK: ret void
+
+// CHECK: define internal void [[MAIN_MICROTASK6]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(8) %{{.+}})
+
+// CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR3_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+
+// Reduction list for runtime.
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x i8*],
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+
+// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]],
+// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*
+// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], i32 0, i32 0
+// CHECK: getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 2
+
+// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [2 x [[S_FLOAT_TY]]]** %
+
+// CHECK: ret void
+
// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
diff --git a/test/OpenMP/for_reduction_codegen_UDR.cpp b/test/OpenMP/for_reduction_codegen_UDR.cpp
new file mode 100644
index 0000000000000..a30df368663db
--- /dev/null
+++ b/test/OpenMP/for_reduction_codegen_UDR.cpp
@@ -0,0 +1,984 @@
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// expected-no-diagnostics
+// REQUIRES: x86-registered-target
+#ifndef HEADER
+#define HEADER
+
+volatile double g, g_orig;
+volatile double &g1 = g_orig;
+
+struct BaseS {
+ int x;
+};
+struct BaseS1 {
+ float y;
+};
+
+template <class T>
+struct S : public BaseS, public BaseS1 {
+ T f;
+ S(T a) : f(a + g) {}
+ S() : f(g) {}
+ ~S() {}
+};
+void red(BaseS1&, const BaseS1&);
+void red_plus(BaseS1&, const BaseS1&);
+void init(BaseS1&, const BaseS1&);
+void init1(BaseS1&, const BaseS1&);
+void init2(BaseS1&, const BaseS1&);
+void init_plus(BaseS1&, const BaseS1&);
+#pragma omp declare reduction(operator& : BaseS1 : red(omp_out, omp_in)) initializer(init(omp_priv, omp_orig))
+#pragma omp declare reduction(+ : BaseS1 : red_plus(omp_out, omp_in)) initializer(init_plus(omp_priv, omp_orig))
+#pragma omp declare reduction(&& : S<float>, S<int> : omp_out.f *= omp_in.f) initializer(init1(omp_priv, omp_orig))
+
+// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { %{{[^,]+}}, %{{[^,]+}}, float }
+// CHECK-DAG: [[S_INT_TY:%.+]] = type { %{{[^,]+}}, %{{[^,]+}}, i{{[0-9]+}} }
+// CHECK-DAG: [[ATOMIC_REDUCE_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 18, i32 0, i32 0, i8*
+// CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8*
+// CHECK-DAG: [[REDUCTION_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 18, i32 0, i32 0, i8*
+// CHECK-DAG: [[REDUCTION_LOCK:@.+]] = common global [8 x i32] zeroinitializer
+
+#pragma omp declare reduction(operator&& : int : omp_out = 111 & omp_in)
+template <typename T>
+T tmain() {
+ T t;
+ S<T> test;
+ T t_var = T(), t_var1;
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> &var = test;
+ S<T> var1;
+#pragma omp declare reduction(operator& : T : omp_out = 15 + omp_in)
+#pragma omp declare reduction(operator+ : T : omp_out = 1513 + omp_in) initializer(omp_priv = 321)
+#pragma omp declare reduction(min : T : omp_out = 47 - omp_in) initializer(omp_priv = 432 / omp_orig)
+#pragma omp declare reduction(operator&& : S<T> : omp_out.f = 17 * omp_in.f) initializer(init2(omp_priv, omp_orig))
+#pragma omp declare reduction(operator&& : T : omp_out = 17 * omp_in)
+#pragma omp parallel
+#pragma omp for reduction(+ : t_var) reduction(& : var) reduction(&& : var1) reduction(min : t_var1) nowait
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+#pragma omp parallel
+#pragma omp for reduction(&& : t_var)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ return T();
+}
+
+extern S<float> **foo();
+
+#pragma omp declare reduction(operator- : float, double : omp_out = 333 + omp_in)
+#pragma omp declare reduction(min : float, double : omp_out = 555 + omp_in)
+int main() {
+#pragma omp declare reduction(operator+ : float, double : omp_out = 222 - omp_in) initializer(omp_priv = -1)
+ S<float> test;
+ float t_var = 0, t_var1;
+ int vec[] = {1, 2};
+ S<float> s_arr[] = {1, 2};
+ S<float> &var = test;
+ S<float> var1, arrs[10][4];
+ S<float> **var2 = foo();
+ S<float> vvar2[2];
+ S<float>(&var3)[2] = s_arr;
+#pragma omp declare reduction(operator+ : int : omp_out = 555 * omp_in) initializer(omp_priv = 888)
+#pragma omp parallel
+#pragma omp for reduction(+ : t_var) reduction(& : var) reduction(&& : var1) reduction(min : t_var1)
+ for (int i = 0; i < 2; ++i) {
+ vec[i] = t_var;
+ s_arr[i] = var;
+ }
+ int arr[10][vec[1]];
+#pragma omp parallel for reduction(+ : arr[1][ : vec[1]]) reduction(& : arrs[1 : vec[1]][1 : 2])
+ for (int i = 0; i < 10; ++i)
+ ++arr[1][i];
+#pragma omp parallel
+#pragma omp for reduction(+ : arr) reduction(& : arrs)
+ for (int i = 0; i < 10; ++i)
+ ++arr[1][i];
+#pragma omp parallel
+#pragma omp for reduction(& : var2[0 : 5][1 : 6])
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp parallel
+#pragma omp for reduction(& : vvar2[0 : 5])
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp parallel
+#pragma omp for reduction(& : var3[1 : 2])
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp parallel
+#pragma omp for reduction(& : var3)
+ for (int i = 0; i < 10; ++i)
+ ;
+ return tmain<int>();
+}
+
+// CHECK: define {{.*}}i{{[0-9]+}} @main()
+// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 6, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, float*, [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]*, float*, [2 x i32]*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, i64, i32*, [2 x i32]*, [10 x [4 x [[S_FLOAT_TY]]]]*)* [[MAIN_MICROTASK1:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, i64, i32*, [10 x [4 x [[S_FLOAT_TY]]]]*)* [[MAIN_MICROTASK2:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[S_FLOAT_TY]]***)* [[MAIN_MICROTASK3:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK4:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK5:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK6:@.+]] to void
+// CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]()
+// CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]*
+// CHECK: ret
+//
+// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, float* dereferenceable(4) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(12) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(12) %{{.+}}, float* dereferenceable(4) %{{.+}}, [2 x i32]* dereferenceable(8) %vec, [2 x [[S_FLOAT_TY]]]* dereferenceable(24) %{{.+}})
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca float,
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[VAR1_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[T_VAR1_PRIV:%.+]] = alloca float,
+
+// Reduction list for runtime.
+// CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*],
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+
+// CHECK: [[T_VAR_REF:%.+]] = load float*, float** %
+// CHECK: [[VAR1_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %
+// CHECK: [[T_VAR1_REF:%.+]] = load float*, float** %
+
+// For + reduction operation initial value of private variable is -1.
+// CHECK: store float -1.0{{.+}}, float*
+
+// For & reduction operation initial value of private variable is defined by call of 'init()' function.
+// CHECK: call {{.*}}void @_Z4initR6BaseS1RKS_(
+
+// For && reduction operation initial value of private variable is 1.0.
+// CHECK: call {{.*}}void @_Z5init1R6BaseS1RKS_(
+
+// For min reduction operation initial value of private variable is largest repesentable value.
+// CHECK: [[INIT:%.+]] = load float, float* @
+// CHECK: store float [[INIT]], float* [[T_VAR1_PRIV]],
+
+// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
+// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
+// CHECK: call void @__kmpc_for_static_init_4(
+// Skip checks for internal operations.
+// CHECK: call void @__kmpc_for_static_fini(
+
+// void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
+
+// CHECK: [[T_VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 0
+// CHECK: [[BITCAST:%.+]] = bitcast float* [[T_VAR_PRIV]] to i8*
+// CHECK: store i8* [[BITCAST]], i8** [[T_VAR_PRIV_REF]],
+// CHECK: [[VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 1
+// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_PRIV]] to i8*
+// CHECK: store i8* [[BITCAST]], i8** [[VAR_PRIV_REF]],
+// CHECK: [[VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 2
+// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR1_PRIV]] to i8*
+// CHECK: store i8* [[BITCAST]], i8** [[VAR1_PRIV_REF]],
+// CHECK: [[T_VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 3
+// CHECK: [[BITCAST:%.+]] = bitcast float* [[T_VAR1_PRIV]] to i8*
+// CHECK: store i8* [[BITCAST]], i8** [[T_VAR1_PRIV_REF]],
+
+// res = __kmpc_reduce(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>);
+
+// CHECK: [[BITCAST:%.+]] = bitcast [4 x i8*]* [[RED_LIST]] to i8*
+// CHECK: [[RES:%.+]] = call i32 @__kmpc_reduce(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], i32 4, i64 32, i8* [[BITCAST]], void (i8*, i8*)* [[REDUCTION_FUNC:@.+]], [8 x i32]* [[REDUCTION_LOCK]])
+
+// switch(res)
+// CHECK: switch i32 [[RES]], label %[[RED_DONE:.+]] [
+// CHECK: i32 1, label %[[CASE1:.+]]
+// CHECK: i32 2, label %[[CASE2:.+]]
+// CHECK: ]
+
+// case 1:
+// t_var += t_var_reduction;
+// CHECK: fsub float 2.220000e+02, %
+
+// var = var.operator &(var_reduction);
+// CHECK: call {{.*}}void @_Z3redR6BaseS1RKS_(
+
+// var1 = var1.operator &&(var1_reduction);
+// CHECK: fmul float
+
+// t_var1 = min(t_var1, t_var1_reduction);
+// CHECK: fadd float 5.550000e+02, %
+
+// __kmpc_end_reduce(<loc>, <gtid>, &<lock>);
+// CHECK: call void @__kmpc_end_reduce(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]])
+
+// break;
+// CHECK: br label %[[RED_DONE]]
+
+// case 2:
+// t_var += t_var_reduction;
+// CHECK: call void @__kmpc_critical(
+// CHECK: fsub float 2.220000e+02, %
+// CHECK: call void @__kmpc_end_critical(
+
+// var = var.operator &(var_reduction);
+// CHECK: call void @__kmpc_critical(
+// CHECK: call {{.*}}void @_Z3redR6BaseS1RKS_(
+// CHECK: call void @__kmpc_end_critical(
+
+// var1 = var1.operator &&(var1_reduction);
+// CHECK: call void @__kmpc_critical(
+// CHECK: fmul float
+// CHECK: call void @__kmpc_end_critical(
+
+// t_var1 = min(t_var1, t_var1_reduction);
+// CHECK: call void @__kmpc_critical(
+// CHECK: fadd float 5.550000e+02, %
+// CHECK: call void @__kmpc_end_critical(
+
+// __kmpc_end_reduce(<loc>, <gtid>, &<lock>);
+// CHECK: call void @__kmpc_end_reduce(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]])
+
+// break;
+// CHECK: br label %[[RED_DONE]]
+// CHECK: [[RED_DONE]]
+// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
+// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]*
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+
+// CHECK: ret void
+
+// void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
+// *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]);
+// ...
+// *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1],
+// *(Type<n>-1*)rhs[<n>-1]);
+// }
+// CHECK: define internal void [[REDUCTION_FUNC]](i8*, i8*)
+// t_var_lhs = (float*)lhs[0];
+// CHECK: [[T_VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS:%.+]], i64 0, i64 0
+// CHECK: [[T_VAR_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR_RHS_REF]],
+// CHECK: [[T_VAR_RHS:%.+]] = bitcast i8* [[T_VAR_RHS_VOID]] to float*
+// t_var_rhs = (float*)rhs[0];
+// CHECK: [[T_VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS:%.+]], i64 0, i64 0
+// CHECK: [[T_VAR_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR_LHS_REF]],
+// CHECK: [[T_VAR_LHS:%.+]] = bitcast i8* [[T_VAR_LHS_VOID]] to float*
+
+// var_lhs = (S<float>*)lhs[1];
+// CHECK: [[VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 1
+// CHECK: [[VAR_RHS_VOID:%.+]] = load i8*, i8** [[VAR_RHS_REF]],
+// CHECK: [[VAR_RHS:%.+]] = bitcast i8* [[VAR_RHS_VOID]] to [[S_FLOAT_TY]]*
+// var_rhs = (S<float>*)rhs[1];
+// CHECK: [[VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 1
+// CHECK: [[VAR_LHS_VOID:%.+]] = load i8*, i8** [[VAR_LHS_REF]],
+// CHECK: [[VAR_LHS:%.+]] = bitcast i8* [[VAR_LHS_VOID]] to [[S_FLOAT_TY]]*
+
+// var1_lhs = (S<float>*)lhs[2];
+// CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 2
+// CHECK: [[VAR1_RHS_VOID:%.+]] = load i8*, i8** [[VAR1_RHS_REF]],
+// CHECK: [[VAR1_RHS:%.+]] = bitcast i8* [[VAR1_RHS_VOID]] to [[S_FLOAT_TY]]*
+// var1_rhs = (S<float>*)rhs[2];
+// CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 2
+// CHECK: [[VAR1_LHS_VOID:%.+]] = load i8*, i8** [[VAR1_LHS_REF]],
+// CHECK: [[VAR1_LHS:%.+]] = bitcast i8* [[VAR1_LHS_VOID]] to [[S_FLOAT_TY]]*
+
+// t_var1_lhs = (float*)lhs[3];
+// CHECK: [[T_VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 3
+// CHECK: [[T_VAR1_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_RHS_REF]],
+// CHECK: [[T_VAR1_RHS:%.+]] = bitcast i8* [[T_VAR1_RHS_VOID]] to float*
+// t_var1_rhs = (float*)rhs[3];
+// CHECK: [[T_VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 3
+// CHECK: [[T_VAR1_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_LHS_REF]],
+// CHECK: [[T_VAR1_LHS:%.+]] = bitcast i8* [[T_VAR1_LHS_VOID]] to float*
+
+// t_var_lhs += t_var_rhs;
+// CHECK: fsub float 2.220000e+02, %
+
+// var_lhs = var_lhs.operator &(var_rhs);
+// CHECK: call {{.*}}void @_Z3redR6BaseS1RKS_(
+
+// var1_lhs = var1_lhs.operator &&(var1_rhs);
+// CHECK: fmul float
+
+// t_var1_lhs = min(t_var1_lhs, t_var1_rhs);
+// CHECK: fadd float 5.550000e+02, %
+// CHECK: ret void
+
+// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* nonnull %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(480) %{{.+}})
+
+// Reduction list for runtime.
+// CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*],
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+
+// CHECK: [[IDX1:%.+]] = mul nsw i64 1, %{{.+}}
+// CHECK: [[LB1:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]]
+// CHECK: [[LB1_0:%.+]] = getelementptr inbounds i32, i32* [[LB1]], i64 0
+// CHECK: [[IDX1:%.+]] = mul nsw i64 1, %{{.+}}
+// CHECK: [[UB1:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]]
+// CHECK: [[UB1_UP:%.+]] = getelementptr inbounds i32, i32* [[UB1]], i64 %
+// CHECK: [[UB_CAST:%.+]] = ptrtoint i32* [[UB1_UP]] to i64
+// CHECK: [[LB_CAST:%.+]] = ptrtoint i32* [[LB1_0]] to i64
+// CHECK: [[DIFF:%.+]] = sub i64 [[UB_CAST]], [[LB_CAST]]
+// CHECK: [[SIZE_1:%.+]] = sdiv exact i64 [[DIFF]], ptrtoint (i32* getelementptr (i32, i32* null, i32 1) to i64)
+// CHECK: [[ARR_SIZE:%.+]] = add nuw i64 [[SIZE_1]], 1
+// CHECK: call i8* @llvm.stacksave()
+// CHECK: [[ARR_PRIV:%.+]] = alloca i32, i64 [[ARR_SIZE]],
+
+// Check initialization of private copy.
+// CHECK: [[END:%.+]] = getelementptr i32, i32* [[ARR_PRIV]], i64 [[ARR_SIZE]]
+// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[ARR_PRIV]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi i32*
+// CHECK: store i32 888, i32* %
+// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]]
+// CHECK: br i1 [[DONE]],
+
+// CHECK: [[ARRS_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[ARRS_SIZE:%.+]],
+
+// Check initialization of private copy.
+// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[ARRS_PRIV]], i64 [[ARRS_SIZE]]
+// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[ARRS_PRIV]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi [[S_FLOAT_TY]]*
+// CHECK: call void @_Z4initR6BaseS1RKS_(%
+// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]]
+// CHECK: br i1 [[DONE]],
+
+// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
+// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
+// CHECK: call void @__kmpc_for_static_init_4(
+// Skip checks for internal operations.
+// CHECK: call void @__kmpc_for_static_fini(
+
+// void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
+
+// CHECK: [[ARR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 0
+// CHECK: [[BITCAST:%.+]] = bitcast i32* [[ARR_PRIV]] to i8*
+// CHECK: store i8* [[BITCAST]], i8** [[ARR_PRIV_REF]],
+// CHECK: [[ARR_SIZE_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 1
+// CHECK: [[BITCAST:%.+]] = inttoptr i64 [[ARR_SIZE]] to i8*
+// CHECK: store i8* [[BITCAST]], i8** [[ARR_SIZE_REF]],
+// CHECK: [[ARRS_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 2
+// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[ARRS_PRIV]] to i8*
+// CHECK: store i8* [[BITCAST]], i8** [[ARRS_PRIV_REF]],
+// CHECK: [[ARRS_SIZE_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 3
+// CHECK: [[BITCAST:%.+]] = inttoptr i64 [[ARRS_SIZE]] to i8*
+// CHECK: store i8* [[BITCAST]], i8** [[ARRS_SIZE_REF]],
+
+// res = __kmpc_reduce(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>);
+
+// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
+// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
+// CHECK: [[BITCAST:%.+]] = bitcast [4 x i8*]* [[RED_LIST]] to i8*
+// CHECK: [[RES:%.+]] = call i32 @__kmpc_reduce_nowait(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], i32 2, i64 32, i8* [[BITCAST]], void (i8*, i8*)* [[REDUCTION_FUNC:@.+]], [8 x i32]* [[REDUCTION_LOCK]])
+
+// switch(res)
+// CHECK: switch i32 [[RES]], label %[[RED_DONE:.+]] [
+// CHECK: i32 1, label %[[CASE1:.+]]
+// CHECK: i32 2, label %[[CASE2:.+]]
+// CHECK: ]
+
+// case 1:
+// CHECK: [[CASE1]]
+
+// arr[:] += arr_reduction[:];
+// CHECK: [[END:%.+]] = getelementptr i32, i32* [[LB1_0]], i64 [[ARR_SIZE]]
+// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[LB1_0]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi i32*
+// CHECK: [[ADD:%.+]] = mul nsw i32 555, %
+// CHECK: store i32 [[ADD]], i32* %
+// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]]
+// CHECK: br i1 [[DONE]],
+
+// arrs[:] = var.operator &(arrs_reduction[:]);
+// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[ARRS_LB:%.+]], i64 [[ARRS_SIZE]]
+// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[ARRS_LB]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi [[S_FLOAT_TY]]*
+// CHECK: call void @_Z3redR6BaseS1RKS_(%
+// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]]
+// CHECK: br i1 [[DONE]],
+
+// __kmpc_end_reduce(<loc>, <gtid>, &<lock>);
+// CHECK: call void @__kmpc_end_reduce_nowait(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]])
+
+// break;
+// CHECK: br label %[[RED_DONE]]
+
+// case 2:
+// CHECK: [[CASE2]]
+
+// arr[:] += arr_reduction[:];
+// CHECK: [[END:%.+]] = getelementptr i32, i32* [[LB1_0]], i64 [[ARR_SIZE]]
+// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[LB1_0]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi i32*
+// CHECK: call void @__kmpc_critical(
+// CHECK: [[ADD:%.+]] = mul nsw i32 555, %
+// CHECK: call void @__kmpc_end_critical(
+// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]]
+// CHECK: br i1 [[DONE]],
+
+// arrs[:] = var.operator &(arrs_reduction[:]);
+// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[ARRS_LB:%.+]], i64 [[ARRS_SIZE]]
+// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[ARRS_LB]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi [[S_FLOAT_TY]]*
+// CHECK: call void @__kmpc_critical(
+// CHECK: call void @_Z3redR6BaseS1RKS_(%
+// CHECK: call void @__kmpc_end_critical(
+// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]]
+// CHECK: br i1 [[DONE]],
+
+// break;
+// CHECK: br label %[[RED_DONE]]
+// CHECK: [[RED_DONE]]
+
+// Check destruction of private copy.
+// CHECK: [[END:%.+]] = getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[ARRS_PRIV]], i64 [[ARRS_SIZE]]
+// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[ARRS_PRIV]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi [[S_FLOAT_TY]]*
+// CHECK: call void @_ZN1SIfED1Ev([[S_FLOAT_TY]]* %
+// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[ARRS_PRIV]]
+// CHECK: br i1 [[DONE]],
+// CHECK: call void @llvm.stackrestore(i8*
+
+// CHECK: ret void
+
+// void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
+// *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]);
+// ...
+// *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1],
+// *(Type<n>-1*)rhs[<n>-1]);
+// }
+// CHECK: define internal void [[REDUCTION_FUNC]](i8*, i8*)
+// arr_rhs = (int*)rhs[0];
+// CHECK: [[ARR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS:%.+]], i64 0, i64 0
+// CHECK: [[ARR_RHS_VOID:%.+]] = load i8*, i8** [[ARR_RHS_REF]],
+// CHECK: [[ARR_RHS:%.+]] = bitcast i8* [[ARR_RHS_VOID]] to i32*
+// arr_lhs = (int*)lhs[0];
+// CHECK: [[ARR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS:%.+]], i64 0, i64 0
+// CHECK: [[ARR_LHS_VOID:%.+]] = load i8*, i8** [[ARR_LHS_REF]],
+// CHECK: [[ARR_LHS:%.+]] = bitcast i8* [[ARR_LHS_VOID]] to i32*
+
+// arr_size = (size_t)lhs[1];
+// CHECK: [[ARR_SIZE_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 1
+// CHECK: [[ARR_SIZE_VOID:%.+]] = load i8*, i8** [[ARR_SIZE_REF]],
+// CHECK: [[ARR_SIZE:%.+]] = ptrtoint i8* [[ARR_SIZE_VOID]] to i64
+
+// arrs_rhs = (S<float>*)rhs[2];
+// CHECK: [[ARRS_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 2
+// CHECK: [[ARRS_RHS_VOID:%.+]] = load i8*, i8** [[ARRS_RHS_REF]],
+// CHECK: [[ARRS_RHS:%.+]] = bitcast i8* [[ARRS_RHS_VOID]] to [[S_FLOAT_TY]]*
+// arrs_lhs = (S<float>*)lhs[2];
+// CHECK: [[ARRS_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 2
+// CHECK: [[ARRS_LHS_VOID:%.+]] = load i8*, i8** [[ARRS_LHS_REF]],
+// CHECK: [[ARRS_LHS:%.+]] = bitcast i8* [[ARRS_LHS_VOID]] to [[S_FLOAT_TY]]*
+
+// arrs_size = (size_t)lhs[3];
+// CHECK: [[ARRS_SIZE_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 3
+// CHECK: [[ARRS_SIZE_VOID:%.+]] = load i8*, i8** [[ARRS_SIZE_REF]],
+// CHECK: [[ARRS_SIZE:%.+]] = ptrtoint i8* [[ARRS_SIZE_VOID]] to i64
+
+// arr_lhs[:] += arr_rhs[:];
+// CHECK: [[END:%.+]] = getelementptr i32, i32* [[ARR_LHS]], i64 [[ARR_SIZE]]
+// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[ARR_LHS]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi i32*
+// CHECK: [[ADD:%.+]] = mul nsw i32 555, %
+// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]]
+// CHECK: br i1 [[DONE]],
+
+// arrs_lhs = arrs_lhs.operator &(arrs_rhs);
+// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[ARRS_LB:%.+]], i64 [[ARRS_SIZE]]
+// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[ARRS_LB]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi [[S_FLOAT_TY]]*
+// CHECK: call void @_Z3redR6BaseS1RKS_(%
+// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]]
+// CHECK: br i1 [[DONE]],
+
+// CHECK: ret void
+
+// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* nonnull %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(480) %{{.+}})
+
+// CHECK: [[ARRS_PRIV:%.+]] = alloca [10 x [4 x [[S_FLOAT_TY]]]],
+
+// Reduction list for runtime.
+// CHECK: [[RED_LIST:%.+]] = alloca [3 x i8*],
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+
+// CHECK: [[ARR_SIZE:%.+]] = mul nuw i64 %{{.+}}, 4
+// CHECK: call i8* @llvm.stacksave()
+// CHECK: [[ARR_PRIV:%.+]] = alloca i32, i64 [[ARR_SIZE]],
+
+// Check initialization of private copy.
+// CHECK: [[END:%.+]] = getelementptr i32, i32* [[ARR_PRIV]], i64 [[ARR_SIZE]]
+// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[ARR_PRIV]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi i32*
+// CHECK: store i32 888, i32* %
+// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]]
+// CHECK: br i1 [[DONE]],
+
+// Check initialization of private copy.
+// CHECK: [[LHS_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* %{{.+}} to [[S_FLOAT_TY]]*
+// CHECK: [[BEGIN:%.+]] = getelementptr inbounds [10 x [4 x [[S_FLOAT_TY]]]], [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]], i32 0, i32 0, i32 0
+// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[BEGIN]], i64 40
+// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[BEGIN]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi [[S_FLOAT_TY]]*
+// CHECK: call void @_Z4initR6BaseS1RKS_(%
+// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]]
+// CHECK: br i1 [[DONE]],
+// CHECK: [[ARRS_PRIV_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]] to [[S_FLOAT_TY]]*
+
+// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
+// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
+// CHECK: call void @__kmpc_for_static_init_4(
+// Skip checks for internal operations.
+// CHECK: call void @__kmpc_for_static_fini(
+
+// void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
+
+// CHECK: [[ARR_PRIV_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST]], i64 0, i64 0
+// CHECK: [[BITCAST:%.+]] = bitcast i32* [[ARR_PRIV]] to i8*
+// CHECK: store i8* [[BITCAST]], i8** [[ARR_PRIV_REF]],
+// CHECK: [[ARR_SIZE_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST]], i64 0, i64 1
+// CHECK: [[BITCAST:%.+]] = inttoptr i64 [[ARR_SIZE]] to i8*
+// CHECK: store i8* [[BITCAST]], i8** [[ARR_SIZE_REF]],
+// CHECK: [[ARRS_PRIV_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST]], i64 0, i64 2
+// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[ARRS_PRIV_BEGIN]] to i8*
+// CHECK: store i8* [[BITCAST]], i8** [[ARRS_PRIV_REF]],
+
+// res = __kmpc_reduce(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>);
+
+// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
+// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
+// CHECK: [[BITCAST:%.+]] = bitcast [3 x i8*]* [[RED_LIST]] to i8*
+// CHECK: [[RES:%.+]] = call i32 @__kmpc_reduce(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], i32 2, i64 24, i8* [[BITCAST]], void (i8*, i8*)* [[REDUCTION_FUNC:@.+]], [8 x i32]* [[REDUCTION_LOCK]])
+
+// switch(res)
+// CHECK: switch i32 [[RES]], label %[[RED_DONE:.+]] [
+// CHECK: i32 1, label %[[CASE1:.+]]
+// CHECK: i32 2, label %[[CASE2:.+]]
+// CHECK: ]
+
+// case 1:
+// CHECK: [[CASE1]]
+
+// arr[:] += arr_reduction[:];
+// CHECK: [[END:%.+]] = getelementptr i32, i32* [[LB1_0:%.+]], i64 [[ARR_SIZE]]
+// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[LB1_0]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi i32*
+// CHECK: [[ADD:%[^ ]+]] = mul nsw i32 555, %
+// CHECK: store i32 [[ADD]], i32* %
+// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]]
+// CHECK: br i1 [[DONE]],
+
+// arrs[:] = var.operator &(arrs_reduction[:]);
+// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[LHS_BEGIN]], i64 40
+// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[LHS_BEGIN]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi [[S_FLOAT_TY]]*
+// CHECK: call void @_Z3redR6BaseS1RKS_(%
+// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]]
+// CHECK: br i1 [[DONE]],
+
+// __kmpc_end_reduce(<loc>, <gtid>, &<lock>);
+// CHECK: call void @__kmpc_end_reduce(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]])
+
+// break;
+// CHECK: br label %[[RED_DONE]]
+
+// case 2:
+// CHECK: [[CASE2]]
+
+// arr[:] += arr_reduction[:];
+// CHECK: [[END:%.+]] = getelementptr i32, i32* [[LB1_0]], i64 [[ARR_SIZE]]
+// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[LB1_0]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi i32*
+// CHECK: call void @__kmpc_critical(
+// CHECK: [[ADD:%.+]] = mul nsw i32 555, %
+// CHECK: call void @__kmpc_end_critical(
+// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]]
+// CHECK: br i1 [[DONE]],
+
+// arrs[:] = var.operator &(arrs_reduction[:]);
+// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[LHS_BEGIN]], i64 40
+// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[LHS_BEGIN]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi [[S_FLOAT_TY]]*
+// CHECK: call void @__kmpc_critical(
+// CHECK: call void @_Z3redR6BaseS1RKS_(%
+// CHECK: call void @__kmpc_end_critical(
+// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]]
+// CHECK: br i1 [[DONE]],
+
+// break;
+// CHECK: br label %[[RED_DONE]]
+// CHECK: [[RED_DONE]]
+
+// Check destruction of private copy.
+// CHECK: [[BEGIN:%.+]] = getelementptr inbounds [10 x [4 x [[S_FLOAT_TY]]]], [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]], i32 0, i32 0, i32 0
+// CHECK: [[END:%.+]] = getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[BEGIN]], i64 40
+// CHECK: br
+// CHECK: phi [[S_FLOAT_TY]]*
+// CHECK: call void @_ZN1SIfED1Ev([[S_FLOAT_TY]]* %
+// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[BEGIN]]
+// CHECK: br i1 [[DONE]],
+// CHECK: call void @llvm.stackrestore(i8*
+// CHECK: call void @__kmpc_barrier(
+
+// CHECK: ret void
+
+// void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
+// *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]);
+// ...
+// *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1],
+// *(Type<n>-1*)rhs[<n>-1]);
+// }
+// CHECK: define internal void [[REDUCTION_FUNC]](i8*, i8*)
+// arr_rhs = (int*)rhs[0];
+// CHECK: [[ARR_RHS_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_RHS:%.+]], i64 0, i64 0
+// CHECK: [[ARR_RHS_VOID:%.+]] = load i8*, i8** [[ARR_RHS_REF]],
+// CHECK: [[ARR_RHS:%.+]] = bitcast i8* [[ARR_RHS_VOID]] to i32*
+// arr_lhs = (int*)lhs[0];
+// CHECK: [[ARR_LHS_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_LHS:%.+]], i64 0, i64 0
+// CHECK: [[ARR_LHS_VOID:%.+]] = load i8*, i8** [[ARR_LHS_REF]],
+// CHECK: [[ARR_LHS:%.+]] = bitcast i8* [[ARR_LHS_VOID]] to i32*
+
+// arr_size = (size_t)lhs[1];
+// CHECK: [[ARR_SIZE_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_LHS]], i64 0, i64 1
+// CHECK: [[ARR_SIZE_VOID:%.+]] = load i8*, i8** [[ARR_SIZE_REF]],
+// CHECK: [[ARR_SIZE:%.+]] = ptrtoint i8* [[ARR_SIZE_VOID]] to i64
+
+// arrs_rhs = (S<float>*)rhs[2];
+// CHECK: [[ARRS_RHS_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_RHS]], i64 0, i64 2
+// CHECK: [[ARRS_RHS_VOID:%.+]] = load i8*, i8** [[ARRS_RHS_REF]],
+// CHECK: [[ARRS_RHS:%.+]] = bitcast i8* [[ARRS_RHS_VOID]] to [[S_FLOAT_TY]]*
+// arrs_lhs = (S<float>*)lhs[2];
+// CHECK: [[ARRS_LHS_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_LHS]], i64 0, i64 2
+// CHECK: [[ARRS_LHS_VOID:%.+]] = load i8*, i8** [[ARRS_LHS_REF]],
+// CHECK: [[ARRS_LHS:%.+]] = bitcast i8* [[ARRS_LHS_VOID]] to [[S_FLOAT_TY]]*
+
+// arr_lhs[:] += arr_rhs[:];
+// CHECK: [[END:%.+]] = getelementptr i32, i32* [[ARR_LHS]], i64 [[ARR_SIZE]]
+// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[ARR_LHS]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi i32*
+// CHECK: [[ADD:%.+]] = mul nsw i32 555, %
+// CHECK: store i32 [[ADD]], i32* %
+// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]]
+// CHECK: br i1 [[DONE]],
+
+// arrs_lhs = arrs_lhs.operator &(arrs_rhs);
+// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[ARRS_LB:%.+]], i64 40
+// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[ARRS_LB]], [[END]]
+// CHECK: br i1 [[ISEMPTY]],
+// CHECK: phi [[S_FLOAT_TY]]*
+// CHECK: call void @_Z3redR6BaseS1RKS_(%
+// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]]
+// CHECK: br i1 [[DONE]],
+
+// CHECK: ret void
+
+// CHECK: define internal void [[MAIN_MICROTASK3]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[S_FLOAT_TY]]*** dereferenceable(8) %{{.+}})
+
+// CHECK: [[VAR2_ORIG_ADDR:%.+]] = alloca [[S_FLOAT_TY]]***,
+
+// Reduction list for runtime.
+// CHECK: [[RED_LIST:%.+]] = alloca [2 x i8*],
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+// CHECK: [[VAR2_ORIG:%.+]] = load [[S_FLOAT_TY]]***, [[S_FLOAT_TY]]**** [[VAR2_ORIG_ADDR]],
+
+// CHECK: load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],
+// CHECK: getelementptr inbounds [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %{{.+}}, i64 0
+// CHECK: load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %
+// CHECK: [[LOW:%.+]] = getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 1
+// CHECK: load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],
+// CHECK: getelementptr inbounds [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %{{.+}}, i64 4
+// CHECK: load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %
+// CHECK: getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 6
+// CHECK: [[LD:%.+]] = load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],
+// CHECK: [[ORIG_START:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[LD]],
+// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64
+// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
+// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]]
+// CHECK: [[DIF:%.+]] = sdiv exact i64 [[BYTE_DIF]], ptrtoint ([[S_FLOAT_TY]]* getelementptr ([[S_FLOAT_TY]], [[S_FLOAT_TY]]* null, i32 1) to i64)
+// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1
+// CHECK: call i8* @llvm.stacksave()
+// CHECK: [[VAR2_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]],
+// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64
+// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
+// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]
+// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint ([[S_FLOAT_TY]]* getelementptr ([[S_FLOAT_TY]], [[S_FLOAT_TY]]* null, i32 1) to i64)
+// CHECK: [[PSEUDO_VAR2_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VAR2_PRIV]], i64 [[OFFSET]]
+// CHECK: store [[S_FLOAT_TY]]** [[REF:.+]], [[S_FLOAT_TY]]*** %
+// CHECK: store [[S_FLOAT_TY]]* [[PSEUDO_VAR2_PRIV]], [[S_FLOAT_TY]]** [[REF]]
+// CHECK: ret void
+
+// CHECK: define internal void [[MAIN_MICROTASK4]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(24) %{{.+}})
+
+// CHECK: [[VVAR2_ORIG_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+
+// Reduction list for runtime.
+// CHECK: [[RED_LIST:%.+]] = alloca [2 x i8*],
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+// CHECK: [[VVAR2_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VVAR2_ORIG_ADDR]],
+
+// CHECK: [[LOW:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]], i64 0, i64 0
+// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]], i64 0, i64 4
+// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]] to [[S_FLOAT_TY]]*
+// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64
+// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
+// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]]
+// CHECK: [[DIF:%.+]] = sdiv exact i64 [[BYTE_DIF]], ptrtoint ([[S_FLOAT_TY]]* getelementptr ([[S_FLOAT_TY]], [[S_FLOAT_TY]]* null, i32 1) to i64)
+// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1
+// CHECK: call i8* @llvm.stacksave()
+// CHECK: [[VVAR2_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]],
+// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64
+// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
+// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]
+// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint ([[S_FLOAT_TY]]* getelementptr ([[S_FLOAT_TY]], [[S_FLOAT_TY]]* null, i32 1) to i64)
+// CHECK: [[PSEUDO_VVAR2_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VVAR2_PRIV]], i64 [[OFFSET]]
+// CHECK: [[VVAR2_PRIV:%.+]] = bitcast [[S_FLOAT_TY]]* [[PSEUDO_VVAR2_PRIV]] to [2 x [[S_FLOAT_TY]]]*
+// CHECK: ret void
+
+// CHECK: define internal void [[MAIN_MICROTASK5]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(24) %{{.+}})
+
+// CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+
+// Reduction list for runtime.
+// CHECK: [[RED_LIST:%.+]] = alloca [2 x i8*],
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+
+// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]],
+// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: [[LOW:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], i64 0, i64 1
+// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], i64 0, i64 2
+// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*
+// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64
+// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
+// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]]
+// CHECK: [[DIF:%.+]] = sdiv exact i64 [[BYTE_DIF]], ptrtoint ([[S_FLOAT_TY]]* getelementptr ([[S_FLOAT_TY]], [[S_FLOAT_TY]]* null, i32 1) to i64)
+// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1
+// CHECK: call i8* @llvm.stacksave()
+// CHECK: [[VAR3_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]],
+// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64
+// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
+// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]
+// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint ([[S_FLOAT_TY]]* getelementptr ([[S_FLOAT_TY]], [[S_FLOAT_TY]]* null, i32 1) to i64)
+// CHECK: [[PSEUDO_VAR3_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VAR3_PRIV]], i64 [[OFFSET]]
+// CHECK: [[VAR3_PRIV:%.+]] = bitcast [[S_FLOAT_TY]]* [[PSEUDO_VAR3_PRIV]] to [2 x [[S_FLOAT_TY]]]*
+
+// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [2 x [[S_FLOAT_TY]]]** %
+
+// CHECK: ret void
+
+// CHECK: define internal void [[MAIN_MICROTASK6]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(24) %{{.+}})
+
+// CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR3_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+
+// Reduction list for runtime.
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x i8*],
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+
+// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]],
+// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*
+// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], i32 0, i32 0
+// CHECK: getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 2
+
+// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [2 x [[S_FLOAT_TY]]]** %
+
+// CHECK: ret void
+
+// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
+// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
+// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 6, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i32*, [[S_INT_TY]]*, [[S_INT_TY]]*, i32*, [2 x i32]*, [2 x [[S_INT_TY]]]*)* [[TMAIN_MICROTASK:@.+]] to void
+// CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
+// CHECK: ret
+//
+// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, [[S_INT_TY]]* dereferenceable(12) %{{.+}}, [[S_INT_TY]]* dereferenceable(12) %{{.+}}, i32* dereferenceable(4) %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(24) %{{.+}})
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[VAR1_PRIV:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[T_VAR1_PRIV:%.+]] = alloca i{{[0-9]+}},
+
+// Reduction list for runtime.
+// CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*],
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+
+// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %
+// CHECK: [[VAR1_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** %
+// CHECK: [[T_VAR1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %
+
+// For + reduction operation initial value of private variable is 0.
+// CHECK: store i32 321, i32* %
+
+// For & reduction operation initial value of private variable is ones in all bits.
+// CHECK: call void @_Z4initR6BaseS1RKS_(
+
+// For && reduction operation initial value of private variable is 1.0.
+// CHECK: call void @_Z5init2R6BaseS1RKS_(
+
+// For min reduction operation initial value of private variable is largest repesentable value.
+// CHECK: sdiv i32 432, %
+
+// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
+// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
+// CHECK: call void @__kmpc_for_static_init_4(
+// Skip checks for internal operations.
+// CHECK: call void @__kmpc_for_static_fini(
+
+// void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
+
+// CHECK: [[T_VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 0
+// CHECK: [[BITCAST:%.+]] = bitcast i{{[0-9]+}}* [[T_VAR_PRIV]] to i8*
+// CHECK: store i8* [[BITCAST]], i8** [[T_VAR_PRIV_REF]],
+// CHECK: [[VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 1
+// CHECK: [[BITCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR_PRIV]] to i8*
+// CHECK: store i8* [[BITCAST]], i8** [[VAR_PRIV_REF]],
+// CHECK: [[VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 2
+// CHECK: [[BITCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR1_PRIV]] to i8*
+// CHECK: store i8* [[BITCAST]], i8** [[VAR1_PRIV_REF]],
+// CHECK: [[T_VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 3
+// CHECK: [[BITCAST:%.+]] = bitcast i{{[0-9]+}}* [[T_VAR1_PRIV]] to i8*
+// CHECK: store i8* [[BITCAST]], i8** [[T_VAR1_PRIV_REF]],
+
+// res = __kmpc_reduce_nowait(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>);
+
+// CHECK: [[BITCAST:%.+]] = bitcast [4 x i8*]* [[RED_LIST]] to i8*
+// CHECK: [[RES:%.+]] = call i32 @__kmpc_reduce_nowait(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], i32 4, i64 32, i8* [[BITCAST]], void (i8*, i8*)* [[REDUCTION_FUNC:@.+]], [8 x i32]* [[REDUCTION_LOCK]])
+
+// switch(res)
+// CHECK: switch i32 [[RES]], label %[[RED_DONE:.+]] [
+// CHECK: i32 1, label %[[CASE1:.+]]
+// CHECK: i32 2, label %[[CASE2:.+]]
+// CHECK: ]
+
+// case 1:
+// t_var += t_var_reduction;
+// CHECK: add nsw i32 1513, %
+
+// var = var.operator &(var_reduction);
+// CHECK: call void @_Z3redR6BaseS1RKS_(%
+
+// var1 = var1.operator &&(var1_reduction);
+// CHECK: mul nsw i32 17, %
+
+// t_var1 = min(t_var1, t_var1_reduction);
+// CHECK: sub nsw i32 47, %
+
+// __kmpc_end_reduce_nowait(<loc>, <gtid>, &<lock>);
+// CHECK: call void @__kmpc_end_reduce_nowait(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]])
+
+// break;
+// CHECK: br label %[[RED_DONE]]
+
+// case 2:
+// t_var += t_var_reduction;
+// CHECK: call void @__kmpc_critical(
+// CHECK: add nsw i32 1513, %
+// CHECK: call void @__kmpc_end_critical(
+
+// var = var.operator &(var_reduction);
+// CHECK: call void @__kmpc_critical(
+// CHECK: call void @_Z3redR6BaseS1RKS_(%
+// CHECK: call void @__kmpc_end_critical(
+
+// var1 = var1.operator &&(var1_reduction);
+// CHECK: call void @__kmpc_critical(
+// CHECK: mul nsw i32 17, %
+// CHECK: call void @__kmpc_end_critical(
+
+// t_var1 = min(t_var1, t_var1_reduction);
+// CHECK: call void @__kmpc_critical(
+// CHECK: sub nsw i32 47, %
+// CHECK: call void @__kmpc_end_critical(
+
+// break;
+// CHECK: br label %[[RED_DONE]]
+// CHECK: [[RED_DONE]]
+// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]])
+// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]*
+// CHECK: ret void
+
+// void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
+// *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]);
+// ...
+// *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1],
+// *(Type<n>-1*)rhs[<n>-1]);
+// }
+// CHECK: define internal void [[REDUCTION_FUNC]](i8*, i8*)
+// t_var_lhs = (i{{[0-9]+}}*)lhs[0];
+// CHECK: [[T_VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS:%.+]], i64 0, i64 0
+// CHECK: [[T_VAR_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR_RHS_REF]],
+// CHECK: [[T_VAR_RHS:%.+]] = bitcast i8* [[T_VAR_RHS_VOID]] to i{{[0-9]+}}*
+// t_var_rhs = (i{{[0-9]+}}*)rhs[0];
+// CHECK: [[T_VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS:%.+]], i64 0, i64 0
+// CHECK: [[T_VAR_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR_LHS_REF]],
+// CHECK: [[T_VAR_LHS:%.+]] = bitcast i8* [[T_VAR_LHS_VOID]] to i{{[0-9]+}}*
+
+// var_lhs = (S<i{{[0-9]+}}>*)lhs[1];
+// CHECK: [[VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 1
+// CHECK: [[VAR_RHS_VOID:%.+]] = load i8*, i8** [[VAR_RHS_REF]],
+// CHECK: [[VAR_RHS:%.+]] = bitcast i8* [[VAR_RHS_VOID]] to [[S_INT_TY]]*
+// var_rhs = (S<i{{[0-9]+}}>*)rhs[1];
+// CHECK: [[VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 1
+// CHECK: [[VAR_LHS_VOID:%.+]] = load i8*, i8** [[VAR_LHS_REF]],
+// CHECK: [[VAR_LHS:%.+]] = bitcast i8* [[VAR_LHS_VOID]] to [[S_INT_TY]]*
+
+// var1_lhs = (S<i{{[0-9]+}}>*)lhs[2];
+// CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 2
+// CHECK: [[VAR1_RHS_VOID:%.+]] = load i8*, i8** [[VAR1_RHS_REF]],
+// CHECK: [[VAR1_RHS:%.+]] = bitcast i8* [[VAR1_RHS_VOID]] to [[S_INT_TY]]*
+// var1_rhs = (S<i{{[0-9]+}}>*)rhs[2];
+// CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 2
+// CHECK: [[VAR1_LHS_VOID:%.+]] = load i8*, i8** [[VAR1_LHS_REF]],
+// CHECK: [[VAR1_LHS:%.+]] = bitcast i8* [[VAR1_LHS_VOID]] to [[S_INT_TY]]*
+
+// t_var1_lhs = (i{{[0-9]+}}*)lhs[3];
+// CHECK: [[T_VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 3
+// CHECK: [[T_VAR1_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_RHS_REF]],
+// CHECK: [[T_VAR1_RHS:%.+]] = bitcast i8* [[T_VAR1_RHS_VOID]] to i{{[0-9]+}}*
+// t_var1_rhs = (i{{[0-9]+}}*)rhs[3];
+// CHECK: [[T_VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 3
+// CHECK: [[T_VAR1_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_LHS_REF]],
+// CHECK: [[T_VAR1_LHS:%.+]] = bitcast i8* [[T_VAR1_LHS_VOID]] to i{{[0-9]+}}*
+
+// t_var_lhs += t_var_rhs;
+// CHECK: add nsw i32 1513, %
+
+// var_lhs = var_lhs.operator &(var_rhs);
+// CHECK: call void @_Z3redR6BaseS1RKS_(%
+
+// var1_lhs = var1_lhs.operator &&(var1_rhs);
+// CHECK: mul nsw i32 17, %
+
+// t_var1_lhs = min(t_var1_lhs, t_var1_rhs);
+// CHECK: sub nsw i32 47, %
+// CHECK: ret void
+
+#endif
+
diff --git a/test/OpenMP/for_reduction_messages.cpp b/test/OpenMP/for_reduction_messages.cpp
index 317f88ce11ba9..45a4681440fc2 100644
--- a/test/OpenMP/for_reduction_messages.cpp
+++ b/test/OpenMP/for_reduction_messages.cpp
@@ -13,7 +13,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat
extern S1 a;
class S2 {
mutable int a;
- S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}}
+ S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}}
public:
S2() : a(0) {}
@@ -22,7 +22,7 @@ public:
static const float S2sc;
};
const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
-S2 b; // expected-note 2 {{'b' defined here}}
+S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
int a;
@@ -33,7 +33,7 @@ public:
S3 operator+(const S3 &arg1) { return arg1; }
};
int operator+(const S3 &arg1, const S3 &arg2) { return 5; }
-S3 c; // expected-note 2 {{'c' defined here}}
+S3 c; // expected-note 3 {{'c' defined here}}
const S3 ca[5]; // expected-note 2 {{'ca' defined here}}
extern const int f; // expected-note 4 {{'f' declared here}}
class S4 {
@@ -55,9 +55,9 @@ class S5 {
public:
S5(int v) : a(v) {}
};
-class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
#if __cplusplus >= 201103L // C++11 or later
-// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable: no known conversion from 'int' to 'S6' for 1st argument}}
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable: no known conversion from 'int' to 'S6' for 1st argument}}
#endif
int a;
@@ -123,7 +123,7 @@ T tmain(T argc) {
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
-#pragma omp for reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+#pragma omp for reduction(foo : argc) // expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
@@ -135,11 +135,11 @@ T tmain(T argc) {
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
-#pragma omp for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}}
+#pragma omp for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
-#pragma omp for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
@@ -147,15 +147,15 @@ T tmain(T argc) {
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
-#pragma omp for reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}}
+#pragma omp for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
-#pragma omp for reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}}
+#pragma omp for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
-#pragma omp for reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}}
+#pragma omp for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
@@ -175,7 +175,7 @@ T tmain(T argc) {
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
-#pragma omp for reduction(+ : o) // expected-error {{no viable overloaded '='}}
+#pragma omp for reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
@@ -187,7 +187,7 @@ T tmain(T argc) {
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
-#pragma omp for reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}}
+#pragma omp for reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
@@ -304,15 +304,15 @@ int main(int argc, char **argv) {
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
-#pragma omp for reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}}
+#pragma omp for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
-#pragma omp for reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}}
+#pragma omp for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
-#pragma omp for reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}}
+#pragma omp for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
diff --git a/test/OpenMP/for_simd_aligned_messages.cpp b/test/OpenMP/for_simd_aligned_messages.cpp
index 1007b3c545cc0..cef83c30e239c 100644
--- a/test/OpenMP/for_simd_aligned_messages.cpp
+++ b/test/OpenMP/for_simd_aligned_messages.cpp
@@ -196,6 +196,7 @@ int main(int argc, char **argv) {
#pragma omp for simd aligned(h)
for (int k = 0; k < argc; ++k) ++k;
int *pargc = &argc;
+ // expected-note@+1 {{in instantiation of function template specialization 'foomain<int *, char>' requested here}}
foomain<int*,char>(pargc,argv);
return 0;
}
diff --git a/test/OpenMP/for_simd_ast_print.cpp b/test/OpenMP/for_simd_ast_print.cpp
index d4b13ba1998c8..54f0d4676134d 100644
--- a/test/OpenMP/for_simd_ast_print.cpp
+++ b/test/OpenMP/for_simd_ast_print.cpp
@@ -6,6 +6,57 @@
#ifndef HEADER
#define HEADER
+struct S1 {
+ S1(): a(0) {}
+ S1(int v) : a(v) {}
+ int a;
+ typedef int type;
+};
+
+template <typename T>
+class S7 : public T {
+protected:
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(typename T::type v) : a(v) {
+#pragma omp for simd private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp for simd private(a) private(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp for simd private(this->a) private(this->a) private(this->S1::a)
+// CHECK: #pragma omp for simd private(this->a) private(this->a) private(T::a)
+// CHECK: #pragma omp for simd private(this->a) private(this->a)
+
+class S8 : public S7<S1> {
+ S8() {}
+
+public:
+ S8(int v) : S7<S1>(v){
+#pragma omp for simd private(a) private(this->a) private(S7<S1>::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S8 &operator=(S8 &s) {
+#pragma omp for simd private(a) private(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp for simd private(this->a) private(this->a) private(this->S7<S1>::a)
+// CHECK: #pragma omp for simd private(this->a) private(this->a)
+
void foo() {}
int g_ind = 1;
template<class T, class N> T reduct(T* arr, N num) {
diff --git a/test/OpenMP/for_simd_codegen.cpp b/test/OpenMP/for_simd_codegen.cpp
index e1aa8926418f8..fb282d0511bb5 100644
--- a/test/OpenMP/for_simd_codegen.cpp
+++ b/test/OpenMP/for_simd_codegen.cpp
@@ -54,13 +54,13 @@ void simple(float *a, float *b, float *c, float *d) {
long long k = get_val();
- #pragma omp for simd linear(k : 3) schedule(dynamic)
+ #pragma omp for simd linear(k : 3) schedule(simd, nonmonotonic: dynamic)
// CHECK: [[K0:%.+]] = call {{.*}}i64 @{{.*}}get_val
// CHECK-NEXT: store i64 [[K0]], i64* [[K_VAR:%[^,]+]]
// CHECK: [[K0LOAD:%.+]] = load i64, i64* [[K_VAR]]
// CHECK-NEXT: store i64 [[K0LOAD]], i64* [[LIN0:%[^,]+]]
-// CHECK: call void @__kmpc_dispatch_init_4(%ident_t* {{.+}}, i32 %{{.+}}, i32 35, i32 0, i32 8, i32 1, i32 1)
+// CHECK: call void @__kmpc_dispatch_init_4(%ident_t* {{.+}}, i32 %{{.+}}, i32 1073741859, i32 0, i32 8, i32 1, i32 1)
// CHECK: [[NEXT:%.+]] = call i32 @__kmpc_dispatch_next_4(%ident_t* {{.+}}, i32 %{{.+}}, i32* %{{.+}}, i32* [[LB:%.+]], i32* [[UB:%.+]], i32* %{{.+}})
// CHECK: [[COND:%.+]] = icmp ne i32 [[NEXT]], 0
// CHECK: br i1 [[COND]], label %[[CONT:.+]], label %[[END:.+]]
@@ -362,7 +362,7 @@ template <class T, unsigned K> T tfoo(T a) { return a + K; }
template <typename T, unsigned N>
int templ1(T a, T *z) {
- #pragma omp for simd collapse(N)
+ #pragma omp for simd collapse(N) schedule(simd: static, N)
for (int i = 0; i < N * 2; i++) {
for (long long j = 0; j < (N + N + N + N); j += 2) {
z[i + j] = a + tfoo<T, N>(i + j);
@@ -373,7 +373,7 @@ int templ1(T a, T *z) {
// Instatiation templ1<float,2>
// CHECK-LABEL: define {{.*i32}} @{{.*}}templ1{{.*}}(float {{.+}}, float* {{.+}})
-// CHECK: call void @__kmpc_for_static_init_8(%ident_t* {{[^,]+}}, i32 %{{[^,]+}}, i32 34, i32* %{{[^,]+}}, i64* [[LB:%[^,]+]], i64* [[UB:%[^,]+]], i64* [[STRIDE:%[^,]+]], i64 1, i64 1)
+// CHECK: call void @__kmpc_for_static_init_8(%ident_t* {{[^,]+}}, i32 %{{[^,]+}}, i32 45, i32* %{{[^,]+}}, i64* [[LB:%[^,]+]], i64* [[UB:%[^,]+]], i64* [[STRIDE:%[^,]+]], i64 1, i64 2)
// CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]],
// CHECK: [[CMP:%.+]] = icmp sgt i64 [[UB_VAL]], 15
// CHECK: br i1 [[CMP]], label %[[TRUE:.+]], label %[[FALSE:[^,]+]]
@@ -389,6 +389,7 @@ int templ1(T a, T *z) {
// CHECK: store i64 [[LB_VAL]], i64* [[T1_OMP_IV:%[^,]+]],
// ...
+// CHECK: icmp sle i64
// CHECK: [[IV:%.+]] = load i64, i64* [[T1_OMP_IV]]
// CHECK-NEXT: [[UB_VAL:%.+]] = load i64, i64* [[UB]]
// CHECK-NEXT: [[CMP1:%.+]] = icmp sle i64 [[IV]], [[UB_VAL]]
@@ -581,9 +582,11 @@ void collapsed(float *a, float *b, float *c, float *d) {
}
// i,j,l are updated; k is not updated.
// CHECK: call void @__kmpc_for_static_fini(%ident_t* {{.+}}, i32 %{{.+}})
-// CHECK-NEXT: store i32 3, i32* [[I:%[^,]+]]
-// CHECK-NEXT: store i32 5, i32* [[I:%[^,]+]]
-// CHECK-NEXT: store i16 9, i16* [[I:%[^,]+]]
+// CHECK: br i1
+// CHECK: store i32 3, i32*
+// CHECK-NEXT: store i32 5,
+// CHECK-NEXT: store i32 7,
+// CHECK-NEXT: store i16 9, i16*
// CHECK: call void @__kmpc_barrier(%ident_t* {{.+}}, i32 %{{.+}})
// CHECK: ret void
}
diff --git a/test/OpenMP/for_simd_collapse_messages.cpp b/test/OpenMP/for_simd_collapse_messages.cpp
index 5c9d058b975c6..2efd49479ea9f 100644
--- a/test/OpenMP/for_simd_collapse_messages.cpp
+++ b/test/OpenMP/for_simd_collapse_messages.cpp
@@ -1,8 +1,13 @@
// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
void foo() {
}
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
bool foobool(int argc) {
return argc;
}
@@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp for simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp for simd', but found only 1}}
- // expected-error@+3 2 {{directive '#pragma omp for simd' cannot contain more than one 'collapse' clause}}
- // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+ // expected-error@+6 2 {{directive '#pragma omp for simd' cannot contain more than one 'collapse' clause}}
+ // expected-error@+5 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
#pragma omp for simd collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp for simd collapse (S) // expected-error {{'S' does not refer to a value}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp for simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp for simd collapse (1)
@@ -59,16 +71,27 @@ int main(int argc, char **argv) {
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp for simd', but found only 1}}
#pragma omp for simd collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}} expected-note {{as specified in 'collapse' clause}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp for simd', but found only 1}}
- #pragma omp for simd collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+ #pragma omp for simd collapse (foobool(1) > 0 ? 1 : 2)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+3 {{expression is not an integral constant expression}}
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
// expected-error@+2 2 {{directive '#pragma omp for simd' cannot contain more than one 'collapse' clause}}
// expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp for simd collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp for simd collapse (S1) // expected-error {{'S1' does not refer to a value}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+1 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp for simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
// expected-error@+3 {{statement after '#pragma omp for simd' must be a for loop}}
diff --git a/test/OpenMP/for_simd_firstprivate_messages.cpp b/test/OpenMP/for_simd_firstprivate_messages.cpp
index cb74ee081710c..4e96866c1a2c2 100644
--- a/test/OpenMP/for_simd_firstprivate_messages.cpp
+++ b/test/OpenMP/for_simd_firstprivate_messages.cpp
@@ -147,7 +147,7 @@ int foomain(int argc, char **argv) {
foo();
#pragma omp parallel reduction(+ : i) // expected-note {{defined as reduction}}
#pragma omp for simd firstprivate(i) // expected-error {{firstprivate variable must be shared}}
- for (i = 0; i < argc; ++i)
+ for (int k = 0; k < argc; ++k)
foo();
return 0;
}
diff --git a/test/OpenMP/for_simd_linear_messages.cpp b/test/OpenMP/for_simd_linear_messages.cpp
index 44370a15664fb..3f93125a38a29 100644
--- a/test/OpenMP/for_simd_linear_messages.cpp
+++ b/test/OpenMP/for_simd_linear_messages.cpp
@@ -208,7 +208,7 @@ int main(int argc, char **argv) {
#pragma omp for simd linear(i)
for (int k = 0; k < argc; ++k) ++k;
- foomain<int,char>(argc,argv);
+ foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
return 0;
}
diff --git a/test/OpenMP/for_simd_loop_messages.cpp b/test/OpenMP/for_simd_loop_messages.cpp
index afd7b0bb545e5..e9729a8fc26d8 100644
--- a/test/OpenMP/for_simd_loop_messages.cpp
+++ b/test/OpenMP/for_simd_loop_messages.cpp
@@ -408,12 +408,12 @@ public:
typedef int difference_type;
typedef std::random_access_iterator_tag iterator_category;
};
-// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 2nd argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}}
// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
int operator-(GoodIter a, GoodIter b) { return 0; }
// expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}}
GoodIter operator-(GoodIter a) { return a; }
-// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 2nd argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}}
// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
GoodIter operator-(GoodIter a, int v) { return GoodIter(); }
// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}}
@@ -465,7 +465,7 @@ int test_with_random_access_iterator() {
for (begin = GoodIter(0); begin < end; ++begin)
++begin;
#pragma omp parallel
-// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'Iter0')}}
+// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}}
// expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
#pragma omp for simd
for (begin = begin0; begin < end; ++begin)
diff --git a/test/OpenMP/for_simd_private_messages.cpp b/test/OpenMP/for_simd_private_messages.cpp
index 15e235c2f8f41..ca4c3a33fcaff 100644
--- a/test/OpenMP/for_simd_private_messages.cpp
+++ b/test/OpenMP/for_simd_private_messages.cpp
@@ -29,7 +29,11 @@ class S4 {
S4(); // expected-note {{implicitly declared private here}}
public:
- S4(int v) : a(v) {}
+ S4(int v) : a(v) {
+#pragma omp for simd private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
};
class S5 {
int a;
@@ -37,6 +41,50 @@ class S5 {
public:
S5(int v) : a(v) {}
+ S5 &operator=(S5 &s) {
+#pragma omp for simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S6 {
+public:
+ T a;
+
+ S6() : a(0) {}
+ S6(T v) : a(v) {
+#pragma omp for simd private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+ S6 &operator=(S6 &s) {
+#pragma omp for simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S7 : public T {
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(T v) : a(v) {
+#pragma omp for simd private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp for simd private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
};
S3 h;
@@ -119,6 +167,8 @@ using A::x;
int main(int argc, char **argv) {
S4 e(4);
S5 g(5);
+ S6<float> s6(0.0) , s6_0(1.0);
+ S7<S6<float> > s7(0.0) , s7_0(1.0);
int i;
int &j = i;
#pragma omp for simd private // expected-error {{expected '(' after 'private'}}
@@ -180,6 +230,8 @@ int main(int argc, char **argv) {
for (int k = 0; k < argc; ++k)
m = k + 2;
- return 0;
+ s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}}
+ s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}}
+ return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
}
diff --git a/test/OpenMP/for_simd_reduction_messages.cpp b/test/OpenMP/for_simd_reduction_messages.cpp
index 000960fb55b53..2935cec602dd2 100644
--- a/test/OpenMP/for_simd_reduction_messages.cpp
+++ b/test/OpenMP/for_simd_reduction_messages.cpp
@@ -13,7 +13,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat
extern S1 a;
class S2 {
mutable int a;
- S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}}
+ S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}}
public:
S2() : a(0) {}
@@ -22,7 +22,7 @@ public:
static const float S2sc;
};
const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
-S2 b; // expected-note 2 {{'b' defined here}}
+S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
int a;
@@ -34,7 +34,7 @@ public:
S3 operator+(const S3 &arg1) { return arg1; }
};
int operator+(const S3 &arg1, const S3 &arg2) { return 5; }
-S3 c; // expected-note 2 {{'c' defined here}}
+S3 c; // expected-note 3 {{'c' defined here}}
const S3 ca[5]; // expected-note 2 {{'ca' defined here}}
extern const int f; // expected-note 4 {{'f' declared here}}
class S4 {
@@ -56,9 +56,9 @@ class S5 {
public:
S5(int v) : a(v) {}
};
-class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
#if __cplusplus >= 201103L // C++11 or later
-// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable}}
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
#endif
int a;
@@ -122,7 +122,7 @@ T tmain(T argc) {
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
-#pragma omp for simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+#pragma omp for simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
@@ -134,11 +134,11 @@ T tmain(T argc) {
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
-#pragma omp for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}}
+#pragma omp for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
-#pragma omp for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
@@ -146,15 +146,15 @@ T tmain(T argc) {
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
-#pragma omp for simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}}
+#pragma omp for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
-#pragma omp for simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}}
+#pragma omp for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
-#pragma omp for simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}}
+#pragma omp for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
@@ -174,7 +174,7 @@ T tmain(T argc) {
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
-#pragma omp for simd reduction(+ : o) // expected-error {{no viable overloaded '='}}
+#pragma omp for simd reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
@@ -186,7 +186,7 @@ T tmain(T argc) {
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
-#pragma omp for simd reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}}
+#pragma omp for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
@@ -295,15 +295,15 @@ int main(int argc, char **argv) {
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
-#pragma omp for simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}}
+#pragma omp for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
-#pragma omp for simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}}
+#pragma omp for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
-#pragma omp for simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}}
+#pragma omp for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
diff --git a/test/OpenMP/for_simd_safelen_messages.cpp b/test/OpenMP/for_simd_safelen_messages.cpp
index d70e90198ad6e..fa1b4442cee49 100644
--- a/test/OpenMP/for_simd_safelen_messages.cpp
+++ b/test/OpenMP/for_simd_safelen_messages.cpp
@@ -1,8 +1,13 @@
// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
void foo() {
}
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
bool foobool(int argc) {
return argc;
}
@@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp for simd safelen ((ST > 0) ? 1 + ST : 2)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error@+3 2 {{directive '#pragma omp for simd' cannot contain more than one 'safelen' clause}}
- // expected-error@+2 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+ // expected-error@+6 2 {{directive '#pragma omp for simd' cannot contain more than one 'safelen' clause}}
+ // expected-error@+5 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
#pragma omp for simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp for simd safelen (S) // expected-error {{'S' does not refer to a value}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp for simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp for simd safelen (4)
@@ -57,16 +69,27 @@ int main(int argc, char **argv) {
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp for simd safelen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- #pragma omp for simd safelen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+ #pragma omp for simd safelen (foobool(1) > 0 ? 1 : 2)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+3 {{expression is not an integral constant expression}}
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
// expected-error@+2 2 {{directive '#pragma omp for simd' cannot contain more than one 'safelen' clause}}
// expected-error@+1 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
#pragma omp for simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp for simd safelen (S1) // expected-error {{'S1' does not refer to a value}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+1 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp for simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
// expected-error@+3 {{statement after '#pragma omp for simd' must be a for loop}}
diff --git a/test/OpenMP/for_simd_simdlen_messages.cpp b/test/OpenMP/for_simd_simdlen_messages.cpp
index c72e546811924..8fe197979cc27 100644
--- a/test/OpenMP/for_simd_simdlen_messages.cpp
+++ b/test/OpenMP/for_simd_simdlen_messages.cpp
@@ -1,8 +1,13 @@
// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
void foo() {
}
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
bool foobool(int argc) {
return argc;
}
@@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp for simd simdlen ((ST > 0) ? 1 + ST : 2)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error@+3 2 {{directive '#pragma omp for simd' cannot contain more than one 'simdlen' clause}}
- // expected-error@+2 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+ // expected-error@+6 2 {{directive '#pragma omp for simd' cannot contain more than one 'simdlen' clause}}
+ // expected-error@+5 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
#pragma omp for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp for simd simdlen (S) // expected-error {{'S' does not refer to a value}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp for simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp for simd simdlen (4)
@@ -57,16 +69,27 @@ int main(int argc, char **argv) {
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp for simd simdlen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- #pragma omp for simd simdlen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+ #pragma omp for simd simdlen (foobool(1) > 0 ? 1 : 2)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+3 {{expression is not an integral constant expression}}
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
// expected-error@+2 2 {{directive '#pragma omp for simd' cannot contain more than one 'simdlen' clause}}
// expected-error@+1 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
#pragma omp for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp for simd simdlen (S1) // expected-error {{'S1' does not refer to a value}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+1 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp for simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
// expected-error@+3 {{statement after '#pragma omp for simd' must be a for loop}}
diff --git a/test/OpenMP/loops_explicit_clauses_codegen.cpp b/test/OpenMP/loops_explicit_clauses_codegen.cpp
new file mode 100644
index 0000000000000..dc21fd11af6f9
--- /dev/null
+++ b/test/OpenMP/loops_explicit_clauses_codegen.cpp
@@ -0,0 +1,162 @@
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// expected-no-diagnostics
+
+
+#ifndef HEADER
+#define HEADER
+
+#define N 10
+int foo();
+int bar();
+int k;
+// CHECK-LABEL: @main
+int main(int argc, char **argv) {
+ foo();
+// CHECK: @{{.+}}foo
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-NOT: @k
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK-NOT: @k
+#pragma omp for private(k)
+ for (k = 0; k < argc; k++)
+ ;
+ foo();
+// CHECK: @{{.+}}foo
+// CHECK: call void @__kmpc_for_static_init_8(
+// CHECK-NOT: @k
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: store i32 %{{.+}}, i32* @k
+#pragma omp for lastprivate(k) collapse(2)
+ for (int i = 0; i < 2; ++i)
+ for (k = 0; k < argc; k++)
+ ;
+ foo();
+// CHECK: @{{.+}}foo
+// CHECK-NOT: @k{{.+}}!llvm.mem.parallel_loop_access
+// CHECK: i32 @{{.+}}bar{{.+}}!llvm.mem.parallel_loop_access
+// CHECK-NOT: @k{{.+}}!llvm.mem.parallel_loop_access
+// CHECK: sdiv i32
+// CHECK: store i32 %{{.+}}, i32* @k,
+#pragma omp simd linear(k : 2)
+ for (k = 0; k < argc; k++)
+ bar();
+// CHECK: @{{.+}}foo
+// CHECK-NOT: @k{{.+}}!llvm.mem.parallel_loop_access
+// CHECK: i32 @{{.+}}bar{{.+}}!llvm.mem.parallel_loop_access
+// CHECK-NOT: @k{{.+}}!llvm.mem.parallel_loop_access
+// CHECK: sdiv i32
+// CHECK: store i32 %{{.+}}, i32* @k,
+ foo();
+#pragma omp simd lastprivate(k) collapse(2)
+ for (int i = 0; i < 2; ++i)
+ for (k = 0; k < argc; k++)
+ bar() ;
+ foo();
+// CHECK: @{{.+}}foo
+// CHECK-NOT: @k{{.+}}!llvm.mem.parallel_loop_access
+// CHECK: i32 @{{.+}}bar{{.+}}!llvm.mem.parallel_loop_access
+// CHECK-NOT: @k{{.+}}!llvm.mem.parallel_loop_access
+// CHECK: sdiv i32
+// CHECK: store i32 %{{.+}}, i32* @k,
+#pragma omp simd
+ for (k = 0; k < argc; k++)
+ bar();
+ foo();
+// CHECK: @{{.+}}foo
+// CHECK-NOT: @k{{.+}}!llvm.mem.parallel_loop_access
+// CHECK: i32 @{{.+}}bar{{.+}}!llvm.mem.parallel_loop_access
+// CHECK-NOT: @k{{.+}}!llvm.mem.parallel_loop_access
+// CHECK: sdiv i32
+// CHECK: store i32 %{{.+}}, i32* @k,
+#pragma omp simd collapse(2)
+ for (int i = 0; i < 2; ++i)
+ for (k = 0; k < argc; k++)
+ bar();
+// CHECK: @{{.+}}foo
+ foo();
+ return 0;
+}
+
+struct S {
+ int k;
+ S(int argc) {
+ foo();
+// CHECK: @{{.+}}foo
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
+#pragma omp for private(k)
+ for (k = 0; k < argc; k++)
+ ;
+ foo();
+// CHECK: @{{.+}}foo
+// CHECK: call void @__kmpc_for_static_init_8(
+// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
+// CHECK: call void @__kmpc_for_static_fini(
+#pragma omp for lastprivate(k) collapse(2)
+ for (int i = 0; i < 2; ++i)
+ for (k = 0; k < argc; k++)
+ ;
+ foo();
+// CHECK: @{{.+}}foo
+// CHECK: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
+// CHECK: br i1
+// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
+// CHECK: i32 @{{.+}}bar{{.+}}!llvm.mem.parallel_loop_access
+// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
+// CHECK: add nsw i32 %{{.+}}, 1
+// CHECK: br label {{.+}}, !llvm.loop
+// CHECK: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
+#pragma omp simd linear(k : 2)
+ for (k = 0; k < argc; k++)
+ bar();
+ foo();
+// CHECK: @{{.+}}foo
+// CHECK: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
+// CHECK: br i1
+// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
+// CHECK: i32 @{{.+}}bar{{.+}}!llvm.mem.parallel_loop_access
+// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
+// CHECK: add nsw i64 %{{.+}}, 1
+// CHECK: br label {{.+}}, !llvm.loop
+// CHECK: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
+#pragma omp simd lastprivate(k) collapse(2)
+ for (int i = 0; i < 2; ++i)
+ for (k = 0; k < argc; k++)
+ bar();
+ foo();
+// CHECK: @{{.+}}foo
+// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
+// CHECK: br i1
+// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
+// CHECK: i32 @{{.+}}bar{{.+}}!llvm.mem.parallel_loop_access
+// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
+// CHECK: add nsw i32 %{{.+}}, 1
+// CHECK: br label {{.+}}, !llvm.loop
+// CHECK: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
+#pragma omp simd
+ for (k = 0; k < argc; k++)
+ bar();
+ foo();
+// CHECK: @{{.+}}foo
+// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
+// CHECK: br i1
+// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
+// CHECK: i32 @{{.+}}bar{{.+}}!llvm.mem.parallel_loop_access
+// CHECK-NOT: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
+// CHECK: add nsw i64 %{{.+}}, 1
+// CHECK: br label {{.+}}, !llvm.loop
+// CHECK: getelementptr inbounds %struct.S, %struct.S* %{{.+}}, i32 0, i32 0
+#pragma omp simd collapse(2)
+ for (int i = 0; i < 2; ++i)
+ for (k = 0; k < argc; k++)
+ bar();
+// CHECK: @{{.+}}foo
+ foo();
+ }
+} s(N);
+
+#endif // HEADER
diff --git a/test/OpenMP/nesting_of_regions.cpp b/test/OpenMP/nesting_of_regions.cpp
index b2b87db6a158a..b6082e7447ddc 100644
--- a/test/OpenMP/nesting_of_regions.cpp
+++ b/test/OpenMP/nesting_of_regions.cpp
@@ -97,6 +97,27 @@ void foo() {
}
#pragma omp parallel
{
+#pragma omp target parallel
+ ++a;
+ }
+#pragma omp parallel
+ {
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp parallel
+ {
+#pragma omp target enter data map(to: a)
+ ++a;
+ }
+#pragma omp parallel
+ {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp parallel
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -112,7 +133,29 @@ void foo() {
for (int i = 0; i < 10; ++i)
;
}
-
+#pragma omp parallel
+ {
+#pragma omp target update to(a)
+ }
+#pragma omp parallel
+ {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp parallel
+ {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp parallel
+ {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+
// SIMD DIRECTIVE
#pragma omp simd
for (int i = 0; i < 10; ++i) {
@@ -122,7 +165,7 @@ void foo() {
}
#pragma omp simd
for (int i = 0; i < 10; ++i) {
-#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}}
for (int i = 0; i < 10; ++i)
;
}
@@ -226,6 +269,16 @@ void foo() {
}
#pragma omp simd
for (int i = 0; i < 10; ++i) {
+#pragma omp ordered simd // OK
+ bar();
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp ordered threads // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ bar();
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}}
++a;
}
@@ -236,6 +289,27 @@ void foo() {
}
#pragma omp simd
for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
++a;
}
@@ -251,6 +325,28 @@ void foo() {
for (int j = 0; j < 10; ++j)
;
}
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for// expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
// FOR DIRECTIVE
#pragma omp for
@@ -398,6 +494,27 @@ void foo() {
}
#pragma omp for
for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel
+ ++a;
+ }
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a)
+ ++a;
+ }
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -413,6 +530,28 @@ void foo() {
for (int j = 0; j < 10; ++j)
;
}
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a)
+ }
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
// FOR SIMD DIRECTIVE
#pragma omp for simd
@@ -423,7 +562,7 @@ void foo() {
}
#pragma omp for simd
for (int i = 0; i < 10; ++i) {
-#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}}
for (int i = 0; i < 10; ++i)
;
}
@@ -527,6 +666,16 @@ void foo() {
}
#pragma omp for simd
for (int i = 0; i < 10; ++i) {
+#pragma omp ordered simd // OK
+ bar();
+ }
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp ordered threads // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ bar();
+ }
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}}
++a;
}
@@ -537,6 +686,27 @@ void foo() {
}
#pragma omp for simd
for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
++a;
}
@@ -552,6 +722,29 @@ void foo() {
for (int j = 0; j < 10; ++j)
;
}
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ bar();
+ }
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
// SECTIONS DIRECTIVE
#pragma omp sections
@@ -706,6 +899,25 @@ void foo() {
}
#pragma omp sections
{
+#pragma omp target parallel
+ ++a;
+ }
+#pragma omp sections
+ {
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp sections
+ {
+#pragma omp target enter data map(to: a)
+ }
+#pragma omp sections
+ {
+#pragma omp target exit data map(from: a)
+ }
+#pragma omp sections
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -721,6 +933,28 @@ void foo() {
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp sections
+ {
+#pragma omp target update to(a)
+ }
+#pragma omp sections
+ {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp sections
+ {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp sections
+ {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
// SECTION DIRECTIVE
#pragma omp section // expected-error {{orphaned 'omp section' directives are prohibited, it must be closely nested to a sections region}}
@@ -911,6 +1145,37 @@ void foo() {
#pragma omp sections
{
#pragma omp section
+#pragma omp target parallel
+ ++a;
+ }
+#pragma omp sections
+ {
+#pragma omp section
+ {
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+ }
+#pragma omp sections
+ {
+#pragma omp section
+ {
+#pragma omp target enter data map(to: a)
+ ++a;
+ }
+ }
+#pragma omp sections
+ {
+#pragma omp section
+ {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+ }
+#pragma omp sections
+ {
+#pragma omp section
#pragma omp teams // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -928,6 +1193,35 @@ void foo() {
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp sections
+ {
+#pragma omp section
+ {
+ bar();
+#pragma omp target update to(a)
+ }
+ }
+#pragma omp sections
+ {
+#pragma omp section
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp sections
+ {
+#pragma omp section
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp sections
+ {
+#pragma omp section
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
// SINGLE DIRECTIVE
#pragma omp single
@@ -1065,6 +1359,27 @@ void foo() {
}
#pragma omp single
{
+#pragma omp target parallel
+ ++a;
+ }
+#pragma omp single
+ {
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp single
+ {
+#pragma omp target enter data map(to: a)
+ ++a;
+ }
+#pragma omp single
+ {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp single
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -1080,6 +1395,29 @@ void foo() {
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp single
+ {
+#pragma omp target update to(a)
+ bar();
+ }
+#pragma omp single
+ {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp single
+ {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp single
+ {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
// MASTER DIRECTIVE
#pragma omp master
@@ -1217,6 +1555,27 @@ void foo() {
}
#pragma omp master
{
+#pragma omp target parallel
+ ++a;
+ }
+#pragma omp master
+ {
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp master
+ {
+#pragma omp target enter data map(to: a)
+ ++a;
+ }
+#pragma omp master
+ {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp master
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -1232,6 +1591,29 @@ void foo() {
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp master
+ {
+#pragma omp target update to(a)
+ bar();
+ }
+#pragma omp master
+ {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp master
+ {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp master
+ {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
// CRITICAL DIRECTIVE
#pragma omp critical
@@ -1383,6 +1765,27 @@ void foo() {
}
#pragma omp critical
{
+#pragma omp target parallel
+ ++a;
+ }
+#pragma omp critical
+ {
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp critical
+ {
+#pragma omp target enter data map(to: a)
+ ++a;
+ }
+#pragma omp critical
+ {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp critical
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -1398,6 +1801,29 @@ void foo() {
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp critical
+ {
+#pragma omp target update to(a)
+ bar();
+ }
+#pragma omp critical
+ {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp critical
+ {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp critical
+ {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
// PARALLEL FOR DIRECTIVE
#pragma omp parallel for
@@ -1550,6 +1976,27 @@ void foo() {
}
#pragma omp parallel for
for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel
+ ++a;
+ }
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a)
+ ++a;
+ }
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -1565,6 +2012,28 @@ void foo() {
for (int j = 0; j < 10; ++j)
;
}
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a)
+ }
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
// PARALLEL FOR SIMD DIRECTIVE
#pragma omp parallel for simd
@@ -1575,7 +2044,7 @@ void foo() {
}
#pragma omp parallel for simd
for (int i = 0; i < 10; ++i) {
-#pragma omp simd// expected-error {{OpenMP constructs may not be nested inside a simd region}}
+#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}}
for (int i = 0; i < 10; ++i)
;
}
@@ -1717,6 +2186,27 @@ void foo() {
}
#pragma omp parallel for simd
for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
++a;
}
@@ -1732,6 +2222,29 @@ void foo() {
for (int j = 0; j < 10; ++j)
;
}
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ bar();
+ }
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
// PARALLEL SECTIONS DIRECTIVE
#pragma omp parallel sections
@@ -1875,6 +2388,25 @@ void foo() {
}
#pragma omp parallel sections
{
+#pragma omp target parallel
+ ++a;
+ }
+#pragma omp parallel sections
+ {
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp parallel sections
+ {
+#pragma omp target enter data map(to: a)
+ }
+#pragma omp parallel sections
+ {
+#pragma omp target exit data map(from: a)
+ }
+#pragma omp parallel sections
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -1890,6 +2422,28 @@ void foo() {
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp parallel sections
+ {
+#pragma omp target update to(a)
+ }
+#pragma omp parallel sections
+ {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp parallel sections
+ {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp parallel sections
+ {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
// TASK DIRECTIVE
#pragma omp task
@@ -1979,6 +2533,25 @@ void foo() {
}
#pragma omp task
{
+#pragma omp target parallel
+ ++a;
+ }
+#pragma omp task
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp task
+ {
+#pragma omp target enter data map(to: a)
+ ++a;
+ }
+#pragma omp task
+ {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp task
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -1994,6 +2567,29 @@ void foo() {
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp task
+ {
+#pragma omp target update to(a)
+ bar();
+ }
+#pragma omp task
+ {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp task
+ {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp task
+ {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
// ORDERED DIRECTIVE
#pragma omp ordered
@@ -2141,6 +2737,37 @@ void foo() {
}
#pragma omp ordered
{
+#pragma omp target parallel
+ ++a;
+ }
+#pragma omp ordered
+ {
+#pragma omp target parallel for ordered
+ for (int j = 0; j < 10; ++j) {
+#pragma omp ordered // OK
+ {
+ bar();
+ }
+ }
+ }
+#pragma omp ordered
+ {
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp ordered
+ {
+#pragma omp target enter data map(to: a)
+ ++a;
+ }
+#pragma omp ordered
+ {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp ordered
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'ordered' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -2156,6 +2783,30 @@ void foo() {
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp ordered
+ {
+ bar();
+#pragma omp target update to(a)
+ bar();
+ }
+#pragma omp ordered
+ {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'ordered' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp ordered
+ {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'ordered' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp ordered
+ {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'ordered' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
// ATOMIC DIRECTIVE
#pragma omp atomic
@@ -2322,6 +2973,35 @@ void foo() {
// expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
// expected-note@+1 {{expected an expression statement}}
{
+#pragma omp target parallel // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+ ++a;
+ }
+#pragma omp atomic
+ // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-note@+1 {{expected an expression statement}}
+ {
+#pragma omp target parallel for // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp atomic
+ // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-note@+1 {{expected an expression statement}}
+ {
+#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+ ++a;
+ }
+#pragma omp atomic
+ // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-note@+1 {{expected an expression statement}}
+ {
+#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+ ++a;
+ }
+#pragma omp atomic
+ // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-note@+1 {{expected an expression statement}}
+ {
#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
++a;
}
@@ -2341,6 +3021,37 @@ void foo() {
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp atomic
+ // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-note@+1 {{expected an expression statement}}
+ {
+#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+ bar();
+ }
+#pragma omp atomic
+ // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-note@+1 {{expected an expression statement}}
+ {
+#pragma omp distribute parallel for // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp atomic
+ // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-note@+1 {{expected an expression statement}}
+ {
+#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp atomic
+ // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-note@+1 {{expected an expression statement}}
+ {
+#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
// TARGET DIRECTIVE
#pragma omp target
@@ -2432,10 +3143,19 @@ void foo() {
}
#pragma omp target
{
+#pragma omp target // expected-error {{region cannot be nested inside 'target' region}}
+ ++a;
+ }
#pragma omp target
+ {
+#pragma omp target parallel // expected-error {{region cannot be nested inside 'target' region}}
++a;
}
#pragma omp target
+#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target' region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target
{
#pragma omp teams
++a;
@@ -2446,6 +3166,12 @@ void foo() {
#pragma omp teams // expected-note {{nested teams construct here}}
++a;
}
+#pragma omp target // expected-error {{target construct with nested teams region contains statements outside of the teams construct}}
+ {
+ while (0) // expected-note {{statement outside teams construct here}}
+#pragma omp teams // expected-note {{nested teams construct here}}
+ ++a;
+ }
#pragma omp target
{
#pragma omp taskloop
@@ -2458,6 +3184,402 @@ void foo() {
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp target
+ {
+#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target' region}}
+ }
+#pragma omp target
+ {
+#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target' region}}
+ }
+#pragma omp target
+ {
+#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target' region}}
+ }
+#pragma omp target
+ {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'target' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+ {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'target' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+ {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'target' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+
+// TARGET PARALLEL DIRECTIVE
+#pragma omp target parallel
+#pragma omp parallel
+ bar();
+#pragma omp target parallel
+#pragma omp for
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target parallel
+#pragma omp simd
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target parallel
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target parallel
+#pragma omp sections
+ {
+ bar();
+ }
+#pragma omp target parallel
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a target parallel region}}
+ {
+ bar();
+ }
+#pragma omp target parallel
+#pragma omp single
+ bar();
+
+#pragma omp target parallel
+#pragma omp master
+ {
+ bar();
+ }
+#pragma omp target parallel
+#pragma omp critical
+ {
+ bar();
+ }
+#pragma omp target parallel
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target parallel
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target parallel
+#pragma omp parallel sections
+ {
+ bar();
+ }
+#pragma omp target parallel
+#pragma omp task
+ {
+ bar();
+ }
+#pragma omp target parallel
+ {
+#pragma omp taskyield
+ bar();
+ }
+#pragma omp target parallel
+ {
+#pragma omp barrier
+ bar();
+ }
+#pragma omp target parallel
+ {
+#pragma omp taskwait
+ bar();
+ }
+#pragma omp target parallel
+ {
+#pragma omp flush
+ bar();
+ }
+#pragma omp target parallel
+ {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+ bar();
+ }
+#pragma omp target parallel
+ {
+#pragma omp atomic
+ ++a;
+ }
+#pragma omp target parallel
+ {
+#pragma omp target // expected-error {{region cannot be nested inside 'target parallel' region}}
+ ++a;
+ }
+#pragma omp target parallel
+ {
+#pragma omp target parallel // expected-error {{region cannot be nested inside 'target parallel' region}}
+ ++a;
+ }
+#pragma omp target parallel
+#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target parallel' region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target parallel
+ {
+#pragma omp teams // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
+ ++a;
+ }
+#pragma omp target parallel
+ {
+ ++a;
+#pragma omp teams // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
+ ++a;
+ }
+#pragma omp target parallel
+ {
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i)
+ ++a;
+ }
+#pragma omp target parallel
+ {
+#pragma omp distribute // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target parallel
+ {
+#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target parallel' region}}
+ }
+#pragma omp target parallel
+ {
+#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target parallel' region}}
+ }
+#pragma omp target parallel
+ {
+#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target parallel' region}}
+ }
+#pragma omp target parallel
+ {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target parallel
+ {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target parallel
+ {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+
+// TARGET PARALLEL FOR DIRECTIVE
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp simd
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp for simd // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+ {
+ bar();
+ }
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a target parallel for region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+ {
+ bar();
+ }
+ }
+
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp master // expected-error {{region cannot be closely nested inside 'target parallel for' region}}
+ {
+ bar();
+ }
+ }
+
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp critical
+ {
+ bar();
+ }
+ }
+
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+ {
+#pragma omp single // OK
+ {
+ bar();
+ }
+#pragma omp for // OK
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp for simd // OK
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp sections // OK
+ {
+ bar();
+ }
+ }
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel sections
+ {
+ bar();
+ }
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp task
+ {
+ bar();
+ }
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp taskyield
+ bar();
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'target parallel for' region}}
+ bar();
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp taskwait
+ bar();
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp flush
+ bar();
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+ bar();
+ }
+#pragma omp target parallel for ordered
+ for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // OK
+ bar();
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp atomic
+ ++a;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target // expected-error {{region cannot be nested inside 'target parallel for' region}}
+ ++a;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel // expected-error {{region cannot be nested inside 'target parallel for' region}}
+ ++a;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target parallel for' region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target parallel for' region}}
+ ++a;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target parallel for' region}}
+ ++a;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp teams // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
+ ++a;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i)
+ ++a;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target parallel for' region}}
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
// TEAMS DIRECTIVE
#pragma omp target
@@ -2575,6 +3697,29 @@ void foo() {
#pragma omp target
#pragma omp teams
{
+#pragma omp target parallel // expected-error {{region cannot be nested inside 'target' region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target' region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+ {
+#pragma omp target enter data map(to: a) // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target enter data' directive into a parallel region?}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+ {
+#pragma omp target exit data map(from: a) // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target exit data' directive into a parallel region?}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -2598,6 +3743,41 @@ void foo() {
#pragma omp distribute
for (int j = 0; j < 10; ++j)
;
+#pragma omp target
+#pragma omp teams
+ {
+#pragma omp target update to(a) // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target update' directive into a parallel region?}}
+ }
+#pragma omp target
+#pragma omp teams
+ {
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp distribute parallel for
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+ {
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp distribute parallel for simd
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+ {
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp distribute simd
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
// TASKLOOP DIRECTIVE
#pragma omp taskloop
@@ -2740,6 +3920,27 @@ void foo() {
}
#pragma omp taskloop
for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel
+ ++a;
+ }
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a)
+ ++a;
+ }
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -2749,6 +3950,36 @@ void foo() {
for (int i = 0; i < 10; ++i)
++a;
}
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a)
+ bar();
+ }
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}}
+ for (int j = 0; j < 10; ++j)
+ ++a;
+ }
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int j = 0; j < 10; ++j)
+ ++a;
+ }
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int j = 0; j < 10; ++j)
+ ++a;
+ }
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int j = 0; j < 10; ++j)
+ ++a;
+ }
+
// DISTRIBUTE DIRECTIVE
#pragma omp target
#pragma omp teams
@@ -2927,7 +4158,36 @@ void foo() {
#pragma omp teams
#pragma omp distribute
for (int i = 0; i < 10; ++i) {
+#pragma omp target // expected-error {{region cannot be nested inside 'target' region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel // expected-error {{region cannot be nested inside 'target' region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target' region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target' region}}
+ ++a;
+ }
#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target' region}}
++a;
}
#pragma omp target
@@ -2937,6 +4197,495 @@ void foo() {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'distribute' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target' region}}
+ ++a;
+ }
+
+// DISTRIBUTE PARALLEL FOR DIRECTIVE
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp simd
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp for simd // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a distribute parallel for region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp master // expected-error {{region cannot be closely nested inside 'distribute parallel for' region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp critical
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+ {
+#pragma omp single
+ {
+ bar();
+ }
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel sections
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp task
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp taskyield
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'distribute parallel for' region}}
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp taskwait
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp flush
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp atomic
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target // expected-error {{region cannot be nested inside 'target' region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel // expected-error {{region cannot be nested inside 'target' region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target' region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target' region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target' region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp teams // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target' region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+
+// DISTRIBUTE PARALLEL FOR SIMD DIRECTIVE
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp sections // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp section // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp single // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp master // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp critical // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+#pragma omp single
+ {
+ bar();
+ }
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel sections // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp task // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp taskyield // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp barrier // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp flush // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ++a;
+ }
}
void foo() {
@@ -3033,6 +4782,25 @@ void foo() {
}
#pragma omp parallel
{
+#pragma omp target parallel
+ ++a;
+ }
+#pragma omp parallel
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp parallel
+ {
+#pragma omp target enter data map(to: a)
+ ++a;
+ }
+#pragma omp parallel
+ {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp parallel
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -3048,6 +4816,29 @@ void foo() {
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp parallel
+ {
+#pragma omp target update to(a)
+ a++;
+ }
+#pragma omp parallel
+ {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp parallel
+ {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp parallel
+ {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'parallel' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
// SIMD DIRECTIVE
#pragma omp simd
@@ -3058,7 +4849,7 @@ void foo() {
}
#pragma omp simd
for (int i = 0; i < 10; ++i) {
-#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}}
for (int i = 0; i < 10; ++i)
;
}
@@ -3165,6 +4956,27 @@ void foo() {
}
#pragma omp simd
for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
++a;
}
@@ -3180,6 +4992,29 @@ void foo() {
for (int j = 0; j < 10; ++j)
;
}
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ a++;
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
// FOR DIRECTIVE
#pragma omp for
@@ -3317,6 +5152,27 @@ void foo() {
}
#pragma omp for
for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel
+ ++a;
+ }
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a)
+ ++a;
+ }
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -3332,6 +5188,29 @@ void foo() {
for (int j = 0; j < 10; ++j)
;
}
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a)
+ ++a;
+ }
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
// FOR SIMD DIRECTIVE
#pragma omp for simd
@@ -3342,7 +5221,7 @@ void foo() {
}
#pragma omp for simd
for (int i = 0; i < 10; ++i) {
-#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}}
for (int i = 0; i < 10; ++i)
;
}
@@ -3449,6 +5328,27 @@ void foo() {
}
#pragma omp for simd
for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
++a;
}
@@ -3464,6 +5364,29 @@ void foo() {
for (int j = 0; j < 10; ++j)
;
}
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
// SECTIONS DIRECTIVE
#pragma omp sections
@@ -3593,6 +5516,25 @@ void foo() {
}
#pragma omp sections
{
+#pragma omp target parallel
+ ++a;
+ }
+#pragma omp sections
+ {
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp sections
+ {
+#pragma omp target enter data map(to: a)
+ }
+#pragma omp sections
+ {
+#pragma omp target exit data map(from: a)
+ }
+#pragma omp sections
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -3608,6 +5550,28 @@ void foo() {
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp sections
+ {
+#pragma omp target update to(a)
+ }
+#pragma omp sections
+ {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp sections
+ {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp sections
+ {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
// SECTION DIRECTIVE
#pragma omp section // expected-error {{orphaned 'omp section' directives are prohibited, it must be closely nested to a sections region}}
@@ -3803,6 +5767,39 @@ void foo() {
{
#pragma omp section
{
+#pragma omp target parallel
+ ++a;
+ }
+ }
+#pragma omp sections
+ {
+#pragma omp section
+ {
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+ }
+#pragma omp sections
+ {
+#pragma omp section
+ {
+#pragma omp target enter data map(to: a)
+ ++a;
+ }
+ }
+#pragma omp sections
+ {
+#pragma omp section
+ {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+ }
+#pragma omp sections
+ {
+#pragma omp section
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -3823,6 +5820,35 @@ void foo() {
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp sections
+ {
+#pragma omp section
+ {
+#pragma omp target update to(a)
+ a++;
+ }
+ }
+#pragma omp sections
+ {
+#pragma omp section
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp sections
+ {
+#pragma omp section
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp sections
+ {
+#pragma omp section
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
// SINGLE DIRECTIVE
#pragma omp single
@@ -3950,6 +5976,27 @@ void foo() {
}
#pragma omp single
{
+#pragma omp target parallel
+ ++a;
+ }
+#pragma omp single
+ {
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp single
+ {
+#pragma omp target enter data map(to: a)
+ ++a;
+ }
+#pragma omp single
+ {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp single
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -3965,6 +6012,29 @@ void foo() {
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp single
+ {
+#pragma omp target update to(a)
+ a++;
+ }
+#pragma omp single
+ {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp single
+ {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp single
+ {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
// MASTER DIRECTIVE
#pragma omp master
@@ -4102,6 +6172,27 @@ void foo() {
}
#pragma omp master
{
+#pragma omp target parallel
+ ++a;
+ }
+#pragma omp master
+ {
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp master
+ {
+#pragma omp target enter data map(to: a)
+ ++a;
+ }
+#pragma omp master
+ {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp master
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -4117,6 +6208,29 @@ void foo() {
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp master
+ {
+#pragma omp target update to(a)
+ ++a;
+ }
+#pragma omp master
+ {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp master
+ {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp master
+ {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
// CRITICAL DIRECTIVE
#pragma omp critical
@@ -4273,6 +6387,27 @@ void foo() {
}
#pragma omp critical
{
+#pragma omp target parallel
+ ++a;
+ }
+#pragma omp critical
+ {
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp critical
+ {
+#pragma omp target enter data map(to: a)
+ ++a;
+ }
+#pragma omp critical
+ {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp critical
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -4288,6 +6423,29 @@ void foo() {
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp critical
+ {
+#pragma omp target update to(a)
+ a++;
+ }
+#pragma omp critical
+ {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp critical
+ {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp critical
+ {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
// PARALLEL FOR DIRECTIVE
#pragma omp parallel for
@@ -4440,6 +6598,27 @@ void foo() {
}
#pragma omp parallel for
for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel
+ ++a;
+ }
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a)
+ ++a;
+ }
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -4455,6 +6634,29 @@ void foo() {
for (int j = 0; j < 10; ++j)
;
}
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a)
+ a++;
+ }
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
// PARALLEL FOR SIMD DIRECTIVE
#pragma omp parallel for simd
@@ -4465,7 +6667,7 @@ void foo() {
}
#pragma omp parallel for simd
for (int i = 0; i < 10; ++i) {
-#pragma omp simd// expected-error {{OpenMP constructs may not be nested inside a simd region}}
+#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}}
for (int i = 0; i < 10; ++i)
;
}
@@ -4607,6 +6809,27 @@ void foo() {
}
#pragma omp parallel for simd
for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
++a;
}
@@ -4622,6 +6845,29 @@ void foo() {
for (int j = 0; j < 10; ++j)
;
}
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ a++;
+ }
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
// PARALLEL SECTIONS DIRECTIVE
#pragma omp parallel sections
@@ -4761,6 +7007,25 @@ void foo() {
}
#pragma omp parallel sections
{
+#pragma omp target parallel
+ ++a;
+ }
+#pragma omp parallel sections
+ {
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp parallel sections
+ {
+#pragma omp target enter data map(to: a)
+ }
+#pragma omp parallel sections
+ {
+#pragma omp target exit data map(from: a)
+ }
+#pragma omp parallel sections
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -4776,6 +7041,28 @@ void foo() {
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp parallel sections
+ {
+#pragma omp target update to(a)
+ }
+#pragma omp parallel sections
+ {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp parallel sections
+ {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp parallel sections
+ {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
// TASK DIRECTIVE
#pragma omp task
@@ -4864,6 +7151,25 @@ void foo() {
}
#pragma omp task
{
+#pragma omp target parallel
+ ++a;
+ }
+#pragma omp task
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp task
+ {
+#pragma omp target enter data map(to: a)
+ ++a;
+ }
+#pragma omp task
+ {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp task
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -4879,6 +7185,29 @@ void foo() {
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp task
+ {
+#pragma omp target update to(a)
+ a++;
+ }
+#pragma omp task
+ {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp task
+ {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp task
+ {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
// ATOMIC DIRECTIVE
#pragma omp atomic
@@ -5045,6 +7374,35 @@ void foo() {
// expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
// expected-note@+1 {{expected an expression statement}}
{
+#pragma omp target parallel // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+ ++a;
+ }
+#pragma omp atomic
+ // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-note@+1 {{expected an expression statement}}
+ {
+#pragma omp target parallel for // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp atomic
+ // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-note@+1 {{expected an expression statement}}
+ {
+#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+ ++a;
+ }
+#pragma omp atomic
+ // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-note@+1 {{expected an expression statement}}
+ {
+#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+ ++a;
+ }
+#pragma omp atomic
+ // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-note@+1 {{expected an expression statement}}
+ {
#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
++a;
}
@@ -5064,6 +7422,36 @@ void foo() {
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp atomic
+ // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-note@+1 {{expected an expression statement}}
+ {
+#pragma omp target update // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+ }
+#pragma omp atomic
+ // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-note@+1 {{expected an expression statement}}
+ {
+#pragma omp distribute parallel for// expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp atomic
+ // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-note@+1 {{expected an expression statement}}
+ {
+#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp atomic
+ // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-note@+1 {{expected an expression statement}}
+ {
+#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
// TARGET DIRECTIVE
#pragma omp target
@@ -5155,10 +7543,27 @@ void foo() {
}
#pragma omp target
{
+#pragma omp target // expected-error {{region cannot be nested inside 'target' region}}
+ ++a;
+ }
#pragma omp target
+ {
+#pragma omp target parallel // expected-error {{region cannot be nested inside 'target' region}}
++a;
}
#pragma omp target
+#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target' region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target
+ {
+#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target' region}}
+ }
+#pragma omp target
+ {
+#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target' region}}
+ }
+#pragma omp target
{
#pragma omp teams
++a;
@@ -5181,6 +7586,398 @@ void foo() {
for (int i = 0; i < 10; ++i)
;
}
+#pragma omp atomic
+ // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+ // expected-note@+1 {{expected an expression statement}}
+ {
+#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside an atomic region}}
+ a++;
+ }
+#pragma omp target
+ {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'target' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+ {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'target' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+ {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'target' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+
+// TARGET PARALLEL DIRECTIVE
+#pragma omp target parallel
+#pragma omp parallel
+ bar();
+#pragma omp target parallel
+#pragma omp for
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target parallel
+#pragma omp simd
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target parallel
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target parallel
+#pragma omp sections
+ {
+ bar();
+ }
+#pragma omp target parallel
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a target parallel region}}
+ {
+ bar();
+ }
+#pragma omp target parallel
+#pragma omp single
+ bar();
+
+#pragma omp target parallel
+#pragma omp master
+ {
+ bar();
+ }
+#pragma omp target parallel
+#pragma omp critical
+ {
+ bar();
+ }
+#pragma omp target parallel
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target parallel
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target parallel
+#pragma omp parallel sections
+ {
+ bar();
+ }
+#pragma omp target parallel
+#pragma omp task
+ {
+ bar();
+ }
+#pragma omp target parallel
+ {
+#pragma omp taskyield
+ bar();
+ }
+#pragma omp target parallel
+ {
+#pragma omp barrier
+ bar();
+ }
+#pragma omp target parallel
+ {
+#pragma omp taskwait
+ bar();
+ }
+#pragma omp target parallel
+ {
+#pragma omp flush
+ bar();
+ }
+#pragma omp target parallel
+ {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+ bar();
+ }
+#pragma omp target parallel
+ {
+#pragma omp atomic
+ ++a;
+ }
+#pragma omp target parallel
+ {
+#pragma omp target // expected-error {{region cannot be nested inside 'target parallel' region}}
+ ++a;
+ }
+#pragma omp target parallel
+ {
+#pragma omp target parallel // expected-error {{region cannot be nested inside 'target parallel' region}}
+ ++a;
+ }
+#pragma omp target parallel
+#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target parallel' region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target parallel
+ {
+#pragma omp teams // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
+ ++a;
+ }
+#pragma omp target parallel
+ {
+ ++a;
+#pragma omp teams // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
+ ++a;
+ }
+#pragma omp target parallel
+ {
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i)
+ ++a;
+ }
+#pragma omp target parallel
+ {
+#pragma omp distribute // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target parallel
+ {
+#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target parallel' region}}
+ }
+#pragma omp target parallel
+ {
+#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target parallel' region}}
+ }
+#pragma omp target parallel
+ {
+#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target parallel' region}}
+ }
+#pragma omp target parallel
+ {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target parallel
+ {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target parallel
+ {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'target parallel' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+
+// TARGET PARALLEL FOR DIRECTIVE
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp simd
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp for simd // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+ {
+ bar();
+ }
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a target parallel for region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+ {
+ bar();
+ }
+ }
+
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp master // expected-error {{region cannot be closely nested inside 'target parallel for' region}}
+ {
+ bar();
+ }
+ }
+
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp critical
+ {
+ bar();
+ }
+ }
+
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+ {
+#pragma omp single // OK
+ {
+ bar();
+ }
+#pragma omp for // OK
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp for simd // OK
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp sections // OK
+ {
+ bar();
+ }
+ }
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel sections
+ {
+ bar();
+ }
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp task
+ {
+ bar();
+ }
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp taskyield
+ bar();
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'target parallel for' region}}
+ bar();
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp taskwait
+ bar();
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp flush
+ bar();
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+ bar();
+ }
+#pragma omp target parallel for ordered
+ for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // OK
+ bar();
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp atomic
+ ++a;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target // expected-error {{region cannot be nested inside 'target parallel for' region}}
+ ++a;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel // expected-error {{region cannot be nested inside 'target parallel for' region}}
+ ++a;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target parallel for' region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target parallel for' region}}
+ ++a;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target parallel for' region}}
+ ++a;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp teams // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
+ ++a;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i)
+ ++a;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target parallel for' region}}
+ a++;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
// TEAMS DIRECTIVE
#pragma omp target
@@ -5298,6 +8095,27 @@ void foo() {
#pragma omp target
#pragma omp teams
{
+#pragma omp target parallel // expected-error {{region cannot be nested inside 'target' region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target' region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+ {
+#pragma omp target enter data map(to: a) // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target enter data' directive into a parallel region?}}
+ }
+#pragma omp target
+#pragma omp teams
+ {
+#pragma omp target exit data map(from: a) // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target exit data' directive into a parallel region?}}
+ }
+#pragma omp target
+#pragma omp teams
+ {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -5321,6 +8139,47 @@ void foo() {
#pragma omp distribute
for (int j = 0; j < 10; ++j)
;
+#pragma omp target
+#pragma omp teams
+ {
+#pragma omp target update to(a) // expected-error {{region cannot be closely nested inside 'teams' region; perhaps you forget to enclose 'omp target update' directive into a parallel region?}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target
+#pragma omp teams
+ {
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp distribute parallel for
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+ {
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp distribute parallel for simd
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+ {
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp distribute simd
+ for (int j = 0; j < 10; ++j)
+ ;
+ }
// TASKLOOP DIRECTIVE
#pragma omp taskloop
@@ -5463,6 +8322,27 @@ void foo() {
}
#pragma omp taskloop
for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel
+ ++a;
+ }
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a)
+ ++a;
+ }
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a)
+ ++a;
+ }
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
@@ -5472,6 +8352,35 @@ void foo() {
for (int i = 0; i < 10; ++i)
++a;
}
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a)
+ ++a;
+ }
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp taskloop
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'taskloop' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
// DISTRIBUTE DIRECTIVE
#pragma omp target
@@ -5651,16 +8560,786 @@ void foo() {
#pragma omp teams
#pragma omp distribute
for (int i = 0; i < 10; ++i) {
+#pragma omp target // expected-error {{region cannot be nested inside 'target' region}}
+ ++a;
+ }
#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel // expected-error {{region cannot be nested inside 'target' region}}
++a;
}
#pragma omp target
#pragma omp teams
#pragma omp distribute
for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target' region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+ for (int i = 0; i < 10; ++i) {
#pragma omp teams // expected-error {{region cannot be closely nested inside 'distribute' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
++a;
}
return foo<int>();
-}
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target' region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target' region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target' region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'distribute' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{region cannot be closely nested inside 'distribute' region; perhaps you forget to enclose 'omp distribute parallel for simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'distribute' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ++a;
+ }
+
+ // DISTRIBUTE PARALLEL FOR DIRECTIVE
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp distribute parallel for' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp distribute' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp simd
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp for simd // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp for simd' directive into a parallel region?}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a distribute parallel for region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp master // expected-error {{region cannot be closely nested inside 'distribute parallel for' region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp critical
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+ {
+#pragma omp single
+ {
+ bar();
+ }
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for simd
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel sections
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp task
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp taskyield
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'distribute parallel for' region}}
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp taskwait
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp flush
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp ordered' directive into a for or a parallel for region with 'ordered' clause?}}
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp atomic
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target // expected-error {{region cannot be nested inside 'target' region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel // expected-error {{region cannot be nested inside 'target' region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel for // expected-error {{region cannot be nested inside 'target' region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp teams // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp teams' directive into a target region?}}
+ ++a;
+ }
+ return foo<int>();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a) // expected-error {{region cannot be nested inside 'target' region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{region cannot be nested inside 'target' region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a) // expected-error {{region cannot be nested inside 'target' region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{region cannot be closely nested inside 'distribute parallel for' region; perhaps you forget to enclose 'omp distribute simd' directive into a teams region?}}
+ for (int i = 0; i < 10; ++i)
+ ++a;
+ }
+// DISTRIBUTE PARALLEL FOR SIMD DIRECTIVE
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp sections // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp section // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp single // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp master // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp critical // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+#pragma omp single
+ {
+ bar();
+ }
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel sections // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp task // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp taskyield // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp barrier // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp flush // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+ return foo<int>();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+
+// DISTRIBUTE SIMD DIRECTIVE
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp sections // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp section // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp single // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp master // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp critical // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+#pragma omp single
+ {
+ bar();
+ }
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel sections // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp task // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ {
+ bar();
+ }
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp taskyield // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp barrier // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp taskwait // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp flush // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ bar();
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp teams // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+ return foo<int>();
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target enter data map(to: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target exit data map(from: a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp target update to(a) // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ ++a;
+ }
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp distribute simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i)
+ ;
+ }
+}
diff --git a/test/OpenMP/nvptx_target_codegen.cpp b/test/OpenMP/nvptx_target_codegen.cpp
new file mode 100644
index 0000000000000..c4df636367d3b
--- /dev/null
+++ b/test/OpenMP/nvptx_target_codegen.cpp
@@ -0,0 +1,581 @@
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK-DAG: [[OMP_NT:@.+]] = common addrspace(3) global i32 0
+// CHECK-DAG: [[OMP_WID:@.+]] = common addrspace(3) global i64 0
+
+template<typename tx, typename ty>
+struct TT{
+ tx X;
+ ty Y;
+};
+
+int foo(int n) {
+ int a = 0;
+ short aa = 0;
+ float b[10];
+ float bn[n];
+ double c[5][10];
+ double cn[5][n];
+ TT<long long, char> d;
+
+ // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+foo.+l86}}_worker()
+ // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
+ //
+ // CHECK: [[AWAIT_WORK]]
+ // CHECK: call void @llvm.nvvm.barrier0()
+ // CHECK: [[WORK:%.+]] = load i64, i64 addrspace(3)* [[OMP_WID]],
+ // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i64 [[WORK]], 0
+ // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
+ //
+ // CHECK: [[SEL_WORKERS]]
+ // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+ // CHECK: [[NT:%.+]] = load i32, i32 addrspace(3)* [[OMP_NT]]
+ // CHECK: [[IS_ACTIVE:%.+]] = icmp slt i32 [[TID]], [[NT]]
+ // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]]
+ //
+ // CHECK: [[EXEC_PARALLEL]]
+ // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]]
+ //
+ // CHECK: [[TERM_PARALLEL]]
+ // CHECK: br label {{%?}}[[BAR_PARALLEL]]
+ //
+ // CHECK: [[BAR_PARALLEL]]
+ // CHECK: call void @llvm.nvvm.barrier0()
+ // CHECK: br label {{%?}}[[AWAIT_WORK]]
+ //
+ // CHECK: [[EXIT]]
+ // CHECK: ret void
+
+ // CHECK: define {{.*}}void [[T1:@__omp_offloading_.+foo.+l86]]()
+ // CHECK: [[NTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+ // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+ // CHECK: [[A:%.+]] = sub i32 [[WS]], 1
+ // CHECK: [[B:%.+]] = sub i32 [[NTID]], 1
+ // CHECK: [[MID:%.+]] = and i32 [[B]],
+ // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+ // CHECK: [[EXCESS:%.+]] = icmp ugt i32 [[TID]], [[MID]]
+ // CHECK: br i1 [[EXCESS]], label {{%?}}[[EXIT:.+]], label {{%?}}[[CHECK_WORKER:.+]]
+ //
+ // CHECK: [[CHECK_WORKER]]
+ // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[MID]]
+ // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[MASTER:.+]]
+ //
+ // CHECK: [[WORKER]]
+ // CHECK: call void [[T1]]_worker()
+ // CHECK: br label {{%?}}[[EXIT]]
+ //
+ // CHECK: [[MASTER]]
+ // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+ // CHECK: call void @__kmpc_kernel_init(i32 0, i32 [[TID]])
+ // CHECK: br label {{%?}}[[TERM:.+]]
+ //
+ // CHECK: [[TERM]]
+ // CHECK: store i64 0, i64 addrspace(3)* [[OMP_WID]],
+ // CHECK: call void @llvm.nvvm.barrier0()
+ // CHECK: br label {{%?}}[[EXIT]]
+ //
+ // CHECK: [[EXIT]]
+ // CHECK: ret void
+ #pragma omp target
+ {
+ }
+
+ // CHECK-NOT: define {{.*}}void [[T2:@__omp_offloading_.+foo.+]]_worker()
+ #pragma omp target if(0)
+ {
+ }
+
+ // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+foo.+l157}}_worker()
+ // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
+ //
+ // CHECK: [[AWAIT_WORK]]
+ // CHECK: call void @llvm.nvvm.barrier0()
+ // CHECK: [[WORK:%.+]] = load i64, i64 addrspace(3)* [[OMP_WID]],
+ // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i64 [[WORK]], 0
+ // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
+ //
+ // CHECK: [[SEL_WORKERS]]
+ // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+ // CHECK: [[NT:%.+]] = load i32, i32 addrspace(3)* [[OMP_NT]]
+ // CHECK: [[IS_ACTIVE:%.+]] = icmp slt i32 [[TID]], [[NT]]
+ // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]]
+ //
+ // CHECK: [[EXEC_PARALLEL]]
+ // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]]
+ //
+ // CHECK: [[TERM_PARALLEL]]
+ // CHECK: br label {{%?}}[[BAR_PARALLEL]]
+ //
+ // CHECK: [[BAR_PARALLEL]]
+ // CHECK: call void @llvm.nvvm.barrier0()
+ // CHECK: br label {{%?}}[[AWAIT_WORK]]
+ //
+ // CHECK: [[EXIT]]
+ // CHECK: ret void
+
+ // CHECK: define {{.*}}void [[T3:@__omp_offloading_.+foo.+l157]](i[[SZ:32|64]] [[ARG1:%.+]])
+ // CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]],
+ // CHECK: store i[[SZ]] [[ARG1]], i[[SZ]]* [[AA_ADDR]],
+ // CHECK: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
+ // CHECK: [[NTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+ // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+ // CHECK: [[A:%.+]] = sub i32 [[WS]], 1
+ // CHECK: [[B:%.+]] = sub i32 [[NTID]], 1
+ // CHECK: [[MID:%.+]] = and i32 [[B]],
+ // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+ // CHECK: [[EXCESS:%.+]] = icmp ugt i32 [[TID]], [[MID]]
+ // CHECK: br i1 [[EXCESS]], label {{%?}}[[EXIT:.+]], label {{%?}}[[CHECK_WORKER:.+]]
+ //
+ // CHECK: [[CHECK_WORKER]]
+ // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[MID]]
+ // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[MASTER:.+]]
+ //
+ // CHECK: [[WORKER]]
+ // CHECK: call void [[T3]]_worker()
+ // CHECK: br label {{%?}}[[EXIT]]
+ //
+ // CHECK: [[MASTER]]
+ // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+ // CHECK: call void @__kmpc_kernel_init(i32 0, i32 [[TID]])
+ // CHECK: load i16, i16* [[AA_CADDR]],
+ // CHECK: br label {{%?}}[[TERM:.+]]
+ //
+ // CHECK: [[TERM]]
+ // CHECK: store i64 0, i64 addrspace(3)* [[OMP_WID]],
+ // CHECK: call void @llvm.nvvm.barrier0()
+ // CHECK: br label {{%?}}[[EXIT]]
+ //
+ // CHECK: [[EXIT]]
+ // CHECK: ret void
+ #pragma omp target if(1)
+ {
+ aa += 1;
+ }
+
+ // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+foo.+l260}}_worker()
+ // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
+ //
+ // CHECK: [[AWAIT_WORK]]
+ // CHECK: call void @llvm.nvvm.barrier0()
+ // CHECK: [[WORK:%.+]] = load i64, i64 addrspace(3)* [[OMP_WID]],
+ // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i64 [[WORK]], 0
+ // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
+ //
+ // CHECK: [[SEL_WORKERS]]
+ // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+ // CHECK: [[NT:%.+]] = load i32, i32 addrspace(3)* [[OMP_NT]]
+ // CHECK: [[IS_ACTIVE:%.+]] = icmp slt i32 [[TID]], [[NT]]
+ // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]]
+ //
+ // CHECK: [[EXEC_PARALLEL]]
+ // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]]
+ //
+ // CHECK: [[TERM_PARALLEL]]
+ // CHECK: br label {{%?}}[[BAR_PARALLEL]]
+ //
+ // CHECK: [[BAR_PARALLEL]]
+ // CHECK: call void @llvm.nvvm.barrier0()
+ // CHECK: br label {{%?}}[[AWAIT_WORK]]
+ //
+ // CHECK: [[EXIT]]
+ // CHECK: ret void
+
+ // CHECK: define {{.*}}void [[T4:@__omp_offloading_.+foo.+l260]](i[[SZ]]
+ // Create local storage for each capture.
+ // CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
+ // CHECK: [[LOCAL_B:%.+]] = alloca [10 x float]*
+ // CHECK: [[LOCAL_VLA1:%.+]] = alloca i[[SZ]]
+ // CHECK: [[LOCAL_BN:%.+]] = alloca float*
+ // CHECK: [[LOCAL_C:%.+]] = alloca [5 x [10 x double]]*
+ // CHECK: [[LOCAL_VLA2:%.+]] = alloca i[[SZ]]
+ // CHECK: [[LOCAL_VLA3:%.+]] = alloca i[[SZ]]
+ // CHECK: [[LOCAL_CN:%.+]] = alloca double*
+ // CHECK: [[LOCAL_D:%.+]] = alloca [[TT:%.+]]*
+ // CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+ // CHECK-DAG: store [10 x float]* [[ARG_B:%.+]], [10 x float]** [[LOCAL_B]]
+ // CHECK-DAG: store i[[SZ]] [[ARG_VLA1:%.+]], i[[SZ]]* [[LOCAL_VLA1]]
+ // CHECK-DAG: store float* [[ARG_BN:%.+]], float** [[LOCAL_BN]]
+ // CHECK-DAG: store [5 x [10 x double]]* [[ARG_C:%.+]], [5 x [10 x double]]** [[LOCAL_C]]
+ // CHECK-DAG: store i[[SZ]] [[ARG_VLA2:%.+]], i[[SZ]]* [[LOCAL_VLA2]]
+ // CHECK-DAG: store i[[SZ]] [[ARG_VLA3:%.+]], i[[SZ]]* [[LOCAL_VLA3]]
+ // CHECK-DAG: store double* [[ARG_CN:%.+]], double** [[LOCAL_CN]]
+ // CHECK-DAG: store [[TT]]* [[ARG_D:%.+]], [[TT]]** [[LOCAL_D]]
+ //
+ // CHECK-64-DAG: [[REF_A:%.+]] = bitcast i64* [[LOCAL_A]] to i32*
+ // CHECK-DAG: [[REF_B:%.+]] = load [10 x float]*, [10 x float]** [[LOCAL_B]],
+ // CHECK-DAG: [[VAL_VLA1:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA1]],
+ // CHECK-DAG: [[REF_BN:%.+]] = load float*, float** [[LOCAL_BN]],
+ // CHECK-DAG: [[REF_C:%.+]] = load [5 x [10 x double]]*, [5 x [10 x double]]** [[LOCAL_C]],
+ // CHECK-DAG: [[VAL_VLA2:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA2]],
+ // CHECK-DAG: [[VAL_VLA3:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA3]],
+ // CHECK-DAG: [[REF_CN:%.+]] = load double*, double** [[LOCAL_CN]],
+ // CHECK-DAG: [[REF_D:%.+]] = load [[TT]]*, [[TT]]** [[LOCAL_D]],
+ //
+ // CHECK: [[NTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+ // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+ // CHECK: [[A:%.+]] = sub i32 [[WS]], 1
+ // CHECK: [[B:%.+]] = sub i32 [[NTID]], 1
+ // CHECK: [[MID:%.+]] = and i32 [[B]],
+ // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+ // CHECK: [[EXCESS:%.+]] = icmp ugt i32 [[TID]], [[MID]]
+ // CHECK: br i1 [[EXCESS]], label {{%?}}[[EXIT:.+]], label {{%?}}[[CHECK_WORKER:.+]]
+ //
+ // CHECK: [[CHECK_WORKER]]
+ // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[MID]]
+ // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[MASTER:.+]]
+ //
+ // CHECK: [[WORKER]]
+ // CHECK: call void [[T4]]_worker()
+ // CHECK: br label {{%?}}[[EXIT]]
+ //
+ // CHECK: [[MASTER]]
+ // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+ // CHECK: call void @__kmpc_kernel_init(i32 0, i32 [[TID]])
+ //
+ // Use captures.
+ // CHECK-64-DAG: load i32, i32* [[REF_A]]
+ // CHECK-32-DAG: load i32, i32* [[LOCAL_A]]
+ // CHECK-DAG: getelementptr inbounds [10 x float], [10 x float]* [[REF_B]], i[[SZ]] 0, i[[SZ]] 2
+ // CHECK-DAG: getelementptr inbounds float, float* [[REF_BN]], i[[SZ]] 3
+ // CHECK-DAG: getelementptr inbounds [5 x [10 x double]], [5 x [10 x double]]* [[REF_C]], i[[SZ]] 0, i[[SZ]] 1
+ // CHECK-DAG: getelementptr inbounds double, double* [[REF_CN]], i[[SZ]] %{{.+}}
+ // CHECK-DAG: getelementptr inbounds [[TT]], [[TT]]* [[REF_D]], i32 0, i32 0
+ //
+ // CHECK: br label {{%?}}[[TERM:.+]]
+ //
+ // CHECK: [[TERM]]
+ // CHECK: store i64 0, i64 addrspace(3)* [[OMP_WID]],
+ // CHECK: call void @llvm.nvvm.barrier0()
+ // CHECK: br label {{%?}}[[EXIT]]
+ //
+ // CHECK: [[EXIT]]
+ // CHECK: ret void
+ #pragma omp target if(n>20)
+ {
+ a += 1;
+ b[2] += 1.0;
+ bn[3] += 1.0;
+ c[1][2] += 1.0;
+ cn[1][3] += 1.0;
+ d.X += 1;
+ d.Y += 1;
+ }
+
+ return a;
+}
+
+template<typename tx>
+tx ftemplate(int n) {
+ tx a = 0;
+ short aa = 0;
+ tx b[10];
+
+ #pragma omp target if(n>40)
+ {
+ a += 1;
+ aa += 1;
+ b[2] += 1;
+ }
+
+ return a;
+}
+
+static
+int fstatic(int n) {
+ int a = 0;
+ short aa = 0;
+ char aaa = 0;
+ int b[10];
+
+ #pragma omp target if(n>50)
+ {
+ a += 1;
+ aa += 1;
+ aaa += 1;
+ b[2] += 1;
+ }
+
+ return a;
+}
+
+struct S1 {
+ double a;
+
+ int r1(int n){
+ int b = n+1;
+ short int c[2][n];
+
+ #pragma omp target if(n>60)
+ {
+ this->a = (double)b + 1.5;
+ c[1][1] = ++a;
+ }
+
+ return c[1][1] + (int)b;
+ }
+};
+
+int bar(int n){
+ int a = 0;
+
+ a += foo(n);
+
+ S1 S;
+ a += S.r1(n);
+
+ a += fstatic(n);
+
+ a += ftemplate<int>(n);
+
+ return a;
+}
+
+ // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+static.+l297}}_worker()
+ // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
+ //
+ // CHECK: [[AWAIT_WORK]]
+ // CHECK: call void @llvm.nvvm.barrier0()
+ // CHECK: [[WORK:%.+]] = load i64, i64 addrspace(3)* [[OMP_WID]],
+ // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i64 [[WORK]], 0
+ // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
+ //
+ // CHECK: [[SEL_WORKERS]]
+ // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+ // CHECK: [[NT:%.+]] = load i32, i32 addrspace(3)* [[OMP_NT]]
+ // CHECK: [[IS_ACTIVE:%.+]] = icmp slt i32 [[TID]], [[NT]]
+ // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]]
+ //
+ // CHECK: [[EXEC_PARALLEL]]
+ // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]]
+ //
+ // CHECK: [[TERM_PARALLEL]]
+ // CHECK: br label {{%?}}[[BAR_PARALLEL]]
+ //
+ // CHECK: [[BAR_PARALLEL]]
+ // CHECK: call void @llvm.nvvm.barrier0()
+ // CHECK: br label {{%?}}[[AWAIT_WORK]]
+ //
+ // CHECK: [[EXIT]]
+ // CHECK: ret void
+
+ // CHECK: define {{.*}}void [[T5:@__omp_offloading_.+static.+l297]](i[[SZ]]
+ // Create local storage for each capture.
+ // CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
+ // CHECK: [[LOCAL_AA:%.+]] = alloca i[[SZ]]
+ // CHECK: [[LOCAL_AAA:%.+]] = alloca i[[SZ]]
+ // CHECK: [[LOCAL_B:%.+]] = alloca [10 x i32]*
+ // CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+ // CHECK-DAG: store i[[SZ]] [[ARG_AA:%.+]], i[[SZ]]* [[LOCAL_AA]]
+ // CHECK-DAG: store i[[SZ]] [[ARG_AAA:%.+]], i[[SZ]]* [[LOCAL_AAA]]
+ // CHECK-DAG: store [10 x i32]* [[ARG_B:%.+]], [10 x i32]** [[LOCAL_B]]
+ // Store captures in the context.
+ // CHECK-64-DAG: [[REF_A:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+ // CHECK-DAG: [[REF_AA:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA]] to i16*
+ // CHECK-DAG: [[REF_AAA:%.+]] = bitcast i[[SZ]]* [[LOCAL_AAA]] to i8*
+ // CHECK-DAG: [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]],
+ //
+ // CHECK: [[NTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+ // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+ // CHECK: [[A:%.+]] = sub i32 [[WS]], 1
+ // CHECK: [[B:%.+]] = sub i32 [[NTID]], 1
+ // CHECK: [[MID:%.+]] = and i32 [[B]],
+ // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+ // CHECK: [[EXCESS:%.+]] = icmp ugt i32 [[TID]], [[MID]]
+ // CHECK: br i1 [[EXCESS]], label {{%?}}[[EXIT:.+]], label {{%?}}[[CHECK_WORKER:.+]]
+ //
+ // CHECK: [[CHECK_WORKER]]
+ // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[MID]]
+ // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[MASTER:.+]]
+ //
+ // CHECK: [[WORKER]]
+ // CHECK: call void [[T5]]_worker()
+ // CHECK: br label {{%?}}[[EXIT]]
+ //
+ // CHECK: [[MASTER]]
+ // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+ // CHECK: call void @__kmpc_kernel_init(i32 0, i32 [[TID]])
+ //
+ // CHECK-64-DAG: load i32, i32* [[REF_A]]
+ // CHECK-32-DAG: load i32, i32* [[LOCAL_A]]
+ // CHECK-DAG: load i16, i16* [[REF_AA]]
+ // CHECK-DAG: getelementptr inbounds [10 x i32], [10 x i32]* [[REF_B]], i[[SZ]] 0, i[[SZ]] 2
+ //
+ // CHECK: br label {{%?}}[[TERM:.+]]
+ //
+ // CHECK: [[TERM]]
+ // CHECK: store i64 0, i64 addrspace(3)* [[OMP_WID]],
+ // CHECK: call void @llvm.nvvm.barrier0()
+ // CHECK: br label {{%?}}[[EXIT]]
+ //
+ // CHECK: [[EXIT]]
+ // CHECK: ret void
+
+
+
+ // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+S1.+l315}}_worker()
+ // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
+ //
+ // CHECK: [[AWAIT_WORK]]
+ // CHECK: call void @llvm.nvvm.barrier0()
+ // CHECK: [[WORK:%.+]] = load i64, i64 addrspace(3)* [[OMP_WID]],
+ // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i64 [[WORK]], 0
+ // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
+ //
+ // CHECK: [[SEL_WORKERS]]
+ // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+ // CHECK: [[NT:%.+]] = load i32, i32 addrspace(3)* [[OMP_NT]]
+ // CHECK: [[IS_ACTIVE:%.+]] = icmp slt i32 [[TID]], [[NT]]
+ // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]]
+ //
+ // CHECK: [[EXEC_PARALLEL]]
+ // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]]
+ //
+ // CHECK: [[TERM_PARALLEL]]
+ // CHECK: br label {{%?}}[[BAR_PARALLEL]]
+ //
+ // CHECK: [[BAR_PARALLEL]]
+ // CHECK: call void @llvm.nvvm.barrier0()
+ // CHECK: br label {{%?}}[[AWAIT_WORK]]
+ //
+ // CHECK: [[EXIT]]
+ // CHECK: ret void
+
+ // CHECK: define {{.*}}void [[T6:@__omp_offloading_.+S1.+l315]](
+ // Create local storage for each capture.
+ // CHECK: [[LOCAL_THIS:%.+]] = alloca [[S1:%struct.*]]*
+ // CHECK: [[LOCAL_B:%.+]] = alloca i[[SZ]]
+ // CHECK: [[LOCAL_VLA1:%.+]] = alloca i[[SZ]]
+ // CHECK: [[LOCAL_VLA2:%.+]] = alloca i[[SZ]]
+ // CHECK: [[LOCAL_C:%.+]] = alloca i16*
+ // CHECK-DAG: store [[S1]]* [[ARG_THIS:%.+]], [[S1]]** [[LOCAL_THIS]]
+ // CHECK-DAG: store i[[SZ]] [[ARG_B:%.+]], i[[SZ]]* [[LOCAL_B]]
+ // CHECK-DAG: store i[[SZ]] [[ARG_VLA1:%.+]], i[[SZ]]* [[LOCAL_VLA1]]
+ // CHECK-DAG: store i[[SZ]] [[ARG_VLA2:%.+]], i[[SZ]]* [[LOCAL_VLA2]]
+ // CHECK-DAG: store i16* [[ARG_C:%.+]], i16** [[LOCAL_C]]
+ // Store captures in the context.
+ // CHECK-DAG: [[REF_THIS:%.+]] = load [[S1]]*, [[S1]]** [[LOCAL_THIS]],
+ // CHECK-64-DAG:[[REF_B:%.+]] = bitcast i[[SZ]]* [[LOCAL_B]] to i32*
+ // CHECK-DAG: [[VAL_VLA1:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA1]],
+ // CHECK-DAG: [[VAL_VLA2:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA2]],
+ // CHECK-DAG: [[REF_C:%.+]] = load i16*, i16** [[LOCAL_C]],
+ // CHECK: [[NTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+ // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+ // CHECK: [[A:%.+]] = sub i32 [[WS]], 1
+ // CHECK: [[B:%.+]] = sub i32 [[NTID]], 1
+ // CHECK: [[MID:%.+]] = and i32 [[B]],
+ // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+ // CHECK: [[EXCESS:%.+]] = icmp ugt i32 [[TID]], [[MID]]
+ // CHECK: br i1 [[EXCESS]], label {{%?}}[[EXIT:.+]], label {{%?}}[[CHECK_WORKER:.+]]
+ //
+ // CHECK: [[CHECK_WORKER]]
+ // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[MID]]
+ // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[MASTER:.+]]
+ //
+ // CHECK: [[WORKER]]
+ // CHECK: call void [[T6]]_worker()
+ // CHECK: br label {{%?}}[[EXIT]]
+ //
+ // CHECK: [[MASTER]]
+ // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+ // CHECK: call void @__kmpc_kernel_init(i32 0, i32 [[TID]])
+ // Use captures.
+ // CHECK-DAG: getelementptr inbounds [[S1]], [[S1]]* [[REF_THIS]], i32 0, i32 0
+ // CHECK-64-DAG:load i32, i32* [[REF_B]]
+ // CHECK-32-DAG:load i32, i32* [[LOCAL_B]]
+ // CHECK-DAG: getelementptr inbounds i16, i16* [[REF_C]], i[[SZ]] %{{.+}}
+ // CHECK: br label {{%?}}[[TERM:.+]]
+ //
+ // CHECK: [[TERM]]
+ // CHECK: store i64 0, i64 addrspace(3)* [[OMP_WID]],
+ // CHECK: call void @llvm.nvvm.barrier0()
+ // CHECK: br label {{%?}}[[EXIT]]
+ //
+ // CHECK: [[EXIT]]
+ // CHECK: ret void
+
+
+
+ // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l280}}_worker()
+ // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
+ //
+ // CHECK: [[AWAIT_WORK]]
+ // CHECK: call void @llvm.nvvm.barrier0()
+ // CHECK: [[WORK:%.+]] = load i64, i64 addrspace(3)* [[OMP_WID]],
+ // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i64 [[WORK]], 0
+ // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
+ //
+ // CHECK: [[SEL_WORKERS]]
+ // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+ // CHECK: [[NT:%.+]] = load i32, i32 addrspace(3)* [[OMP_NT]]
+ // CHECK: [[IS_ACTIVE:%.+]] = icmp slt i32 [[TID]], [[NT]]
+ // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]]
+ //
+ // CHECK: [[EXEC_PARALLEL]]
+ // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]]
+ //
+ // CHECK: [[TERM_PARALLEL]]
+ // CHECK: br label {{%?}}[[BAR_PARALLEL]]
+ //
+ // CHECK: [[BAR_PARALLEL]]
+ // CHECK: call void @llvm.nvvm.barrier0()
+ // CHECK: br label {{%?}}[[AWAIT_WORK]]
+ //
+ // CHECK: [[EXIT]]
+ // CHECK: ret void
+
+ // CHECK: define {{.*}}void [[T7:@__omp_offloading_.+template.+l280]](i[[SZ]]
+ // Create local storage for each capture.
+ // CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
+ // CHECK: [[LOCAL_AA:%.+]] = alloca i[[SZ]]
+ // CHECK: [[LOCAL_B:%.+]] = alloca [10 x i32]*
+ // CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
+ // CHECK-DAG: store i[[SZ]] [[ARG_AA:%.+]], i[[SZ]]* [[LOCAL_AA]]
+ // CHECK-DAG: store [10 x i32]* [[ARG_B:%.+]], [10 x i32]** [[LOCAL_B]]
+ // Store captures in the context.
+ // CHECK-64-DAG:[[REF_A:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
+ // CHECK-DAG: [[REF_AA:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA]] to i16*
+ // CHECK-DAG: [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]],
+ //
+ // CHECK: [[NTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
+ // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+ // CHECK: [[A:%.+]] = sub i32 [[WS]], 1
+ // CHECK: [[B:%.+]] = sub i32 [[NTID]], 1
+ // CHECK: [[MID:%.+]] = and i32 [[B]],
+ // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+ // CHECK: [[EXCESS:%.+]] = icmp ugt i32 [[TID]], [[MID]]
+ // CHECK: br i1 [[EXCESS]], label {{%?}}[[EXIT:.+]], label {{%?}}[[CHECK_WORKER:.+]]
+ //
+ // CHECK: [[CHECK_WORKER]]
+ // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[MID]]
+ // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[MASTER:.+]]
+ //
+ // CHECK: [[WORKER]]
+ // CHECK: call void [[T7]]_worker()
+ // CHECK: br label {{%?}}[[EXIT]]
+ //
+ // CHECK: [[MASTER]]
+ // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
+ // CHECK: call void @__kmpc_kernel_init(i32 0, i32 [[TID]])
+ //
+ // CHECK-64-DAG: load i32, i32* [[REF_A]]
+ // CHECK-32-DAG: load i32, i32* [[LOCAL_A]]
+ // CHECK-DAG: load i16, i16* [[REF_AA]]
+ // CHECK-DAG: getelementptr inbounds [10 x i32], [10 x i32]* [[REF_B]], i[[SZ]] 0, i[[SZ]] 2
+ //
+ // CHECK: br label {{%?}}[[TERM:.+]]
+ //
+ // CHECK: [[TERM]]
+ // CHECK: store i64 0, i64 addrspace(3)* [[OMP_WID]],
+ // CHECK: call void @llvm.nvvm.barrier0()
+ // CHECK: br label {{%?}}[[EXIT]]
+ //
+ // CHECK: [[EXIT]]
+ // CHECK: ret void
+#endif
diff --git a/test/OpenMP/nvptx_target_firstprivate_codegen.cpp b/test/OpenMP/nvptx_target_firstprivate_codegen.cpp
new file mode 100644
index 0000000000000..5dcff8e548426
--- /dev/null
+++ b/test/OpenMP/nvptx_target_firstprivate_codegen.cpp
@@ -0,0 +1,223 @@
+
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template<typename tx, typename ty>
+struct TT{
+ tx X;
+ ty Y;
+};
+
+// TCHECK: [[TT:%.+]] = type { i64, i8 }
+// TCHECK: [[S1:%.+]] = type { double }
+
+int foo(int n, double *ptr) {
+ int a = 0;
+ short aa = 0;
+ float b[10];
+ double c[5][10];
+ TT<long long, char> d;
+
+ #pragma omp target firstprivate(a)
+ {
+ }
+
+ // TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A_IN:%.+]])
+ // TCHECK: [[A_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // TCHECK-NOT: alloca i{{[0-9]+}},
+ // TCHECK: store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[A_ADDR]],
+ // TCHECK: ret void
+
+#pragma omp target firstprivate(aa,b,c,d)
+ {
+ aa += 1;
+ b[2] = 1.0;
+ c[1][2] = 1.0;
+ d.X = 1;
+ d.Y = 1;
+ }
+
+ // make sure that firstprivate variables are generated in all cases and that we use those instances for operations inside the
+ // target region
+ // TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A2_IN:%.+]], [10 x float]* {{.+}} [[B_IN:%.+]], [5 x [10 x double]]* {{.+}} [[C_IN:%.+]], [[TT]]* {{.+}} [[D_IN:%.+]])
+ // TCHECK: [[A2_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // TCHECK: [[B_ADDR:%.+]] = alloca [10 x float]*,
+ // TCHECK: [[C_ADDR:%.+]] = alloca [5 x [10 x double]]*,
+ // TCHECK: [[D_ADDR:%.+]] = alloca [[TT]]*,
+ // TCHECK-NOT: alloca i{{[0-9]+}},
+ // TCHECK: [[B_PRIV:%.+]] = alloca [10 x float],
+ // TCHECK: [[C_PRIV:%.+]] = alloca [5 x [10 x double]],
+ // TCHECK: [[D_PRIV:%.+]] = alloca [[TT]],
+ // TCHECK: store i{{[0-9]+}} [[A2_IN]], i{{[0-9]+}}* [[A2_ADDR]],
+ // TCHECK: store [10 x float]* [[B_IN]], [10 x float]** [[B_ADDR]],
+ // TCHECK: store [5 x [10 x double]]* [[C_IN]], [5 x [10 x double]]** [[C_ADDR]],
+ // TCHECK: store [[TT]]* [[D_IN]], [[TT]]** [[D_ADDR]],
+ // TCHECK: [[CONV_A2ADDR:%.+]] = bitcast i{{[0-9]+}}* [[A2_ADDR]] to i{{[0-9]+}}*
+ // TCHECK: [[B_ADDR_REF:%.+]] = load [10 x float]*, [10 x float]** [[B_ADDR]],
+ // TCHECK: [[C_ADDR_REF:%.+]] = load [5 x [10 x double]]*, [5 x [10 x double]]** [[C_ADDR]],
+ // TCHECK: [[D_ADDR_REF:%.+]] = load [[TT]]*, [[TT]]** [[D_ADDR]],
+
+ // firstprivate(aa): a_priv = a_in
+
+ // firstprivate(b): memcpy(b_priv,b_in)
+ // TCHECK: [[B_PRIV_BCAST:%.+]] = bitcast [10 x float]* [[B_PRIV]] to i8*
+ // TCHECK: [[B_ADDR_REF_BCAST:%.+]] = bitcast [10 x float]* [[B_ADDR_REF]] to i8*
+ // TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[B_PRIV_BCAST]], i8* [[B_ADDR_REF_BCAST]], {{.+}})
+
+ // firstprivate(c)
+ // TCHECK: [[C_PRIV_BCAST:%.+]] = bitcast [5 x [10 x double]]* [[C_PRIV]] to i8*
+ // TCHECK: [[C_IN_BCAST:%.+]] = bitcast [5 x [10 x double]]* [[C_ADDR_REF]] to i8*
+ // TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[C_PRIV_BCAST]], i8* [[C_IN_BCAST]],{{.+}})
+
+ // firstprivate(d)
+ // TCHECK: [[D_PRIV_BCAST:%.+]] = bitcast [[TT]]* [[D_PRIV]] to i8*
+ // TCHECK: [[D_IN_BCAST:%.+]] = bitcast [[TT]]* [[D_ADDR_REF]] to i8*
+ // TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[D_PRIV_BCAST]], i8* [[D_IN_BCAST]],{{.+}})
+
+ // TCHECK: load i16, i16* [[CONV_A2ADDR]],
+
+
+ #pragma omp target firstprivate(ptr)
+ {
+ ptr[0]++;
+ }
+
+ // TCHECK: define void @__omp_offloading_{{.+}}(double* [[PTR_IN:%.+]])
+ // TCHECK: [[PTR_ADDR:%.+]] = alloca double*,
+ // TCHECK-NOT: alloca double*,
+ // TCHECK: store double* [[PTR_IN]], double** [[PTR_ADDR]],
+ // TCHECK: [[PTR_IN_REF:%.+]] = load double*, double** [[PTR_ADDR]],
+ // TCHECK-NOT: store double* [[PTR_IN_REF]], double** [[PTR_PRIV]],
+
+ return a;
+}
+
+
+template<typename tx>
+tx ftemplate(int n) {
+ tx a = 0;
+ tx b[10];
+
+#pragma omp target firstprivate(a,b)
+ {
+ a += 1;
+ b[2] += 1;
+ }
+
+ return a;
+}
+
+static
+int fstatic(int n) {
+ int a = 0;
+ char aaa = 0;
+ int b[10];
+
+#pragma omp target firstprivate(a,aaa,b)
+ {
+ a += 1;
+ aaa += 1;
+ b[2] += 1;
+ }
+
+ return a;
+}
+
+// TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A_IN:%.+]], i{{[0-9]+}} [[A3_IN:%.+]], [10 x i{{[0-9]+}}]*{{.+}} [[B_IN:%.+]])
+// TCHECK: [[A_ADDR:%.+]] = alloca i{{[0-9]+}},
+// TCHECK: [[A3_ADDR:%.+]] = alloca i{{[0-9]+}},
+// TCHECK: [[B_ADDR:%.+]] = alloca [10 x i{{[0-9]+}}]*,
+// TCHECK-NOT: alloca i{{[0-9]+}},
+// TCHECK: [[B_PRIV:%.+]] = alloca [10 x i{{[0-9]+}}],
+// TCHECK: store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[A_ADDR]],
+// TCHECK: store i{{[0-9]+}} [[A3_IN]], i{{[0-9]+}}* [[A3_ADDR]],
+// TCHECK: store [10 x i{{[0-9]+}}]* [[B_IN]], [10 x i{{[0-9]+}}]** [[B_ADDR]],
+// TCHECK-64: [[A_CONV:%.+]] = bitcast i{{[0-9]+}}* [[A_ADDR]] to i{{[0-9]+}}*
+// TCHECK: [[A3_CONV:%.+]] = bitcast i{{[0-9]+}}* [[A3_ADDR]] to i8*
+// TCHECK: [[B_ADDR_REF:%.+]] = load [10 x i{{[0-9]+}}]*, [10 x i{{[0-9]+}}]** [[B_ADDR]],
+
+// firstprivate(a): a_priv = a_in
+
+// firstprivate(aaa)
+
+// TCHECK-NOT: store i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}*
+
+// firstprivate(b)
+// TCHECK: [[B_PRIV_BCAST:%.+]] = bitcast [10 x i{{[0-9]+}}]* [[B_PRIV]] to i8*
+// TCHECK: [[B_IN_BCAST:%.+]] = bitcast [10 x i{{[0-9]+}}]* [[B_ADDR_REF]] to i8*
+// TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[B_PRIV_BCAST]], i8* [[B_IN_BCAST]],{{.+}})
+
+// TCHECK: ret void
+
+struct S1 {
+ double a;
+
+ int r1(int n){
+ int b = n+1;
+
+#pragma omp target firstprivate(b)
+ {
+ this->a = (double)b + 1.5;
+ }
+
+ return (int)b;
+ }
+
+ // TCHECK: define void @__omp_offloading_{{.+}}([[S1]]* [[TH:%.+]], i{{[0-9]+}} [[B_IN:%.+]])
+ // TCHECK: [[TH_ADDR:%.+]] = alloca [[S1]]*,
+ // TCHECK: [[B_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // TCHECK-NOT: alloca i{{[0-9]+}},
+
+ // TCHECK: store [[S1]]* [[TH]], [[S1]]** [[TH_ADDR]],
+ // TCHECK: store i{{[0-9]+}} [[B_IN]], i{{[0-9]+}}* [[B_ADDR]],
+ // TCHECK: [[TH_ADDR_REF:%.+]] = load [[S1]]*, [[S1]]** [[TH_ADDR]],
+ // TCHECK-64: [[B_ADDR_CONV:%.+]] = bitcast i{{[0-9]+}}* [[B_ADDR]] to i{{[0-9]+}}*
+
+ // firstprivate(b)
+ // TCHECK-NOT: store i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}*
+
+ // TCHECK: ret void
+};
+
+
+
+int bar(int n, double *ptr){
+ int a = 0;
+ a += foo(n, ptr);
+ S1 S;
+ a += S.r1(n);
+ a += fstatic(n);
+ a += ftemplate<int>(n);
+
+ return a;
+}
+
+// template
+
+// TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A_IN:%.+]], [10 x i{{[0-9]+}}]*{{.+}} [[B_IN:%.+]])
+// TCHECK: [[A_ADDR:%.+]] = alloca i{{[0-9]+}},
+// TCHECK: [[B_ADDR:%.+]] = alloca [10 x i{{[0-9]+}}]*,
+// TCHECK-NOT: alloca i{{[0-9]+}},
+// TCHECK: [[B_PRIV:%.+]] = alloca [10 x i{{[0-9]+}}],
+// TCHECK: store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[A_ADDR]],
+// TCHECK: store [10 x i{{[0-9]+}}]* [[B_IN]], [10 x i{{[0-9]+}}]** [[B_ADDR]],
+// TCHECK-64: [[A_ADDR_CONV:%.+]] = bitcast i{{[0-9]+}}* [[A_ADDR]] to i{{[0-9]+}}*
+// TCHECK: [[B_ADDR_REF:%.+]] = load [10 x i{{[0-9]+}}]*, [10 x i{{[0-9]+}}]** [[B_ADDR]],
+
+// firstprivate(a)
+// TCHECK-NOT: store i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}*
+
+// firstprivate(b)
+// TCHECK: [[B_PRIV_BCAST:%.+]] = bitcast [10 x i{{[0-9]+}}]* [[B_PRIV]] to i8*
+// TCHECK: [[B_IN_BCAST:%.+]] = bitcast [10 x i{{[0-9]+}}]* [[B_ADDR_REF]] to i8*
+// TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[B_PRIV_BCAST]], i8* [[B_IN_BCAST]],{{.+}})
+
+// TCHECK: ret void
+
+#endif
diff --git a/test/OpenMP/nvptx_teams_codegen.cpp b/test/OpenMP/nvptx_teams_codegen.cpp
new file mode 100644
index 0000000000000..b26d47c706aca
--- /dev/null
+++ b/test/OpenMP/nvptx_teams_codegen.cpp
@@ -0,0 +1,132 @@
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+#ifdef CK1
+
+template <typename T>
+int tmain(T argc) {
+#pragma omp target
+#pragma omp teams
+ argc = 0;
+ return 0;
+}
+
+
+int main (int argc, char **argv) {
+#pragma omp target
+#pragma omp teams
+ {
+ argc = 0;
+ }
+ return tmain(argv);
+}
+
+// only nvptx side: do not outline teams region and do not call fork_teams
+// CK1: define {{.*}}void @{{[^,]+}}(i{{[0-9]+}} [[ARGC:%.+]])
+// CK1: {{.+}} = alloca i{{[0-9]+}}*,
+// CK1: {{.+}} = alloca i{{[0-9]+}}*,
+// CK1: [[ARGCADDR_PTR:%.+]] = alloca i{{[0-9]+}}*,
+// CK1: [[ARGCADDR:%.+]] = alloca i{{[0-9]+}},
+// CK1: store {{.+}} 0, {{.+}},
+// CK1: store i{{[0-9]+}} [[ARGC]], i{{[0-9]+}}* [[ARGCADDR]],
+// CK1-64: [[CONV:%.+]] = bitcast i{{[0-9]+}}* [[ARGCADDR]] to i{{[0-9]+}}*
+// CK1-64: store i{{[0-9]+}}* [[CONV]], i{{[0-9]+}}** [[ARGCADDR_PTR]],
+// CK1-32: store i{{[0-9]+}}* [[ARGCADDR]], i{{[0-9]+}}** [[ARGCADDR_PTR]],
+// CK1: [[ARGCADDR_PTR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[ARGCADDR_PTR]],
+// CK1: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[ARGCADDR_PTR_REF]],
+// CK1-NOT: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(
+// CK1: ret void
+// CK1-NEXT: }
+
+// target region in template
+// CK1: define {{.*}}void @{{[^,]+}}(i{{.+}}** [[ARGC:%.+]])
+// CK1: [[ARGCADDR_PTR:%.+]] = alloca i{{.+}}***,
+// CK1: [[ARGCADDR:%.+]] = alloca i{{.+}}**,
+// CK1: store i{{.+}}** [[ARGC]], i{{.+}}*** [[ARGCADDR]]
+// CK1: store i8*** [[ARGCADDR]], i8**** [[ARGCADDR_PTR]],
+// CK1: [[ARGCADDR_PTR_REF:%.+]] = load i{{.+}}**, i{{.+}}*** [[ARGCADDR_PTR]],
+// CK1: store i{{[0-9]+}}** null, i{{[0-9]+}}*** [[ARGCADDR_PTR_REF]],
+// CK1-NOT: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(
+// CK1: ret void
+// CK1-NEXT: }
+
+
+#endif // CK1
+
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// expected-no-diagnostics
+#ifdef CK2
+
+template <typename T>
+int tmain(T argc) {
+ int a = 10;
+ int b = 5;
+#pragma omp target
+#pragma omp teams num_teams(a) thread_limit(b)
+ {
+ argc = 0;
+ }
+ return 0;
+}
+
+int main (int argc, char **argv) {
+ int a = 20;
+ int b = 5;
+#pragma omp target
+#pragma omp teams num_teams(a) thread_limit(b)
+ {
+ argc = 0;
+ }
+ return tmain(argv);
+}
+
+// CK2: define {{.*}}void @{{[^,]+}}(i{{[0-9]+}} [[A_IN:%.+]], i{{[0-9]+}} [[B_IN:%.+]], i{{[0-9]+}} [[ARGC_IN:.+]])
+// CK2: {{.}} = alloca i{{[0-9]+}}*,
+// CK2: {{.}} = alloca i{{[0-9]+}}*,
+// CK2: [[ARGCADDR_PTR:%.+]] = alloca i{{[0-9]+}}*,
+// CK2: [[AADDR:%.+]] = alloca i{{[0-9]+}},
+// CK2: [[BADDR:%.+]] = alloca i{{[0-9]+}},
+// CK2: [[ARGCADDR:%.+]] = alloca i{{[0-9]+}},
+// CK2-NOT: {{%.+}} = call i32 @__kmpc_global_thread_num(
+// CK2: store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[AADDR]],
+// CK2: store i{{[0-9]+}} [[B_IN]], i{{[0-9]+}}* [[BADDR]],
+// CK2: store i{{[0-9]+}} [[ARGC_IN]], i{{[0-9]+}}* [[ARGCADDR]],
+// CK2-64: [[ACONV:%.+]] = bitcast i64* [[AADDR]] to i32*
+// CK2-64: [[BCONV:%.+]] = bitcast i64* [[BADDR]] to i32*
+// CK2-64: [[CONV:%.+]] = bitcast i64* [[ARGCADDR]] to i32*
+// CK2-64: store i{{[0-9]+}}* [[CONV]], i{{[0-9]+}}** [[ARGCADDR_PTR]],
+// CK2-32: store i{{[0-9]+}}* [[ARGCADDR]], i{{[0-9]+}}** [[ARGCADDR_PTR]],
+// CK2: [[ARGCADDR_PTR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[ARGCADDR_PTR]],
+// CK2: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[ARGCADDR_PTR_REF]],
+// CK2-NOT: {{.+}} = call i32 @__kmpc_push_num_teams(
+// CK2-NOT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(
+// CK2: ret
+
+// CK2: define {{.*}}void @{{[^,]+}}(i{{[0-9]+}} [[A_IN:%.+]], i{{[0-9]+}} [[BP:%.+]], i{{[0-9]+}}** [[ARGC:%.+]])
+// CK2: [[ARGCADDR_PTR:%.+]] = alloca i{{[0-9]+}}***,
+// CK2: [[AADDR:%.+]] = alloca i{{[0-9]+}},
+// CK2: [[BADDR:%.+]] = alloca i{{[0-9]+}},
+// CK2: [[ARGCADDR:%.+]] = alloca i{{[0-9]+}}**,
+// CK2-NOT: {{%.+}} = call i32 @__kmpc_global_thread_num(
+// CK2: store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[AADDR]],
+// CK2: store i{{[0-9]+}} [[B_IN]], i{{[0-9]+}}* [[BADDR]],
+// CK2: store i{{[0-9]+}}** [[ARGC]], i{{[0-9]+}}*** [[ARGCADDR]],
+// CK2: store i{{[0-9]+}}*** [[ARGCADDR]], i{{[0-9]+}}**** [[ARGCADDR_PTR]],
+// CK2: [[ARGCADDR_PTR_REF:%.+]] = load i{{[0-9]+}}***, i{{[0-9]+}}**** [[ARGCADDR_PTR]],
+// CK2: store i{{[0-9]+}}** null, i{{[0-9]+}}*** [[ARGCADDR_PTR_REF]],
+// CK2-NOT: {{.+}} = call i32 @__kmpc_push_num_teams(
+// CK2-NOT: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(
+// CK2: ret void
+
+#endif // CK2
+#endif
diff --git a/test/OpenMP/ordered_doacross_codegen.cpp b/test/OpenMP/ordered_doacross_codegen.cpp
new file mode 100644
index 0000000000000..d1fe99d4b826b
--- /dev/null
+++ b/test/OpenMP/ordered_doacross_codegen.cpp
@@ -0,0 +1,124 @@
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// REQUIRES: x86-registered-target
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+// CHECK: [[KMP_DIM:%.+]] = type { i64, i64, i64 }
+extern int n;
+int a[10], b[10], c[10], d[10];
+void foo();
+
+// CHECK-LABEL: @main()
+int main() {
+ int i;
+// CHECK: [[DIMS:%.+]] = alloca [[KMP_DIM]],
+// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT:%.+]])
+// CHECK: icmp
+// CHECK-NEXT: br i1 %
+// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8*
+// CHECK: call void @llvm.memset.p0i8.i64(i8* [[CAST]], i8 0, i64 24, i32 8, i1 false)
+// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIMS]], i32 0, i32 1
+// CHECK: store i64 %{{.+}}, i64* %
+// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIMS]], i32 0, i32 2
+// CHECK: store i64 1, i64* %
+// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8*
+// CHECK: call void @__kmpc_doacross_init([[IDENT]], i32 [[GTID]], i32 1, i8* [[CAST]])
+// CHECK: call void @__kmpc_for_static_init_4(
+#pragma omp for ordered(1)
+ for (i = 0; i < n; ++i) {
+ a[i] = b[i] + 1;
+ foo();
+// CHECK: invoke void [[FOO:.+]](
+// CHECK: load i32, i32* [[CNT:%.+]],
+// CHECK-NEXT: sext i32 %{{.+}} to i64
+// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]],
+// CHECK-NEXT: call void @__kmpc_doacross_post([[IDENT]], i32 [[GTID]], i64* [[TMP]])
+#pragma omp ordered depend(source)
+ c[i] = c[i] + 1;
+ foo();
+// CHECK: invoke void [[FOO]]
+// CHECK: load i32, i32* [[CNT]],
+// CHECK-NEXT: sub nsw i32 %{{.+}}, 2
+// CHECK-NEXT: sext i32 %{{.+}} to i64
+// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]],
+// CHECK-NEXT: call void @__kmpc_doacross_wait([[IDENT]], i32 [[GTID]], i64* [[TMP]])
+#pragma omp ordered depend(sink : i - 2)
+ d[i] = a[i - 2];
+ }
+ // CHECK: landingpad
+ // CHECK: call void @__kmpc_doacross_fini([[IDENT]], i32 [[GTID]])
+ // CHECK: br label %
+
+ // CHECK: call void @__kmpc_for_static_fini(
+ // CHECK: call void @__kmpc_doacross_fini([[IDENT]], i32 [[GTID]])
+ // CHECK: ret i32 0
+ return 0;
+}
+
+// CHECK: define {{.+}}TestStruct
+template <typename T>
+struct TestStruct {
+ static const int M = 10;
+ static const int N = 20;
+ T i;
+ T a[N][M];
+ T b[N][M];
+ T foo(T, T);
+ T bar(T, T, T);
+ void baz(T, T);
+ TestStruct() {
+// CHECK: [[CNT:%.+]] = alloca i64,
+// CHECK: [[DIMS:%.+]] = alloca [[KMP_DIM]],
+// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT:%.+]])
+// CHECK: icmp
+// CHECK-NEXT: br i1 %
+// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8*
+// CHECK: call void @llvm.memset.p0i8.i64(i8* [[CAST]], i8 0, i64 24, i32 8, i1 false)
+// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIMS]], i32 0, i32 1
+// CHECK: store i64 %{{.+}}, i64* %
+// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIMS]], i32 0, i32 2
+// CHECK: store i64 1, i64* %
+// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8*
+// CHECK: call void @__kmpc_doacross_init([[IDENT]], i32 [[GTID]], i32 1, i8* [[CAST]])
+// CHECK: call void @__kmpc_for_static_init_8(
+#pragma omp for ordered(2)
+ for (T j = 0; j < M; j++)
+ for (i = 0; i < n; i += 2) {
+ a[i][j] = foo(i, j);
+// CHECK: invoke {{.+TestStruct.+foo}}
+// CHECK: load i64, i64* [[CNT]],
+// CHECK-NEXT: sub nsw i64 %{{.+}}, 1
+// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]],
+// CHECK-NEXT: call void @__kmpc_doacross_wait([[IDENT]], i32 [[GTID]], i64* [[TMP]])
+// CHECK-NEXT: load i64, i64* [[CNT]],
+// CHECK-NEXT: load i32, i32* %
+// CHECK-NEXT: mul nsw i32 1, %
+// CHECK-NEXT: sext i32 %{{.+}} to i64
+// CHECK-NEXT: sub nsw i64 %
+// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]],
+// CHECK-NEXT: call void @__kmpc_doacross_wait([[IDENT]], i32 [[GTID]], i64* [[TMP]])
+#pragma omp ordered depend(sink : j, i - 2) depend(sink : j - 1, i)
+ b[i][j] = bar(a[i][j], b[i - 1][j], b[i][j - 1]);
+// CHECK: invoke {{.+TestStruct.+bar}}
+// CHECK: load i64, i64* [[CNT]],
+// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]],
+// CHECK-NEXT: call void @__kmpc_doacross_post([[IDENT]], i32 [[GTID]], i64* [[TMP]])
+#pragma omp ordered depend(source)
+ baz(a[i][j], b[i][j]);
+ }
+ }
+ // CHECK: landingpad
+ // CHECK: call void @__kmpc_doacross_fini([[IDENT]], i32 [[GTID]])
+ // CHECK: br label %
+
+ // CHECK: call void @__kmpc_for_static_fini(
+ // CHECK: call void @__kmpc_doacross_fini([[IDENT]], i32 [[GTID]])
+ // CHECK: ret
+};
+
+TestStruct<int> s;
+#endif // HEADER
diff --git a/test/OpenMP/parallel_ast_print.cpp b/test/OpenMP/parallel_ast_print.cpp
index 1e46fba48ca31..8a1533959e364 100644
--- a/test/OpenMP/parallel_ast_print.cpp
+++ b/test/OpenMP/parallel_ast_print.cpp
@@ -8,6 +8,113 @@
void foo() {}
+struct S1 {
+ S1(): a(0) {}
+ S1(int v) : a(v) {}
+ int a;
+ typedef int type;
+ S1& operator +(const S1&);
+ S1& operator *(const S1&);
+ S1& operator &&(const S1&);
+ S1& operator ^(const S1&);
+};
+
+template <typename T>
+class S7 : public T {
+protected:
+ T a;
+ T b[100];
+ S7() : a(0) {}
+
+public:
+ S7(typename T::type v) : a(v) {
+#pragma omp parallel private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+#pragma omp parallel firstprivate(a) firstprivate(this->a) firstprivate(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+#pragma omp parallel shared(a) shared(this->a) shared(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+#pragma omp parallel reduction(+ : a) reduction(*: b[:])
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp parallel private(a) private(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+#pragma omp parallel firstprivate(a) firstprivate(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+#pragma omp parallel shared(a) shared(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+#pragma omp parallel reduction(&& : this->a) reduction(^: b[s.a.a])
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp parallel private(this->a) private(this->a) private(this->S1::a)
+// CHECK: #pragma omp parallel firstprivate(this->a) firstprivate(this->a) firstprivate(this->S1::a)
+// CHECK: #pragma omp parallel shared(this->a) shared(this->a) shared(this->S1::a)
+// CHECK: #pragma omp parallel reduction(+: this->a) reduction(*: this->b[:])
+// CHECK: #pragma omp parallel private(this->a) private(this->a) private(T::a)
+// CHECK: #pragma omp parallel firstprivate(this->a) firstprivate(this->a) firstprivate(T::a)
+// CHECK: #pragma omp parallel shared(this->a) shared(this->a) shared(T::a)
+// CHECK: #pragma omp parallel reduction(+: this->a) reduction(*: this->b[:])
+// CHECK: #pragma omp parallel private(this->a) private(this->a)
+// CHECK: #pragma omp parallel firstprivate(this->a) firstprivate(this->a)
+// CHECK: #pragma omp parallel shared(this->a) shared(this->a)
+// CHECK: #pragma omp parallel reduction(&&: this->a) reduction(^: this->b[s.a.a])
+
+class S8 : public S7<S1> {
+ S8() {}
+
+public:
+ S8(int v) : S7<S1>(v){
+#pragma omp parallel private(a) private(this->a) private(S7 < S1 > ::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+#pragma omp parallel firstprivate(a) firstprivate(this->a) firstprivate(S7 < S1 > ::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+#pragma omp parallel shared(a) shared(this->a) shared(S7 < S1 > ::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+#pragma omp parallel reduction(^ : S7 < S1 > ::a) reduction(+ : S7 < S1 > ::b[ : S7 < S1 > ::a.a])
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S8 &operator=(S8 &s) {
+#pragma omp parallel private(a) private(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+#pragma omp parallel firstprivate(a) firstprivate(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+#pragma omp parallel shared(a) shared(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+#pragma omp parallel reduction(* : this->a) reduction(&&:this->b[a.a:])
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp parallel private(this->a) private(this->a) private(this->S7<S1>::a)
+// CHECK: #pragma omp parallel firstprivate(this->a) firstprivate(this->a) firstprivate(this->S7<S1>::a)
+// CHECK: #pragma omp parallel shared(this->a) shared(this->a) shared(this->S7<S1>::a)
+// CHECK: #pragma omp parallel reduction(^: this->S7<S1>::a) reduction(+: this->S7<S1>::b[:this->S7<S1>::a.a])
+// CHECK: #pragma omp parallel private(this->a) private(this->a)
+// CHECK: #pragma omp parallel firstprivate(this->a) firstprivate(this->a)
+// CHECK: #pragma omp parallel shared(this->a) shared(this->a)
+// CHECK: #pragma omp parallel reduction(*: this->a) reduction(&&: this->b[this->a.a:])
+
template <class T>
struct S {
operator T() {return T();}
@@ -120,4 +227,7 @@ void foo(const Foo<int> &arg) {
}
}
+template<typename T>
+T S<T>::TS = 0;
+
#endif
diff --git a/test/OpenMP/parallel_copyin_codegen.cpp b/test/OpenMP/parallel_copyin_codegen.cpp
index ff76cfe4dd6c8..49e7b3fd618ba 100644
--- a/test/OpenMP/parallel_copyin_codegen.cpp
+++ b/test/OpenMP/parallel_copyin_codegen.cpp
@@ -87,10 +87,6 @@ int main() {
// TLS-LAMBDA: [[G_CPY_VAL:%.+]] = call{{( cxx_fast_tlscc)?}} i{{[0-9]+}}* [[G_CTOR:@.+]]()
// TLS-LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G_CPY_VAL]])
- // TLS-LAMBDA: define {{.*}}i{{[0-9]+}}* [[G_CTOR]]()
- // TLS-LAMBDA: ret i{{[0-9]+}}* [[G]]
- // TLS-LAMBDA: }
-
#pragma omp parallel copyin(g)
{
// LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}})
@@ -122,6 +118,11 @@ int main() {
g = 1;
// LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}*
// TLS-LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}*
+
+ // TLS-LAMBDA: define {{.*}}i{{[0-9]+}}* [[G_CTOR]]()
+ // TLS-LAMBDA: ret i{{[0-9]+}}* [[G]]
+ // TLS-LAMBDA: }
+
[&]() {
// LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
// LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
@@ -149,9 +150,6 @@ int main() {
// TLS-BLOCKS: [[G_CPY_VAL:%.+]] = call{{( cxx_fast_tlscc)?}} i{{[0-9]+}}* [[G_CTOR:@.+]]()
// TLS-BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G_CPY_VAL]])
- // TLS-BLOCKS: define {{.*}}i{{[0-9]+}}* [[G_CTOR]]()
- // TLS-BLOCKS: ret i{{[0-9]+}}* [[G]]
- // TLS-BLOCKS: }
#pragma omp parallel copyin(g)
{
// BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}})
@@ -189,6 +187,10 @@ int main() {
// TLS-BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_CAPTURE_DST]]
// TLS-BLOCKS-NOT: [[G]]{{[[^:word:]]}}
// TLS-BLOCKS: call {{.*}}void {{%.+}}(i8
+
+ // TLS-BLOCKS: define {{.*}}i{{[0-9]+}}* [[G_CTOR]]()
+ // TLS-BLOCKS: ret i{{[0-9]+}}* [[G]]
+ // TLS-BLOCKS: }
^{
// BLOCKS: define {{.+}} void {{@.+}}(i8*
// TLS-BLOCKS: define {{.+}} void {{@.+}}(i8*
diff --git a/test/OpenMP/parallel_firstprivate_codegen.cpp b/test/OpenMP/parallel_firstprivate_codegen.cpp
index d0da8cea87ac0..d20f3f5135691 100644
--- a/test/OpenMP/parallel_firstprivate_codegen.cpp
+++ b/test/OpenMP/parallel_firstprivate_codegen.cpp
@@ -1,8 +1,15 @@
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-32
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-32
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA -check-prefix=LAMBDA-32 %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS -check-prefix=BLOCKS-32 %s
+
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-64
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple x86_64-pc-linux-gnu -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA -check-prefix=LAMBDA-64 %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple x86_64-pc-linux-gnu -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS -check-prefix=BLOCKS-64 %s
+
// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=ARRAY %s
// expected-no-diagnostics
#ifndef ARRAY
@@ -18,6 +25,60 @@ struct St {
volatile int g __attribute__((aligned(128))) = 1212;
+struct SS {
+ int a;
+ int b : 4;
+ int &c;
+ int e[4];
+ SS(int &d) : a(0), b(0), c(d) {
+#pragma omp parallel firstprivate(a, b, c, e)
+#ifdef LAMBDA
+ [&]() {
+ ++this->a, --b, (this)->c /= 1;
+#pragma omp parallel firstprivate(a, b, c)
+ ++(this)->a, --b, this->c /= 1;
+ }();
+#elif defined(BLOCKS)
+ ^{
+ ++a;
+ --this->b;
+ (this)->c /= 1;
+#pragma omp parallel firstprivate(a, b, c)
+ ++(this)->a, --b, this->c /= 1;
+ }();
+#else
+ ++this->a, --b, c /= 1, e[2] = 1111;
+#endif
+ }
+};
+
+template<typename T>
+struct SST {
+ T a;
+ SST() : a(T()) {
+#pragma omp parallel firstprivate(a)
+#ifdef LAMBDA
+ [&]() {
+ [&]() {
+ ++this->a;
+#pragma omp parallel firstprivate(a)
+ ++(this)->a;
+ }();
+ }();
+#elif defined(BLOCKS)
+ ^{
+ ^{
+ ++a;
+#pragma omp parallel firstprivate(a)
+ ++(this)->a;
+ }();
+ }();
+#else
+ ++(this)->a;
+#endif
+ }
+};
+
template <class T>
struct S {
T f;
@@ -28,14 +89,17 @@ struct S {
~S() {}
};
+// CHECK: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8
+// LAMBDA: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8
+// BLOCKS: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8
// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float }
// CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
// CHECK-DAG: [[ST_TY:%.+]] = type { i{{[0-9]+}}, i{{[0-9]+}} }
-// CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8*
template <typename T>
T tmain() {
S<T> test;
+ SST<T> sst;
T t_var __attribute__((aligned(128))) = T();
T vec[] __attribute__((aligned(128))) = {1, 2};
S<T> s_arr[] __attribute__((aligned(128))) = {1, 2};
@@ -52,33 +116,79 @@ T tmain() {
int main() {
static int sivar;
+ SS ss(sivar);
#ifdef LAMBDA
// LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
// LAMBDA-LABEL: @main
- // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]](
+ // LAMBDA: alloca [[SS_TY]],
+ // LAMBDA: alloca [[CAP_TY:%.+]],
+ // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@[^(]+]]([[CAP_TY]]*
[&]() {
// LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
// LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 2, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G]], {{.+}})
#pragma omp parallel firstprivate(g, sivar)
{
- // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}})
- // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, align 128
+ // LAMBDA: define {{.+}} @{{.+}}([[SS_TY]]*
+ // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
+ // LAMBDA: store i{{[0-9]+}} 0, i{{[0-9]+}}* %
+ // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
+ // LAMBDA: store i8
+ // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
+ // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
+ // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
+ // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
+ // LAMBDA: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*, [[iz:i64|i32]], {{i64|i32}}, {{i64|i32}}, [4 x i{{[0-9]+}}]*)* [[SS_MICROTASK:@.+]] to void
+ // LAMBDA: ret
+
+ // LAMBDA: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [4 x i{{[0-9]+}}]* {{.+}})
+ // LAMBDA-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %
+ // LAMBDA: call{{.*}} void
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}})
+ // LAMBDA: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA-64: [[A_CONV:%.+]] = bitcast i64* [[A_PRIV]] to i32*
+ // LAMBDA-64: store i32* [[A_CONV]], i32** [[REFA:%.+]],
+ // LAMBDA-32: store i32* [[A_PRIV]], i32** [[REFA:%.+]],
+ // LAMBDA-64: [[B_CONV:%.+]] = bitcast i64* [[B_PRIV]] to i32*
+ // LAMBDA-64: [[C_CONV:%.+]] = bitcast i64* [[C_PRIV]] to i32*
+ // LAMBDA-64: store i32* [[C_CONV]], i32** [[REFC:%.+]],
+ // LAMBDA-32: store i32* [[C_PRIV]], i32** [[REFC:%.+]],
+ // LAMBDA-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]],
+ // LAMBDA-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]],
+ // LAMBDA-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1
+ // LAMBDA-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]],
+ // LAMBDA-64-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_CONV]],
+ // LAMBDA-32-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]],
+ // LAMBDA-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1
+ // LAMBDA-64-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_CONV]],
+ // LAMBDA-32-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]],
+ // LAMBDA-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]],
+ // LAMBDA-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]],
+ // LAMBDA-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1
+ // LAMBDA-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]],
+ // LAMBDA-NEXT: ret void
+
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, [[iz]] {{.*}}%{{.+}})
// LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, align 128
// LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR:%.+]]
- // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_REF_ADDR:%.+]]
+ // LAMBDA-64: [[SIVAR_PRIVATE_CONV:%.+]] = bitcast i64* [[SIVAR_PRIVATE_ADDR]] to i32*
// LAMBDA: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G_REF]], align 128
// LAMBDA: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]], align 128
- // LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]]
- // LAMBDA: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]]
- // LAMBDA: call {{.*}}void @__kmpc_barrier(
+ // LAMBDA-NOT: call {{.*}}void @__kmpc_barrier(
g = 1;
sivar = 2;
// LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]],
- // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]],
+ // LAMBDA-64: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_CONV]],
+ // LAMBDA-32: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]],
// LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
// LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]]
// LAMBDA: [[SIVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
- // LAMBDA: store i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA-64: store i{{[0-9]+}}* [[SIVAR_PRIVATE_CONV]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA-32: store i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]]
// LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
[&]() {
// LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
@@ -98,33 +208,32 @@ int main() {
#elif defined(BLOCKS)
// BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212,
// BLOCKS-LABEL: @main
+ // BLOCKS: call
// BLOCKS: call {{.*}}void {{%.+}}(i8
^{
// BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
// BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 2, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G]], {{.+}})
#pragma omp parallel firstprivate(g, sivar)
{
- // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}})
- // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, align 128
+ // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, [[iz:i64|i32]] {{.*}}%{{.+}})
// BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, align 128
// BLOCKS: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR:%.+]]
- // BLOCKS: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_REF_ADDR:%.+]]
+ // BLOCKS-64: [[SIVAR_PRIVATE_CONV:%.+]] = bitcast i64* [[SIVAR_PRIVATE_ADDR]] to i32*
// BLOCKS: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G_REF]], align 128
// BLOCKS: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]], align 128
- // BLOCK: [[SIVAR_REF_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
- // BLOCK: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_REF_ADDR]]
- // BLOCKS: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]],
- // BLOCKS: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]],
- // BLOCKS: call {{.*}}void @__kmpc_barrier(
+ // BLOCKS-NOT: call {{.*}}void @__kmpc_barrier(
g = 1;
sivar = 2;
// BLOCKS: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]],
- // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]],
+ // BLOCKS-64: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_CONV]],
+ // BLOCKS-32: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]],
// BLOCKS-NOT: [[G]]{{[[^:word:]]}}
// BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]]
// BLOCKS-NOT: [[G]]{{[[^:word:]]}}
// BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}
- // BLOCKS: i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]]
+ // BLOCKS-64: i{{[0-9]+}}* [[SIVAR_PRIVATE_CONV]]
+ // BLOCKS-32: i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]]
// BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}
// BLOCKS: call {{.*}}void {{%.+}}(i8
^{
@@ -142,6 +251,48 @@ int main() {
}
}();
return 0;
+// BLOCKS: define {{.+}} @{{.+}}([[SS_TY]]*
+// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
+// BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* %
+// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
+// BLOCKS: store i8
+// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
+// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
+// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
+// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
+// BLOCKS: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*, [[iz]], [[iz]], [[iz]], [4 x i{{[0-9]+}}]*)* [[SS_MICROTASK:@.+]] to void
+// BLOCKS: ret
+
+// BLOCKS: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [4 x i{{[0-9]+}}]* {{.+}})
+// BLOCKS-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %
+// BLOCKS: call{{.*}} void
+// BLOCKS: ret void
+
+// BLOCKS: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}})
+// BLOCKS: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
+// BLOCKS: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
+// BLOCKS: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
+// BLOCKS-64: [[A_CONV:%.+]] = bitcast i64* [[A_PRIV]] to i32*
+// BLOCKS-64: store i32* [[A_CONV]], i32** [[REFA:%.+]],
+// BLOCKS-32: store i32* [[A_PRIV]], i32** [[REFA:%.+]],
+// BLOCKS-64: [[B_CONV:%.+]] = bitcast i64* [[B_PRIV]] to i32*
+// BLOCKS-64: [[C_CONV:%.+]] = bitcast i64* [[C_PRIV]] to i32*
+// BLOCKS-64: store i32* [[C_CONV]], i32** [[REFC:%.+]],
+// BLOCKS-32: store i32* [[C_PRIV]], i32** [[REFC:%.+]],
+// BLOCKS-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]],
+// BLOCKS-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]],
+// BLOCKS-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1
+// BLOCKS-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]],
+// BLOCKS-64-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_CONV]],
+// BLOCKS-32-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]],
+// BLOCKS-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1
+// BLOCKS-64-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_CONV]],
+// BLOCKS-32-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]],
+// BLOCKS-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]],
+// BLOCKS-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]],
+// BLOCKS-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1
+// BLOCKS-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]],
+// BLOCKS-NEXT: ret void
#else
S<float> test;
int t_var = 0;
@@ -162,27 +313,40 @@ int main() {
// CHECK: define {{.*}}i{{[0-9]+}} @main()
// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[T_VAR:%.+]] = alloca i32,
+// CHECK: [[T_VARCAST:%.+]] = alloca [[iz:i64|i32]],
+// CHECK: [[SIVARCAST:%.+]] = alloca [[iz]],
// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
-// CHECK: call {{.*}}void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x i32]*, i32*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, i{{[0-9]+}}*)* [[MAIN_MICROTASK:@.+]] to void
+// CHECK: [[T_VARVAL:%.+]] = load i32, i32* [[T_VAR]],
+// CHECK-64: [[T_VARCONV:%.+]] = bitcast i64* [[T_VARCAST]] to i32*
+// CHECK-64: store i32 [[T_VARVAL]], i32* [[T_VARCONV]],
+// CHECK-32: store i32 [[T_VARVAL]], i32* [[T_VARCAST]],
+// CHECK: [[T_VARPVT:%.+]] = load [[iz]], [[iz]]* [[T_VARCAST]],
+// CHECK: [[SIVARVAL:%.+]] = load i32, i32* @{{.+}},
+// CHECK-64: [[SIVARCONV:%.+]] = bitcast i64* [[SIVARCAST]] to i32*
+// CHECK-64: store i32 [[SIVARVAL]], i32* [[SIVARCONV]],
+// CHECK-32: store i32 [[SIVARVAL]], i32* [[SIVARCAST]],
+// CHECK: [[SIVARPVT:%.+]] = load [[iz]], [[iz]]* [[SIVARCAST]],
+// CHECK: call {{.*}}void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x i32]*, [[iz]], [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, i{{[0-9]+}})* [[MAIN_MICROTASK:@.+]] to void {{.*}}[[iz]] [[T_VARPVT]],{{.*}}[[iz]] [[SIVARPVT]]
// CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]()
// CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]*
// CHECK: ret
//
-// CHECK: define internal {{.*}}void [[MAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, i32* dereferenceable(4) %{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(8) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}}, i32* dereferenceable(4) [[SIVAR:%.+]])
+// CHECK: define internal {{.*}}void [[MAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [[iz]] {{.*}}%{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(8) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}}, [[iz]] {{.*}}[[SIVAR:%.+]])
// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[SIVAR7_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
-// CHECK: [[SIVAR7_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** %
-// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %
+// CHECK-NOT: load i{{[0-9]+}}*, i{{[0-9]+}}** %
+// CHECK-64: [[T_VAR_CONV:%.+]] = bitcast i64* [[T_VAR_PRIV]] to i32*
// CHECK: [[S_ARR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** %
// CHECK: [[VAR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %
-// CHECK: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}},
-// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]],
-// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]],
+// CHECK-NOT: load i{{[0-9]+}}*, i{{[0-9]+}}** %
+// CHECK-64: [[SIVAR7_CONV:%.+]] = bitcast i64* [[SIVAR7_PRIV]] to i32*
// CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
// CHECK: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_REF]] to i8*
// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST]], i8* [[VEC_SRC]],
@@ -200,9 +364,8 @@ int main() {
// CHECK: call {{.*}} [[S_FLOAT_TY_COPY_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]], [[S_FLOAT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]])
// CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]])
-// CHECK: [[SIVAR_REF_ADDR:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]],
-// CHECK: store i{{[0-9]+}} [[SIVAR_REF_ADDR]], i{{[0-9]+}}* [[SIVAR7_PRIV]],
-// CHECK: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR7_PRIV]],
+// CHECK-64: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR7_CONV]],
+// CHECK-32: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR7_PRIV]],
// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]*
@@ -214,6 +377,55 @@ int main() {
// CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
// CHECK: ret
//
+// CHECK: define {{.+}} @{{.+}}([[SS_TY]]*
+// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
+// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* %
+// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
+// CHECK: store i8
+// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
+// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
+// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*, [[iz]], [[iz]], [[iz]], [4 x i32]*)* [[SS_MICROTASK:@.+]] to void
+// CHECK: ret
+
+// CHECK: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [4 x i{{[0-9]+}}]* {{.+}})
+// CHECK: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[E_PRIV:%.+]] = alloca [4 x i{{[0-9]+}}],
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[A_PRIV]]
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[B_PRIV]]
+// CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[C_PRIV]]
+// CHECK-64: [[A_CONV:%.+]] = bitcast i64* [[A_PRIV:%.+]] to i32*
+// CHECK-64: store i32* [[A_CONV]], i32** [[REFA:%.+]],
+// CHECK-32: store i32* [[A_PRIV]], i32** [[REFA:%.+]],
+// CHECK-64: [[B_CONV:%.+]] = bitcast i64* [[B_PRIV:%.+]] to i32*
+// CHECK-64: [[C_CONV:%.+]] = bitcast i64* [[C_PRIV:%.+]] to i32*
+// CHECK-64: store i32* [[C_CONV]], i32** [[REFC:%.+]],
+// CHECK-32: store i32* [[C_PRIV]], i32** [[REFC:%.+]],
+// CHECK: bitcast [4 x i{{[0-9]+}}]* [[E_PRIV]] to i8*
+// CHECK: bitcast [4 x i{{[0-9]+}}]* %{{.+}} to i8*
+// CHECK: call void @llvm.memcpy
+// CHECK: store [4 x i{{[0-9]+}}]* [[E_PRIV]], [4 x i{{[0-9]+}}]** [[REFE:%.+]],
+// CHECK-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]],
+// CHECK-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]],
+// CHECK-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1
+// CHECK-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]],
+// CHECK-64-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_CONV]],
+// CHECK-32-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]],
+// CHECK-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1
+// CHECK-64-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_CONV]],
+// CHECK-32-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]],
+// CHECK-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]],
+// CHECK-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]],
+// CHECK-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1
+// CHECK-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]],
+// CHECK-NEXT: [[E_PRIV:%.+]] = load [4 x i{{[0-9]+}}]*, [4 x i{{[0-9]+}}]** [[REFE]],
+// CHECK-NEXT: [[E_PRIV_2:%.+]] = getelementptr inbounds [4 x i{{[0-9]+}}], [4 x i{{[0-9]+}}]* [[E_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK-NEXT: store i32 1111, i32* [[E_PRIV_2]],
+// CHECK-NEXT: ret void
+
// CHECK: define internal {{.*}}void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, i32* dereferenceable(4) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(8) %{{.+}}, [[S_INT_TY]]* dereferenceable(4) %{{.+}})
// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, align 128
// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], align 128
@@ -244,9 +456,7 @@ int main() {
// CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]])
// CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]])
// CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]])
-// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
-// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
-// CHECK: call {{.*}}void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK-NOT: call {{.*}}void @__kmpc_barrier(
// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]])
// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]*
// CHECK: ret void
@@ -270,13 +480,13 @@ struct St {
void array_func(float a[3], St s[2], int n, long double vla1[n]) {
double vla2[n][n] __attribute__((aligned(128)));
// ARRAY: @__kmpc_fork_call(
-// ARRAY-DAG: [[PRIV_A:%.+]] = alloca float**,
-// ARRAY-DAG: [[PRIV_S:%.+]] = alloca %struct.St**,
-// ARRAY-DAG: [[PRIV_VLA1:%.+]] = alloca x86_fp80**,
+// ARRAY-DAG: [[PRIV_S:%.+]] = alloca %struct.St*,
+// ARRAY-DAG: [[PRIV_VLA1:%.+]] = alloca x86_fp80*,
+// ARRAY-DAG: [[PRIV_A:%.+]] = alloca float*,
// ARRAY-DAG: [[PRIV_VLA2:%.+]] = alloca double*,
-// ARRAY-DAG: store float** %{{.+}}, float*** [[PRIV_A]],
-// ARRAY-DAG: store %struct.St** %{{.+}}, %struct.St*** [[PRIV_S]],
-// ARRAY-DAG: store x86_fp80** %{{.+}}, x86_fp80*** [[PRIV_VLA1]],
+// ARRAY-DAG: store %struct.St* %{{.+}}, %struct.St** [[PRIV_S]],
+// ARRAY-DAG: store x86_fp80* %{{.+}}, x86_fp80** [[PRIV_VLA1]],
+// ARRAY-DAG: store float* %{{.+}}, float** [[PRIV_A]],
// ARRAY-DAG: store double* %{{.+}}, double** [[PRIV_VLA2]],
// ARRAY: call i8* @llvm.stacksave()
// ARRAY: [[SIZE:%.+]] = mul nuw i64 %{{.+}}, 8
@@ -288,11 +498,11 @@ void array_func(float a[3], St s[2], int n, long double vla1[n]) {
// ARRAY-LABEL: St_func
// ARRAY: @__kmpc_fork_call(
-// ARRAY-DAG: [[PRIV_S:%.+]] = alloca %struct.St**,
-// ARRAY-DAG: [[PRIV_VLA1:%.+]] = alloca x86_fp80**,
+// ARRAY-DAG: [[PRIV_VLA1:%.+]] = alloca x86_fp80*,
+// ARRAY-DAG: [[PRIV_S:%.+]] = alloca %struct.St*,
// ARRAY-DAG: [[PRIV_VLA2:%.+]] = alloca double*,
-// ARRAY-DAG: store %struct.St** %{{.+}}, %struct.St*** [[PRIV_S]],
-// ARRAY-DAG: store x86_fp80** %{{.+}}, x86_fp80*** [[PRIV_VLA1]],
+// ARRAY-DAG: store %struct.St* %{{.+}}, %struct.St** [[PRIV_S]],
+// ARRAY-DAG: store x86_fp80* %{{.+}}, x86_fp80** [[PRIV_VLA1]],
// ARRAY-DAG: store double* %{{.+}}, double** [[PRIV_VLA2]],
// ARRAY: call i8* @llvm.stacksave()
// ARRAY: [[SIZE:%.+]] = mul nuw i64 %{{.+}}, 8
diff --git a/test/OpenMP/parallel_for_ast_print.cpp b/test/OpenMP/parallel_for_ast_print.cpp
index c4be521455df2..2476ee87605aa 100644
--- a/test/OpenMP/parallel_for_ast_print.cpp
+++ b/test/OpenMP/parallel_for_ast_print.cpp
@@ -8,6 +8,57 @@
void foo() {}
+struct S {
+ S(): a(0) {}
+ S(int v) : a(v) {}
+ int a;
+ typedef int type;
+};
+
+template <typename T>
+class S7 : public T {
+protected:
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(typename T::type v) : a(v) {
+#pragma omp parallel for private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp parallel for private(a) private(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp parallel for private(this->a) private(this->a) private(this->S::a)
+// CHECK: #pragma omp parallel for private(this->a) private(this->a) private(T::a)
+// CHECK: #pragma omp parallel for private(this->a) private(this->a)
+
+class S8 : public S7<S> {
+ S8() {}
+
+public:
+ S8(int v) : S7<S>(v){
+#pragma omp parallel for private(a) private(this->a) private(S7<S>::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S8 &operator=(S8 &s) {
+#pragma omp parallel for private(a) private(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp parallel for private(this->a) private(this->a) private(this->S7<S>::a)
+// CHECK: #pragma omp parallel for private(this->a) private(this->a)
+
template <class T, int N>
T tmain(T argc) {
T b = argc, c, d, e, f, h;
diff --git a/test/OpenMP/parallel_for_collapse_messages.cpp b/test/OpenMP/parallel_for_collapse_messages.cpp
index 6e5f71ff16727..4461df8cccdba 100644
--- a/test/OpenMP/parallel_for_collapse_messages.cpp
+++ b/test/OpenMP/parallel_for_collapse_messages.cpp
@@ -1,8 +1,13 @@
// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
void foo() {
}
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
bool foobool(int argc) {
return argc;
}
@@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp parallel for collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp parallel for', but found only 1}}
- // expected-error@+3 2 {{directive '#pragma omp parallel for' cannot contain more than one 'collapse' clause}}
- // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+ // expected-error@+6 2 {{directive '#pragma omp parallel for' cannot contain more than one 'collapse' clause}}
+ // expected-error@+5 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
#pragma omp parallel for collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp parallel for collapse (S) // expected-error {{'S' does not refer to a value}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp parallel for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp parallel for collapse (1)
@@ -59,16 +71,27 @@ int main(int argc, char **argv) {
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp parallel for', but found only 1}}
#pragma omp parallel for collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}} expected-note {{as specified in 'collapse' clause}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp parallel for', but found only 1}}
- #pragma omp parallel for collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+ #pragma omp parallel for collapse (foobool(1) > 0 ? 1 : 2)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+3 {{expression is not an integral constant expression}}
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+4{{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
// expected-error@+2 2 {{directive '#pragma omp parallel for' cannot contain more than one 'collapse' clause}}
// expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp parallel for collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp parallel for collapse (S1) // expected-error {{'S1' does not refer to a value}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+1 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp parallel for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
// expected-error@+3 {{statement after '#pragma omp parallel for' must be a for loop}}
diff --git a/test/OpenMP/parallel_for_linear_messages.cpp b/test/OpenMP/parallel_for_linear_messages.cpp
index 7272aada92a08..e5f5b61873c89 100644
--- a/test/OpenMP/parallel_for_linear_messages.cpp
+++ b/test/OpenMP/parallel_for_linear_messages.cpp
@@ -263,7 +263,7 @@ int main(int argc, char **argv) {
for (int k = 0; k < argc; ++k)
++k;
- foomain<int, char>(argc, argv);
+ foomain<int, char>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
return 0;
}
diff --git a/test/OpenMP/parallel_for_loop_messages.cpp b/test/OpenMP/parallel_for_loop_messages.cpp
index 2bb32bdfc1768..7e136e75869cd 100644
--- a/test/OpenMP/parallel_for_loop_messages.cpp
+++ b/test/OpenMP/parallel_for_loop_messages.cpp
@@ -354,12 +354,12 @@ public:
typedef int difference_type;
typedef std::random_access_iterator_tag iterator_category;
};
-// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 2nd argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}}
// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
int operator-(GoodIter a, GoodIter b) { return 0; }
// expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}}
GoodIter operator-(GoodIter a) { return a; }
-// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 2nd argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}}
// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
GoodIter operator-(GoodIter a, int v) { return GoodIter(); }
// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}}
@@ -402,7 +402,7 @@ int test_with_random_access_iterator() {
#pragma omp parallel for
for (begin = GoodIter(0); begin < end; ++begin)
++begin;
-// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'Iter0')}}
+// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}}
// expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
#pragma omp parallel for
for (begin = begin0; begin < end; ++begin)
diff --git a/test/OpenMP/parallel_for_ordered_messages.cpp b/test/OpenMP/parallel_for_ordered_messages.cpp
index 3729eb9a68a35..055fe1bba4237 100644
--- a/test/OpenMP/parallel_for_ordered_messages.cpp
+++ b/test/OpenMP/parallel_for_ordered_messages.cpp
@@ -1,8 +1,13 @@
// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
void foo() {
}
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
bool foobool(int argc) {
return argc;
}
@@ -36,16 +41,23 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}
#pragma omp parallel for ordered((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'ordered' clause}}
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i - ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp parallel for', but found only 1}}
-// expected-error@+3 2 {{directive '#pragma omp parallel for' cannot contain more than one 'ordered' clause}}
-// expected-error@+2 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
-// expected-error@+1 2 {{expression is not an integral constant expression}}
+// expected-error@+6 2 {{directive '#pragma omp parallel for' cannot contain more than one 'ordered' clause}}
+// expected-error@+5 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
+// expected-error@+4 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
#pragma omp parallel for ordered(foobool(argc)), ordered(true), ordered(-5)
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i - ST];
#pragma omp parallel for ordered(S) // expected-error {{'S' does not refer to a value}}
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i - ST];
-// expected-error@+1 2 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+// expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+// expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp parallel for ordered(argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i - ST];
@@ -76,10 +88,17 @@ int main(int argc, char **argv) {
#pragma omp parallel for ordered(2 + 2)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}} expected-note {{as specified in 'ordered' clause}}
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i - 4]; // expected-error {{expected 4 for loops after '#pragma omp parallel for', but found only 1}}
-#pragma omp parallel for ordered(foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+// expected-error@+4 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+// expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp parallel for ordered(foobool(1) > 0 ? 1 : 2)
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i - 4];
-// expected-error@+3 {{expression is not an integral constant expression}}
+// expected-error@+6 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+// expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
// expected-error@+2 2 {{directive '#pragma omp parallel for' cannot contain more than one 'ordered' clause}}
// expected-error@+1 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
#pragma omp parallel for ordered(foobool(argc)), ordered(true), ordered(-5)
@@ -88,7 +107,11 @@ int main(int argc, char **argv) {
#pragma omp parallel for ordered(S1) // expected-error {{'S1' does not refer to a value}}
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i - 4];
-// expected-error@+1 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+// expected-error@+4 {{expression is not an integral constant expression}}
+#else
+// expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp parallel for ordered(argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i - 4];
diff --git a/test/OpenMP/parallel_for_private_messages.cpp b/test/OpenMP/parallel_for_private_messages.cpp
index efc827b0d5e56..cc1b79f4111b0 100644
--- a/test/OpenMP/parallel_for_private_messages.cpp
+++ b/test/OpenMP/parallel_for_private_messages.cpp
@@ -29,7 +29,11 @@ class S4 {
S4(); // expected-note {{implicitly declared private here}}
public:
- S4(int v) : a(v) {}
+ S4(int v) : a(v) {
+#pragma omp parallel for private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
};
class S5 {
int a;
@@ -37,6 +41,50 @@ class S5 {
public:
S5(int v) : a(v) {}
+ S5 &operator=(S5 &s) {
+#pragma omp parallel for private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S6 {
+public:
+ T a;
+
+ S6() : a(0) {}
+ S6(T v) : a(v) {
+#pragma omp parallel for private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+ S6 &operator=(S6 &s) {
+#pragma omp parallel for private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S7 : public T {
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(T v) : a(v) {
+#pragma omp parallel for private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp parallel for private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
};
S3 h;
@@ -119,6 +167,8 @@ using A::x;
int main(int argc, char **argv) {
S4 e(4);
S5 g(5);
+ S6<float> s6(0.0) , s6_0(1.0);
+ S7<S6<float> > s7(0.0) , s7_0(1.0);
int i;
int &j = i;
#pragma omp parallel for private // expected-error {{expected '(' after 'private'}}
@@ -180,6 +230,8 @@ int main(int argc, char **argv) {
for (int k = 0; k < argc; ++k)
m = k + 2;
- return 0;
+ s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}}
+ s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}}
+ return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
}
diff --git a/test/OpenMP/parallel_for_reduction_messages.cpp b/test/OpenMP/parallel_for_reduction_messages.cpp
index 22251b446300b..4d5a143bae3a3 100644
--- a/test/OpenMP/parallel_for_reduction_messages.cpp
+++ b/test/OpenMP/parallel_for_reduction_messages.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s
-// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 100 -o - %s
-// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 100 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s
void foo() {
}
@@ -13,7 +13,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat
extern S1 a;
class S2 {
mutable int a;
- S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}}
+ S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}}
public:
S2() : a(0) {}
@@ -22,7 +22,7 @@ public:
static const float S2sc;
};
const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
-S2 b; // expected-note 2 {{'b' defined here}}
+S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
int a;
@@ -34,7 +34,7 @@ public:
S3 operator+(const S3 &arg1) { return arg1; }
};
int operator+(const S3 &arg1, const S3 &arg2) { return 5; }
-S3 c; // expected-note 2 {{'c' defined here}}
+S3 c; // expected-note 3 {{'c' defined here}}
const S3 ca[5]; // expected-note 2 {{'ca' defined here}}
extern const int f; // expected-note 4 {{'f' declared here}}
class S4 {
@@ -56,9 +56,9 @@ class S5 {
public:
S5(int v) : a(v) {}
};
-class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
#if __cplusplus >= 201103L // C++11 or later
-// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable}}
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
#endif
int a;
@@ -111,7 +111,7 @@ T tmain(T argc) {
#pragma omp parallel for reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp parallel for reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+#pragma omp parallel for reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel for reduction(&& : argc)
@@ -120,22 +120,22 @@ T tmain(T argc) {
#pragma omp parallel for reduction(^ : T) // expected-error {{'T' does not refer to a value}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}}
+#pragma omp parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp parallel for reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}}
+#pragma omp parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp parallel for reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}}
+#pragma omp parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp parallel for reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}}
+#pragma omp parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -150,7 +150,7 @@ T tmain(T argc) {
#pragma omp parallel for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp parallel for reduction(+ : o) // expected-error {{no viable overloaded '='}}
+#pragma omp parallel for reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel for private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
@@ -160,7 +160,7 @@ T tmain(T argc) {
#pragma omp parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp parallel for reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}}
+#pragma omp parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel for reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
@@ -251,13 +251,13 @@ int main(int argc, char **argv) {
#pragma omp parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp parallel for reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}}
+#pragma omp parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp parallel for reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}}
+#pragma omp parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp parallel for reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}}
+#pragma omp parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
diff --git a/test/OpenMP/parallel_for_simd_aligned_messages.cpp b/test/OpenMP/parallel_for_simd_aligned_messages.cpp
index 8bffd21f4655f..2ccdf0697624e 100644
--- a/test/OpenMP/parallel_for_simd_aligned_messages.cpp
+++ b/test/OpenMP/parallel_for_simd_aligned_messages.cpp
@@ -196,6 +196,7 @@ int main(int argc, char **argv) {
#pragma omp parallel for simd aligned(h)
for (int k = 0; k < argc; ++k) ++k;
int *pargc = &argc;
+ // expected-note@+1 {{in instantiation of function template specialization 'foomain<int *, char>' requested here}}
foomain<int*,char>(pargc,argv);
return 0;
}
diff --git a/test/OpenMP/parallel_for_simd_ast_print.cpp b/test/OpenMP/parallel_for_simd_ast_print.cpp
index 1b9415d8dbf30..cdd1b73b59032 100644
--- a/test/OpenMP/parallel_for_simd_ast_print.cpp
+++ b/test/OpenMP/parallel_for_simd_ast_print.cpp
@@ -7,6 +7,58 @@
#define HEADER
void foo() {}
+
+struct S1 {
+ S1() : a(0) {}
+ S1(int v) : a(v) {}
+ int a;
+ typedef int type;
+};
+
+template <typename T>
+class S7 : public T {
+protected:
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(typename T::type v) : a(v) {
+#pragma omp parallel for simd private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp parallel for simd private(a) private(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp parallel for simd private(this->a) private(this->a) private(this->S1::a)
+// CHECK: #pragma omp parallel for simd private(this->a) private(this->a) private(T::a)
+// CHECK: #pragma omp parallel for simd private(this->a) private(this->a)
+
+class S8 : public S7<S1> {
+ S8() {}
+
+public:
+ S8(int v) : S7<S1>(v){
+#pragma omp parallel for simd private(a) private(this->a) private(S7<S1>::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S8 &operator=(S8 &s) {
+#pragma omp parallel for simd private(a) private(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp parallel for simd private(this->a) private(this->a) private(this->S7<S1>::a)
+// CHECK: #pragma omp parallel for simd private(this->a) private(this->a)
+
int g_ind = 1;
template<class T, class N> T reduct(T* arr, N num) {
N i;
diff --git a/test/OpenMP/parallel_for_simd_collapse_messages.cpp b/test/OpenMP/parallel_for_simd_collapse_messages.cpp
index 4f04cca5635eb..c7effbddeb28c 100644
--- a/test/OpenMP/parallel_for_simd_collapse_messages.cpp
+++ b/test/OpenMP/parallel_for_simd_collapse_messages.cpp
@@ -1,8 +1,13 @@
// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
void foo() {
}
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
bool foobool(int argc) {
return argc;
}
@@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp parallel for simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp parallel for simd', but found only 1}}
- // expected-error@+3 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'collapse' clause}}
- // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+ // expected-error@+6 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'collapse' clause}}
+ // expected-error@+5 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
#pragma omp parallel for simd collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp parallel for simd collapse (S) // expected-error {{'S' does not refer to a value}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp parallel for simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp parallel for simd collapse (1)
@@ -59,16 +71,27 @@ int main(int argc, char **argv) {
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp parallel for simd', but found only 1}}
#pragma omp parallel for simd collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} expected-note {{as specified in 'collapse' clause}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp parallel for simd', but found only 1}}
- #pragma omp parallel for simd collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+ #pragma omp parallel for simd collapse (foobool(1) > 0 ? 1 : 2)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+3 {{expression is not an integral constant expression}}
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
// expected-error@+2 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'collapse' clause}}
// expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp parallel for simd collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp parallel for simd collapse (S1) // expected-error {{'S1' does not refer to a value}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+1 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp parallel for simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
// expected-error@+3 {{statement after '#pragma omp parallel for simd' must be a for loop}}
diff --git a/test/OpenMP/parallel_for_simd_linear_messages.cpp b/test/OpenMP/parallel_for_simd_linear_messages.cpp
index 858f53f4674da..fc1895a36854a 100644
--- a/test/OpenMP/parallel_for_simd_linear_messages.cpp
+++ b/test/OpenMP/parallel_for_simd_linear_messages.cpp
@@ -208,7 +208,7 @@ int main(int argc, char **argv) {
#pragma omp parallel for simd linear(i)
for (int k = 0; k < argc; ++k) ++k;
- foomain<int,char>(argc,argv);
+ foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
return 0;
}
diff --git a/test/OpenMP/parallel_for_simd_loop_messages.cpp b/test/OpenMP/parallel_for_simd_loop_messages.cpp
index e5fd8c04c0cfc..403e951d53c43 100644
--- a/test/OpenMP/parallel_for_simd_loop_messages.cpp
+++ b/test/OpenMP/parallel_for_simd_loop_messages.cpp
@@ -355,12 +355,12 @@ public:
typedef int difference_type;
typedef std::random_access_iterator_tag iterator_category;
};
-// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 2nd argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}}
// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
int operator-(GoodIter a, GoodIter b) { return 0; }
// expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}}
GoodIter operator-(GoodIter a) { return a; }
-// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 2nd argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}}
// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
GoodIter operator-(GoodIter a, int v) { return GoodIter(); }
// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}}
@@ -403,7 +403,7 @@ int test_with_random_access_iterator() {
#pragma omp parallel for simd
for (begin = GoodIter(0); begin < end; ++begin)
++begin;
-// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'Iter0')}}
+// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}}
// expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
#pragma omp parallel for simd
for (begin = begin0; begin < end; ++begin)
diff --git a/test/OpenMP/parallel_for_simd_private_messages.cpp b/test/OpenMP/parallel_for_simd_private_messages.cpp
index a031d407ec1bf..a33b35d57d1ef 100644
--- a/test/OpenMP/parallel_for_simd_private_messages.cpp
+++ b/test/OpenMP/parallel_for_simd_private_messages.cpp
@@ -29,7 +29,11 @@ class S4 {
S4(); // expected-note {{implicitly declared private here}}
public:
- S4(int v) : a(v) {}
+ S4(int v) : a(v) {
+#pragma omp parallel for simd private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
};
class S5 {
int a;
@@ -37,6 +41,50 @@ class S5 {
public:
S5(int v) : a(v) {}
+ S5 &operator=(S5 &s) {
+#pragma omp parallel for simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S6 {
+public:
+ T a;
+
+ S6() : a(0) {}
+ S6(T v) : a(v) {
+#pragma omp parallel for simd private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+ S6 &operator=(S6 &s) {
+#pragma omp parallel for simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S7 : public T {
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(T v) : a(v) {
+#pragma omp parallel for simd private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp parallel for simd private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
};
S3 h;
@@ -119,6 +167,8 @@ using A::x;
int main(int argc, char **argv) {
S4 e(4);
S5 g(5);
+ S6<float> s6(0.0) , s6_0(1.0);
+ S7<S6<float> > s7(0.0) , s7_0(1.0);
int i;
int &j = i;
#pragma omp parallel for simd private // expected-error {{expected '(' after 'private'}}
@@ -180,6 +230,8 @@ int main(int argc, char **argv) {
for (int k = 0; k < argc; ++k)
m = k + 3;
- return 0;
+ s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}}
+ s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}}
+ return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
}
diff --git a/test/OpenMP/parallel_for_simd_reduction_messages.cpp b/test/OpenMP/parallel_for_simd_reduction_messages.cpp
index e2e9e1bca38b0..afb0b367c4193 100644
--- a/test/OpenMP/parallel_for_simd_reduction_messages.cpp
+++ b/test/OpenMP/parallel_for_simd_reduction_messages.cpp
@@ -13,7 +13,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat
extern S1 a;
class S2 {
mutable int a;
- S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}}
+ S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}}
public:
S2() : a(0) {}
@@ -22,7 +22,7 @@ public:
static const float S2sc;
};
const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
-S2 b; // expected-note 2 {{'b' defined here}}
+S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
int a;
@@ -34,7 +34,7 @@ public:
S3 operator+(const S3 &arg1) { return arg1; }
};
int operator+(const S3 &arg1, const S3 &arg2) { return 5; }
-S3 c; // expected-note 2 {{'c' defined here}}
+S3 c; // expected-note 3 {{'c' defined here}}
const S3 ca[5]; // expected-note 2 {{'ca' defined here}}
extern const int f; // expected-note 4 {{'f' declared here}}
class S4 {
@@ -56,9 +56,9 @@ class S5 {
public:
S5(int v) : a(v) {}
};
-class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
#if __cplusplus >= 201103L // C++11 or later
-// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable}}
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
#endif
int a;
@@ -111,7 +111,7 @@ T tmain(T argc) {
#pragma omp parallel for simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp parallel for simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+#pragma omp parallel for simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel for simd reduction(&& : argc)
@@ -120,22 +120,22 @@ T tmain(T argc) {
#pragma omp parallel for simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}}
+#pragma omp parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp parallel for simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}}
+#pragma omp parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp parallel for simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}}
+#pragma omp parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp parallel for simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}}
+#pragma omp parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -150,7 +150,7 @@ T tmain(T argc) {
#pragma omp parallel for simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp parallel for simd reduction(+ : o) // expected-error {{no viable overloaded '='}}
+#pragma omp parallel for simd reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel for simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
@@ -160,7 +160,7 @@ T tmain(T argc) {
#pragma omp parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}}
+#pragma omp parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel for simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
@@ -251,13 +251,13 @@ int main(int argc, char **argv) {
#pragma omp parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp parallel for simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}}
+#pragma omp parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp parallel for simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}}
+#pragma omp parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp parallel for simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}}
+#pragma omp parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
diff --git a/test/OpenMP/parallel_for_simd_safelen_messages.cpp b/test/OpenMP/parallel_for_simd_safelen_messages.cpp
index 45f2fa2b6277c..3e643c619c6fc 100644
--- a/test/OpenMP/parallel_for_simd_safelen_messages.cpp
+++ b/test/OpenMP/parallel_for_simd_safelen_messages.cpp
@@ -1,8 +1,13 @@
// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
void foo() {
}
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
bool foobool(int argc) {
return argc;
}
@@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp parallel for simd safelen ((ST > 0) ? 1 + ST : 2)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error@+3 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'safelen' clause}}
- // expected-error@+2 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+ // expected-error@+6 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'safelen' clause}}
+ // expected-error@+5 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
#pragma omp parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp parallel for simd safelen (S) // expected-error {{'S' does not refer to a value}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp parallel for simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp parallel for simd safelen (4)
@@ -57,16 +69,27 @@ int main(int argc, char **argv) {
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp parallel for simd safelen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- #pragma omp parallel for simd safelen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+ #pragma omp parallel for simd safelen (foobool(1) > 0 ? 1 : 2)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+3 {{expression is not an integral constant expression}}
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
// expected-error@+2 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'safelen' clause}}
// expected-error@+1 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
#pragma omp parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp parallel for simd safelen (S1) // expected-error {{'S1' does not refer to a value}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+1 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp parallel for simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
// expected-error@+3 {{statement after '#pragma omp parallel for simd' must be a for loop}}
diff --git a/test/OpenMP/parallel_for_simd_simdlen_messages.cpp b/test/OpenMP/parallel_for_simd_simdlen_messages.cpp
index dd1cf0feaa497..fa9e0d6802a9c 100644
--- a/test/OpenMP/parallel_for_simd_simdlen_messages.cpp
+++ b/test/OpenMP/parallel_for_simd_simdlen_messages.cpp
@@ -1,8 +1,13 @@
// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
void foo() {
}
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
bool foobool(int argc) {
return argc;
}
@@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp parallel for simd simdlen ((ST > 0) ? 1 + ST : 2)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error@+3 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'simdlen' clause}}
- // expected-error@+2 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+ // expected-error@+6 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'simdlen' clause}}
+ // expected-error@+5 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
#pragma omp parallel for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp parallel for simd simdlen (S) // expected-error {{'S' does not refer to a value}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp parallel for simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp parallel for simd simdlen (4)
@@ -57,16 +69,27 @@ int main(int argc, char **argv) {
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp parallel for simd simdlen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- #pragma omp parallel for simd simdlen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+ #pragma omp parallel for simd simdlen (foobool(1) > 0 ? 1 : 2)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+3 {{expression is not an integral constant expression}}
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
// expected-error@+2 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'simdlen' clause}}
// expected-error@+1 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
#pragma omp parallel for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp parallel for simd simdlen (S1) // expected-error {{'S1' does not refer to a value}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+1 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp parallel for simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
// expected-error@+3 {{statement after '#pragma omp parallel for simd' must be a for loop}}
diff --git a/test/OpenMP/parallel_num_threads_codegen.cpp b/test/OpenMP/parallel_num_threads_codegen.cpp
index d744e5e87b748..c5f11bde19aed 100644
--- a/test/OpenMP/parallel_num_threads_codegen.cpp
+++ b/test/OpenMP/parallel_num_threads_codegen.cpp
@@ -72,11 +72,11 @@ int main() {
// CHECK: [[GTID:%.+]] = call {{.*}}i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEF_LOC_2]])
// CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID]], i32 1)
// CHECK: call {{.*}}void {{.*}} @__kmpc_fork_call(
-// CHECK: call {{.*}} [[S_TY_CONSTR]]([[S_TY]]* [[S_TEMP:%.+]], [[INTPTR_T_TY]] [[INTPTR_T_TY_ATTR]]23)
+// CHECK: {{(invoke|call)}} {{.*}} [[S_TY_CONSTR]]([[S_TY]]* [[S_TEMP:%.+]], [[INTPTR_T_TY]] [[INTPTR_T_TY_ATTR]]23)
// CHECK: [[S_CHAR_OP:%.+]] = invoke{{.*}} i8 [[S_TY_CHAR_OP]]([[S_TY]]* [[S_TEMP]])
// CHECK: [[RES:%.+]] = sext {{.*}}i8 [[S_CHAR_OP]] to i32
// CHECK: call {{.*}}void @__kmpc_push_num_threads([[IDENT_T_TY]]* [[DEF_LOC_2]], i32 [[GTID]], i32 [[RES]])
-// CHECK: call {{.*}} [[S_TY_DESTR]]([[S_TY]]* [[S_TEMP]])
+// CHECK: {{(invoke|call)}} {{.*}} [[S_TY_DESTR]]([[S_TY]]* [[S_TEMP]])
// CHECK: call {{.*}}void {{.*}} @__kmpc_fork_call(
// CHECK: ret [[INT_TY]] 0
// CHECK: }
diff --git a/test/OpenMP/parallel_private_codegen.cpp b/test/OpenMP/parallel_private_codegen.cpp
index 1d195be97d6e8..1498d456dfa55 100644
--- a/test/OpenMP/parallel_private_codegen.cpp
+++ b/test/OpenMP/parallel_private_codegen.cpp
@@ -18,11 +18,69 @@ struct S {
volatile int g __attribute__((aligned(128))) = 1212;
+struct SS {
+ int a;
+ int b : 4;
+ int &c;
+ SS(int &d) : a(0), b(0), c(d) {
+#pragma omp parallel private(a, b, c)
+#ifdef LAMBDA
+ [&]() {
+ ++this->a, --b, (this)->c /= 1;
+#pragma omp parallel private(a, b, c)
+ ++(this)->a, --b, this->c /= 1;
+ }();
+#elif defined(BLOCKS)
+ ^{
+ ++a;
+ --this->b;
+ (this)->c /= 1;
+#pragma omp parallel private(a, b, c)
+ ++(this)->a, --b, this->c /= 1;
+ }();
+#else
+ ++this->a, --b, c /= 1;
+#endif
+ }
+};
+
+template<typename T>
+struct SST {
+ T a;
+ SST() : a(T()) {
+#pragma omp parallel private(a)
+#ifdef LAMBDA
+ [&]() {
+ [&]() {
+ ++this->a;
+#pragma omp parallel private(a)
+ ++(this)->a;
+ }();
+ }();
+#elif defined(BLOCKS)
+ ^{
+ ^{
+ ++a;
+#pragma omp parallel private(a)
+ ++(this)->a;
+ }();
+ }();
+#else
+ ++(this)->a;
+#endif
+ }
+};
+
+// CHECK: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8
+// LAMBDA: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8
+// BLOCKS: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8
// CHECK: [[S_FLOAT_TY:%.+]] = type { float }
// CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+// CHECK: [[SST_TY:%.+]] = type { i{{[0-9]+}} }
template <typename T>
T tmain() {
S<T> test;
+ SST<T> sst;
T t_var __attribute__((aligned(128))) = T();
T vec[] __attribute__((aligned(128))) = {1, 2};
S<T> s_arr[] __attribute__((aligned(128))) = {1, 2};
@@ -37,16 +95,49 @@ T tmain() {
int main() {
static int sivar;
+ SS ss(sivar);
#ifdef LAMBDA
// LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
// LAMBDA-LABEL: @main
- // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]](
+ // LAMBDA: alloca [[SS_TY]],
+ // LAMBDA: alloca [[CAP_TY:%.+]],
+ // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@[^(]+]]([[CAP_TY]]*
[&]() {
// LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
// LAMBDA-NOT: = getelementptr inbounds %{{.+}},
// LAMBDA: call{{.*}} void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, {{.+}}* [[OMP_REGION:@.+]] to {{.+}})
#pragma omp parallel private(g, sivar)
{
+ // LAMBDA: define {{.+}} @{{.+}}([[SS_TY]]*
+ // LAMBDA: store i{{[0-9]+}} 0, i{{[0-9]+}}* %
+ // LAMBDA: store i8
+ // LAMBDA: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void
+ // LAMBDA: ret
+
+ // LAMBDA: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}})
+ // LAMBDA-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %
+ // LAMBDA: call{{.*}} void
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}})
+ // LAMBDA: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]],
+ // LAMBDA: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]],
+ // LAMBDA-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]],
+ // LAMBDA-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]],
+ // LAMBDA-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1
+ // LAMBDA-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]],
+ // LAMBDA-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]],
+ // LAMBDA-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1
+ // LAMBDA-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]],
+ // LAMBDA-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]],
+ // LAMBDA-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]],
+ // LAMBDA-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1
+ // LAMBDA-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]],
+ // LAMBDA-NEXT: ret void
+
// LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}})
// LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
// LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
@@ -80,6 +171,7 @@ int main() {
#elif defined(BLOCKS)
// BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212,
// BLOCKS-LABEL: @main
+ // BLOCKS: call
// BLOCKS: call{{.*}} void {{%.+}}(i8
^{
// BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
@@ -116,6 +208,35 @@ int main() {
}
}();
return 0;
+// BLOCKS: define {{.+}} @{{.+}}([[SS_TY]]*
+// BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* %
+// BLOCKS: store i8
+// BLOCKS: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void
+// BLOCKS: ret
+
+// BLOCKS: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}})
+// BLOCKS-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %
+// BLOCKS: call{{.*}} void
+// BLOCKS: ret void
+
+// BLOCKS: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}})
+// BLOCKS: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
+// BLOCKS: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
+// BLOCKS: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
+// BLOCKS: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]],
+// BLOCKS: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]],
+// BLOCKS-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]],
+// BLOCKS-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]],
+// BLOCKS-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1
+// BLOCKS-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]],
+// BLOCKS-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]],
+// BLOCKS-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1
+// BLOCKS-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]],
+// BLOCKS-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]],
+// BLOCKS-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]],
+// BLOCKS-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1
+// BLOCKS-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]],
+// BLOCKS-NEXT: ret void
#else
S<float> test;
int t_var = 0;
@@ -166,6 +287,31 @@ int main() {
// CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
// CHECK: ret
//
+// CHECK: define {{.+}} @{{.+}}([[SS_TY]]*
+// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* %
+// CHECK: store i8
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void
+// CHECK: ret
+
+// CHECK: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}})
+// CHECK: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]],
+// CHECK: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]],
+// CHECK-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]],
+// CHECK-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]],
+// CHECK-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1
+// CHECK-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]],
+// CHECK-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]],
+// CHECK-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1
+// CHECK-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]],
+// CHECK-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]],
+// CHECK-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]],
+// CHECK-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1
+// CHECK-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]],
+// CHECK-NEXT: ret void
+
// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}})
// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, align 128
// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], align 128
@@ -184,5 +330,20 @@ int main() {
// CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]])
// CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]*
// CHECK: ret void
+
+// CHECK: define {{.+}} @{{.+}}([[SST_TY]]* %
+// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* %
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SST_TY]]*)* [[SST_MICROTASK:@.+]] to void
+// CHECK: ret
+
+// CHECK: define internal void [[SST_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SST_TY]]* %{{.+}})
+// CHECK: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REF:%.+]],
+// CHECK-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REF]],
+// CHECK-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]],
+// CHECK-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1
+// CHECK-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]],
+// CHECK-NEXT: ret void
+
#endif
diff --git a/test/OpenMP/parallel_reduction_codegen.cpp b/test/OpenMP/parallel_reduction_codegen.cpp
index 05224d0a1391c..703750c2337f7 100644
--- a/test/OpenMP/parallel_reduction_codegen.cpp
+++ b/test/OpenMP/parallel_reduction_codegen.cpp
@@ -20,6 +20,62 @@ struct S {
~S() {}
};
+struct SS {
+ int a;
+ int b : 4;
+ int &c;
+ SS(int &d) : a(0), b(0), c(d) {
+#pragma omp parallel reduction(+: a, b, c)
+#ifdef LAMBDA
+ [&]() {
+ ++this->a, --b, (this)->c /= 1;
+#pragma omp parallel reduction(&: a, b, c)
+ ++(this)->a, --b, this->c /= 1;
+ }();
+#elif defined(BLOCKS)
+ ^{
+ ++a;
+ --this->b;
+ (this)->c /= 1;
+#pragma omp parallel reduction(-: a, b, c)
+ ++(this)->a, --b, this->c /= 1;
+ }();
+#else
+ ++this->a, --b, c /= 1;
+#endif
+ }
+};
+
+template<typename T>
+struct SST {
+ T a;
+ SST() : a(T()) {
+#pragma omp parallel reduction(*: a)
+#ifdef LAMBDA
+ [&]() {
+ [&]() {
+ ++this->a;
+#pragma omp parallel reduction(&& :a)
+ ++(this)->a;
+ }();
+ }();
+#elif defined(BLOCKS)
+ ^{
+ ^{
+ ++a;
+#pragma omp parallel reduction(|: a)
+ ++(this)->a;
+ }();
+ }();
+#else
+ ++(this)->a;
+#endif
+ }
+};
+
+// CHECK: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8
+// LAMBDA: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8
+// BLOCKS: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8
// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float }
// CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
// CHECK-DAG: [[REDUCTION_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 18, i32 0, i32 0, i8*
@@ -29,6 +85,7 @@ template <typename T>
T tmain() {
T t;
S<T> test;
+ SST<T> sst;
T t_var __attribute__((aligned(128))) = T(), t_var1 __attribute__((aligned(128)));
T vec[] = {1, 2};
S<T> s_arr[] = {1, 2};
@@ -41,16 +98,62 @@ T tmain() {
return T();
}
+int sivar;
int main() {
+ SS ss(sivar);
#ifdef LAMBDA
// LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
// LAMBDA-LABEL: @main
- // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ // LAMBDA: alloca [[SS_TY]],
+ // LAMBDA: alloca [[CAP_TY:%.+]],
+ // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@[^(]+]]([[CAP_TY]]*
[&]() {
// LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
// LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G]])
#pragma omp parallel reduction(+:g)
{
+ // LAMBDA: define {{.+}} @{{.+}}([[SS_TY]]*
+ // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
+ // LAMBDA: store i{{[0-9]+}} 0, i{{[0-9]+}}* %
+ // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
+ // LAMBDA: store i8
+ // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
+ // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
+ // LAMBDA-NOT: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
+ // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
+ // LAMBDA: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*, i32*, i32*, i32*)* [[SS_MICROTASK:@.+]] to void
+ // LAMBDA: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1
+ // LAMBDA: store i8 %{{.+}}, i8* [[B_REF]],
+ // LAMBDA: ret
+
+ // LAMBDA: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, i32* {{.+}}, i32* {{.+}}, i32* {{.+}})
+ // LAMBDA-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %
+ // LAMBDA: call{{.*}} void
+ // LAMBDA: ret void
+
+ // LAMBDA: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]*
+ // LAMBDA: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: store i{{[0-9]+}} -1, i{{[0-9]+}}* [[A_PRIV]],
+ // LAMBDA: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]],
+ // LAMBDA: store i{{[0-9]+}} -1, i{{[0-9]+}}* [[B_PRIV]],
+ // LAMBDA: store i{{[0-9]+}} -1, i{{[0-9]+}}* [[C_PRIV]],
+ // LAMBDA: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]],
+ // LAMBDA: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]],
+ // LAMBDA-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]],
+ // LAMBDA-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1
+ // LAMBDA-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]],
+ // LAMBDA-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]],
+ // LAMBDA-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1
+ // LAMBDA-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]],
+ // LAMBDA-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]],
+ // LAMBDA-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]],
+ // LAMBDA-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1
+ // LAMBDA-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]],
+ // LAMBDA: call i32 @__kmpc_reduce_nowait(
+ // LAMBDA: ret void
+
// LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}})
// LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
@@ -100,6 +203,7 @@ int main() {
#elif defined(BLOCKS)
// BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212,
// BLOCKS-LABEL: @main
+ // BLOCKS: call
// BLOCKS: call void {{%.+}}(i8
^{
// BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
@@ -152,6 +256,47 @@ int main() {
}
}();
return 0;
+// BLOCKS: define {{.+}} @{{.+}}([[SS_TY]]*
+// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
+// BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* %
+// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
+// BLOCKS: store i8
+// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
+// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
+// BLOCKS-NOT: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
+// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
+// BLOCKS: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*, i32*, i32*, i32*)* [[SS_MICROTASK:@.+]] to void
+// BLOCKS: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1
+// BLOCKS: store i8 %{{.+}}, i8* [[B_REF]],
+// BLOCKS: ret
+
+// BLOCKS: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, i32* {{.+}}, i32* {{.+}}, i32* {{.+}})
+// BLOCKS-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %
+// BLOCKS: call{{.*}} void
+// BLOCKS: ret void
+
+// BLOCKS: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, i32* {{.+}}, i32* {{.+}}, i32* {{.+}})
+// BLOCKS: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
+// BLOCKS: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
+// BLOCKS: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
+// BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[A_PRIV]],
+// BLOCKS: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]],
+// BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[B_PRIV]],
+// BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[C_PRIV]],
+// BLOCKS: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]],
+// BLOCKS: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]],
+// BLOCKS-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]],
+// BLOCKS-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1
+// BLOCKS-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]],
+// BLOCKS-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]],
+// BLOCKS-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1
+// BLOCKS-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]],
+// BLOCKS-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]],
+// BLOCKS-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]],
+// BLOCKS-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1
+// BLOCKS-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]],
+// BLOCKS: call i32 @__kmpc_reduce_nowait(
+// BLOCKS: ret void
#else
S<float> test;
float t_var = 0, t_var1;
@@ -472,6 +617,43 @@ int main() {
// CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
// CHECK: ret
//
+// CHECK: define {{.+}} @{{.+}}([[SS_TY]]*
+// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
+// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* %
+// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
+// CHECK: store i8
+// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
+// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
+// CHECK-NOT: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
+// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*, i{{[0-9]+}}*, i{{[0-9]+}}*, i{{[0-9]+}}*)* [[SS_MICROTASK:@.+]] to void
+// CHECK: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1
+// CHECK: store i8 %{{.+}}, i8* [[B_REF]],
+// CHECK: ret
+
+// CHECK: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]*
+// CHECK: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[A_PRIV]],
+// CHECK: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]],
+// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[B_PRIV]],
+// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[C_PRIV]],
+// CHECK: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]],
+// CHECK: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]],
+// CHECK-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]],
+// CHECK-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1
+// CHECK-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]],
+// CHECK-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]],
+// CHECK-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1
+// CHECK-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]],
+// CHECK-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]],
+// CHECK-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]],
+// CHECK-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1
+// CHECK-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]],
+// CHECK: call i32 @__kmpc_reduce_nowait(
+// CHECK: ret void
+
// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}},
// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, align 128
// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]], align 128
diff --git a/test/OpenMP/parallel_reduction_messages.cpp b/test/OpenMP/parallel_reduction_messages.cpp
index b29f7c98a5744..af1f5ed7bc0d9 100644
--- a/test/OpenMP/parallel_reduction_messages.cpp
+++ b/test/OpenMP/parallel_reduction_messages.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s
-// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 100 -o - %s
-// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 100 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s
void foo() {
}
@@ -13,7 +13,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat
extern S1 a;
class S2 {
mutable int a;
- S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}}
+ S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}}
public:
S2() : a(0) {}
@@ -22,7 +22,7 @@ public:
static const float S2sc;
};
const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
-S2 b; // expected-note 2 {{'b' defined here}}
+S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
int a;
@@ -34,7 +34,7 @@ public:
S3 operator+(const S3 &arg1) { return arg1; }
};
int operator+(const S3 &arg1, const S3 &arg2) { return 5; }
-S3 c; // expected-note 2 {{'c' defined here}}
+S3 c; // expected-note 3 {{'c' defined here}}
const S3 ca[5]; // expected-note 2 {{'ca' defined here}}
extern const int f; // expected-note 4 {{'f' declared here}}
class S4 {
@@ -56,9 +56,9 @@ class S5 {
public:
S5(int v) : a(v) {}
};
-class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
#if __cplusplus >= 201103L // C++11 or later
-// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable}}
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
#endif
int a;
@@ -101,23 +101,23 @@ T tmain(T argc) {
foo();
#pragma omp parallel reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}}
foo();
-#pragma omp parallel reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+#pragma omp parallel reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
foo();
#pragma omp parallel reduction(&& : argc)
foo();
#pragma omp parallel reduction(^ : T) // expected-error {{'T' does not refer to a value}}
foo();
-#pragma omp parallel reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}}
+#pragma omp parallel reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
foo();
-#pragma omp parallel reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp parallel reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
foo();
#pragma omp parallel reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
foo();
-#pragma omp parallel reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}}
+#pragma omp parallel reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
foo();
-#pragma omp parallel reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}}
+#pragma omp parallel reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
foo();
-#pragma omp parallel reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}}
+#pragma omp parallel reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
foo();
#pragma omp parallel reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
foo();
@@ -127,14 +127,14 @@ T tmain(T argc) {
foo();
#pragma omp parallel reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
foo();
-#pragma omp parallel reduction(+ : o) // expected-error {{no viable overloaded '='}}
+#pragma omp parallel reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
foo();
#pragma omp parallel private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
foo();
#pragma omp parallel private(k)
#pragma omp parallel reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
foo();
-#pragma omp parallel reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}}
+#pragma omp parallel reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
foo();
#pragma omp parallel reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
foo();
@@ -208,11 +208,11 @@ int main(int argc, char **argv) {
foo();
#pragma omp parallel reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
foo();
-#pragma omp parallel reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}}
+#pragma omp parallel reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
foo();
-#pragma omp parallel reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}}
+#pragma omp parallel reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
foo();
-#pragma omp parallel reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}}
+#pragma omp parallel reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
foo();
#pragma omp parallel reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
foo();
diff --git a/test/OpenMP/parallel_sections_ast_print.cpp b/test/OpenMP/parallel_sections_ast_print.cpp
index 9f5c1fadbeb82..a66b75ea6d796 100644
--- a/test/OpenMP/parallel_sections_ast_print.cpp
+++ b/test/OpenMP/parallel_sections_ast_print.cpp
@@ -141,4 +141,7 @@ int main(int argc, char **argv) {
return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x);
}
+template<typename T>
+T S<T>::TS = 0;
+
#endif
diff --git a/test/OpenMP/parallel_sections_private_messages.cpp b/test/OpenMP/parallel_sections_private_messages.cpp
index ac9280e74ce10..40b0138b53967 100644
--- a/test/OpenMP/parallel_sections_private_messages.cpp
+++ b/test/OpenMP/parallel_sections_private_messages.cpp
@@ -29,7 +29,13 @@ class S4 {
S4(); // expected-note {{implicitly declared private here}}
public:
- S4(int v) : a(v) {}
+ S4(int v) : a(v) {
+#pragma omp parallel sections private(a) private(this->a)
+ {
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+ }
};
class S5 {
int a;
@@ -37,6 +43,60 @@ class S5 {
public:
S5(int v) : a(v) {}
+ S5 &operator=(S5 &s) {
+#pragma omp parallel sections private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ {
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ }
+ return *this;
+ }
+};
+
+template <typename T>
+class S6 {
+public:
+ T a;
+
+ S6() : a(0) {}
+ S6(T v) : a(v) {
+#pragma omp parallel sections private(a) private(this->a)
+ {
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+ }
+ S6 &operator=(S6 &s) {
+#pragma omp parallel sections private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ {
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ }
+ return *this;
+ }
+};
+
+template <typename T>
+class S7 : public T {
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(T v) : a(v) {
+#pragma omp parallel sections private(a) private(this->a) private(T::a)
+ {
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp parallel sections private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}}
+ {
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ }
+ return *this;
+ }
};
S3 h;
@@ -134,6 +194,8 @@ using A::x;
int main(int argc, char **argv) {
S4 e(4);
S5 g(5);
+ S6<float> s6(0.0) , s6_0(1.0);
+ S7<S6<float> > s7(0.0) , s7_0(1.0);
int i;
int &j = i;
#pragma omp parallel sections private // expected-error {{expected '(' after 'private'}}
@@ -212,6 +274,8 @@ int main(int argc, char **argv) {
foo();
}
- return 0;
+ s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}}
+ s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}}
+ return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
}
diff --git a/test/OpenMP/parallel_sections_reduction_messages.cpp b/test/OpenMP/parallel_sections_reduction_messages.cpp
index eff1849d71323..52d4cb9cdcb65 100644
--- a/test/OpenMP/parallel_sections_reduction_messages.cpp
+++ b/test/OpenMP/parallel_sections_reduction_messages.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s
-// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 100 -o - %s
-// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 100 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s
void foo() {
}
@@ -13,7 +13,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat
extern S1 a;
class S2 {
mutable int a;
- S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}}
+ S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}}
public:
S2() : a(0) {}
@@ -22,7 +22,7 @@ public:
static const float S2sc;
};
const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
-S2 b; // expected-note 2 {{'b' defined here}}
+S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
int a;
@@ -34,7 +34,7 @@ public:
S3 operator+(const S3 &arg1) { return arg1; }
};
int operator+(const S3 &arg1, const S3 &arg2) { return 5; }
-S3 c; // expected-note 2 {{'c' defined here}}
+S3 c; // expected-note 3 {{'c' defined here}}
const S3 ca[5]; // expected-note 2 {{'ca' defined here}}
extern const int f; // expected-note 4 {{'f' declared here}}
class S4 {
@@ -56,9 +56,9 @@ class S5 {
public:
S5(int v) : a(v) {}
};
-class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
#if __cplusplus >= 201103L // C++11 or later
-// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable}}
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
#endif
int a;
@@ -121,7 +121,7 @@ T tmain(T argc) {
{
foo();
}
-#pragma omp parallel sections reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+#pragma omp parallel sections reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
{
foo();
}
@@ -133,11 +133,11 @@ T tmain(T argc) {
{
foo();
}
-#pragma omp parallel sections reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}}
+#pragma omp parallel sections reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
{
foo();
}
-#pragma omp parallel sections reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp parallel sections reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
{
foo();
}
@@ -145,15 +145,15 @@ T tmain(T argc) {
{
foo();
}
-#pragma omp parallel sections reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}}
+#pragma omp parallel sections reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
{
foo();
}
-#pragma omp parallel sections reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}}
+#pragma omp parallel sections reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
{
foo();
}
-#pragma omp parallel sections reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}}
+#pragma omp parallel sections reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
{
foo();
}
@@ -173,7 +173,7 @@ T tmain(T argc) {
{
foo();
}
-#pragma omp parallel sections reduction(+ : o) // expected-error {{no viable overloaded '='}}
+#pragma omp parallel sections reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
{
foo();
}
@@ -186,7 +186,7 @@ T tmain(T argc) {
{
foo();
}
-#pragma omp parallel sections reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}}
+#pragma omp parallel sections reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
{
foo();
}
@@ -298,15 +298,15 @@ int main(int argc, char **argv) {
{
foo();
}
-#pragma omp parallel sections reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}}
+#pragma omp parallel sections reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
{
foo();
}
-#pragma omp parallel sections reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}}
+#pragma omp parallel sections reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
{
foo();
}
-#pragma omp parallel sections reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}}
+#pragma omp parallel sections reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
{
foo();
}
diff --git a/test/OpenMP/predefined_macro.c b/test/OpenMP/predefined_macro.c
index 9a961bce552f2..e18c3d26d4c22 100644
--- a/test/OpenMP/predefined_macro.c
+++ b/test/OpenMP/predefined_macro.c
@@ -5,7 +5,7 @@
// -fopenmp option is specified
#ifndef _OPENMP
#error "No _OPENMP macro is defined with -fopenmp option"
-#elsif _OPENMP != 201307
+#elsif _OPENMP != 201107
#error "_OPENMP has incorrect value"
#endif //_OPENMP
#else
diff --git a/test/OpenMP/sections_firstprivate_codegen.cpp b/test/OpenMP/sections_firstprivate_codegen.cpp
index 0e9273f52ca77..51d0c7b61834c 100644
--- a/test/OpenMP/sections_firstprivate_codegen.cpp
+++ b/test/OpenMP/sections_firstprivate_codegen.cpp
@@ -59,7 +59,6 @@ S<float> s_arr[] = {1, 2};
// CHECK-DAG: [[VAR:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
S<float> var(3);
// CHECK-DAG: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0,
-// CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8*
// CHECK-DAG: [[SECTIONS_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 194, i32 0, i32 0, i8*
// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
@@ -94,7 +93,7 @@ int main() {
// LAMBDA: [[SIVAR1_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR1_REF]]
// LAMBDA: store i{{[0-9]+}} [[SIVAR1_VAL]], i{{[0-9]+}}* [[SIVAR1_PRIVATE_ADDR]]
- // LAMBDA: call void @__kmpc_barrier(
+ // LAMBDA-NOT: call void @__kmpc_barrier(
{
g = 1;
sivar = 10;
@@ -154,7 +153,7 @@ int main() {
// BLOCKS: [[SIVAR1_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR1_REF]],
// BLOCKS: store i{{[0-9]+}} [[SIVAR1_VAL]], i{{[0-9]+}}* [[SIVAR1_PRIVATE_ADDR]],
- // BLOCKS: call void @__kmpc_barrier(
+ // BLOCKS-NOT: call void @__kmpc_barrier(
{
g = 1;
sivar = 10;
@@ -217,6 +216,7 @@ int main() {
// firstprivate t_var(t_var)
// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR]],
// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]],
+
// firstprivate vec(vec)
// CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST]], i8* bitcast ([2 x i{{[0-9]+}}]* [[VEC]] to i8*),
@@ -242,7 +242,7 @@ int main() {
// CHECK: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR]],
// CHECK: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIV]],
-// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK-NOT: call void @__kmpc_barrier(
// CHECK: call void @__kmpc_for_static_init_4(
// CHECK: call void @__kmpc_for_static_fini(
@@ -257,7 +257,11 @@ int main() {
// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
-// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i32*, [2 x i32]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void
+// CHECK: [[T_VARVAL:%.+]] = load i32, i32* %{{.+}},
+// CHECK: [[T_VARCONV:%.+]] = bitcast i64* [[T_VARCAST:%.+]] to i32*
+// CHECK: store i32 [[T_VARVAL]], i32* [[T_VARCONV]],
+// CHECK: [[T_VARPVT:%.+]] = load i64, i64* [[T_VARCAST]],
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, [2 x i32]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void {{.*}}i64 [[T_VARPVT]],
// CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
// CHECK: ret
//
@@ -268,19 +272,20 @@ int main() {
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
+// CHECK: alloca i{{[0-9]+}},
// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
-// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %
+// CHECK-NOT: load i{{[0-9]+}}*, i{{[0-9]+}}** %
// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** %
// CHECK: [[S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** %
// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** %
// firstprivate t_var(t_var)
-// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]],
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}*
// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]],
// firstprivate vec(vec)
@@ -304,10 +309,8 @@ int main() {
// CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]])
// CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]])
-// Synchronization for initialization.
-// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
-// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
-// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// No synchronization for initialization.
+// CHECK-NOT: call void @__kmpc_barrier(
// CHECK: call void @__kmpc_for_static_init_4(
// CHECK: call void @__kmpc_for_static_fini(
diff --git a/test/OpenMP/sections_private_messages.cpp b/test/OpenMP/sections_private_messages.cpp
index f13bbdb012e22..27bb3136e7201 100644
--- a/test/OpenMP/sections_private_messages.cpp
+++ b/test/OpenMP/sections_private_messages.cpp
@@ -29,7 +29,13 @@ class S4 {
S4(); // expected-note {{implicitly declared private here}}
public:
- S4(int v) : a(v) {}
+ S4(int v) : a(v) {
+#pragma omp sections private(a) private(this->a)
+ {
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+ }
};
class S5 {
int a;
@@ -37,6 +43,60 @@ class S5 {
public:
S5(int v) : a(v) {}
+ S5 &operator=(S5 &s) {
+#pragma omp sections private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ {
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ }
+ return *this;
+ }
+};
+
+template <typename T>
+class S6 {
+public:
+ T a;
+
+ S6() : a(0) {}
+ S6(T v) : a(v) {
+#pragma omp sections private(a) private(this->a)
+ {
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+ }
+ S6 &operator=(S6 &s) {
+#pragma omp sections private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ {
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ }
+ return *this;
+ }
+};
+
+template <typename T>
+class S7 : public T {
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(T v) : a(v) {
+#pragma omp sections private(a) private(this->a) private(T::a)
+ {
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp sections private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}}
+ {
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ }
+ return *this;
+ }
};
S3 h;
@@ -134,6 +194,8 @@ using A::x;
int main(int argc, char **argv) {
S4 e(4);
S5 g(5);
+ S6<float> s6(0.0) , s6_0(1.0);
+ S7<S6<float> > s7(0.0) , s7_0(1.0);
int i;
int &j = i;
#pragma omp sections private // expected-error {{expected '(' after 'private'}}
@@ -212,6 +274,8 @@ int main(int argc, char **argv) {
foo();
}
- return 0;
+ s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}}
+ s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}}
+ return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
}
diff --git a/test/OpenMP/sections_reduction_messages.cpp b/test/OpenMP/sections_reduction_messages.cpp
index 79473d4e5d289..134bf619c9113 100644
--- a/test/OpenMP/sections_reduction_messages.cpp
+++ b/test/OpenMP/sections_reduction_messages.cpp
@@ -13,7 +13,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat
extern S1 a;
class S2 {
mutable int a;
- S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}}
+ S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}}
public:
S2() : a(0) {}
@@ -22,7 +22,7 @@ public:
static const float S2sc;
};
const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
-S2 b; // expected-note 2 {{'b' defined here}}
+S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
int a;
@@ -34,7 +34,7 @@ public:
S3 operator+(const S3 &arg1) { return arg1; }
};
int operator+(const S3 &arg1, const S3 &arg2) { return 5; }
-S3 c; // expected-note 2 {{'c' defined here}}
+S3 c; // expected-note 3 {{'c' defined here}}
const S3 ca[5]; // expected-note 2 {{'ca' defined here}}
extern const int f; // expected-note 4 {{'f' declared here}}
class S4 {
@@ -56,9 +56,9 @@ class S5 {
public:
S5(int v) : a(v) {}
};
-class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
#if __cplusplus >= 201103L // C++11 or later
-// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable}}
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
#endif
int a;
@@ -132,7 +132,7 @@ T tmain(T argc) {
foo();
}
#pragma omp parallel
-#pragma omp sections reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+#pragma omp sections reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
{
foo();
}
@@ -147,12 +147,12 @@ T tmain(T argc) {
foo();
}
#pragma omp parallel
-#pragma omp sections reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}}
+#pragma omp sections reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
{
foo();
}
#pragma omp parallel
-#pragma omp sections reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp sections reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
{
foo();
}
@@ -162,17 +162,17 @@ T tmain(T argc) {
foo();
}
#pragma omp parallel
-#pragma omp sections reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}}
+#pragma omp sections reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
{
foo();
}
#pragma omp parallel
-#pragma omp sections reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}}
+#pragma omp sections reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
{
foo();
}
#pragma omp parallel
-#pragma omp sections reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}}
+#pragma omp sections reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
{
foo();
}
@@ -197,7 +197,7 @@ T tmain(T argc) {
foo();
}
#pragma omp parallel
-#pragma omp sections reduction(+ : o) // expected-error {{no viable overloaded '='}}
+#pragma omp sections reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
{
foo();
}
@@ -212,7 +212,7 @@ T tmain(T argc) {
foo();
}
#pragma omp parallel
-#pragma omp sections reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}}
+#pragma omp sections reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
{
foo();
}
@@ -342,17 +342,17 @@ int main(int argc, char **argv) {
foo();
}
#pragma omp parallel
-#pragma omp sections reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}}
+#pragma omp sections reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
{
foo();
}
#pragma omp parallel
-#pragma omp sections reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}}
+#pragma omp sections reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
{
foo();
}
#pragma omp parallel
-#pragma omp sections reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}}
+#pragma omp sections reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
{
foo();
}
diff --git a/test/OpenMP/simd_aligned_messages.cpp b/test/OpenMP/simd_aligned_messages.cpp
index 6be7529ad5119..9515a0bca68f1 100644
--- a/test/OpenMP/simd_aligned_messages.cpp
+++ b/test/OpenMP/simd_aligned_messages.cpp
@@ -196,6 +196,7 @@ int main(int argc, char **argv) {
#pragma omp simd aligned(h)
for (int k = 0; k < argc; ++k) ++k;
int *pargc = &argc;
+ // expected-note@+1 {{in instantiation of function template specialization 'foomain<int *, char>' requested here}}
foomain<int*,char>(pargc,argv);
return 0;
}
diff --git a/test/OpenMP/simd_ast_print.cpp b/test/OpenMP/simd_ast_print.cpp
index cabbe338db2a4..99c00c6dca814 100644
--- a/test/OpenMP/simd_ast_print.cpp
+++ b/test/OpenMP/simd_ast_print.cpp
@@ -6,6 +6,58 @@
#ifndef HEADER
#define HEADER
+struct SS {
+ SS(): a(0) {}
+ SS(int v) : a(v) {}
+ int a;
+ typedef int type;
+};
+
+template <typename T>
+class S7 : public T {
+protected:
+ T *a;
+ T b[2];
+ S7() : a(0) {}
+
+public:
+ S7(typename T::type &v) : a((T*)&v) {
+#pragma omp simd aligned(a)
+ for (int k = 0; k < a->a; ++k)
+ ++this->a->a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp simd aligned(this->b : 8)
+ for (int k = 0; k < s.a->a; ++k)
+ ++s.a->a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp simd aligned(this->a)
+// CHECK: #pragma omp simd aligned(this->a)
+// CHECK: #pragma omp simd aligned(this->b: 8)
+
+class S8 : public S7<SS> {
+ S8() {}
+
+public:
+ S8(int v) : S7<SS>(v){
+#pragma omp simd aligned(S7<SS>::a)
+ for (int k = 0; k < a->a; ++k)
+ ++this->a->a;
+ }
+ S8 &operator=(S8 &s) {
+#pragma omp simd aligned(this->b: 4)
+ for (int k = 0; k < s.a->a; ++k)
+ ++s.a->a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp simd aligned(this->S7<SS>::a)
+// CHECK: #pragma omp simd aligned(this->b: 4)
+
void foo() {}
int g_ind = 1;
template<class T, class N> T reduct(T* arr, N num) {
diff --git a/test/OpenMP/simd_codegen.cpp b/test/OpenMP/simd_codegen.cpp
index 62028339f5142..29828b39173cd 100644
--- a/test/OpenMP/simd_codegen.cpp
+++ b/test/OpenMP/simd_codegen.cpp
@@ -4,8 +4,10 @@
// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG
// REQUIRES: x86-registered-target
// expected-no-diagnostics
-#ifndef HEADER
-#define HEADER
+ #ifndef HEADER
+ #define HEADER
+
+// CHECK: [[SS_TY:%.+]] = type { i32 }
long long get_val() { return 0; }
double *g_ptr;
@@ -207,6 +209,7 @@ void simple(float *a, float *b, float *c, float *d) {
// CHECK-NEXT: store i64 [[ADD7_2]], i64* [[OMP_IV7]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP7_ID]]
}
// CHECK: [[SIMPLE_LOOP7_END]]
+// CHECK-NEXT: store i64 11, i64*
// CHECK-NEXT: [[A_PRIV_VAL:%.+]] = load i32, i32* [[A_PRIV]],
// CHECK-NEXT: store i32 [[A_PRIV_VAL]], i32* [[A]],
int R;
@@ -321,7 +324,6 @@ public:
// CHECK-LABEL: define {{.*void}} @{{.*}}iter_simple{{.*}}
void iter_simple(IterDouble ia, IterDouble ib, IterDouble ic) {
//
-// CHECK: store i32 0, i32* [[IT_OMP_IV:%[^,]+]]
// Calculate number of iterations before the loop body.
// CHECK: [[DIFF1:%.+]] = invoke {{.*}}i32 @{{.*}}IterDouble{{.*}}
// CHECK: [[DIFF2:%.+]] = sub nsw i32 [[DIFF1]], 1
@@ -329,6 +331,7 @@ void iter_simple(IterDouble ia, IterDouble ib, IterDouble ic) {
// CHECK-NEXT: [[DIFF4:%.+]] = sdiv i32 [[DIFF3]], 1
// CHECK-NEXT: [[DIFF5:%.+]] = sub nsw i32 [[DIFF4]], 1
// CHECK-NEXT: store i32 [[DIFF5]], i32* [[OMP_LAST_IT:%[^,]+]]{{.+}}
+// CHECK: store i32 0, i32* [[IT_OMP_IV:%[^,]+]]
#pragma omp simd
// CHECK: [[IV:%.+]] = load i32, i32* [[IT_OMP_IV]]{{.+}} !llvm.mem.parallel_loop_access ![[ITER_LOOP_ID:[0-9]+]]
@@ -416,9 +419,10 @@ void collapsed(float *a, float *b, float *c, float *d) {
// CHECK: [[COLL1_END]]
}
// i,j,l are updated; k is not updated.
-// CHECK: store i32 3, i32* [[I:%[^,]+]]
-// CHECK-NEXT: store i32 5, i32* [[I:%[^,]+]]
-// CHECK-NEXT: store i16 9, i16* [[I:%[^,]+]]
+// CHECK: store i32 3, i32*
+// CHECK-NEXT: store i32 5, i32*
+// CHECK-NEXT: store i32 7, i32*
+// CHECK-NEXT: store i16 9, i16*
// CHECK: ret void
}
@@ -490,8 +494,10 @@ void linear(float *a) {
#pragma omp simd linear(k : 3)
// CHECK: store i64* [[VAL_ADDR]], i64** [[K_ADDR]],
+// CHECK: [[VAL_REF:%.+]] = load i64*, i64** [[K_ADDR]],
+// CHECK: store i64* [[VAL_REF]], i64** [[K_ADDR_REF:%.+]],
// CHECK: store i32 0, i32* [[OMP_IV:%[^,]+]]
-// CHECK: [[K_REF:%.+]] = load i64*, i64** [[K_ADDR]],
+// CHECK: [[K_REF:%.+]] = load i64*, i64** [[K_ADDR_REF]],
// CHECK: [[K0LOAD:%.+]] = load i64, i64* [[K_REF]]
// CHECK-NEXT: store i64 [[K0LOAD]], i64* [[LIN0:%[^,]+]]
@@ -524,7 +530,7 @@ void linear(float *a) {
// CHECK: [[SIMPLE_LOOP_END]]
//
// Update linear vars after loop, as the loop was operating on a private version.
-// CHECK: [[K_REF:%.+]] = load i64*, i64** [[K_ADDR]],
+// CHECK: [[K_REF:%.+]] = load i64*, i64** [[K_ADDR_REF]],
// CHECK: store i64* [[K_REF]], i64** [[K_PRIV_REF:%.+]],
// CHECK: [[LIN0_2:%.+]] = load i64, i64* [[LIN0]]
// CHECK-NEXT: [[LIN_ADD2:%.+]] = add nsw i64 [[LIN0_2]], 27
@@ -533,8 +539,10 @@ void linear(float *a) {
//
#pragma omp simd linear(val(k) : 3)
+// CHECK: [[VAL_REF:%.+]] = load i64*, i64** [[K_ADDR]],
+// CHECK: store i64* [[VAL_REF]], i64** [[K_ADDR_REF:%.+]],
// CHECK: store i32 0, i32* [[OMP_IV:%[^,]+]]
-// CHECK: [[K_REF:%.+]] = load i64*, i64** [[K_ADDR]],
+// CHECK: [[K_REF:%.+]] = load i64*, i64** [[K_ADDR_REF]],
// CHECK: [[K0LOAD:%.+]] = load i64, i64* [[K_REF]]
// CHECK-NEXT: store i64 [[K0LOAD]], i64* [[LIN0:%[^,]+]]
@@ -567,7 +575,7 @@ void linear(float *a) {
// CHECK: [[SIMPLE_LOOP_END]]
//
// Update linear vars after loop, as the loop was operating on a private version.
-// CHECK: [[K_REF:%.+]] = load i64*, i64** [[K_ADDR]],
+// CHECK: [[K_REF:%.+]] = load i64*, i64** [[K_ADDR_REF]],
// CHECK: store i64* [[K_REF]], i64** [[K_PRIV_REF:%.+]],
// CHECK: [[LIN0_2:%.+]] = load i64, i64* [[LIN0]]
// CHECK-NEXT: [[LIN_ADD2:%.+]] = add nsw i64 [[LIN0_2]], 27
@@ -632,5 +640,68 @@ void parallel_simd(float *a) {
a[i] += bar();
}
// TERM_DEBUG: !{{[0-9]+}} = !DILocation(line: [[@LINE-11]],
+
+// CHECK-LABEL: S8
+// CHECK: ptrtoint [[SS_TY]]* %{{.+}} to i64
+// CHECK-NEXT: and i64 %{{.+}}, 15
+// CHECK-NEXT: icmp eq i64 %{{.+}}, 0
+// CHECK-NEXT: call void @llvm.assume(i1
+
+// CHECK: ptrtoint [[SS_TY]]* %{{.+}} to i64
+// CHECK-NEXT: and i64 %{{.+}}, 7
+// CHECK-NEXT: icmp eq i64 %{{.+}}, 0
+// CHECK-NEXT: call void @llvm.assume(i1
+
+// CHECK: ptrtoint [[SS_TY]]* %{{.+}} to i64
+// CHECK-NEXT: and i64 %{{.+}}, 15
+// CHECK-NEXT: icmp eq i64 %{{.+}}, 0
+// CHECK-NEXT: call void @llvm.assume(i1
+
+// CHECK: ptrtoint [[SS_TY]]* %{{.+}} to i64
+// CHECK-NEXT: and i64 %{{.+}}, 3
+// CHECK-NEXT: icmp eq i64 %{{.+}}, 0
+// CHECK-NEXT: call void @llvm.assume(i1
+struct SS {
+ SS(): a(0) {}
+ SS(int v) : a(v) {}
+ int a;
+ typedef int type;
+};
+
+template <typename T>
+class S7 : public T {
+protected:
+ T *a;
+ T b[2];
+ S7() : a(0) {}
+
+public:
+ S7(typename T::type &v) : a((T*)&v) {
+#pragma omp simd aligned(a)
+ for (int k = 0; k < a->a; ++k)
+ ++this->a->a;
+#pragma omp simd aligned(this->b : 8)
+ for (int k = 0; k < a->a; ++k)
+ ++a->a;
+ }
+};
+
+class S8 : private IterDouble, public S7<SS> {
+ S8() {}
+
+public:
+ S8(int v) : S7<SS>(v){
+#pragma omp parallel private(a)
+#pragma omp simd aligned(S7<SS>::a)
+ for (int k = 0; k < a->a; ++k)
+ ++this->a->a;
+#pragma omp parallel shared(b)
+#pragma omp simd aligned(this->b: 4)
+ for (int k = 0; k < a->a; ++k)
+ ++a->a;
+ }
+};
+S8 s8(0);
+
#endif // HEADER
diff --git a/test/OpenMP/simd_collapse_messages.cpp b/test/OpenMP/simd_collapse_messages.cpp
index e34f0a15b20c9..5b8802468849b 100644
--- a/test/OpenMP/simd_collapse_messages.cpp
+++ b/test/OpenMP/simd_collapse_messages.cpp
@@ -1,8 +1,13 @@
// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
void foo() {
}
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
bool foobool(int argc) {
return argc;
}
@@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp simd', but found only 1}}
- // expected-error@+3 2 {{directive '#pragma omp simd' cannot contain more than one 'collapse' clause}}
- // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+ // expected-error@+6 2 {{directive '#pragma omp simd' cannot contain more than one 'collapse' clause}}
+ // expected-error@+5 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
#pragma omp simd collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp simd collapse (S) // expected-error {{'S' does not refer to a value}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp simd collapse (1)
@@ -59,16 +71,27 @@ int main(int argc, char **argv) {
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}}
#pragma omp simd collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}} expected-note {{as specified in 'collapse' clause}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}}
- #pragma omp simd collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+ #pragma omp simd collapse (foobool(1) > 0 ? 1 : 2)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+3 {{expression is not an integral constant expression}}
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
// expected-error@+2 2 {{directive '#pragma omp simd' cannot contain more than one 'collapse' clause}}
// expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp simd collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp simd collapse (S1) // expected-error {{'S1' does not refer to a value}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+1 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp simd collapse (2) // expected-note {{as specified in 'collapse' clause}}
diff --git a/test/OpenMP/simd_lastprivate_messages.cpp b/test/OpenMP/simd_lastprivate_messages.cpp
index 7cc5ba81f78b4..16223db71ad57 100644
--- a/test/OpenMP/simd_lastprivate_messages.cpp
+++ b/test/OpenMP/simd_lastprivate_messages.cpp
@@ -217,5 +217,5 @@ int main(int argc, char **argv) {
#pragma omp simd lastprivate(t) // OK
for (i = 0; i < argc; ++i)
foo();
- return 0;
+ return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
}
diff --git a/test/OpenMP/simd_private_messages.cpp b/test/OpenMP/simd_private_messages.cpp
index 3442d182ed02e..1850101891f7e 100644
--- a/test/OpenMP/simd_private_messages.cpp
+++ b/test/OpenMP/simd_private_messages.cpp
@@ -26,13 +26,61 @@ class S4 {
int a;
S4(); // expected-note {{implicitly declared private here}}
public:
- S4(int v):a(v) { }
+ S4(int v) : a(v) {
+#pragma omp simd private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
};
class S5 {
int a;
S5():a(0) {} // expected-note {{implicitly declared private here}}
public:
S5(int v):a(v) { }
+ S5 &operator=(S5 &s) {
+#pragma omp simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S6 {
+public:
+ T a;
+
+ S6() : a(0) {}
+ S6(T v) : a(v) {
+#pragma omp simd private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+ S6 &operator=(S6 &s) {
+#pragma omp simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S7 : public T {
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(T v) : a(v) {
+#pragma omp simd private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp simd private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
};
S3 h;
@@ -96,6 +144,8 @@ using A::x;
int main(int argc, char **argv) {
S4 e(4);
S5 g(5);
+ S6<float> s6(0.0) , s6_0(1.0);
+ S7<S6<float> > s7(0.0) , s7_0(1.0);
int i;
int &j = i;
#pragma omp simd private // expected-error {{expected '(' after 'private'}}
@@ -137,6 +187,8 @@ int main(int argc, char **argv) {
#pragma omp simd private(i)
for (int k = 0; k < argc; ++k) ++k;
- return 0;
+ s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}}
+ s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}}
+ return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
}
diff --git a/test/OpenMP/simd_reduction_messages.cpp b/test/OpenMP/simd_reduction_messages.cpp
index e082921cf3839..c47d53eb9185e 100644
--- a/test/OpenMP/simd_reduction_messages.cpp
+++ b/test/OpenMP/simd_reduction_messages.cpp
@@ -13,7 +13,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat
extern S1 a;
class S2 {
mutable int a;
- S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}}
+ S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}}
public:
S2() : a(0) {}
@@ -22,7 +22,7 @@ public:
static const float S2sc;
};
const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
-S2 b; // expected-note 2 {{'b' defined here}}
+S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
int a;
@@ -34,7 +34,7 @@ public:
S3 operator+(const S3 &arg1) { return arg1; }
};
int operator+(const S3 &arg1, const S3 &arg2) { return 5; }
-S3 c; // expected-note 2 {{'c' defined here}}
+S3 c; // expected-note 3 {{'c' defined here}}
const S3 ca[5]; // expected-note 2 {{'ca' defined here}}
extern const int f; // expected-note 4 {{'f' declared here}}
class S4 {
@@ -56,9 +56,9 @@ class S5 {
public:
S5(int v) : a(v) {}
};
-class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
#if __cplusplus >= 201103L // C++11 or later
-// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable}}
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
#endif
int a;
@@ -111,7 +111,7 @@ T tmain(T argc) {
#pragma omp simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+#pragma omp simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp simd reduction(&& : argc)
@@ -120,22 +120,22 @@ T tmain(T argc) {
#pragma omp simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}}
+#pragma omp simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}}
+#pragma omp simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}}
+#pragma omp simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}}
+#pragma omp simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -150,7 +150,7 @@ T tmain(T argc) {
#pragma omp simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp simd reduction(+ : o) // expected-error {{no viable overloaded '='}}
+#pragma omp simd reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
@@ -163,7 +163,7 @@ T tmain(T argc) {
#pragma omp simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp simd reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}}
+#pragma omp simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
@@ -254,13 +254,13 @@ int main(int argc, char **argv) {
#pragma omp simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}}
+#pragma omp simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}}
+#pragma omp simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}}
+#pragma omp simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
diff --git a/test/OpenMP/simd_safelen_messages.cpp b/test/OpenMP/simd_safelen_messages.cpp
index aa31b7da9b7fc..56cb868337e0f 100644
--- a/test/OpenMP/simd_safelen_messages.cpp
+++ b/test/OpenMP/simd_safelen_messages.cpp
@@ -1,8 +1,13 @@
// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
void foo() {
}
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
bool foobool(int argc) {
return argc;
}
@@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp simd safelen ((ST > 0) ? 1 + ST : 2)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error@+3 2 {{directive '#pragma omp simd' cannot contain more than one 'safelen' clause}}
- // expected-error@+2 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+ // expected-error@+6 2 {{directive '#pragma omp simd' cannot contain more than one 'safelen' clause}}
+ // expected-error@+5 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
#pragma omp simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp simd safelen (S) // expected-error {{'S' does not refer to a value}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp simd safelen (4)
@@ -57,16 +69,27 @@ int main(int argc, char **argv) {
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp simd safelen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- #pragma omp simd safelen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+ #pragma omp simd safelen (foobool(1) > 0 ? 1 : 2)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+3 {{expression is not an integral constant expression}}
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
// expected-error@+2 2 {{directive '#pragma omp simd' cannot contain more than one 'safelen' clause}}
// expected-error@+1 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
#pragma omp simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp simd safelen (S1) // expected-error {{'S1' does not refer to a value}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+1 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
// expected-error@+3 {{statement after '#pragma omp simd' must be a for loop}}
diff --git a/test/OpenMP/simd_simdlen_messages.cpp b/test/OpenMP/simd_simdlen_messages.cpp
index 91656f87b583e..426d1878ba4ca 100644
--- a/test/OpenMP/simd_simdlen_messages.cpp
+++ b/test/OpenMP/simd_simdlen_messages.cpp
@@ -1,8 +1,13 @@
// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
void foo() {
}
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
bool foobool(int argc) {
return argc;
}
@@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp simd simdlen ((ST > 0) ? 1 + ST : 2)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error@+3 2 {{directive '#pragma omp simd' cannot contain more than one 'simdlen' clause}}
- // expected-error@+2 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+ // expected-error@+6 2 {{directive '#pragma omp simd' cannot contain more than one 'simdlen' clause}}
+ // expected-error@+5 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
#pragma omp simd simdlen (foobool(argc)), simdlen (true), simdlen (-5)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp simd simdlen (S) // expected-error {{'S' does not refer to a value}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp simd simdlen (4)
@@ -57,16 +69,27 @@ int main(int argc, char **argv) {
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp simd simdlen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- #pragma omp simd simdlen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+ #pragma omp simd simdlen (foobool(1) > 0 ? 1 : 2)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+3 {{expression is not an integral constant expression}}
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
// expected-error@+2 2 {{directive '#pragma omp simd' cannot contain more than one 'simdlen' clause}}
// expected-error@+1 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
#pragma omp simd simdlen (foobool(argc)), simdlen (true), simdlen (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp simd simdlen (S1) // expected-error {{'S1' does not refer to a value}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+1 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
// expected-error@+3 {{statement after '#pragma omp simd' must be a for loop}}
diff --git a/test/OpenMP/single_ast_print.cpp b/test/OpenMP/single_ast_print.cpp
index 8eb35174a77f2..d30b7feb02c57 100644
--- a/test/OpenMP/single_ast_print.cpp
+++ b/test/OpenMP/single_ast_print.cpp
@@ -8,15 +8,43 @@
void foo() {}
+struct SS {
+ int a;
+ int b : 4;
+ int &c;
+ SS(int &d) : a(0), b(0), c(d) {
+#pragma omp parallel firstprivate(a, b, c)
+#pragma omp single copyprivate(a, this->b, (this)->c)
+// CHECK: #pragma omp parallel firstprivate(this->a,this->b,this->c)
+// CHECK-NEXT: #pragma omp single copyprivate(this->a,this->b,this->c)
+ ++this->a, --b, (this)->c /= 1;
+ }
+};
+
+template<typename T>
+struct SST {
+ T a;
+ SST() : a(T()) {
+// CHECK: #pragma omp parallel firstprivate(this->a)
+// CHECK-NEXT: #pragma omp single copyprivate(this->a)
+// CHECK: #pragma omp parallel firstprivate(this->a)
+// CHECK-NEXT: #pragma omp single copyprivate(this->a)
+#pragma omp parallel firstprivate(a)
+#pragma omp single copyprivate(this->a)
+ ++this->a;
+ }
+};
+
template <class T, int N>
T tmain(T argc) {
T b = argc, c, d, e, f, g;
static T a;
+ SST<T> sst;
// CHECK: static T a;
#pragma omp parallel private(g)
#pragma omp single private(argc, b), firstprivate(c, d), nowait
foo();
- // CHECK-NEXT: #pragma omp parallel private(g)
+ // CHECK: #pragma omp parallel private(g)
// CHECK-NEXT: #pragma omp single private(argc,b) firstprivate(c,d) nowait
// CHECK-NEXT: foo();
#pragma omp parallel private(g)
@@ -31,11 +59,12 @@ T tmain(T argc) {
int main(int argc, char **argv) {
int b = argc, c, d, e, f, g;
static int a;
+ SS ss(a);
// CHECK: static int a;
#pragma omp parallel private(g)
#pragma omp single private(argc, b), firstprivate(argv, c), nowait
foo();
- // CHECK-NEXT: #pragma omp parallel private(g)
+ // CHECK: #pragma omp parallel private(g)
// CHECK-NEXT: #pragma omp single private(argc,b) firstprivate(argv,c) nowait
// CHECK-NEXT: foo();
#pragma omp parallel private(g)
diff --git a/test/OpenMP/single_codegen.cpp b/test/OpenMP/single_codegen.cpp
index 61a93a5a1b735..a2140c2eda78b 100644
--- a/test/OpenMP/single_codegen.cpp
+++ b/test/OpenMP/single_codegen.cpp
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -verify -fopenmp -fnoopenmp-use-tls -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s
// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fnoopenmp-use-tls -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG
+// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -std=c++11 -fopenmp -fnoopenmp-use-tls -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG
// RUN: %clang_cc1 -verify -fopenmp -fnoopenmp-use-tls -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=ARRAY %s
// expected-no-diagnostics
// REQUIRES: x86-registered-target
@@ -19,7 +19,9 @@ public:
};
// CHECK-DAG: [[TEST_CLASS_TY:%.+]] = type { i{{[0-9]+}} }
-// CHECK: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* }
+// CHECK-DAG: [[SST_TY:%.+]] = type { double }
+// CHECK-DAG: [[SS_TY:%.+]] = type { i32, i8, i32* }
+// CHECK-DAG: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* }
// CHECK: [[IMPLICIT_BARRIER_SINGLE_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 322, i32 0, i32 0, i8*
// CHECK: define void [[FOO:@.+]]()
@@ -30,6 +32,39 @@ TestClass tc2[2];
void foo() {}
+struct SS {
+ int a;
+ int b : 4;
+ int &c;
+ SS(int &d) : a(0), b(0), c(d) {
+#pragma omp parallel firstprivate(a, b, c)
+#pragma omp single copyprivate(a, this->b, (this)->c)
+ [&]() {
+ ++this->a, --b, (this)->c /= 1;
+#pragma omp parallel firstprivate(a, b, c)
+#pragma omp single copyprivate(a, this->b, (this)->c)
+ ++(this)->a, --b, this->c /= 1;
+ }();
+ }
+};
+
+template<typename T>
+struct SST {
+ T a;
+ SST() : a(T()) {
+#pragma omp parallel firstprivate(a)
+#pragma omp single copyprivate(this->a)
+ [&]() {
+ [&]() {
+ ++this->a;
+#pragma omp parallel firstprivate(a)
+#pragma omp single copyprivate((this)->a)
+ ++(this)->a;
+ }();
+ }();
+ }
+};
+
// CHECK-LABEL: @main
// TERM_DEBUG-LABEL: @main
int main() {
@@ -39,6 +74,8 @@ int main() {
char a;
char a2[2];
TestClass &c = tc;
+ SST<double> sst;
+ SS ss(c.a);
// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:@.+]])
// CHECK-DAG: [[DID_IT:%.+]] = alloca i32,
@@ -74,8 +111,8 @@ int main() {
// CHECK-NEXT: invoke void [[FOO]]()
// CHECK: to label {{%?}}[[CONT:.+]] unwind
// CHECK: [[CONT]]
-// CHECK: store i32 1, i32* [[DID_IT]]
// CHECK: call void @__kmpc_end_single([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
+// CHECK: store i32 1, i32* [[DID_IT]]
// CHECK-NEXT: br label {{%?}}[[EXIT]]
// CHECK: [[EXIT]]
// CHECK: [[A_PTR_REF:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[COPY_LIST]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
@@ -186,3 +223,210 @@ void array_func(int n, int a[n], St s[2]) {
// ARRAY: store i32* %{{.+}}, i32** %{{.+}},
// ARRAY: store %struct.St* %{{.+}}, %struct.St** %{{.+}},
#endif
+
+// CHECK-LABEL:@_ZN2SSC2ERi(
+// CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* @{{.+}}, i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[SS_TY]]*, i64, i64, i64)* [[SS_MICROTASK:@.+]] to void
+// CHECK-NEXT: ret void
+
+// CHECK: define internal void [[SS_MICROTASK]](i32* {{[^,]+}}, i32* {{[^,]+}}, [[SS_TY]]* {{.+}}, i64 {{.+}}, i64 {{.+}}, i64 {{.+}})
+// Private a
+// CHECK: alloca i64,
+// Private b
+// CHECK: alloca i64,
+// Private c
+// CHECK: alloca i64,
+// CHECK: alloca i32*,
+// CHECK: alloca i32*,
+// CHECK: alloca i32*,
+// CHECK: alloca i32*,
+// CHECK: [[DID_IT:%.+]] = alloca i32,
+// CHECK: bitcast i64* %{{.+}} to i32*
+// CHECK: bitcast i64* %{{.+}} to i32*
+// CHECK: bitcast i64* %{{.+}} to i32*
+// CHECK: store i32 0, i32* [[DID_IT]],
+// CHECK: [[RES:%.+]] = call i32 @__kmpc_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}})
+// CHECK-NEXT: icmp ne i32 [[RES]], 0
+// CHECK-NEXT: br i1
+
+// CHECK: getelementptr inbounds [[CAP_TY:%.+]], [[CAP_TY]]* [[CAP:%.+]], i32 0, i32 0
+// CHECK: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP]], i32 0, i32 1
+// CHECK-NEXT: load i32*, i32** %
+// CHECK-NEXT: store i32* %
+// CHECK-NEXT: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP]], i32 0, i32 2
+// CHECK-NEXT: store i32* %
+// CHECK-NEXT: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP]], i32 0, i32 3
+// CHECK-NEXT: load i32*, i32** %
+// CHECK-NEXT: store i32* %
+// CHECK-LABEL: invoke void @_ZZN2SSC1ERiENKUlvE_clEv(
+// CHECK-SAME: [[CAP_TY]]* [[CAP]])
+
+// CHECK: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}})
+// CHECK: store i32 1, i32* [[DID_IT]],
+// CHECK: br label
+
+// CHECK: call void @__kmpc_end_single(%{{.+}}* @{{.+}}, i32 %{{.+}})
+// CHECK: br label
+
+// CHECK: getelementptr inbounds [3 x i8*], [3 x i8*]* [[LIST:%.+]], i64 0, i64 0
+// CHECK: load i32*, i32** %
+// CHECK-NEXT: bitcast i32* %
+// CHECK-NEXT: store i8* %
+// CHECK: getelementptr inbounds [3 x i8*], [3 x i8*]* [[LIST]], i64 0, i64 1
+// CHECK-NEXT: bitcast i32* %
+// CHECK-NEXT: store i8* %
+// CHECK: getelementptr inbounds [3 x i8*], [3 x i8*]* [[LIST]], i64 0, i64 2
+// CHECK: load i32*, i32** %
+// CHECK-NEXT: bitcast i32* %
+// CHECK-NEXT: store i8* %
+// CHECK-NEXT: bitcast [3 x i8*]* [[LIST]] to i8*
+// CHECK-NEXT: load i32, i32* [[DID_IT]],
+// CHECK-NEXT: call void @__kmpc_copyprivate([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}, i64 24, i8* %{{.+}}, void (i8*, i8*)* [[COPY_FUNC:@[^,]+]], i32 %{{.+}})
+// CHECK-NEXT: ret void
+
+// CHECK-LABEL: @_ZZN2SSC1ERiENKUlvE_clEv(
+// CHECK: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP:%.+]], i32 0, i32 1
+// CHECK-NEXT: load i32*, i32** %
+// CHECK-NEXT: load i32, i32* %
+// CHECK-NEXT: add nsw i32 %{{.+}}, 1
+// CHECK-NEXT: store i32 %
+// CHECK-NEXT: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP]], i32 0, i32 2
+// CHECK-NEXT: load i32*, i32** %
+// CHECK-NEXT: load i32, i32* %
+// CHECK-NEXT: add nsw i32 %{{.+}}, -1
+// CHECK-NEXT: store i32 %
+// CHECK-NEXT: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP]], i32 0, i32 3
+// CHECK-NEXT: load i32*, i32** %
+// CHECK-NEXT: load i32, i32* %
+// CHECK-NEXT: sdiv i32 %{{.+}}, 1
+// CHECK-NEXT: store i32 %
+// CHECK-NEXT: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP]], i32 0, i32 1
+// CHECK-NEXT: load i32*, i32** %
+// CHECK-NEXT: load i32, i32* %
+// CHECK-NEXT: bitcast i64* %
+// CHECK-NEXT: store i32 %{{.+}}, i32* %
+// CHECK-NEXT: load i64, i64* %
+// CHECK-NEXT: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP]], i32 0, i32 2
+// CHECK-NEXT: load i32*, i32** %
+// CHECK-NEXT: load i32, i32* %
+// CHECK-NEXT: bitcast i64* %
+// CHECK-NEXT: store i32 %{{.+}}, i32* %
+// CHECK-NEXT: load i64, i64* %
+// CHECK-NEXT: getelementptr inbounds [[CAP_TY]], [[CAP_TY]]* [[CAP]], i32 0, i32 3
+// CHECK-NEXT: load i32*, i32** %
+// CHECK-NEXT: load i32, i32* %
+// CHECK-NEXT: bitcast i64* %
+// CHECK-NEXT: store i32 %{{.+}}, i32* %
+// CHECK-NEXT: load i64, i64* %
+// CHECK-NEXT: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* @{{.+}}, i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[SS_TY]]*, i64, i64, i64)* [[SS_MICROTASK1:@.+]] to void
+// CHECK-NEXT: ret void
+
+// CHECK: define internal void [[COPY_FUNC]](i8*, i8*)
+// CHECK: ret void
+
+// CHECK: define internal void [[SS_MICROTASK1]](i32* {{[^,]+}}, i32* {{[^,]+}}, [[SS_TY]]* {{.+}}, i64 {{.+}}, i64 {{.+}}, i64 {{.+}})
+// Private a
+// CHECK: alloca i64,
+// Private b
+// CHECK: alloca i64,
+// Private c
+// CHECK: alloca i64,
+// CHECK: alloca i32*,
+// CHECK: alloca i32*,
+// CHECK: alloca i32*,
+// CHECK: alloca i32*,
+// CHECK: [[DID_IT:%.+]] = alloca i32,
+// CHECK: bitcast i64* %{{.+}} to i32*
+// CHECK: bitcast i64* %{{.+}} to i32*
+// CHECK: bitcast i64* %{{.+}} to i32*
+// CHECK: [[RES:%.+]] = call i32 @__kmpc_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}})
+// CHECK-NEXT: icmp ne i32 [[RES]], 0
+// CHECK-NEXT: br i1
+
+// CHECK-NOT: getelementptr inbounds
+// CHECK: load i32*, i32** %
+// CHECK-NEXT: load i32, i32* %
+// CHECK-NEXT: add nsw i32 %{{.+}}, 1
+// CHECK-NEXT: store i32 %
+// CHECK-NOT: getelementptr inbounds
+// CHECK: load i32, i32* %
+// CHECK-NEXT: add nsw i32 %{{.+}}, -1
+// CHECK-NEXT: store i32 %
+// CHECK-NOT: getelementptr inbounds
+// CHECK: load i32*, i32** %
+// CHECK-NEXT: load i32, i32* %
+// CHECK-NEXT: sdiv i32 %{{.+}}, 1
+// CHECK-NEXT: store i32 %
+// CHECK-NEXT: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}})
+// CHECK-NEXT: store i32 1, i32* [[DID_IT]],
+// CHECK-NEXT: br label
+
+// CHECK: getelementptr inbounds [3 x i8*], [3 x i8*]* [[LIST:%.+]], i64 0, i64 0
+// CHECK: load i32*, i32** %
+// CHECK-NEXT: bitcast i32* %
+// CHECK-NEXT: store i8* %
+// CHECK: getelementptr inbounds [3 x i8*], [3 x i8*]* [[LIST]], i64 0, i64 1
+// CHECK-NEXT: bitcast i32* %
+// CHECK-NEXT: store i8* %
+// CHECK: getelementptr inbounds [3 x i8*], [3 x i8*]* [[LIST]], i64 0, i64 2
+// CHECK: load i32*, i32** %
+// CHECK-NEXT: bitcast i32* %
+// CHECK-NEXT: store i8* %
+// CHECK-NEXT: bitcast [3 x i8*]* [[LIST]] to i8*
+// CHECK-NEXT: load i32, i32* [[DID_IT]],
+// CHECK-NEXT: call void @__kmpc_copyprivate([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}, i64 24, i8* %{{.+}}, void (i8*, i8*)* [[COPY_FUNC:@[^,]+]], i32 %{{.+}})
+// CHECK-NEXT: ret void
+
+// CHECK: define internal void [[COPY_FUNC]](i8*, i8*)
+// CHECK: ret void
+
+// CHECK-LABEL: @_ZN3SSTIdEC2Ev
+// CHECK: getelementptr inbounds [[SST_TY]], [[SST_TY]]* %{{.+}}, i32 0, i32 0
+// CHECK-NEXT: store double 0.000000e+00, double* %
+// CHECK-NEXT: getelementptr inbounds [[SST_TY]], [[SST_TY]]* %{{.+}}, i32 0, i32 0
+// CHECK-NEXT: store double* %{{.+}}, double** %
+// CHECK-NEXT: load double*, double** %
+// CHECK-NEXT: load double, double* %
+// CHECK-NEXT: bitcast i64* %{{.+}} to double*
+// CHECK-NEXT: store double %{{.+}}, double* %
+// CHECK-NEXT: load i64, i64* %
+// CHECK-NEXT: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* @{{.+}}, i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[SST_TY]]*, i64)* [[SST_MICROTASK:@.+]] to void
+// CHECK-NEXT: ret void
+
+// CHECK: define internal void [[SST_MICROTASK]](i32* {{[^,]+}}, i32* {{[^,]+}}, [[SST_TY]]* {{.+}}, i64 {{.+}})
+// CHECK: [[RES:%.+]] = call i32 @__kmpc_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}})
+// CHECK-NEXT: icmp ne i32 [[RES]], 0
+// CHECK-NEXT: br i1
+
+// CHECK: getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 1
+// CHECK-NEXT: load double*, double** %
+// CHECK-NEXT: store double* %
+// CHECK-LABEL: invoke void @_ZZN3SSTIdEC1EvENKUlvE_clEv(
+
+// CHECK: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}})
+// CHECK-NEXT: store i32 1, i32* [[DID_IT]],
+// CHECK-NEXT: br label
+
+// CHECK: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}})
+// CHECK-NEXT: br label
+
+// CHECK: getelementptr inbounds [1 x i8*], [1 x i8*]* [[LIST:%.+]], i64 0, i64 0
+// CHECK: load double*, double** %
+// CHECK-NEXT: bitcast double* %
+// CHECK-NEXT: store i8* %
+// CHECK-NEXT: bitcast [1 x i8*]* [[LIST]] to i8*
+// CHECK-NEXT: load i32, i32* [[DID_IT]],
+// CHECK-NEXT: call void @__kmpc_copyprivate([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}, i64 8, i8* %{{.+}}, void (i8*, i8*)* [[COPY_FUNC:@[^,]+]], i32 %{{.+}})
+// CHECK-NEXT: ret void
+
+// CHECK-LABEL: @_ZZN3SSTIdEC1EvENKUlvE_clEv(
+// CHECK: getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 1
+// CHECK-NEXT: getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 1
+// CHECK-NEXT: load double*, double** %
+// CHECK-NEXT: store double* %
+// CHECK-LABEL: call void @_ZZZN3SSTIdEC1EvENKUlvE_clEvENKUlvE_clEv(
+// CHECK-NEXT: ret void
+
+// CHECK: define internal void [[COPY_FUNC]](i8*, i8*)
+// CHECK: ret void
+
+// CHECK-LABEL: @_ZZZN3SSTIdEC1EvENKUlvE_clEvENKUlvE_clEv(
diff --git a/test/OpenMP/single_firstprivate_codegen.cpp b/test/OpenMP/single_firstprivate_codegen.cpp
index cc72addb5f453..537ae76f12772 100644
--- a/test/OpenMP/single_firstprivate_codegen.cpp
+++ b/test/OpenMP/single_firstprivate_codegen.cpp
@@ -57,7 +57,6 @@ int vec[] = {1, 2};
S<float> s_arr[] = {1, 2};
// CHECK-DAG: [[VAR:@.+]] = global [[S_FLOAT_TY]] zeroinitializer,
S<float> var(3);
-// CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8*
// CHECK-DAG: [[SINGLE_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 322, i32 0, i32 0, i8*
// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
@@ -215,7 +214,7 @@ int main() {
// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]*
// CHECK: call void @__kmpc_end_single(
-// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK-NOT: call void @__kmpc_barrier(
// CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]()
@@ -224,18 +223,24 @@ int main() {
// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
-// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i32*, [2 x i32]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void
+// CHECK: [[T_VARVAL:%.+]] = load i32, i32* [[T_VAR:%.+]],
+// CHECK: [[T_VARCONV:%.+]] = bitcast i64* [[T_VARCAST:%.+]] to i32*
+// CHECK: store i32 [[T_VARVAL]], i32* [[T_VARCONV]],
+// CHECK: [[T_VARPVT:%.+]] = load i64, i64* [[T_VARCAST]],
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, [2 x i32]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void {{.*}}i64 [[T_VARPVT:%.+]],
// CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
// CHECK: ret
//
-// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(8) %{{.+}}, [[S_INT_TY]]* dereferenceable(4) %{{.+}})
+// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 {{.*}}%{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(8) %{{.+}}, [[S_INT_TY]]* dereferenceable(4) %{{.+}})
+// CHECK: [[T_VAR_ARG:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]],
// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
-// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %
+// CHECK-NOT: load i{{[0-9]+}}*, i{{[0-9]+}}** %
+// CHECK: [[T_VAR_CONV:%.+]] = bitcast i64* [[T_VAR_ARG]] to i32*
// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** %
// CHECK: [[S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** %
// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** %
@@ -245,7 +250,7 @@ int main() {
// CHECK: call i32 @__kmpc_single(
// firstprivate t_var(t_var)
-// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]],
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}*
// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]],
// firstprivate vec(vec)
diff --git a/test/OpenMP/single_private_messages.cpp b/test/OpenMP/single_private_messages.cpp
index a24cf47cd2a26..0ed0e6cfb0999 100644
--- a/test/OpenMP/single_private_messages.cpp
+++ b/test/OpenMP/single_private_messages.cpp
@@ -29,7 +29,11 @@ class S4 {
S4(); // expected-note {{implicitly declared private here}}
public:
- S4(int v) : a(v) {}
+ S4(int v) : a(v) {
+#pragma omp single private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
};
class S5 {
int a;
@@ -37,6 +41,50 @@ class S5 {
public:
S5(int v) : a(v) {}
+ S5 &operator=(S5 &s) {
+#pragma omp single private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S6 {
+public:
+ T a;
+
+ S6() : a(0) {}
+ S6(T v) : a(v) {
+#pragma omp single private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+ S6 &operator=(S6 &s) {
+#pragma omp single private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S7 : public T {
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(T v) : a(v) {
+#pragma omp single private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp single private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
};
S3 h;
@@ -102,6 +150,8 @@ using A::x;
int main(int argc, char **argv) {
S4 e(4);
S5 g(5);
+ S6<float> s6(0.0) , s6_0(1.0);
+ S7<S6<float> > s7(0.0) , s7_0(1.0);
int i;
int &j = i;
#pragma omp single private // expected-error {{expected '(' after 'private'}}
@@ -146,6 +196,8 @@ int main(int argc, char **argv) {
#pragma omp single private(m) // OK
foo();
- return 0;
+ s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}}
+ s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}}
+ return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
}
diff --git a/test/OpenMP/target_ast_print.cpp b/test/OpenMP/target_ast_print.cpp
index acf032a221202..e093e29979ba8 100644
--- a/test/OpenMP/target_ast_print.cpp
+++ b/test/OpenMP/target_ast_print.cpp
@@ -25,6 +25,12 @@ T tmain(T argc, T *argv) {
foo();
#pragma omp target map(always,alloc: i)
foo();
+#pragma omp target nowait
+ foo();
+#pragma omp target depend(in : argc, argv[i:argc], a[:])
+ foo();
+#pragma omp target defaultmap(tofrom: scalar)
+ foo();
return 0;
}
@@ -44,6 +50,12 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: foo()
// CHECK-NEXT: #pragma omp target map(always,alloc: i)
// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target nowait
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target depend(in : argc,argv[i:argc],a[:])
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target defaultmap(tofrom: scalar)
+// CHECK-NEXT: foo()
// CHECK: template <typename T = char, int C = 1> char tmain(char argc, char *argv) {
// CHECK-NEXT: char i, j, a[20]
// CHECK-NEXT: #pragma omp target
@@ -60,6 +72,12 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: foo()
// CHECK-NEXT: #pragma omp target map(always,alloc: i)
// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target nowait
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target depend(in : argc,argv[i:argc],a[:])
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target defaultmap(tofrom: scalar)
+// CHECK-NEXT: foo()
// CHECK: template <typename T, int C> T tmain(T argc, T *argv) {
// CHECK-NEXT: T i, j, a[20]
// CHECK-NEXT: #pragma omp target
@@ -76,6 +94,12 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: foo()
// CHECK-NEXT: #pragma omp target map(always,alloc: i)
// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target nowait
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target depend(in : argc,argv[i:argc],a[:])
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target defaultmap(tofrom: scalar)
+// CHECK-NEXT: foo()
// CHECK-LABEL: int main(int argc, char **argv) {
int main (int argc, char **argv) {
@@ -115,6 +139,21 @@ int main (int argc, char **argv) {
foo();
// CHECK-NEXT: foo();
+#pragma omp target nowait
+// CHECK-NEXT: #pragma omp target nowait
+ foo();
+// CHECK-NEXT: foo();
+
+#pragma omp target depend(in : argc, argv[i:argc], a[:])
+// CHECK-NEXT: #pragma omp target depend(in : argc,argv[i:argc],a[:])
+ foo();
+// CHECK-NEXT: foo();
+
+#pragma omp target defaultmap(tofrom: scalar)
+// CHECK-NEXT: #pragma omp target defaultmap(tofrom: scalar)
+ foo();
+// CHECK-NEXT: foo();
+
return tmain<int, 5>(argc, &argc) + tmain<char, 1>(argv[0][0], argv[0]);
}
diff --git a/test/OpenMP/target_codegen.cpp b/test/OpenMP/target_codegen.cpp
index c2e08d67b843f..f263ebdd2fe34 100644
--- a/test/OpenMP/target_codegen.cpp
+++ b/test/OpenMP/target_codegen.cpp
@@ -1,20 +1,20 @@
// Test host codegen.
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
// Test target codegen - host bc file has to be created first.
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -omp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -omp-host-ir-file-path %t-ppc-host.bc -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -omp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -omp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -omp-host-ir-file-path %t-x86-host.bc -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -omp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
// expected-no-diagnostics
#ifndef HEADER
@@ -33,15 +33,15 @@
// sizes.
// CHECK-DAG: [[SIZET2:@.+]] = private unnamed_addr constant [1 x i{{32|64}}] [i[[SZ:32|64]] 2]
-// CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [1 x i32] [i32 128]
+// CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [1 x i32] [i32 288]
// CHECK-DAG: [[SIZET3:@.+]] = private unnamed_addr constant [2 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2]
-// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [2 x i32] [i32 128, i32 128]
-// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [9 x i32] [i32 128, i32 3, i32 128, i32 3, i32 3, i32 128, i32 128, i32 3, i32 3]
+// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [2 x i32] [i32 288, i32 288]
+// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [9 x i32] [i32 288, i32 35, i32 288, i32 35, i32 35, i32 288, i32 288, i32 35, i32 35]
// CHECK-DAG: [[SIZET5:@.+]] = private unnamed_addr constant [3 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 40]
-// CHECK-DAG: [[MAPT5:@.+]] = private unnamed_addr constant [3 x i32] [i32 128, i32 128, i32 3]
+// CHECK-DAG: [[MAPT5:@.+]] = private unnamed_addr constant [3 x i32] [i32 288, i32 288, i32 35]
// CHECK-DAG: [[SIZET6:@.+]] = private unnamed_addr constant [4 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 1, i[[SZ]] 40]
-// CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [4 x i32] [i32 128, i32 128, i32 128, i32 3]
-// CHECK-DAG: [[MAPT7:@.+]] = private unnamed_addr constant [5 x i32] [i32 3, i32 128, i32 128, i32 128, i32 3]
+// CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [4 x i32] [i32 288, i32 288, i32 288, i32 35]
+// CHECK-DAG: [[MAPT7:@.+]] = private unnamed_addr constant [5 x i32] [i32 35, i32 288, i32 288, i32 288, i32 35]
// CHECK-DAG: @{{.*}} = private constant i8 0
// CHECK-DAG: @{{.*}} = private constant i8 0
// CHECK-DAG: @{{.*}} = private constant i8 0
diff --git a/test/OpenMP/target_codegen_global_capture.cpp b/test/OpenMP/target_codegen_global_capture.cpp
index 211a3cc884b67..b08bf10f9f29d 100644
--- a/test/OpenMP/target_codegen_global_capture.cpp
+++ b/test/OpenMP/target_codegen_global_capture.cpp
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
// expected-no-diagnostics
#ifndef HEADER
#define HEADER
@@ -21,6 +21,11 @@
// CHECK-DAG: [[BB:@.+]] = internal global float 1.000000e+01
// CHECK-DAG: [[BC:@.+]] = internal global float 1.100000e+01
// CHECK-DAG: [[BD:@.+]] = internal global float 1.200000e+01
+// CHECK-DAG: [[TBA:@.+]] = {{.*}}global float 1.700000e+01
+// CHECK-DAG: [[TBB:@.+]] = {{.*}}global float 1.800000e+01
+// CHECK-DAG: [[TBC:@.+]] = {{.*}}global float 1.900000e+01
+// CHECK-DAG: [[TBD:@.+]] = {{.*}}global float 2.000000e+01
+
double Ga = 1.0;
double Gb = 2.0;
double Gc = 3.0;
@@ -42,14 +47,14 @@ int foo(short a, short b, short c, short d){
static float Sd = 8.0;
// CHECK-DAG: [[VALLB:%.+]] = load i16, i16* [[LB]],
- // CHECK-64-DAG: [[VALGB:%.+]] = load double, double* @Gb,
- // CHECK-DAG: [[VALFB:%.+]] = load float, float* @_ZZ3foossssE2Sb,
- // CHECK-64-DAG: [[VALGC:%.+]] = load double, double* @Gc,
+ // CHECK-64-DAG: [[VALGB:%.+]] = load double, double* [[GB]],
+ // CHECK-DAG: [[VALFB:%.+]] = load float, float* [[FB]],
+ // CHECK-64-DAG: [[VALGC:%.+]] = load double, double* [[GC]],
// CHECK-DAG: [[VALLC:%.+]] = load i16, i16* [[LC]],
- // CHECK-DAG: [[VALFC:%.+]] = load float, float* @_ZZ3foossssE2Sc,
+ // CHECK-DAG: [[VALFC:%.+]] = load float, float* [[FC]],
// CHECK-DAG: [[VALLD:%.+]] = load i16, i16* [[LD]],
- // CHECK-64-DAG: [[VALGD:%.+]] = load double, double* @Gd,
- // CHECK-DAG: [[VALFD:%.+]] = load float, float* @_ZZ3foossssE2Sd,
+ // CHECK-64-DAG: [[VALGD:%.+]] = load double, double* [[GD]],
+ // CHECK-DAG: [[VALFD:%.+]] = load float, float* [[FD]],
// 3 local vars being captured.
@@ -178,14 +183,156 @@ int bar(short a, short b, short c, short d){
#pragma omp parallel
{
// CHECK-DAG: [[VALLB:%.+]] = load i16, i16* [[LLB]],
- // CHECK-64-DAG: [[VALGB:%.+]] = load double, double* @Gb,
- // CHECK-DAG: [[VALFB:%.+]] = load float, float* @_ZZ3barssssE2Sb,
- // CHECK-64-DAG: [[VALGC:%.+]] = load double, double* @Gc,
+ // CHECK-64-DAG: [[VALGB:%.+]] = load double, double* [[GB]],
+ // CHECK-DAG: [[VALFB:%.+]] = load float, float* [[BB]],
+ // CHECK-64-DAG: [[VALGC:%.+]] = load double, double* [[GC]],
+ // CHECK-DAG: [[VALLC:%.+]] = load i16, i16* [[LLC]],
+ // CHECK-DAG: [[VALFC:%.+]] = load float, float* [[BC]],
+ // CHECK-DAG: [[VALLD:%.+]] = load i16, i16* [[LLD]],
+ // CHECK-64-DAG: [[VALGD:%.+]] = load double, double* [[GD]],
+ // CHECK-DAG: [[VALFD:%.+]] = load float, float* [[BD]],
+
+ // 3 local vars being captured.
+
+ // CHECK-DAG: store i16 [[VALLB]], i16* [[CONVLB:%.+]],
+ // CHECK-DAG: [[CONVLB]] = bitcast i[[sz:64|32]]* [[CADDRLB:%.+]] to i16*
+ // CHECK-DAG: [[CVALLB:%.+]] = load i[[sz]], i[[sz]]* [[CADDRLB]],
+ // CHECK-DAG: [[CPTRLB:%.+]] = inttoptr i[[sz]] [[CVALLB]] to i8*
+ // CHECK-DAG: store i8* [[CPTRLB]], i8** [[GEPLB:%.+]],
+ // CHECK-DAG: [[GEPLB]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
+
+ // CHECK-DAG: store i16 [[VALLC]], i16* [[CONVLC:%.+]],
+ // CHECK-DAG: [[CONVLC]] = bitcast i[[sz]]* [[CADDRLC:%.+]] to i16*
+ // CHECK-DAG: [[CVALLC:%.+]] = load i[[sz]], i[[sz]]* [[CADDRLC]],
+ // CHECK-DAG: [[CPTRLC:%.+]] = inttoptr i[[sz]] [[CVALLC]] to i8*
+ // CHECK-DAG: store i8* [[CPTRLC]], i8** [[GEPLC:%.+]],
+ // CHECK-DAG: [[GEPLC]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
+
+ // CHECK-DAG: store i16 [[VALLD]], i16* [[CONVLD:%.+]],
+ // CHECK-DAG: [[CONVLD]] = bitcast i[[sz]]* [[CADDRLD:%.+]] to i16*
+ // CHECK-DAG: [[CVALLD:%.+]] = load i[[sz]], i[[sz]]* [[CADDRLD]],
+ // CHECK-DAG: [[CPTRLD:%.+]] = inttoptr i[[sz]] [[CVALLD]] to i8*
+ // CHECK-DAG: store i8* [[CPTRLD]], i8** [[GEPLD:%.+]],
+ // CHECK-DAG: [[GEPLD]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
+
+ // 3 static vars being captured.
+
+ // CHECK-DAG: store float [[VALFB]], float* [[CONVFB:%.+]],
+ // CHECK-DAG: [[CONVFB]] = bitcast i[[sz]]* [[CADDRFB:%.+]] to float*
+ // CHECK-DAG: [[CVALFB:%.+]] = load i[[sz]], i[[sz]]* [[CADDRFB]],
+ // CHECK-DAG: [[CPTRFB:%.+]] = inttoptr i[[sz]] [[CVALFB]] to i8*
+ // CHECK-DAG: store i8* [[CPTRFB]], i8** [[GEPFB:%.+]],
+ // CHECK-DAG: [[GEPFB]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
+
+ // CHECK-DAG: store float [[VALFC]], float* [[CONVFC:%.+]],
+ // CHECK-DAG: [[CONVFC]] = bitcast i[[sz]]* [[CADDRFC:%.+]] to float*
+ // CHECK-DAG: [[CVALFC:%.+]] = load i[[sz]], i[[sz]]* [[CADDRFC]],
+ // CHECK-DAG: [[CPTRFC:%.+]] = inttoptr i[[sz]] [[CVALFC]] to i8*
+ // CHECK-DAG: store i8* [[CPTRFC]], i8** [[GEPFC:%.+]],
+ // CHECK-DAG: [[GEPFC]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
+
+ // CHECK-DAG: store float [[VALFD]], float* [[CONVFD:%.+]],
+ // CHECK-DAG: [[CONVFD]] = bitcast i[[sz]]* [[CADDRFD:%.+]] to float*
+ // CHECK-DAG: [[CVALFD:%.+]] = load i[[sz]], i[[sz]]* [[CADDRFD]],
+ // CHECK-DAG: [[CPTRFD:%.+]] = inttoptr i[[sz]] [[CVALFD]] to i8*
+ // CHECK-DAG: store i8* [[CPTRFD]], i8** [[GEPFD:%.+]],
+ // CHECK-DAG: [[GEPFD]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
+
+ // 3 static global vars being captured.
+
+ // CHECK-64-DAG: store double [[VALGB]], double* [[CONVGB:%.+]],
+ // CHECK-64-DAG: [[CONVGB]] = bitcast i[[sz]]* [[CADDRGB:%.+]] to double*
+ // CHECK-64-DAG: [[CVALGB:%.+]] = load i[[sz]], i[[sz]]* [[CADDRGB]],
+ // CHECK-64-DAG: [[CPTRGB:%.+]] = inttoptr i[[sz]] [[CVALGB]] to i8*
+ // CHECK-64-DAG: store i8* [[CPTRGB]], i8** [[GEPGB:%.+]],
+ // CHECK-32-DAG: store i8* bitcast (double* @Gb to i8*), i8** [[GEPGB:%.+]],
+ // CHECK-DAG: [[GEPGB]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
+
+ // CHECK-64-DAG: store double [[VALGC]], double* [[CONVGC:%.+]],
+ // CHECK-64-DAG: [[CONVGC]] = bitcast i[[sz]]* [[CADDRGC:%.+]] to double*
+ // CHECK-64-DAG: [[CVALGC:%.+]] = load i[[sz]], i[[sz]]* [[CADDRGC]],
+ // CHECK-64-DAG: [[CPTRGC:%.+]] = inttoptr i[[sz]] [[CVALGC]] to i8*
+ // CHECK-64-DAG: store i8* [[CPTRGC]], i8** [[GEPGC:%.+]],
+ // CHECK-32-DAG: store i8* bitcast (double* @Gc to i8*), i8** [[GEPGC:%.+]],
+ // CHECK-DAG: [[GEPGC]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
+
+ // CHECK-64-DAG: store double [[VALGD]], double* [[CONVGD:%.+]],
+ // CHECK-64-DAG: [[CONVGD]] = bitcast i[[sz]]* [[CADDRGD:%.+]] to double*
+ // CHECK-64-DAG: [[CVALGD:%.+]] = load i[[sz]], i[[sz]]* [[CADDRGD]],
+ // CHECK-64-DAG: [[CPTRGD:%.+]] = inttoptr i[[sz]] [[CVALGD]] to i8*
+ // CHECK-64-DAG: store i8* [[CPTRGD]], i8** [[GEPGD:%.+]],
+ // CHECK-32-DAG: store i8* bitcast (double* @Gd to i8*), i8** [[GEPGD:%.+]],
+ // CHECK-DAG: [[GEPGD]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
+
+ // CHECK: call i32 @__tgt_target
+ // CHECK: call void [[OFFLOADF:@.+]](
+ // Capture b, Gb, Sb, Gc, c, Sc, d, Gd, Sd
+ #pragma omp target if(Ga>0.0 && a>0 && Sa>0.0)
+ {
+ b += 1;
+ Gb += 1.0;
+ Sb += 1.0;
+
+ // CHECK: define internal void [[OFFLOADF]]({{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}})
+ // CHECK: call void {{.*}}@__kmpc_fork_call(%ident_t* {{.+}}, i32 {{.+}}, void (i32*, i32*, ...)* bitcast ({{.*}}[[PARF:@.+]] to {{.*}})
+
+ // CHECK: define internal void [[PARF]](i32* noalias %{{.*}}, i32* noalias %{{.*}}, {{.+}}* dereferenceable({{.+}}) %{{.+}}, {{.+}}* dereferenceable({{.+}}) %{{.+}}, {{.+}}* dereferenceable({{.+}}) %{{.+}})
+ // Capture d, Gd, Sd
+ #pragma omp parallel if(Gc>0.0 && c>0 && Sc>0.0)
+ {
+ d += 1;
+ Gd += 1.0;
+ Sd += 1.0;
+ }
+ }
+ }
+ return a + b + c + d + (int)Sa + (int)Sb + (int)Sc + (int)Sd;
+}
+
+///
+/// Tests with template functions.
+///
+
+// CHECK: define {{.*}} @{{.*}}tbar2{{.*}}(
+
+// CHECK: define {{.*}} @{{.*}}tbar{{.*}}(
+// CHECK-SAME: i16 {{[^,]*}}[[A:%[^,]+]],
+// CHECK-SAME: i16 {{[^,]*}}[[B:%[^,]+]],
+// CHECK-SAME: i16 {{[^,]*}}[[C:%[^,]+]],
+// CHECK-SAME: i16 {{[^,]*}}[[D:%[^,]+]])
+// CHECK: [[LA:%.+]] = alloca i16
+// CHECK: [[LB:%.+]] = alloca i16
+// CHECK: [[LC:%.+]] = alloca i16
+// CHECK: [[LD:%.+]] = alloca i16
+template<typename T>
+int tbar(T a, T b, T c, T d){
+ static float Sa = 17.0;
+ static float Sb = 18.0;
+ static float Sc = 19.0;
+ static float Sd = 20.0;
+
+ // CHECK: call void {{.*}}@__kmpc_fork_call(%ident_t* {{.+}}, i32 {{.+}}, void (i32*, i32*, ...)* bitcast ({{.*}}[[PARF:@.+]] to {{.*}}), i16* %{{.+}}, i16* %{{.+}}, i16* %{{.+}}, i16* %{{.+}})
+ // CHECK: define internal void [[PARF]](i32* noalias %{{.*}}, i32* noalias %{{.*}}, i16* dereferenceable(2) [[A:%.+]], i16* dereferenceable(2) [[B:%.+]], i16* dereferenceable(2) [[C:%.+]], i16* dereferenceable(2) [[D:%.+]])
+ // Capture a, b, c, d
+ // CHECK: [[ALLOCLA:%.+]] = alloca i16
+ // CHECK: [[ALLOCLB:%.+]] = alloca i16
+ // CHECK: [[ALLOCLC:%.+]] = alloca i16
+ // CHECK: [[ALLOCLD:%.+]] = alloca i16
+ // CHECK: [[LLA:%.+]] = load i16*, i16** [[ALLOCLA]],
+ // CHECK: [[LLB:%.+]] = load i16*, i16** [[ALLOCLB]],
+ // CHECK: [[LLC:%.+]] = load i16*, i16** [[ALLOCLC]],
+ // CHECK: [[LLD:%.+]] = load i16*, i16** [[ALLOCLD]],
+ #pragma omp parallel
+ {
+ // CHECK-DAG: [[VALLB:%.+]] = load i16, i16* [[LLB]],
+ // CHECK-64-DAG: [[VALGB:%.+]] = load double, double* [[GB]],
+ // CHECK-DAG: [[VALFB:%.+]] = load float, float* [[TBB]],
+ // CHECK-64-DAG: [[VALGC:%.+]] = load double, double* [[GC]],
// CHECK-DAG: [[VALLC:%.+]] = load i16, i16* [[LLC]],
- // CHECK-DAG: [[VALFC:%.+]] = load float, float* @_ZZ3barssssE2Sc,
+ // CHECK-DAG: [[VALFC:%.+]] = load float, float* [[TBC]],
// CHECK-DAG: [[VALLD:%.+]] = load i16, i16* [[LLD]],
- // CHECK-64-DAG: [[VALGD:%.+]] = load double, double* @Gd,
- // CHECK-DAG: [[VALFD:%.+]] = load float, float* @_ZZ3barssssE2Sd,
+ // CHECK-64-DAG: [[VALGD:%.+]] = load double, double* [[GD]],
+ // CHECK-DAG: [[VALFD:%.+]] = load float, float* [[TBD]],
// 3 local vars being captured.
@@ -284,4 +431,8 @@ int bar(short a, short b, short c, short d){
return a + b + c + d + (int)Sa + (int)Sb + (int)Sc + (int)Sd;
}
+int tbar2(short a, short b, short c, short d){
+ return tbar(a, b, c, d);
+}
+
#endif
diff --git a/test/OpenMP/target_codegen_registration.cpp b/test/OpenMP/target_codegen_registration.cpp
index 7d515bb64d907..a440faff9158c 100644
--- a/test/OpenMP/target_codegen_registration.cpp
+++ b/test/OpenMP/target_codegen_registration.cpp
@@ -1,20 +1,20 @@
// Test host codegen.
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
// Test target codegen - host bc file has to be created first.
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -omp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s -check-prefix=TCHECK
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -omp-host-ir-file-path %t-ppc-host.bc -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -omp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -omp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s -check-prefix=TCHECK
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -omp-host-ir-file-path %t-x86-host.bc -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -omp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
// Check that no target code is emmitted if no omptests flag was provided.
// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK-NTARGET
@@ -61,45 +61,45 @@
// CHECK-DAG: {{@.+}} = private constant i8 0
// TCHECK-NOT: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 128]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 128]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 128]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 128]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 128]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 128]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 128]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 128]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 128]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 128]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 128]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
// CHECK-DAG: {{@.+}} = private constant i8 0
// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i[[SZ]]] [i[[SZ]] 4]
-// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 128]
+// CHECK-DAG: {{@.+}} = private unnamed_addr constant [1 x i32] [i32 288]
// CHECK-NTARGET-NOT: private constant i8 0
// CHECK-NTARGET-NOT: private unnamed_addr constant [1 x i
-// CHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:\.omp_offloading\.[0-9a-f]+\.[0-9a-f]+\._Z.+\.l[0-9]+\.c[0-9]+]]\00"
+// CHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00"
// CHECK-DAG: [[ENTRY1:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR1]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
// CHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00"
// CHECK-DAG: [[ENTRY2:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR2]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
@@ -124,7 +124,7 @@
// CHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00"
// CHECK-DAG: [[ENTRY12:@.+]] = constant [[ENTTY]] { i8* @{{.*}}, i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR12]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
-// TCHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:\.omp_offloading\.[0-9a-f]+\.[0-9a-f]+\._Z.+\.l[0-9]+\.c[0-9]+]]\00"
+// TCHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00"
// TCHECK-DAG: [[ENTRY1:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR1]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
// TCHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00"
// TCHECK-DAG: [[ENTRY2:@.+]] = constant [[ENTTY]] { i8* bitcast (void (i[[SZ]])* @{{.*}} to i8*), i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[NAMEPTR2]], i32 0, i32 0), i[[SZ]] 0 }, section ".omp_offloading.entries", align 1
@@ -407,31 +407,31 @@ int bar(int a){
// Check metadata is properly generated:
// CHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
-// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 193, i32 13, i32 {{[0-9]+}}}
-// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 243, i32 13, i32 {{[0-9]+}}}
-// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 259, i32 13, i32 {{[0-9]+}}}
-// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 265, i32 13, i32 {{[0-9]+}}}
-// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 276, i32 13, i32 {{[0-9]+}}}
-// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 282, i32 13, i32 {{[0-9]+}}}
-// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 402, i32 11, i32 {{[0-9]+}}}
-// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 288, i32 13, i32 {{[0-9]+}}}
-// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 282, i32 13, i32 {{[0-9]+}}}
-// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 288, i32 13, i32 {{[0-9]+}}}
-// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 276, i32 13, i32 {{[0-9]+}}}
-// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 218, i32 13, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 193, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 243, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 259, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 265, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 276, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 282, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 402, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 288, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 282, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 288, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 276, i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 218, i32 {{[0-9]+}}}
// TCHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
-// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 193, i32 13, i32 {{[0-9]+}}}
-// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 243, i32 13, i32 {{[0-9]+}}}
-// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 259, i32 13, i32 {{[0-9]+}}}
-// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 265, i32 13, i32 {{[0-9]+}}}
-// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 276, i32 13, i32 {{[0-9]+}}}
-// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 282, i32 13, i32 {{[0-9]+}}}
-// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 402, i32 11, i32 {{[0-9]+}}}
-// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 288, i32 13, i32 {{[0-9]+}}}
-// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 282, i32 13, i32 {{[0-9]+}}}
-// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 288, i32 13, i32 {{[0-9]+}}}
-// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 276, i32 13, i32 {{[0-9]+}}}
-// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 218, i32 13, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 193, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 243, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 259, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 265, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 276, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 282, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 402, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 288, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 282, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 288, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 276, i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 218, i32 {{[0-9]+}}}
#endif
diff --git a/test/OpenMP/target_codegen_registration_naming.cpp b/test/OpenMP/target_codegen_registration_naming.cpp
index ab7a469aba4d0..ce133eee03e80 100644
--- a/test/OpenMP/target_codegen_registration_naming.cpp
+++ b/test/OpenMP/target_codegen_registration_naming.cpp
@@ -1,20 +1,20 @@
// Test host codegen.
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
// Test target codegen - host bc file has to be created first.
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -omp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s -check-prefix=TCHECK
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -std=c++11 -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -omp-host-ir-file-path %t-ppc-host.bc -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -omptargets=powerpc64le-ibm-linux-gnu -fopenmp-is-device -omp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -omp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s -check-prefix=TCHECK
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -omp-host-ir-file-path %t-x86-host.bc -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -omptargets=i386-pc-linux-gnu -fopenmp-is-device -omp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s -check-prefix=TCHECK
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=TCHECK
// expected-no-diagnostics
#ifndef HEADER
@@ -24,7 +24,7 @@
// CHECK: define {{.*}}i32 @[[NNAME:.+]](i32 {{.*}}%{{.+}})
int nested(int a){
- // CHECK: call void @.omp_offloading.[[FILEID:[0-9a-f]+\.[0-9a-f]+]].[[NNAME]].l[[T1L:[0-9]+]].c[[T1C:[0-9]+]](
+ // CHECK: call void @__omp_offloading_[[FILEID:[0-9a-f]+_[0-9a-f]+]]_[[NNAME]]_l[[T1L:[0-9]+]](
#pragma omp target
++a;
@@ -42,25 +42,25 @@ int nested(int a){
return a;
}
-// CHECK: define {{.*}}void @.omp_offloading.[[FILEID]].[[NNAME]].l[[T1L]].c[[T1C]](
-// TCHECK: define {{.*}}void @.omp_offloading.[[FILEID:[0-9a-f]+\.[0-9a-f]+]].[[NNAME:.+]].l[[T1L:[0-9]+]].c[[T1C:[0-9]+]](
+// CHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T1L]](
+// TCHECK: define {{.*}}void @__omp_offloading_[[FILEID:[0-9a-f]+_[0-9a-f]+]]_[[NNAME:.+]]_l[[T1L:[0-9]+]](
// CHECK: define {{.*}}void @"[[LNAME]]"(
// CHECK: call void {{.*}}@__kmpc_fork_call{{.+}}[[PNAME:@.+]] to
// CHECK: define {{.*}}void [[PNAME]](
-// CHECK: call void @.omp_offloading.[[FILEID]].[[NNAME]].l[[T2L:[0-9]+]].c[[T2C:[0-9]+]](
+// CHECK: call void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T2L:[0-9]+]](
-// CHECK: define {{.*}}void @.omp_offloading.[[FILEID]].[[NNAME]].l[[T2L]].c[[T2C]](
-// TCHECK: define {{.*}}void @.omp_offloading.[[FILEID]].[[NNAME:.+]].l[[T2L:[0-9]+]].c[[T2C:[0-9]+]](
+// CHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME]]_l[[T2L]](
+// TCHECK: define {{.*}}void @__omp_offloading_[[FILEID]]_[[NNAME:.+]]_l[[T2L:[0-9]+]](
// Check metadata is properly generated:
// CHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}}
-// CHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T1L]], i32 [[T1C]], i32 {{[0-9]+}}}
-// CHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T2L]], i32 [[T2C]], i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T1L]], i32 {{[0-9]+}}}
+// CHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T2L]], i32 {{[0-9]+}}}
// TCHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}}
-// TCHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T1L]], i32 [[T1C]], i32 {{[0-9]+}}}
-// TCHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T2L]], i32 [[T2C]], i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T1L]], i32 {{[0-9]+}}}
+// TCHECK-DAG: = !{i32 0, i32 {{-?[0-9]+}}, i32 {{-?[0-9]+}}, !"[[NNAME]]", i32 [[T2L]], i32 {{[0-9]+}}}
#endif
diff --git a/test/OpenMP/target_data_ast_print.cpp b/test/OpenMP/target_data_ast_print.cpp
index cdff857e569ad..ed7a96541196f 100644
--- a/test/OpenMP/target_data_ast_print.cpp
+++ b/test/OpenMP/target_data_ast_print.cpp
@@ -12,13 +12,13 @@ template <typename T, int C>
T tmain(T argc, T *argv) {
T i, j, b, c, d, e, x[20];
-#pragma omp target data
+#pragma omp target data map(to: c)
i = argc;
-#pragma omp target data if (target data: j > 0)
+#pragma omp target data map(to: c) if (target data: j > 0)
foo();
-#pragma omp target data if (b)
+#pragma omp target data map(to: c) if (b)
foo();
#pragma omp target data map(c)
@@ -48,11 +48,11 @@ T tmain(T argc, T *argv) {
// CHECK: template <typename T = int, int C = 5> int tmain(int argc, int *argv) {
// CHECK-NEXT: int i, j, b, c, d, e, x[20];
-// CHECK-NEXT: #pragma omp target data
+// CHECK-NEXT: #pragma omp target data map(to: c)
// CHECK-NEXT: i = argc;
-// CHECK-NEXT: #pragma omp target data if(target data: j > 0)
+// CHECK-NEXT: #pragma omp target data map(to: c) if(target data: j > 0)
// CHECK-NEXT: foo();
-// CHECK-NEXT: #pragma omp target data if(b)
+// CHECK-NEXT: #pragma omp target data map(to: c) if(b)
// CHECK-NEXT: foo();
// CHECK-NEXT: #pragma omp target data map(tofrom: c)
// CHECK-NEXT: foo();
@@ -70,11 +70,11 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: foo();
// CHECK: template <typename T = char, int C = 1> char tmain(char argc, char *argv) {
// CHECK-NEXT: char i, j, b, c, d, e, x[20];
-// CHECK-NEXT: #pragma omp target data
+// CHECK-NEXT: #pragma omp target data map(to: c)
// CHECK-NEXT: i = argc;
-// CHECK-NEXT: #pragma omp target data if(target data: j > 0)
+// CHECK-NEXT: #pragma omp target data map(to: c) if(target data: j > 0)
// CHECK-NEXT: foo();
-// CHECK-NEXT: #pragma omp target data if(b)
+// CHECK-NEXT: #pragma omp target data map(to: c) if(b)
// CHECK-NEXT: foo();
// CHECK-NEXT: #pragma omp target data map(tofrom: c)
// CHECK-NEXT: foo();
@@ -92,11 +92,11 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: foo();
// CHECK: template <typename T, int C> T tmain(T argc, T *argv) {
// CHECK-NEXT: T i, j, b, c, d, e, x[20];
-// CHECK-NEXT: #pragma omp target data
+// CHECK-NEXT: #pragma omp target data map(to: c)
// CHECK-NEXT: i = argc;
-// CHECK-NEXT: #pragma omp target data if(target data: j > 0)
+// CHECK-NEXT: #pragma omp target data map(to: c) if(target data: j > 0)
// CHECK-NEXT: foo();
-// CHECK-NEXT: #pragma omp target data if(b)
+// CHECK-NEXT: #pragma omp target data map(to: c) if(b)
// CHECK-NEXT: foo();
// CHECK-NEXT: #pragma omp target data map(tofrom: c)
// CHECK-NEXT: foo();
@@ -118,17 +118,17 @@ int main (int argc, char **argv) {
static int a;
// CHECK: static int a;
-#pragma omp target data
-// CHECK: #pragma omp target data
+#pragma omp target data map(to: c)
+// CHECK: #pragma omp target data map(to: c)
a=2;
// CHECK-NEXT: a = 2;
-#pragma omp target data if (target data: b)
-// CHECK: #pragma omp target data if(target data: b)
+#pragma omp target data map(to: c) if (target data: b)
+// CHECK: #pragma omp target data map(to: c) if(target data: b)
foo();
// CHECK-NEXT: foo();
-#pragma omp target data if (b > g)
-// CHECK: #pragma omp target data if(b > g)
+#pragma omp target data map(to: c) if (b > g)
+// CHECK: #pragma omp target data map(to: c) if(b > g)
foo();
// CHECK-NEXT: foo();
diff --git a/test/OpenMP/target_data_codegen.cpp b/test/OpenMP/target_data_codegen.cpp
new file mode 100644
index 0000000000000..a149ba9332b93
--- /dev/null
+++ b/test/OpenMP/target_data_codegen.cpp
@@ -0,0 +1,248 @@
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+///==========================================================================///
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+#ifdef CK1
+
+// CK1: [[ST:%.+]] = type { i32, double* }
+template <typename T>
+struct ST {
+ T a;
+ double *b;
+};
+
+ST<int> gb;
+double gc[100];
+
+// CK1: [[SIZE00:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 800]
+// CK1: [[MTYPE00:@.+]] = {{.+}}constant [1 x i32] [i32 34]
+
+// CK1: [[SIZE02:@.+]] = {{.+}}constant [1 x i[[sz]]] [i[[sz]] 4]
+// CK1: [[MTYPE02:@.+]] = {{.+}}constant [1 x i32] [i32 33]
+
+// CK1: [[MTYPE03:@.+]] = {{.+}}constant [1 x i32] [i32 37]
+
+// CK1: [[SIZE04:@.+]] = {{.+}}constant [2 x i[[sz]]] [i[[sz]] {{8|4}}, i[[sz]] 24]
+// CK1: [[MTYPE04:@.+]] = {{.+}}constant [2 x i32] [i32 33, i32 17]
+
+// CK1-LABEL: _Z3fooi
+void foo(int arg) {
+ int la;
+ float lb[arg];
+
+ // Region 00
+ // CK1-DAG: call void @__tgt_target_data_begin(i32 [[DEV:%[^,]+]], i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK1-DAG: [[DEV]] = load i32, i32* %{{[^,]+}},
+ // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: store i8* bitcast ([100 x double]* @gc to i8*), i8** [[BP0]]
+ // CK1-DAG: store i8* bitcast ([100 x double]* @gc to i8*), i8** [[P0]]
+
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+
+ // CK1-DAG: call void @__tgt_target_data_end(i32 [[DEV:%[^,]+]], i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK1-DAG: [[DEV]] = load i32, i32* %{{[^,]+}},
+ // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP]]
+ // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P]]
+ #pragma omp target data if(1+3-5) device(arg) map(from: gc)
+ {++arg;}
+
+ // Region 01
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ #pragma omp target data map(la) if(1+3-4)
+ {++arg;}
+
+ // Region 02
+ // CK1: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+ // CK1: [[IFTHEN]]
+ // CK1-DAG: call void @__tgt_target_data_begin(i32 4, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK1-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK1-DAG: [[CBPVAL0]] = bitcast i32* [[VAR0:%.+]] to i8*
+ // CK1-DAG: [[CPVAL0]] = bitcast i32* [[VAR0]] to i8*
+ // CK1: br label %[[IFEND:[^,]+]]
+
+ // CK1: [[IFELSE]]
+ // CK1: br label %[[IFEND]]
+ // CK1: [[IFEND]]
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ // CK1: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+
+ // CK1: [[IFTHEN]]
+ // CK1-DAG: call void @__tgt_target_data_end(i32 4, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP]]
+ // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P]]
+ // CK1: br label %[[IFEND:[^,]+]]
+ // CK1: [[IFELSE]]
+ // CK1: br label %[[IFEND]]
+ // CK1: [[IFEND]]
+ #pragma omp target data map(to: arg) if(arg) device(4)
+ {++arg;}
+
+ // Region 03
+ // CK1-DAG: call void @__tgt_target_data_begin(i32 -1, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[sz]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
+ // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+ // CK1-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
+
+ // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK1-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK1-DAG: store i[[sz]] [[CSVAL0:%[^,]+]], i[[sz]]* [[S0]]
+ // CK1-DAG: [[CBPVAL0]] = bitcast float* [[VAR0:%.+]] to i8*
+ // CK1-DAG: [[CPVAL0]] = bitcast float* [[VAR0]] to i8*
+ // CK1-DAG: [[CSVAL0]] = mul nuw i[[sz]] %{{[^,]+}}, 4
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+
+ // CK1-DAG: call void @__tgt_target_data_end(i32 -1, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[sz]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
+ // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP]]
+ // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P]]
+ // CK1-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S]]
+ #pragma omp target data map(always, to: lb)
+ {++arg;}
+
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ {++arg;}
+
+ // Region 04
+ // CK1-DAG: call void @__tgt_target_data_begin(i32 -1, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE04]]{{.+}})
+ // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: store i8* bitcast ([[ST]]* @gb to i8*), i8** [[BP0]]
+ // CK1-DAG: store i8* bitcast (double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1) to i8*), i8** [[P0]]
+
+
+ // CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK1-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK1-DAG: store i8* bitcast (double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1) to i8*), i8** [[BP1]]
+ // CK1-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK1-DAG: [[CPVAL1]] = bitcast double* [[SEC1:%.+]] to i8*
+ // CK1-DAG: [[SEC1]] = getelementptr inbounds {{.+}}double* [[SEC11:%[^,]+]], i{{.+}} 0
+ // CK1-DAG: [[SEC11]] = load double*, double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1),
+
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+
+ // CK1-DAG: call void @__tgt_target_data_end(i32 -1, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE04]]{{.+}})
+ // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP]]
+ // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P]]
+ #pragma omp target data map(to: gb.b[:3])
+ {++arg;}
+}
+#endif
+///==========================================================================///
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+#ifdef CK2
+
+// CK2: [[ST:%.+]] = type { i32, double* }
+template <typename T>
+struct ST {
+ T a;
+ double *b;
+
+ T foo(T arg) {
+ // Region 00
+ #pragma omp target data map(always, to: b[1:3]) if(a>123) device(arg)
+ {arg++;}
+ return arg;
+ }
+};
+
+// CK2: [[SIZE00:@.+]] = {{.+}}constant [2 x i[[sz:64|32]]] [i{{64|32}} {{8|4}}, i{{64|32}} 24]
+// CK2: [[MTYPE00:@.+]] = {{.+}}constant [2 x i32] [i32 37, i32 21]
+
+// CK2-LABEL: _Z3bari
+int bar(int arg){
+ ST<int> A;
+ return A.foo(arg);
+}
+
+// Region 00
+// CK2: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+// CK2: [[IFTHEN]]
+// CK2-DAG: call void @__tgt_target_data_begin(i32 [[DEV:%[^,]+]], i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}})
+// CK2-DAG: [[DEV]] = load i32, i32* %{{[^,]+}},
+// CK2-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK2-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK2-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK2-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK2-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK2-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK2-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[VAR0:%.+]] to i8*
+// CK2-DAG: [[CPVAL0]] = bitcast double** [[SEC0:%[^,]+]] to i8*
+// CK2-DAG: [[SEC0]] = getelementptr inbounds {{.*}}[[ST]]* [[VAR0]], i32 0, i32 1
+
+
+// CK2-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+// CK2-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+// CK2-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+// CK2-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+// CK2-DAG: [[CBPVAL1]] = bitcast double** [[SEC0]] to i8*
+// CK2-DAG: [[CPVAL1]] = bitcast double* [[SEC1:%[^,]+]] to i8*
+// CK2-DAG: [[SEC1]] = getelementptr inbounds {{.*}}double* [[SEC11:%[^,]+]], i{{.+}} 1
+// CK2-DAG: [[SEC11]] = load double*, double** [[SEC111:%[^,]+]],
+// CK2-DAG: [[SEC111]] = getelementptr inbounds {{.*}}[[ST]]* [[VAR0]], i32 0, i32 1
+
+// CK2: br label %[[IFEND:[^,]+]]
+
+// CK2: [[IFELSE]]
+// CK2: br label %[[IFEND]]
+// CK2: [[IFEND]]
+// CK2: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+// CK2: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+
+// CK2: [[IFTHEN]]
+// CK2-DAG: call void @__tgt_target_data_end(i32 [[DEV:%[^,]+]], i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}})
+// CK2-DAG: [[DEV]] = load i32, i32* %{{[^,]+}},
+// CK2-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP]]
+// CK2-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P]]
+// CK2: br label %[[IFEND:[^,]+]]
+// CK2: [[IFELSE]]
+// CK2: br label %[[IFEND]]
+// CK2: [[IFEND]]
+#endif
+///==========================================================================///
+// RUN: %clang_cc1 -DCK3 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64
+// RUN: %clang_cc1 -DCK3 -verify -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32
+#ifdef CK3
+
+// CK3-LABEL: no_target_devices
+void no_target_devices(int arg) {
+ // CK3-NOT: tgt_target_data_begin
+ // CK3: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ // CK3-NOT: tgt_target_data_end
+ // CK3: ret
+ #pragma omp target data map(to: arg) if(arg) device(4)
+ {++arg;}
+}
+#endif
+#endif
diff --git a/test/OpenMP/target_data_device_messages.cpp b/test/OpenMP/target_data_device_messages.cpp
index 9e8e31a28f5b6..9ed7a54b4399a 100644
--- a/test/OpenMP/target_data_device_messages.cpp
+++ b/test/OpenMP/target_data_device_messages.cpp
@@ -10,18 +10,19 @@ bool foobool(int argc) {
struct S1; // expected-note {{declared here}}
int main(int argc, char **argv) {
- #pragma omp target data device // expected-error {{expected '(' after 'device'}}
- #pragma omp target data device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
- #pragma omp target data device () // expected-error {{expected expression}}
- #pragma omp target data device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
- #pragma omp target data device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target data' are ignored}}
-#pragma omp target data device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
- #pragma omp target data device (argc + argc)
- #pragma omp target data device (argc), device (argc+1) // expected-error {{directive '#pragma omp target data' cannot contain more than one 'device' clause}}
- #pragma omp target data device (S1) // expected-error {{'S1' does not refer to a value}}
- #pragma omp target data device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}}
- #pragma omp target device (-10u)
- #pragma omp target device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
+ int a;
+ #pragma omp target data map(to: a) device // expected-error {{expected '(' after 'device'}}
+ #pragma omp target data map(to: a) device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target data map(to: a) device () // expected-error {{expected expression}}
+ #pragma omp target data map(to: a) device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target data map(to: a) device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target data' are ignored}}
+#pragma omp target data map(to: a) device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ #pragma omp target data map(to: a) device (argc + argc)
+ #pragma omp target data map(to: a) device (argc), device (argc+1) // expected-error {{directive '#pragma omp target data' cannot contain more than one 'device' clause}}
+ #pragma omp target data map(to: a) device (S1) // expected-error {{'S1' does not refer to a value}}
+ #pragma omp target data map(to: a) device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}}
+ #pragma omp target data map(to: a) device (-10u)
+ #pragma omp target data map(to: a) device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
foo();
return 0;
diff --git a/test/OpenMP/target_data_if_messages.cpp b/test/OpenMP/target_data_if_messages.cpp
index 77edefa48b8a4..ec6fe26921538 100644
--- a/test/OpenMP/target_data_if_messages.cpp
+++ b/test/OpenMP/target_data_if_messages.cpp
@@ -10,22 +10,23 @@ bool foobool(int argc) {
struct S1; // expected-note {{declared here}}
int main(int argc, char **argv) {
- #pragma omp target data if // expected-error {{expected '(' after 'if'}}
- #pragma omp target data if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
- #pragma omp target data if () // expected-error {{expected expression}}
- #pragma omp target data if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
- #pragma omp target data if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target data' are ignored}}
- #pragma omp target data if (argc > 0 ? argv[1] : argv[2])
- #pragma omp target data if (argc + argc)
- #pragma omp target data if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target data' cannot contain more than one 'if' clause}}
- #pragma omp target data if (S1) // expected-error {{'S1' does not refer to a value}}
- #pragma omp target data if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
- #pragma omp target data if(target data : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
- #pragma omp target data if(target data : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
- #pragma omp target data if(target data : argc)
- #pragma omp target data if(target data : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target data'}}
- #pragma omp target data if(target data : argc) if (target data:argc) // expected-error {{directive '#pragma omp target data' cannot contain more than one 'if' clause with 'target data' name modifier}}
- #pragma omp target data if(target data : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}}
+ int a;
+ #pragma omp target data map(to: a) if // expected-error {{expected '(' after 'if'}}
+ #pragma omp target data map(to: a) if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target data map(to: a) if () // expected-error {{expected expression}}
+ #pragma omp target data map(to: a) if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target data map(to: a) if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target data' are ignored}}
+ #pragma omp target data map(to: a) if (argc > 0 ? argv[1] : argv[2])
+ #pragma omp target data map(to: a) if (argc + argc)
+ #pragma omp target data map(to: a) if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target data' cannot contain more than one 'if' clause}}
+ #pragma omp target data map(to: a) if (S1) // expected-error {{'S1' does not refer to a value}}
+ #pragma omp target data map(to: a) if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target data map(to: a) if(target data : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target data map(to: a) if(target data : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target data map(to: a) if(target data : argc)
+ #pragma omp target data map(to: a) if(target data : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target data'}}
+ #pragma omp target data map(to: a) if(target data : argc) if (target data:argc) // expected-error {{directive '#pragma omp target data' cannot contain more than one 'if' clause with 'target data' name modifier}}
+ #pragma omp target data map(to: a) if(target data : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}}
foo();
return 0;
diff --git a/test/OpenMP/target_data_messages.c b/test/OpenMP/target_data_messages.c
index cd60d85a9030b..153b4377290ca 100644
--- a/test/OpenMP/target_data_messages.c
+++ b/test/OpenMP/target_data_messages.c
@@ -3,19 +3,22 @@
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'}}
+ {}
L1:
foo();
- #pragma omp target data
+ #pragma omp target data map(a)
{
foo();
goto L1; // expected-error {{use of undeclared label 'L1'}}
}
goto L2; // expected-error {{use of undeclared label 'L2'}}
- #pragma omp target data
+ #pragma omp target data map(a)
L2:
foo();
- #pragma omp target data(i) // expected-warning {{extra tokens at the end of '#pragma omp target data' are ignored}}
+ #pragma omp target data map(a)(i) // expected-warning {{extra tokens at the end of '#pragma omp target data' are ignored}}
{
foo();
}
diff --git a/test/OpenMP/target_data_use_device_ptr_ast_print.cpp b/test/OpenMP/target_data_use_device_ptr_ast_print.cpp
new file mode 100644
index 0000000000000..4e3253b2798fd
--- /dev/null
+++ b/test/OpenMP/target_data_use_device_ptr_ast_print.cpp
@@ -0,0 +1,154 @@
+// RxUN: %clang_cc1 -verify -fopenmp -std=c++11 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+struct ST {
+ int *a;
+};
+struct SA {
+ int i, j;
+ int *k = &j;
+ int *&z = k;
+ void func(int arg) {
+#pragma omp target data map(tofrom: i) use_device_ptr(k)
+ {}
+#pragma omp target data map(tofrom: i) use_device_ptr(z)
+ {}
+ return;
+ }
+};
+// CHECK: struct SA
+// CHECK: void func(
+// CHECK: #pragma omp target data map(tofrom: this->i) use_device_ptr(this->k)
+// CHECK: #pragma omp target data map(tofrom: this->i) use_device_ptr(this->z)
+struct SB {
+ unsigned A;
+ unsigned B;
+ float Arr[100];
+ float *Ptr;
+ float *foo() {
+ return &Arr[0];
+ }
+};
+
+struct SC {
+ unsigned A : 2;
+ unsigned B : 3;
+ unsigned C;
+ unsigned D;
+ float Arr[100];
+ SB S;
+ SB ArrS[100];
+ SB *PtrS;
+ SB *&RPtrS;
+ float *Ptr;
+
+ SC(SB *&_RPtrS) : RPtrS(_RPtrS) {}
+};
+
+union SD {
+ unsigned A;
+ float B;
+};
+
+struct S1;
+extern S1 a;
+class S2 {
+ mutable int a;
+public:
+ S2():a(0) { }
+ S2(S2 &s2):a(s2.a) { }
+ static float S2s;
+ static const float S2sc;
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+public:
+ S3():a(0) { }
+ S3(S3 &s3):a(s3.a) { }
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 {
+ int a;
+ S4();
+ S4(const S4 &s4);
+public:
+ S4(int v):a(v) { }
+};
+class S5 {
+ int a;
+ S5():a(0) {}
+ S5(const S5 &s5):a(s5.a) { }
+public:
+ S5(int v):a(v) { }
+};
+
+S3 h;
+#pragma omp threadprivate(h)
+
+typedef int from;
+
+template <typename T>
+T tmain(T argc) {
+ T i;
+ T &j = i;
+ T *k = &j;
+ T *&z = k;
+#pragma omp target data map(tofrom: i) use_device_ptr(k)
+ {}
+#pragma omp target data map(tofrom: i) use_device_ptr(z)
+ {}
+ return 0;
+}
+
+// CHECK: template <typename T = int> int tmain(int argc) {
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = i;
+// CHECK-NEXT: int *k = &j;
+// CHECK-NEXT: int *&z = k;
+// CHECK-NEXT: #pragma omp target data map(tofrom: i) use_device_ptr(k)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target data map(tofrom: i) use_device_ptr(z)
+
+// CHECK: template <typename T = int *> int *tmain(int *argc) {
+// CHECK-NEXT: int *i;
+// CHECK-NEXT: int *&j = i;
+// CHECK-NEXT: int **k = &j;
+// CHECK-NEXT: int **&z = k;
+// CHECK-NEXT: #pragma omp target data map(tofrom: i) use_device_ptr(k)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target data map(tofrom: i) use_device_ptr(z)
+
+// CHECK-LABEL: int main(int argc, char **argv) {
+int main(int argc, char **argv) {
+ int i;
+ int &j = i;
+ int *k = &j;
+ int *&z = k;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = i;
+// CHECK-NEXT: int *k = &j;
+// CHECK-NEXT: int *&z = k;
+#pragma omp target data map(tofrom: i) use_device_ptr(k)
+// CHECK-NEXT: #pragma omp target data map(tofrom: i) use_device_ptr(k)
+ {}
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+#pragma omp target data map(tofrom: i) use_device_ptr(z)
+// CHECK-NEXT: #pragma omp target data map(tofrom: i) use_device_ptr(z)
+ {}
+ return tmain<int>(argc) + (*tmain<int*>(&argc));
+}
+
+#endif
diff --git a/test/OpenMP/target_data_use_device_ptr_messages.cpp b/test/OpenMP/target_data_use_device_ptr_messages.cpp
new file mode 100644
index 0000000000000..1d8002c1ff603
--- /dev/null
+++ b/test/OpenMP/target_data_use_device_ptr_messages.cpp
@@ -0,0 +1,206 @@
+// RUN: %clang_cc1 -std=c++11 -verify -fopenmp -ferror-limit 200 %s
+struct ST {
+ int *a;
+};
+struct SA {
+ const int d = 5;
+ const int da[5] = { 0 };
+ ST e;
+ ST g[10];
+ int i;
+ int &j = i;
+ int *k = &j;
+ int *&z = k;
+ int aa[10];
+ void func(int arg) {
+#pragma omp target data map(i) use_device_ptr // expected-error {{expected '(' after 'use_device_ptr'}}
+ {}
+#pragma omp target data map(i) use_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+ {}
+#pragma omp target data map(i) use_device_ptr() // expected-error {{expected expression}}
+ {}
+#pragma omp target data map(i) use_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+ {}
+#pragma omp target data map(i) use_device_ptr(arg // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+#pragma omp target data map(i) use_device_ptr(i) // expected-error {{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+#pragma omp target data map(i) use_device_ptr(j) // expected-error {{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+#pragma omp target data map(i) use_device_ptr(k) // OK
+ {}
+#pragma omp target data map(i) use_device_ptr(z) // OK
+ {}
+#pragma omp target data map(i) use_device_ptr(aa) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+#pragma omp target data map(i) use_device_ptr(e) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+#pragma omp target data map(i) use_device_ptr(g) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+#pragma omp target data map(i) use_device_ptr(k,i,j) // expected-error2 {{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+#pragma omp target data map(i) use_device_ptr(d) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+#pragma omp target data map(i) use_device_ptr(da) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+ return;
+ }
+};
+struct SB {
+ unsigned A;
+ unsigned B;
+ float Arr[100];
+ float *Ptr;
+ float *foo() {
+ return &Arr[0];
+ }
+};
+
+struct SC {
+ unsigned A : 2;
+ unsigned B : 3;
+ unsigned C;
+ unsigned D;
+ float Arr[100];
+ SB S;
+ SB ArrS[100];
+ SB *PtrS;
+ SB *&RPtrS;
+ float *Ptr;
+
+ SC(SB *&_RPtrS) : RPtrS(_RPtrS) {}
+};
+
+union SD {
+ unsigned A;
+ float B;
+};
+
+struct S1;
+extern S1 a;
+class S2 {
+ mutable int a;
+public:
+ S2():a(0) { }
+ S2(S2 &s2):a(s2.a) { }
+ static float S2s;
+ static const float S2sc;
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+public:
+ S3():a(0) { }
+ S3(S3 &s3):a(s3.a) { }
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 {
+ int a;
+ S4();
+ S4(const S4 &s4);
+public:
+ S4(int v):a(v) { }
+};
+class S5 {
+ int a;
+ S5():a(0) {}
+ S5(const S5 &s5):a(s5.a) { }
+public:
+ S5(int v):a(v) { }
+};
+
+S3 h;
+#pragma omp threadprivate(h)
+
+typedef int from;
+
+template <typename T, int I>
+T tmain(T argc) {
+ const T d = 5;
+ const T da[5] = { 0 };
+ S4 e(4);
+ S5 g(5);
+ T i;
+ T &j = i;
+ T *k = &j;
+ T *&z = k;
+ T aa[10];
+#pragma omp target data map(i) use_device_ptr // expected-error {{expected '(' after 'use_device_ptr'}}
+ {}
+#pragma omp target data map(i) use_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+ {}
+#pragma omp target data map(i) use_device_ptr() // expected-error {{expected expression}}
+ {}
+#pragma omp target data map(i) use_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+ {}
+#pragma omp target data map(i) use_device_ptr(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+#pragma omp target data map(i) use_device_ptr(i) // expected-error {{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+#pragma omp target data map(i) use_device_ptr(j) // expected-error {{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+#pragma omp target data map(i) use_device_ptr(k) // OK
+ {}
+#pragma omp target data map(i) use_device_ptr(z) // OK
+ {}
+#pragma omp target data map(i) use_device_ptr(aa) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+#pragma omp target data map(i) use_device_ptr(e) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+#pragma omp target data map(i) use_device_ptr(g) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+#pragma omp target data map(i) use_device_ptr(k,i,j) // expected-error2 {{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+#pragma omp target data map(i) use_device_ptr(d) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+#pragma omp target data map(i) use_device_ptr(da) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5;
+ const int da[5] = { 0 };
+ S4 e(4);
+ S5 g(5);
+ int i;
+ int &j = i;
+ int *k = &j;
+ int *&z = k;
+ int aa[10];
+#pragma omp target data map(i) use_device_ptr // expected-error {{expected '(' after 'use_device_ptr'}}
+ {}
+#pragma omp target data map(i) use_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+ {}
+#pragma omp target data map(i) use_device_ptr() // expected-error {{expected expression}}
+ {}
+#pragma omp target data map(i) use_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+ {}
+#pragma omp target data map(i) use_device_ptr(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+#pragma omp target data map(i) use_device_ptr(i) // expected-error {{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+#pragma omp target data map(i) use_device_ptr(j) // expected-error {{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+#pragma omp target data map(i) use_device_ptr(k) // OK
+ {}
+#pragma omp target data map(i) use_device_ptr(z) // OK
+ {}
+#pragma omp target data map(i) use_device_ptr(aa) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+#pragma omp target data map(i) use_device_ptr(e) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+#pragma omp target data map(i) use_device_ptr(g) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+#pragma omp target data map(i) use_device_ptr(k,i,j) // expected-error2 {{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+#pragma omp target data map(i) use_device_ptr(d) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+#pragma omp target data map(i) use_device_ptr(da) // expected-error{{expected pointer or reference to pointer in 'use_device_ptr' clause}}
+ {}
+ return tmain<int, 3>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}}
+}
diff --git a/test/OpenMP/target_defaultmap_messages.cpp b/test/OpenMP/target_defaultmap_messages.cpp
new file mode 100644
index 0000000000000..59348d42c5253
--- /dev/null
+++ b/test/OpenMP/target_defaultmap_messages.cpp
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+template <class T, typename S, int N, int ST>
+T tmain(T argc, S **argv) {
+ #pragma omp target defaultmap // expected-error {{expected '(' after 'defaultmap'}}
+ foo();
+ #pragma omp target defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}}
+ foo();
+ #pragma omp target defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+ foo();
+ #pragma omp target defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+ foo();
+ #pragma omp target defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+ foo();
+ #pragma omp target defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}}
+ foo();
+ #pragma omp target defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+ foo();
+
+ return argc;
+}
+
+int main(int argc, char **argv) {
+ #pragma omp target defaultmap // expected-error {{expected '(' after 'defaultmap'}}
+ foo();
+ #pragma omp target defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}}
+ foo();
+ #pragma omp target defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+ foo();
+ #pragma omp target defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+ foo();
+ #pragma omp target defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+ foo();
+ #pragma omp target defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}}
+ foo();
+ #pragma omp target defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+ foo();
+
+ return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/target_depend_messages.cpp b/test/OpenMP/target_depend_messages.cpp
new file mode 100644
index 0000000000000..c13a3edaf699a
--- /dev/null
+++ b/test/OpenMP/target_depend_messages.cpp
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+class vector {
+ public:
+ int operator[](int index) { return 0; }
+};
+
+int main(int argc, char **argv, char *env[]) {
+ vector vec;
+ typedef float V __attribute__((vector_size(16)));
+ V a;
+ auto arr = x; // expected-error {{use of undeclared identifier 'x'}}
+
+ #pragma omp target depend // expected-error {{expected '(' after 'depend'}}
+ foo();
+ #pragma omp target depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+ foo();
+ #pragma omp target depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+ foo();
+ #pragma omp target depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+ foo();
+ #pragma omp target depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
+ foo();
+ #pragma omp target depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}}
+ foo();
+ #pragma omp target depend (out: ) // expected-error {{expected expression}}
+ foo();
+ #pragma omp target depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+ foo();
+ #pragma omp target depend (out :S1) // expected-error {{'S1' does not refer to a value}}
+ foo();
+ #pragma omp target depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+ foo();
+ #pragma omp target depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+ foo();
+ #pragma omp target depend (in : argv[0])
+ foo();
+ #pragma omp target depend (in : ) // expected-error {{expected expression}}
+ foo();
+ #pragma omp target depend (in : main) // expected-error {{expected variable name, array element or array section}}
+ foo();
+ #pragma omp target depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+ foo();
+ #pragma omp target depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
+ foo();
+ #pragma omp target depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target depend (in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target depend (in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target depend (in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}}
+ foo();
+ #pragma omp target depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}}
+ foo();
+ #pragma omp target depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ foo();
+ #pragma omp target depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}}
+ foo();
+ #pragma omp target depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}}
+ foo();
+ #pragma omp target depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}}
+ foo();
+ #pragma omp target depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ foo();
+ #pragma omp target depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}}
+ foo();
+ #pragma omp target depend(in : argv[ : argc][1 : argc - 1])
+ foo();
+ #pragma omp target depend(in : arr[0])
+ foo();
+
+ return 0;
+}
diff --git a/test/OpenMP/target_device_messages.cpp b/test/OpenMP/target_device_messages.cpp
index fb0f2defa42bc..3befcd690810b 100644
--- a/test/OpenMP/target_device_messages.cpp
+++ b/test/OpenMP/target_device_messages.cpp
@@ -11,16 +11,27 @@ struct S1; // expected-note {{declared here}}
int main(int argc, char **argv) {
#pragma omp target device // expected-error {{expected '(' after 'device'}}
+ foo();
#pragma omp target device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
#pragma omp target device () // expected-error {{expected expression}}
+ foo();
#pragma omp target device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
#pragma omp target device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}}
-#pragma omp target device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ foo();
+ #pragma omp target device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ foo();
#pragma omp target device (argc + argc)
+ foo();
#pragma omp target device (argc), device (argc+1) // expected-error {{directive '#pragma omp target' cannot contain more than one 'device' clause}}
+ foo();
#pragma omp target device (S1) // expected-error {{'S1' does not refer to a value}}
+ foo();
#pragma omp target device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}}
+ foo();
#pragma omp target device (-10u)
+ foo();
#pragma omp target device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
foo();
diff --git a/test/OpenMP/target_enter_data_ast_print.cpp b/test/OpenMP/target_enter_data_ast_print.cpp
new file mode 100644
index 0000000000000..10ec925284998
--- /dev/null
+++ b/test/OpenMP/target_enter_data_ast_print.cpp
@@ -0,0 +1,228 @@
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+template <typename T, int C>
+T tmain(T argc, T *argv) {
+ T i, j, b, c, d, e, x[20];
+
+ i = argc;
+#pragma omp target enter data map(to: i)
+
+#pragma omp target enter data map(to: i) if (target enter data: j > 0)
+
+#pragma omp target enter data map(to: i) if (b)
+
+#pragma omp target enter data map(to: c)
+
+#pragma omp target enter data map(to: c) if(b>e)
+
+#pragma omp target enter data map(alloc: x[0:10], c)
+
+#pragma omp target enter data map(to: c) map(alloc: d)
+
+#pragma omp target enter data map(always,alloc: e)
+
+#pragma omp target enter data nowait map(to: i)
+
+#pragma omp target enter data nowait map(to: i) if (target enter data: j > 0)
+
+#pragma omp target enter data map(to: i) if (b) nowait
+
+#pragma omp target enter data map(to: c) nowait
+
+#pragma omp target enter data map(to: c) nowait if(b>e)
+
+#pragma omp target enter data nowait map(alloc: x[0:10], c)
+
+#pragma omp target enter data nowait map(to: c) map(alloc: d)
+
+#pragma omp target enter data nowait map(always,alloc: e)
+
+#pragma omp target enter data nowait depend(in : argc, argv[i:argc], x[:]) map(to: i)
+
+#pragma omp target enter data nowait map(to: i) if (target enter data: j > 0) depend(in : argc, argv[i:argc], x[:])
+
+#pragma omp target enter data depend(in : argc, argv[i:argc], x[:]) map(to: i) if (b) nowait
+
+#pragma omp target enter data map(to: c) depend(in : argc, argv[i:argc], x[:]) nowait
+
+#pragma omp target enter data map(to: c) nowait if(b>e) depend(in : argc, argv[i:argc], x[:])
+
+#pragma omp target enter data nowait map(alloc: x[0:10], c) depend(in : argc, argv[i:argc], x[:])
+
+#pragma omp target enter data nowait depend(in : argc, argv[i:argc], x[:]) map(to: c) map(alloc: d)
+
+#pragma omp target enter data nowait map(always,alloc: e) depend(in : argc, argv[i:argc], x[:])
+
+ return 0;
+}
+
+// CHECK: template <typename T = int, int C = 5> int tmain(int argc, int *argv) {
+// CHECK-NEXT: int i, j, b, c, d, e, x[20];
+// CHECK-NEXT: i = argc;
+// CHECK-NEXT: #pragma omp target enter data map(to: i)
+// CHECK-NEXT: #pragma omp target enter data map(to: i) if(target enter data: j > 0)
+// CHECK-NEXT: #pragma omp target enter data map(to: i) if(b)
+// CHECK-NEXT: #pragma omp target enter data map(to: c)
+// CHECK-NEXT: #pragma omp target enter data map(to: c) if(b > e)
+// CHECK-NEXT: #pragma omp target enter data map(alloc: x[0:10],c)
+// CHECK-NEXT: #pragma omp target enter data map(to: c) map(alloc: d)
+// CHECK-NEXT: #pragma omp target enter data map(always,alloc: e)
+// CHECK-NEXT: #pragma omp target enter data nowait map(to: i)
+// CHECK-NEXT: #pragma omp target enter data nowait map(to: i) if(target enter data: j > 0)
+// CHECK-NEXT: #pragma omp target enter data map(to: i) if(b) nowait
+// CHECK-NEXT: #pragma omp target enter data map(to: c) nowait
+// CHECK-NEXT: #pragma omp target enter data map(to: c) nowait if(b > e)
+// CHECK-NEXT: #pragma omp target enter data nowait map(alloc: x[0:10],c)
+// CHECK-NEXT: #pragma omp target enter data nowait map(to: c) map(alloc: d)
+// CHECK-NEXT: #pragma omp target enter data nowait map(always,alloc: e)
+// CHECK-NEXT: #pragma omp target enter data nowait depend(in : argc,argv[i:argc],x[:]) map(to: i)
+// CHECK-NEXT: #pragma omp target enter data nowait map(to: i) if(target enter data: j > 0) depend(in : argc,argv[i:argc],x[:])
+// CHECK-NEXT: #pragma omp target enter data depend(in : argc,argv[i:argc],x[:]) map(to: i) if(b) nowait
+// CHECK-NEXT: #pragma omp target enter data map(to: c) depend(in : argc,argv[i:argc],x[:]) nowait
+// CHECK-NEXT: #pragma omp target enter data map(to: c) nowait if(b > e) depend(in : argc,argv[i:argc],x[:])
+// CHECK-NEXT: #pragma omp target enter data nowait map(alloc: x[0:10],c) depend(in : argc,argv[i:argc],x[:])
+// CHECK-NEXT: #pragma omp target enter data nowait depend(in : argc,argv[i:argc],x[:]) map(to: c) map(alloc: d)
+// CHECK-NEXT: #pragma omp target enter data nowait map(always,alloc: e) depend(in : argc,argv[i:argc],x[:])
+// CHECK: template <typename T = char, int C = 1> char tmain(char argc, char *argv) {
+// CHECK-NEXT: char i, j, b, c, d, e, x[20];
+// CHECK-NEXT: i = argc;
+// CHECK-NEXT: #pragma omp target enter data map(to: i)
+// CHECK-NEXT: #pragma omp target enter data map(to: i) if(target enter data: j > 0)
+// CHECK-NEXT: #pragma omp target enter data map(to: i) if(b)
+// CHECK-NEXT: #pragma omp target enter data map(to: c)
+// CHECK-NEXT: #pragma omp target enter data map(to: c) if(b > e)
+// CHECK-NEXT: #pragma omp target enter data map(alloc: x[0:10],c)
+// CHECK-NEXT: #pragma omp target enter data map(to: c) map(alloc: d)
+// CHECK-NEXT: #pragma omp target enter data map(always,alloc: e)
+// CHECK-NEXT: #pragma omp target enter data nowait map(to: i)
+// CHECK-NEXT: #pragma omp target enter data nowait map(to: i) if(target enter data: j > 0)
+// CHECK-NEXT: #pragma omp target enter data map(to: i) if(b) nowait
+// CHECK-NEXT: #pragma omp target enter data map(to: c) nowait
+// CHECK-NEXT: #pragma omp target enter data map(to: c) nowait if(b > e)
+// CHECK-NEXT: #pragma omp target enter data nowait map(alloc: x[0:10],c)
+// CHECK-NEXT: #pragma omp target enter data nowait map(to: c) map(alloc: d)
+// CHECK-NEXT: #pragma omp target enter data nowait map(always,alloc: e)
+// CHECK-NEXT: #pragma omp target enter data nowait depend(in : argc,argv[i:argc],x[:]) map(to: i)
+// CHECK-NEXT: #pragma omp target enter data nowait map(to: i) if(target enter data: j > 0) depend(in : argc,argv[i:argc],x[:])
+// CHECK-NEXT: #pragma omp target enter data depend(in : argc,argv[i:argc],x[:]) map(to: i) if(b) nowait
+// CHECK-NEXT: #pragma omp target enter data map(to: c) depend(in : argc,argv[i:argc],x[:]) nowait
+// CHECK-NEXT: #pragma omp target enter data map(to: c) nowait if(b > e) depend(in : argc,argv[i:argc],x[:])
+// CHECK-NEXT: #pragma omp target enter data nowait map(alloc: x[0:10],c) depend(in : argc,argv[i:argc],x[:])
+// CHECK-NEXT: #pragma omp target enter data nowait depend(in : argc,argv[i:argc],x[:]) map(to: c) map(alloc: d)
+// CHECK-NEXT: #pragma omp target enter data nowait map(always,alloc: e) depend(in : argc,argv[i:argc],x[:])
+// CHECK: template <typename T, int C> T tmain(T argc, T *argv) {
+// CHECK-NEXT: T i, j, b, c, d, e, x[20];
+// CHECK-NEXT: i = argc;
+// CHECK-NEXT: #pragma omp target enter data map(to: i)
+// CHECK-NEXT: #pragma omp target enter data map(to: i) if(target enter data: j > 0)
+// CHECK-NEXT: #pragma omp target enter data map(to: i) if(b)
+// CHECK-NEXT: #pragma omp target enter data map(to: c)
+// CHECK-NEXT: #pragma omp target enter data map(to: c) if(b > e)
+// CHECK-NEXT: #pragma omp target enter data map(alloc: x[0:10],c)
+// CHECK-NEXT: #pragma omp target enter data map(to: c) map(alloc: d)
+// CHECK-NEXT: #pragma omp target enter data map(always,alloc: e)
+// CHECK-NEXT: #pragma omp target enter data nowait map(to: i)
+// CHECK-NEXT: #pragma omp target enter data nowait map(to: i) if(target enter data: j > 0)
+// CHECK-NEXT: #pragma omp target enter data map(to: i) if(b) nowait
+// CHECK-NEXT: #pragma omp target enter data map(to: c) nowait
+// CHECK-NEXT: #pragma omp target enter data map(to: c) nowait if(b > e)
+// CHECK-NEXT: #pragma omp target enter data nowait map(alloc: x[0:10],c)
+// CHECK-NEXT: #pragma omp target enter data nowait map(to: c) map(alloc: d)
+// CHECK-NEXT: #pragma omp target enter data nowait map(always,alloc: e)
+// CHECK-NEXT: #pragma omp target enter data nowait depend(in : argc,argv[i:argc],x[:]) map(to: i)
+// CHECK-NEXT: #pragma omp target enter data nowait map(to: i) if(target enter data: j > 0) depend(in : argc,argv[i:argc],x[:])
+// CHECK-NEXT: #pragma omp target enter data depend(in : argc,argv[i:argc],x[:]) map(to: i) if(b) nowait
+// CHECK-NEXT: #pragma omp target enter data map(to: c) depend(in : argc,argv[i:argc],x[:]) nowait
+// CHECK-NEXT: #pragma omp target enter data map(to: c) nowait if(b > e) depend(in : argc,argv[i:argc],x[:])
+// CHECK-NEXT: #pragma omp target enter data nowait map(alloc: x[0:10],c) depend(in : argc,argv[i:argc],x[:])
+// CHECK-NEXT: #pragma omp target enter data nowait depend(in : argc,argv[i:argc],x[:]) map(to: c) map(alloc: d)
+// CHECK-NEXT: #pragma omp target enter data nowait map(always,alloc: e) depend(in : argc,argv[i:argc],x[:])
+
+int main (int argc, char **argv) {
+ int b = argc, i, c, d, e, f, g, x[20];
+ static int a;
+// CHECK: static int a;
+
+#pragma omp target enter data map(to: a)
+// CHECK: #pragma omp target enter data map(to: a)
+ a=2;
+// CHECK-NEXT: a = 2;
+#pragma omp target enter data map(to: a) if (target enter data: b)
+// CHECK: #pragma omp target enter data map(to: a) if(target enter data: b)
+
+#pragma omp target enter data map(to: a) if (b > g)
+// CHECK: #pragma omp target enter data map(to: a) if(b > g)
+
+#pragma omp target enter data map(to: c)
+// CHECK-NEXT: #pragma omp target enter data map(to: c)
+
+#pragma omp target enter data map(alloc: c) if(b>g)
+// CHECK-NEXT: #pragma omp target enter data map(alloc: c) if(b > g)
+
+#pragma omp target enter data map(to: x[0:10], c)
+// CHECK-NEXT: #pragma omp target enter data map(to: x[0:10],c)
+
+#pragma omp target enter data map(to: c) map(alloc: d)
+// CHECK-NEXT: #pragma omp target enter data map(to: c) map(alloc: d)
+
+#pragma omp target enter data map(always,alloc: e)
+// CHECK-NEXT: #pragma omp target enter data map(always,alloc: e)
+
+#pragma omp target enter data nowait map(to: a)
+// CHECK: #pragma omp target enter data nowait map(to: a)
+
+#pragma omp target enter data nowait map(to: a) if (target enter data: b)
+// CHECK: #pragma omp target enter data nowait map(to: a) if(target enter data: b)
+
+#pragma omp target enter data map(to: a) if (b > g) nowait
+// CHECK: #pragma omp target enter data map(to: a) if(b > g) nowait
+
+#pragma omp target enter data map(to: c) nowait
+// CHECK-NEXT: #pragma omp target enter data map(to: c) nowait
+
+#pragma omp target enter data map(alloc: c) nowait if(b>g)
+// CHECK-NEXT: #pragma omp target enter data map(alloc: c) nowait if(b > g)
+
+#pragma omp target enter data nowait map(to: x[0:10], c)
+// CHECK-NEXT: #pragma omp target enter data nowait map(to: x[0:10],c)
+
+#pragma omp target enter data nowait map(to: c) map(alloc: d)
+// CHECK-NEXT: #pragma omp target enter data nowait map(to: c) map(alloc: d)
+
+#pragma omp target enter data nowait map(always,alloc: e)
+// CHECK-NEXT: #pragma omp target enter data nowait map(always,alloc: e)
+
+#pragma omp target enter data depend(in : argc, argv[i:argc], x[:]) nowait map(to: a)
+// CHECK: #pragma omp target enter data depend(in : argc,argv[i:argc],x[:]) nowait map(to: a)
+
+#pragma omp target enter data nowait depend(in : argc, argv[i:argc], x[:]) map(to: a) if (target enter data: b)
+// CHECK: #pragma omp target enter data nowait depend(in : argc,argv[i:argc],x[:]) map(to: a) if(target enter data: b)
+
+#pragma omp target enter data map(to: a) depend(in : argc, argv[i:argc], x[:]) if (b > g) nowait
+// CHECK: #pragma omp target enter data map(to: a) depend(in : argc,argv[i:argc],x[:]) if(b > g) nowait
+
+#pragma omp target enter data map(to: c) nowait depend(in : argc, argv[i:argc], x[:])
+// CHECK-NEXT: #pragma omp target enter data map(to: c) nowait depend(in : argc,argv[i:argc],x[:])
+
+#pragma omp target enter data depend(in : argc, argv[i:argc], x[:]) map(alloc: c) nowait if(b>g)
+// CHECK-NEXT: #pragma omp target enter data depend(in : argc,argv[i:argc],x[:]) map(alloc: c) nowait if(b > g)
+
+#pragma omp target enter data nowait map(to: x[0:10], c) depend(in : argc, argv[i:argc], x[:])
+// CHECK-NEXT: #pragma omp target enter data nowait map(to: x[0:10],c) depend(in : argc,argv[i:argc],x[:])
+
+#pragma omp target enter data nowait map(to: c) depend(in : argc, argv[i:argc], x[:]) map(alloc: d)
+// CHECK-NEXT: #pragma omp target enter data nowait map(to: c) depend(in : argc,argv[i:argc],x[:]) map(alloc: d)
+
+#pragma omp target enter data nowait map(always,alloc: e) depend(in : argc, argv[i:argc], x[:])
+// CHECK-NEXT: #pragma omp target enter data nowait map(always,alloc: e) depend(in : argc,argv[i:argc],x[:])
+
+ return tmain<int, 5>(argc, &argc) + tmain<char, 1>(argv[0][0], argv[0]);
+}
+
+#endif
diff --git a/test/OpenMP/target_enter_data_codegen.cpp b/test/OpenMP/target_enter_data_codegen.cpp
new file mode 100644
index 0000000000000..152cd46b4a2ff
--- /dev/null
+++ b/test/OpenMP/target_enter_data_codegen.cpp
@@ -0,0 +1,249 @@
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+///==========================================================================///
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+#ifdef CK1
+
+// CK1: [[ST:%.+]] = type { i32, double* }
+template <typename T>
+struct ST {
+ T a;
+ double *b;
+};
+
+ST<int> gb;
+double gc[100];
+
+// CK1: [[SIZE00:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 800]
+// CK1: [[MTYPE00:@.+]] = {{.+}}constant [1 x i32] [i32 32]
+
+// CK1: [[SIZE02:@.+]] = {{.+}}constant [1 x i[[sz]]] [i[[sz]] 4]
+// CK1: [[MTYPE02:@.+]] = {{.+}}constant [1 x i32] [i32 33]
+
+// CK1: [[MTYPE03:@.+]] = {{.+}}constant [1 x i32] [i32 37]
+
+// CK1: [[SIZE04:@.+]] = {{.+}}constant [2 x i[[sz]]] [i[[sz]] {{8|4}}, i[[sz]] 24]
+// CK1: [[MTYPE04:@.+]] = {{.+}}constant [2 x i32] [i32 33, i32 17]
+
+// CK1-LABEL: _Z3fooi
+void foo(int arg) {
+ int la;
+ float lb[arg];
+
+ // Region 00
+ // CK1-DAG: call void @__tgt_target_data_begin(i32 [[DEV:%[^,]+]], i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK1-DAG: [[DEV]] = load i32, i32* %{{[^,]+}},
+ // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: store i8* bitcast ([100 x double]* @gc to i8*), i8** [[BP0]]
+ // CK1-DAG: store i8* bitcast ([100 x double]* @gc to i8*), i8** [[P0]]
+
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ // CK1-NOT: __tgt_target_data_end
+ #pragma omp target enter data if(1+3-5) device(arg) map(alloc: gc)
+ {++arg;}
+
+ // Region 01
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ #pragma omp target enter data map(to: la) if(1+3-4)
+ {++arg;}
+
+ // Region 02
+ // CK1: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+ // CK1: [[IFTHEN]]
+ // CK1-DAG: call void @__tgt_target_data_begin(i32 4, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK1-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK1-DAG: [[CBPVAL0]] = bitcast i32* [[VAR0:%.+]] to i8*
+ // CK1-DAG: [[CPVAL0]] = bitcast i32* [[VAR0]] to i8*
+ // CK1: br label %[[IFEND:[^,]+]]
+
+ // CK1: [[IFELSE]]
+ // CK1: br label %[[IFEND]]
+ // CK1: [[IFEND]]
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ // CK1-NOT: __tgt_target_data_end
+ #pragma omp target enter data map(to: arg) if(arg) device(4)
+ {++arg;}
+
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ {++arg;}
+
+ // Region 03
+ // CK1-DAG: call void @__tgt_target_data_begin(i32 -1, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[sz]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
+ // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+ // CK1-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
+
+ // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK1-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK1-DAG: store i[[sz]] [[CSVAL0:%[^,]+]], i[[sz]]* [[S0]]
+ // CK1-DAG: [[CBPVAL0]] = bitcast float* [[VAR0:%.+]] to i8*
+ // CK1-DAG: [[CPVAL0]] = bitcast float* [[VAR0]] to i8*
+ // CK1-DAG: [[CSVAL0]] = mul nuw i[[sz]] %{{[^,]+}}, 4
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ // CK1-NOT: __tgt_target_data_end
+ #pragma omp target enter data map(always, to: lb)
+ {++arg;}
+
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ {++arg;}
+
+ // Region 04
+ // CK1-DAG: call void @__tgt_target_data_begin(i32 -1, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE04]]{{.+}})
+ // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: store i8* bitcast ([[ST]]* @gb to i8*), i8** [[BP0]]
+ // CK1-DAG: store i8* bitcast (double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1) to i8*), i8** [[P0]]
+
+
+ // CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK1-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK1-DAG: store i8* bitcast (double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1) to i8*), i8** [[BP1]]
+ // CK1-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK1-DAG: [[CPVAL1]] = bitcast double* [[SEC1:%.+]] to i8*
+ // CK1-DAG: [[SEC1]] = getelementptr inbounds {{.+}}double* [[SEC11:%[^,]+]], i{{.+}} 0
+ // CK1-DAG: [[SEC11]] = load double*, double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1),
+
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ // CK1-NOT: __tgt_target_data_end
+ #pragma omp target enter data map(to: gb.b[:3])
+ {++arg;}
+}
+#endif
+///==========================================================================///
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+#ifdef CK2
+
+// CK2: [[ST:%.+]] = type { i32, double* }
+template <typename T>
+struct ST {
+ T a;
+ double *b;
+
+ T foo(T arg) {
+ // Region 00
+ #pragma omp target enter data map(always, to: b[1:3]) if(a>123) device(arg)
+ {arg++;}
+ return arg;
+ }
+};
+
+// CK2: [[SIZE00:@.+]] = {{.+}}constant [2 x i[[sz:64|32]]] [i{{64|32}} {{8|4}}, i{{64|32}} 24]
+// CK2: [[MTYPE00:@.+]] = {{.+}}constant [2 x i32] [i32 37, i32 21]
+
+// CK2-LABEL: _Z3bari
+int bar(int arg){
+ ST<int> A;
+ return A.foo(arg);
+}
+
+// Region 00
+// CK2: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+// CK2: [[IFTHEN]]
+// CK2-DAG: call void @__tgt_target_data_begin(i32 [[DEV:%[^,]+]], i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}})
+// CK2-DAG: [[DEV]] = load i32, i32* %{{[^,]+}},
+// CK2-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK2-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK2-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK2-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK2-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK2-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK2-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[VAR0:%.+]] to i8*
+// CK2-DAG: [[CPVAL0]] = bitcast double** [[SEC0:%[^,]+]] to i8*
+// CK2-DAG: [[SEC0]] = getelementptr inbounds {{.*}}[[ST]]* [[VAR0]], i32 0, i32 1
+
+
+// CK2-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+// CK2-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+// CK2-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+// CK2-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+// CK2-DAG: [[CBPVAL1]] = bitcast double** [[SEC0]] to i8*
+// CK2-DAG: [[CPVAL1]] = bitcast double* [[SEC1:%[^,]+]] to i8*
+// CK2-DAG: [[SEC1]] = getelementptr inbounds {{.*}}double* [[SEC11:%[^,]+]], i{{.+}} 1
+// CK2-DAG: [[SEC11]] = load double*, double** [[SEC111:%[^,]+]],
+// CK2-DAG: [[SEC111]] = getelementptr inbounds {{.*}}[[ST]]* [[VAR0]], i32 0, i32 1
+
+// CK2: br label %[[IFEND:[^,]+]]
+
+// CK2: [[IFELSE]]
+// CK2: br label %[[IFEND]]
+// CK2: [[IFEND]]
+// CK2: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+// CK2-NOT: __tgt_target_data_end
+#endif
+///==========================================================================///
+// RUN: %clang_cc1 -DCK3 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64
+// RUN: %clang_cc1 -DCK3 -verify -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32
+#ifdef CK3
+
+// CK3-LABEL: no_target_devices
+void no_target_devices(int arg) {
+ // CK3-NOT: tgt_target_data_begin
+ // CK3: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ // CK3-NOT: tgt_target_data_end
+ // CK3: ret
+ #pragma omp target enter data map(to: arg) if(arg) device(4)
+ {++arg;}
+}
+#endif
+///==========================================================================///
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64
+// RUN: %clang_cc1 -DCK4 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32
+// RUN: %clang_cc1 -DCK4 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32
+
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCK4 --check-prefix TCK4-64
+// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCK4 --check-prefix TCK4-64
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCK4 --check-prefix TCK4-32
+// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCK4 --check-prefix TCK4-32
+#ifdef CK4
+
+// CK4-LABEL: device_side_scan
+void device_side_scan(int arg) {
+ // CK4: tgt_target_data_begin
+ // CK4: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ // CK4: ret
+ // TCK4-NOT: tgt_target_data_begin
+ #pragma omp target enter data map(to: arg) if(arg) device(4)
+ {++arg;}
+}
+#endif
+#endif
diff --git a/test/OpenMP/target_enter_data_depend_messages.cpp b/test/OpenMP/target_enter_data_depend_messages.cpp
new file mode 100644
index 0000000000000..84254b5c312a9
--- /dev/null
+++ b/test/OpenMP/target_enter_data_depend_messages.cpp
@@ -0,0 +1,166 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note {{declared here}}
+
+class vector {
+ public:
+ int operator[](int index) { return 0; }
+};
+
+template <class T, class S, class R>
+int tmain(T argc, S **argv, R *env[]) {
+ vector vec;
+ typedef float V __attribute__((vector_size(16)));
+ V a;
+ char *arr;
+
+ int i;
+ #pragma omp target enter data map(to: i) depend // expected-error {{expected '(' after 'depend'}}
+ foo();
+ #pragma omp target enter data map(to: i) depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+ foo();
+ #pragma omp target enter data map(to: i) depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (out: ) // expected-error {{expected expression}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (out :S1) // expected-error {{'S1' does not refer to a value}}
+ foo();
+ #pragma omp target enter data map(to: i) depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : argv[0])
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : ) // expected-error {{expected expression}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : tmain) // expected-error {{expected variable name, array element or array section}}
+ foo();
+ #pragma omp target enter data map(to: i) depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}}
+ foo();
+ #pragma omp target enter data map(to: i) depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}}
+ foo();
+ #pragma omp target enter data map(to: i) depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}}
+ foo();
+ #pragma omp target enter data map(to: i) depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ foo();
+ #pragma omp target enter data map(to: i) depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}}
+ foo();
+ #pragma omp target enter data map(to: i) depend(in : argv[ : argc][1 : argc - 1])
+ foo();
+ #pragma omp target enter data map(to: i) depend(in : arr[0])
+ foo();
+
+ return 0;
+}
+
+int main(int argc, char **argv, char *env[]) {
+ vector vec;
+ typedef float V __attribute__((vector_size(16)));
+ V a;
+ char *arr;
+
+ int i;
+ #pragma omp target enter data map(to: i) depend // expected-error {{expected '(' after 'depend'}}
+ foo();
+ #pragma omp target enter data map(to: i) depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+ foo();
+ #pragma omp target enter data map(to: i) depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (out: ) // expected-error {{expected expression}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (out :S1) // expected-error {{'S1' does not refer to a value}}
+ foo();
+ #pragma omp target enter data map(to: i) depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : argv[0])
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : ) // expected-error {{expected expression}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : main) // expected-error {{expected variable name, array element or array section}}
+ foo();
+ #pragma omp target enter data map(to: i) depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ foo();
+ #pragma omp target enter data map(to: i) depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}}
+ foo();
+ #pragma omp target enter data map(to: i) depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}}
+ foo();
+ #pragma omp target enter data map(to: i) depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}}
+ foo();
+ #pragma omp target enter data map(to: i) depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ foo();
+ #pragma omp target enter data map(to: i) depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}}
+ foo();
+ #pragma omp target enter data map(to: i) depend(in : argv[ : argc][1 : argc - 1])
+ foo();
+ #pragma omp target enter data map(to: i) depend(in : arr[0])
+ foo();
+
+ return tmain(argc, argv, env); // expected-note {{in instantiation of function template specialization 'tmain<int, char, char>' requested here}}
+}
diff --git a/test/OpenMP/target_enter_data_device_messages.cpp b/test/OpenMP/target_enter_data_device_messages.cpp
new file mode 100644
index 0000000000000..d954eca319dd2
--- /dev/null
+++ b/test/OpenMP/target_enter_data_device_messages.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+int main(int argc, char **argv) {
+ int i;
+ #pragma omp target enter data map(to: i) device // expected-error {{expected '(' after 'device'}}
+ #pragma omp target enter data map(to: i) device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target enter data map(to: i) device () // expected-error {{expected expression}}
+ #pragma omp target enter data map(to: i) device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target enter data map(to: i) device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}}
+#pragma omp target enter data map(to: i) device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ #pragma omp target enter data map(to: i) device (argc + argc)
+ #pragma omp target enter data map(to: i) device (argc), device (argc+1) // expected-error {{directive '#pragma omp target enter data' cannot contain more than one 'device' clause}}
+ #pragma omp target enter data map(to: i) device (S1) // expected-error {{'S1' does not refer to a value}}
+ #pragma omp target enter data map(to: i) device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}}
+ #pragma omp target enter data map(to: i) device (-10u)
+ #pragma omp target enter data map(to: i) device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
+ foo();
+
+ return 0;
+}
diff --git a/test/OpenMP/target_enter_data_if_messages.cpp b/test/OpenMP/target_enter_data_if_messages.cpp
new file mode 100644
index 0000000000000..0d18af187b19e
--- /dev/null
+++ b/test/OpenMP/target_enter_data_if_messages.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+int main(int argc, char **argv) {
+ int i;
+ #pragma omp target enter data map(to: i) if // expected-error {{expected '(' after 'if'}}
+ #pragma omp target enter data map(to: i) if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target enter data map(to: i) if () // expected-error {{expected expression}}
+ #pragma omp target enter data map(to: i) if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target enter data map(to: i) if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}}
+ #pragma omp target enter data map(to: i) if (argc > 0 ? argv[1] : argv[2])
+ #pragma omp target enter data map(to: i) if (argc + argc)
+ #pragma omp target enter data map(to: i) if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target enter data' cannot contain more than one 'if' clause}}
+ #pragma omp target enter data map(to: i) if (S1) // expected-error {{'S1' does not refer to a value}}
+ #pragma omp target enter data map(to: i) if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target enter data map(to: i) if(target data : true) // expected-error {{directive name modifier 'target data' is not allowed for '#pragma omp target enter data'}}
+ #pragma omp target enter data map(to: i) if(target enter data : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target enter data map(to: i) if(target enter data : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target enter data map(to: i) if(target enter data : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target enter data map(to: i) if(target enter data : argc)
+ #pragma omp target enter data map(to: i) if(target enter data : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target enter data'}}
+ #pragma omp target enter data map(to: i) if(target enter data : argc) if (target enter data:argc) // expected-error {{directive '#pragma omp target enter data' cannot contain more than one 'if' clause with 'target enter data' name modifier}}
+ #pragma omp target enter data map(to: i) if(target enter data : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}}
+ foo();
+
+ return 0;
+}
diff --git a/test/OpenMP/target_enter_data_map_messages.c b/test/OpenMP/target_enter_data_map_messages.c
new file mode 100644
index 0000000000000..6f5aad1ef6504
--- /dev/null
+++ b/test/OpenMP/target_enter_data_map_messages.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - -x c++ %s
+
+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 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'}}
+
+ #pragma omp target enter data map(always, to: r)
+ #pragma omp target enter data map(always, alloc: r)
+ #pragma omp target enter data map(always, from: r) // expected-error {{map type 'from' is not allowed for '#pragma omp target enter data'}}
+ #pragma omp target enter data map(release: r) // expected-error {{map type 'release' is not allowed for '#pragma omp target enter data'}}
+ #pragma omp target enter data map(delete: r) // expected-error {{map type 'delete' is not allowed for '#pragma omp target enter data'}}
+
+ return 0;
+}
diff --git a/test/OpenMP/target_enter_data_nowait_messages.cpp b/test/OpenMP/target_enter_data_nowait_messages.cpp
new file mode 100644
index 0000000000000..e682e8c47d703
--- /dev/null
+++ b/test/OpenMP/target_enter_data_nowait_messages.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+
+int main(int argc, char **argv) {
+ int i;
+
+ #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 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)
+ #pragma omp target enter data map(to: i) nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}}
+ #pragma omp target enter data map(to: i) nowait nowait // expected-error {{directive '#pragma omp target enter data' cannot contain more than one 'nowait' clause}}
+ #pragma omp target enter data nowait map(to: i) nowait // expected-error {{directive '#pragma omp target enter data' cannot contain more than one 'nowait' clause}}
+ return 0;
+}
diff --git a/test/OpenMP/target_exit_data_ast_print.cpp b/test/OpenMP/target_exit_data_ast_print.cpp
new file mode 100644
index 0000000000000..e2c6d7fd65ceb
--- /dev/null
+++ b/test/OpenMP/target_exit_data_ast_print.cpp
@@ -0,0 +1,244 @@
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+template <typename T, int C>
+T tmain(T argc, T *argv) {
+ T i, j, b, c, d, e, x[20];
+
+ i = argc;
+#pragma omp target exit data map(from: i)
+
+#pragma omp target exit data map(from: i) if (target exit data: j > 0)
+
+#pragma omp target exit data map(from: i) if (b)
+
+#pragma omp target exit data map(from: c)
+
+#pragma omp target exit data map(from: c) if(b>e)
+
+#pragma omp target exit data map(release: x[0:10], c)
+
+#pragma omp target exit data map(delete: x[0:10])
+
+#pragma omp target exit data map(always, delete: x[0:10])
+
+#pragma omp target exit data map(from: c) map(release: d)
+
+#pragma omp target exit data map(always,release: e)
+
+#pragma omp target exit data nowait map(from: i)
+
+#pragma omp target exit data nowait map(from: i) if (target exit data: j > 0)
+
+#pragma omp target exit data map(from: i) if (b) nowait
+
+#pragma omp target exit data map(from: c) nowait
+
+#pragma omp target exit data map(from: c) nowait if(b>e)
+
+#pragma omp target exit data nowait map(release: x[0:10], c)
+
+#pragma omp target exit data nowait map(from: c) map(release: d)
+
+#pragma omp target exit data nowait map(always,release: e)
+
+#pragma omp target exit data depend(in : argc, argv[i:argc], x[:]) nowait map(from: i)
+
+#pragma omp target exit data nowait depend(in : argc, argv[i:argc], x[:]) map(from: i) if (target exit data: j > 0)
+
+#pragma omp target exit data map(from: i) depend(in : argc, argv[i:argc], x[:]) if (b) nowait
+
+#pragma omp target exit data map(from: c) depend(in : argc, argv[i:argc], x[:]) nowait
+
+#pragma omp target exit data map(from: c) depend(in : argc, argv[i:argc], x[:]) nowait if(b>e)
+
+#pragma omp target exit data nowait map(release: x[0:10], c) depend(in : argc, argv[i:argc], x[:])
+
+#pragma omp target exit data nowait map(from: c) depend(in : argc, argv[i:argc], x[:]) map(release: d)
+
+#pragma omp target exit data depend(in : argc, argv[i:argc], x[:]) nowait map(always,release: e)
+
+ return 0;
+}
+
+// CHECK: template <typename T = int, int C = 5> int tmain(int argc, int *argv) {
+// CHECK-NEXT: int i, j, b, c, d, e, x[20];
+// CHECK-NEXT: i = argc;
+// CHECK-NEXT: #pragma omp target exit data map(from: i)
+// CHECK-NEXT: #pragma omp target exit data map(from: i) if(target exit data: j > 0)
+// CHECK-NEXT: #pragma omp target exit data map(from: i) if(b)
+// CHECK-NEXT: #pragma omp target exit data map(from: c)
+// CHECK-NEXT: #pragma omp target exit data map(from: c) if(b > e)
+// CHECK-NEXT: #pragma omp target exit data map(release: x[0:10],c)
+// CHECK-NEXT: #pragma omp target exit data map(delete: x[0:10])
+// CHECK-NEXT: #pragma omp target exit data map(always,delete: x[0:10])
+// CHECK-NEXT: #pragma omp target exit data map(from: c) map(release: d)
+// CHECK-NEXT: #pragma omp target exit data map(always,release: e)
+// CHECK-NEXT: #pragma omp target exit data nowait map(from: i)
+// CHECK-NEXT: #pragma omp target exit data nowait map(from: i) if(target exit data: j > 0)
+// CHECK-NEXT: #pragma omp target exit data map(from: i) if(b) nowait
+// CHECK-NEXT: #pragma omp target exit data map(from: c) nowait
+// CHECK-NEXT: #pragma omp target exit data map(from: c) nowait if(b > e)
+// CHECK-NEXT: #pragma omp target exit data nowait map(release: x[0:10],c)
+// CHECK-NEXT: #pragma omp target exit data nowait map(from: c) map(release: d)
+// CHECK-NEXT: #pragma omp target exit data nowait map(always,release: e)
+// CHECK-NEXT: #pragma omp target exit data depend(in : argc,argv[i:argc],x[:]) nowait map(from: i)
+// CHECK-NEXT: #pragma omp target exit data nowait depend(in : argc,argv[i:argc],x[:]) map(from: i) if(target exit data: j > 0)
+// CHECK-NEXT: #pragma omp target exit data map(from: i) depend(in : argc,argv[i:argc],x[:]) if(b) nowait
+// CHECK-NEXT: #pragma omp target exit data map(from: c) depend(in : argc,argv[i:argc],x[:]) nowait
+// CHECK-NEXT: #pragma omp target exit data map(from: c) depend(in : argc,argv[i:argc],x[:]) nowait if(b > e)
+// CHECK-NEXT: #pragma omp target exit data nowait map(release: x[0:10],c) depend(in : argc,argv[i:argc],x[:])
+// CHECK-NEXT: #pragma omp target exit data nowait map(from: c) depend(in : argc,argv[i:argc],x[:]) map(release: d)
+// CHECK-NEXT: #pragma omp target exit data depend(in : argc,argv[i:argc],x[:]) nowait map(always,release: e)
+// CHECK: template <typename T = char, int C = 1> char tmain(char argc, char *argv) {
+// CHECK-NEXT: char i, j, b, c, d, e, x[20];
+// CHECK-NEXT: i = argc;
+// CHECK-NEXT: #pragma omp target exit data map(from: i)
+// CHECK-NEXT: #pragma omp target exit data map(from: i) if(target exit data: j > 0)
+// CHECK-NEXT: #pragma omp target exit data map(from: i) if(b)
+// CHECK-NEXT: #pragma omp target exit data map(from: c)
+// CHECK-NEXT: #pragma omp target exit data map(from: c) if(b > e)
+// CHECK-NEXT: #pragma omp target exit data map(release: x[0:10],c)
+// CHECK-NEXT: #pragma omp target exit data map(delete: x[0:10])
+// CHECK-NEXT: #pragma omp target exit data map(always,delete: x[0:10])
+// CHECK-NEXT: #pragma omp target exit data map(from: c) map(release: d)
+// CHECK-NEXT: #pragma omp target exit data map(always,release: e)
+// CHECK-NEXT: #pragma omp target exit data nowait map(from: i)
+// CHECK-NEXT: #pragma omp target exit data nowait map(from: i) if(target exit data: j > 0)
+// CHECK-NEXT: #pragma omp target exit data map(from: i) if(b) nowait
+// CHECK-NEXT: #pragma omp target exit data map(from: c) nowait
+// CHECK-NEXT: #pragma omp target exit data map(from: c) nowait if(b > e)
+// CHECK-NEXT: #pragma omp target exit data nowait map(release: x[0:10],c)
+// CHECK-NEXT: #pragma omp target exit data nowait map(from: c) map(release: d)
+// CHECK-NEXT: #pragma omp target exit data nowait map(always,release: e)
+// CHECK-NEXT: #pragma omp target exit data depend(in : argc,argv[i:argc],x[:]) nowait map(from: i)
+// CHECK-NEXT: #pragma omp target exit data nowait depend(in : argc,argv[i:argc],x[:]) map(from: i) if(target exit data: j > 0)
+// CHECK-NEXT: #pragma omp target exit data map(from: i) depend(in : argc,argv[i:argc],x[:]) if(b) nowait
+// CHECK-NEXT: #pragma omp target exit data map(from: c) depend(in : argc,argv[i:argc],x[:]) nowait
+// CHECK-NEXT: #pragma omp target exit data map(from: c) depend(in : argc,argv[i:argc],x[:]) nowait if(b > e)
+// CHECK-NEXT: #pragma omp target exit data nowait map(release: x[0:10],c) depend(in : argc,argv[i:argc],x[:])
+// CHECK-NEXT: #pragma omp target exit data nowait map(from: c) depend(in : argc,argv[i:argc],x[:]) map(release: d)
+// CHECK-NEXT: #pragma omp target exit data depend(in : argc,argv[i:argc],x[:]) nowait map(always,release: e)
+// CHECK: template <typename T, int C> T tmain(T argc, T *argv) {
+// CHECK-NEXT: T i, j, b, c, d, e, x[20];
+// CHECK-NEXT: i = argc;
+// CHECK-NEXT: #pragma omp target exit data map(from: i)
+// CHECK-NEXT: #pragma omp target exit data map(from: i) if(target exit data: j > 0)
+// CHECK-NEXT: #pragma omp target exit data map(from: i) if(b)
+// CHECK-NEXT: #pragma omp target exit data map(from: c)
+// CHECK-NEXT: #pragma omp target exit data map(from: c) if(b > e)
+// CHECK-NEXT: #pragma omp target exit data map(release: x[0:10],c)
+// CHECK-NEXT: #pragma omp target exit data map(delete: x[0:10])
+// CHECK-NEXT: #pragma omp target exit data map(always,delete: x[0:10])
+// CHECK-NEXT: #pragma omp target exit data map(from: c) map(release: d)
+// CHECK-NEXT: #pragma omp target exit data map(always,release: e)
+// CHECK-NEXT: #pragma omp target exit data nowait map(from: i)
+// CHECK-NEXT: #pragma omp target exit data nowait map(from: i) if(target exit data: j > 0)
+// CHECK-NEXT: #pragma omp target exit data map(from: i) if(b) nowait
+// CHECK-NEXT: #pragma omp target exit data map(from: c) nowait
+// CHECK-NEXT: #pragma omp target exit data map(from: c) nowait if(b > e)
+// CHECK-NEXT: #pragma omp target exit data nowait map(release: x[0:10],c)
+// CHECK-NEXT: #pragma omp target exit data nowait map(from: c) map(release: d)
+// CHECK-NEXT: #pragma omp target exit data nowait map(always,release: e)
+// CHECK-NEXT: #pragma omp target exit data depend(in : argc,argv[i:argc],x[:]) nowait map(from: i)
+// CHECK-NEXT: #pragma omp target exit data nowait depend(in : argc,argv[i:argc],x[:]) map(from: i) if(target exit data: j > 0)
+// CHECK-NEXT: #pragma omp target exit data map(from: i) depend(in : argc,argv[i:argc],x[:]) if(b) nowait
+// CHECK-NEXT: #pragma omp target exit data map(from: c) depend(in : argc,argv[i:argc],x[:]) nowait
+// CHECK-NEXT: #pragma omp target exit data map(from: c) depend(in : argc,argv[i:argc],x[:]) nowait if(b > e)
+// CHECK-NEXT: #pragma omp target exit data nowait map(release: x[0:10],c) depend(in : argc,argv[i:argc],x[:])
+// CHECK-NEXT: #pragma omp target exit data nowait map(from: c) depend(in : argc,argv[i:argc],x[:]) map(release: d)
+// CHECK-NEXT: #pragma omp target exit data depend(in : argc,argv[i:argc],x[:]) nowait map(always,release: e)
+
+int main (int argc, char **argv) {
+ int b = argc, i, c, d, e, f, g, x[20];
+ static int a;
+// CHECK: static int a;
+
+#pragma omp target exit data map(from: a)
+// CHECK: #pragma omp target exit data map(from: a)
+ a=2;
+// CHECK-NEXT: a = 2;
+#pragma omp target exit data map(from: a) if (target exit data: b)
+// CHECK: #pragma omp target exit data map(from: a) if(target exit data: b)
+
+#pragma omp target exit data map(from: a) if (b > g)
+// CHECK: #pragma omp target exit data map(from: a) if(b > g)
+
+#pragma omp target exit data map(from: c)
+// CHECK-NEXT: #pragma omp target exit data map(from: c)
+
+#pragma omp target exit data map(release: c) if(b>g)
+// CHECK-NEXT: #pragma omp target exit data map(release: c) if(b > g)
+
+#pragma omp target exit data map(from: x[0:10], c)
+// CHECK-NEXT: #pragma omp target exit data map(from: x[0:10],c)
+
+#pragma omp target exit data map(delete: x[0:10])
+// CHECK-NEXT: #pragma omp target exit data map(delete: x[0:10])
+
+#pragma omp target exit data map(always, delete: x[0:10])
+// CHECK-NEXT: #pragma omp target exit data map(always,delete: x[0:10])
+
+#pragma omp target exit data map(from: c) map(release: d)
+// CHECK-NEXT: #pragma omp target exit data map(from: c) map(release: d)
+
+#pragma omp target exit data map(always,release: e)
+// CHECK-NEXT: #pragma omp target exit data map(always,release: e)
+
+#pragma omp target exit data nowait map(from: a)
+// CHECK: #pragma omp target exit data nowait map(from: a)
+
+#pragma omp target exit data nowait map(from: a) if (target exit data: b)
+// CHECK: #pragma omp target exit data nowait map(from: a) if(target exit data: b)
+
+#pragma omp target exit data map(from: a) if (b > g) nowait
+// CHECK: #pragma omp target exit data map(from: a) if(b > g) nowait
+
+#pragma omp target exit data map(from: c) nowait
+// CHECK-NEXT: #pragma omp target exit data map(from: c) nowait
+
+#pragma omp target exit data map(release: c) nowait if(b>g)
+// CHECK-NEXT: #pragma omp target exit data map(release: c) nowait if(b > g)
+
+#pragma omp target exit data nowait map(from: x[0:10], c)
+// CHECK-NEXT: #pragma omp target exit data nowait map(from: x[0:10],c)
+
+#pragma omp target exit data nowait map(from: c) map(release: d)
+// CHECK-NEXT: #pragma omp target exit data nowait map(from: c) map(release: d)
+
+#pragma omp target exit data nowait map(always,release: e)
+// CHECK-NEXT: #pragma omp target exit data nowait map(always,release: e)
+
+#pragma omp target exit data nowait depend(in : argc,argv[i:argc],x[:]) map(from: a)
+// CHECK: #pragma omp target exit data nowait depend(in : argc,argv[i:argc],x[:]) map(from: a)
+
+#pragma omp target exit data nowait map(from: a) depend(in : argc,argv[i:argc],x[:]) if (target exit data: b)
+// CHECK: #pragma omp target exit data nowait map(from: a) depend(in : argc,argv[i:argc],x[:]) if(target exit data: b)
+
+#pragma omp target exit data map(from: a) if (b > g) nowait depend(in : argc,argv[i:argc],x[:])
+// CHECK: #pragma omp target exit data map(from: a) if(b > g) nowait depend(in : argc,argv[i:argc],x[:])
+
+#pragma omp target exit data map(from: c) depend(in : argc,argv[i:argc],x[:]) nowait
+// CHECK-NEXT: #pragma omp target exit data map(from: c) depend(in : argc,argv[i:argc],x[:]) nowait
+
+#pragma omp target exit data depend(in : argc,argv[i:argc],x[:]) map(release: c) nowait if(b>g)
+// CHECK-NEXT: #pragma omp target exit data depend(in : argc,argv[i:argc],x[:]) map(release: c) nowait if(b > g)
+
+#pragma omp target exit data nowait map(from: x[0:10], c) depend(in : argc,argv[i:argc],x[:])
+// CHECK-NEXT: #pragma omp target exit data nowait map(from: x[0:10],c) depend(in : argc,argv[i:argc],x[:])
+
+#pragma omp target exit data nowait map(from: c) depend(in : argc,argv[i:argc],x[:]) map(release: d)
+// CHECK-NEXT: #pragma omp target exit data nowait map(from: c) depend(in : argc,argv[i:argc],x[:]) map(release: d)
+
+#pragma omp target exit data nowait depend(in : argc,argv[i:argc],x[:]) map(always,release: e)
+// CHECK-NEXT: #pragma omp target exit data nowait depend(in : argc,argv[i:argc],x[:]) map(always,release: e)
+
+ return tmain<int, 5>(argc, &argc) + tmain<char, 1>(argv[0][0], argv[0]);
+}
+
+#endif
diff --git a/test/OpenMP/target_exit_data_codegen.cpp b/test/OpenMP/target_exit_data_codegen.cpp
new file mode 100644
index 0000000000000..d3a38592a6103
--- /dev/null
+++ b/test/OpenMP/target_exit_data_codegen.cpp
@@ -0,0 +1,221 @@
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+///==========================================================================///
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+#ifdef CK1
+
+// CK1: [[ST:%.+]] = type { i32, double* }
+template <typename T>
+struct ST {
+ T a;
+ double *b;
+};
+
+ST<int> gb;
+double gc[100];
+
+// CK1: [[SIZE00:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 800]
+// CK1: [[MTYPE00:@.+]] = {{.+}}constant [1 x i32] [i32 34]
+
+// CK1: [[SIZE02:@.+]] = {{.+}}constant [1 x i[[sz]]] [i[[sz]] 4]
+// CK1: [[MTYPE02:@.+]] = {{.+}}constant [1 x i32] [i32 32]
+
+// CK1: [[MTYPE03:@.+]] = {{.+}}constant [1 x i32] [i32 38]
+
+// CK1: [[SIZE04:@.+]] = {{.+}}constant [2 x i[[sz]]] [i[[sz]] {{8|4}}, i[[sz]] 24]
+// CK1: [[MTYPE04:@.+]] = {{.+}}constant [2 x i32] [i32 32, i32 16]
+
+// CK1-LABEL: _Z3fooi
+void foo(int arg) {
+ int la;
+ float lb[arg];
+
+ // Region 00
+ // CK1-NOT: __tgt_target_data_begin
+ // CK1-DAG: call void @__tgt_target_data_end(i32 [[DEV:%[^,]+]], i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK1-DAG: [[DEV]] = load i32, i32* %{{[^,]+}},
+ // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: store i8* bitcast ([100 x double]* @gc to i8*), i8** [[BP0]]
+ // CK1-DAG: store i8* bitcast ([100 x double]* @gc to i8*), i8** [[P0]]
+
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ #pragma omp target exit data if(1+3-5) device(arg) map(from: gc)
+ {++arg;}
+
+ // Region 01
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ #pragma omp target exit data map(release: la) if(1+3-4)
+ {++arg;}
+
+ // Region 02
+ // CK1-NOT: __tgt_target_data_begin
+ // CK1: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+ // CK1: [[IFTHEN]]
+ // CK1-DAG: call void @__tgt_target_data_end(i32 4, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK1-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK1-DAG: [[CBPVAL0]] = bitcast i32* [[VAR0:%.+]] to i8*
+ // CK1-DAG: [[CPVAL0]] = bitcast i32* [[VAR0]] to i8*
+ // CK1: br label %[[IFEND:[^,]+]]
+
+ // CK1: [[IFELSE]]
+ // CK1: br label %[[IFEND]]
+ // CK1: [[IFEND]]
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ #pragma omp target exit data map(release: arg) if(arg) device(4)
+ {++arg;}
+
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ {++arg;}
+
+ // Region 03
+ // CK1-NOT: __tgt_target_data_begin
+ // CK1-DAG: call void @__tgt_target_data_end(i32 -1, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[sz]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
+ // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+ // CK1-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
+
+ // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK1-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK1-DAG: store i[[sz]] [[CSVAL0:%[^,]+]], i[[sz]]* [[S0]]
+ // CK1-DAG: [[CBPVAL0]] = bitcast float* [[VAR0:%.+]] to i8*
+ // CK1-DAG: [[CPVAL0]] = bitcast float* [[VAR0]] to i8*
+ // CK1-DAG: [[CSVAL0]] = mul nuw i[[sz]] %{{[^,]+}}, 4
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ #pragma omp target exit data map(always, from: lb)
+ {++arg;}
+
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ {++arg;}
+
+ // Region 04
+ // CK1-NOT: __tgt_target_data_begin
+ // CK1-DAG: call void @__tgt_target_data_end(i32 -1, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE04]]{{.+}})
+ // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: store i8* bitcast ([[ST]]* @gb to i8*), i8** [[BP0]]
+ // CK1-DAG: store i8* bitcast (double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1) to i8*), i8** [[P0]]
+
+
+ // CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK1-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK1-DAG: store i8* bitcast (double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1) to i8*), i8** [[BP1]]
+ // CK1-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK1-DAG: [[CPVAL1]] = bitcast double* [[SEC1:%.+]] to i8*
+ // CK1-DAG: [[SEC1]] = getelementptr inbounds {{.+}}double* [[SEC11:%[^,]+]], i{{.+}} 0
+ // CK1-DAG: [[SEC11]] = load double*, double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1),
+
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ #pragma omp target exit data map(release: gb.b[:3])
+ {++arg;}
+}
+#endif
+///==========================================================================///
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+#ifdef CK2
+
+// CK2: [[ST:%.+]] = type { i32, double* }
+template <typename T>
+struct ST {
+ T a;
+ double *b;
+
+ T foo(T arg) {
+ // Region 00
+ #pragma omp target exit data map(always, release: b[1:3]) if(a>123) device(arg)
+ {arg++;}
+ return arg;
+ }
+};
+
+// CK2: [[SIZE00:@.+]] = {{.+}}constant [2 x i[[sz:64|32]]] [i{{64|32}} {{8|4}}, i{{64|32}} 24]
+// CK2: [[MTYPE00:@.+]] = {{.+}}constant [2 x i32] [i32 36, i32 20]
+
+// CK2-LABEL: _Z3bari
+int bar(int arg){
+ ST<int> A;
+ return A.foo(arg);
+}
+
+// Region 00
+// CK2-NOT: __tgt_target_data_begin
+// CK2: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+// CK2: [[IFTHEN]]
+// CK2-DAG: call void @__tgt_target_data_end(i32 [[DEV:%[^,]+]], i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}})
+// CK2-DAG: [[DEV]] = load i32, i32* %{{[^,]+}},
+// CK2-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK2-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK2-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK2-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK2-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK2-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK2-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[VAR0:%.+]] to i8*
+// CK2-DAG: [[CPVAL0]] = bitcast double** [[SEC0:%[^,]+]] to i8*
+// CK2-DAG: [[SEC0]] = getelementptr inbounds {{.*}}[[ST]]* [[VAR0]], i32 0, i32 1
+
+
+// CK2-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+// CK2-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+// CK2-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+// CK2-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+// CK2-DAG: [[CBPVAL1]] = bitcast double** [[SEC0]] to i8*
+// CK2-DAG: [[CPVAL1]] = bitcast double* [[SEC1:%[^,]+]] to i8*
+// CK2-DAG: [[SEC1]] = getelementptr inbounds {{.*}}double* [[SEC11:%[^,]+]], i{{.+}} 1
+// CK2-DAG: [[SEC11]] = load double*, double** [[SEC111:%[^,]+]],
+// CK2-DAG: [[SEC111]] = getelementptr inbounds {{.*}}[[ST]]* [[VAR0]], i32 0, i32 1
+
+// CK2: br label %[[IFEND:[^,]+]]
+
+// CK2: [[IFELSE]]
+// CK2: br label %[[IFEND]]
+// CK2: [[IFEND]]
+// CK2: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+#endif
+///==========================================================================///
+// RUN: %clang_cc1 -DCK3 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64
+// RUN: %clang_cc1 -DCK3 -verify -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32
+#ifdef CK3
+
+// CK3-LABEL: no_target_devices
+void no_target_devices(int arg) {
+ // CK3-NOT: tgt_target_data_begin
+ // CK3: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ // CK3-NOT: tgt_target_data_end
+ // CK3: ret
+ #pragma omp target exit data map(from: arg) if(arg) device(4)
+ {++arg;}
+}
+#endif
+#endif
diff --git a/test/OpenMP/target_exit_data_depend_messages.cpp b/test/OpenMP/target_exit_data_depend_messages.cpp
new file mode 100644
index 0000000000000..4c59b6205f188
--- /dev/null
+++ b/test/OpenMP/target_exit_data_depend_messages.cpp
@@ -0,0 +1,166 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note {{declared here}}
+
+class vector {
+ public:
+ int operator[](int index) { return 0; }
+};
+
+template <class T, class S, class R>
+int tmain(T argc, S **argv, R *env[]) {
+ vector vec;
+ typedef float V __attribute__((vector_size(16)));
+ V a;
+ char *arr;
+
+ int i;
+ #pragma omp target exit data map(from: i) depend // expected-error {{expected '(' after 'depend'}}
+ foo();
+ #pragma omp target exit data map(from: i) depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+ foo();
+ #pragma omp target exit data map(from: i) depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (out: ) // expected-error {{expected expression}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (out :S1) // expected-error {{'S1' does not refer to a value}}
+ foo();
+ #pragma omp target exit data map(from: i) depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : argv[0])
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : ) // expected-error {{expected expression}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : tmain) // expected-error {{expected variable name, array element or array section}}
+ foo();
+ #pragma omp target exit data map(from: i) depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}}
+ foo();
+ #pragma omp target exit data map(from: i) depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}}
+ foo();
+ #pragma omp target exit data map(from: i) depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}}
+ foo();
+ #pragma omp target exit data map(from: i) depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ foo();
+ #pragma omp target exit data map(from: i) depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}}
+ foo();
+ #pragma omp target exit data map(from: i) depend(in : argv[ : argc][1 : argc - 1])
+ foo();
+ #pragma omp target exit data map(from: i) depend(in : arr[0])
+ foo();
+
+ return 0;
+}
+
+int main(int argc, char **argv, char *env[]) {
+ vector vec;
+ typedef float V __attribute__((vector_size(16)));
+ V a;
+ char *arr;
+
+ int i;
+ #pragma omp target exit data map(from: i) depend // expected-error {{expected '(' after 'depend'}}
+ foo();
+ #pragma omp target exit data map(from: i) depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+ foo();
+ #pragma omp target exit data map(from: i) depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (out: ) // expected-error {{expected expression}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (out :S1) // expected-error {{'S1' does not refer to a value}}
+ foo();
+ #pragma omp target exit data map(from: i) depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : argv[0])
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : ) // expected-error {{expected expression}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : main) // expected-error {{expected variable name, array element or array section}}
+ foo();
+ #pragma omp target exit data map(from: i) depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ foo();
+ #pragma omp target exit data map(from: i) depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}}
+ foo();
+ #pragma omp target exit data map(from: i) depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}}
+ foo();
+ #pragma omp target exit data map(from: i) depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}}
+ foo();
+ #pragma omp target exit data map(from: i) depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ foo();
+ #pragma omp target exit data map(from: i) depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}}
+ foo();
+ #pragma omp target exit data map(from: i) depend(in : argv[ : argc][1 : argc - 1])
+ foo();
+ #pragma omp target exit data map(from: i) depend(in : arr[0])
+ foo();
+
+ return tmain(argc, argv, env); // expected-note {{in instantiation of function template specialization 'tmain<int, char, char>' requested here}}
+}
diff --git a/test/OpenMP/target_exit_data_device_messages.cpp b/test/OpenMP/target_exit_data_device_messages.cpp
new file mode 100644
index 0000000000000..d9ce0ddd7ea00
--- /dev/null
+++ b/test/OpenMP/target_exit_data_device_messages.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+int main(int argc, char **argv) {
+ int i;
+ #pragma omp target exit data map(from: i) device // expected-error {{expected '(' after 'device'}}
+ #pragma omp target exit data map(from: i) device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target exit data map(from: i) device () // expected-error {{expected expression}}
+ #pragma omp target exit data map(from: i) device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target exit data map(from: i) device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}}
+#pragma omp target exit data map(from: i) device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ #pragma omp target exit data map(from: i) device (argc + argc)
+ #pragma omp target exit data map(from: i) device (argc), device (argc+1) // expected-error {{directive '#pragma omp target exit data' cannot contain more than one 'device' clause}}
+ #pragma omp target exit data map(from: i) device (S1) // expected-error {{'S1' does not refer to a value}}
+ #pragma omp target exit data map(from: i) device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}}
+ #pragma omp target exit data map(from: i) device (-10u)
+ #pragma omp target exit data map(from: i) device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
+ foo();
+
+ return 0;
+}
diff --git a/test/OpenMP/target_exit_data_if_messages.cpp b/test/OpenMP/target_exit_data_if_messages.cpp
new file mode 100644
index 0000000000000..cc674e6933cc3
--- /dev/null
+++ b/test/OpenMP/target_exit_data_if_messages.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+int main(int argc, char **argv) {
+ int i;
+ #pragma omp target exit data map(from: i) if // expected-error {{expected '(' after 'if'}}
+ #pragma omp target exit data map(from: i) if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target exit data map(from: i) if () // expected-error {{expected expression}}
+ #pragma omp target exit data map(from: i) if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target exit data map(from: i) if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}}
+ #pragma omp target exit data map(from: i) if (argc > 0 ? argv[1] : argv[2])
+ #pragma omp target exit data map(from: i) if (argc + argc)
+ #pragma omp target exit data map(from: i) if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target exit data' cannot contain more than one 'if' clause}}
+ #pragma omp target exit data map(from: i) if (S1) // expected-error {{'S1' does not refer to a value}}
+ #pragma omp target exit data map(from: i) if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target exit data map(from: i) if(target data : true) // expected-error {{directive name modifier 'target data' is not allowed for '#pragma omp target exit data'}}
+ #pragma omp target exit data map(from: i) if(target exit data : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target exit data map(from: i) if(target exit data : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target exit data map(from: i) if(target exit data : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target exit data map(from: i) if(target exit data : argc)
+ #pragma omp target exit data map(from: i) if(target exit data : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target exit data'}}
+ #pragma omp target exit data map(from: i) if(target exit data : argc) if (target exit data:argc) // expected-error {{directive '#pragma omp target exit data' cannot contain more than one 'if' clause with 'target exit data' name modifier}}
+ #pragma omp target exit data map(from: i) if(target exit data : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}}
+ foo();
+
+ return 0;
+}
diff --git a/test/OpenMP/target_exit_data_map_messages.c b/test/OpenMP/target_exit_data_map_messages.c
new file mode 100644
index 0000000000000..a9953fbbb4c6f
--- /dev/null
+++ b/test/OpenMP/target_exit_data_map_messages.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - -x c++ %s
+
+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 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'}}
+
+ #pragma omp target exit data map(always, from: r)
+ #pragma omp target exit data map(delete: r)
+ #pragma omp target exit data map(release: r)
+ #pragma omp target exit data map(always, alloc: r) // expected-error {{map type 'alloc' is not allowed for '#pragma omp target exit data'}}
+ #pragma omp target exit data map(to: r) // expected-error {{map type 'to' is not allowed for '#pragma omp target exit data'}}
+
+ return 0;
+}
diff --git a/test/OpenMP/target_exit_data_nowait_messages.cpp b/test/OpenMP/target_exit_data_nowait_messages.cpp
new file mode 100644
index 0000000000000..cd743d89278ef
--- /dev/null
+++ b/test/OpenMP/target_exit_data_nowait_messages.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+
+int main(int argc, char **argv) {
+ int i;
+
+ #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 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)
+ #pragma omp target exit data map(from: i) nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}}
+ #pragma omp target exit data map(from: i) nowait nowait // expected-error {{directive '#pragma omp target exit data' cannot contain more than one 'nowait' clause}}
+ #pragma omp target exit data nowait map(from: i) nowait // expected-error {{directive '#pragma omp target exit data' cannot contain more than one 'nowait' clause}}
+ return 0;
+}
diff --git a/test/OpenMP/target_firstprivate_codegen.cpp b/test/OpenMP/target_firstprivate_codegen.cpp
new file mode 100644
index 0000000000000..ca459e02a4256
--- /dev/null
+++ b/test/OpenMP/target_firstprivate_codegen.cpp
@@ -0,0 +1,580 @@
+// Test host codegen.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template<typename tx, typename ty>
+struct TT{
+ tx X;
+ ty Y;
+};
+
+// CHECK: [[TT:%.+]] = type { i64, i8 }
+// CHECK: [[S1:%.+]] = type { double }
+
+// TCHECK: [[TT:%.+]] = type { i64, i8 }
+// TCHECK: [[S1:%.+]] = type { double }
+
+// CHECK-DAG: [[SIZET:@.+]] = private unnamed_addr constant [1 x i{{32|64}}] [i[[SZ:32|64]] 4]
+// CHECK: [[MAPT:@.+]] = private unnamed_addr constant [1 x i32] [i32 288]
+// CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [9 x i32] [i32 288, i32 161, i32 288, i32 161, i32 161, i32 288, i32 288, i32 161, i32 161]
+// CHECK-DAG: [[SIZET3:@.+]] = private unnamed_addr constant [1 x i{{32|64}}] zeroinitializer
+// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [1 x i32] [i32 32]
+// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [5 x i32] [i32 35, i32 288, i32 288, i32 288, i32 161]
+// CHECK-DAG: [[SIZET5:@.+]] = private unnamed_addr constant [3 x i{{32|64}}] [i[[SZ]] 4, i[[SZ]] 1, i[[SZ]] 40]
+// CHECK-DAG: [[MAPT5:@.+]] = private unnamed_addr constant [3 x i32] [i32 288, i32 288, i32 161]
+// CHECK-DAG: [[SIZET6:@.+]] = private unnamed_addr constant [2 x i{{32|64}}] [i[[SZ]] 4, i[[SZ]] 40]
+// CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [2 x i32] [i32 288, i32 161]
+
+
+// CHECK: define {{.*}}[[FOO:@.+]](
+int foo(int n, double *ptr) {
+ int a = 0;
+ short aa = 0;
+ float b[10];
+ float bn[n];
+ double c[5][10];
+ double cn[5][n];
+ TT<long long, char> d;
+
+ #pragma omp target firstprivate(a)
+ {
+ }
+
+ // a is passed by value to tgt_target
+ // CHECK: [[N_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // CHECK: [[PTR_ADDR:%.+]] = alloca double*,
+ // CHECK: [[A:%.+]] = alloca i{{[0-9]+}},
+ // CHECK: [[A2:%.+]] = alloca i{{[0-9]+}},
+ // CHECK: [[B:%.+]] = alloca [10 x float],
+ // CHECK: [[SSTACK:%.+]] = alloca i8*,
+ // CHECK: [[C:%.+]] = alloca [5 x [10 x double]],
+ // CHECK: [[D:%.+]] = alloca [[TT]],
+ // CHECK: [[ACAST:%.+]] = alloca i{{[0-9]+}},
+ // CHECK: {{.+}} = alloca i{{[0-9]+}},
+ // CHECK: [[BASE_PTR_ARR:%.+]] = alloca [1 x i8*],
+ // CHECK: [[PTR_ARR:%.+]] = alloca [1 x i8*],
+ // CHECK: [[A2CAST:%.+]] = alloca i{{[0-9]+}},
+ // CHECK: [[BASE_PTR_ARR2:%.+]] = alloca [9 x i8*],
+ // CHECK: [[PTR_ARR2:%.+]] = alloca [9 x i8*],
+ // CHECK: [[SIZET2:%.+]] = alloca [9 x i{{[0-9]+}}],
+ // CHECK: [[BASE_PTR_ARR3:%.+]] = alloca [1 x i8*],
+ // CHECK: [[PTR_ARR3:%.+]] = alloca [1 x i8*],
+ // CHECK: [[N_ADDR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[N_ADDR]],
+ // CHECK-64: [[N_EXT:%.+]] = zext i{{[0-9]+}} [[N_ADDR_VAL]] to i{{[0-9]+}}
+ // CHECK: [[SSAVE_RET:%.+]] = call i8* @llvm.stacksave()
+ // CHECK: store i8* [[SSAVE_RET]], i8** [[SSTACK]],
+ // CHECK-64: [[BN_VLA:%.+]] = alloca float, i{{[0-9]+}} [[N_EXT]],
+ // CHECK-32: [[BN_VLA:%.+]] = alloca float, i{{[0-9]+}} [[N_ADDR_VAL]],
+ // CHECK: [[N_ADDR_VAL2:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[N_ADDR]],
+ // CHECK-64: [[N_EXT2:%.+]] = zext i{{[0-9]+}} [[N_ADDR_VAL2]] to i{{[0-9]+}}
+ // CHECK-64: [[CN_SIZE:%.+]] = mul{{.+}} i{{[0-9]+}} 5, [[N_EXT2]]
+ // CHECK-32: [[CN_SIZE:%.+]] = mul{{.+}} i{{[0-9]+}} 5, [[N_ADDR_VAL2]]
+ // CHECK: [[CN_VLA:%.+]] = alloca double, i{{[0-9]+}} [[CN_SIZE]],
+ // CHECK: [[AVAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A]],
+ // CHECK-64: [[CONV:%.+]] = bitcast i{{[0-9]+}}* [[ACAST]] to i{{[0-9]+}}*
+ // CHECK-64: store i{{[0-9]+}} [[AVAL]], i{{[0-9]+}}* [[CONV]],
+ // CHECK-32: store i{{[0-9]+}} [[AVAL]], i{{[0-9]+}}* [[ACAST]],
+ // CHECK: [[ACAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[ACAST]],
+ // CHECK: [[ACAST_TOPTR:%.+]] = inttoptr i{{[0-9]+}} [[ACAST_VAL]] to i8*
+ // CHECK: [[BASE_PTR_GEP:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BASE_PTR_ARR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: store i8* [[ACAST_TOPTR]], i8** [[BASE_PTR_GEP]],
+ // CHECK: [[ACAST_TOPTR2:%.+]] = inttoptr i{{[0-9]+}} [[ACAST_VAL]] to i8*
+ // CHECK: [[PTR_GEP:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PTR_ARR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: store i8* [[ACAST_TOPTR2]], i8** [[PTR_GEP]],
+ // CHECK: [[BASE_PTR_GEP_ARG:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BASE_PTR_ARR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[PTR_GEP_ARG:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PTR_ARR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: {{.+}} = call i32 @__tgt_target(i32 -1, {{.+}}, i32 1, i8** [[BASE_PTR_GEP_ARG]], i8** [[PTR_GEP_ARG]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET]], i32 0, i32 0), i32* getelementptr inbounds ([1 x i32], [1 x i32]* [[MAPT]], i32 0, i32 0))
+
+ // TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A_IN:%.+]])
+ // TCHECK: [[A_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // TCHECK-NOT: alloca i{{[0-9]+}},
+ // TCHECK: store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[A_ADDR]],
+ // TCHECK-NOT: store i{{[0-9]+}} %
+ // TCHECK: ret void
+
+#pragma omp target firstprivate(aa,b,bn,c,cn,d)
+ {
+ aa += 1;
+ b[2] = 1.0;
+ bn[3] = 1.0;
+ c[1][2] = 1.0;
+ cn[1][3] = 1.0;
+ d.X = 1;
+ d.Y = 1;
+ }
+
+ // CHECK: [[A2VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A2]],
+ // CHECK: [[A2CASTCONV:%.+]] = bitcast i{{[0-9]+}}* [[A2CAST]] to i{{[0-9]+}}*
+ // CHECK: store i{{[0-9]+}} [[A2VAL]], i{{[0-9]+}}* [[A2CASTCONV]],
+ // CHECK: [[A2CAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A2CAST]],
+ // CHECK-64: [[BN_SIZE:%.+]] = mul{{.+}} i{{[0-9]+}} [[N_EXT]], 4
+ // CHECK-32: [[BN_SIZE:%.+]] = mul{{.+}} i{{[0-9]+}} [[N_ADDR_VAL]], 4
+ // CHECK-64: [[CN_SIZE_1:%.+]] = mul{{.+}} i{{[0-9]+}} 5, [[N_EXT2]]
+ // CHECK-32: [[CN_SIZE_1:%.+]] = mul{{.+}} i{{[0-9]+}} 5, [[N_ADDR_VAL2]]
+ // CHECK: [[CN_SIZE_2:%.+]] = mul{{.+}} i{{[0-9]+}} [[CN_SIZE_1]], 8
+
+ // firstprivate(aa) --> base_ptr = aa, ptr = aa, size = 2 (short)
+ // CHECK: [[A2CAST_TO_INT:%.+]] = inttoptr i{{[0-9]+}} [[A2CAST_VAL]] to i8*
+ // CHECK: [[BASE_PTR_GEP2_0:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: store i8* [[A2CAST_TO_INT]], i8** [[BASE_PTR_GEP2_0]],
+ // CHECK: [[A2CAST_TO_INT_2:%.+]] = inttoptr i{{[0-9]+}} [[A2CAST_VAL]] to i8*
+ // CHECK: [[PTR_GEP2_0:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: store i8* [[A2CAST_TO_INT_2]], i8** [[PTR_GEP2_0]],
+ // CHECK: [[SIZE_GEPA2:%.+]] = getelementptr inbounds [9 x i{{[0-9]+}}], [9 x i{{[0-9]+}}]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIZE_GEPA2]],
+
+ // firstprivate(b): base_ptr = &b[0], ptr = &b[0], size = 40 (sizeof(float)*10)
+ // CHECK: [[BCAST:%.+]] = bitcast [10 x float]* [[B]] to i8*
+ // CHECK: [[BASE_PTR_GEP2_1:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: store i8* [[BCAST]], i8** [[BASE_PTR_GEP2_1]],
+ // CHECK: [[BCAST2:%.+]] = bitcast [10 x float]* [[B]] to i8*
+ // CHECK: [[PTR_GEP2_1:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: store i8* [[BCAST2]], i8** [[PTR_GEP2_1]],
+ // CHECK: [[SIZE_GEPB:%.+]] = getelementptr inbounds [9 x i{{[0-9]+}}], [9 x i{{[0-9]+}}]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: store i{{[0-9]+}} 40, i{{[0-9]+}}* [[SIZE_GEPB]],
+
+ // firstprivate(bn), 2 entries, n and bn: (1) base_ptr = n, ptr = n, size = 8 ; (2) base_ptr = &c[0], ptr = &c[0], size = n*sizeof(float)
+ // CHECK-64: [[N_EXT3_1:%.+]] = inttoptr i{{[0-9]+}} [[N_EXT]] to i8*
+ // CHECK-32: [[N_EXT3_1:%.+]] = inttoptr i{{[0-9]+}} [[N_ADDR_VAL]] to i8*
+ // CHECK: [[BASE_PTR_GEP2_2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // CHECK: store i8* [[N_EXT3_1]], i8** [[BASE_PTR_GEP2_2]],
+ // CHECK-64: [[N_EXT3_2:%.+]] = inttoptr i{{[0-9]+}} [[N_EXT]] to i8*
+ // CHECK-32: [[N_EXT3_2:%.+]] = inttoptr i{{[0-9]+}} [[N_ADDR_VAL]] to i8*
+ // CHECK: [[PTR_GEP2_2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // CHECK: store i8* [[N_EXT3_2]], i8** [[PTR_GEP2_2]],
+ // CHECK: [[SIZE_GEPBN_1:%.+]] = getelementptr inbounds [9 x i{{[0-9]+}}], [9 x i{{[0-9]+}}]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // CHECK: store i{{[0-9]+}} {{[0-9]}}, i{{[0-9]+}}* [[SIZE_GEPBN_1]],
+ // CHECK: [[VLABN_BCAST:%.+]] = bitcast float* [[BN_VLA]] to i8*
+ // CHECK: [[BASE_PTR_GEP2_3:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // CHECK: store i8* [[VLABN_BCAST]], i8** [[BASE_PTR_GEP2_3]],
+ // CHECK: [[SIZE_GEPBN_3:%.+]] = getelementptr inbounds [9 x i{{[0-9]+}}], [9 x i{{[0-9]+}}]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // CHECK: store i{{[0-9]+}} [[BN_SIZE]], i{{[0-9]+}}* [[SIZE_GEPBN_3]]
+
+ // firstprivate(c): base_ptr = &c[0], ptr = &c[0], size = 400 (5*10*sizeof(double))
+ // CHECK: [[C_BCAST:%.+]] = bitcast [5 x [10 x double]]* [[C]] to i8*
+ // CHECK: [[BASE_PTR_GEP2_4:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 4
+ // CHECK: store i8* [[C_BCAST]], i8** [[BASE_PTR_GEP2_4]],
+ // CHECK: [[C_BCAST2:%.+]] = bitcast [5 x [10 x double]]* [[C]] to i8*
+ // CHECK: [[PTR_GEP2_4:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 4
+ // CHECK: store i8* [[C_BCAST2]], i8** [[PTR_GEP2_4]],
+ // CHECK: [[SIZE_GEPC_4:%.+]] = getelementptr inbounds [9 x i{{[0-9]+}}], [9 x i{{[0-9]+}}]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 4
+ // CHECK: store i{{[0-9]+}} 400, i{{[0-9]+}}* [[SIZE_GEPC_4]],
+
+ // firstprivate(cn), 3 entries, 5, n, cn: (1) base_ptr = 5, ptr = 5, size = 8; (2) (1) base_ptr = n, ptr = n, size = 8; (3) base_ptr = &cn[0], ptr = &cn[0], size = 5*n*sizeof(double)
+ // CHECK: [[BASE_PTR_GEP2_5:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 5
+ // CHECK: store i8* inttoptr (i{{[0-9]+}} 5 to i8*), i8** [[BASE_PTR_GEP2_5]],
+ // CHECK: [[PTR_GEP2_5:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 5
+ // CHECK: store i8* inttoptr (i{{[0-9]+}} 5 to i8*), i8** [[PTR_GEP2_5]],
+ // CHECK: [[SIZE_GEPCN_5:%.+]] = getelementptr inbounds [9 x i{{[0-9]+}}], [9 x i{{[0-9]+}}]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 5
+ // CHECK: store i{{[0-9]+}} {{[0-9]}}, i{{[0-9]+}}* [[SIZE_GEPCN_5]],
+ // CHECK-64: [[CN_SZ_2_1:%.+]] = inttoptr i{{[0-9]+}} [[N_EXT2]] to i8*
+ // CHECK-32: [[CN_SZ_2_1:%.+]] = inttoptr i{{[0-9]+}} [[N_ADDR_VAL2]] to i8*
+ // CHECK: [[BASE_PTR_GEP2_6:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 6
+ // CHECK: store i8* [[CN_SZ_2_1]], i8** [[BASE_PTR_GEP2_6]],
+ // CHECK-64: [[CN_SZ_2_2:%.+]] = inttoptr i{{[0-9]+}} [[N_EXT2]] to i8*
+ // CHECK-32: [[CN_SZ_2_2:%.+]] = inttoptr i{{[0-9]+}} [[N_ADDR_VAL2]] to i8*
+ // CHECK: [[PTR_GEP2_6:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 6
+ // CHECK: store i8* [[CN_SZ_2_2]], i8** [[PTR_GEP2_6]],
+ // CHECK: [[SIZE_GEPCN_6:%.+]] = getelementptr inbounds [9 x i{{[0-9]+}}], [9 x i{{[0-9]+}}]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 6
+ // CHECK: store i{{[0-9]+}} {{[0-9]}}, i{{[0-9]+}}* [[SIZE_GEPCN_6]],
+ // CHECK: [[VLA_CN_BCAST:%.+]] = bitcast double* [[CN_VLA]] to i8*
+ // CHECK: [[BASE_PTR_GEP2_7:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 7
+ // CHECK: store i8* [[VLA_CN_BCAST]], i8** [[BASE_PTR_GEP2_7]],
+ // CHECK: [[VLA_CN_BCAST2:%.+]] = bitcast double* [[CN_VLA]] to i8*
+ // CHECK: [[PTR_GEP2_7:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 7
+ // CHECK: store i8* [[VLA_CN_BCAST2]], i8** [[PTR_GEP2_7]],
+ // CHECK: [[SIZE_GEPCN_7:%.+]] = getelementptr inbounds [9 x i{{[0-9]+}}], [9 x i{{[0-9]+}}]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 7
+ // CHECK: store i{{[0-9]+}} [[CN_SIZE_2]], i{{[0-9]+}}* [[SIZE_GEPCN_7]],
+
+ // firstprivate(d): base_ptr = &d, ptr = &d, size = 16
+ // CHECK: [[D_REF:%.+]] = bitcast [[TT]]* [[D]] to i8*
+ // CHECK: [[BASE_PTR_GEP2_8:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 8
+ // CHECK: store i8* [[D_REF]], i8** [[BASE_PTR_GEP2_8]],
+ // CHECK: [[D_REF2:%.+]] = bitcast [[TT]]* [[D]] to i8*
+ // CHECK: [[PTR_GEP2_8:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 8
+ // CHECK: store i8* [[D_REF2]], i8** [[PTR_GEP2_8]],
+ // CHECK: [[SIZE_GEPCN_8:%.+]] = getelementptr inbounds [9 x i{{[0-9]+}}], [9 x i{{[0-9]+}}]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 8
+ // CHECK: store i{{[0-9]+}} {{[0-9]+}}, i{{[0-9]+}}* [[SIZE_GEPCN_8]],
+
+
+ // CHECK: [[BASE_PTR_GEP_ARG2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[PTR_GEP_ARG2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[SIZES_ARG2:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: {{.+}} = call i32 @__tgt_target(i32 -1, {{.+}}, i32 9, i8** [[BASE_PTR_GEP_ARG2]], i8** [[PTR_GEP_ARG2]], i[[SZ]]* [[SIZES_ARG2]], i32* getelementptr inbounds ([9 x i32], [9 x i32]* [[MAPT2]], i32 0, i32 0))
+
+ // make sure that firstprivate variables are generated in all cases and that we use those instances for operations inside the
+ // target region
+ // TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A2_IN:%.+]], [10 x float]* {{.+}} [[B_IN:%.+]], i{{[0-9]+}} [[BN_SZ:%.+]], float* {{.+}} [[BN_IN:%.+]], [5 x [10 x double]]* {{.+}} [[C_IN:%.+]], i{{[0-9]+}} [[CN_SZ1:%.+]], i{{[0-9]+}} [[CN_SZ2:%.+]], double* {{.+}} [[CN_IN:%.+]], [[TT]]* {{.+}} [[D_IN:%.+]])
+ // TCHECK: [[A2_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // TCHECK: [[B_ADDR:%.+]] = alloca [10 x float]*,
+ // TCHECK: [[VLA_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // TCHECK: [[BN_ADDR:%.+]] = alloca float*,
+ // TCHECK: [[C_ADDR:%.+]] = alloca [5 x [10 x double]]*,
+ // TCHECK: [[VLA_ADDR2:%.+]] = alloca i{{[0-9]+}},
+ // TCHECK: [[VLA_ADDR4:%.+]] = alloca i{{[0-9]+}},
+ // TCHECK: [[CN_ADDR:%.+]] = alloca double*,
+ // TCHECK: [[D_ADDR:%.+]] = alloca [[TT]]*,
+ // TCHECK-NOT: alloca i{{[0-9]+}},
+ // TCHECK: [[B_PRIV:%.+]] = alloca [10 x float],
+ // TCHECK: [[SSTACK:%.+]] = alloca i8*,
+ // TCHECK: [[C_PRIV:%.+]] = alloca [5 x [10 x double]],
+ // TCHECK: [[D_PRIV:%.+]] = alloca [[TT]],
+ // TCHECK: store i{{[0-9]+}} [[A2_IN]], i{{[0-9]+}}* [[A2_ADDR]],
+ // TCHECK: store [10 x float]* [[B_IN]], [10 x float]** [[B_ADDR]],
+ // TCHECK: store i{{[0-9]+}} [[BN_SZ]], i{{[0-9]+}}* [[VLA_ADDR]],
+ // TCHECK: store float* [[BN_IN]], float** [[BN_ADDR]],
+ // TCHECK: store [5 x [10 x double]]* [[C_IN]], [5 x [10 x double]]** [[C_ADDR]],
+ // TCHECK: store i{{[0-9]+}} [[CN_SZ1]], i{{[0-9]+}}* [[VLA_ADDR2]],
+ // TCHECK: store i{{[0-9]+}} [[CN_SZ2]], i{{[0-9]+}}* [[VLA_ADDR4]],
+ // TCHECK: store double* [[CN_IN]], double** [[CN_ADDR]],
+ // TCHECK: store [[TT]]* [[D_IN]], [[TT]]** [[D_ADDR]],
+ // TCHECK: [[CONV_A2ADDR:%.+]] = bitcast i{{[0-9]+}}* [[A2_ADDR]] to i{{[0-9]+}}*
+ // TCHECK: [[B_ADDR_REF:%.+]] = load [10 x float]*, [10 x float]** [[B_ADDR]],
+ // TCHECK: [[BN_SZ_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[VLA_ADDR]],
+ // TCHECK: [[BN_ADDR_REF:%.+]] = load float*, float** [[BN_ADDR]],
+ // TCHECK: [[C_ADDR_REF:%.+]] = load [5 x [10 x double]]*, [5 x [10 x double]]** [[C_ADDR]],
+ // TCHECK: [[CN_SZ1_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[VLA_ADDR2]],
+ // TCHECK: [[CN_SZ2_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[VLA_ADDR4]],
+ // TCHECK: [[CN_ADDR_REF:%.+]] = load double*, double** [[CN_ADDR]],
+ // TCHECK: [[D_ADDR_REF:%.+]] = load [[TT]]*, [[TT]]** [[D_ADDR]],
+
+ // firstprivate(aa): a_priv = a_in
+ // TCHECK-NOT: store i{{[0-9]+}} %
+
+ // firstprivate(b): memcpy(b_priv,b_in)
+ // TCHECK: [[B_PRIV_BCAST:%.+]] = bitcast [10 x float]* [[B_PRIV]] to i8*
+ // TCHECK: [[B_ADDR_REF_BCAST:%.+]] = bitcast [10 x float]* [[B_ADDR_REF]] to i8*
+ // TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[B_PRIV_BCAST]], i8* [[B_ADDR_REF_BCAST]], {{.+}})
+
+ // TCHECK: [[RET_STACK:%.+]] = call i8* @llvm.stacksave()
+ // TCHECK: store i8* [[RET_STACK]], i8** [[SSTACK]],
+
+ // firstprivate(bn)
+ // TCHECK: [[BN_PRIV:%.+]] = alloca float, i{{[0-9]+}} [[BN_SZ_VAL]],
+ // TCHECK: [[BN_COPY_SZ:%.+]] = mul{{.+}} i{{[0-9]+}} [[BN_SZ_VAL]], 4
+ // TCHECK: [[BN_PRIV__BCAST:%.+]] = bitcast float* [[BN_PRIV]] to i8*
+ // TCHECK: [[BN_REF_IN_BCAST:%.+]] = bitcast float* [[BN_ADDR_REF]] to i8*
+ // TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[BN_PRIV__BCAST]], i8* [[BN_REF_IN_BCAST]], i{{[0-9]+}} [[BN_COPY_SZ]],{{.+}})
+
+ // firstprivate(c)
+ // TCHECK: [[C_PRIV_BCAST:%.+]] = bitcast [5 x [10 x double]]* [[C_PRIV]] to i8*
+ // TCHECK: [[C_IN_BCAST:%.+]] = bitcast [5 x [10 x double]]* [[C_ADDR_REF]] to i8*
+ // TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[C_PRIV_BCAST]], i8* [[C_IN_BCAST]],{{.+}})
+
+ // firstprivate(cn)
+ // TCHECK: [[CN_SZ:%.+]] = mul{{.+}} i{{[0-9]+}} [[CN_SZ1_VAL]], [[CN_SZ2_VAL]]
+ // TCHECK: [[CN_PRIV:%.+]] = alloca double, i{{[0-9]+}} [[CN_SZ]],
+ // TCHECK: [[CN_SZ2:%.+]] = mul{{.+}} i{{[0-9]+}} [[CN_SZ1_VAL]], [[CN_SZ2_VAL]]
+ // TCHECK: [[CN_SZ2_CPY:%.+]] = mul{{.+}} i{{[0-9]+}} [[CN_SZ2]], 8
+ // TCHECK: [[CN_PRIV_BCAST:%.+]] = bitcast double* [[CN_PRIV]] to i8*
+ // TCHECK: [[CN_IN_BCAST:%.+]] = bitcast double* [[CN_ADDR_REF]] to i8*
+ // TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[CN_PRIV_BCAST]], i8* [[CN_IN_BCAST]], i{{[0-9]+}} [[CN_SZ2_CPY]],{{.+}})
+
+ // firstprivate(d)
+ // TCHECK: [[D_PRIV_BCAST:%.+]] = bitcast [[TT]]* [[D_PRIV]] to i8*
+ // TCHECK: [[D_IN_BCAST:%.+]] = bitcast [[TT]]* [[D_ADDR_REF]] to i8*
+ // TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[D_PRIV_BCAST]], i8* [[D_IN_BCAST]],{{.+}})
+
+
+ #pragma omp target firstprivate(ptr)
+ {
+ ptr[0]++;
+ }
+ // CHECK: [[PTR_ADDR_REF:%.+]] = load double*, double** [[PTR_ADDR]],
+ // CHECK: [[PTR_ADDR_BCAST:%.+]] = bitcast double* [[PTR_ADDR_REF]] to i8*
+
+ // CHECK: [[BASE_PTR_GEP3_0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BASE_PTR_ARR3]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: store i8* [[PTR_ADDR_BCAST]], i8** [[BASE_PTR_GEP3_0]],
+ // CHECK: [[PTR_ADDR_BCAST2:%.+]] = bitcast double* [[PTR_ADDR_REF]] to i8*
+ // CHECK: [[PTR_GEP3_0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PTR_ARR3]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: store i8* [[PTR_ADDR_BCAST2]], i8** [[PTR_GEP3_0]],
+
+ // CHECK: [[BASE_PTR_GEP_ARG3:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BASE_PTR_ARR3]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[PTR_GEP_ARG3:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PTR_ARR3]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: {{.+}} = call i32 @__tgt_target(i32 -1, {{.+}}, i32 1, i8** [[BASE_PTR_GEP_ARG3]], i8** [[PTR_GEP_ARG3]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i32* getelementptr inbounds ([1 x i32], [1 x i32]* [[MAPT3]], i32 0, i32 0))
+
+ // TCHECK: define void @__omp_offloading_{{.+}}(double* [[PTR_IN:%.+]])
+ // TCHECK: [[PTR_ADDR:%.+]] = alloca double*,
+ // TCHECK-NOT: alloca double*,
+ // TCHECK: store double* [[PTR_IN]], double** [[PTR_ADDR]],
+ // TCHECK-NOT: store double* %
+
+ return a;
+}
+
+
+template<typename tx>
+tx ftemplate(int n) {
+ tx a = 0;
+ tx b[10];
+
+#pragma omp target firstprivate(a,b)
+ {
+ a += 1;
+ b[2] += 1;
+ }
+
+ return a;
+}
+
+static
+int fstatic(int n) {
+ int a = 0;
+ char aaa = 0;
+ int b[10];
+
+#pragma omp target firstprivate(a,aaa,b)
+ {
+ a += 1;
+ aaa += 1;
+ b[2] += 1;
+ }
+
+ return a;
+}
+
+// TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A_IN:%.+]], i{{[0-9]+}} [[A3_IN:%.+]], [10 x i{{[0-9]+}}]*{{.+}} [[B_IN:%.+]])
+// TCHECK: [[A_ADDR:%.+]] = alloca i{{[0-9]+}},
+// TCHECK: [[A3_ADDR:%.+]] = alloca i{{[0-9]+}},
+// TCHECK: [[B_ADDR:%.+]] = alloca [10 x i{{[0-9]+}}]*,
+// TCHECK-NOT: alloca i{{[0-9]+}},
+// TCHECK: [[B_PRIV:%.+]] = alloca [10 x i{{[0-9]+}}],
+// TCHECK: store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[A_ADDR]],
+// TCHECK: store i{{[0-9]+}} [[A3_IN]], i{{[0-9]+}}* [[A3_ADDR]],
+// TCHECK: store [10 x i{{[0-9]+}}]* [[B_IN]], [10 x i{{[0-9]+}}]** [[B_ADDR]],
+// TCHECK-64: [[A_CONV:%.+]] = bitcast i{{[0-9]+}}* [[A_ADDR]] to i{{[0-9]+}}*
+// TCHECK: [[A3_CONV:%.+]] = bitcast i{{[0-9]+}}* [[A3_ADDR]] to i8*
+// TCHECK: [[B_ADDR_REF:%.+]] = load [10 x i{{[0-9]+}}]*, [10 x i{{[0-9]+}}]** [[B_ADDR]],
+
+// firstprivate(a): a_priv = a_in
+
+// firstprivate(aaa)
+// TCHECK-NOT: store i{{[0-9]+}} %
+
+// firstprivate(b)
+// TCHECK: [[B_PRIV_BCAST:%.+]] = bitcast [10 x i{{[0-9]+}}]* [[B_PRIV]] to i8*
+// TCHECK: [[B_IN_BCAST:%.+]] = bitcast [10 x i{{[0-9]+}}]* [[B_ADDR_REF]] to i8*
+// TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[B_PRIV_BCAST]], i8* [[B_IN_BCAST]],{{.+}})
+
+// TCHECK: ret void
+
+struct S1 {
+ double a;
+
+ int r1(int n){
+ int b = n+1;
+ short int c[2][n];
+
+#pragma omp target firstprivate(b,c)
+ {
+ this->a = (double)b + 1.5;
+ c[1][1] = ++a;
+ }
+
+ return c[1][1] + (int)b;
+ }
+
+ // on the host side, we first generate r1, then the static function and the template above
+ // CHECK: define{{.+}} i32 {{.+}}([[S1]]* {{.+}}, i{{[0-9]+}} {{.+}})
+ // CHECK: [[BASE_PTRS4:%.+]] = alloca [5 x i8*],
+ // CHECK: [[PTRS4:%.+]] = alloca [5 x i8*],
+ // CHECK: [[SIZET4:%.+]] = alloca [5 x i{{[0-9]+}}],
+
+ // map(this: this ptr is implicitly captured (not firstprivate matter)
+ // CHECK: {{.+}} = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BASE_PTRS4]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: store {{.+}}, {{.+}},
+ // CHECK: {{.+}} = getelementptr inbounds [5 x i8*], [5 x i8*]* [[PTRS4]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: store {{.+}}, {{.+}},
+ // CHECK: {{.+}} getelementptr inbounds [5 x i{{[0-9]+}}], [5 x i{{[0-9]+}}]* [[SIZET4]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: store {{.+}}, {{.+}}
+
+ // firstprivate(b): base_ptr = b, ptr = b, size = 4 (pass by-value)
+ // CHECK: [[B_CAST_PTR:%.+]] = inttoptr i{{[0-9]+}} [[B_CAST:%.+]] to i8*
+ // CHECK: [[BASE_PTRS_GEP4_1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BASE_PTRS4]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: store i8* [[B_CAST_PTR]], i8** [[BASE_PTRS_GEP4_1]],
+ // CHECK: [[B_CAST_PTR2:%.+]] = inttoptr i{{[0-9]+}} [[B_CAST:%.+]] to i8*
+ // CHECK: [[PTRS_GEP4_1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[PTRS4]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: store i8* [[B_CAST_PTR2]], i8** [[PTRS_GEP4_1]],
+ // CHECK: [[SIZES_GEP4_1:%.+]] = getelementptr inbounds [5 x i{{[0-9]+}}], [5 x i{{[0-9]+}}]* [[SIZET4]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIZES_GEP4_1]],
+
+ // firstprivate(c), 3 entries: 2, n, c
+ // CHECK: [[BASE_PTRS_GEP4_2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BASE_PTRS4]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // CHECK: store i8* inttoptr (i{{[0-9]+}} 2 to i8*), i8** [[BASE_PTRS_GEP4_2]],
+ // CHECK: [[PTRS_GEP4_2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[PTRS4]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // CHECK: store i8* inttoptr (i{{[0-9]+}} 2 to i8*), i8** [[PTRS_GEP4_2]],
+ // CHECK: [[SIZES_GEP4_2:%.+]] = getelementptr inbounds [5 x i{{[0-9]+}}], [5 x i{{[0-9]+}}]* [[SIZET4]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // CHECK-64: store i{{[0-9]+}} 8, i{{[0-9]+}}* [[SIZES_GEP4_2]],
+ // CHECK-32: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIZES_GEP4_2]],
+ // CHECK: [[N_PTR:%.+]] = inttoptr i{{[0-9]+}} [[N:%.+]] to i8*
+ // CHECK: [[BASE_PTRS_GEP4_3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BASE_PTRS4]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // CHECK: store i8* [[N_PTR]], i8** [[BASE_PTRS_GEP4_3]],
+ // CHECK: [[N_PTR2:%.+]] = inttoptr i{{[0-9]+}} [[N:%.+]] to i8*
+ // CHECK: [[PTRS_GEP4_3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[PTRS4]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // CHECK: store i8* [[N_PTR2]], i8** [[PTRS_GEP4_3]],
+ // CHECK: [[SIZES_GEP4_3:%.+]] = getelementptr inbounds [5 x i{{[0-9]+}}], [5 x i{{[0-9]+}}]* [[SIZET4]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // CHECK-64: store i{{[0-9]+}} 8, i{{[0-9]+}}* [[SIZES_GEP4_3]],
+ // CHECK-32: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIZES_GEP4_3]],
+ // CHECK: [[B_BCAST:%.+]] = bitcast i{{[0-9]+}}* [[B:%.+]] to i8*
+ // CHECK: [[BASE_PTRS_GEP4_4:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BASE_PTRS4]], i{{[0-9]+}} 0, i{{[0-9]+}} 4
+ // CHECK: store i8* [[B_BCAST]], i8** [[BASE_PTRS_GEP4_4]],
+ // CHECK: [[B_BCAST2:%.+]] = bitcast i{{[0-9]+}}* [[B:%.+]] to i8*
+ // CHECK: [[PTRS_GEP4_4:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[PTRS4]], i{{[0-9]+}} 0, i{{[0-9]+}} 4
+ // CHECK: store i8* [[B_BCAST2]], i8** [[PTRS_GEP4_4]],
+ // CHECK: [[SIZES_GEP4_4:%.+]] = getelementptr inbounds [5 x i{{[0-9]+}}], [5 x i{{[0-9]+}}]* [[SIZET4]], i{{[0-9]+}} 0, i{{[0-9]+}} 4
+ // CHECK: store i{{[0-9]+}} [[B_SIZE:%.+]], i{{[0-9]+}}* [[SIZES_GEP4_4]],
+
+ // only check that we use the map types stored in the global variable
+ // CHECK: call i32 @__tgt_target(i32 -1, {{.+}}, i32 5, i8** {{.+}}, i8** {{.+}}, i{{[0-9]+}}* {{.+}}, i32* getelementptr inbounds ([5 x i32], [5 x i32]* [[MAPT4]], i32 0, i32 0))
+
+ // TCHECK: define void @__omp_offloading_{{.+}}([[S1]]* [[TH:%.+]], i{{[0-9]+}} [[B_IN:%.+]], i{{[0-9]+}} [[VLA:%.+]], i{{[0-9]+}} [[VLA1:%.+]], i{{[0-9]+}}{{.+}} [[C_IN:%.+]])
+ // TCHECK: [[TH_ADDR:%.+]] = alloca [[S1]]*,
+ // TCHECK: [[B_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // TCHECK: [[VLA_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // TCHECK: [[VLA_ADDR2:%.+]] = alloca i{{[0-9]+}},
+ // TCHECK: [[C_ADDR:%.+]] = alloca i{{[0-9]+}}*,
+ // TCHECK-NOT: alloca i{{[0-9]+}},
+ // TCHECK: [[SSTACK:%.+]] = alloca i8*,
+
+ // TCHECK: store [[S1]]* [[TH]], [[S1]]** [[TH_ADDR]],
+ // TCHECK: store i{{[0-9]+}} [[B_IN]], i{{[0-9]+}}* [[B_ADDR]],
+ // TCHECK: store i{{[0-9]+}} [[VLA]], i{{[0-9]+}}* [[VLA_ADDR]],
+ // TCHECK: store i{{[0-9]+}} [[VLA1]], i{{[0-9]+}}* [[VLA_ADDR2]],
+ // TCHECK: store i{{[0-9]+}}* [[C_IN]], i{{[0-9]+}}** [[C_ADDR]],
+ // TCHECK: [[TH_ADDR_REF:%.+]] = load [[S1]]*, [[S1]]** [[TH_ADDR]],
+ // TCHECK-64: [[B_ADDR_CONV:%.+]] = bitcast i{{[0-9]+}}* [[B_ADDR]] to i{{[0-9]+}}*
+ // TCHECK: [[VLA_ADDR_REF:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[VLA_ADDR]],
+ // TCHECK: [[VLA_ADDR_REF2:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[VLA_ADDR2]],
+ // TCHECK: [[C_ADDR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[C_ADDR]],
+
+ // firstprivate(b)
+ // TCHECK-NOT: store i{{[0-9]+}} %
+
+ // TCHECK: [[RET_STACK:%.+]] = call i8* @llvm.stacksave()
+ // TCHECK: store i8* [[RET_STACK:%.+]], i8** [[SSTACK]],
+
+ // firstprivate(c)
+ // TCHECK: [[C_SZ:%.+]] = mul{{.+}} i{{[0-9]+}} [[VLA_ADDR_REF]], [[VLA_ADDR_REF2]]
+ // TCHECK: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, i{{[0-9]+}} [[C_SZ]],
+ // TCHECK: [[C_SZ2:%.+]] = mul{{.+}} i{{[0-9]+}} [[VLA_ADDR_REF]], [[VLA_ADDR_REF2]]
+ // TCHECK: [[C_SZ_CPY:%.+]] = mul{{.+}} i{{[0-9]+}} [[C_SZ2]], 2
+ // TCHECK: [[C_PRIV_BCAST:%.+]] = bitcast i{{[0-9]+}}* [[C_PRIV]] to i8*
+ // TCHECK: [[C_IN_BCAST:%.+]] = bitcast i{{[0-9]+}}* [[C_ADDR_REF]] to i8*
+ // TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[C_PRIV_BCAST]], i8* [[C_IN_BCAST]],{{.+}})
+
+ // finish
+ // TCHECK: [[RELOAD_SSTACK:%.+]] = load i8*, i8** [[SSTACK]],
+ // TCHECK: call void @llvm.stackrestore(i8* [[RELOAD_SSTACK]])
+ // TCHECK: ret void
+
+
+ // static host function
+ // CHECK: define{{.+}} i32 {{.+}}(i{{[0-9]+}} {{.+}})
+ // CHECK: [[BASE_PTRS5:%.+]] = alloca [3 x i8*],
+ // CHECK: [[PTRS5:%.+]] = alloca [3 x i8*],
+
+ // firstprivate(a): by value
+ // CHECK: [[A_CAST_PTR:%.+]] = inttoptr i{{[0-9]+}} [[A_CAST:%.+]] to i8*
+ // CHECK: [[BASE_PTRS_GEP5_0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BASE_PTRS5]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: store i8* [[A_CAST_PTR]], i8** [[BASE_PTRS_GEP5_0]],
+ // CHECK: [[A_CAST_PTR2:%.+]] = inttoptr i{{[0-9]+}} [[A_CAST:%.+]] to i8*
+ // CHECK: [[PTRS_GEP5_0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PTRS5]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: store i8* [[A_CAST_PTR2]], i8** [[PTRS_GEP5_0]],
+
+ // firstprivate(aaa): by value
+ // CHECK: [[A3_CAST_PTR:%.+]] = inttoptr i{{[0-9]+}} [[A3_CAST:%.+]] to i8*
+ // CHECK: [[BASE_PTRS_GEP5_1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BASE_PTRS5]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: store i8* [[A3_CAST_PTR]], i8** [[BASE_PTRS_GEP5_1]],
+ // CHECK: [[A3_CAST_PTR2:%.+]] = inttoptr i{{[0-9]+}} [[A3_CAST:%.+]] to i8*
+ // CHECK: [[PTRS_GEP5_1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PTRS5]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: store i8* [[A3_CAST_PTR2]], i8** [[PTRS_GEP5_1]],
+
+ // firstprivate(b): base_ptr = &b[0], ptr= &b[0]
+ // CHECK: [[B_BCAST:%.+]] = bitcast [10 x i{{[0-9]+}}]* [[B:%.+]] to i8*
+ // CHECK: [[BASE_PTRS_GEP5_2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BASE_PTRS5]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // CHECK: store i8* [[B_BCAST]], i8** [[BASE_PTRS_GEP5_2]],
+ // CHECK: [[B_BCAST2:%.+]] = bitcast [10 x i{{[0-9]+}}]* [[B:%.+]] to i8*
+ // CHECK: [[PTRS_GEP5_2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PTRS5]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // CHECK: store i8* [[B_BCAST2]], i8** [[PTRS_GEP5_2]],
+
+ // only check that the right sizes and map types are used
+ // CHECK: call i32 @__tgt_target(i32 -1, {{.+}}, i32 3, i8** {{.+}}, i8** {{.+}}, i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET5]], i32 0, i32 0), i32* getelementptr inbounds ([3 x i32], [3 x i32]* [[MAPT5]], i32 0, i32 0))
+};
+
+
+
+int bar(int n, double *ptr){
+ int a = 0;
+ a += foo(n, ptr);
+ S1 S;
+ a += S.r1(n);
+ a += fstatic(n);
+ a += ftemplate<int>(n);
+
+ return a;
+}
+
+// template host and device
+
+// CHECK: define{{.+}} i32 {{.+}}(i{{[0-9]+}} {{.+}})
+// CHECK: [[BASE_PTRS6:%.+]] = alloca [2 x i8*],
+// CHECK: [[PTRS6:%.+]] = alloca [2 x i8*],
+
+// firstprivate(a): by value
+// CHECK: [[AT_CAST_PTR:%.+]] = inttoptr i{{[0-9]+}} [[AT_CAST:%.+]] to i8*
+// CHECK: [[BASE_PTRS_GEP6_0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BASE_PTRS6]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: store i8* [[AT_CAST_PTR]], i8** [[BASE_PTRS_GEP6_0]],
+// CHECK: [[AT_CAST_PTR2:%.+]] = inttoptr i{{[0-9]+}} [[AT_CAST:%.+]] to i8*
+// CHECK: [[PTRS_GEP6_0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[PTRS6]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: store i8* [[AT_CAST_PTR2]], i8** [[PTRS_GEP6_0]],
+
+// firstprivate(b): pointer
+// CHECK: [[B_BCAST:%.+]] = bitcast [10 x i{{[0-9]+}}]* [[B:%.+]] to i8*
+// CHECK: [[BASE_PTRS_GEP6_1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BASE_PTRS6]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+// CHECK: store i8* [[B_BCAST]], i8** [[BASE_PTRS_GEP6_1]],
+// CHECK: [[B_BCAST2:%.+]] = bitcast [10 x i{{[0-9]+}}]* [[B:%.+]] to i8*
+// CHECK: [[PTRS_GEP6_1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[PTRS6]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+// CHECK: store i8* [[B_BCAST2]], i8** [[PTRS_GEP6_1]],
+
+// CHECK: call i32 @__tgt_target(i32 -1, {{.+}}, i32 2, i8** {{.+}}, i8** {{.+}}, i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET6]], i32 0, i32 0), i32* getelementptr inbounds ([2 x i32], [2 x i32]* [[MAPT6]], i32 0, i32 0))
+
+
+// TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A_IN:%.+]], [10 x i{{[0-9]+}}]*{{.+}} [[B_IN:%.+]])
+// TCHECK: [[A_ADDR:%.+]] = alloca i{{[0-9]+}},
+// TCHECK: [[B_ADDR:%.+]] = alloca [10 x i{{[0-9]+}}]*,
+// TCHECK-NOT: alloca i{{[0-9]+}},
+// TCHECK: [[B_PRIV:%.+]] = alloca [10 x i{{[0-9]+}}],
+// TCHECK: store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[A_ADDR]],
+// TCHECK: store [10 x i{{[0-9]+}}]* [[B_IN]], [10 x i{{[0-9]+}}]** [[B_ADDR]],
+// TCHECK-64: [[A_ADDR_CONV:%.+]] = bitcast i{{[0-9]+}}* [[A_ADDR]] to i{{[0-9]+}}*
+// TCHECK: [[B_ADDR_REF:%.+]] = load [10 x i{{[0-9]+}}]*, [10 x i{{[0-9]+}}]** [[B_ADDR]],
+
+// firstprivate(a)
+// TCHECK-NOT: store i{{[0-9]+}} %
+
+// firstprivate(b)
+// TCHECK: [[B_PRIV_BCAST:%.+]] = bitcast [10 x i{{[0-9]+}}]* [[B_PRIV]] to i8*
+// TCHECK: [[B_IN_BCAST:%.+]] = bitcast [10 x i{{[0-9]+}}]* [[B_ADDR_REF]] to i8*
+// TCHECK: call void @llvm.memcpy.{{.+}}(i8* [[B_PRIV_BCAST]], i8* [[B_IN_BCAST]],{{.+}})
+
+// TCHECK: ret void
+
+#endif
diff --git a/test/OpenMP/target_firstprivate_messages.cpp b/test/OpenMP/target_firstprivate_messages.cpp
new file mode 100644
index 0000000000000..6dbad671de7c6
--- /dev/null
+++ b/test/OpenMP/target_firstprivate_messages.cpp
@@ -0,0 +1,198 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+
+public:
+ S2() : a(0) {}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+
+public:
+ S3() : a(0) {}
+};
+const S3 ca[5];
+class S4 {
+ int a;
+ S4();
+
+public:
+ S4(int v) : a(v) {
+#pragma omp target firstprivate(a) firstprivate(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+};
+class S5 {
+ int a;
+ S5() : a(0) {}
+
+public:
+ S5(int v) : a(v) {}
+ S5 &operator=(S5 &s) {
+#pragma omp target firstprivate(a) firstprivate(this->a) firstprivate(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S6 {
+public:
+ T a;
+
+ S6() : a(0) {}
+ S6(T v) : a(v) {
+#pragma omp target firstprivate(a) firstprivate(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+ S6 &operator=(S6 &s) {
+#pragma omp target firstprivate(a) firstprivate(this->a) firstprivate(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S7 : public T {
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(T v) : a(v) {
+#pragma omp target firstprivate(a) firstprivate(this->a) firstprivate(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp target firstprivate(a) firstprivate(this->a) firstprivate(s.a) firstprivate(s.T::a) // expected-error 2 {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(I argc, C **argv) {
+ I e(4);
+ I g(5);
+ int i;
+ int &j = i;
+#pragma omp target firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+{}
+#pragma omp target firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+{}
+#pragma omp target firstprivate() // expected-error {{expected expression}}
+{}
+#pragma omp target firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+{}
+#pragma omp target firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+{}
+#pragma omp target firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+{}
+#pragma omp target firstprivate(argc)
+{}
+#pragma omp target firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+{}
+#pragma omp target firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+{}
+#pragma omp target firstprivate(argv[1]) // expected-error {{expected variable name}}
+{}
+#pragma omp target firstprivate(e, g)
+{}
+#pragma omp target firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+{}
+#pragma omp target shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp target'}}
+#pragma omp parallel
+ {
+ int v = 0;
+ int i;
+ }
+#pragma omp parallel shared(i)
+#pragma omp parallel firstprivate(i)
+#pragma omp target firstprivate(j)
+{}
+#pragma omp target firstprivate(i)
+ {}
+ return 0;
+}
+
+void bar(S4 a[2]) {
+#pragma omp parallel
+#pragma omp target firstprivate(a)
+ {}
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ S4 e(4);
+ S5 g(5);
+ S6<float> s6(0.0) , s6_0(1.0);
+ S7<S6<float> > s7(0.0) , s7_0(1.0);
+ int i;
+ int &j = i;
+#pragma omp target firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+{}
+#pragma omp target firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+{}
+#pragma omp target firstprivate() // expected-error {{expected expression}}
+{}
+#pragma omp target firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+{}
+#pragma omp target firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+{}
+#pragma omp target firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+{}
+#pragma omp target firstprivate(argc)
+{}
+#pragma omp target firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+{}
+#pragma omp target firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+{}
+#pragma omp target firstprivate(argv[1]) // expected-error {{expected variable name}}
+{}
+#pragma omp target firstprivate(e, g)
+{}
+#pragma omp target firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+{}
+#pragma omp target firstprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+{}
+#pragma omp target shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp target'}}
+#pragma omp parallel
+ {
+ int i;
+ }
+#pragma omp parallel shared(i)
+#pragma omp parallel firstprivate(i)
+#pragma omp target firstprivate(j)
+{}
+#pragma omp target firstprivate(i)
+ {}
+ static int si;
+#pragma omp target firstprivate(si) // OK
+ {}
+#pragma omp target map(i) firstprivate(i) // expected-error {{firstprivate variable cannot be in a map clause in '#pragma omp target' directive}}
+ {}
+ s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}}
+ s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}}
+ return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
+}
+
diff --git a/test/OpenMP/target_if_messages.cpp b/test/OpenMP/target_if_messages.cpp
index 4ee7302282f6c..189256e60fea2 100644
--- a/test/OpenMP/target_if_messages.cpp
+++ b/test/OpenMP/target_if_messages.cpp
@@ -12,21 +12,37 @@ struct S1; // expected-note {{declared here}}
template <class T, class S> // expected-note {{declared here}}
int tmain(T argc, S **argv) {
#pragma omp target if // expected-error {{expected '(' after 'if'}}
+ foo();
#pragma omp target if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
#pragma omp target if () // expected-error {{expected expression}}
+ foo();
#pragma omp target if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
#pragma omp target if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}}
+ foo();
#pragma omp target if (argc > 0 ? argv[1] : argv[2])
+ foo();
#pragma omp target if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target' cannot contain more than one 'if' clause}}
+ foo();
#pragma omp target if (S) // expected-error {{'S' does not refer to a value}}
+ foo();
#pragma omp target if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
#pragma omp target if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
#pragma omp target if(argc)
+ foo();
#pragma omp target if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
#pragma omp target if(target : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
#pragma omp target if(target : argc)
+ foo();
#pragma omp target if(target : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target'}}
+ foo();
#pragma omp target if(target : argc) if (target:argc) // expected-error {{directive '#pragma omp target' cannot contain more than one 'if' clause with 'target' name modifier}}
+ foo();
#pragma omp target if(target : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}}
foo();
@@ -35,22 +51,39 @@ int tmain(T argc, S **argv) {
int main(int argc, char **argv) {
#pragma omp target if // expected-error {{expected '(' after 'if'}}
+ foo();
#pragma omp target if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
#pragma omp target if () // expected-error {{expected expression}}
+ foo();
#pragma omp target if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
#pragma omp target if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}}
+ foo();
#pragma omp target if (argc > 0 ? argv[1] : argv[2])
+ foo();
#pragma omp target if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target' cannot contain more than one 'if' clause}}
+ foo();
#pragma omp target if (S1) // expected-error {{'S1' does not refer to a value}}
+ foo();
#pragma omp target if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
#pragma omp target if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
#pragma omp target if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
#pragma omp target if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
#pragma omp target if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
#pragma omp target if(target : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
#pragma omp target if(target : argc)
+ foo();
#pragma omp target if(target : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target'}}
+ foo();
#pragma omp target if(target : argc) if (target:argc) // expected-error {{directive '#pragma omp target' cannot contain more than one 'if' clause with 'target' name modifier}}
+ foo();
#pragma omp target if(target : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}}
foo();
diff --git a/test/OpenMP/target_is_device_ptr_ast_print.cpp b/test/OpenMP/target_is_device_ptr_ast_print.cpp
new file mode 100644
index 0000000000000..f519235a0b365
--- /dev/null
+++ b/test/OpenMP/target_is_device_ptr_ast_print.cpp
@@ -0,0 +1,294 @@
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+struct ST {
+ int *a;
+};
+typedef int arr[10];
+typedef ST STarr[10];
+struct SA {
+ const int da[5] = { 0 };
+ ST g[10];
+ STarr &rg = g;
+ int i;
+ int &j = i;
+ int *k = &j;
+ int *&z = k;
+ int aa[10];
+ arr &raa = aa;
+ void func(int arg) {
+#pragma omp target is_device_ptr(k)
+ {}
+#pragma omp target is_device_ptr(z)
+ {}
+#pragma omp target is_device_ptr(aa) // OK
+ {}
+#pragma omp target is_device_ptr(raa) // OK
+ {}
+#pragma omp target is_device_ptr(g) // OK
+ {}
+#pragma omp target is_device_ptr(rg) // OK
+ {}
+#pragma omp target is_device_ptr(da) // OK
+ {}
+ return;
+ }
+};
+// CHECK: struct SA
+// CHECK-NEXT: const int da[5] = {0};
+// CHECK-NEXT: ST g[10];
+// CHECK-NEXT: STarr &rg = this->g;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = this->i;
+// CHECK-NEXT: int *k = &this->j;
+// CHECK-NEXT: int *&z = this->k;
+// CHECK-NEXT: int aa[10];
+// CHECK-NEXT: arr &raa = this->aa;
+// CHECK-NEXT: func(
+// CHECK-NEXT: #pragma omp target is_device_ptr(this->k)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target is_device_ptr(this->z)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target is_device_ptr(this->aa)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target is_device_ptr(this->raa)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target is_device_ptr(this->g)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target is_device_ptr(this->rg)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target is_device_ptr(this->da)
+
+struct SB {
+ unsigned A;
+ unsigned B;
+ float Arr[100];
+ float *Ptr;
+ float *foo() {
+ return &Arr[0];
+ }
+};
+
+struct SC {
+ unsigned A : 2;
+ unsigned B : 3;
+ unsigned C;
+ unsigned D;
+ float Arr[100];
+ SB S;
+ SB ArrS[100];
+ SB *PtrS;
+ SB *&RPtrS;
+ float *Ptr;
+
+ SC(SB *&_RPtrS) : RPtrS(_RPtrS) {}
+};
+
+union SD {
+ unsigned A;
+ float B;
+};
+
+struct S1;
+extern S1 a;
+class S2 {
+ mutable int a;
+public:
+ S2():a(0) { }
+ S2(S2 &s2):a(s2.a) { }
+ static float S2s;
+ static const float S2sc;
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+public:
+ S3():a(0) { }
+ S3(S3 &s3):a(s3.a) { }
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 {
+ int a;
+ S4();
+ S4(const S4 &s4);
+public:
+ S4(int v):a(v) { }
+};
+class S5 {
+ int a;
+ S5():a(0) {}
+ S5(const S5 &s5):a(s5.a) { }
+public:
+ S5(int v):a(v) { }
+};
+
+S3 h;
+#pragma omp threadprivate(h)
+
+typedef struct {
+ int a;
+} S6;
+
+template <typename T>
+T tmain(T argc) {
+ const T da[5] = { 0 };
+ S6 h[10];
+ auto &rh = h;
+ T i;
+ T &j = i;
+ T *k = &j;
+ T *&z = k;
+ T aa[10];
+ auto &raa = aa;
+#pragma omp target is_device_ptr(k)
+ {}
+#pragma omp target is_device_ptr(z)
+ {}
+#pragma omp target is_device_ptr(aa)
+ {}
+#pragma omp target is_device_ptr(raa)
+ {}
+#pragma omp target is_device_ptr(h)
+ {}
+#pragma omp target is_device_ptr(rh)
+ {}
+#pragma omp target is_device_ptr(da)
+ {}
+ return 0;
+}
+
+// CHECK: template <typename T = int> int tmain(int argc) {
+// CHECK-NEXT: const int da[5] = {0};
+// CHECK-NEXT: S6 h[10];
+// CHECK-NEXT: auto &rh = h;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = i;
+// CHECK-NEXT: int *k = &j;
+// CHECK-NEXT: int *&z = k;
+// CHECK-NEXT: int aa[10];
+// CHECK-NEXT: auto &raa = aa;
+// CHECK-NEXT: #pragma omp target is_device_ptr(k)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target is_device_ptr(z)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target is_device_ptr(aa)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target is_device_ptr(raa)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target is_device_ptr(h)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target is_device_ptr(rh)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target is_device_ptr(da)
+
+// CHECK: template <typename T = int *> int *tmain(int *argc) {
+// CHECK-NEXT: int *const da[5] = {0};
+// CHECK-NEXT: S6 h[10];
+// CHECK-NEXT: auto &rh = h;
+// CHECK-NEXT: int *i;
+// CHECK-NEXT: int *&j = i;
+// CHECK-NEXT: int **k = &j;
+// CHECK-NEXT: int **&z = k;
+// CHECK-NEXT: int *aa[10];
+// CHECK-NEXT: auto &raa = aa;
+// CHECK-NEXT: #pragma omp target is_device_ptr(k)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target is_device_ptr(z)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target is_device_ptr(aa)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target is_device_ptr(raa)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target is_device_ptr(h)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target is_device_ptr(rh)
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp target is_device_ptr(da)
+
+// CHECK-LABEL: int main(int argc, char **argv) {
+int main(int argc, char **argv) {
+ const int da[5] = { 0 };
+ S6 h[10];
+ auto &rh = h;
+ int i;
+ int &j = i;
+ int *k = &j;
+ int *&z = k;
+ int aa[10];
+ auto &raa = aa;
+// CHECK-NEXT: const int da[5] = {0};
+// CHECK-NEXT: S6 h[10];
+// CHECK-NEXT: auto &rh = h;
+// CHECK-NEXT: int i;
+// CHECK-NEXT: int &j = i;
+// CHECK-NEXT: int *k = &j;
+// CHECK-NEXT: int *&z = k;
+// CHECK-NEXT: int aa[10];
+// CHECK-NEXT: auto &raa = aa;
+#pragma omp target is_device_ptr(k)
+// CHECK-NEXT: #pragma omp target is_device_ptr(k)
+ {}
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+#pragma omp target is_device_ptr(z)
+// CHECK-NEXT: #pragma omp target is_device_ptr(z)
+ {}
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+#pragma omp target is_device_ptr(aa)
+// CHECK-NEXT: #pragma omp target is_device_ptr(aa)
+ {}
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+#pragma omp target is_device_ptr(raa)
+// CHECK-NEXT: #pragma omp target is_device_ptr(raa)
+ {}
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+#pragma omp target is_device_ptr(h)
+// CHECK-NEXT: #pragma omp target is_device_ptr(h)
+ {}
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+#pragma omp target is_device_ptr(rh)
+// CHECK-NEXT: #pragma omp target is_device_ptr(rh)
+ {}
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+#pragma omp target is_device_ptr(da)
+// CHECK-NEXT: #pragma omp target is_device_ptr(da)
+ {}
+// CHECK-NEXT: {
+// CHECK-NEXT: }
+ return tmain<int>(argc) + *tmain<int *>(&argc);
+}
+
+
+#endif
diff --git a/test/OpenMP/target_is_device_ptr_messages.cpp b/test/OpenMP/target_is_device_ptr_messages.cpp
new file mode 100644
index 0000000000000..634e16114e1be
--- /dev/null
+++ b/test/OpenMP/target_is_device_ptr_messages.cpp
@@ -0,0 +1,234 @@
+// RUN: %clang_cc1 -std=c++11 -verify -fopenmp -ferror-limit 200 %s
+struct ST {
+ int *a;
+};
+typedef int arr[10];
+typedef ST STarr[10];
+struct SA {
+ const int d = 5;
+ const int da[5] = { 0 };
+ ST e;
+ ST g[10];
+ STarr &rg = g;
+ int i;
+ int &j = i;
+ int *k = &j;
+ int *&z = k;
+ int aa[10];
+ arr &raa = aa;
+ void func(int arg) {
+#pragma omp target is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}}
+ {}
+#pragma omp target is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+ {}
+#pragma omp target is_device_ptr() // expected-error {{expected expression}}
+ {}
+#pragma omp target is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+ {}
+#pragma omp target is_device_ptr(arg // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+ {}
+#pragma omp target is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+ {}
+#pragma omp target is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+ {}
+#pragma omp target is_device_ptr(k) // OK
+ {}
+#pragma omp target is_device_ptr(z) // OK
+ {}
+#pragma omp target is_device_ptr(aa) // OK
+ {}
+#pragma omp target is_device_ptr(raa) // OK
+ {}
+#pragma omp target is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+ {}
+#pragma omp target is_device_ptr(g) // OK
+ {}
+#pragma omp target is_device_ptr(rg) // OK
+ {}
+#pragma omp target is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+ {}
+#pragma omp target is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+ {}
+#pragma omp target is_device_ptr(da) // OK
+ {}
+ return;
+ }
+};
+struct SB {
+ unsigned A;
+ unsigned B;
+ float Arr[100];
+ float *Ptr;
+ float *foo() {
+ return &Arr[0];
+ }
+};
+
+struct SC {
+ unsigned A : 2;
+ unsigned B : 3;
+ unsigned C;
+ unsigned D;
+ float Arr[100];
+ SB S;
+ SB ArrS[100];
+ SB *PtrS;
+ SB *&RPtrS;
+ float *Ptr;
+
+ SC(SB *&_RPtrS) : RPtrS(_RPtrS) {}
+};
+
+union SD {
+ unsigned A;
+ float B;
+};
+
+struct S1;
+extern S1 a;
+class S2 {
+ mutable int a;
+public:
+ S2():a(0) { }
+ S2(S2 &s2):a(s2.a) { }
+ static float S2s;
+ static const float S2sc;
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+public:
+ S3():a(0) { }
+ S3(S3 &s3):a(s3.a) { }
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 {
+ int a;
+ S4();
+ S4(const S4 &s4);
+public:
+ S4(int v):a(v) { }
+};
+class S5 {
+ int a;
+ S5():a(0) {}
+ S5(const S5 &s5):a(s5.a) { }
+public:
+ S5(int v):a(v) { }
+};
+
+S3 h;
+#pragma omp threadprivate(h)
+
+typedef struct {
+ int a;
+} S6;
+
+template <typename T, int I>
+T tmain(T argc) {
+ const T d = 5;
+ const T da[5] = { 0 };
+ S4 e(4);
+ S5 g(5);
+ S6 h[10];
+ auto &rh = h;
+ T i;
+ T &j = i;
+ T *k = &j;
+ T *&z = k;
+ T aa[10];
+ auto &raa = aa;
+#pragma omp target is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}}
+ {}
+#pragma omp target is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+ {}
+#pragma omp target is_device_ptr() // expected-error {{expected expression}}
+ {}
+#pragma omp target is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+ {}
+#pragma omp target is_device_ptr(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+ {}
+#pragma omp target is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+ {}
+#pragma omp target is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+ {}
+#pragma omp target is_device_ptr(k) // OK
+ {}
+#pragma omp target is_device_ptr(z) // OK
+ {}
+#pragma omp target is_device_ptr(aa) // OK
+ {}
+#pragma omp target is_device_ptr(raa) // OK
+ {}
+#pragma omp target is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+ {}
+#pragma omp target is_device_ptr(g) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+ {}
+#pragma omp target is_device_ptr(h) // OK
+ {}
+#pragma omp target is_device_ptr(rh) // OK
+ {}
+#pragma omp target is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+ {}
+#pragma omp target is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+ {}
+#pragma omp target is_device_ptr(da) // OK
+ {}
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5;
+ const int da[5] = { 0 };
+ S4 e(4);
+ S5 g(5);
+ S6 h[10];
+ auto &rh = h;
+ int i;
+ int &j = i;
+ int *k = &j;
+ int *&z = k;
+ int aa[10];
+ auto &raa = aa;
+#pragma omp target is_device_ptr // expected-error {{expected '(' after 'is_device_ptr'}}
+ {}
+#pragma omp target is_device_ptr( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+ {}
+#pragma omp target is_device_ptr() // expected-error {{expected expression}}
+ {}
+#pragma omp target is_device_ptr(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+ {}
+#pragma omp target is_device_ptr(argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+ {}
+#pragma omp target is_device_ptr(i) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+ {}
+#pragma omp target is_device_ptr(j) // expected-error {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+ {}
+#pragma omp target is_device_ptr(k) // OK
+ {}
+#pragma omp target is_device_ptr(z) // OK
+ {}
+#pragma omp target is_device_ptr(aa) // OK
+ {}
+#pragma omp target is_device_ptr(raa) // OK
+ {}
+#pragma omp target is_device_ptr(e) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+ {}
+#pragma omp target is_device_ptr(g) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+ {}
+#pragma omp target is_device_ptr(h) // OK
+ {}
+#pragma omp target is_device_ptr(rh) // OK
+ {}
+#pragma omp target is_device_ptr(k,i,j) // expected-error2 {{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+ {}
+#pragma omp target is_device_ptr(d) // expected-error{{expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'}}
+ {}
+#pragma omp target is_device_ptr(da) // OK
+ {}
+ return tmain<int, 3>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}}
+}
diff --git a/test/OpenMP/target_map_codegen.cpp b/test/OpenMP/target_map_codegen.cpp
index 942cc4c09fd30..626f68d5a2a94 100644
--- a/test/OpenMP/target_map_codegen.cpp
+++ b/test/OpenMP/target_map_codegen.cpp
@@ -7,17 +7,17 @@
///
///==========================================================================///
-// RUN: %clang_cc1 -DCK1 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
-// RUN: %clang_cc1 -DCK1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
-// RUN: %clang_cc1 -DCK1 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
-// RUN: %clang_cc1 -DCK1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
#ifdef CK1
// CK1-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4]
-// Map types: OMP_MAP_BYCOPY = 128
-// CK1-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 128]
+// Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288
+// CK1-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288]
// CK1-LABEL: implicit_maps_integer
void implicit_maps_integer (int a){
@@ -52,17 +52,17 @@ void implicit_maps_integer (int a){
#endif
///==========================================================================///
-// RUN: %clang_cc1 -DCK2 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
-// RUN: %clang_cc1 -DCK2 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
-// RUN: %clang_cc1 -DCK2 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
-// RUN: %clang_cc1 -DCK2 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
#ifdef CK2
// CK2-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4]
-// Map types: OMP_MAP_BYCOPY = 128
-// CK2-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 128]
+// Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288
+// CK2-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288]
// CK2-LABEL: implicit_maps_integer_reference
void implicit_maps_integer_reference (int a){
@@ -101,17 +101,17 @@ void implicit_maps_integer_reference (int a){
#endif
///==========================================================================///
-// RUN: %clang_cc1 -DCK3 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64
-// RUN: %clang_cc1 -DCK3 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64
-// RUN: %clang_cc1 -DCK3 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32
-// RUN: %clang_cc1 -DCK3 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32
+// RUN: %clang_cc1 -DCK3 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64
+// RUN: %clang_cc1 -DCK3 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64
+// RUN: %clang_cc1 -DCK3 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32
+// RUN: %clang_cc1 -DCK3 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32
#ifdef CK3
// CK3-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4]
-// Map types: OMP_MAP_BYCOPY = 128
-// CK3-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 128]
+// Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288
+// CK3-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288]
// CK3-LABEL: implicit_maps_parameter
void implicit_maps_parameter (int a){
@@ -145,17 +145,17 @@ void implicit_maps_parameter (int a){
#endif
///==========================================================================///
-// RUN: %clang_cc1 -DCK4 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64
-// RUN: %clang_cc1 -DCK4 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64
-// RUN: %clang_cc1 -DCK4 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32
-// RUN: %clang_cc1 -DCK4 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64
+// RUN: %clang_cc1 -DCK4 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32
+// RUN: %clang_cc1 -DCK4 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32
#ifdef CK4
// CK4-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4]
-// Map types: OMP_MAP_BYCOPY = 128
-// CK4-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 128]
+// Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288
+// CK4-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288]
// CK4-LABEL: implicit_maps_nested_integer
void implicit_maps_nested_integer (int a){
@@ -201,17 +201,17 @@ void implicit_maps_nested_integer (int a){
// CK4: define internal void [[KERNELP2]](i32* {{[^,]+}}, i32* {{[^,]+}}, i32* {{[^,]+}})
#endif
///==========================================================================///
-// RUN: %clang_cc1 -DCK5 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-64
-// RUN: %clang_cc1 -DCK5 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-64
-// RUN: %clang_cc1 -DCK5 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-32
-// RUN: %clang_cc1 -DCK5 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-32
+// RUN: %clang_cc1 -DCK5 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-64
+// RUN: %clang_cc1 -DCK5 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-64
+// RUN: %clang_cc1 -DCK5 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-32
+// RUN: %clang_cc1 -DCK5 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-32
#ifdef CK5
// CK5-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4]
-// Map types: OMP_MAP_BYCOPY = 128
-// CK5-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 128]
+// Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288
+// CK5-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288]
// CK5-LABEL: implicit_maps_nested_integer_and_enum
void implicit_maps_nested_integer_and_enum (int a){
@@ -252,17 +252,17 @@ void implicit_maps_nested_integer_and_enum (int a){
#endif
///==========================================================================///
-// RUN: %clang_cc1 -DCK6 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK6 --check-prefix CK6-64
-// RUN: %clang_cc1 -DCK6 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK6 --check-prefix CK6-64
-// RUN: %clang_cc1 -DCK6 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK6 --check-prefix CK6-32
-// RUN: %clang_cc1 -DCK6 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK6 --check-prefix CK6-32
+// RUN: %clang_cc1 -DCK6 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK6 --check-prefix CK6-64
+// RUN: %clang_cc1 -DCK6 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK6 --check-prefix CK6-64
+// RUN: %clang_cc1 -DCK6 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK6 --check-prefix CK6-32
+// RUN: %clang_cc1 -DCK6 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK6 --check-prefix CK6-32
#ifdef CK6
// CK6-DAG: [[GBL:@Gi]] = global i32 0
// CK6-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4]
-// Map types: OMP_MAP_BYCOPY = 128
-// CK6-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 128]
+// Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288
+// CK6-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288]
// CK6-LABEL: implicit_maps_host_global
int Gi;
@@ -298,22 +298,22 @@ void implicit_maps_host_global (int a){
#endif
///==========================================================================///
-// RUN: %clang_cc1 -DCK7 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK7 --check-prefix CK7-64
-// RUN: %clang_cc1 -DCK7 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK7 --check-prefix CK7-64
-// RUN: %clang_cc1 -DCK7 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK7 --check-prefix CK7-32
-// RUN: %clang_cc1 -DCK7 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK7 --check-prefix CK7-32
+// RUN: %clang_cc1 -DCK7 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK7 --check-prefix CK7-64
+// RUN: %clang_cc1 -DCK7 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK7 --check-prefix CK7-64
+// RUN: %clang_cc1 -DCK7 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK7 --check-prefix CK7-32
+// RUN: %clang_cc1 -DCK7 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK7 --check-prefix CK7-32
#ifdef CK7
// For a 32-bit targets, the value doesn't fit the size of the pointer,
// therefore it is passed by reference with a map 'to' specification.
// CK7-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 8]
-// Map types: OMP_MAP_BYCOPY = 128
-// CK7-64-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 128]
-// Map types: OMP_MAP_TO = 1
-// CK7-32-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 1]
+// Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288
+// CK7-64-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288]
+// Map types: OMP_MAP_TO | OMP_MAP_IS_FIRST = 33
+// CK7-32-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 33]
// CK7-LABEL: implicit_maps_double
void implicit_maps_double (int a){
@@ -360,17 +360,17 @@ void implicit_maps_double (int a){
#endif
///==========================================================================///
-// RUN: %clang_cc1 -DCK8 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK8
-// RUN: %clang_cc1 -DCK8 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK8
-// RUN: %clang_cc1 -DCK8 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK8
-// RUN: %clang_cc1 -DCK8 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK8
+// RUN: %clang_cc1 -DCK8 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK8
+// RUN: %clang_cc1 -DCK8 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK8
+// RUN: %clang_cc1 -DCK8 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK8
+// RUN: %clang_cc1 -DCK8 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK8
#ifdef CK8
// CK8-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4]
-// Map types: OMP_MAP_BYCOPY = 128
-// CK8-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 128]
+// Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288
+// CK8-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288]
// CK8-LABEL: implicit_maps_float
void implicit_maps_float (int a){
@@ -404,17 +404,17 @@ void implicit_maps_float (int a){
#endif
///==========================================================================///
-// RUN: %clang_cc1 -DCK9 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK9
-// RUN: %clang_cc1 -DCK9 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK9
-// RUN: %clang_cc1 -DCK9 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK9
-// RUN: %clang_cc1 -DCK9 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK9
+// RUN: %clang_cc1 -DCK9 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK9
+// RUN: %clang_cc1 -DCK9 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK9
+// RUN: %clang_cc1 -DCK9 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK9
+// RUN: %clang_cc1 -DCK9 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK9
#ifdef CK9
// CK9-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 16]
-// Map types: OMP_MAP_TO + OMP_MAP_FROM = 2 + 1
-// CK9-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 3]
+// Map types: OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_IS_FIRST = 35
+// CK9-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 35]
// CK9-LABEL: implicit_maps_array
void implicit_maps_array (int a){
@@ -445,17 +445,17 @@ void implicit_maps_array (int a){
// CK9: {{.+}} = getelementptr inbounds [2 x double], [2 x double]* [[REF]], i[[sz]] 0, i[[sz]] 0
#endif
///==========================================================================///
-// RUN: %clang_cc1 -DCK10 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK10
-// RUN: %clang_cc1 -DCK10 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK10
-// RUN: %clang_cc1 -DCK10 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK10
-// RUN: %clang_cc1 -DCK10 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK10
+// RUN: %clang_cc1 -DCK10 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK10
+// RUN: %clang_cc1 -DCK10 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK10
+// RUN: %clang_cc1 -DCK10 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK10
+// RUN: %clang_cc1 -DCK10 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK10
#ifdef CK10
-// CK10-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} {{8|4}}]
-// Map types: OMP_MAP_BYCOPY | OMP_MAP_PTR = 128 + 32
-// CK10-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 160]
+// CK10-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] zeroinitializer
+// Map types: OMP_MAP_IS_FIRST = 32
+// CK10-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 32]
// CK10-LABEL: implicit_maps_pointer
void implicit_maps_pointer (){
@@ -487,17 +487,17 @@ void implicit_maps_pointer (){
#endif
///==========================================================================///
-// RUN: %clang_cc1 -DCK11 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK11
-// RUN: %clang_cc1 -DCK11 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK11
-// RUN: %clang_cc1 -DCK11 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK11
-// RUN: %clang_cc1 -DCK11 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK11
+// RUN: %clang_cc1 -DCK11 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK11
+// RUN: %clang_cc1 -DCK11 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK11
+// RUN: %clang_cc1 -DCK11 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK11
+// RUN: %clang_cc1 -DCK11 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK11
#ifdef CK11
// CK11-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 16]
-// Map types: OMP_MAP_TO = 1
-// CK11-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 1]
+// Map types: OMP_MAP_TO + OMP_MAP_IS_FIRST = 33
+// CK11-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 33]
// CK11-LABEL: implicit_maps_double_complex
void implicit_maps_double_complex (int a){
@@ -527,22 +527,22 @@ void implicit_maps_double_complex (int a){
// CK11: {{.+}} = getelementptr inbounds { double, double }, { double, double }* [[REF]], i32 0, i32 0
#endif
///==========================================================================///
-// RUN: %clang_cc1 -DCK12 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK12 --check-prefix CK12-64
-// RUN: %clang_cc1 -DCK12 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK12 --check-prefix CK12-64
-// RUN: %clang_cc1 -DCK12 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK12 --check-prefix CK12-32
-// RUN: %clang_cc1 -DCK12 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK12 --check-prefix CK12-32
+// RUN: %clang_cc1 -DCK12 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK12 --check-prefix CK12-64
+// RUN: %clang_cc1 -DCK12 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK12 --check-prefix CK12-64
+// RUN: %clang_cc1 -DCK12 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK12 --check-prefix CK12-32
+// RUN: %clang_cc1 -DCK12 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK12 --check-prefix CK12-32
#ifdef CK12
// For a 32-bit targets, the value doesn't fit the size of the pointer,
// therefore it is passed by reference with a map 'to' specification.
// CK12-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 8]
-// Map types: OMP_MAP_BYCOPY = 128
-// CK12-64-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 128]
-// Map types: OMP_MAP_TO = 1
-// CK12-32-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 1]
+// Map types: OMP_MAP_PRIVATE_VAL + OMP_MAP_IS_FIRST = 288
+// CK12-64-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288]
+// Map types: OMP_MAP_TO + OMP_MAP_IS_FIRST = 33
+// CK12-32-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 33]
// CK12-LABEL: implicit_maps_float_complex
void implicit_maps_float_complex (int a){
@@ -588,20 +588,20 @@ void implicit_maps_float_complex (int a){
// CK12-32: {{.+}} = getelementptr inbounds { float, float }, { float, float }* [[REF]], i32 0, i32 0
#endif
///==========================================================================///
-// RUN: %clang_cc1 -DCK13 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK13
-// RUN: %clang_cc1 -DCK13 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK13
-// RUN: %clang_cc1 -DCK13 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK13
-// RUN: %clang_cc1 -DCK13 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK13
+// RUN: %clang_cc1 -DCK13 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK13
+// RUN: %clang_cc1 -DCK13 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK13
+// RUN: %clang_cc1 -DCK13 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK13
+// RUN: %clang_cc1 -DCK13 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK13
#ifdef CK13
// We don't have a constant map size for VLAs.
// Map types:
-// - OMP_MAP_BYCOPY = 128 (vla size)
-// - OMP_MAP_BYCOPY = 128 (vla size)
-// - OMP_MAP_TO + OMP_MAP_FROM = 2 + 1
-// CK13-DAG: [[TYPES:@.+]] = {{.+}}constant [3 x i32] [i32 128, i32 128, i32 3]
+// - OMP_MAP_PRIVATE_VAL + OMP_MAP_IS_FIRST = 288 (vla size)
+// - OMP_MAP_PRIVATE_VAL + OMP_MAP_IS_FIRST = 288 (vla size)
+// - OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_IS_FIRST = 35
+// CK13-DAG: [[TYPES:@.+]] = {{.+}}constant [3 x i32] [i32 288, i32 288, i32 35]
// CK13-LABEL: implicit_maps_variable_length_array
void implicit_maps_variable_length_array (int a){
@@ -658,20 +658,20 @@ void implicit_maps_variable_length_array (int a){
// CK13: {{.+}} = getelementptr inbounds double, double* [[REF]], i[[sz]] %{{.+}}
#endif
///==========================================================================///
-// RUN: %clang_cc1 -DCK14 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK14 --check-prefix CK14-64
-// RUN: %clang_cc1 -DCK14 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK14 --check-prefix CK14-64
-// RUN: %clang_cc1 -DCK14 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK14 --check-prefix CK14-32
-// RUN: %clang_cc1 -DCK14 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK14 --check-prefix CK14-32
+// RUN: %clang_cc1 -DCK14 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK14 --check-prefix CK14-64
+// RUN: %clang_cc1 -DCK14 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK14 --check-prefix CK14-64
+// RUN: %clang_cc1 -DCK14 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK14 --check-prefix CK14-32
+// RUN: %clang_cc1 -DCK14 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK14 --check-prefix CK14-32
#ifdef CK14
// CK14-DAG: [[ST:%.+]] = type { i32, double }
// CK14-DAG: [[SIZES:@.+]] = {{.+}}constant [2 x i[[sz:64|32]]] [i{{64|32}} {{16|12}}, i{{64|32}} 4]
// Map types:
-// - OMP_MAP_TO | OMP_MAP_FROM = 1 + 2
-// - OMP_MAP_BYCOPY = 128
-// CK14-DAG: [[TYPES:@.+]] = {{.+}}constant [2 x i32] [i32 3, i32 128]
+// - OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_IS_FIRST = 35
+// - OMP_MAP_PRIVATE_VAL + OMP_MAP_IS_FIRST = 288
+// CK14-DAG: [[TYPES:@.+]] = {{.+}}constant [2 x i32] [i32 35, i32 288]
class SSS {
public:
@@ -732,26 +732,26 @@ void implicit_maps_class (int a){
#endif
///==========================================================================///
-// RUN: %clang_cc1 -DCK15 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK15 --check-prefix CK15-64
-// RUN: %clang_cc1 -DCK15 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK15 --check-prefix CK15-64
-// RUN: %clang_cc1 -DCK15 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK15 --check-prefix CK15-32
-// RUN: %clang_cc1 -DCK15 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK15 --check-prefix CK15-32
+// RUN: %clang_cc1 -DCK15 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK15 --check-prefix CK15-64
+// RUN: %clang_cc1 -DCK15 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK15 --check-prefix CK15-64
+// RUN: %clang_cc1 -DCK15 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK15 --check-prefix CK15-32
+// RUN: %clang_cc1 -DCK15 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK15 --check-prefix CK15-32
#ifdef CK15
// CK15: [[ST:%.+]] = type { i32, double, i32* }
// CK15: [[SIZES:@.+]] = {{.+}}constant [2 x i[[sz:64|32]]] [i{{64|32}} {{24|16}}, i{{64|32}} 4]
// Map types:
-// - OMP_MAP_TO | OMP_MAP_FROM = 1 + 2
-// - OMP_MAP_BYCOPY = 128
-// CK15: [[TYPES:@.+]] = {{.+}}constant [2 x i32] [i32 3, i32 128]
+// - OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_IS_FIRST = 35
+// - OMP_MAP_PRIVATE_VAL + OMP_MAP_IS_FIRST = 288
+// CK15: [[TYPES:@.+]] = {{.+}}constant [2 x i32] [i32 35, i32 288]
// CK15: [[SIZES2:@.+]] = {{.+}}constant [2 x i[[sz]]] [i{{64|32}} {{24|16}}, i{{64|32}} 4]
// Map types:
-// - OMP_MAP_TO | OMP_MAP_FROM = 1 + 2
-// - OMP_MAP_BYCOPY = 128
-// CK15: [[TYPES2:@.+]] = {{.+}}constant [2 x i32] [i32 3, i32 128]
+// - OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_IS_FIRST = 35
+// - OMP_MAP_PRIVATE_VAL + OMP_MAP_IS_FIRST = 288
+// CK15: [[TYPES2:@.+]] = {{.+}}constant [2 x i32] [i32 35, i32 288]
template<int x>
class SSST {
@@ -860,18 +860,18 @@ void implicit_maps_templated_class (int a){
#endif
///==========================================================================///
-// RUN: %clang_cc1 -DCK16 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK16 --check-prefix CK16-64
-// RUN: %clang_cc1 -DCK16 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK16 --check-prefix CK16-64
-// RUN: %clang_cc1 -DCK16 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK16 --check-prefix CK16-32
-// RUN: %clang_cc1 -DCK16 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK16 --check-prefix CK16-32
+// RUN: %clang_cc1 -DCK16 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK16 --check-prefix CK16-64
+// RUN: %clang_cc1 -DCK16 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK16 --check-prefix CK16-64
+// RUN: %clang_cc1 -DCK16 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK16 --check-prefix CK16-32
+// RUN: %clang_cc1 -DCK16 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK16 --check-prefix CK16-32
#ifdef CK16
// CK16-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4]
// Map types:
-// - OMP_MAP_BYCOPY = 128
-// CK16-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 128]
+// - OMP_MAP_PRIVATE_VAL + OMP_MAP_IS_FIRST = 288
+// CK16-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288]
template<int y>
int foo(int d) {
@@ -913,18 +913,18 @@ void implicit_maps_templated_function (int a){
#endif
///==========================================================================///
-// RUN: %clang_cc1 -DCK17 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK17
-// RUN: %clang_cc1 -DCK17 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK17
-// RUN: %clang_cc1 -DCK17 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK17
-// RUN: %clang_cc1 -DCK17 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK17
+// RUN: %clang_cc1 -DCK17 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK17
+// RUN: %clang_cc1 -DCK17 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK17
+// RUN: %clang_cc1 -DCK17 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK17
+// RUN: %clang_cc1 -DCK17 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK17
#ifdef CK17
// CK17-DAG: [[ST:%.+]] = type { i32, double }
// CK17-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} {{16|12}}]
-// Map types: OMP_MAP_TO + OMP_MAP_FROM = 2 + 1
-// CK17-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 3]
+// Map types: OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_IS_FIRST = 35
+// CK17-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 35]
class SSS {
public:
@@ -961,18 +961,18 @@ void implicit_maps_struct (int a){
// CK17: {{.+}} = getelementptr inbounds [[ST]], [[ST]]* [[REF]], i32 0, i32 0
#endif
///==========================================================================///
-// RUN: %clang_cc1 -DCK18 -verify -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK18 --check-prefix CK18-64
-// RUN: %clang_cc1 -DCK18 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK18 --check-prefix CK18-64
-// RUN: %clang_cc1 -DCK18 -verify -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK18 --check-prefix CK18-32
-// RUN: %clang_cc1 -DCK18 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -omptargets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK18 --check-prefix CK18-32
+// RUN: %clang_cc1 -DCK18 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK18 --check-prefix CK18-64
+// RUN: %clang_cc1 -DCK18 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK18 --check-prefix CK18-64
+// RUN: %clang_cc1 -DCK18 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK18 --check-prefix CK18-32
+// RUN: %clang_cc1 -DCK18 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK18 --check-prefix CK18-32
#ifdef CK18
// CK18-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4]
// Map types:
-// - OMP_MAP_BYCOPY = 128
-// CK18-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 128]
+// - OMP_MAP_PRIVATE_VAL + OMP_MAP_IS_FIRST = 288
+// CK18-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288]
template<typename T>
int foo(T d) {
@@ -1012,4 +1012,3463 @@ void implicit_maps_template_type_capture (int a){
// CK18-32: {{.+}} = load i32, i32* [[ADDR]],
#endif
+///==========================================================================///
+// RUN: %clang_cc1 -DCK19 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK19 --check-prefix CK19-64
+// RUN: %clang_cc1 -DCK19 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK19 --check-prefix CK19-64
+// RUN: %clang_cc1 -DCK19 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK19 --check-prefix CK19-32
+// RUN: %clang_cc1 -DCK19 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK19 --check-prefix CK19-32
+#ifdef CK19
+
+// CK19: [[SIZE00:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4]
+// CK19: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i32] [i32 32]
+
+// CK19: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 400]
+// CK19: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 33]
+
+// CK19: [[SIZE02:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 240]
+// CK19: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i32] [i32 34]
+
+// CK19: [[SIZE03:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 240]
+// CK19: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK19: [[SIZE04:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 400]
+// CK19: [[MTYPE04:@.+]] = private {{.*}}constant [1 x i32] [i32 32]
+
+// CK19: [[SIZE05:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
+// CK19: [[MTYPE05:@.+]] = private {{.*}}constant [1 x i32] [i32 33]
+
+// CK19: [[MTYPE06:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK19: [[MTYPE07:@.+]] = private {{.*}}constant [1 x i32] [i32 32]
+
+// CK19: [[SIZE08:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
+// CK19: [[MTYPE08:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK19: [[SIZE09:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] {{8|4}}]
+// CK19: [[MTYPE09:@.+]] = private {{.*}}constant [1 x i32] [i32 34]
+
+// CK19: [[SIZE10:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 240]
+// CK19: [[MTYPE10:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK19: [[SIZE11:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 240]
+// CK19: [[MTYPE11:@.+]] = private {{.*}}constant [1 x i32] [i32 32]
+
+// CK19: [[SIZE12:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
+// CK19: [[MTYPE12:@.+]] = private {{.*}}constant [1 x i32] [i32 33]
+
+// CK19: [[MTYPE13:@.+]] = private {{.*}}constant [1 x i32] [i32 32]
+
+// CK19: [[MTYPE14:@.+]] = private {{.*}}constant [1 x i32] [i32 33]
+
+// CK19: [[SIZE15:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
+// CK19: [[MTYPE15:@.+]] = private {{.*}}constant [1 x i32] [i32 34]
+
+// CK19: [[MTYPE16:@.+]] = private {{.*}}constant [2 x i32] [i32 288, i32 33]
+
+// CK19: [[SIZE17:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 240]
+// CK19: [[MTYPE17:@.+]] = private {{.*}}constant [2 x i32] [i32 288, i32 34]
+
+// CK19: [[SIZE18:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 240]
+// CK19: [[MTYPE18:@.+]] = private {{.*}}constant [2 x i32] [i32 288, i32 35]
+
+// CK19: [[MTYPE19:@.+]] = private {{.*}}constant [2 x i32] [i32 288, i32 32]
+
+// CK19: [[SIZE20:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 4]
+// CK19: [[MTYPE20:@.+]] = private {{.*}}constant [2 x i32] [i32 288, i32 33]
+
+// CK19: [[MTYPE21:@.+]] = private {{.*}}constant [2 x i32] [i32 288, i32 35]
+
+// CK19: [[SIZE22:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 4]
+// CK19: [[MTYPE22:@.+]] = private {{.*}}constant [2 x i32] [i32 288, i32 35]
+
+// CK19: [[SIZE23:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
+// CK19: [[MTYPE23:@.+]] = private {{.*}}constant [1 x i32] [i32 39]
+
+// CK19: [[SIZE24:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 480]
+// CK19: [[MTYPE24:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK19: [[SIZE25:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 16]
+// CK19: [[MTYPE25:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK19: [[SIZE26:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 24]
+// CK19: [[MTYPE26:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK19: [[SIZE27:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
+// CK19: [[MTYPE27:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK19: [[SIZE28:@.+]] = private {{.*}}constant [3 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] 16]
+// CK19: [[MTYPE28:@.+]] = private {{.*}}constant [3 x i32] [i32 35, i32 19, i32 19]
+
+// CK19: [[SIZE29:@.+]] = private {{.*}}constant [3 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] 4]
+// CK19: [[MTYPE29:@.+]] = private {{.*}}constant [3 x i32] [i32 35, i32 19, i32 19]
+
+// CK19: [[MTYPE30:@.+]] = private {{.*}}constant [4 x i32] [i32 288, i32 288, i32 288, i32 35]
+
+// CK19: [[SIZE31:@.+]] = private {{.*}}constant [4 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] 40]
+// CK19: [[MTYPE31:@.+]] = private {{.*}}constant [4 x i32] [i32 288, i32 288, i32 288, i32 35]
+
+// CK19: [[SIZE32:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 13728]
+// CK19: [[MTYPE32:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK19: [[SIZE33:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 13728]
+// CK19: [[MTYPE33:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK19: [[SIZE34:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 13728]
+// CK19: [[MTYPE34:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK19: [[MTYPE35:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK19: [[SIZE36:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 208]
+// CK19: [[MTYPE36:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK19: [[MTYPE37:@.+]] = private {{.*}}constant [3 x i32] [i32 288, i32 288, i32 35]
+
+// CK19: [[MTYPE38:@.+]] = private {{.*}}constant [3 x i32] [i32 288, i32 288, i32 35]
+
+// CK19: [[MTYPE39:@.+]] = private {{.*}}constant [3 x i32] [i32 288, i32 288, i32 35]
+
+// CK19: [[MTYPE40:@.+]] = private {{.*}}constant [3 x i32] [i32 288, i32 288, i32 35]
+
+// CK19: [[SIZE41:@.+]] = private {{.*}}constant [3 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] 208]
+// CK19: [[MTYPE41:@.+]] = private {{.*}}constant [3 x i32] [i32 288, i32 288, i32 35]
+
+// CK19: [[SIZE42:@.+]] = private {{.*}}constant [3 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] 104]
+// CK19: [[MTYPE42:@.+]] = private {{.*}}constant [3 x i32] [i32 35, i32 19, i32 19]
+
+// CK19: [[MTYPE43:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK19-LABEL: explicit_maps_single
+void explicit_maps_single (int ii){
+ // Map of a scalar.
+ int a = ii;
+
+ // Region 00
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast i32* [[VAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast i32* [[VAR0]] to i8*
+
+ // CK19: call void [[CALL00:@.+]](i32* {{[^,]+}})
+ #pragma omp target map(alloc:a)
+ {
+ ++a;
+ }
+
+ // Map of an array.
+ int arra[100];
+
+ // Region 01
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast [100 x i32]* [[VAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast [100 x i32]* [[VAR0]] to i8*
+
+ // CK19: call void [[CALL01:@.+]]([100 x i32]* {{[^,]+}})
+ #pragma omp target map(to:arra)
+ {
+ arra[50]++;
+ }
+
+ // Region 02
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast [100 x i32]* [[VAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK19-DAG: [[SEC0]] = getelementptr {{.*}}[100 x i32]* [[VAR0]], i{{.+}} 0, i{{.+}} 20
+
+ // CK19: call void [[CALL02:@.+]]([100 x i32]* {{[^,]+}})
+ #pragma omp target map(from:arra[20:60])
+ {
+ arra[50]++;
+ }
+
+ // Region 03
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast [100 x i32]* [[VAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK19-DAG: [[SEC0]] = getelementptr {{.*}}[100 x i32]* [[VAR0]], i{{.+}} 0, i{{.+}} 0
+
+ // CK19: call void [[CALL03:@.+]]([100 x i32]* {{[^,]+}})
+ #pragma omp target map(tofrom:arra[:60])
+ {
+ arra[50]++;
+ }
+
+ // Region 04
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE04]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast [100 x i32]* [[VAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK19-DAG: [[SEC0]] = getelementptr {{.*}}[100 x i32]* [[VAR0]], i{{.+}} 0, i{{.+}} 0
+
+ // CK19: call void [[CALL04:@.+]]([100 x i32]* {{[^,]+}})
+ #pragma omp target map(alloc:arra[:])
+ {
+ arra[50]++;
+ }
+
+ // Region 05
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE05]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE05]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast [100 x i32]* [[VAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK19-DAG: [[SEC0]] = getelementptr {{.*}}[100 x i32]* [[VAR0]], i{{.+}} 0, i{{.+}} 15
+
+ // CK19: call void [[CALL05:@.+]]([100 x i32]* {{[^,]+}})
+ #pragma omp target map(to:arra[15])
+ {
+ arra[15]++;
+ }
+
+ // Region 06
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE06]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+ // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: store i{{.+}} [[CSVAL0:%[^,]+]], i{{.+}}* [[S0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast [100 x i32]* [[VAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK19-DAG: [[CSVAL0]] = mul nuw i{{.+}} %{{.*}}, 4
+ // CK19-DAG: [[SEC0]] = getelementptr {{.*}}[100 x i32]* [[VAR0]], i{{.+}} 0, i{{.+}} %{{.*}}
+
+ // CK19: call void [[CALL06:@.+]]([100 x i32]* {{[^,]+}})
+ #pragma omp target map(tofrom:arra[ii:ii+23])
+ {
+ arra[50]++;
+ }
+
+ // Region 07
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE07]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+ // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: store i{{.+}} [[CSVAL0:%[^,]+]], i{{.+}}* [[S0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast [100 x i32]* [[VAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK19-DAG: [[CSVAL0]] = mul nuw i{{.+}} %{{.*}}, 4
+ // CK19-DAG: [[SEC0]] = getelementptr {{.*}}[100 x i32]* [[VAR0]], i{{.+}} 0, i{{.+}} 0
+
+ // CK19: call void [[CALL07:@.+]]([100 x i32]* {{[^,]+}})
+ #pragma omp target map(alloc:arra[:ii])
+ {
+ arra[50]++;
+ }
+
+ // Region 08
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE08]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE08]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast [100 x i32]* [[VAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK19-DAG: [[SEC0]] = getelementptr {{.*}}[100 x i32]* [[VAR0]], i{{.+}} 0, i{{.+}} %{{.*}}
+
+ // CK19: call void [[CALL08:@.+]]([100 x i32]* {{[^,]+}})
+ #pragma omp target map(tofrom:arra[ii])
+ {
+ arra[15]++;
+ }
+
+ // Map of a pointer.
+ int *pa;
+
+ // Region 09
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE09]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE09]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast i32** [[VAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast i32** [[VAR0]] to i8*
+
+ // CK19: call void [[CALL09:@.+]](i32** {{[^,]+}})
+ #pragma omp target map(from:pa)
+ {
+ pa[50]++;
+ }
+
+ // Region 10
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE10]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE10]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast i32* [[RVAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK19-DAG: [[RVAR0]] = load i32*, i32** [[VAR0:%[^,]+]]
+ // CK19-DAG: [[SEC0]] = getelementptr {{.*}}i32* [[RVAR00:%.+]], i{{.+}} 20
+ // CK19-DAG: [[RVAR00]] = load i32*, i32** [[VAR0]]
+
+ // CK19: call void [[CALL10:@.+]](i32* {{[^,]+}})
+ #pragma omp target map(tofrom:pa[20:60])
+ {
+ pa[50]++;
+ }
+
+ // Region 11
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE11]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE11]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast i32* [[RVAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK19-DAG: [[RVAR0]] = load i32*, i32** [[VAR0:%[^,]+]]
+ // CK19-DAG: [[SEC0]] = getelementptr {{.*}}i32* [[RVAR00:%.+]], i{{.+}} 0
+ // CK19-DAG: [[RVAR00]] = load i32*, i32** [[VAR0]]
+
+ // CK19: call void [[CALL11:@.+]](i32* {{[^,]+}})
+ #pragma omp target map(alloc:pa[:60])
+ {
+ pa[50]++;
+ }
+
+ // Region 12
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE12]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE12]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast i32* [[RVAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK19-DAG: [[RVAR0]] = load i32*, i32** [[VAR0:%[^,]+]]
+ // CK19-DAG: [[SEC0]] = getelementptr {{.*}}i32* [[RVAR00:%.+]], i{{.+}} 15
+ // CK19-DAG: [[RVAR00]] = load i32*, i32** [[VAR0]]
+
+ // CK19: call void [[CALL12:@.+]](i32* {{[^,]+}})
+ #pragma omp target map(to:pa[15])
+ {
+ pa[15]++;
+ }
+
+ // Region 13
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE13]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+ // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: store i{{.+}} [[CSVAL0:%[^,]+]], i{{.+}}* [[S0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast i32* [[RVAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK19-DAG: [[CSVAL0]] = mul nuw i{{.+}} %{{.*}}, 4
+ // CK19-DAG: [[RVAR0]] = load i32*, i32** [[VAR0:%[^,]+]]
+ // CK19-DAG: [[SEC0]] = getelementptr {{.*}}i32* [[RVAR00:%.+]], i{{.+}} %{{.*}}
+ // CK19-DAG: [[RVAR00]] = load i32*, i32** [[VAR0]]
+
+ // CK19: call void [[CALL13:@.+]](i32* {{[^,]+}})
+ #pragma omp target map(alloc:pa[ii-23:ii])
+ {
+ pa[50]++;
+ }
+
+ // Region 14
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE14]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+ // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: store i{{.+}} [[CSVAL0:%[^,]+]], i{{.+}}* [[S0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast i32* [[RVAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK19-DAG: [[CSVAL0]] = mul nuw i{{.+}} %{{.*}}, 4
+ // CK19-DAG: [[RVAR0]] = load i32*, i32** [[VAR0:%[^,]+]]
+ // CK19-DAG: [[SEC0]] = getelementptr {{.*}}i32* [[RVAR00:%.+]], i{{.+}} 0
+ // CK19-DAG: [[RVAR00]] = load i32*, i32** [[VAR0]]
+
+ // CK19: call void [[CALL14:@.+]](i32* {{[^,]+}})
+ #pragma omp target map(to:pa[:ii])
+ {
+ pa[50]++;
+ }
+
+ // Region 15
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE15]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE15]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast i32* [[RVAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK19-DAG: [[RVAR0]] = load i32*, i32** [[VAR0:%[^,]+]]
+ // CK19-DAG: [[SEC0]] = getelementptr {{.*}}i32* [[RVAR00:%.+]], i{{.+}} %{{.*}}
+ // CK19-DAG: [[RVAR00]] = load i32*, i32** [[VAR0]]
+
+ // CK19: call void [[CALL15:@.+]](i32* {{[^,]+}})
+ #pragma omp target map(from:pa[ii+12])
+ {
+ pa[15]++;
+ }
+
+ // Map of a variable-size array.
+ int va[ii];
+
+ // Region 16
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE16]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+ // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: store i{{.+}} {{8|4}}, i{{.+}}* [[S0]]
+ // CK19-DAG: [[CBPVAL0]] = inttoptr i[[Z]] %{{.+}} to i8*
+ // CK19-DAG: [[CPVAL0]] = inttoptr i[[Z]] %{{.+}}to i8*
+
+ // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[S1:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+ // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK19-DAG: store i{{.+}} [[CSVAL1:%[^,]+]], i{{.+}}* [[S1]]
+ // CK19-DAG: [[CBPVAL1]] = bitcast i32* [[VAR1:%.+]] to i8*
+ // CK19-DAG: [[CPVAL1]] = bitcast i32* [[VAR1]] to i8*
+ // CK19-DAG: [[CSVAL1]] = mul nuw i{{.+}} %{{.*}}, 4
+
+ // CK19: call void [[CALL16:@.+]](i{{.+}} {{[^,]+}}, i32* {{[^,]+}})
+ #pragma omp target map(to:va)
+ {
+ va[50]++;
+ }
+
+ // Region 17
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE17]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE17]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = inttoptr i[[Z]] %{{.+}} to i8*
+ // CK19-DAG: [[CPVAL0]] = inttoptr i[[Z]] %{{.+}}to i8*
+
+ // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+ // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK19-DAG: [[CBPVAL1]] = bitcast i32* [[VAR1:%.+]] to i8*
+ // CK19-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8*
+ // CK19-DAG: [[SEC1]] = getelementptr {{.*}}i32* [[VAR1]], i{{.+}} 20
+
+ // CK19: call void [[CALL17:@.+]](i{{.+}} {{[^,]+}}, i32* {{[^,]+}})
+ #pragma omp target map(from:va[20:60])
+ {
+ va[50]++;
+ }
+
+ // Region 18
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE18]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE18]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = inttoptr i[[Z]] %{{.+}} to i8*
+ // CK19-DAG: [[CPVAL0]] = inttoptr i[[Z]] %{{.+}}to i8*
+
+ // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+ // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK19-DAG: [[CBPVAL1]] = bitcast i32* [[VAR1:%.+]] to i8*
+ // CK19-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8*
+ // CK19-DAG: [[SEC1]] = getelementptr {{.*}}i32* [[VAR1]], i{{.+}} 0
+
+ // CK19: call void [[CALL18:@.+]](i{{.+}} {{[^,]+}}, i32* {{[^,]+}})
+ #pragma omp target map(tofrom:va[:60])
+ {
+ va[50]++;
+ }
+
+ // Region 19
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE19]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+ // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: store i{{.+}} {{8|4}}, i{{.+}}* [[S0]]
+ // CK19-DAG: [[CBPVAL0]] = inttoptr i[[Z]] %{{.+}} to i8*
+ // CK19-DAG: [[CPVAL0]] = inttoptr i[[Z]] %{{.+}}to i8*
+
+ // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[S1:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+ // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK19-DAG: store i{{.+}} [[CSVAL1:%[^,]+]], i{{.+}}* [[S1]]
+ // CK19-DAG: [[CBPVAL1]] = bitcast i32* [[VAR1:%.+]] to i8*
+ // CK19-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8*
+ // CK19-DAG: [[CSVAL1]] = mul nuw i{{.+}} %{{.*}}, 4
+ // CK19-DAG: [[SEC1]] = getelementptr {{.*}}i32* [[VAR1]], i{{.+}} 0
+
+ // CK19: call void [[CALL19:@.+]](i{{.+}} {{[^,]+}}, i32* {{[^,]+}})
+ #pragma omp target map(alloc:va[:])
+ {
+ va[50]++;
+ }
+
+ // Region 20
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE20]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE20]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = inttoptr i[[Z]] %{{.+}} to i8*
+ // CK19-DAG: [[CPVAL0]] = inttoptr i[[Z]] %{{.+}}to i8*
+
+ // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+ // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK19-DAG: [[CBPVAL1]] = bitcast i32* [[VAR1:%.+]] to i8*
+ // CK19-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8*
+ // CK19-DAG: [[SEC1]] = getelementptr {{.*}}i32* [[VAR1]], i{{.+}} 15
+
+ // CK19: call void [[CALL20:@.+]](i{{.+}} {{[^,]+}}, i32* {{[^,]+}})
+ #pragma omp target map(to:va[15])
+ {
+ va[15]++;
+ }
+
+ // Region 21
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE21]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+ // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: store i{{.+}} {{8|4}}, i{{.+}}* [[S0]]
+ // CK19-DAG: [[CBPVAL0]] = inttoptr i[[Z]] %{{.+}} to i8*
+ // CK19-DAG: [[CPVAL0]] = inttoptr i[[Z]] %{{.+}}to i8*
+
+ // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[S1:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+ // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK19-DAG: store i{{.+}} [[CSVAL1:%[^,]+]], i{{.+}}* [[S1]]
+ // CK19-DAG: [[CBPVAL1]] = bitcast i32* [[VAR1:%.+]] to i8*
+ // CK19-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8*
+ // CK19-DAG: [[CSVAL1]] = mul nuw i{{.+}} %{{.*}}, 4
+ // CK19-DAG: [[SEC1]] = getelementptr {{.*}}i32* [[VAR1]], i{{.+}} %{{.+}}
+
+ // CK19: call void [[CALL21:@.+]](i{{.+}} {{[^,]+}}, i32* {{[^,]+}})
+ #pragma omp target map(tofrom:va[ii:ii+23])
+ {
+ va[50]++;
+ }
+
+ // Region 22
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE22]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE22]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = inttoptr i[[Z]] %{{.+}} to i8*
+ // CK19-DAG: [[CPVAL0]] = inttoptr i[[Z]] %{{.+}}to i8*
+
+ // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+ // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK19-DAG: [[CBPVAL1]] = bitcast i32* [[VAR1:%.+]] to i8*
+ // CK19-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8*
+ // CK19-DAG: [[SEC1]] = getelementptr {{.*}}i32* [[VAR1]], i{{.+}} %{{.+}}
+
+ // CK19: call void [[CALL22:@.+]](i{{.+}} {{[^,]+}}, i32* {{[^,]+}})
+ #pragma omp target map(tofrom:va[ii])
+ {
+ va[15]++;
+ }
+
+ // Always.
+ // Region 23
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE23]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE23]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast i32* [[VAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast i32* [[VAR0]] to i8*
+
+ // CK19: call void [[CALL23:@.+]](i32* {{[^,]+}})
+ #pragma omp target map(always, tofrom: a)
+ {
+ a++;
+ }
+
+ // Multidimensional arrays.
+ int marr[4][5][6];
+ int ***mptr;
+
+ // Region 24
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE24]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE24]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast [4 x [5 x [6 x i32]]]* [[VAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast [4 x [5 x [6 x i32]]]* [[VAR0]] to i8*
+
+ // CK19: call void [[CALL24:@.+]]([4 x [5 x [6 x i32]]]* {{[^,]+}})
+ #pragma omp target map(tofrom: marr)
+ {
+ marr[1][2][3]++;
+ }
+
+ // Region 25
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE25]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE25]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast [4 x [5 x [6 x i32]]]* [[VAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK19-DAG: [[SEC0]] = getelementptr {{.*}}[6 x i32]* [[SEC00:[^,]+]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: [[SEC00]] = getelementptr {{.*}}[5 x [6 x i32]]* [[SEC000:[^,]+]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: [[SEC000]] = getelementptr {{.*}}[4 x [5 x [6 x i32]]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1
+
+ // CK19: call void [[CALL25:@.+]]([4 x [5 x [6 x i32]]]* {{[^,]+}})
+ #pragma omp target map(tofrom: marr[1][2][2:4])
+ {
+ marr[1][2][3]++;
+ }
+
+ // Region 26
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE26]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE26]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast [4 x [5 x [6 x i32]]]* [[VAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK19-DAG: [[SEC0]] = getelementptr {{.*}}[6 x i32]* [[SEC00:[^,]+]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[SEC00]] = getelementptr {{.*}}[5 x [6 x i32]]* [[SEC000:[^,]+]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: [[SEC000]] = getelementptr {{.*}}[4 x [5 x [6 x i32]]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1
+
+ // CK19: call void [[CALL26:@.+]]([4 x [5 x [6 x i32]]]* {{[^,]+}})
+ #pragma omp target map(tofrom: marr[1][2][:])
+ {
+ marr[1][2][3]++;
+ }
+
+ // Region 27
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE27]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE27]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast [4 x [5 x [6 x i32]]]* [[VAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK19-DAG: [[SEC0]] = getelementptr {{.*}}[6 x i32]* [[SEC00:[^,]+]], i{{.+}} 0, i{{.+}} 3
+ // CK19-DAG: [[SEC00]] = getelementptr {{.*}}[5 x [6 x i32]]* [[SEC000:[^,]+]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: [[SEC000]] = getelementptr {{.*}}[4 x [5 x [6 x i32]]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1
+
+ // CK19: call void [[CALL27:@.+]]([4 x [5 x [6 x i32]]]* {{[^,]+}})
+ #pragma omp target map(tofrom: marr[1][2][3])
+ {
+ marr[1][2][3]++;
+ }
+
+ // Region 28
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[SIZE28]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE28]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast i32*** [[VAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast i32*** [[SEC0:%.+]] to i8*
+ // CK19-DAG: [[VAR0]] = load i32***, i32**** [[PTR:%[^,]+]],
+ // CK19-DAG: [[SEC0]] = getelementptr {{.*}}i32*** [[SEC00:[^,]+]], i{{.+}} 1
+ // CK19-DAG: [[SEC00]] = load i32***, i32**** [[PTR]],
+
+ // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+ // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK19-DAG: [[CBPVAL1]] = bitcast i32*** [[SEC0]] to i8*
+ // CK19-DAG: [[CPVAL1]] = bitcast i32** [[SEC1:%.+]] to i8*
+ // CK19-DAG: [[SEC1]] = getelementptr {{.*}}i32** [[SEC11:[^,]+]], i{{.+}} 2
+ // CK19-DAG: [[SEC11]] = load i32**, i32*** [[SEC111:%[^,]+]],
+ // CK19-DAG: [[SEC111]] = getelementptr {{.*}}i32*** [[SEC1111:[^,]+]], i{{.+}} 1
+ // CK19-DAG: [[SEC1111]] = load i32***, i32**** [[PTR]],
+
+ // CK19-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: store i8* [[CBPVAL2:%[^,]+]], i8** [[BP2]]
+ // CK19-DAG: store i8* [[CPVAL2:%[^,]+]], i8** [[P2]]
+ // CK19-DAG: [[CBPVAL2]] = bitcast i32** [[SEC1]] to i8*
+ // CK19-DAG: [[CPVAL2]] = bitcast i32* [[SEC2:%.+]] to i8*
+ // CK19-DAG: [[SEC2]] = getelementptr {{.*}}i32* [[SEC22:[^,]+]], i{{.+}} 2
+ // CK19-DAG: [[SEC22]] = load i32*, i32** [[SEC222:%[^,]+]],
+ // CK19-DAG: [[SEC222]] = getelementptr {{.*}}i32** [[SEC2222:[^,]+]], i{{.+}} 2
+ // CK19-DAG: [[SEC2222]] = load i32**, i32*** [[SEC22222:%[^,]+]],
+ // CK19-DAG: [[SEC22222]] = getelementptr {{.*}}i32*** [[SEC222222:[^,]+]], i{{.+}} 1
+ // CK19-DAG: [[SEC222222]] = load i32***, i32**** [[PTR]],
+
+ // CK19: call void [[CALL28:@.+]](i32*** {{[^,]+}})
+ #pragma omp target map(tofrom: mptr[1][2][2:4])
+ {
+ mptr[1][2][3]++;
+ }
+
+ // Region 29
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[SIZE29]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE29]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast i32*** [[VAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast i32*** [[SEC0:%.+]] to i8*
+ // CK19-DAG: [[VAR0]] = load i32***, i32**** [[PTR:%[^,]+]],
+ // CK19-DAG: [[SEC0]] = getelementptr {{.*}}i32*** [[SEC00:[^,]+]], i{{.+}} 1
+ // CK19-DAG: [[SEC00]] = load i32***, i32**** [[PTR]],
+
+ // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+ // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK19-DAG: [[CBPVAL1]] = bitcast i32*** [[SEC0]] to i8*
+ // CK19-DAG: [[CPVAL1]] = bitcast i32** [[SEC1:%.+]] to i8*
+ // CK19-DAG: [[SEC1]] = getelementptr {{.*}}i32** [[SEC11:[^,]+]], i{{.+}} 2
+ // CK19-DAG: [[SEC11]] = load i32**, i32*** [[SEC111:%[^,]+]],
+ // CK19-DAG: [[SEC111]] = getelementptr {{.*}}i32*** [[SEC1111:[^,]+]], i{{.+}} 1
+ // CK19-DAG: [[SEC1111]] = load i32***, i32**** [[PTR]],
+
+ // CK19-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: store i8* [[CBPVAL2:%[^,]+]], i8** [[BP2]]
+ // CK19-DAG: store i8* [[CPVAL2:%[^,]+]], i8** [[P2]]
+ // CK19-DAG: [[CBPVAL2]] = bitcast i32** [[SEC1]] to i8*
+ // CK19-DAG: [[CPVAL2]] = bitcast i32* [[SEC2:%.+]] to i8*
+ // CK19-DAG: [[SEC2]] = getelementptr {{.*}}i32* [[SEC22:[^,]+]], i{{.+}} 3
+ // CK19-DAG: [[SEC22]] = load i32*, i32** [[SEC222:%[^,]+]],
+ // CK19-DAG: [[SEC222]] = getelementptr {{.*}}i32** [[SEC2222:[^,]+]], i{{.+}} 2
+ // CK19-DAG: [[SEC2222]] = load i32**, i32*** [[SEC22222:%[^,]+]],
+ // CK19-DAG: [[SEC22222]] = getelementptr {{.*}}i32*** [[SEC222222:[^,]+]], i{{.+}} 1
+ // CK19-DAG: [[SEC222222]] = load i32***, i32**** [[PTR]],
+
+ // CK19: call void [[CALL29:@.+]](i32*** {{[^,]+}})
+ #pragma omp target map(tofrom: mptr[1][2][3])
+ {
+ mptr[1][2][3]++;
+ }
+
+ // Multidimensional VLA.
+ double mva[23][ii][ii+5];
+
+ // Region 30
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 4, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[MTYPE30]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+ // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
+ //
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* inttoptr (i[[Z]] 23 to i8*), i8** [[BP0]]
+ // CK19-DAG: store i8* inttoptr (i[[Z]] 23 to i8*), i8** [[P0]]
+ // CK19-DAG: store i[[Z]] {{8|4}}, i[[Z]]* [[S0]]
+ //
+ // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[S1:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+ // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK19-DAG: store i[[Z]] {{8|4}}, i[[Z]]* [[S1]]
+ // CK19-DAG: [[CBPVAL1]] = inttoptr i[[Z]] [[VAR1:%.+]] to i8*
+ // CK19-DAG: [[CPVAL1]] = inttoptr i[[Z]] [[VAR11:%.+]] to i8*
+ // CK19-64-DAG: [[VAR1]] = zext i32 %{{[^,]+}} to i64
+ // CK19-64-DAG: [[VAR11]] = zext i32 %{{[^,]+}} to i64
+ //
+ // CK19-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: [[S2:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: store i8* [[CBPVAL2:%[^,]+]], i8** [[BP2]]
+ // CK19-DAG: store i8* [[CPVAL2:%[^,]+]], i8** [[P2]]
+ // CK19-DAG: store i[[Z]] {{8|4}}, i[[Z]]* [[S2]]
+ // CK19-DAG: [[CBPVAL2]] = inttoptr i[[Z]] [[VAR2:%.+]] to i8*
+ // CK19-DAG: [[CPVAL2]] = inttoptr i[[Z]] [[VAR22:%.+]] to i8*
+ // CK19-64-DAG: [[VAR2]] = zext i32 %{{[^,]+}} to i64
+ // CK19-64-DAG: [[VAR22]] = zext i32 %{{[^,]+}} to i64
+ //
+ // CK19-DAG: [[BP3:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 3
+ // CK19-DAG: [[P3:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 3
+ // CK19-DAG: [[S3:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 3
+ // CK19-DAG: store i8* [[CBPVAL3:%[^,]+]], i8** [[BP3]]
+ // CK19-DAG: store i8* [[CPVAL3:%[^,]+]], i8** [[P3]]
+ // CK19-DAG: store i[[Z]] [[CSVAL3:%[^,]+]], i[[Z]]* [[S3]]
+ // CK19-DAG: [[CBPVAL3]] = bitcast double* [[VAR3:%.+]] to i8*
+ // CK19-DAG: [[CPVAL3]] = bitcast double* [[VAR3]] to i8*
+ // CK19-DAG: [[CSVAL3]] = mul nuw i[[Z]] %{{[^,]+}}, {{8|4}}
+
+ // CK19: call void [[CALL30:@.+]](i[[Z]] 23, i[[Z]] %{{[^,]+}}, i[[Z]] %{{[^,]+}}, double* %{{[^,]+}})
+ #pragma omp target map(tofrom: mva)
+ {
+ mva[1][2][3]++;
+ }
+
+ // Region 31
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 4, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[SIZE31]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[MTYPE31]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+ //
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* inttoptr (i[[Z]] 23 to i8*), i8** [[BP0]]
+ // CK19-DAG: store i8* inttoptr (i[[Z]] 23 to i8*), i8** [[P0]]
+ //
+ // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+ // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK19-DAG: [[CBPVAL1]] = inttoptr i[[Z]] [[VAR1:%.+]] to i8*
+ // CK19-DAG: [[CPVAL1]] = inttoptr i[[Z]] [[VAR11:%.+]] to i8*
+ //
+ // CK19-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: store i8* [[CBPVAL2:%[^,]+]], i8** [[BP2]]
+ // CK19-DAG: store i8* [[CPVAL2:%[^,]+]], i8** [[P2]]
+ // CK19-DAG: [[CBPVAL2]] = inttoptr i[[Z]] [[VAR2:%.+]] to i8*
+ // CK19-DAG: [[CPVAL2]] = inttoptr i[[Z]] [[VAR22:%.+]] to i8*
+ //
+ // CK19-DAG: [[BP3:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 3
+ // CK19-DAG: [[P3:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 3
+ // CK19-DAG: store i8* [[CBPVAL3:%[^,]+]], i8** [[BP3]]
+ // CK19-DAG: store i8* [[CPVAL3:%[^,]+]], i8** [[P3]]
+ // CK19-DAG: [[CBPVAL3]] = bitcast double* [[VAR3:%.+]] to i8*
+ // CK19-DAG: [[CPVAL3]] = bitcast double* [[SEC3:%.+]] to i8*
+ // CK19-DAG: [[SEC3]] = getelementptr {{.*}}double* [[SEC33:%.+]], i[[Z]] 0
+ // CK19-DAG: [[SEC33]] = getelementptr {{.*}}double* [[SEC333:%.+]], i[[Z]] [[IDX3:%.+]]
+ // CK19-DAG: [[IDX3]] = mul nsw i[[Z]] %{{[^,]+}}, %{{[^,]+}}
+ // CK19-DAG: [[SEC333]] = getelementptr {{.*}}double* [[VAR3]], i[[Z]] [[IDX33:%.+]]
+ // CK19-DAG: [[IDX33]] = mul nsw i[[Z]] 1, %{{[^,]+}}
+
+ // CK19: call void [[CALL31:@.+]](i[[Z]] 23, i[[Z]] %{{[^,]+}}, i[[Z]] %{{[^,]+}}, double* %{{[^,]+}})
+ #pragma omp target map(tofrom: mva[1][ii-2][:5])
+ {
+ mva[1][2][3]++;
+ }
+
+ // Multidimensional array sections.
+ double marras[11][12][13];
+ double mvlaas[11][ii][13];
+ double ***mptras;
+
+ // Region 32
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE32]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE32]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast [11 x [12 x [13 x double]]]* [[VAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast [11 x [12 x [13 x double]]]* [[VAR0]] to i8*
+
+ // CK19: call void [[CALL32:@.+]]([11 x [12 x [13 x double]]]* {{[^,]+}})
+ #pragma omp target map(marras)
+ {
+ marras[1][2][3]++;
+ }
+
+ // Region 33
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE33]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE33]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast [11 x [12 x [13 x double]]]* [[VAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast [12 x [13 x double]]* [[SEC0:%.+]] to i8*
+ // CK19-DAG: [[SEC0]] = getelementptr {{.+}}[11 x [12 x [13 x double]]]* [[VAR0]], i[[Z]] 0, i[[Z]] 0
+
+ // CK19: call void [[CALL33:@.+]]([11 x [12 x [13 x double]]]* {{[^,]+}})
+ #pragma omp target map(marras[:])
+ {
+ marras[1][2][3]++;
+ }
+
+ // Region 34
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE34]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE34]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast [11 x [12 x [13 x double]]]* [[VAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast [12 x [13 x double]]* [[SEC0:%.+]] to i8*
+ // CK19-DAG: [[SEC0]] = getelementptr {{.+}}[11 x [12 x [13 x double]]]* [[VAR0]], i[[Z]] 0, i[[Z]] 0
+
+ // CK19: call void [[CALL34:@.+]]([11 x [12 x [13 x double]]]* {{[^,]+}})
+ #pragma omp target map(marras[:][:][:])
+ {
+ marras[1][2][3]++;
+ }
+
+ // Region 35
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE35]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+ // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
+ //
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0
+
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: store i[[Z]] [[CSVAL0:%[^,]+]], i[[Z]]* [[S0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast [11 x [12 x [13 x double]]]* [[VAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast [13 x double]* [[SEC0:%.+]] to i8*
+ // CK19-DAG: [[SEC0]] = getelementptr {{.+}}[12 x [13 x double]]* [[SEC00:%[^,]+]], i[[Z]] 0, i[[Z]] 0
+ // CK19-DAG: [[SEC00]] = getelementptr {{.+}}[11 x [12 x [13 x double]]]* [[VAR0]], i[[Z]] 0, i[[Z]] 1
+ // CK19-DAG: [[CSVAL0]] = mul nuw i[[Z]] %{{[^,]+}}, 104
+
+ // CK19: call void [[CALL35:@.+]]([11 x [12 x [13 x double]]]* {{[^,]+}})
+ #pragma omp target map(marras[1][:ii][:])
+ {
+ marras[1][2][3]++;
+ }
+
+ // Region 36
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE36]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE36]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast [11 x [12 x [13 x double]]]* [[VAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast [13 x double]* [[SEC0:%.+]] to i8*
+ // CK19-DAG: [[SEC0]] = getelementptr {{.+}}[13 x double]* [[SEC00:%[^,]+]], i{{.+}} 0
+ // CK19-DAG: [[SEC00]] = getelementptr {{.+}}[12 x [13 x double]]* [[SEC000:%[^,]+]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[SEC000]] = getelementptr {{.+}}[11 x [12 x [13 x double]]]* [[VAR0]], i{{.+}} 0, i{{.+}} 0
+
+ // CK19: call void [[CALL36:@.+]]([11 x [12 x [13 x double]]]* {{[^,]+}})
+ #pragma omp target map(marras[:1][:2][:13])
+ {
+ marras[1][2][3]++;
+ }
+
+ // Region 37
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE37]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+ // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
+ //
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* inttoptr (i[[Z]] 11 to i8*), i8** [[BP0]]
+ // CK19-DAG: store i8* inttoptr (i[[Z]] 11 to i8*), i8** [[P0]]
+ // CK19-DAG: store i[[Z]] {{8|4}}, i[[Z]]* [[S0]]
+ //
+ // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[S1:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+ // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK19-DAG: store i[[Z]] {{8|4}}, i[[Z]]* [[S1]]
+ // CK19-DAG: [[CBPVAL1]] = inttoptr i[[Z]] [[VAR1:%.+]] to i8*
+ // CK19-DAG: [[CPVAL1]] = inttoptr i[[Z]] [[VAR11:%.+]] to i8*
+ //
+ // CK19-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: [[S2:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: store i8* [[CBPVAL2:%[^,]+]], i8** [[BP2]]
+ // CK19-DAG: store i8* [[CPVAL2:%[^,]+]], i8** [[P2]]
+ // CK19-DAG: store i[[Z]] [[CSVAL2:%[^,]+]], i[[Z]]* [[S2]]
+ // CK19-DAG: [[CBPVAL2]] = bitcast [13 x double]* [[VAR2:%.+]] to i8*
+ // CK19-DAG: [[CPVAL2]] = bitcast [13 x double]* [[VAR2]] to i8*
+ // CK19-DAG: [[CSVAL2]] = mul nuw i[[Z]] %{{[^,]+}}, 104
+
+ // CK19: call void [[CALL37:@.+]](i[[Z]] 11, i[[Z]] %{{[^,]+}}, [13 x double]* %{{[^,]+}})
+ #pragma omp target map(mvlaas)
+ {
+ mvlaas[1][2][3]++;
+ }
+
+ // Region 38
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE38]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+ // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
+ //
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* inttoptr (i[[Z]] 11 to i8*), i8** [[BP0]]
+ // CK19-DAG: store i8* inttoptr (i[[Z]] 11 to i8*), i8** [[P0]]
+ // CK19-DAG: store i[[Z]] {{8|4}}, i[[Z]]* [[S0]]
+ //
+ // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[S1:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+ // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK19-DAG: store i[[Z]] {{8|4}}, i[[Z]]* [[S1]]
+ // CK19-DAG: [[CBPVAL1]] = inttoptr i[[Z]] [[VAR1:%.+]] to i8*
+ // CK19-DAG: [[CPVAL1]] = inttoptr i[[Z]] [[VAR11:%.+]] to i8*
+ //
+ // CK19-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: [[S2:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: store i8* [[CBPVAL2:%[^,]+]], i8** [[BP2]]
+ // CK19-DAG: store i8* [[CPVAL2:%[^,]+]], i8** [[P2]]
+ // CK19-DAG: store i[[Z]] [[CSVAL2:%[^,]+]], i[[Z]]* [[S2]]
+ // CK19-DAG: [[CBPVAL2]] = bitcast [13 x double]* [[VAR2:%.+]] to i8*
+ // CK19-DAG: [[CPVAL2]] = bitcast [13 x double]* [[SEC2:%.+]] to i8*
+ // CK19-DAG: [[SEC2]] = getelementptr {{.+}}[13 x double]* [[VAR2]], i[[Z]] [[SEC22:%[^,]+]]
+ // CK19-DAG: [[SEC22]] = mul nsw i[[Z]] 0, %{{[^,]+}}
+ // CK19-DAG: [[CSVAL2]] = mul nuw i[[Z]] %{{[^,]+}}, 104
+
+ // CK19: call void [[CALL38:@.+]](i[[Z]] 11, i[[Z]] %{{[^,]+}}, [13 x double]* %{{[^,]+}})
+ #pragma omp target map(mvlaas[:])
+ {
+ mvlaas[1][2][3]++;
+ }
+
+ // Region 39
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE39]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+ // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
+ //
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* inttoptr (i[[Z]] 11 to i8*), i8** [[BP0]]
+ // CK19-DAG: store i8* inttoptr (i[[Z]] 11 to i8*), i8** [[P0]]
+ // CK19-DAG: store i[[Z]] {{8|4}}, i[[Z]]* [[S0]]
+ //
+ // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[S1:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+ // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK19-DAG: store i[[Z]] {{8|4}}, i[[Z]]* [[S1]]
+ // CK19-DAG: [[CBPVAL1]] = inttoptr i[[Z]] [[VAR1:%.+]] to i8*
+ // CK19-DAG: [[CPVAL1]] = inttoptr i[[Z]] [[VAR11:%.+]] to i8*
+ //
+ // CK19-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: [[S2:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: store i8* [[CBPVAL2:%[^,]+]], i8** [[BP2]]
+ // CK19-DAG: store i8* [[CPVAL2:%[^,]+]], i8** [[P2]]
+ // CK19-DAG: store i[[Z]] [[CSVAL2:%[^,]+]], i[[Z]]* [[S2]]
+ // CK19-DAG: [[CBPVAL2]] = bitcast [13 x double]* [[VAR2:%.+]] to i8*
+ // CK19-DAG: [[CPVAL2]] = bitcast [13 x double]* [[SEC2:%.+]] to i8*
+ // CK19-DAG: [[SEC2]] = getelementptr {{.+}}[13 x double]* [[VAR2]], i[[Z]] [[SEC22:%[^,]+]]
+ // CK19-DAG: [[SEC22]] = mul nsw i[[Z]] 0, %{{[^,]+}}
+ // CK19-DAG: [[CSVAL2]] = mul nuw i[[Z]] %{{[^,]+}}, 104
+
+ // CK19: call void [[CALL39:@.+]](i[[Z]] 11, i[[Z]] %{{[^,]+}}, [13 x double]* %{{[^,]+}})
+ #pragma omp target map(mvlaas[:][:][:])
+ {
+ mvlaas[1][2][3]++;
+ }
+
+ // Region 40
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE40]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+ // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
+ //
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* inttoptr (i[[Z]] 11 to i8*), i8** [[BP0]]
+ // CK19-DAG: store i8* inttoptr (i[[Z]] 11 to i8*), i8** [[P0]]
+ // CK19-DAG: store i[[Z]] {{8|4}}, i[[Z]]* [[S0]]
+ //
+ // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[S1:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+ // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK19-DAG: store i[[Z]] {{8|4}}, i[[Z]]* [[S1]]
+ // CK19-DAG: [[CBPVAL1]] = inttoptr i[[Z]] [[VAR1:%.+]] to i8*
+ // CK19-DAG: [[CPVAL1]] = inttoptr i[[Z]] [[VAR11:%.+]] to i8*
+ //
+ // CK19-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: [[S2:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: store i8* [[CBPVAL2:%[^,]+]], i8** [[BP2]]
+ // CK19-DAG: store i8* [[CPVAL2:%[^,]+]], i8** [[P2]]
+ // CK19-DAG: store i[[Z]] [[CSVAL2:%[^,]+]], i[[Z]]* [[S2]]
+ // CK19-DAG: [[CBPVAL2]] = bitcast [13 x double]* [[VAR2:%.+]] to i8*
+ // CK19-DAG: [[CPVAL2]] = bitcast [13 x double]* [[SEC2:%.+]] to i8*
+ // CK19-DAG: [[SEC2]] = getelementptr {{.+}}[13 x double]* [[SEC22:%[^,]+]], i[[Z]] 0
+ // CK19-DAG: [[SEC22]] = getelementptr {{.+}}[13 x double]* [[VAR2]], i[[Z]] [[SEC222:%[^,]+]]
+ // CK19-DAG: [[SEC222]] = mul nsw i[[Z]] 1, %{{[^,]+}}
+
+ // CK19: call void [[CALL40:@.+]](i[[Z]] 11, i[[Z]] %{{[^,]+}}, [13 x double]* %{{[^,]+}})
+ #pragma omp target map(mvlaas[1][:ii][:])
+ {
+ mvlaas[1][2][3]++;
+ }
+
+ // Region 41
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[SIZE41]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE41]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+ //
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* inttoptr (i[[Z]] 11 to i8*), i8** [[BP0]]
+ // CK19-DAG: store i8* inttoptr (i[[Z]] 11 to i8*), i8** [[P0]]
+ //
+ // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+ // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK19-DAG: [[CBPVAL1]] = inttoptr i[[Z]] [[VAR1:%.+]] to i8*
+ // CK19-DAG: [[CPVAL1]] = inttoptr i[[Z]] [[VAR11:%.+]] to i8*
+ //
+ // CK19-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: store i8* [[CBPVAL2:%[^,]+]], i8** [[BP2]]
+ // CK19-DAG: store i8* [[CPVAL2:%[^,]+]], i8** [[P2]]
+ // CK19-DAG: [[CBPVAL2]] = bitcast [13 x double]* [[VAR2:%.+]] to i8*
+ // CK19-DAG: [[CPVAL2]] = bitcast [13 x double]* [[SEC2:%.+]] to i8*
+ // CK19-DAG: [[SEC2]] = getelementptr {{.+}}[13 x double]* [[SEC22:%[^,]+]], i[[Z]] 0
+ // CK19-DAG: [[SEC22]] = getelementptr {{.+}}[13 x double]* [[VAR2]], i[[Z]] [[SEC222:%[^,]+]]
+ // CK19-DAG: [[SEC222]] = mul nsw i[[Z]] 0, %{{[^,]+}}
+
+ // CK19: call void [[CALL41:@.+]](i[[Z]] 11, i[[Z]] %{{[^,]+}}, [13 x double]* %{{[^,]+}})
+ #pragma omp target map(mvlaas[:1][:2][:13])
+ {
+ mvlaas[1][2][3]++;
+ }
+
+ // Region 42
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 3, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[SIZE42]], {{.+}}getelementptr {{.+}}[3 x i{{.+}}]* [[MTYPE42]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast double*** [[VAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast double*** [[SEC0:%.+]] to i8*
+ // CK19-DAG: [[VAR0]] = load double***, double**** [[PTR:%[^,]+]],
+ // CK19-DAG: [[SEC0]] = getelementptr {{.*}}double*** [[SEC00:[^,]+]], i{{.+}} 0
+ // CK19-DAG: [[SEC00]] = load double***, double**** [[PTR]],
+
+ // CK19-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK19-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+ // CK19-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK19-DAG: [[CBPVAL1]] = bitcast double*** [[SEC0]] to i8*
+ // CK19-DAG: [[CPVAL1]] = bitcast double** [[SEC1:%.+]] to i8*
+ // CK19-DAG: [[SEC1]] = getelementptr {{.*}}double** [[SEC11:[^,]+]], i{{.+}} 2
+ // CK19-DAG: [[SEC11]] = load double**, double*** [[SEC111:%[^,]+]],
+ // CK19-DAG: [[SEC111]] = getelementptr {{.*}}double*** [[SEC1111:[^,]+]], i{{.+}} 0
+ // CK19-DAG: [[SEC1111]] = load double***, double**** [[PTR]],
+
+ // CK19-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2
+ // CK19-DAG: store i8* [[CBPVAL2:%[^,]+]], i8** [[BP2]]
+ // CK19-DAG: store i8* [[CPVAL2:%[^,]+]], i8** [[P2]]
+ // CK19-DAG: [[CBPVAL2]] = bitcast double** [[SEC1]] to i8*
+ // CK19-DAG: [[CPVAL2]] = bitcast double* [[SEC2:%.+]] to i8*
+ // CK19-DAG: [[SEC2]] = getelementptr {{.*}}double* [[SEC22:[^,]+]], i{{.+}} 0
+ // CK19-DAG: [[SEC22]] = load double*, double** [[SEC222:%[^,]+]],
+ // CK19-DAG: [[SEC222]] = getelementptr {{.*}}double** [[SEC2222:[^,]+]], i{{.+}} 2
+ // CK19-DAG: [[SEC2222]] = load double**, double*** [[SEC22222:%[^,]+]],
+ // CK19-DAG: [[SEC22222]] = getelementptr {{.*}}double*** [[SEC222222:[^,]+]], i{{.+}} 0
+ // CK19-DAG: [[SEC222222]] = load double***, double**** [[PTR]],
+
+ // CK19: call void [[CALL42:@.+]](double*** {{[^,]+}})
+ #pragma omp target map(mptras[:1][2][:13])
+ {
+ mptras[1][2][3]++;
+ }
+
+ // Region 43 - the memory is not contiguous for this map - will map the whole last dimension.
+ // CK19-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[Z]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE43]]{{.+}})
+ // CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+ // CK19-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
+ //
+ // CK19-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK19-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0
+
+ // CK19-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK19-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK19-DAG: store i[[Z]] [[CSVAL0:%[^,]+]], i[[Z]]* [[S0]]
+ // CK19-DAG: [[CBPVAL0]] = bitcast [11 x [12 x [13 x double]]]* [[VAR0:%.+]] to i8*
+ // CK19-DAG: [[CPVAL0]] = bitcast [13 x double]* [[SEC0:%.+]] to i8*
+ // CK19-DAG: [[SEC0]] = getelementptr {{.+}}[12 x [13 x double]]* [[SEC00:%[^,]+]], i[[Z]] 0, i[[Z]] 0
+ // CK19-DAG: [[SEC00]] = getelementptr {{.+}}[11 x [12 x [13 x double]]]* [[VAR0]], i[[Z]] 0, i[[Z]] 1
+ // CK19-DAG: [[CSVAL0]] = mul nuw i[[Z]] %{{[^,]+}}, 104
+
+ // CK19: call void [[CALL43:@.+]]([11 x [12 x [13 x double]]]* {{[^,]+}})
+ #pragma omp target map(marras[1][:ii][1:])
+ {
+ marras[1][2][3]++;
+ }
+
+}
+
+// CK19: define {{.+}}[[CALL00]]
+// CK19: define {{.+}}[[CALL01]]
+// CK19: define {{.+}}[[CALL02]]
+// CK19: define {{.+}}[[CALL03]]
+// CK19: define {{.+}}[[CALL04]]
+// CK19: define {{.+}}[[CALL05]]
+// CK19: define {{.+}}[[CALL06]]
+// CK19: define {{.+}}[[CALL07]]
+// CK19: define {{.+}}[[CALL08]]
+// CK19: define {{.+}}[[CALL09]]
+// CK19: define {{.+}}[[CALL10]]
+// CK19: define {{.+}}[[CALL11]]
+// CK19: define {{.+}}[[CALL12]]
+// CK19: define {{.+}}[[CALL13]]
+// CK19: define {{.+}}[[CALL14]]
+// CK19: define {{.+}}[[CALL15]]
+// CK19: define {{.+}}[[CALL16]]
+// CK19: define {{.+}}[[CALL17]]
+// CK19: define {{.+}}[[CALL18]]
+// CK19: define {{.+}}[[CALL19]]
+// CK19: define {{.+}}[[CALL20]]
+// CK19: define {{.+}}[[CALL21]]
+// CK19: define {{.+}}[[CALL22]]
+// CK19: define {{.+}}[[CALL23]]
+// CK19: define {{.+}}[[CALL24]]
+// CK19: define {{.+}}[[CALL25]]
+// CK19: define {{.+}}[[CALL26]]
+// CK19: define {{.+}}[[CALL27]]
+// CK19: define {{.+}}[[CALL28]]
+// CK19: define {{.+}}[[CALL29]]
+// CK19: define {{.+}}[[CALL30]]
+// CK19: define {{.+}}[[CALL31]]
+// CK19: define {{.+}}[[CALL32]]
+// CK19: define {{.+}}[[CALL33]]
+// CK19: define {{.+}}[[CALL34]]
+// CK19: define {{.+}}[[CALL35]]
+// CK19: define {{.+}}[[CALL36]]
+// CK19: define {{.+}}[[CALL37]]
+// CK19: define {{.+}}[[CALL38]]
+// CK19: define {{.+}}[[CALL39]]
+// CK19: define {{.+}}[[CALL40]]
+// CK19: define {{.+}}[[CALL41]]
+// CK19: define {{.+}}[[CALL42]]
+// CK19: define {{.+}}[[CALL43]]
+
+#endif
+///==========================================================================///
+// RUN: %clang_cc1 -DCK20 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK20 --check-prefix CK20-64
+// RUN: %clang_cc1 -DCK20 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK20 --check-prefix CK20-64
+// RUN: %clang_cc1 -DCK20 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK20 --check-prefix CK20-32
+// RUN: %clang_cc1 -DCK20 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK20 --check-prefix CK20-32
+#ifdef CK20
+
+// CK20: [[SIZE00:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4]
+// CK20: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i32] [i32 33]
+
+// CK20: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 20]
+// CK20: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 33]
+
+// CK20: [[SIZE02:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
+// CK20: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i32] [i32 34]
+
+// CK20: [[SIZE03:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 12]
+// CK20: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i32] [i32 34]
+
+// CK20-LABEL: explicit_maps_references_and_function_args
+void explicit_maps_references_and_function_args (int a, float b, int (&c)[10], float *d){
+
+ int &aa = a;
+ float &bb = b;
+ int (&cc)[10] = c;
+ float *&dd = d;
+
+ // Region 00
+ // CK20-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK20-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK20-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK20-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK20-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK20-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK20-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK20-DAG: [[CBPVAL0]] = bitcast i32* [[RVAR0:%.+]] to i8*
+ // CK20-DAG: [[CPVAL0]] = bitcast i32* [[RVAR00:%.+]] to i8*
+ // CK20-DAG: [[RVAR0]] = load i32*, i32** [[VAR0:%[^,]+]]
+ // CK20-DAG: [[RVAR00]] = load i32*, i32** [[VAR0]]
+
+ // CK20: call void [[CALL00:@.+]](i32* {{[^,]+}})
+ #pragma omp target map(to:aa)
+ {
+ aa += 1;
+ }
+
+ // Region 01
+ // CK20-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
+ // CK20-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK20-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK20-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK20-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK20-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK20-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK20-DAG: [[CBPVAL0]] = bitcast [10 x i32]* [[RVAR0:%.+]] to i8*
+ // CK20-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK20-DAG: [[SEC0]] = getelementptr {{.*}}[10 x i32]* [[RVAR00:%.+]], i{{.+}} 0, i{{.+}} 0
+ // CK20-DAG: [[RVAR0]] = load [10 x i32]*, [10 x i32]** [[VAR0:%[^,]+]]
+ // CK20-DAG: [[RVAR00]] = load [10 x i32]*, [10 x i32]** [[VAR0]]
+
+ // CK20: call void [[CALL01:@.+]]([10 x i32]* {{[^,]+}})
+ #pragma omp target map(to:cc[:5])
+ {
+ cc[3] += 1;
+ }
+
+ // Region 02
+ // CK20-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK20-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK20-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK20-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK20-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK20-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK20-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK20-DAG: [[CBPVAL0]] = bitcast float* [[VAR0:%.+]] to i8*
+ // CK20-DAG: [[CPVAL0]] = bitcast float* [[VAR0]] to i8*
+
+ // CK20: call void [[CALL02:@.+]](float* {{[^,]+}})
+ #pragma omp target map(from:b)
+ {
+ b += 1.0f;
+ }
+
+ // Region 03
+ // CK20-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
+ // CK20-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK20-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK20-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK20-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK20-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK20-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK20-DAG: [[CBPVAL0]] = bitcast float* [[RVAR0:%.+]] to i8*
+ // CK20-DAG: [[CPVAL0]] = bitcast float* [[SEC0:%.+]] to i8*
+ // CK20-DAG: [[RVAR0]] = load float*, float** [[VAR0:%[^,]+]]
+ // CK20-DAG: [[SEC0]] = getelementptr {{.*}}float* [[RVAR00:%.+]], i{{.+}} 2
+ // CK20-DAG: [[RVAR00]] = load float*, float** [[VAR0]]
+
+ // CK20: call void [[CALL03:@.+]](float* {{[^,]+}})
+ #pragma omp target map(from:d[2:3])
+ {
+ d[2] += 1.0f;
+ }
+}
+
+// CK20: define {{.+}}[[CALL00]]
+// CK20: define {{.+}}[[CALL01]]
+// CK20: define {{.+}}[[CALL02]]
+// CK20: define {{.+}}[[CALL03]]
+
+#endif
+///==========================================================================///
+// RUN: %clang_cc1 -DCK21 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK21 --check-prefix CK21-64
+// RUN: %clang_cc1 -DCK21 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK21 --check-prefix CK21-64
+// RUN: %clang_cc1 -DCK21 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK21 --check-prefix CK21-32
+// RUN: %clang_cc1 -DCK21 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK21 --check-prefix CK21-32
+#ifdef CK21
+// CK21: [[ST:%.+]] = type { i32, i32, float* }
+
+// CK21: [[SIZE00:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4]
+// CK21: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK21: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 492]
+// CK21: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK21: [[SIZE02:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 500]
+// CK21: [[MTYPE02:@.+]] = private {{.*}}constant [2 x i32] [i32 34, i32 18]
+
+// CK21: [[SIZE03:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 492]
+// CK21: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i32] [i32 34]
+
+// CK21: [[SIZE04:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
+// CK21: [[MTYPE04:@.+]] = private {{.*}}constant [1 x i32] [i32 34]
+
+// CK21: [[SIZE05:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] 4, i[[Z]] 4]
+// CK21: [[MTYPE05:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 3]
+
+// CK21-LABEL: explicit_maps_template_args_and_members
+
+template <int X, typename T>
+struct CC {
+ T A;
+ int A2;
+ float *B;
+
+ int foo(T arg) {
+ float la[X];
+ T *lb;
+
+ // Region 00
+ // CK21-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK21-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK21-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK21-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK21-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK21-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK21-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK21-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[VAR0:%.+]] to i8*
+ // CK21-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK21-DAG: [[SEC0]] = getelementptr {{.*}}[[ST]]* [[VAR0:%.+]], i{{.+}} 0, i{{.+}} 0
+
+ // CK21: call void [[CALL00:@.+]]([[ST]]* {{[^,]+}})
+ #pragma omp target map(A)
+ {
+ A += 1;
+ }
+
+ // Region 01
+ // CK21-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
+ // CK21-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK21-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK21-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK21-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK21-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK21-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK21-DAG: [[CBPVAL0]] = bitcast i32* [[RVAR0:%.+]] to i8*
+ // CK21-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK21-DAG: [[RVAR0]] = load i32*, i32** [[VAR0:%[^,]+]]
+ // CK21-DAG: [[SEC0]] = getelementptr {{.*}}i32* [[RVAR00:%.+]], i{{.+}} 0
+ // CK21-DAG: [[RVAR00]] = load i32*, i32** [[VAR0]]
+
+ // CK21: call void [[CALL01:@.+]](i32* {{[^,]+}})
+ #pragma omp target map(lb[:X])
+ {
+ lb[4] += 1;
+ }
+
+ // Region 02
+ // CK21-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK21-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK21-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK21-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK21-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK21-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK21-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK21-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[VAR0:%.+]] to i8*
+ // CK21-DAG: [[CPVAL0]] = bitcast float** [[SEC0:%.+]] to i8*
+ // CK21-DAG: [[SEC0]] = getelementptr {{.*}}[[ST]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2
+
+ // CK21-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK21-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK21-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+ // CK21-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK21-DAG: [[CBPVAL1]] = bitcast float** [[SEC0]] to i8*
+ // CK21-DAG: [[CPVAL1]] = bitcast float* [[SEC1:%.+]] to i8*
+ // CK21-DAG: [[SEC1]] = getelementptr {{.*}}float* [[RVAR1:%[^,]+]], i{{.+}} 123
+ // CK21-DAG: [[RVAR1]] = load float*, float** [[SEC1_:%[^,]+]]
+ // CK21-DAG: [[SEC1_]] = getelementptr {{.*}}[[ST]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2
+
+ // CK21: call void [[CALL02:@.+]]([[ST]]* {{[^,]+}})
+ #pragma omp target map(from:B[X:X+2])
+ {
+ B[2] += 1.0f;
+ }
+
+ // Region 03
+ // CK21-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
+ // CK21-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK21-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK21-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK21-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK21-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK21-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK21-DAG: [[CBPVAL0]] = bitcast [123 x float]* [[VAR0:%.+]] to i8*
+ // CK21-DAG: [[CPVAL0]] = bitcast [123 x float]* [[VAR0]] to i8*
+
+ // CK21: call void [[CALL03:@.+]]([123 x float]* {{[^,]+}})
+ #pragma omp target map(from:la)
+ {
+ la[3] += 1.0f;
+ }
+
+ // Region 04
+ // CK21-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE04]]{{.+}})
+ // CK21-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK21-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK21-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK21-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK21-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK21-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK21-DAG: [[CBPVAL0]] = bitcast i32* [[VAR0:%.+]] to i8*
+ // CK21-DAG: [[CPVAL0]] = bitcast i32* [[VAR0]] to i8*
+
+ // CK21: call void [[CALL04:@.+]](i32* {{[^,]+}})
+ #pragma omp target map(from:arg)
+ {
+ arg +=1;
+ }
+
+ // Make sure the extra flag is passed to the second map.
+ // Region 05
+ // CK21-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE05]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE05]]{{.+}})
+ // CK21-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK21-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK21-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK21-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK21-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK21-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK21-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[VAR0:%.+]] to i8*
+ // CK21-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK21-DAG: [[SEC0]] = getelementptr {{.*}}[[ST]]* [[VAR0]], i{{.+}} 0, i{{.+}} 0
+
+ // CK21-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK21-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK21-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+ // CK21-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK21-DAG: [[CBPVAL1]] = bitcast [[ST]]* [[VAR1:%.+]] to i8*
+ // CK21-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8*
+ // CK21-DAG: [[SEC1]] = getelementptr {{.*}}[[ST]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1
+
+ // CK21: call void [[CALL05:@.+]]([[ST]]* {{[^,]+}})
+ #pragma omp target map(A, A2)
+ {
+ A += 1;
+ A2 += 1;
+ }
+ return A;
+ }
+};
+
+int explicit_maps_template_args_and_members(int a){
+ CC<123,int> c;
+ return c.foo(a);
+}
+
+// CK21: define {{.+}}[[CALL00]]
+// CK21: define {{.+}}[[CALL01]]
+// CK21: define {{.+}}[[CALL02]]
+// CK21: define {{.+}}[[CALL03]]
+// CK21: define {{.+}}[[CALL04]]
+// CK21: define {{.+}}[[CALL05]]
+#endif
+///==========================================================================///
+// RUN: %clang_cc1 -DCK22 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK22 --check-prefix CK22-64
+// RUN: %clang_cc1 -DCK22 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK22 --check-prefix CK22-64
+// RUN: %clang_cc1 -DCK22 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK22 --check-prefix CK22-32
+// RUN: %clang_cc1 -DCK22 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK22 --check-prefix CK22-32
+#ifdef CK22
+
+// CK22-DAG: [[ST:%.+]] = type { float }
+// CK22-DAG: [[STT:%.+]] = type { i32 }
+
+// CK22: [[SIZE00:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4]
+// CK22: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK22: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 400]
+// CK22: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK22: [[SIZE02:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] {{8|4}}]
+// CK22: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK22: [[SIZE03:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 16]
+// CK22: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK22: [[SIZE04:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 20]
+// CK22: [[MTYPE04:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK22: [[SIZE05:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
+// CK22: [[MTYPE05:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK22: [[SIZE06:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 400]
+// CK22: [[MTYPE06:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK22: [[SIZE07:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] {{8|4}}]
+// CK22: [[MTYPE07:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK22: [[SIZE08:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 16]
+// CK22: [[MTYPE08:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK22: [[SIZE09:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 20]
+// CK22: [[MTYPE09:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK22: [[SIZE10:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
+// CK22: [[MTYPE10:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK22: [[SIZE11:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 400]
+// CK22: [[MTYPE11:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK22: [[SIZE12:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] {{8|4}}]
+// CK22: [[MTYPE12:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK22: [[SIZE13:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 16]
+// CK22: [[MTYPE13:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK22: [[SIZE14:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 20]
+// CK22: [[MTYPE14:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+int a;
+int c[100];
+int *d;
+
+struct ST {
+ float fa;
+};
+
+ST sa ;
+ST sc[100];
+ST *sd;
+
+template<typename T>
+struct STT {
+ T fa;
+};
+
+STT<int> sta ;
+STT<int> stc[100];
+STT<int> *std;
+
+// CK22-LABEL: explicit_maps_globals
+int explicit_maps_globals(void){
+ // Region 00
+ // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: store i8* bitcast (i32* @a to i8*), i8** [[BP0]]
+ // CK22-DAG: store i8* bitcast (i32* @a to i8*), i8** [[P0]]
+
+ // CK22: call void [[CALL00:@.+]](i32* {{[^,]+}})
+ #pragma omp target map(a)
+ { a+=1; }
+
+ // Region 01
+ // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
+ // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: store i8* bitcast ([100 x i32]* @c to i8*), i8** [[BP0]]
+ // CK22-DAG: store i8* bitcast ([100 x i32]* @c to i8*), i8** [[P0]]
+
+ // CK22: call void [[CALL01:@.+]]([100 x i32]* {{[^,]+}})
+ #pragma omp target map(c)
+ { c[3]+=1; }
+
+ // Region 02
+ // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: store i8* bitcast (i32** @d to i8*), i8** [[BP0]]
+ // CK22-DAG: store i8* bitcast (i32** @d to i8*), i8** [[P0]]
+
+ // CK22: call void [[CALL02:@.+]](i32** {{[^,]+}})
+ #pragma omp target map(d)
+ { d[3]+=1; }
+
+ // Region 03
+ // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
+ // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: store i8* bitcast ([100 x i32]* @c to i8*), i8** [[BP0]]
+ // CK22-DAG: store i8* bitcast (i32* getelementptr inbounds ([100 x i32], [100 x i32]* @c, i{{.+}} 0, i{{.+}} 1) to i8*), i8** [[P0]]
+
+ // CK22: call void [[CALL03:@.+]]([100 x i32]* {{[^,]+}})
+ #pragma omp target map(c[1:4])
+ { c[3]+=1; }
+
+ // Region 04
+ // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE04]]{{.+}})
+ // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK22-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK22-DAG: [[CBPVAL0]] = bitcast i32* [[RVAR0:%.+]] to i8*
+ // CK22-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK22-DAG: [[RVAR0]] = load i32*, i32** @d
+ // CK22-DAG: [[SEC0]] = getelementptr {{.*}}i32* [[RVAR00:%.+]], i{{.+}} 2
+ // CK22-DAG: [[RVAR00]] = load i32*, i32** @d
+
+ // CK22: call void [[CALL04:@.+]](i32* {{[^,]+}})
+ #pragma omp target map(d[2:5])
+ { d[3]+=1; }
+
+ // Region 05
+ // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE05]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE05]]{{.+}})
+ // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: store i8* bitcast ([[ST]]* @sa to i8*), i8** [[BP0]]
+ // CK22-DAG: store i8* bitcast ([[ST]]* @sa to i8*), i8** [[P0]]
+
+ // CK22: call void [[CALL05:@.+]]([[ST]]* {{[^,]+}})
+ #pragma omp target map(sa)
+ { sa.fa+=1; }
+
+ // Region 06
+ // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE06]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE06]]{{.+}})
+ // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: store i8* bitcast ([100 x [[ST]]]* @sc to i8*), i8** [[BP0]]
+ // CK22-DAG: store i8* bitcast ([100 x [[ST]]]* @sc to i8*), i8** [[P0]]
+
+ // CK22: call void [[CALL06:@.+]]([100 x [[ST]]]* {{[^,]+}})
+ #pragma omp target map(sc)
+ { sc[3].fa+=1; }
+
+ // Region 07
+ // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE07]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE07]]{{.+}})
+ // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: store i8* bitcast ([[ST]]** @sd to i8*), i8** [[BP0]]
+ // CK22-DAG: store i8* bitcast ([[ST]]** @sd to i8*), i8** [[P0]]
+
+ // CK22: call void [[CALL07:@.+]]([[ST]]** {{[^,]+}})
+ #pragma omp target map(sd)
+ { sd[3].fa+=1; }
+
+ // Region 08
+ // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE08]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE08]]{{.+}})
+ // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: store i8* bitcast ([100 x [[ST]]]* @sc to i8*), i8** [[BP0]]
+ // CK22-DAG: store i8* bitcast ([[ST]]* getelementptr inbounds ([100 x [[ST]]], [100 x [[ST]]]* @sc, i{{.+}} 0, i{{.+}} 1) to i8*), i8** [[P0]]
+
+ // CK22: call void [[CALL08:@.+]]([100 x [[ST]]]* {{[^,]+}})
+ #pragma omp target map(sc[1:4])
+ { sc[3].fa+=1; }
+
+ // Region 09
+ // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE09]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE09]]{{.+}})
+ // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK22-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK22-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[RVAR0:%.+]] to i8*
+ // CK22-DAG: [[CPVAL0]] = bitcast [[ST]]* [[SEC0:%.+]] to i8*
+ // CK22-DAG: [[RVAR0]] = load [[ST]]*, [[ST]]** @sd
+ // CK22-DAG: [[SEC0]] = getelementptr {{.*}}[[ST]]* [[RVAR00:%.+]], i{{.+}} 2
+ // CK22-DAG: [[RVAR00]] = load [[ST]]*, [[ST]]** @sd
+
+ // CK22: call void [[CALL09:@.+]]([[ST]]* {{[^,]+}})
+ #pragma omp target map(sd[2:5])
+ { sd[3].fa+=1; }
+
+ // Region 10
+ // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE10]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE10]]{{.+}})
+ // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: store i8* bitcast ([[STT]]* @sta to i8*), i8** [[BP0]]
+ // CK22-DAG: store i8* bitcast ([[STT]]* @sta to i8*), i8** [[P0]]
+
+ // CK22: call void [[CALL10:@.+]]([[STT]]* {{[^,]+}})
+ #pragma omp target map(sta)
+ { sta.fa+=1; }
+
+ // Region 11
+ // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE11]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE11]]{{.+}})
+ // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: store i8* bitcast ([100 x [[STT]]]* @stc to i8*), i8** [[BP0]]
+ // CK22-DAG: store i8* bitcast ([100 x [[STT]]]* @stc to i8*), i8** [[P0]]
+
+ // CK22: call void [[CALL11:@.+]]([100 x [[STT]]]* {{[^,]+}})
+ #pragma omp target map(stc)
+ { stc[3].fa+=1; }
+
+ // Region 12
+ // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE12]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE12]]{{.+}})
+ // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: store i8* bitcast ([[STT]]** @std to i8*), i8** [[BP0]]
+ // CK22-DAG: store i8* bitcast ([[STT]]** @std to i8*), i8** [[P0]]
+
+ // CK22: call void [[CALL12:@.+]]([[STT]]** {{[^,]+}})
+ #pragma omp target map(std)
+ { std[3].fa+=1; }
+
+ // Region 13
+ // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE13]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE13]]{{.+}})
+ // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: store i8* bitcast ([100 x [[STT]]]* @stc to i8*), i8** [[BP0]]
+ // CK22-DAG: store i8* bitcast ([[STT]]* getelementptr inbounds ([100 x [[STT]]], [100 x [[STT]]]* @stc, i{{.+}} 0, i{{.+}} 1) to i8*), i8** [[P0]]
+
+ // CK22: call void [[CALL13:@.+]]([100 x [[STT]]]* {{[^,]+}})
+ #pragma omp target map(stc[1:4])
+ { stc[3].fa+=1; }
+
+ // Region 14
+ // CK22-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE14]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE14]]{{.+}})
+ // CK22-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK22-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK22-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK22-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK22-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK22-DAG: [[CBPVAL0]] = bitcast [[STT]]* [[RVAR0:%.+]] to i8*
+ // CK22-DAG: [[CPVAL0]] = bitcast [[STT]]* [[SEC0:%.+]] to i8*
+ // CK22-DAG: [[RVAR0]] = load [[STT]]*, [[STT]]** @std
+ // CK22-DAG: [[SEC0]] = getelementptr {{.*}}[[STT]]* [[RVAR00:%.+]], i{{.+}} 2
+ // CK22-DAG: [[RVAR00]] = load [[STT]]*, [[STT]]** @std
+
+ // CK22: call void [[CALL14:@.+]]([[STT]]* {{[^,]+}})
+ #pragma omp target map(std[2:5])
+ { std[3].fa+=1; }
+
+ return 0;
+}
+// CK22: define {{.+}}[[CALL00]]
+// CK22: define {{.+}}[[CALL01]]
+// CK22: define {{.+}}[[CALL02]]
+// CK22: define {{.+}}[[CALL03]]
+// CK22: define {{.+}}[[CALL04]]
+// CK22: define {{.+}}[[CALL05]]
+// CK22: define {{.+}}[[CALL06]]
+// CK22: define {{.+}}[[CALL07]]
+// CK22: define {{.+}}[[CALL08]]
+// CK22: define {{.+}}[[CALL09]]
+// CK22: define {{.+}}[[CALL10]]
+// CK22: define {{.+}}[[CALL11]]
+// CK22: define {{.+}}[[CALL12]]
+// CK22: define {{.+}}[[CALL13]]
+// CK22: define {{.+}}[[CALL14]]
+#endif
+///==========================================================================///
+// RUN: %clang_cc1 -std=c++11 -DCK23 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK23 --check-prefix CK23-64
+// RUN: %clang_cc1 -std=c++11 -DCK23 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -std=c++11 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK23 --check-prefix CK23-64
+// RUN: %clang_cc1 -std=c++11 -DCK23 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK23 --check-prefix CK23-32
+// RUN: %clang_cc1 -std=c++11 -DCK23 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -std=c++11 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK23 --check-prefix CK23-32
+#ifdef CK23
+
+// CK23: [[SIZE00:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4]
+// CK23: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK23: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
+// CK23: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK23: [[SIZE02:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 400]
+// CK23: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK23: [[SIZE03:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] {{8|4}}]
+// CK23: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK23: [[SIZE04:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 16]
+// CK23: [[MTYPE04:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK23: [[SIZE05:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 16]
+// CK23: [[MTYPE05:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK23-LABEL: explicit_maps_inside_captured
+int explicit_maps_inside_captured(int a){
+ float b;
+ float c[100];
+ float *d;
+
+ // CK23: call void @{{.*}}explicit_maps_inside_captured{{.*}}([[SA:%.+]]* {{.*}})
+ // CK23: define {{.*}}explicit_maps_inside_captured{{.*}}
+ [&](void){
+ // Region 00
+ // CK23-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK23-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK23-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK23-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK23-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK23-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK23-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK23-DAG: [[CBPVAL0]] = bitcast i32* [[VAR0:%.+]] to i8*
+ // CK23-DAG: [[CPVAL0]] = bitcast i32* [[VAR00:%.+]] to i8*
+ // CK23-DAG: [[VAR0]] = load i32*, i32** [[CAP0:%[^,]+]]
+ // CK23-DAG: [[CAP0]] = getelementptr inbounds [[SA]], [[SA]]
+ // CK23-DAG: [[VAR00]] = load i32*, i32** [[CAP00:%[^,]+]]
+ // CK23-DAG: [[CAP00]] = getelementptr inbounds [[SA]], [[SA]]
+
+ // CK23: call void [[CALL00:@.+]](i32* {{[^,]+}})
+ #pragma omp target map(a)
+ { a+=1; }
+ // Region 01
+ // CK23-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
+ // CK23-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK23-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK23-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK23-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK23-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK23-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK23-DAG: [[CBPVAL0]] = bitcast float* [[VAR0:%.+]] to i8*
+ // CK23-DAG: [[CPVAL0]] = bitcast float* [[VAR00:%.+]] to i8*
+ // CK23-DAG: [[VAR0]] = load float*, float** [[CAP0:%[^,]+]]
+ // CK23-DAG: [[CAP0]] = getelementptr inbounds [[SA]], [[SA]]
+ // CK23-DAG: [[VAR00]] = load float*, float** [[CAP00:%[^,]+]]
+ // CK23-DAG: [[CAP00]] = getelementptr inbounds [[SA]], [[SA]]
+
+ // CK23: call void [[CALL01:@.+]](float* {{[^,]+}})
+ #pragma omp target map(b)
+ { b+=1; }
+ // Region 02
+ // CK23-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK23-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK23-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK23-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK23-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK23-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK23-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK23-DAG: [[CBPVAL0]] = bitcast [100 x float]* [[VAR0:%.+]] to i8*
+ // CK23-DAG: [[CPVAL0]] = bitcast [100 x float]* [[VAR00:%.+]] to i8*
+ // CK23-DAG: [[VAR0]] = load [100 x float]*, [100 x float]** [[CAP0:%[^,]+]]
+ // CK23-DAG: [[CAP0]] = getelementptr inbounds [[SA]], [[SA]]
+ // CK23-DAG: [[VAR00]] = load [100 x float]*, [100 x float]** [[CAP00:%[^,]+]]
+ // CK23-DAG: [[CAP00]] = getelementptr inbounds [[SA]], [[SA]]
+
+ // CK23: call void [[CALL02:@.+]]([100 x float]* {{[^,]+}})
+ #pragma omp target map(c)
+ { c[3]+=1; }
+
+ // Region 03
+ // CK23-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
+ // CK23-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK23-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK23-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK23-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK23-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK23-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK23-DAG: [[CBPVAL0]] = bitcast float** [[VAR0:%.+]] to i8*
+ // CK23-DAG: [[CPVAL0]] = bitcast float** [[VAR00:%.+]] to i8*
+ // CK23-DAG: [[VAR0]] = load float**, float*** [[CAP0:%[^,]+]]
+ // CK23-DAG: [[CAP0]] = getelementptr inbounds [[SA]], [[SA]]
+ // CK23-DAG: [[VAR00]] = load float**, float*** [[CAP00:%[^,]+]]
+ // CK23-DAG: [[CAP00]] = getelementptr inbounds [[SA]], [[SA]]
+
+ // CK23: call void [[CALL03:@.+]](float** {{[^,]+}})
+ #pragma omp target map(d)
+ { d[3]+=1; }
+ // Region 04
+ // CK23-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE04]]{{.+}})
+ // CK23-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK23-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK23-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK23-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK23-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK23-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK23-DAG: [[CBPVAL0]] = bitcast [100 x float]* [[VAR0:%.+]] to i8*
+ // CK23-DAG: [[CPVAL0]] = bitcast float* [[SEC0:%.+]] to i8*
+ // CK23-DAG: [[SEC0]] = getelementptr {{.*}}[100 x float]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 2
+ // CK23-DAG: [[VAR0]] = load [100 x float]*, [100 x float]** [[CAP0:%[^,]+]]
+ // CK23-DAG: [[CAP0]] = getelementptr inbounds [[SA]], [[SA]]
+ // CK23-DAG: [[VAR00]] = load [100 x float]*, [100 x float]** [[CAP00:%[^,]+]]
+ // CK23-DAG: [[CAP00]] = getelementptr inbounds [[SA]], [[SA]]
+
+ // CK23: call void [[CALL04:@.+]]([100 x float]* {{[^,]+}})
+ #pragma omp target map(c[2:4])
+ { c[3]+=1; }
+
+ // Region 05
+ // CK23-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE05]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE05]]{{.+}})
+ // CK23-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK23-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK23-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK23-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK23-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK23-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK23-DAG: [[CBPVAL0]] = bitcast float* [[RVAR0:%.+]] to i8*
+ // CK23-DAG: [[CPVAL0]] = bitcast float* [[SEC0:%.+]] to i8*
+ // CK23-DAG: [[RVAR0]] = load float*, float** [[VAR0:%[^,]+]]
+ // CK23-DAG: [[SEC0]] = getelementptr {{.*}}float* [[RVAR00:%.+]], i{{.+}} 2
+ // CK23-DAG: [[RVAR00]] = load float*, float** [[VAR00:%[^,]+]]
+ // CK23-DAG: [[VAR0]] = load float**, float*** [[CAP0:%[^,]+]]
+ // CK23-DAG: [[CAP0]] = getelementptr inbounds [[SA]], [[SA]]
+ // CK23-DAG: [[VAR00]] = load float**, float*** [[CAP00:%[^,]+]]
+ // CK23-DAG: [[CAP00]] = getelementptr inbounds [[SA]], [[SA]]
+
+ // CK23: call void [[CALL05:@.+]](float* {{[^,]+}})
+ #pragma omp target map(d[2:4])
+ { d[3]+=1; }
+ }();
+ return b;
+}
+
+// CK23: define {{.+}}[[CALL00]]
+// CK23: define {{.+}}[[CALL01]]
+// CK23: define {{.+}}[[CALL02]]
+// CK23: define {{.+}}[[CALL03]]
+// CK23: define {{.+}}[[CALL04]]
+// CK23: define {{.+}}[[CALL05]]
+#endif
+///==========================================================================///
+// RUN: %clang_cc1 -DCK24 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK24 --check-prefix CK24-64
+// RUN: %clang_cc1 -DCK24 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK24 --check-prefix CK24-64
+// RUN: %clang_cc1 -DCK24 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK24 --check-prefix CK24-32
+// RUN: %clang_cc1 -DCK24 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK24 --check-prefix CK24-32
+#ifdef CK24
+
+// CK24-DAG: [[SC:%.+]] = type { i32, [[SB:%.+]], [[SB:%.+]]*, [10 x i32] }
+// CK24-DAG: [[SB]] = type { i32, [[SA:%.+]], [10 x [[SA:%.+]]], [10 x [[SA:%.+]]*], [[SA:%.+]]* }
+// CK24-DAG: [[SA]] = type { i32, [[SA]]*, [10 x i32] }
+
+struct SA{
+ int a;
+ struct SA *p;
+ int b[10];
+};
+struct SB{
+ int a;
+ struct SA s;
+ struct SA sa[10];
+ struct SA *sp[10];
+ struct SA *p;
+};
+struct SC{
+ int a;
+ struct SB s;
+ struct SB *p;
+ int b[10];
+};
+
+// CK24: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4]
+// CK24: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK24: [[SIZE02:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] {{56|48}}]
+// CK24: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK24: [[SIZE03:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
+// CK24: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK24: [[SIZE04:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 20]
+// CK24: [[MTYPE04:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK24: [[SIZE05:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{3560|2880}}]
+// CK24: [[MTYPE05:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19]
+
+// CK24: [[SIZE06:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
+// CK24: [[MTYPE06:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK24: [[SIZE07:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 4]
+// CK24: [[MTYPE07:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19]
+
+// CK24: [[SIZE08:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 4]
+// CK24: [[MTYPE08:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19]
+
+// CK24: [[SIZE09:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 4]
+// CK24: [[MTYPE09:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19]
+
+// CK24: [[SIZE10:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 8]
+// CK24: [[MTYPE10:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK24: [[SIZE11:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}]
+// CK24: [[MTYPE11:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19]
+
+// CK24: [[SIZE12:@.+]] = private {{.*}}constant [4 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] 4]
+// CK24: [[MTYPE12:@.+]] = private {{.*}}constant [4 x i32] [i32 35, i32 19, i32 19, i32 19]
+
+// CK24: [[SIZE13:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
+// CK24: [[MTYPE13:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK24: [[SIZE14:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] {{56|48}}]
+// CK24: [[MTYPE14:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK24: [[SIZE15:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
+// CK24: [[MTYPE15:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK24: [[SIZE16:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 20]
+// CK24: [[MTYPE16:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK24: [[SIZE17:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{3560|2880}}]
+// CK24: [[MTYPE17:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19]
+
+// CK24: [[SIZE18:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
+// CK24: [[MTYPE18:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK24: [[SIZE19:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 4]
+// CK24: [[MTYPE19:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19]
+
+// CK24: [[SIZE20:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 4]
+// CK24: [[MTYPE20:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19]
+
+// CK24: [[SIZE21:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] 4]
+// CK24: [[MTYPE21:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19]
+
+// CK24: [[SIZE22:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] {{8|4}}]
+// CK24: [[MTYPE22:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK24: [[SIZE23:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}]
+// CK24: [[MTYPE23:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 19]
+
+// CK24: [[SIZE24:@.+]] = private {{.*}}constant [4 x i[[Z]]] [i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] {{8|4}}, i[[Z]] 4]
+// CK24: [[MTYPE24:@.+]] = private {{.*}}constant [4 x i32] [i32 35, i32 19, i32 19, i32 19]
+
+// CK24-LABEL: explicit_maps_struct_fields
+int explicit_maps_struct_fields(int a){
+ SC s;
+ SC *p;
+
+// Region 01
+// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
+// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8*
+// CK24-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 0
+
+// CK24: call void [[CALL01:@.+]]([[SC]]* {{[^,]+}})
+#pragma omp target map(s.a)
+ { s.a++; }
+
+// Region 02
+// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
+// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8*
+// CK24-DAG: [[CPVAL0]] = bitcast [[SA]]* [[SEC0:%.+]] to i8*
+// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SB]]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1
+
+// CK24: call void [[CALL02:@.+]]([[SC]]* {{[^,]+}})
+#pragma omp target map(s.s.s)
+ { s.a++; }
+
+// Region 03
+// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
+// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8*
+// CK24-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SA]]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SB]]* [[SEC000:%[^,]+]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: [[SEC000]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1
+
+// CK24: call void [[CALL03:@.+]]([[SC]]* {{[^,]+}})
+#pragma omp target map(s.s.s.a)
+ { s.a++; }
+
+// Region 04
+// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE04]]{{.+}})
+// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8*
+// CK24-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[10 x i32]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 3
+
+// CK24: call void [[CALL04:@.+]]([[SC]]* {{[^,]+}})
+#pragma omp target map(s.b[:5])
+ { s.a++; }
+
+// Region 05
+// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE05]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE05]]{{.+}})
+// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8*
+// CK24-DAG: [[CPVAL0]] = bitcast [[SB]]** [[SEC0:%.+]] to i8*
+// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2
+
+// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+// CK24-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+// CK24-DAG: [[CBPVAL1]] = bitcast [[SB]]** [[SEC0]] to i8*
+// CK24-DAG: [[CPVAL1]] = bitcast [[SB]]* [[SEC1:%.+]] to i8*
+// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SB]]* [[SEC11:%[^,]+]], i{{.+}} 0
+// CK24-DAG: [[SEC11]] = load [[SB]]*, [[SB]]** [[SEC111:%[^,]+]],
+// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2
+
+// CK24: call void [[CALL05:@.+]]([[SC]]* {{[^,]+}})
+#pragma omp target map(s.p[:5])
+ { s.a++; }
+
+// Region 06
+// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE06]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE06]]{{.+}})
+// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8*
+// CK24-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SA]]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[10 x [[SA]]]* [[SEC000:%[^,]+]], i{{.+}} 0, i{{.+}} 3
+// CK24-DAG: [[SEC000]] = getelementptr {{.*}}[[SB]]* [[SEC0000:%[^,]+]], i{{.+}} 0, i{{.+}} 2
+// CK24-DAG: [[SEC0000]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1
+
+// CK24: call void [[CALL06:@.+]]([[SC]]* {{[^,]+}})
+#pragma omp target map(s.s.sa[3].a)
+ { s.a++; }
+
+// Region 07
+// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE07]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE07]]{{.+}})
+// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8*
+// CK24-DAG: [[CPVAL0]] = bitcast [[SA]]** [[SEC0:%.+]] to i8*
+// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[10 x [[SA]]*]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 3
+// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SB]]* [[SEC000:%[^,]+]], i{{.+}} 0, i{{.+}} 3
+// CK24-DAG: [[SEC000]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1
+
+// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+// CK24-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+// CK24-DAG: [[CBPVAL1]] = bitcast [[SA]]** [[SEC0]] to i8*
+// CK24-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8*
+// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SA]]* [[SEC11:%[^,]+]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[SEC11]] = load [[SA]]*, [[SA]]** [[SEC111:%[^,]+]],
+// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[10 x [[SA]]*]* [[SEC1111:%[^,]+]], i{{.+}} 0, i{{.+}} 3
+// CK24-DAG: [[SEC1111]] = getelementptr {{.*}}[[SB]]* [[SEC11111:%[^,]+]], i{{.+}} 0, i{{.+}} 3
+// CK24-DAG: [[SEC11111]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1
+
+// CK24: call void [[CALL07:@.+]]([[SC]]* {{[^,]+}})
+#pragma omp target map(s.s.sp[3]->a)
+ { s.a++; }
+
+// Region 08
+// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE08]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE08]]{{.+}})
+// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8*
+// CK24-DAG: [[CPVAL0]] = bitcast [[SB]]** [[SEC0:%.+]] to i8*
+// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2
+
+// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+// CK24-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+// CK24-DAG: [[CBPVAL1]] = bitcast [[SB]]** [[SEC0]] to i8*
+// CK24-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8*
+// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SB]]* [[SEC11:%[^,]+]], i{{.+}} 0
+// CK24-DAG: [[SEC11]] = load [[SB]]*, [[SB]]** [[SEC111:%[^,]+]],
+// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2
+
+// CK24: call void [[CALL08:@.+]]([[SC]]* {{[^,]+}})
+#pragma omp target map(s.p->a)
+ { s.a++; }
+
+// Region 09
+// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE09]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE09]]{{.+}})
+// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8*
+// CK24-DAG: [[CPVAL0]] = bitcast [[SA]]** [[SEC0:%.+]] to i8*
+// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SB]]* [[SEC00:[^,]+]], i{{.+}} 0, i{{.+}} 4
+// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1
+
+// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+// CK24-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+// CK24-DAG: [[CBPVAL1]] = bitcast [[SA]]** [[SEC0]] to i8*
+// CK24-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8*
+// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SA]]* [[SEC11:%[^,]+]], i{{.+}} 0
+// CK24-DAG: [[SEC11]] = load [[SA]]*, [[SA]]** [[SEC111:%[^,]+]],
+// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[[SB]]* [[SEC1111:[^,]+]], i{{.+}} 0, i{{.+}} 4
+// CK24-DAG: [[SEC1111]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1
+
+// CK24: call void [[CALL09:@.+]]([[SC]]* {{[^,]+}})
+#pragma omp target map(s.s.p->a)
+ { s.a++; }
+
+// Region 10
+// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE10]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE10]]{{.+}})
+// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8*
+// CK24-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[10 x i32]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SA]]* [[SEC000:%[^,]+]], i{{.+}} 0, i{{.+}} 2
+// CK24-DAG: [[SEC000]] = getelementptr {{.*}}[[SB]]* [[SEC0000:%[^,]+]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: [[SEC0000]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1
+
+// CK24: call void [[CALL10:@.+]]([[SC]]* {{[^,]+}})
+#pragma omp target map(s.s.s.b[:2])
+ { s.a++; }
+
+// Region 11
+// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE11]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE11]]{{.+}})
+// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8*
+// CK24-DAG: [[CPVAL0]] = bitcast [[SA]]** [[SEC0:%.+]] to i8*
+// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SB]]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 4
+// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1
+
+// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+// CK24-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+// CK24-DAG: [[CBPVAL1]] = bitcast [[SA]]** [[SEC0]] to i8*
+// CK24-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8*
+// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[10 x i32]* [[SEC11:%[^,]+]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[SEC11]] = getelementptr {{.*}}[[SA]]* [[SEC111:%[^,]+]], i{{.+}} 0, i{{.+}} 2
+// CK24-DAG: [[SEC111]] = load [[SA]]*, [[SA]]** [[SEC1111:%[^,]+]],
+// CK24-DAG: [[SEC1111]] = getelementptr {{.*}}[[SB]]* [[SEC11111:%[^,]+]], i{{.+}} 0, i{{.+}} 4
+// CK24-DAG: [[SEC11111]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 1
+
+// CK24: call void [[CALL11:@.+]]([[SC]]* {{[^,]+}})
+#pragma omp target map(s.s.p->b[:2])
+ { s.a++; }
+
+// Region 12
+// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 4, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[SIZE12]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[MTYPE12]]{{.+}})
+// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8*
+// CK24-DAG: [[CPVAL0]] = bitcast [[SB]]** [[SEC0:%.+]] to i8*
+// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2
+
+// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+// CK24-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+// CK24-DAG: [[CBPVAL1]] = bitcast [[SB]]** [[SEC0]] to i8*
+// CK24-DAG: [[CPVAL1]] = bitcast [[SA]]** [[SEC1:%.+]] to i8*
+// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SB]]* [[SEC11:%[^,]+]], i{{.+}} 0, i{{.+}} 4
+// CK24-DAG: [[SEC11]] = load [[SB]]*, [[SB]]** [[SEC111:%[^,]+]],
+// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2
+
+// CK24-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2
+// CK24-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2
+// CK24-DAG: store i8* [[CBPVAL2:%[^,]+]], i8** [[BP2]]
+// CK24-DAG: store i8* [[CPVAL2:%[^,]+]], i8** [[P2]]
+// CK24-DAG: [[CBPVAL2]] = bitcast [[SA]]** [[SEC1]] to i8*
+// CK24-DAG: [[CPVAL2]] = bitcast [[SA]]** [[SEC2:%.+]] to i8*
+// CK24-DAG: [[SEC2]] = getelementptr {{.*}}[[SA]]* [[SEC22:%[^,]+]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: [[SEC22]] = load [[SA]]*, [[SA]]** [[SEC222:%[^,]+]],
+// CK24-DAG: [[SEC222]] = getelementptr {{.*}}[[SB]]* [[SEC2222:%[^,]+]], i{{.+}} 0, i{{.+}} 4
+// CK24-DAG: [[SEC2222]] = load [[SB]]*, [[SB]]** [[SEC22222:%[^,]+]],
+// CK24-DAG: [[SEC22222]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2
+
+// CK24-DAG: [[BP3:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 3
+// CK24-DAG: [[P3:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 3
+// CK24-DAG: store i8* [[CBPVAL3:%[^,]+]], i8** [[BP3]]
+// CK24-DAG: store i8* [[CPVAL3:%[^,]+]], i8** [[P3]]
+// CK24-DAG: [[CBPVAL3]] = bitcast [[SA]]** [[SEC2]] to i8*
+// CK24-DAG: [[CPVAL3]] = bitcast i32* [[SEC3:%.+]] to i8*
+// CK24-DAG: [[SEC3]] = getelementptr {{.*}}[[SA]]* [[SEC33:%[^,]+]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[SEC33]] = load [[SA]]*, [[SA]]** [[SEC333:%[^,]+]],
+// CK24-DAG: [[SEC333]] = getelementptr {{.*}}[[SA]]* [[SEC3333:%[^,]+]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: [[SEC3333]] = load [[SA]]*, [[SA]]** [[SEC33333:%[^,]+]],
+// CK24-DAG: [[SEC33333]] = getelementptr {{.*}}[[SB]]* [[SEC333333:%[^,]+]], i{{.+}} 0, i{{.+}} 4
+// CK24-DAG: [[SEC333333]] = load [[SB]]*, [[SB]]** [[SEC3333333:%[^,]+]],
+// CK24-DAG: [[SEC3333333]] = getelementptr {{.*}}[[SC]]* [[VAR0]], i{{.+}} 0, i{{.+}} 2
+
+// CK24: call void [[CALL12:@.+]]([[SC]]* {{[^,]+}})
+#pragma omp target map(s.p->p->p->a)
+ { s.a++; }
+
+//
+// Same thing but starting from a pointer.
+//
+// Region 13
+// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE13]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE13]]{{.+}})
+// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8*
+// CK24-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SC]]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 0
+
+// CK24-DAG: [[VAR0]] = load [[SC]]*, [[SC]]** %{{.+}}
+// CK24-DAG: [[VAR00]] = load [[SC]]*, [[SC]]** %{{.+}}
+
+// CK24: call void [[CALL13:@.+]]([[SC]]* {{[^,]+}})
+#pragma omp target map(p->a)
+ { p->a++; }
+
+// Region 14
+// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE14]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE14]]{{.+}})
+// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8*
+// CK24-DAG: [[CPVAL0]] = bitcast [[SA]]* [[SEC0:%.+]] to i8*
+// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SB]]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SC]]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 1
+
+// CK24-DAG: [[VAR0]] = load [[SC]]*, [[SC]]** %{{.+}}
+// CK24-DAG: [[VAR00]] = load [[SC]]*, [[SC]]** %{{.+}}
+
+// CK24: call void [[CALL14:@.+]]([[SC]]* {{[^,]+}})
+#pragma omp target map(p->s.s)
+ { p->a++; }
+
+// Region 15
+// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE15]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE15]]{{.+}})
+// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8*
+// CK24-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SA]]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SB]]* [[SEC000:%[^,]+]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: [[SEC000]] = getelementptr {{.*}}[[SC]]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 1
+
+// CK24-DAG: [[VAR0]] = load [[SC]]*, [[SC]]** %{{.+}}
+// CK24-DAG: [[VAR00]] = load [[SC]]*, [[SC]]** %{{.+}}
+
+// CK24: call void [[CALL15:@.+]]([[SC]]* {{[^,]+}})
+#pragma omp target map(p->s.s.a)
+ { p->a++; }
+
+// Region 16
+// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE16]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE16]]{{.+}})
+// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8*
+// CK24-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[10 x i32]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SC]]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 3
+
+// CK24-DAG: [[VAR0]] = load [[SC]]*, [[SC]]** %{{.+}}
+// CK24-DAG: [[VAR00]] = load [[SC]]*, [[SC]]** %{{.+}}
+
+// CK24: call void [[CALL16:@.+]]([[SC]]* {{[^,]+}})
+#pragma omp target map(p->b[:5])
+ { p->a++; }
+
+// Region 17
+// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE17]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE17]]{{.+}})
+// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8*
+// CK24-DAG: [[CPVAL0]] = bitcast [[SB]]** [[SEC0:%.+]] to i8*
+// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SC]]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 2
+
+// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+// CK24-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+// CK24-DAG: [[CBPVAL1]] = bitcast [[SB]]** [[SEC0]] to i8*
+// CK24-DAG: [[CPVAL1]] = bitcast [[SB]]* [[SEC1:%.+]] to i8*
+// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SB]]* [[SEC11:%[^,]+]], i{{.+}} 0
+// CK24-DAG: [[SEC11]] = load [[SB]]*, [[SB]]** [[SEC111:%[^,]+]],
+// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[[SC]]* [[VAR000:%.+]], i{{.+}} 0, i{{.+}} 2
+
+// CK24-DAG: [[VAR0]] = load [[SC]]*, [[SC]]** %{{.+}}
+// CK24-DAG: [[VAR00]] = load [[SC]]*, [[SC]]** %{{.+}}
+// CK24-DAG: [[VAR000]] = load [[SC]]*, [[SC]]** %{{.+}}
+
+// CK24: call void [[CALL17:@.+]]([[SC]]* {{[^,]+}})
+#pragma omp target map(p->p[:5])
+ { p->a++; }
+
+// Region 18
+// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE18]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE18]]{{.+}})
+// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8*
+// CK24-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SA]]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[10 x [[SA]]]* [[SEC000:%[^,]+]], i{{.+}} 0, i{{.+}} 3
+// CK24-DAG: [[SEC000]] = getelementptr {{.*}}[[SB]]* [[SEC0000:%[^,]+]], i{{.+}} 0, i{{.+}} 2
+// CK24-DAG: [[SEC0000]] = getelementptr {{.*}}[[SC]]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 1
+
+// CK24-DAG: [[VAR0]] = load [[SC]]*, [[SC]]** %{{.+}}
+// CK24-DAG: [[VAR00]] = load [[SC]]*, [[SC]]** %{{.+}}
+
+// CK24: call void [[CALL18:@.+]]([[SC]]* {{[^,]+}})
+#pragma omp target map(p->s.sa[3].a)
+ { p->a++; }
+
+// Region 19
+// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE19]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE19]]{{.+}})
+// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8*
+// CK24-DAG: [[CPVAL0]] = bitcast [[SA]]** [[SEC0:%.+]] to i8*
+// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[10 x [[SA]]*]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 3
+// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SB]]* [[SEC000:%[^,]+]], i{{.+}} 0, i{{.+}} 3
+// CK24-DAG: [[SEC000]] = getelementptr {{.*}}[[SC]]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 1
+
+// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+// CK24-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+// CK24-DAG: [[CBPVAL1]] = bitcast [[SA]]** [[SEC0]] to i8*
+// CK24-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8*
+// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SA]]* [[SEC11:%[^,]+]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[SEC11]] = load [[SA]]*, [[SA]]** [[SEC111:%[^,]+]],
+// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[10 x [[SA]]*]* [[SEC1111:%[^,]+]], i{{.+}} 0, i{{.+}} 3
+// CK24-DAG: [[SEC1111]] = getelementptr {{.*}}[[SB]]* [[SEC11111:%[^,]+]], i{{.+}} 0, i{{.+}} 3
+// CK24-DAG: [[SEC11111]] = getelementptr {{.*}}[[SC]]* [[VAR000:%.+]], i{{.+}} 0, i{{.+}} 1
+
+// CK24-DAG: [[VAR0]] = load [[SC]]*, [[SC]]** %{{.+}}
+// CK24-DAG: [[VAR00]] = load [[SC]]*, [[SC]]** %{{.+}}
+// CK24-DAG: [[VAR000]] = load [[SC]]*, [[SC]]** %{{.+}}
+
+// CK24: call void [[CALL19:@.+]]([[SC]]* {{[^,]+}})
+#pragma omp target map(p->s.sp[3]->a)
+ { p->a++; }
+
+// Region 20
+// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE20]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE20]]{{.+}})
+// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8*
+// CK24-DAG: [[CPVAL0]] = bitcast [[SB]]** [[SEC0:%.+]] to i8*
+// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SC]]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 2
+
+// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+// CK24-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+// CK24-DAG: [[CBPVAL1]] = bitcast [[SB]]** [[SEC0]] to i8*
+// CK24-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8*
+// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SB]]* [[SEC11:%[^,]+]], i{{.+}} 0
+// CK24-DAG: [[SEC11]] = load [[SB]]*, [[SB]]** [[SEC111:%[^,]+]],
+// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[[SC]]* [[VAR000:%.+]], i{{.+}} 0, i{{.+}} 2
+
+// CK24-DAG: [[VAR0]] = load [[SC]]*, [[SC]]** %{{.+}}
+// CK24-DAG: [[VAR00]] = load [[SC]]*, [[SC]]** %{{.+}}
+// CK24-DAG: [[VAR000]] = load [[SC]]*, [[SC]]** %{{.+}}
+
+// CK24: call void [[CALL20:@.+]]([[SC]]* {{[^,]+}})
+#pragma omp target map(p->p->a)
+ { p->a++; }
+
+// Region 21
+// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE21]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE21]]{{.+}})
+// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8*
+// CK24-DAG: [[CPVAL0]] = bitcast [[SA]]** [[SEC0:%.+]] to i8*
+// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SB]]* [[SEC00:[^,]+]], i{{.+}} 0, i{{.+}} 4
+// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SC]]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 1
+
+// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+// CK24-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+// CK24-DAG: [[CBPVAL1]] = bitcast [[SA]]** [[SEC0]] to i8*
+// CK24-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8*
+// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SA]]* [[SEC11:%[^,]+]], i{{.+}} 0
+// CK24-DAG: [[SEC11]] = load [[SA]]*, [[SA]]** [[SEC111:%[^,]+]],
+// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[[SB]]* [[SEC1111:[^,]+]], i{{.+}} 0, i{{.+}} 4
+// CK24-DAG: [[SEC1111]] = getelementptr {{.*}}[[SC]]* [[VAR000:%.+]], i{{.+}} 0, i{{.+}} 1
+
+// CK24-DAG: [[VAR0]] = load [[SC]]*, [[SC]]** %{{.+}}
+// CK24-DAG: [[VAR00]] = load [[SC]]*, [[SC]]** %{{.+}}
+// CK24-DAG: [[VAR000]] = load [[SC]]*, [[SC]]** %{{.+}}
+
+// CK24: call void [[CALL21:@.+]]([[SC]]* {{[^,]+}})
+#pragma omp target map(p->s.p->a)
+ { p->a++; }
+
+// Region 22
+// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE22]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE22]]{{.+}})
+// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8*
+// CK24-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[10 x i32]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SA]]* [[SEC000:%[^,]+]], i{{.+}} 0, i{{.+}} 2
+// CK24-DAG: [[SEC000]] = getelementptr {{.*}}[[SB]]* [[SEC0000:%[^,]+]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: [[SEC0000]] = getelementptr {{.*}}[[SC]]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 1
+
+// CK24-DAG: [[VAR0]] = load [[SC]]*, [[SC]]** %{{.+}}
+// CK24-DAG: [[VAR00]] = load [[SC]]*, [[SC]]** %{{.+}}
+
+// CK24: call void [[CALL22:@.+]]([[SC]]* {{[^,]+}})
+#pragma omp target map(p->s.s.b[:2])
+ { p->a++; }
+
+// Region 23
+// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE23]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE23]]{{.+}})
+// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8*
+// CK24-DAG: [[CPVAL0]] = bitcast [[SA]]** [[SEC0:%.+]] to i8*
+// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SB]]* [[SEC00:%[^,]+]], i{{.+}} 0, i{{.+}} 4
+// CK24-DAG: [[SEC00]] = getelementptr {{.*}}[[SC]]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 1
+
+// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+// CK24-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+// CK24-DAG: [[CBPVAL1]] = bitcast [[SA]]** [[SEC0]] to i8*
+// CK24-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8*
+// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[10 x i32]* [[SEC11:%[^,]+]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[SEC11]] = getelementptr {{.*}}[[SA]]* [[SEC111:%[^,]+]], i{{.+}} 0, i{{.+}} 2
+// CK24-DAG: [[SEC111]] = load [[SA]]*, [[SA]]** [[SEC1111:%[^,]+]],
+// CK24-DAG: [[SEC1111]] = getelementptr {{.*}}[[SB]]* [[SEC11111:%[^,]+]], i{{.+}} 0, i{{.+}} 4
+// CK24-DAG: [[SEC11111]] = getelementptr {{.*}}[[SC]]* [[VAR000:%.+]], i{{.+}} 0, i{{.+}} 1
+
+// CK24-DAG: [[VAR0]] = load [[SC]]*, [[SC]]** %{{.+}}
+// CK24-DAG: [[VAR00]] = load [[SC]]*, [[SC]]** %{{.+}}
+// CK24-DAG: [[VAR000]] = load [[SC]]*, [[SC]]** %{{.+}}
+
+// CK24: call void [[CALL23:@.+]]([[SC]]* {{[^,]+}})
+#pragma omp target map(p->s.p->b[:2])
+ { p->a++; }
+
+// Region 24
+// CK24-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 4, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[SIZE24]], {{.+}}getelementptr {{.+}}[4 x i{{.+}}]* [[MTYPE24]]{{.+}})
+// CK24-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK24-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK24-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK24-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK24-DAG: [[CBPVAL0]] = bitcast [[SC]]* [[VAR0:%.+]] to i8*
+// CK24-DAG: [[CPVAL0]] = bitcast [[SB]]** [[SEC0:%.+]] to i8*
+// CK24-DAG: [[SEC0]] = getelementptr {{.*}}[[SC]]* [[VAR00:%.+]], i{{.+}} 0, i{{.+}} 2
+
+// CK24-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+// CK24-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+// CK24-DAG: [[CBPVAL1]] = bitcast [[SB]]** [[SEC0]] to i8*
+// CK24-DAG: [[CPVAL1]] = bitcast [[SA]]** [[SEC1:%.+]] to i8*
+// CK24-DAG: [[SEC1]] = getelementptr {{.*}}[[SB]]* [[SEC11:%[^,]+]], i{{.+}} 0, i{{.+}} 4
+// CK24-DAG: [[SEC11]] = load [[SB]]*, [[SB]]** [[SEC111:%[^,]+]],
+// CK24-DAG: [[SEC111]] = getelementptr {{.*}}[[SC]]* [[VAR000:%.+]], i{{.+}} 0, i{{.+}} 2
+
+// CK24-DAG: [[BP2:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 2
+// CK24-DAG: [[P2:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 2
+// CK24-DAG: store i8* [[CBPVAL2:%[^,]+]], i8** [[BP2]]
+// CK24-DAG: store i8* [[CPVAL2:%[^,]+]], i8** [[P2]]
+// CK24-DAG: [[CBPVAL2]] = bitcast [[SA]]** [[SEC1]] to i8*
+// CK24-DAG: [[CPVAL2]] = bitcast [[SA]]** [[SEC2:%.+]] to i8*
+// CK24-DAG: [[SEC2]] = getelementptr {{.*}}[[SA]]* [[SEC22:%[^,]+]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: [[SEC22]] = load [[SA]]*, [[SA]]** [[SEC222:%[^,]+]],
+// CK24-DAG: [[SEC222]] = getelementptr {{.*}}[[SB]]* [[SEC2222:%[^,]+]], i{{.+}} 0, i{{.+}} 4
+// CK24-DAG: [[SEC2222]] = load [[SB]]*, [[SB]]** [[SEC22222:%[^,]+]],
+// CK24-DAG: [[SEC22222]] = getelementptr {{.*}}[[SC]]* [[VAR0000:%.+]], i{{.+}} 0, i{{.+}} 2
+
+// CK24-DAG: [[BP3:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 3
+// CK24-DAG: [[P3:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 3
+// CK24-DAG: store i8* [[CBPVAL3:%[^,]+]], i8** [[BP3]]
+// CK24-DAG: store i8* [[CPVAL3:%[^,]+]], i8** [[P3]]
+// CK24-DAG: [[CBPVAL3]] = bitcast [[SA]]** [[SEC2]] to i8*
+// CK24-DAG: [[CPVAL3]] = bitcast i32* [[SEC3:%.+]] to i8*
+// CK24-DAG: [[SEC3]] = getelementptr {{.*}}[[SA]]* [[SEC33:%[^,]+]], i{{.+}} 0, i{{.+}} 0
+// CK24-DAG: [[SEC33]] = load [[SA]]*, [[SA]]** [[SEC333:%[^,]+]],
+// CK24-DAG: [[SEC333]] = getelementptr {{.*}}[[SA]]* [[SEC3333:%[^,]+]], i{{.+}} 0, i{{.+}} 1
+// CK24-DAG: [[SEC3333]] = load [[SA]]*, [[SA]]** [[SEC33333:%[^,]+]],
+// CK24-DAG: [[SEC33333]] = getelementptr {{.*}}[[SB]]* [[SEC333333:%[^,]+]], i{{.+}} 0, i{{.+}} 4
+// CK24-DAG: [[SEC333333]] = load [[SB]]*, [[SB]]** [[SEC3333333:%[^,]+]],
+// CK24-DAG: [[SEC3333333]] = getelementptr {{.*}}[[SC]]* [[VAR00000:%.+]], i{{.+}} 0, i{{.+}} 2
+
+// CK24-DAG: [[VAR0]] = load [[SC]]*, [[SC]]** %{{.+}}
+// CK24-DAG: [[VAR00]] = load [[SC]]*, [[SC]]** %{{.+}}
+// CK24-DAG: [[VAR000]] = load [[SC]]*, [[SC]]** %{{.+}}
+// CK24-DAG: [[VAR0000]] = load [[SC]]*, [[SC]]** %{{.+}}
+// CK24-DAG: [[VAR00000]] = load [[SC]]*, [[SC]]** %{{.+}}
+
+// CK24: call void [[CALL24:@.+]]([[SC]]* {{[^,]+}})
+#pragma omp target map(p->p->p->p->a)
+ { p->a++; }
+
+ return s.a;
+}
+
+// CK24: define {{.+}}[[CALL01]]
+// CK24: define {{.+}}[[CALL02]]
+// CK24: define {{.+}}[[CALL03]]
+// CK24: define {{.+}}[[CALL04]]
+// CK24: define {{.+}}[[CALL05]]
+// CK24: define {{.+}}[[CALL06]]
+// CK24: define {{.+}}[[CALL07]]
+// CK24: define {{.+}}[[CALL08]]
+// CK24: define {{.+}}[[CALL09]]
+// CK24: define {{.+}}[[CALL10]]
+// CK24: define {{.+}}[[CALL11]]
+// CK24: define {{.+}}[[CALL12]]
+// CK24: define {{.+}}[[CALL13]]
+// CK24: define {{.+}}[[CALL14]]
+// CK24: define {{.+}}[[CALL15]]
+// CK24: define {{.+}}[[CALL16]]
+// CK24: define {{.+}}[[CALL17]]
+// CK24: define {{.+}}[[CALL18]]
+// CK24: define {{.+}}[[CALL19]]
+// CK24: define {{.+}}[[CALL20]]
+// CK24: define {{.+}}[[CALL21]]
+// CK24: define {{.+}}[[CALL22]]
+// CK24: define {{.+}}[[CALL23]]
+// CK24: define {{.+}}[[CALL24]]
+#endif
+///==========================================================================///
+// RUN: %clang_cc1 -DCK25 -std=c++11 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK25 --check-prefix CK25-64
+// RUN: %clang_cc1 -DCK25 -std=c++11 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK25 --check-prefix CK25-64
+// RUN: %clang_cc1 -DCK25 -std=c++11 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK25 --check-prefix CK25-32
+// RUN: %clang_cc1 -DCK25 -std=c++11 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK25 --check-prefix CK25-32
+#ifdef CK25
+// CK25: [[ST:%.+]] = type { i32, float }
+// CK25: [[CA00:%.+]] = type { [[ST]]* }
+// CK25: [[CA01:%.+]] = type { i32* }
+
+// CK25: [[SIZE00:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4]
+// CK25: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i32] [i32 33]
+
+// CK25: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
+// CK25: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 33]
+
+// CK25-LABEL: explicit_maps_with_inner_lambda
+
+template <int X, typename T>
+struct CC {
+ T A;
+ float B;
+
+ int foo(T arg) {
+ // Region 00
+ // CK25-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK25-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK25-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK25-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK25-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK25-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK25-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK25-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[VAR0:%.+]] to i8*
+ // CK25-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK25-DAG: [[SEC0]] = getelementptr {{.*}}[[ST]]* [[VAR0:%.+]], i{{.+}} 0, i{{.+}} 0
+
+ // CK25: call void [[CALL00:@.+]]([[ST]]* {{[^,]+}})
+ #pragma omp target map(to:A)
+ {
+ [&]() {
+ A += 1;
+ }();
+ }
+
+ // Region 01
+ // CK25-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
+ // CK25-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK25-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK25-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK25-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK25-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK25-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK25-DAG: [[CBPVAL0]] = bitcast i32* [[VAR0:%.+]] to i8*
+ // CK25-DAG: [[CPVAL0]] = bitcast i32* [[VAR0]] to i8*
+
+ // CK25: call void [[CALL01:@.+]](i32* {{[^,]+}})
+ #pragma omp target map(to:arg)
+ {
+ [&]() {
+ arg += 1;
+ }();
+ }
+
+ return A+arg;
+ }
+};
+
+int explicit_maps_with_inner_lambda(int a){
+ CC<123,int> c;
+ return c.foo(a);
+}
+
+// CK25: define {{.+}}[[CALL00]]([[ST]]* [[VAL:%.+]])
+// CK25: store [[ST]]* [[VAL]], [[ST]]** [[VALADDR:%[^,]+]],
+// CK25: [[VAL1:%.+]] = load [[ST]]*, [[ST]]** [[VALADDR]],
+// CK25: [[VALADDR1:%.+]] = getelementptr inbounds [[CA00]], [[CA00]]* [[CA:%[^,]+]], i32 0, i32 0
+// CK25: store [[ST]]* [[VAL1]], [[ST]]** [[VALADDR1]],
+// CK25: call void {{.*}}[[LAMBDA:@.+]]{{.*}}([[CA00]]* [[CA]])
+
+// CK25: define {{.+}}[[LAMBDA]]
+
+// CK25: define {{.+}}[[CALL01]](i32* {{.*}}[[VAL:%.+]])
+// CK25: store i32* [[VAL]], i32** [[VALADDR:%[^,]+]],
+// CK25: [[VAL1:%.+]] = load i32*, i32** [[VALADDR]],
+// CK25: [[VALADDR1:%.+]] = getelementptr inbounds [[CA01]], [[CA01]]* [[CA:%[^,]+]], i32 0, i32 0
+// CK25: store i32* [[VAL1]], i32** [[VALADDR1]],
+// CK25: call void {{.*}}[[LAMBDA]]{{.*}}([[CA01]]* [[CA]])
+#endif
+///==========================================================================///
+// RUN: %clang_cc1 -DCK26 -std=c++11 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK26 --check-prefix CK26-64
+// RUN: %clang_cc1 -DCK26 -std=c++11 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK26 --check-prefix CK26-64
+// RUN: %clang_cc1 -DCK26 -std=c++11 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK26 --check-prefix CK26-32
+// RUN: %clang_cc1 -DCK26 -std=c++11 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK26 --check-prefix CK26-32
+#ifdef CK26
+// CK26: [[ST:%.+]] = type { i32, float*, i32, float* }
+
+// CK26: [[SIZE00:@.+]] = private {{.*}}constant [2 x i[[Z:64|32]]] [i[[Z:64|32]] {{32|16}}, i[[Z:64|32]] 4]
+// CK26: [[MTYPE00:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 35]
+
+// CK26: [[SIZE01:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{32|16}}, i[[Z]] 4]
+// CK26: [[MTYPE01:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 35]
+
+// CK26: [[SIZE02:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{32|16}}, i[[Z]] 4]
+// CK26: [[MTYPE02:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 35]
+
+// CK26: [[SIZE03:@.+]] = private {{.*}}constant [2 x i[[Z]]] [i[[Z]] {{32|16}}, i[[Z]] 4]
+// CK26: [[MTYPE03:@.+]] = private {{.*}}constant [2 x i32] [i32 35, i32 35]
+
+// CK26-LABEL: explicit_maps_with_private_class_members
+
+struct CC {
+ int fA;
+ float &fB;
+ int pA;
+ float &pB;
+
+ CC(float &B) : fB(B), pB(B) {
+
+ // CK26: call {{.*}}@__kmpc_fork_call{{.*}} [[OUTCALL:@.+]] to void (i32*, i32*, ...)*
+ // define {{.*}}void [[OUTCALL]]
+ #pragma omp parallel firstprivate(fA,fB) private(pA,pB)
+ {
+ // Region 00
+ // CK26-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK26-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK26-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK26-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK26-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK26-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK26-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK26-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[VAR0:%.+]] to i8*
+ // CK26-DAG: [[CPVAL0]] = bitcast [[ST]]* [[VAR0]] to i8*
+
+ // CK26-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK26-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK26-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+ // CK26-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK26-DAG: [[CBPVAL1]] = bitcast i32* [[VAR1:%.+]] to i8*
+ // CK26-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8*
+ // CK26-DAG: [[VAR1]] = load i32*, i32** [[PVT:%.+]],
+ // CK26-DAG: [[SEC1]] = load i32*, i32** [[PVT]],
+
+ // CK26: call void [[CALL00:@.+]]([[ST]]* {{[^,]+}}, i32* {{[^,]+}})
+ #pragma omp target map(fA)
+ {
+ ++fA;
+ }
+
+ // Region 01
+ // CK26-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE01]]{{.+}})
+ // CK26-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK26-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK26-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK26-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK26-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK26-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK26-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[VAR0:%.+]] to i8*
+ // CK26-DAG: [[CPVAL0]] = bitcast [[ST]]* [[VAR0]] to i8*
+
+ // CK26-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK26-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK26-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+ // CK26-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK26-DAG: [[CBPVAL1]] = bitcast float* [[VAR1:%.+]] to i8*
+ // CK26-DAG: [[CPVAL1]] = bitcast float* [[SEC1:%.+]] to i8*
+ // CK26-DAG: [[VAR1]] = load float*, float** [[PVT:%.+]],
+ // CK26-DAG: [[SEC1]] = load float*, float** [[PVT]],
+
+ // CK26: call void [[CALL01:@.+]]([[ST]]* {{[^,]+}}, float* {{[^,]+}})
+ #pragma omp target map(fB)
+ {
+ fB += 1.0;
+ }
+
+ // Region 02
+ // CK26-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK26-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK26-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK26-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK26-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK26-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK26-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK26-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[VAR0:%.+]] to i8*
+ // CK26-DAG: [[CPVAL0]] = bitcast [[ST]]* [[VAR0]] to i8*
+
+ // CK26-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK26-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK26-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+ // CK26-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK26-DAG: [[CBPVAL1]] = bitcast i32* [[VAR1:%.+]] to i8*
+ // CK26-DAG: [[CPVAL1]] = bitcast i32* [[SEC1:%.+]] to i8*
+ // CK26-DAG: [[VAR1]] = load i32*, i32** [[PVT:%.+]],
+ // CK26-DAG: [[SEC1]] = load i32*, i32** [[PVT]],
+
+ // CK26: call void [[CALL02:@.+]]([[ST]]* {{[^,]+}}, i32* {{[^,]+}})
+ #pragma omp target map(pA)
+ {
+ ++pA;
+ }
+
+ // Region 01
+ // CK26-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE03]]{{.+}})
+ // CK26-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK26-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK26-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK26-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK26-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK26-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK26-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[VAR0:%.+]] to i8*
+ // CK26-DAG: [[CPVAL0]] = bitcast [[ST]]* [[VAR0]] to i8*
+
+ // CK26-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK26-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK26-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+ // CK26-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK26-DAG: [[CBPVAL1]] = bitcast float* [[VAR1:%.+]] to i8*
+ // CK26-DAG: [[CPVAL1]] = bitcast float* [[SEC1:%.+]] to i8*
+ // CK26-DAG: [[VAR1]] = load float*, float** [[PVT:%.+]],
+ // CK26-DAG: [[SEC1]] = load float*, float** [[PVT]],
+
+ // CK26: call void [[CALL03:@.+]]([[ST]]* {{[^,]+}}, float* {{[^,]+}})
+ #pragma omp target map(pB)
+ {
+ pB += 1.0;
+ }
+ }
+ }
+
+ int foo() {
+ return fA + pA;
+ }
+};
+
+// Make sure the private instance is used in all target regions.
+// CK26: define {{.+}}[[CALL00]]({{.*}}i32*{{.*}}[[PVTARG:%.+]])
+// CK26: store i32* [[PVTARG]], i32** [[PVTADDR:%.+]],
+// CK26: [[ADDR:%.+]] = load i32*, i32** [[PVTADDR]],
+// CK26: [[VAL:%.+]] = load i32, i32* [[ADDR]],
+// CK26: add nsw i32 [[VAL]], 1
+
+// CK26: define {{.+}}[[CALL01]]({{.*}}float*{{.*}}[[PVTARG:%.+]])
+// CK26: store float* [[PVTARG]], float** [[PVTADDR:%.+]],
+// CK26: [[ADDR:%.+]] = load float*, float** [[PVTADDR]],
+// CK26: [[VAL:%.+]] = load float, float* [[ADDR]],
+// CK26: [[EXT:%.+]] = fpext float [[VAL]] to double
+// CK26: fadd double [[EXT]], 1.000000e+00
+
+// CK26: define {{.+}}[[CALL02]]({{.*}}i32*{{.*}}[[PVTARG:%.+]])
+// CK26: store i32* [[PVTARG]], i32** [[PVTADDR:%.+]],
+// CK26: [[ADDR:%.+]] = load i32*, i32** [[PVTADDR]],
+// CK26: [[VAL:%.+]] = load i32, i32* [[ADDR]],
+// CK26: add nsw i32 [[VAL]], 1
+
+// CK26: define {{.+}}[[CALL03]]({{.*}}float*{{.*}}[[PVTARG:%.+]])
+// CK26: store float* [[PVTARG]], float** [[PVTADDR:%.+]],
+// CK26: [[ADDR:%.+]] = load float*, float** [[PVTADDR]],
+// CK26: [[VAL:%.+]] = load float, float* [[ADDR]],
+// CK26: [[EXT:%.+]] = fpext float [[VAL]] to double
+// CK26: fadd double [[EXT]], 1.000000e+00
+
+int explicit_maps_with_private_class_members(){
+ float B;
+ CC c(B);
+ return c.foo();
+}
+#endif
+///==========================================================================///
+// RUN: %clang_cc1 -DCK27 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK27 --check-prefix CK27-64
+// RUN: %clang_cc1 -DCK27 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK27 --check-prefix CK27-64
+// RUN: %clang_cc1 -DCK27 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK27 --check-prefix CK27-32
+// RUN: %clang_cc1 -DCK27 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK27 --check-prefix CK27-32
+#ifdef CK27
+
+// CK27: [[SIZE00:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] zeroinitializer
+// CK27: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i32] [i32 32]
+
+// CK27: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z]]] zeroinitializer
+// CK27: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK27: [[SIZE02:@.+]] = private {{.*}}constant [1 x i[[Z]]] zeroinitializer
+// CK27: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK27: [[SIZE03:@.+]] = private {{.*}}constant [1 x i[[Z]]] zeroinitializer
+// CK27: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i32] [i32 35]
+
+// CK27: [[SIZE05:@.+]] = private {{.*}}constant [1 x i[[Z]]] zeroinitializer
+// CK27: [[MTYPE05:@.+]] = private {{.*}}constant [1 x i32] [i32 32]
+
+// CK27: [[SIZE07:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 4]
+// CK27: [[MTYPE07:@.+]] = private {{.*}}constant [1 x i32] [i32 288]
+
+// CK27: [[SIZE09:@.+]] = private {{.*}}constant [1 x i[[Z]]] [i[[Z]] 40]
+// CK27: [[MTYPE09:@.+]] = private {{.*}}constant [1 x i32] [i32 161]
+
+// CK27-LABEL: zero_size_section_and_private_maps
+void zero_size_section_and_private_maps (int ii){
+
+ // Map of a pointer.
+ int *pa;
+
+ // Region 00
+ // CK27-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK27-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK27-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK27-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK27-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK27-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK27-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK27-DAG: [[CBPVAL0]] = bitcast i32* [[VAR0:%.+]] to i8*
+ // CK27-DAG: [[CPVAL0]] = bitcast i32* [[VAR0]] to i8*
+
+ // CK27: call void [[CALL00:@.+]](i32* {{[^,]+}})
+ #pragma omp target
+ {
+ pa[50]++;
+ }
+
+ // Region 01
+ // CK27-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE01]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE01]]{{.+}})
+ // CK27-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK27-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK27-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK27-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK27-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK27-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK27-DAG: [[CBPVAL0]] = bitcast i32* [[RVAR0:%.+]] to i8*
+ // CK27-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK27-DAG: [[RVAR0]] = load i32*, i32** [[VAR0:%[^,]+]]
+ // CK27-DAG: [[SEC0]] = getelementptr {{.*}}i32* [[RVAR00:%.+]], i{{.+}} 0
+ // CK27-DAG: [[RVAR00]] = load i32*, i32** [[VAR0]]
+
+ // CK27: call void [[CALL01:@.+]](i32* {{[^,]+}})
+ #pragma omp target map(pa[:0])
+ {
+ pa[50]++;
+ }
+
+ // Region 02
+ // CK27-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK27-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK27-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK27-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK27-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK27-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK27-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK27-DAG: [[CBPVAL0]] = bitcast i32* [[RVAR0:%.+]] to i8*
+ // CK27-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK27-DAG: [[RVAR0]] = load i32*, i32** [[VAR0:%[^,]+]]
+ // CK27-DAG: [[SEC0]] = getelementptr {{.*}}i32* [[RVAR00:%.+]], i{{.+}} 0
+ // CK27-DAG: [[RVAR00]] = load i32*, i32** [[VAR0]]
+
+ // CK27: call void [[CALL02:@.+]](i32* {{[^,]+}})
+ #pragma omp target map(pa[0:0])
+ {
+ pa[50]++;
+ }
+
+ // Region 03
+ // CK27-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE03]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
+ // CK27-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK27-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK27-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK27-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK27-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK27-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK27-DAG: [[CBPVAL0]] = bitcast i32* [[RVAR0:%.+]] to i8*
+ // CK27-DAG: [[CPVAL0]] = bitcast i32* [[SEC0:%.+]] to i8*
+ // CK27-DAG: [[RVAR0]] = load i32*, i32** [[VAR0:%[^,]+]]
+ // CK27-DAG: [[SEC0]] = getelementptr {{.*}}i32* [[RVAR00:%.+]], i{{.+}} %{{.+}}
+ // CK27-DAG: [[RVAR00]] = load i32*, i32** [[VAR0]]
+
+ // CK27: call void [[CALL03:@.+]](i32* {{[^,]+}})
+ #pragma omp target map(pa[ii:0])
+ {
+ pa[50]++;
+ }
+
+ int *pvtPtr;
+ int pvtScl;
+ int pvtArr[10];
+
+ // Region 04
+ // CK27: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i32* null)
+ // CK27: call void [[CALL04:@.+]]()
+ #pragma omp target private(pvtPtr)
+ {
+ pvtPtr[5]++;
+ }
+
+ // Region 05
+ // CK27-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE05]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE05]]{{.+}})
+ // CK27-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK27-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK27-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK27-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK27-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK27-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK27-DAG: [[CBPVAL0]] = bitcast i32* [[VAR0:%.+]] to i8*
+ // CK27-DAG: [[CPVAL0]] = bitcast i32* [[VAR0]] to i8*
+
+ // CK27: call void [[CALL05:@.+]](i32* {{[^,]+}})
+ #pragma omp target firstprivate(pvtPtr)
+ {
+ pvtPtr[5]++;
+ }
+
+ // Region 06
+ // CK27: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i32* null)
+ // CK27: call void [[CALL06:@.+]]()
+ #pragma omp target private(pvtScl)
+ {
+ pvtScl++;
+ }
+
+ // Region 07
+ // CK27-DAG: call i32 @__tgt_target(i32 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZE07]]{{.+}}, {{.+}}[[MTYPE07]]{{.+}})
+ // CK27-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
+ // CK27-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
+ // CK27-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
+ // CK27-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0
+ // CK27-DAG: store i8* [[VALBP:%.+]], i8** [[BP1]],
+ // CK27-DAG: store i8* [[VALP:%.+]], i8** [[P1]],
+ // CK27-DAG: [[VALBP]] = inttoptr i[[Z]] [[VAL:%.+]] to i8*
+ // CK27-DAG: [[VALP]] = inttoptr i[[Z]] [[VAL:%.+]] to i8*
+ // CK27-DAG: [[VAL]] = load i[[Z]], i[[Z]]* [[ADDR:%.+]],
+ // CK27-64-DAG: [[CADDR:%.+]] = bitcast i[[Z]]* [[ADDR]] to i32*
+ // CK27-64-DAG: store i32 {{.+}}, i32* [[CADDR]],
+
+ // CK27: call void [[CALL07:@.+]](i[[Z]] [[VAL]])
+ #pragma omp target firstprivate(pvtScl)
+ {
+ pvtScl++;
+ }
+
+ // Region 08
+ // CK27: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i32* null)
+ // CK27: call void [[CALL08:@.+]]()
+ #pragma omp target private(pvtArr)
+ {
+ pvtArr[5]++;
+ }
+
+ // Region 09
+ // CK27-DAG: call i32 @__tgt_target(i32 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE09]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE09]]{{.+}})
+ // CK27-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK27-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK27-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK27-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK27-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK27-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK27-DAG: [[CBPVAL0]] = bitcast [10 x i32]* [[VAR0:%.+]] to i8*
+ // CK27-DAG: [[CPVAL0]] = bitcast [10 x i32]* [[VAR0]] to i8*
+
+ // CK27: call void [[CALL09:@.+]]([10 x i32]* {{[^,]+}})
+ #pragma omp target firstprivate(pvtArr)
+ {
+ pvtArr[5]++;
+ }
+}
+
+// CK27: define {{.+}}[[CALL00]]
+// CK27: define {{.+}}[[CALL01]]
+// CK27: define {{.+}}[[CALL02]]
+// CK27: define {{.+}}[[CALL03]]
+// CK27: define {{.+}}[[CALL04]]
+// CK27: define {{.+}}[[CALL05]]
+// CK27: define {{.+}}[[CALL06]]
+// CK27: define {{.+}}[[CALL07]]
+#endif
#endif
diff --git a/test/OpenMP/target_map_messages.cpp b/test/OpenMP/target_map_messages.cpp
index d61e766c6b4b2..543f47f8216a8 100644
--- a/test/OpenMP/target_map_messages.cpp
+++ b/test/OpenMP/target_map_messages.cpp
@@ -1,5 +1,299 @@
-// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 200 %s
+// RUN: %clang_cc1 -DCCODE -verify -fopenmp -ferror-limit 200 -x c %s
+#ifdef CCODE
+void foo(int arg) {
+ const int n = 0;
+ double marr[10][10][10];
+
+ #pragma omp target map(marr[2][0:2][0:2]) // expected-error {{array section does not specify contiguous storage}}
+ {}
+ #pragma omp target map(marr[:][0:][:])
+ {}
+ #pragma omp target map(marr[:][1:][:]) // expected-error {{array section does not specify contiguous storage}}
+ {}
+ #pragma omp target map(marr[:][n:][:])
+ {}
+}
+#else
+template <typename T, int I>
+struct SA {
+ static int ss;
+ #pragma omp threadprivate(ss) // expected-note {{defined as threadprivate or thread local}}
+ float a;
+ int b[12];
+ float *c;
+ T d;
+ float e[I];
+ T *f;
+ void func(int arg) {
+ #pragma omp target map(arg,a,d)
+ {}
+ #pragma omp target map(arg[2:2],a,d) // expected-error {{subscripted value is not an array or pointer}}
+ {}
+ #pragma omp target map(arg,a*2) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}}
+ {}
+ #pragma omp target map(arg,(c+1)[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}}
+ {}
+ #pragma omp target map(arg,a[:2],d) // expected-error {{subscripted value is not an array or pointer}}
+ {}
+ #pragma omp target map(arg,a,d[:2]) // expected-error {{subscripted value is not an array or pointer}}
+ {}
+
+ #pragma omp target map(to:ss) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
+ {}
+
+ #pragma omp target map(to:b,e)
+ {}
+ #pragma omp target map(to:b,e) map(to:b) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
+ {}
+ #pragma omp target map(to:b[:2],e)
+ {}
+ #pragma omp target map(to:b,e[:])
+ {}
+
+ #pragma omp target map(always, tofrom: c,f)
+ {}
+ #pragma omp target map(always, tofrom: c[1:2],f)
+ {}
+ #pragma omp target map(always, tofrom: c,f[1:2])
+ {}
+ #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, tofrom: c,f[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ {}
+ return;
+ }
+};
+
+struct SB {
+ unsigned A;
+ unsigned B;
+ float Arr[100];
+ float *Ptr;
+ float *foo() {
+ return &Arr[0];
+ }
+};
+
+struct SC {
+ unsigned A : 2;
+ unsigned B : 3;
+ unsigned C;
+ unsigned D;
+ float Arr[100];
+ SB S;
+ SB ArrS[100];
+ SB *PtrS;
+ SB *&RPtrS;
+ float *Ptr;
+
+ SC(SB *&_RPtrS) : RPtrS(_RPtrS) {}
+};
+
+union SD {
+ unsigned A;
+ float B;
+};
+
+void SAclient(int arg) {
+ SA<int,123> s;
+ s.func(arg); // expected-note {{in instantiation of member function}}
+ double marr[10][10][10];
+ double marr2[5][10][1];
+ double mvla[5][arg][10];
+ double ***mptr;
+ const int n = 0;
+ const int m = 1;
+ double mvla2[5][arg][m+n+10];
+
+ SB *p;
+
+ SD u;
+ SC r(p),t(p);
+ #pragma omp target map(r)
+ {}
+ #pragma omp target map(marr[2][0:2][0:2]) // expected-error {{array section does not specify contiguous storage}}
+ {}
+ #pragma omp target map(marr[:][0:2][0:2]) // expected-error {{array section does not specify contiguous storage}}
+ {}
+ #pragma omp target map(marr[2][3][0:2])
+ {}
+ #pragma omp target map(marr[:][:][:])
+ {}
+ #pragma omp target map(marr[:2][:][:])
+ {}
+ #pragma omp target map(marr[arg:][:][:])
+ {}
+ #pragma omp target map(marr[arg:])
+ {}
+ #pragma omp target map(marr[arg:][:arg][:]) // correct if arg is the size of dimension 2
+ {}
+ #pragma omp target map(marr[:arg][:])
+ {}
+ #pragma omp target map(marr[:arg][n:])
+ {}
+ #pragma omp target map(marr[:][:arg][n:]) // correct if arg is the size of dimension 2
+ {}
+ #pragma omp target map(marr[:][:m][n:]) // expected-error {{array section does not specify contiguous storage}}
+ {}
+ #pragma omp target map(marr[n:m][:arg][n:])
+ {}
+ #pragma omp target map(marr[:2][:1][:]) // expected-error {{array section does not specify contiguous storage}}
+ {}
+ #pragma omp target map(marr[:2][1:][:]) // expected-error {{array section does not specify contiguous storage}}
+ {}
+ #pragma omp target map(marr[:2][:][:1]) // expected-error {{array section does not specify contiguous storage}}
+ {}
+ #pragma omp target map(marr[:2][:][1:]) // expected-error {{array section does not specify contiguous storage}}
+ {}
+ #pragma omp target map(marr[:1][:2][:])
+ {}
+ #pragma omp target map(marr[:1][0][:])
+ {}
+ #pragma omp target map(marr[:arg][:2][:]) // correct if arg is 1
+ {}
+ #pragma omp target map(marr[:1][3:1][:2])
+ {}
+ #pragma omp target map(marr[:1][3:arg][:2]) // correct if arg is 1
+ {}
+ #pragma omp target map(marr[:1][3:2][:2]) // expected-error {{array section does not specify contiguous storage}}
+ {}
+ #pragma omp target map(marr[:2][:10][:])
+ {}
+ #pragma omp target map(marr[:2][:][:5+5])
+ {}
+ #pragma omp target map(marr[:2][2+2-4:][0:5+5])
+ {}
+
+ #pragma omp target map(marr[:1][:2][0]) // expected-error {{array section does not specify contiguous storage}}
+ {}
+ #pragma omp target map(marr2[:1][:2][0])
+ {}
+
+ #pragma omp target map(mvla[:1][:][0]) // correct if the size of dimension 2 is 1.
+ {}
+ #pragma omp target map(mvla[:2][:arg][:]) // correct if arg is the size of dimension 2.
+ {}
+ #pragma omp target map(mvla[:1][:2][0]) // expected-error {{array section does not specify contiguous storage}}
+ {}
+ #pragma omp target map(mvla[1][2:arg][:])
+ {}
+ #pragma omp target map(mvla[:1][:][:])
+ {}
+ #pragma omp target map(mvla2[:1][:2][:11])
+ {}
+ #pragma omp target map(mvla2[:1][:2][:10]) // expected-error {{array section does not specify contiguous storage}}
+ {}
+
+ #pragma omp target map(mptr[:2][2+2-4:1][0:5+5]) // expected-error {{array section does not specify contiguous storage}}
+ {}
+ #pragma omp target map(mptr[:1][:2-1][2:4-3])
+ {}
+ #pragma omp target map(mptr[:1][:arg][2:4-3]) // correct if arg is 1.
+ {}
+ #pragma omp target map(mptr[:1][:2-1][0:2])
+ {}
+ #pragma omp target map(mptr[:1][:2][0:2]) // expected-error {{array section does not specify contiguous storage}}
+ {}
+ #pragma omp target map(mptr[:1][:][0:2]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ {}
+ #pragma omp target map(mptr[:2][:1][0:2]) // expected-error {{array section does not specify contiguous storage}}
+ {}
+
+ #pragma omp target map(r.ArrS[0].B)
+ {}
+ #pragma omp target map(r.ArrS[:1].B) // expected-error {{OpenMP array section is not allowed here}}
+ {}
+ #pragma omp target map(r.ArrS[:arg].B) // expected-error {{OpenMP array section is not allowed here}}
+ {}
+ #pragma omp target map(r.ArrS[0].Arr[1:23])
+ {}
+ #pragma omp target map(r.ArrS[0].Arr[1:arg])
+ {}
+ #pragma omp target map(r.ArrS[0].Arr[arg:23])
+ {}
+ #pragma omp target map(r.ArrS[0].Error) // expected-error {{no member named 'Error' in 'SB'}}
+ {}
+ #pragma omp target map(r.ArrS[0].A, r.ArrS[1].A) // expected-error {{multiple array elements associated with the same variable are not allowed in map clauses of the same construct}} expected-note {{used here}}
+ {}
+ #pragma omp target map(r.ArrS[0].A, t.ArrS[1].A)
+ {}
+ #pragma omp target map(r.PtrS[0], r.PtrS->B) // expected-error {{same pointer derreferenced in multiple different ways in map clause expressions}} expected-note {{used here}}
+ {}
+ #pragma omp target map(r.RPtrS[0], r.RPtrS->B) // expected-error {{same pointer derreferenced in multiple different ways in map clause expressions}} expected-note {{used here}}
+ {}
+ #pragma omp target map(r.S.Arr[:12])
+ {}
+ #pragma omp target map(r.S.foo()[:12]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}}
+ {}
+ #pragma omp target map(r.C, r.D)
+ {}
+ #pragma omp target map(r.C, r.C) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
+ {}
+ #pragma omp target map(r.C) map(r.C) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
+ {}
+ #pragma omp target map(r.C, r.S) // this would be an error only caught at runtime - Sema would have to make sure there is not way for the missing data between fields to be mapped somewhere else.
+ {}
+ #pragma omp target map(r, r.S) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
+ {}
+ #pragma omp target map(r.C, t.C)
+ {}
+ #pragma omp target map(r.A) // expected-error {{bit fields cannot be used to specify storage in a 'map' clause}}
+ {}
+ #pragma omp target map(r.Arr)
+ {}
+ #pragma omp target map(r.Arr[3:5])
+ {}
+ #pragma omp target map(r.Ptr[3:5])
+ {}
+ #pragma omp target map(r.ArrS[3:5].A) // expected-error {{OpenMP array section is not allowed here}}
+ {}
+ #pragma omp target map(r.ArrS[3:5].Arr[6:7]) // expected-error {{OpenMP array section is not allowed here}}
+ {}
+ #pragma omp target map(r.ArrS[3].Arr[6:7])
+ {}
+ #pragma omp target map(r.S.Arr[4:5])
+ {}
+ #pragma omp target map(r.S.Ptr[4:5])
+ {}
+ #pragma omp target map(r.S.Ptr[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ {}
+ #pragma omp target map((p+1)->A) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}}
+ {}
+ #pragma omp target map(u.B) // expected-error {{mapped storage cannot be derived from a union}}
+ {}
+
+ #pragma omp target data map(to: r.C) //expected-note {{used here}}
+ {
+ #pragma omp target map(r.D) // expected-error {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}}
+ {}
+ }
+
+ #pragma omp target data map(to: t.Ptr) //expected-note {{used here}}
+ {
+ #pragma omp target map(t.Ptr[:23]) // expected-error {{pointer cannot be mapped along with a section derived from itself}}
+ {}
+ }
+
+ #pragma omp target data map(to: t.C, t.D)
+ {
+ #pragma omp target data map(to: t.C)
+ {
+ #pragma omp target map(t.D)
+ {}
+ }
+ }
+
+ #pragma omp target data map(to: t)
+ {
+ #pragma omp target data map(to: t.C)
+ {
+ #pragma omp target map(t.D)
+ {}
+ }
+ }
+}
void foo() {
}
@@ -62,25 +356,31 @@ T tmain(T argc) {
T y;
T to, tofrom, always;
const T (&l)[5] = da;
-
-
#pragma omp target map // expected-error {{expected '(' after 'map'}}
+ {}
#pragma omp target map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+ {}
#pragma omp target map() // expected-error {{expected expression}}
+ {}
#pragma omp target map(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+ {}
#pragma omp target map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}}
+ {}
#pragma omp target map(to:) // expected-error {{expected expression}}
+ {}
#pragma omp target map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ {}
#pragma omp target map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+ {}
#pragma omp target map(x)
foo();
#pragma omp target map(tofrom: t[:I])
foo();
-#pragma omp target map(T: a) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+#pragma omp target map(T: a) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} expected-error {{incomplete type 'S1' where a complete type is required}}
foo();
#pragma omp target map(T) // expected-error {{'T' does not refer to a value}}
foo();
-#pragma omp target map(I) // expected-error 2 {{expected variable name, array element or array section}}
+#pragma omp target map(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
foo();
#pragma omp target map(S2::S2s)
foo();
@@ -96,42 +396,41 @@ T tmain(T argc) {
foo();
#pragma omp target map(to, x)
foo();
-#pragma omp target map(to x) // expected-error {{expected ',' or ')' in 'map' clause}}
-#pragma omp target map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected variable name, array element or array section}}
-#pragma omp target map(argc)
-#pragma omp target map(S1) // expected-error {{'S1' does not refer to a value}}
-#pragma omp target map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
-#pragma omp target map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
-#pragma omp target map(ca)
-#pragma omp target map(da)
-#pragma omp target map(S2::S2s)
-#pragma omp target map(S2::S2sc)
-#pragma omp target map(e, g)
-#pragma omp target map(h) // expected-error {{threadprivate variables are not allowed in map clause}}
-#pragma omp target map(k), map(k) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
-#pragma omp target map(k), map(k[:5]) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
+#pragma omp target data map(to x) // expected-error {{expected ',' or ')' in 'map' clause}}
+#pragma omp target data map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
+#pragma omp target data map(argc)
+#pragma omp target data map(S1) // expected-error {{'S1' does not refer to a value}}
+#pragma omp target data map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target data map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target data map(ca)
+#pragma omp target data map(da)
+#pragma omp target data map(S2::S2s)
+#pragma omp target data map(S2::S2sc)
+#pragma omp target data map(e, g)
+#pragma omp target data map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
+#pragma omp target data map(k) map(k) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
+#pragma omp target map(k), map(k[:5]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} expected-note 2 {{used here}}
foo();
-#pragma omp target map(da)
+#pragma omp target data map(da)
#pragma omp target map(da[:4])
foo();
-#pragma omp target map(k, j, l) // expected-note 4 {{used here}}
-#pragma omp target map(k[:4]) // expected-error 2 {{variable already marked as mapped in current construct}}
-#pragma omp target map(j)
-#pragma omp target map(l[:5]) // expected-error 2 {{variable already marked as mapped in current construct}}
+#pragma omp target data map(k, j, l) // expected-note 2 {{used here}}
+#pragma omp target data map(k[:4]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}}
+#pragma omp target data map(j)
+#pragma omp target map(l) map(l[:5]) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
foo();
-#pragma omp target map(k[:4], j, l[:5]) // expected-note 4 {{used here}}
-#pragma omp target map(k) // expected-error 2 {{variable already marked as mapped in current construct}}
-#pragma omp target map(j)
-#pragma omp target map(l) // expected-error 2 {{variable already marked as mapped in current construct}}
+#pragma omp target data map(k[:4], j, l[:5]) // expected-note 4 {{used here}}
+#pragma omp target data map(k) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}}
+#pragma omp target data map(j)
+#pragma omp target map(l) // expected-error 2 {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}}
foo();
-#pragma omp target map(always, tofrom: x)
-#pragma omp target map(always: x) // expected-error {{missing map type}}
-#pragma omp target map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
-#pragma omp target map(always, tofrom: always, tofrom, x)
+#pragma omp target data map(always, tofrom: x)
+#pragma omp target data map(always: x) // expected-error {{missing map type}}
+#pragma omp target data map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+#pragma omp target data map(always, tofrom: always, tofrom, x)
#pragma omp target map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}}
foo();
-
return 0;
}
@@ -147,14 +446,14 @@ int main(int argc, char **argv) {
int y;
int to, tofrom, always;
const int (&l)[5] = da;
-#pragma omp target map // expected-error {{expected '(' after 'map'}}
-#pragma omp target map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
-#pragma omp target map() // expected-error {{expected expression}}
-#pragma omp target map(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
-#pragma omp target map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}}
-#pragma omp target map(to:) // expected-error {{expected expression}}
-#pragma omp target map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
-#pragma omp target map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+#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 ')'}} 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'}}
+#pragma omp target data map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}}
+#pragma omp target data map(to:) // expected-error {{expected expression}}
+#pragma omp target data map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target data map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
#pragma omp target map(x)
foo();
#pragma omp target map(to: x)
@@ -165,43 +464,46 @@ int main(int argc, char **argv) {
foo();
#pragma omp target map(to, x)
foo();
-#pragma omp target map(to x) // expected-error {{expected ',' or ')' in 'map' clause}}
-#pragma omp target map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}}
-#pragma omp target map(argc)
-#pragma omp target map(S1) // expected-error {{'S1' does not refer to a value}}
-#pragma omp target map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
-#pragma omp target map(argv[1])
-#pragma omp target map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
-#pragma omp target map(ca)
-#pragma omp target map(da)
-#pragma omp target map(S2::S2s)
-#pragma omp target map(S2::S2sc)
-#pragma omp target map(e, g)
-#pragma omp target map(h) // expected-error {{threadprivate variables are not allowed in map clause}}
-#pragma omp target map(k), map(k) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
-#pragma omp target map(k), map(k[:5]) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
+#pragma omp target data map(to x) // expected-error {{expected ',' or ')' in 'map' clause}}
+#pragma omp target data map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{xpected expression containing only member accesses and/or array sections based on named variables}}
+#pragma omp target data map(argc)
+#pragma omp target data map(S1) // expected-error {{'S1' does not refer to a value}}
+#pragma omp target data map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target data map(argv[1])
+#pragma omp target data map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target data map(ca)
+#pragma omp target data map(da)
+#pragma omp target data map(S2::S2s)
+#pragma omp target data map(S2::S2sc)
+#pragma omp target data map(e, g)
+#pragma omp target data map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
+#pragma omp target data map(k), map(k) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
+#pragma omp target map(k), map(k[:5]) // expected-error {{pointer cannot be mapped along with a section derived from itself}} expected-note {{used here}}
foo();
-#pragma omp target map(da)
+#pragma omp target data map(da)
#pragma omp target map(da[:4])
foo();
-#pragma omp target map(k, j, l) // expected-note 2 {{used here}}
-#pragma omp target map(k[:4]) // expected-error {{variable already marked as mapped in current construct}}
-#pragma omp target map(j)
-#pragma omp target map(l[:5]) // expected-error {{variable already marked as mapped in current construct}}
+#pragma omp target data map(k, j, l) // expected-note {{used here}}
+#pragma omp target data map(k[:4]) // expected-error {{pointer cannot be mapped along with a section derived from itself}}
+#pragma omp target data map(j)
+#pragma omp target map(l) map(l[:5]) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
foo();
-#pragma omp target map(k[:4], j, l[:5]) // expected-note 2 {{used here}}
-#pragma omp target map(k) // expected-error {{variable already marked as mapped in current construct}}
-#pragma omp target map(j)
-#pragma omp target map(l) // expected-error {{variable already marked as mapped in current construct}}
+#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}}
+#pragma omp target data map(k) // expected-error {{pointer cannot be mapped along with a section derived from itself}}
+#pragma omp target data map(j)
+#pragma omp target map(l) // expected-error {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}}
foo();
-#pragma omp target map(always, tofrom: x)
-#pragma omp target map(always: x) // expected-error {{missing map type}}
-#pragma omp target map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
-#pragma omp target map(always, tofrom: always, tofrom, x)
+#pragma omp target data map(always, tofrom: x)
+#pragma omp target data map(always: x) // expected-error {{missing map type}}
+#pragma omp target data map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+#pragma omp target data map(always, tofrom: always, tofrom, x)
#pragma omp target map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}}
foo();
-
+#pragma omp target private(j) map(j) // expected-error {{private variable cannot be in a map clause in '#pragma omp target' directive}} expected-note {{defined as private}}
+ {}
+#pragma omp target firstprivate(j) map(j) // expected-error {{firstprivate variable cannot be in a map clause in '#pragma omp target' directive}} expected-note {{defined as firstprivate}}
+ {}
return tmain<int, 3>(argc)+tmain<from, 4>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<int, 4>' requested here}}
}
-
+#endif
diff --git a/test/OpenMP/target_messages.cpp b/test/OpenMP/target_messages.cpp
index 86a91838ce021..6f79f44627fa4 100644
--- a/test/OpenMP/target_messages.cpp
+++ b/test/OpenMP/target_messages.cpp
@@ -1,6 +1,9 @@
// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -o - %s
-// RUN: not %clang_cc1 -fopenmp -std=c++11 -omptargets=aaa-bbb-ccc-ddd -o - %s 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -fopenmp -std=c++11 -fopenmp-targets=aaa-bbb-ccc-ddd -o - %s 2>&1 | FileCheck %s
// CHECK: error: OpenMP target is invalid: 'aaa-bbb-ccc-ddd'
+// RUN: not %clang_cc1 -fopenmp -std=c++11 -triple nvptx64-nvidia-cuda -o - %s 2>&1 | FileCheck --check-prefix CHECK-UNSUPPORTED-HOST-TARGET %s
+// RUN: not %clang_cc1 -fopenmp -std=c++11 -triple nvptx-nvidia-cuda -o - %s 2>&1 | FileCheck --check-prefix CHECK-UNSUPPORTED-HOST-TARGET %s
+// CHECK-UNSUPPORTED-HOST-TARGET: error: The target '{{nvptx64-nvidia-cuda|nvptx-nvidia-cuda}}' is not a supported OpenMP host target.
void foo() {
}
@@ -21,6 +24,7 @@ int main(int argc, char **argv) {
#pragma omp target } // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}}
foo();
#pragma omp target
+ foo();
// expected-warning@+1 {{extra tokens at the end of '#pragma omp target' are ignored}}
#pragma omp target unknown()
foo();
diff --git a/test/OpenMP/target_nowait_messages.cpp b/test/OpenMP/target_nowait_messages.cpp
new file mode 100644
index 0000000000000..7531c81c0f6ae
--- /dev/null
+++ b/test/OpenMP/target_nowait_messages.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+int main(int argc, char **argv) {
+ #pragma omp target nowait( // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}}
+ foo();
+ #pragma omp target nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}}
+ foo();
+ #pragma omp target nowait device (-10u)
+ foo();
+ #pragma omp target nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}}
+ foo();
+
+ return 0;
+}
diff --git a/test/OpenMP/target_parallel_ast_print.cpp b/test/OpenMP/target_parallel_ast_print.cpp
new file mode 100644
index 0000000000000..1c0fca5ccfc06
--- /dev/null
+++ b/test/OpenMP/target_parallel_ast_print.cpp
@@ -0,0 +1,233 @@
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+template <class T>
+struct S {
+ operator T() {return T();}
+ static T TS;
+ #pragma omp threadprivate(TS)
+};
+
+// CHECK: template <class T = int> struct S {
+// CHECK: static int TS;
+// CHECK-NEXT: #pragma omp threadprivate(S<int>::TS)
+// CHECK-NEXT: }
+// CHECK: template <class T = char> struct S {
+// CHECK: static char TS;
+// CHECK-NEXT: #pragma omp threadprivate(S<char>::TS)
+// CHECK-NEXT: }
+// CHECK: template <class T> struct S {
+// CHECK: static T TS;
+// CHECK-NEXT: #pragma omp threadprivate(S::TS)
+// CHECK: };
+
+template <typename T, int C>
+T tmain(T argc, T *argv) {
+ T b = argc, c, d, e, f, g;
+ static T h;
+ S<T> s;
+ T arr[C][10], arr1[C];
+ T i, j, a[20];
+#pragma omp target parallel
+ h=2;
+#pragma omp target parallel default(none), private(argc,b) firstprivate(argv) shared (d) if (parallel:argc > 0) num_threads(C) proc_bind(master) reduction(+:c, arr1[argc]) reduction(max:e, arr[:C][0:10])
+ foo();
+#pragma omp target parallel if (C) num_threads(s) proc_bind(close) reduction(^:e, f, arr[0:C][:argc]) reduction(&& : g)
+ foo();
+#pragma omp target parallel if (target:argc > 0)
+ foo();
+#pragma omp target parallel if (parallel:argc > 0)
+ foo();
+#pragma omp target parallel if (C)
+ foo();
+#pragma omp target parallel map(i)
+ foo();
+#pragma omp target parallel map(a[0:10], i)
+ foo();
+#pragma omp target parallel map(to: i) map(from: j)
+ foo();
+#pragma omp target parallel map(always,alloc: i)
+ foo();
+#pragma omp target parallel nowait
+ foo();
+#pragma omp target parallel depend(in : argc, argv[i:argc], a[:])
+ foo();
+#pragma omp target parallel defaultmap(tofrom: scalar)
+ foo();
+ return 0;
+}
+
+// CHECK: template <typename T = int, int C = 5> int tmain(int argc, int *argv) {
+// CHECK-NEXT: int b = argc, c, d, e, f, g;
+// CHECK-NEXT: static int h;
+// CHECK-NEXT: S<int> s;
+// CHECK-NEXT: int arr[5][10], arr1[5];
+// CHECK-NEXT: int i, j, a[20]
+// CHECK-NEXT: #pragma omp target parallel
+// CHECK-NEXT: h = 2;
+// CHECK-NEXT: #pragma omp target parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(5) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:5][0:10])
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel if(5) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:5][:argc]) reduction(&&: g)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel if(target: argc > 0)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel if(parallel: argc > 0)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel if(5)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel map(tofrom: i)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel map(tofrom: a[0:10],i)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel map(to: i) map(from: j)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel map(always,alloc: i)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel nowait
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel depend(in : argc,argv[i:argc],a[:])
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel defaultmap(tofrom: scalar)
+// CHECK-NEXT: foo()
+// CHECK: template <typename T = char, int C = 1> char tmain(char argc, char *argv) {
+// CHECK-NEXT: char b = argc, c, d, e, f, g;
+// CHECK-NEXT: static char h;
+// CHECK-NEXT: S<char> s;
+// CHECK-NEXT: char arr[1][10], arr1[1];
+// CHECK-NEXT: char i, j, a[20]
+// CHECK-NEXT: #pragma omp target parallel
+// CHECK-NEXT: h = 2;
+// CHECK-NEXT: #pragma omp target parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(1) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:1][0:10])
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel if(1) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:1][:argc]) reduction(&&: g)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel if(target: argc > 0)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel if(parallel: argc > 0)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel if(1)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel map(tofrom: i)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel map(tofrom: a[0:10],i)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel map(to: i) map(from: j)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel map(always,alloc: i)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel nowait
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel depend(in : argc,argv[i:argc],a[:])
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel defaultmap(tofrom: scalar)
+// CHECK-NEXT: foo()
+// CHECK: template <typename T, int C> T tmain(T argc, T *argv) {
+// CHECK-NEXT: T b = argc, c, d, e, f, g;
+// CHECK-NEXT: static T h;
+// CHECK-NEXT: S<T> s;
+// CHECK-NEXT: T arr[C][10], arr1[C];
+// CHECK-NEXT: T i, j, a[20]
+// CHECK-NEXT: #pragma omp target parallel
+// CHECK-NEXT: h = 2;
+// CHECK-NEXT: #pragma omp target parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(C) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:C][0:10])
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel if(C) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:C][:argc]) reduction(&&: g)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel if(target: argc > 0)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel if(parallel: argc > 0)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel if(C)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel map(tofrom: i)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel map(tofrom: a[0:10],i)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel map(to: i) map(from: j)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel map(always,alloc: i)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel nowait
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel depend(in : argc,argv[i:argc],a[:])
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp target parallel defaultmap(tofrom: scalar)
+// CHECK-NEXT: foo()
+
+// CHECK-LABEL: int main(int argc, char **argv) {
+int main (int argc, char **argv) {
+ int i, j, a[20];
+// CHECK-NEXT: int i, j, a[20]
+#pragma omp target parallel
+// CHECK-NEXT: #pragma omp target parallel
+ foo();
+// CHECK-NEXT: foo();
+#pragma omp target parallel if (argc > 0)
+// CHECK-NEXT: #pragma omp target parallel if(argc > 0)
+ foo();
+// CHECK-NEXT: foo();
+
+#pragma omp target parallel if (target: argc > 0)
+// CHECK-NEXT: #pragma omp target parallel if(target: argc > 0)
+ foo();
+// CHECK-NEXT: foo();
+
+#pragma omp target parallel if (parallel: argc > 0)
+// CHECK-NEXT: #pragma omp target parallel if(parallel: argc > 0)
+ foo();
+// CHECK-NEXT: foo();
+
+#pragma omp target parallel map(i) if(argc>0)
+// CHECK-NEXT: #pragma omp target parallel map(tofrom: i) if(argc > 0)
+ foo();
+// CHECK-NEXT: foo();
+
+#pragma omp target parallel map(i)
+// CHECK-NEXT: #pragma omp target parallel map(tofrom: i)
+ foo();
+// CHECK-NEXT: foo();
+
+#pragma omp target parallel map(a[0:10], i)
+// CHECK-NEXT: #pragma omp target parallel map(tofrom: a[0:10],i)
+ foo();
+// CHECK-NEXT: foo();
+
+#pragma omp target parallel map(to: i) map(from: j)
+// CHECK-NEXT: #pragma omp target parallel map(to: i) map(from: j)
+ foo();
+// CHECK-NEXT: foo();
+
+#pragma omp target parallel map(always,alloc: i)
+// CHECK-NEXT: #pragma omp target parallel map(always,alloc: i)
+ foo();
+// CHECK-NEXT: foo();
+
+#pragma omp target parallel nowait
+// CHECK-NEXT: #pragma omp target parallel nowait
+ foo();
+// CHECK-NEXT: foo();
+
+#pragma omp target parallel depend(in : argc, argv[i:argc], a[:])
+// CHECK-NEXT: #pragma omp target parallel depend(in : argc,argv[i:argc],a[:])
+ foo();
+// CHECK-NEXT: foo();
+
+#pragma omp target parallel defaultmap(tofrom: scalar)
+// CHECK-NEXT: #pragma omp target parallel defaultmap(tofrom: scalar)
+ foo();
+// CHECK-NEXT: foo();
+
+ return tmain<int, 5>(argc, &argc) + tmain<char, 1>(argv[0][0], argv[0]);
+}
+
+extern template int S<int>::TS;
+extern template char S<char>::TS;
+
+#endif
diff --git a/test/OpenMP/target_parallel_default_messages.cpp b/test/OpenMP/target_parallel_default_messages.cpp
new file mode 100644
index 0000000000000..40f31b84848ae
--- /dev/null
+++ b/test/OpenMP/target_parallel_default_messages.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo();
+
+int main(int argc, char **argv) {
+ #pragma omp target parallel default // expected-error {{expected '(' after 'default'}}
+ foo();
+ #pragma omp target parallel default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+ foo();
+ #pragma omp target parallel default (none // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel default (shared), default(shared) // expected-error {{directive '#pragma omp target parallel' cannot contain more than one 'default' clause}}
+ foo();
+ #pragma omp target parallel default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+ foo();
+
+ #pragma omp target parallel default(none)
+ ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+
+ #pragma omp target parallel default(none)
+ foo();
+ #pragma omp target parallel default(shared)
+ ++argc;
+ return 0;
+}
diff --git a/test/OpenMP/target_parallel_defaultmap_messages.cpp b/test/OpenMP/target_parallel_defaultmap_messages.cpp
new file mode 100644
index 0000000000000..49e7c30a7d15f
--- /dev/null
+++ b/test/OpenMP/target_parallel_defaultmap_messages.cpp
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+template <class T, typename S, int N, int ST>
+T tmain(T argc, S **argv) {
+ #pragma omp target parallel defaultmap // expected-error {{expected '(' after 'defaultmap'}}
+ foo();
+ #pragma omp target parallel defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}}
+ foo();
+ #pragma omp target parallel defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+ foo();
+ #pragma omp target parallel defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+ foo();
+ #pragma omp target parallel defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+ foo();
+ #pragma omp target parallel defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}}
+ foo();
+ #pragma omp target parallel defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+ foo();
+
+ return argc;
+}
+
+int main(int argc, char **argv) {
+ #pragma omp target parallel defaultmap // expected-error {{expected '(' after 'defaultmap'}}
+ foo();
+ #pragma omp target parallel defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}}
+ foo();
+ #pragma omp target parallel defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+ foo();
+ #pragma omp target parallel defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+ foo();
+ #pragma omp target parallel defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+ foo();
+ #pragma omp target parallel defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}}
+ foo();
+ #pragma omp target parallel defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+ foo();
+
+ return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/target_parallel_depend_messages.cpp b/test/OpenMP/target_parallel_depend_messages.cpp
new file mode 100644
index 0000000000000..a9300ca6adb2b
--- /dev/null
+++ b/test/OpenMP/target_parallel_depend_messages.cpp
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+class vector {
+ public:
+ int operator[](int index) { return 0; }
+};
+
+int main(int argc, char **argv, char *env[]) {
+ vector vec;
+ typedef float V __attribute__((vector_size(16)));
+ V a;
+ auto arr = x; // expected-error {{use of undeclared identifier 'x'}}
+
+ #pragma omp target parallel depend // expected-error {{expected '(' after 'depend'}}
+ foo();
+ #pragma omp target parallel depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+ foo();
+ #pragma omp target parallel depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+ foo();
+ #pragma omp target parallel depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+ foo();
+ #pragma omp target parallel depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
+ foo();
+ #pragma omp target parallel depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}}
+ foo();
+ #pragma omp target parallel depend (out: ) // expected-error {{expected expression}}
+ foo();
+ #pragma omp target parallel depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+ foo();
+ #pragma omp target parallel depend (out :S1) // expected-error {{'S1' does not refer to a value}}
+ foo();
+ #pragma omp target parallel depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+ foo();
+ #pragma omp target parallel depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+ foo();
+ #pragma omp target parallel depend (in : argv[0])
+ foo();
+ #pragma omp target parallel depend (in : ) // expected-error {{expected expression}}
+ foo();
+ #pragma omp target parallel depend (in : main) // expected-error {{expected variable name, array element or array section}}
+ foo();
+ #pragma omp target parallel depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+ foo();
+ #pragma omp target parallel depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
+ foo();
+ #pragma omp target parallel depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel depend (in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel depend (in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel depend (in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}}
+ foo();
+ #pragma omp target parallel depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}}
+ foo();
+ #pragma omp target parallel depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ foo();
+ #pragma omp target parallel depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}}
+ foo();
+ #pragma omp target parallel depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}}
+ foo();
+ #pragma omp target parallel depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}}
+ foo();
+ #pragma omp target parallel depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ foo();
+ #pragma omp target parallel depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}}
+ foo();
+ #pragma omp target parallel depend(in : argv[ : argc][1 : argc - 1])
+ foo();
+ #pragma omp target parallel depend(in : arr[0])
+ foo();
+
+ return 0;
+}
diff --git a/test/OpenMP/target_parallel_device_messages.cpp b/test/OpenMP/target_parallel_device_messages.cpp
new file mode 100644
index 0000000000000..6c8d4c2e43ab2
--- /dev/null
+++ b/test/OpenMP/target_parallel_device_messages.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+int main(int argc, char **argv) {
+ #pragma omp target parallel device // expected-error {{expected '(' after 'device'}}
+ foo();
+ #pragma omp target parallel device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel device () // expected-error {{expected expression}}
+ foo();
+ #pragma omp target parallel device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}}
+ foo();
+ #pragma omp target parallel device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ foo();
+ #pragma omp target parallel device (argc + argc)
+ foo();
+ #pragma omp target parallel device (argc), device (argc+1) // expected-error {{directive '#pragma omp target parallel' cannot contain more than one 'device' clause}}
+ foo();
+ #pragma omp target parallel device (S1) // expected-error {{'S1' does not refer to a value}}
+ foo();
+ #pragma omp target parallel device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}}
+ foo();
+ #pragma omp target parallel device (-10u)
+ foo();
+ #pragma omp target parallel device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
+ foo();
+
+ return 0;
+}
diff --git a/test/OpenMP/target_parallel_firstprivate_messages.cpp b/test/OpenMP/target_parallel_firstprivate_messages.cpp
new file mode 100644
index 0000000000000..dd6825aa251f9
--- /dev/null
+++ b/test/OpenMP/target_parallel_firstprivate_messages.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note{{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+public:
+ S2():a(0) { }
+ S2(const S2 &s2):a(s2.a) { }
+ static float S2s;
+ static const float S2sc;
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+public:
+ S3():a(0) { }
+ S3(const S3 &s3):a(s3.a) { }
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 {
+ int a;
+ S4();
+ S4(const S4 &s4); // expected-note {{implicitly declared private here}}
+public:
+ S4(int v):a(v) { }
+};
+class S5 {
+ int a;
+ S5():a(0) {}
+ S5(const S5 &s5):a(s5.a) { } // expected-note {{implicitly declared private here}}
+public:
+ S5(int v):a(v) { }
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note {{defined as threadprivate or thread local}}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5;
+ const int da[5] = { 0 };
+ S4 e(4);
+ S5 g(5);
+ int i;
+ int &j = i;
+ static int m;
+ #pragma omp target parallel firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+ foo();
+ #pragma omp target parallel firstprivate ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel firstprivate () // expected-error {{expected expression}}
+ foo();
+ #pragma omp target parallel firstprivate (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel firstprivate (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel firstprivate (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ foo();
+ #pragma omp target parallel firstprivate (argc)
+ foo();
+ #pragma omp target parallel firstprivate (S1) // expected-error {{'S1' does not refer to a value}}
+ foo();
+ #pragma omp target parallel firstprivate (a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+ foo();
+ #pragma omp target parallel firstprivate (argv[1]) // expected-error {{expected variable name}}
+ foo();
+ #pragma omp target parallel firstprivate(ba)
+ foo();
+ #pragma omp target parallel firstprivate(ca)
+ foo();
+ #pragma omp target parallel firstprivate(da)
+ foo();
+ #pragma omp target parallel firstprivate(S2::S2s)
+ foo();
+ #pragma omp target parallel firstprivate(S2::S2sc)
+ foo();
+ #pragma omp target parallel firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+ foo();
+ #pragma omp target parallel firstprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be firstprivate}}
+ foo();
+ #pragma omp target parallel private(i), firstprivate(i) // expected-error {{private variable cannot be firstprivate}} expected-note{{defined as private}}
+ foo();
+ #pragma omp target parallel shared(i)
+ foo();
+ #pragma omp target parallel firstprivate(i)
+ foo();
+ #pragma omp target parallel firstprivate(j)
+ foo();
+ #pragma omp target parallel firstprivate(m)
+ foo();
+
+ return 0;
+}
diff --git a/test/OpenMP/target_parallel_for_ast_print.cpp b/test/OpenMP/target_parallel_for_ast_print.cpp
new file mode 100644
index 0000000000000..6c551cbb9abfe
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_ast_print.cpp
@@ -0,0 +1,252 @@
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+struct S {
+ S(): a(0) {}
+ S(int v) : a(v) {}
+ int a;
+ typedef int type;
+};
+
+template <typename T>
+class S7 : public T {
+protected:
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(typename T::type v) : a(v) {
+#pragma omp target parallel for private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp target parallel for private(a) private(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp target parallel for private(this->a) private(this->a) private(this->S::a)
+// CHECK: #pragma omp target parallel for private(this->a) private(this->a) private(T::a)
+// CHECK: #pragma omp target parallel for private(this->a) private(this->a)
+
+class S8 : public S7<S> {
+ S8() {}
+
+public:
+ S8(int v) : S7<S>(v){
+#pragma omp target parallel for private(a) private(this->a) private(S7<S>::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S8 &operator=(S8 &s) {
+#pragma omp target parallel for private(a) private(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp target parallel for private(this->a) private(this->a) private(this->S7<S>::a)
+// CHECK: #pragma omp target parallel for private(this->a) private(this->a)
+
+template <class T, int N>
+T tmain(T argc, T *argv) {
+ T b = argc, c, d, e, f, h;
+ T arr[N][10], arr1[N];
+ T i, j;
+ T s;
+ static T a;
+// CHECK: static T a;
+ static T g;
+#pragma omp threadprivate(g)
+#pragma omp target parallel for schedule(dynamic) default(none) linear(a)
+ // CHECK: #pragma omp target parallel for schedule(dynamic) default(none) linear(a)
+ for (int i = 0; i < 2; ++i)
+ a = 2;
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp target parallel for private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered(N) if (parallel :argc) num_threads(N) default(shared) shared(e) reduction(+ : h)
+ for (int i = 0; i < 2; ++i)
+ for (int j = 0; j < 2; ++j)
+ for (int j = 0; j < 2; ++j)
+ for (int j = 0; j < 2; ++j)
+ for (int j = 0; j < 2; ++j)
+ for (int i = 0; i < 2; ++i)
+ for (int j = 0; j < 2; ++j)
+ for (int j = 0; j < 2; ++j)
+ for (int j = 0; j < 2; ++j)
+ for (int j = 0; j < 2; ++j)
+ foo();
+ // CHECK-NEXT: #pragma omp target parallel for private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered(N) if(parallel: argc) num_threads(N) default(shared) shared(e) reduction(+: h)
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: foo();
+#pragma omp target parallel for default(none), private(argc,b) firstprivate(argv) shared (d) if (parallel:argc > 0) num_threads(N) proc_bind(master) reduction(+:c, arr1[argc]) reduction(max:e, arr[:N][0:10])
+ for (int i = 0; i < 2; ++i) {}
+// CHECK-NEXT: #pragma omp target parallel for default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(N) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:N][0:10])
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+#pragma omp target parallel for if (N) num_threads(s) proc_bind(close) reduction(^:e, f, arr[0:N][:argc]) reduction(&& : h)
+// CHECK-NEXT: #pragma omp target parallel for if(N) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:N][:argc]) reduction(&&: h)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+#pragma omp target parallel for if (target:argc > 0)
+// CHECK-NEXT: #pragma omp target parallel for if(target: argc > 0)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+#pragma omp target parallel for if (parallel:argc > 0)
+// CHECK-NEXT: #pragma omp target parallel for if(parallel: argc > 0)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+#pragma omp target parallel for if (N)
+// CHECK-NEXT: #pragma omp target parallel for if(N)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+#pragma omp target parallel for map(i)
+// CHECK-NEXT: #pragma omp target parallel for map(tofrom: i)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+#pragma omp target parallel for map(arr1[0:10], i)
+// CHECK-NEXT: #pragma omp target parallel for map(tofrom: arr1[0:10],i)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+#pragma omp target parallel for map(to: i) map(from: j)
+// CHECK-NEXT: #pragma omp target parallel for map(to: i) map(from: j)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+#pragma omp target parallel for map(always,alloc: i)
+// CHECK-NEXT: #pragma omp target parallel for map(always,alloc: i)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+#pragma omp target parallel for nowait
+// CHECK-NEXT: #pragma omp target parallel for nowait
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+#pragma omp target parallel for depend(in : argc, arr[i:argc], arr1[:])
+// CHECK-NEXT: #pragma omp target parallel for depend(in : argc,arr[i:argc],arr1[:])
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+#pragma omp target parallel for defaultmap(tofrom: scalar)
+// CHECK-NEXT: #pragma omp target parallel for defaultmap(tofrom: scalar)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+ return T();
+}
+
+int main(int argc, char **argv) {
+ int b = argc, c, d, e, f, h;
+ int arr[5][10], arr1[5];
+ int i, j;
+ int s;
+ static int a;
+// CHECK: static int a;
+ static float g;
+#pragma omp threadprivate(g)
+#pragma omp target parallel for schedule(guided, argc) default(none) linear(a)
+ // CHECK: #pragma omp target parallel for schedule(guided, argc) default(none) linear(a)
+ for (int i = 0; i < 2; ++i)
+ a = 2;
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp target parallel for private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) ordered if (target: argc) num_threads(a) default(shared) shared(e) reduction(+ : h) linear(a:-5)
+ for (int i = 0; i < 10; ++i)
+ for (int j = 0; j < 10; ++j)
+ foo();
+ // CHECK-NEXT: #pragma omp target parallel for private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) ordered if(target: argc) num_threads(a) default(shared) shared(e) reduction(+: h) linear(a: -5)
+ // CHECK-NEXT: for (int i = 0; i < 10; ++i)
+ // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+ // CHECK-NEXT: foo();
+#pragma omp target parallel for default(none), private(argc,b) firstprivate(argv) shared (d) if (parallel:argc > 0) num_threads(5) proc_bind(master) reduction(+:c, arr1[argc]) reduction(max:e, arr[:5][0:10])
+ for (int i = 0; i < 2; ++i) {}
+// CHECK-NEXT: #pragma omp target parallel for default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(5) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:5][0:10])
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+#pragma omp target parallel for if (5) num_threads(s) proc_bind(close) reduction(^:e, f, arr[0:5][:argc]) reduction(&& : h)
+// CHECK-NEXT: #pragma omp target parallel for if(5) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:5][:argc]) reduction(&&: h)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+#pragma omp target parallel for if (target:argc > 0)
+// CHECK-NEXT: #pragma omp target parallel for if(target: argc > 0)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+#pragma omp target parallel for if (parallel:argc > 0)
+// CHECK-NEXT: #pragma omp target parallel for if(parallel: argc > 0)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+#pragma omp target parallel for if (5)
+// CHECK-NEXT: #pragma omp target parallel for if(5)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+#pragma omp target parallel for map(i)
+// CHECK-NEXT: #pragma omp target parallel for map(tofrom: i)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+#pragma omp target parallel for map(arr1[0:10], i)
+// CHECK-NEXT: #pragma omp target parallel for map(tofrom: arr1[0:10],i)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+#pragma omp target parallel for map(to: i) map(from: j)
+// CHECK-NEXT: #pragma omp target parallel for map(to: i) map(from: j)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+#pragma omp target parallel for map(always,alloc: i)
+// CHECK-NEXT: #pragma omp target parallel for map(always,alloc: i)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+#pragma omp target parallel for nowait
+// CHECK-NEXT: #pragma omp target parallel for nowait
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+#pragma omp target parallel for depend(in : argc, arr[i:argc], arr1[:])
+// CHECK-NEXT: #pragma omp target parallel for depend(in : argc,arr[i:argc],arr1[:])
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+#pragma omp target parallel for defaultmap(tofrom: scalar)
+// CHECK-NEXT: #pragma omp target parallel for defaultmap(tofrom: scalar)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+ return (tmain<int, 5>(argc, &argc) + tmain<char, 1>(argv[0][0], argv[0]));
+}
+
+#endif
diff --git a/test/OpenMP/target_parallel_for_collapse_messages.cpp b/test/OpenMP/target_parallel_for_collapse_messages.cpp
new file mode 100644
index 0000000000000..8cf502be0d9cc
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_collapse_messages.cpp
@@ -0,0 +1,83 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
+ #pragma omp target parallel for collapse // expected-error {{expected '(' after 'collapse'}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for collapse () // expected-error {{expected expression}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+ // expected-error@+2 2 {{expression is not an integral constant expression}}
+ // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}}
+ #pragma omp target parallel for collapse (argc
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ #pragma omp target parallel for collapse (ST // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp target parallel for', but found only 1}}
+ // expected-error@+3 2 {{directive '#pragma omp target parallel for' cannot contain more than one 'collapse' clause}}
+ // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+1 2 {{expression is not an integral constant expression}}
+ #pragma omp target parallel for collapse (foobool(argc)), collapse (true), collapse (-5)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for collapse (S) // expected-error {{'S' does not refer to a value}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-error@+1 2 {{expression is not an integral constant expression}}
+ #pragma omp target parallel for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for collapse (1)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for collapse (N) // expected-error {{argument to 'collapse' clause must be a strictly positive integer value}}
+ for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for collapse (2) // expected-note {{as specified in 'collapse' clause}}
+ foo(); // expected-error {{expected 2 for loops after '#pragma omp target parallel for'}}
+ return argc;
+}
+
+int main(int argc, char **argv) {
+ #pragma omp target parallel for collapse // expected-error {{expected '(' after 'collapse'}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for collapse () // expected-error {{expected expression}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for collapse (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'collapse' clause}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp target parallel for', but found only 1}}
+ #pragma omp target parallel for collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} expected-note {{as specified in 'collapse' clause}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp target parallel for', but found only 1}}
+ #pragma omp target parallel for collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+3 {{expression is not an integral constant expression}}
+ // expected-error@+2 2 {{directive '#pragma omp target parallel for' cannot contain more than one 'collapse' clause}}
+ // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ #pragma omp target parallel for collapse (foobool(argc)), collapse (true), collapse (-5)
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for collapse (S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+1 {{expression is not an integral constant expression}}
+ #pragma omp target parallel for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+3 {{statement after '#pragma omp target parallel for' must be a for loop}}
+ // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+ #pragma omp target parallel for collapse(collapse(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+ foo();
+ #pragma omp target parallel for collapse (2) // expected-note {{as specified in 'collapse' clause}}
+ foo(); // expected-error {{expected 2 for loops after '#pragma omp target parallel for'}}
+ // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
+ return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/target_parallel_for_default_messages.cpp b/test/OpenMP/target_parallel_for_default_messages.cpp
new file mode 100644
index 0000000000000..c1f04f4f6e409
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_default_messages.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo();
+
+int main(int argc, char **argv) {
+ int i;
+#pragma omp target parallel for default // expected-error {{expected '(' after 'default'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for default(none // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+ foo();
+#pragma omp target parallel for default(shared), default(shared) // expected-error {{directive '#pragma omp target parallel for' cannot contain more than one 'default' clause}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+
+#pragma omp target parallel for default(none)
+ for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+ foo();
+
+#pragma omp parallel default(none)
+#pragma omp target parallel for default(shared)
+ for (i = 0; i < argc; ++i)
+ foo();
+
+ return 0;
+}
diff --git a/test/OpenMP/target_parallel_for_defaultmap_messages.cpp b/test/OpenMP/target_parallel_for_defaultmap_messages.cpp
new file mode 100644
index 0000000000000..24973edd2bda8
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_defaultmap_messages.cpp
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+template <class T, typename S, int N, int ST>
+T tmain(T argc, S **argv) {
+ int i;
+ #pragma omp target parallel for defaultmap // expected-error {{expected '(' after 'defaultmap'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return argc;
+}
+
+int main(int argc, char **argv) {
+ int i;
+ #pragma omp target parallel for defaultmap // expected-error {{expected '(' after 'defaultmap'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/target_parallel_for_depend_messages.cpp b/test/OpenMP/target_parallel_for_depend_messages.cpp
new file mode 100644
index 0000000000000..d0e74f9cc6295
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_depend_messages.cpp
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+class vector {
+ public:
+ int operator[](int index) { return 0; }
+};
+
+int main(int argc, char **argv, char *env[]) {
+ vector vec;
+ typedef float V __attribute__((vector_size(16)));
+ V a;
+ auto arr = x; // expected-error {{use of undeclared identifier 'x'}}
+ int i;
+
+ #pragma omp target parallel for depend // expected-error {{expected '(' after 'depend'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend (out: ) // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend (out :S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend (in : argv[0])
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend (in : ) // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend (in : main) // expected-error {{expected variable name, array element or array section}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend (in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend (in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend (in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend(in : argv[ : argc][1 : argc - 1])
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for depend(in : arr[0])
+ for (i = 0; i < argc; ++i) foo();
+
+ return 0;
+}
diff --git a/test/OpenMP/target_parallel_for_device_messages.cpp b/test/OpenMP/target_parallel_for_device_messages.cpp
new file mode 100644
index 0000000000000..16a21ba4d662d
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_device_messages.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+int main(int argc, char **argv) {
+ int i;
+ #pragma omp target parallel for device // expected-error {{expected '(' after 'device'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for device () // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for device (argc + argc)
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for device (argc), device (argc+1) // expected-error {{directive '#pragma omp target parallel for' cannot contain more than one 'device' clause}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for device (S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for device (-10u)
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return 0;
+}
diff --git a/test/OpenMP/target_parallel_for_firstprivate_messages.cpp b/test/OpenMP/target_parallel_for_firstprivate_messages.cpp
new file mode 100644
index 0000000000000..36bfe25e94682
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_firstprivate_messages.cpp
@@ -0,0 +1,261 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+
+public:
+ S2() : a(0) {}
+ S2(const S2 &s2) : a(s2.a) {}
+ static float S2s;
+ static const float S2sc;
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+ S3 &operator=(const S3 &s3);
+
+public:
+ S3() : a(0) {}
+ S3(const S3 &s3) : a(s3.a) {}
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 {
+ int a;
+ S4();
+ S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}}
+
+public:
+ S4(int v) : a(v) {}
+};
+class S5 {
+ int a;
+ S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}}
+
+public:
+ S5() : a(0) {}
+ S5(int v) : a(v) {}
+};
+class S6 {
+ int a;
+ S6() : a(0) {}
+
+public:
+ S6(const S6 &s6) : a(s6.a) {}
+ S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+ I e(4);
+ C g(5);
+ int i;
+ int &j = i;
+#pragma omp target parallel for firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for firstprivate() // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for firstprivate(argc)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for firstprivate(argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp parallel
+ {
+ int v = 0;
+ int i;
+#pragma omp target parallel for firstprivate(i)
+ for (int k = 0; k < argc; ++k) {
+ i = k;
+ v += i;
+ }
+ }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp target parallel for firstprivate(j)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for firstprivate(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp parallel private(i)
+#pragma omp target parallel for firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for' directive may not be firstprivate, predetermined as private}}
+ foo();
+#pragma omp parallel reduction(+ : i)
+#pragma omp target parallel for firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for' directive may not be firstprivate, predetermined as private}}
+ foo();
+ return 0;
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5;
+ const int da[5] = {0};
+ S4 e(4);
+ S5 g(5);
+ S3 m;
+ S6 n(2);
+ int i;
+ int &j = i;
+#pragma omp target parallel for firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for firstprivate() // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for firstprivate(argc)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for firstprivate(argv[1]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for firstprivate(2 * 2) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for firstprivate(ba) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for firstprivate(ca) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for firstprivate(da) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+ int xa;
+#pragma omp target parallel for firstprivate(xa) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for firstprivate(S2::S2s) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for firstprivate(S2::S2sc) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp target parallel for'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for firstprivate(m) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for firstprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be firstprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for' directive may not be firstprivate, predetermined as private}}
+ foo();
+#pragma omp parallel shared(xa)
+#pragma omp target parallel for firstprivate(xa) // OK: may be firstprivate
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for firstprivate(j)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for lastprivate(n) firstprivate(n) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp parallel
+ {
+ int v = 0;
+ int i;
+#pragma omp target parallel for firstprivate(i)
+ for (int k = 0; k < argc; ++k) {
+ i = k;
+ v += i;
+ }
+ }
+#pragma omp parallel private(i)
+#pragma omp target parallel for firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for' directive may not be firstprivate, predetermined as private}}
+ foo();
+#pragma omp parallel reduction(+ : i)
+#pragma omp target parallel for firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for' directive may not be firstprivate, predetermined as private}}
+ foo();
+ static int si;
+#pragma omp target parallel for firstprivate(si) // OK
+ for (i = 0; i < argc; ++i)
+ si = i + 1;
+
+ return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/target_parallel_for_if_messages.cpp b/test/OpenMP/target_parallel_for_if_messages.cpp
new file mode 100644
index 0000000000000..01173c159d57f
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_if_messages.cpp
@@ -0,0 +1,105 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, class S> // expected-note {{declared here}}
+int tmain(T argc, S **argv) {
+ int i;
+ #pragma omp target parallel for if // expected-error {{expected '(' after 'if'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if () // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if (argc > 0 ? argv[1] : argv[2])
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target parallel for' cannot contain more than one 'if' clause}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if (S) // expected-error {{'S' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if(argc)
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if(target : argc)
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if(parallel : argc)
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if(target : argc) if(parallel : argc)
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target parallel for'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if(target : argc) if (target :argc) // expected-error {{directive '#pragma omp target parallel for' cannot contain more than one 'if' clause with 'target' name modifier}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if(parallel : argc) if (parallel :argc) // expected-error {{directive '#pragma omp target parallel for' cannot contain more than one 'if' clause with 'parallel' name modifier}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if(target : argc) if (argc) // expected-error {{expected 'parallel' directive name modifier}} expected-note {{previous clause with directive name modifier specified here}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if(target : argc) if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} expected-note {{previous clause with directive name modifier specified here}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ int i;
+ #pragma omp target parallel for if // expected-error {{expected '(' after 'if'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if () // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if (argc > 0 ? argv[1] : argv[2])
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target parallel for' cannot contain more than one 'if' clause}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if (S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if(parallel : argc)
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if(target : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target parallel for'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if(target : argc) if (target :argc) // expected-error {{directive '#pragma omp target parallel for' cannot contain more than one 'if' clause with 'target' name modifier}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if(parallel : argc) if (parallel :argc) // expected-error {{directive '#pragma omp target parallel for' cannot contain more than one 'if' clause with 'parallel' name modifier}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if(target : argc) if (argc) // expected-error {{expected 'parallel' directive name modifier}} expected-note {{previous clause with directive name modifier specified here}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for if(target : argc) if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} expected-note {{previous clause with directive name modifier specified here}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return tmain(argc, argv);
+}
diff --git a/test/OpenMP/target_parallel_for_lastprivate_messages.cpp b/test/OpenMP/target_parallel_for_lastprivate_messages.cpp
new file mode 100644
index 0000000000000..c001b7f0d1685
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_lastprivate_messages.cpp
@@ -0,0 +1,238 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+
+public:
+ S2() : a(0) {}
+ S2(S2 &s2) : a(s2.a) {}
+ S2 &operator=(const S2 &);
+ const S2 &operator=(const S2 &) const;
+ static float S2s; // expected-note {{static data member is predetermined as shared}}
+ static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+ S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}}
+
+public:
+ S3() : a(0) {}
+ S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c; // expected-note {{global variable is predetermined as shared}}
+const S3 ca[5]; // expected-note {{global variable is predetermined as shared}}
+extern const int f; // expected-note {{global variable is predetermined as shared}}
+class S4 {
+ int a;
+ S4(); // expected-note 3 {{implicitly declared private here}}
+ S4(const S4 &s4);
+
+public:
+ S4(int v) : a(v) {}
+};
+class S5 {
+ int a;
+ S5() : a(0) {} // expected-note {{implicitly declared private here}}
+
+public:
+ S5(const S5 &s5) : a(s5.a) {}
+ S5(int v) : a(v) {}
+};
+class S6 {
+ int a;
+ S6() : a(0) {}
+
+public:
+ S6(const S6 &s6) : a(s6.a) {}
+ S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+ I e(4);
+ I g(5);
+ int i;
+ int &j = i;
+#pragma omp target parallel for lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for lastprivate() // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for lastprivate(argc)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for lastprivate(argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp parallel
+ {
+ int v = 0;
+ int i;
+#pragma omp target parallel for lastprivate(i)
+ for (int k = 0; k < argc; ++k) {
+ i = k;
+ v += i;
+ }
+ }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp target parallel for lastprivate(j)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for lastprivate(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+ return 0;
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5; // expected-note {{constant variable is predetermined as shared}}
+ const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+ S4 e(4);
+ S5 g(5);
+ S3 m;
+ S6 n(2);
+ int i;
+ int &j = i;
+#pragma omp target parallel for lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for lastprivate() // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for lastprivate(argc)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for lastprivate(argv[1]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for lastprivate(2 * 2) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for lastprivate(ba)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+ int xa;
+#pragma omp target parallel for lastprivate(xa) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp target parallel for'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for lastprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for lastprivate(i)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp parallel private(xa)
+#pragma omp target parallel for lastprivate(xa)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp parallel reduction(+ : xa)
+#pragma omp target parallel for lastprivate(xa)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for lastprivate(j)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for lastprivate(n) firstprivate(n) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+ static int si;
+#pragma omp target parallel for lastprivate(si) // OK
+ for (i = 0; i < argc; ++i)
+ si = i + 2;
+
+ return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/target_parallel_for_linear_messages.cpp b/test/OpenMP/target_parallel_for_linear_messages.cpp
new file mode 100644
index 0000000000000..36e897d5946e6
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_linear_messages.cpp
@@ -0,0 +1,269 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+namespace X {
+int x;
+};
+
+struct B {
+ static int ib; // expected-note {{'B::ib' declared here}}
+ static int bfoo() { return 8; }
+};
+
+int bfoo() { return 4; }
+
+int z;
+const int C1 = 1;
+const int C2 = 2;
+void test_linear_colons() {
+ int B = 0;
+#pragma omp target parallel for linear(B : bfoo())
+ for (int i = 0; i < 10; ++i)
+ ;
+// expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'}}
+#pragma omp target parallel for linear(B::ib : B : bfoo())
+ for (int i = 0; i < 10; ++i)
+ ;
+// expected-error@+1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+#pragma omp target parallel for linear(B : ib)
+ for (int i = 0; i < 10; ++i)
+ ;
+// expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
+#pragma omp target parallel for linear(z : B : ib)
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target parallel for linear(B : B::bfoo())
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target parallel for linear(X::x : ::z)
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target parallel for linear(B, ::z, X::x)
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target parallel for linear(::z)
+ for (int i = 0; i < 10; ++i)
+ ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp target parallel for linear(B::bfoo())
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target parallel for linear(B::ib, B : C1 + C2)
+ for (int i = 0; i < 10; ++i)
+ ;
+}
+
+template <int L, class T, class N>
+T test_template(T *arr, N num) {
+ N i;
+ T sum = (T)0;
+ T ind2 = -num * L; // expected-note {{'ind2' defined here}}
+// expected-error@+1 {{argument of a linear clause should be of integral or pointer type}}
+#pragma omp target parallel for linear(ind2 : L)
+ for (i = 0; i < num; ++i) {
+ T cur = arr[(int)ind2];
+ ind2 += L;
+ sum += cur;
+ }
+ return T();
+}
+
+template <int LEN>
+int test_warn() {
+ int ind2 = 0;
+// expected-warning@+1 {{zero linear step (ind2 should probably be const)}}
+#pragma omp target parallel for linear(ind2 : LEN)
+ for (int i = 0; i < 100; i++) {
+ ind2 += LEN;
+ }
+ return ind2;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+
+public:
+ S2() : a(0) {}
+};
+const S2 b; // expected-note 2 {{'b' defined here}}
+const S2 ba[5];
+class S3 {
+ int a;
+
+public:
+ S3() : a(0) {}
+};
+const S3 ca[5];
+class S4 {
+ int a;
+ S4();
+
+public:
+ S4(int v) : a(v) {}
+};
+class S5 {
+ int a;
+ S5() : a(0) {}
+
+public:
+ S5(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(I argc, C **argv) {
+ I e(4);
+ I g(5);
+ int i;
+ int &j = i;
+#pragma omp target parallel for linear // expected-error {{expected '(' after 'linear'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for linear( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for linear() // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for linear(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for linear(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for linear(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for linear(argc : 5)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for linear(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+// expected-error@+2 {{linear variable with incomplete type 'S1'}}
+// expected-error@+1 {{const-qualified variable cannot be linear}}
+#pragma omp target parallel for linear(a, b : B::ib)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for linear(argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for linear(e, g)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for linear(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp parallel
+ {
+ int v = 0;
+ int i;
+#pragma omp target parallel for linear(v : i)
+ for (int k = 0; k < argc; ++k) {
+ i = k;
+ v += i;
+ }
+ }
+#pragma omp target parallel for linear(j)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+ int v = 0;
+#pragma omp target parallel for linear(v : j)
+ for (int k = 0; k < argc; ++k) {
+ ++k;
+ v += j;
+ }
+#pragma omp target parallel for linear(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+ return 0;
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace C {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ double darr[100];
+ // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}}
+ test_template<-4>(darr, 4);
+ // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}}
+ test_warn<0>();
+
+ S4 e(4); // expected-note {{'e' defined here}}
+ S5 g(5); // expected-note {{'g' defined here}}
+ int i;
+ int &j = i;
+#pragma omp target parallel for linear // expected-error {{expected '(' after 'linear'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for linear( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for linear() // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for linear(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for linear(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for linear(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for linear(argc)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for linear(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+// expected-error@+2 {{linear variable with incomplete type 'S1'}}
+// expected-error@+1 {{const-qualified variable cannot be linear}}
+#pragma omp target parallel for linear(a, b)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for linear(argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+// expected-error@+2 {{argument of a linear clause should be of integral or pointer type, not 'S4'}}
+// expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S5'}}
+#pragma omp target parallel for linear(e, g)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp parallel
+ {
+ int i;
+#pragma omp target parallel for linear(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for linear(i : 4)
+ for (int k = 0; k < argc; ++k) {
+ ++k;
+ i += 4;
+ }
+ }
+#pragma omp target parallel for linear(j)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for linear(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+
+ foomain<int, char>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
+ return 0;
+}
+
diff --git a/test/OpenMP/target_parallel_for_loop_messages.cpp b/test/OpenMP/target_parallel_for_loop_messages.cpp
new file mode 100644
index 0000000000000..0e8eab10b5cb5
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_loop_messages.cpp
@@ -0,0 +1,627 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s
+
+class S {
+ int a;
+ S() : a(0) {}
+
+public:
+ S(int v) : a(v) {}
+ S(const S &s) : a(s.a) {}
+};
+
+static int sii;
+// expected-note@+1 {{defined as threadprivate or thread local}}
+#pragma omp threadprivate(sii)
+static int globalii;
+
+int test_iteration_spaces() {
+ const int N = 100;
+ float a[N], b[N], c[N];
+ int ii, jj, kk;
+ float fii;
+ double dii;
+#pragma omp target parallel for
+ for (int i = 0; i < 10; i += 1) {
+ c[i] = a[i] + b[i];
+ }
+#pragma omp target parallel for
+ for (char i = 0; i < 10; i++) {
+ c[i] = a[i] + b[i];
+ }
+#pragma omp target parallel for
+ for (char i = 0; i < 10; i += '\1') {
+ c[i] = a[i] + b[i];
+ }
+#pragma omp target parallel for
+ for (long long i = 0; i < 10; i++) {
+ c[i] = a[i] + b[i];
+ }
+// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}}
+#pragma omp target parallel for
+ for (long long i = 0; i < 10; i += 1.5) {
+ c[i] = a[i] + b[i];
+ }
+#pragma omp target parallel for
+ for (long long i = 0; i < 'z'; i += 1u) {
+ c[i] = a[i] + b[i];
+ }
+// expected-error@+2 {{variable must be of integer or random access iterator type}}
+#pragma omp target parallel for
+ for (float fi = 0; fi < 10.0; fi++) {
+ c[(int)fi] = a[(int)fi] + b[(int)fi];
+ }
+// expected-error@+2 {{variable must be of integer or random access iterator type}}
+#pragma omp target parallel for
+ for (double fi = 0; fi < 10.0; fi++) {
+ c[(int)fi] = a[(int)fi] + b[(int)fi];
+ }
+// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for
+ for (int &ref = ii; ref < 10; ref++) {
+ }
+// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for
+ for (int i; i < 10; i++)
+ c[i] = a[i];
+
+// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for
+ for (int i = 0, j = 0; i < 10; ++i)
+ c[i] = a[i];
+
+// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for
+ for (; ii < 10; ++ii)
+ c[ii] = a[ii];
+
+// expected-warning@+3 {{expression result unused}}
+// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for
+ for (ii + 1; ii < 10; ++ii)
+ c[ii] = a[ii];
+
+// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for
+ for (c[ii] = 0; ii < 10; ++ii)
+ c[ii] = a[ii];
+
+// Ok to skip parenthesises.
+#pragma omp target parallel for
+ for (((ii)) = 0; ii < 10; ++ii)
+ c[ii] = a[ii];
+
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp target parallel for
+ for (int i = 0; i; i++)
+ c[i] = a[i];
+
+// expected-error@+3 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}}
+#pragma omp target parallel for
+ for (int i = 0; jj < kk; ii++)
+ c[i] = a[i];
+
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp target parallel for
+ for (int i = 0; !!i; i++)
+ c[i] = a[i];
+
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp target parallel for
+ for (int i = 0; i != 1; i++)
+ c[i] = a[i];
+
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp target parallel for
+ for (int i = 0;; i++)
+ c[i] = a[i];
+
+// Ok.
+#pragma omp target parallel for
+ for (int i = 11; i > 10; i--)
+ c[i] = a[i];
+
+// Ok.
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i)
+ c[i] = a[i];
+
+// Ok.
+#pragma omp target parallel for
+ for (ii = 0; ii < 10; ++ii)
+ c[ii] = a[ii];
+
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp target parallel for
+ for (ii = 0; ii < 10; ++jj)
+ c[ii] = a[jj];
+
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp target parallel for
+ for (ii = 0; ii < 10; ++++ii)
+ c[ii] = a[ii];
+
+// Ok but undefined behavior (in general, cannot check that incr
+// is really loop-invariant).
+#pragma omp target parallel for
+ for (ii = 0; ii < 10; ii = ii + ii)
+ c[ii] = a[ii];
+
+// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'float'}}
+#pragma omp target parallel for
+ for (ii = 0; ii < 10; ii = ii + 1.0f)
+ c[ii] = a[ii];
+
+// Ok - step was converted to integer type.
+#pragma omp target parallel for
+ for (ii = 0; ii < 10; ii = ii + (int)1.1f)
+ c[ii] = a[ii];
+
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp target parallel for
+ for (ii = 0; ii < 10; jj = ii + 2)
+ c[ii] = a[ii];
+
+// expected-warning@+3 {{relational comparison result unused}}
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp target parallel for
+ for (ii = 0; ii<10; jj> kk + 2)
+ c[ii] = a[ii];
+
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp target parallel for
+ for (ii = 0; ii < 10;)
+ c[ii] = a[ii];
+
+// expected-warning@+3 {{expression result unused}}
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp target parallel for
+ for (ii = 0; ii < 10; !ii)
+ c[ii] = a[ii];
+
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp target parallel for
+ for (ii = 0; ii < 10; ii ? ++ii : ++jj)
+ c[ii] = a[ii];
+
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp target parallel for
+ for (ii = 0; ii < 10; ii = ii < 10)
+ c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp target parallel for
+ for (ii = 0; ii < 10; ii = ii + 0)
+ c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp target parallel for
+ for (ii = 0; ii < 10; ii = ii + (int)(0.8 - 0.45))
+ c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp target parallel for
+ for (ii = 0; (ii) < 10; ii -= 25)
+ c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp target parallel for
+ for (ii = 0; (ii < 10); ii -= 0)
+ c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+#pragma omp target parallel for
+ for (ii = 0; ii > 10; (ii += 0))
+ c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp target parallel for
+ for (ii = 0; ii < 10; (ii) = (1 - 1) + (ii))
+ c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+#pragma omp target parallel for
+ for ((ii = 0); ii > 10; (ii -= 0))
+ c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp target parallel for
+ for (ii = 0; (ii < 10); (ii -= 0))
+ c[ii] = a[ii];
+
+// expected-note@+2 {{defined as firstprivate}}
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp target parallel for' directive may not be firstprivate, predetermined as private}}
+#pragma omp target parallel for firstprivate(ii)
+ for (ii = 0; ii < 10; ii++)
+ c[ii] = a[ii];
+
+// expected-note@+2 {{defined as linear}}
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp target parallel for' directive may not be linear, predetermined as private}}
+#pragma omp target parallel for linear(ii)
+ for (ii = 0; ii < 10; ii++)
+ c[ii] = a[ii];
+
+#pragma omp target parallel for private(ii)
+ for (ii = 0; ii < 10; ii++)
+ c[ii] = a[ii];
+
+#pragma omp target parallel for lastprivate(ii)
+ for (ii = 0; ii < 10; ii++)
+ c[ii] = a[ii];
+
+ {
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp target parallel for' directive may not be threadprivate or thread local, predetermined as private}}
+#pragma omp target parallel for
+ for (sii = 0; sii < 10; sii += 1)
+ c[sii] = a[sii];
+ }
+
+ {
+#pragma omp target parallel for
+ for (globalii = 0; globalii < 10; globalii += 1)
+ c[globalii] = a[globalii];
+ }
+
+ {
+#pragma omp target parallel for collapse(2)
+ for (ii = 0; ii < 10; ii += 1)
+ for (globalii = 0; globalii < 10; globalii += 1)
+ c[globalii] += a[globalii] + ii;
+ }
+
+// expected-error@+2 {{statement after '#pragma omp target parallel for' must be a for loop}}
+#pragma omp target parallel for
+ for (auto &item : a) {
+ item = item + 1;
+ }
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'i' to increase on each iteration of OpenMP for loop}}
+#pragma omp target parallel for
+ for (unsigned i = 9; i < 10; i--) {
+ c[i] = a[i] + b[i];
+ }
+
+ int(*lb)[4] = nullptr;
+#pragma omp target parallel for
+ for (int(*p)[4] = lb; p < lb + 8; ++p) {
+ }
+
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for
+ for (int a{0}; a < 10; ++a) {
+ }
+
+ return 0;
+}
+
+// Iterators allowed in openmp for-loops.
+namespace std {
+struct random_access_iterator_tag {};
+template <class Iter>
+struct iterator_traits {
+ typedef typename Iter::difference_type difference_type;
+ typedef typename Iter::iterator_category iterator_category;
+};
+template <class Iter>
+typename iterator_traits<Iter>::difference_type
+distance(Iter first, Iter last) { return first - last; }
+}
+class Iter0 {
+public:
+ Iter0() {}
+ Iter0(const Iter0 &) {}
+ Iter0 operator++() { return *this; }
+ Iter0 operator--() { return *this; }
+ bool operator<(Iter0 a) { return true; }
+};
+// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'Iter0' for 1st argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'Iter0' for 1st argument}}
+int operator-(Iter0 a, Iter0 b) { return 0; }
+class Iter1 {
+public:
+ Iter1(float f = 0.0f, double d = 0.0) {}
+ Iter1(const Iter1 &) {}
+ Iter1 operator++() { return *this; }
+ Iter1 operator--() { return *this; }
+ bool operator<(Iter1 a) { return true; }
+ bool operator>=(Iter1 a) { return false; }
+};
+class GoodIter {
+public:
+ GoodIter() {}
+ GoodIter(const GoodIter &) {}
+ GoodIter(int fst, int snd) {}
+ GoodIter &operator=(const GoodIter &that) { return *this; }
+ GoodIter &operator=(const Iter0 &that) { return *this; }
+ GoodIter &operator+=(int x) { return *this; }
+ GoodIter &operator-=(int x) { return *this; }
+ explicit GoodIter(void *) {}
+ GoodIter operator++() { return *this; }
+ GoodIter operator--() { return *this; }
+ bool operator!() { return true; }
+ bool operator<(GoodIter a) { return true; }
+ bool operator<=(GoodIter a) { return true; }
+ bool operator>=(GoodIter a) { return false; }
+ typedef int difference_type;
+ typedef std::random_access_iterator_tag iterator_category;
+};
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
+int operator-(GoodIter a, GoodIter b) { return 0; }
+// expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}}
+GoodIter operator-(GoodIter a) { return a; }
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
+GoodIter operator-(GoodIter a, int v) { return GoodIter(); }
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}}
+GoodIter operator+(GoodIter a, int v) { return GoodIter(); }
+// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'int' for 1st argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'int' for 1st argument}}
+GoodIter operator-(int v, GoodIter a) { return GoodIter(); }
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 1st argument}}
+GoodIter operator+(int v, GoodIter a) { return GoodIter(); }
+
+int test_with_random_access_iterator() {
+ GoodIter begin, end;
+ Iter0 begin0, end0;
+#pragma omp target parallel for
+ for (GoodIter I = begin; I < end; ++I)
+ ++I;
+// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for
+ for (GoodIter &I = begin; I < end; ++I)
+ ++I;
+#pragma omp target parallel for
+ for (GoodIter I = begin; I >= end; --I)
+ ++I;
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for
+ for (GoodIter I(begin); I < end; ++I)
+ ++I;
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for
+ for (GoodIter I(nullptr); I < end; ++I)
+ ++I;
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for
+ for (GoodIter I(0); I < end; ++I)
+ ++I;
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for
+ for (GoodIter I(1, 2); I < end; ++I)
+ ++I;
+#pragma omp target parallel for
+ for (begin = GoodIter(0); begin < end; ++begin)
+ ++begin;
+// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}}
+// expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
+#pragma omp target parallel for
+ for (begin = begin0; begin < end; ++begin)
+ ++begin;
+// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for
+ for (++begin; begin < end; ++begin)
+ ++begin;
+#pragma omp target parallel for
+ for (begin = end; begin < end; ++begin)
+ ++begin;
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+#pragma omp target parallel for
+ for (GoodIter I = begin; I - I; ++I)
+ ++I;
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+#pragma omp target parallel for
+ for (GoodIter I = begin; begin < end; ++I)
+ ++I;
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+#pragma omp target parallel for
+ for (GoodIter I = begin; !I; ++I)
+ ++I;
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp target parallel for
+ for (GoodIter I = begin; I >= end; I = I + 1)
+ ++I;
+#pragma omp target parallel for
+ for (GoodIter I = begin; I >= end; I = I - 1)
+ ++I;
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+#pragma omp target parallel for
+ for (GoodIter I = begin; I >= end; I = -I)
+ ++I;
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp target parallel for
+ for (GoodIter I = begin; I >= end; I = 2 + I)
+ ++I;
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+#pragma omp target parallel for
+ for (GoodIter I = begin; I >= end; I = 2 - I)
+ ++I;
+// expected-error@+2 {{invalid operands to binary expression ('Iter0' and 'int')}}
+#pragma omp target parallel for
+ for (Iter0 I = begin0; I < end0; ++I)
+ ++I;
+// Initializer is constructor without params.
+// expected-error@+3 {{invalid operands to binary expression ('Iter0' and 'int')}}
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for
+ for (Iter0 I; I < end0; ++I)
+ ++I;
+ Iter1 begin1, end1;
+// expected-error@+3 {{invalid operands to binary expression ('Iter1' and 'Iter1')}}
+// expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
+#pragma omp target parallel for
+ for (Iter1 I = begin1; I < end1; ++I)
+ ++I;
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp target parallel for
+ for (Iter1 I = begin1; I >= end1; ++I)
+ ++I;
+// expected-error@+5 {{invalid operands to binary expression ('Iter1' and 'float')}}
+// expected-error@+4 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
+// Initializer is constructor with all default params.
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for
+ for (Iter1 I; I < end1; ++I) {
+ }
+ return 0;
+}
+
+template <typename IT, int ST>
+class TC {
+public:
+ int dotest_lt(IT begin, IT end) {
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+#pragma omp target parallel for
+ for (IT I = begin; I < end; I = I + ST) {
+ ++I;
+ }
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+#pragma omp target parallel for
+ for (IT I = begin; I <= end; I += ST) {
+ ++I;
+ }
+#pragma omp target parallel for
+ for (IT I = begin; I < end; ++I) {
+ ++I;
+ }
+ }
+
+ static IT step() {
+ return IT(ST);
+ }
+};
+template <typename IT, int ST = 0>
+int dotest_gt(IT begin, IT end) {
+// expected-note@+3 2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp target parallel for
+ for (IT I = begin; I >= end; I = I + ST) {
+ ++I;
+ }
+// expected-note@+3 2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp target parallel for
+ for (IT I = begin; I >= end; I += ST) {
+ ++I;
+ }
+
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp target parallel for
+ for (IT I = begin; I >= end; ++I) {
+ ++I;
+ }
+
+#pragma omp target parallel for
+ for (IT I = begin; I < end; I += TC<int, ST>::step()) {
+ ++I;
+ }
+}
+
+void test_with_template() {
+ GoodIter begin, end;
+ TC<GoodIter, 100> t1;
+ TC<GoodIter, -100> t2;
+ t1.dotest_lt(begin, end);
+ t2.dotest_lt(begin, end); // expected-note {{in instantiation of member function 'TC<GoodIter, -100>::dotest_lt' requested here}}
+ dotest_gt(begin, end); // expected-note {{in instantiation of function template specialization 'dotest_gt<GoodIter, 0>' requested here}}
+ dotest_gt<unsigned, -10>(0, 100); // expected-note {{in instantiation of function template specialization 'dotest_gt<unsigned int, -10>' requested here}}
+}
+
+void test_loop_break() {
+ const int N = 100;
+ float a[N], b[N], c[N];
+#pragma omp target parallel for
+ for (int i = 0; i < 10; i++) {
+ c[i] = a[i] + b[i];
+ for (int j = 0; j < 10; ++j) {
+ if (a[i] > b[j])
+ break; // OK in nested loop
+ }
+ switch (i) {
+ case 1:
+ b[i]++;
+ break;
+ default:
+ break;
+ }
+ if (c[i] > 10)
+ break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+
+ if (c[i] > 11)
+ break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+ }
+
+#pragma omp target parallel for
+ for (int i = 0; i < 10; i++) {
+ for (int j = 0; j < 10; j++) {
+ c[i] = a[i] + b[i];
+ if (c[i] > 10) {
+ if (c[i] < 20) {
+ break; // OK
+ }
+ }
+ }
+ }
+}
+
+void test_loop_eh() {
+ const int N = 100;
+ float a[N], b[N], c[N];
+#pragma omp target parallel for
+ for (int i = 0; i < 10; i++) {
+ c[i] = a[i] + b[i];
+ try {
+ for (int j = 0; j < 10; ++j) {
+ if (a[i] > b[j])
+ throw a[i];
+ }
+ throw a[i];
+ } catch (float f) {
+ if (f > 0.1)
+ throw a[i];
+ return; // expected-error {{cannot return from OpenMP region}}
+ }
+ switch (i) {
+ case 1:
+ b[i]++;
+ break;
+ default:
+ break;
+ }
+ for (int j = 0; j < 10; j++) {
+ if (c[i] > 10)
+ throw c[i];
+ }
+ }
+ if (c[9] > 10)
+ throw c[9]; // OK
+
+#pragma omp target parallel for
+ for (int i = 0; i < 10; ++i) {
+ struct S {
+ void g() { throw 0; }
+ };
+ }
+}
+
+void test_loop_firstprivate_lastprivate() {
+ S s(4);
+#pragma omp target parallel for lastprivate(s) firstprivate(s)
+ for (int i = 0; i < 16; ++i)
+ ;
+}
diff --git a/test/OpenMP/target_parallel_for_map_messages.cpp b/test/OpenMP/target_parallel_for_map_messages.cpp
new file mode 100644
index 0000000000000..5223a2cc78ea8
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_map_messages.cpp
@@ -0,0 +1,273 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+extern S1 a;
+class S2 {
+ mutable int a;
+public:
+ S2():a(0) { }
+ S2(S2 &s2):a(s2.a) { }
+ static float S2s; // expected-note 4 {{mappable type cannot contain static members}}
+ static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}}
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+public:
+ S3():a(0) { }
+ S3(S3 &s3):a(s3.a) { }
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 {
+ int a;
+ S4();
+ S4(const S4 &s4);
+public:
+ S4(int v):a(v) { }
+};
+class S5 {
+ int a;
+ S5():a(0) {}
+ S5(const S5 &s5):a(s5.a) { }
+public:
+ S5(int v):a(v) { }
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+typedef int from;
+
+template <typename T, int I> // expected-note {{declared here}}
+T tmain(T argc) {
+ const T d = 5;
+ const T da[5] = { 0 };
+ S4 e(4);
+ S5 g(5);
+ T i, t[20];
+ T &j = i;
+ T *k = &j;
+ T x;
+ T y;
+ T to, tofrom, always;
+ const T (&l)[5] = da;
+
+
+#pragma omp target parallel for map // expected-error {{expected '(' after 'map'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map() // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(to:) // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(x)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(tofrom: t[:I])
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(T: a) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} expected-error {{incomplete type 'S1' where a complete type is required}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(T) // expected-error {{'T' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(S2::S2s)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(S2::S2sc)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(x)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(to: x)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(to: to)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(to)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(to, x)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(to x) // expected-error {{expected ',' or ')' in 'map' clause}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(argc)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(ca)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(da)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(S2::S2s)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(S2::S2sc)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(e, g)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(k), map(k) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(k), map(k[:5]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} expected-note 2 {{used here}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(da)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(da[:4])
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target data map(k, j, l) // expected-note 2 {{used here}}
+#pragma omp target parallel for map(k[:4]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(j)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(l) map(l[:5]) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target data map(k[:4], j, l[:5]) // expected-note 4 {{used here}}
+{
+#pragma omp target parallel for map(k) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(j)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(l) // expected-error 2 {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}}
+ for (i = 0; i < argc; ++i) foo();
+}
+
+#pragma omp target parallel for map(always, tofrom: x)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(always: x) // expected-error {{missing map type}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(always, tofrom: always, tofrom, x)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5;
+ const int da[5] = { 0 };
+ S4 e(4);
+ S5 g(5);
+ int i;
+ int &j = i;
+ int *k = &j;
+ int x;
+ int y;
+ int to, tofrom, always;
+ const int (&l)[5] = da;
+
+#pragma omp target parallel for map // expected-error {{expected '(' after 'map'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map() // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(to:) // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(x)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(to: x)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(to: to)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(to)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(to, x)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(to x) // expected-error {{expected ',' or ')' in 'map' clause}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(argc)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(argv[1])
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(ca)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(da)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(S2::S2s)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(S2::S2sc)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(e, g)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(k), map(k) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(k), map(k[:5]) // expected-error {{pointer cannot be mapped along with a section derived from itself}} expected-note {{used here}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(da)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(da[:4])
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target data map(k, j, l) // expected-note {{used here}}
+#pragma omp target parallel for map(k[:4]) // expected-error {{pointer cannot be mapped along with a section derived from itself}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(j)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(l) map(l[:5]) // expected-error 1 {{variable already marked as mapped in current construct}} expected-note 1 {{used here}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}}
+{
+#pragma omp target parallel for map(k) // expected-error {{pointer cannot be mapped along with a section derived from itself}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(j)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(l) // expected-error {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}}
+ for (i = 0; i < argc; ++i) foo();
+}
+
+#pragma omp target parallel for map(always, tofrom: x)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(always: x) // expected-error {{missing map type}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(always, tofrom: always, tofrom, x)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return tmain<int, 3>(argc)+tmain<from, 4>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<int, 4>' requested here}}
+}
+
diff --git a/test/OpenMP/target_parallel_for_messages.cpp b/test/OpenMP/target_parallel_for_messages.cpp
new file mode 100644
index 0000000000000..173025c01ce76
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_messages.cpp
@@ -0,0 +1,92 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -std=c++11 -o - %s
+
+void foo() {
+}
+
+static int pvt;
+#pragma omp threadprivate(pvt)
+
+#pragma omp target parallel for // expected-error {{unexpected OpenMP directive '#pragma omp target parallel for'}}
+
+int main(int argc, char **argv) {
+#pragma omp target parallel for { // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+ for (int i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for ( // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+ for (int i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for[ // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+ for (int i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for] // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+ for (int i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+ for (int i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for } // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+ for (int i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for
+ for (int i = 0; i < argc; ++i)
+ foo();
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+#pragma omp target parallel for unknown()
+ for (int i = 0; i < argc; ++i)
+ foo();
+L1:
+ for (int i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for
+ for (int i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for
+ for (int i = 0; i < argc; ++i) {
+ goto L1; // expected-error {{use of undeclared label 'L1'}}
+ argc++;
+ }
+
+ for (int i = 0; i < 10; ++i) {
+ switch (argc) {
+ case (0):
+#pragma omp target parallel for
+ for (int i = 0; i < argc; ++i) {
+ foo();
+ break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+ continue;
+ }
+ default:
+ break;
+ }
+ }
+#pragma omp target parallel for default(none)
+ for (int i = 0; i < 10; ++i)
+ ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+
+ goto L2; // expected-error {{use of undeclared label 'L2'}}
+#pragma omp target parallel for
+ for (int i = 0; i < argc; ++i)
+ L2:
+ foo();
+#pragma omp target parallel for
+ for (int i = 0; i < argc; ++i) {
+ return 1; // expected-error {{cannot return from OpenMP region}}
+ }
+
+ [[]] // expected-error {{an attribute list cannot appear here}}
+#pragma omp target parallel for
+ for (int n = 0; n < 100; ++n) {
+ }
+
+#pragma omp target parallel for copyin(pvt) // expected-error {{unexpected OpenMP clause 'copyin' in directive '#pragma omp target parallel for'}}
+ for (int n = 0; n < 100; ++n) {}
+
+ return 0;
+}
+
+void test_ordered() {
+#pragma omp target parallel for ordered ordered // expected-error {{directive '#pragma omp target parallel for' cannot contain more than one 'ordered' clause}}
+ for (int i = 0; i < 16; ++i)
+ ;
+}
+
diff --git a/test/OpenMP/target_parallel_for_misc_messages.c b/test/OpenMP/target_parallel_for_misc_messages.c
new file mode 100644
index 0000000000000..cfe83f1301075
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_misc_messages.c
@@ -0,0 +1,314 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp -verify %s
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp target parallel for'}}
+#pragma omp target parallel for
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp target parallel for'}}
+#pragma omp target parallel for foo
+
+void test_no_clause() {
+ int i;
+#pragma omp target parallel for
+ for (i = 0; i < 16; ++i)
+ ;
+
+// expected-error@+2 {{statement after '#pragma omp target parallel for' must be a for loop}}
+#pragma omp target parallel for
+ ++i;
+}
+
+void test_branch_protected_scope() {
+ int i = 0;
+L1:
+ ++i;
+
+ int x[24];
+
+#pragma omp target parallel for
+ for (i = 0; i < 16; ++i) {
+ if (i == 5)
+ goto L1; // expected-error {{use of undeclared label 'L1'}}
+ else if (i == 6)
+ return; // expected-error {{cannot return from OpenMP region}}
+ else if (i == 7)
+ goto L2;
+ else if (i == 8) {
+ L2:
+ x[i]++;
+ }
+ }
+
+ if (x[0] == 0)
+ goto L2; // expected-error {{use of undeclared label 'L2'}}
+ else if (x[1] == 1)
+ goto L1;
+}
+
+void test_invalid_clause() {
+ int i;
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+#pragma omp target parallel for foo bar
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+void test_non_identifiers() {
+ int i, x;
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+#pragma omp target parallel for;
+ for (i = 0; i < 16; ++i)
+ ;
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+#pragma omp target parallel for private(x);
+ for (i = 0; i < 16; ++i)
+ ;
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+#pragma omp target parallel for, private(x);
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+extern int foo();
+
+void test_collapse() {
+ int i;
+// expected-error@+1 {{expected '('}}
+#pragma omp target parallel for collapse
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for collapse(
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target parallel for collapse()
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for collapse(,
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for collapse(, )
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-warning@+2 {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+// expected-error@+1 {{expected '('}}
+#pragma omp target parallel for collapse 4)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target parallel for collapse(4
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target parallel for collapse(4,
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target parallel for collapse(4, )
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for', but found only 1}}
+// expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target parallel for collapse(4)
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target parallel for collapse(4 4)
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target parallel for collapse(4, , 4)
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for', but found only 1}}
+#pragma omp target parallel for collapse(4)
+ for (int i1 = 0; i1 < 16; ++i1)
+ for (int i2 = 0; i2 < 16; ++i2)
+ for (int i3 = 0; i3 < 16; ++i3)
+ for (int i4 = 0; i4 < 16; ++i4)
+ foo();
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target parallel for collapse(4, 8)
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for', but found only 1}}
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp target parallel for collapse(2.5)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp target parallel for collapse(foo())
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp target parallel for collapse(-5)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp target parallel for collapse(0)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp target parallel for collapse(5 - 5)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-note@+1 {{defined as firstprivate}}
+#pragma omp target parallel for collapse(2) firstprivate(i)
+ for (i = 0; i < 16; ++i)
+// expected-note@+1 {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp for' directive into a parallel or another task region?}}
+ for (int j = 0; j < 16; ++j)
+// expected-error@+2 2 {{reduction variable must be shared}}
+// expected-error@+1 {{region cannot be closely nested inside 'target parallel for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+#pragma omp for reduction(+ : i, j)
+ for (int k = 0; k < 16; ++k)
+ i += j;
+}
+
+void test_private() {
+ int i;
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for private(
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp target parallel for private(,
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 2 {{expected expression}}
+#pragma omp target parallel for private(, )
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target parallel for private()
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target parallel for private(int)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp target parallel for private(0)
+ for (i = 0; i < 16; ++i)
+ ;
+
+ int x, y, z;
+#pragma omp target parallel for private(x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target parallel for private(x, y)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target parallel for private(x, y, z)
+ for (i = 0; i < 16; ++i) {
+ x = y * i + z;
+ }
+}
+
+void test_lastprivate() {
+ int i;
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp target parallel for lastprivate(
+ for (i = 0; i < 16; ++i)
+ ;
+
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp target parallel for lastprivate(,
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 2 {{expected expression}}
+#pragma omp target parallel for lastprivate(, )
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target parallel for lastprivate()
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target parallel for lastprivate(int)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp target parallel for lastprivate(0)
+ for (i = 0; i < 16; ++i)
+ ;
+
+ int x, y, z;
+#pragma omp target parallel for lastprivate(x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target parallel for lastprivate(x, y)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target parallel for lastprivate(x, y, z)
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+void test_firstprivate() {
+ int i;
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp target parallel for firstprivate(
+ for (i = 0; i < 16; ++i)
+ ;
+
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp target parallel for firstprivate(,
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 2 {{expected expression}}
+#pragma omp target parallel for firstprivate(, )
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target parallel for firstprivate()
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target parallel for firstprivate(int)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp target parallel for firstprivate(0)
+ for (i = 0; i < 16; ++i)
+ ;
+
+ int x, y, z;
+#pragma omp target parallel for lastprivate(x) firstprivate(x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target parallel for lastprivate(x, y) firstprivate(x, y)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target parallel for lastprivate(x, y, z) firstprivate(x, y, z)
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+void test_loop_messages() {
+ float a[100], b[100], c[100];
+// expected-error@+2 {{variable must be of integer or pointer type}}
+#pragma omp target parallel for
+ for (float fi = 0; fi < 10.0; fi++) {
+ c[(int)fi] = a[(int)fi] + b[(int)fi];
+ }
+// expected-error@+2 {{variable must be of integer or pointer type}}
+#pragma omp target parallel for
+ for (double fi = 0; fi < 10.0; fi++) {
+ c[(int)fi] = a[(int)fi] + b[(int)fi];
+ }
+}
+
diff --git a/test/OpenMP/target_parallel_for_nowait_messages.cpp b/test/OpenMP/target_parallel_for_nowait_messages.cpp
new file mode 100644
index 0000000000000..06d22969c4a4c
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_nowait_messages.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+int main(int argc, char **argv) {
+ int i;
+ #pragma omp target parallel for nowait( // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for nowait device (-10u)
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return 0;
+}
diff --git a/test/OpenMP/target_parallel_for_num_threads_messages.cpp b/test/OpenMP/target_parallel_for_num_threads_messages.cpp
new file mode 100644
index 0000000000000..915cfb1dfc9e0
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_num_threads_messages.cpp
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N> // expected-note {{declared here}}
+T tmain(T argc, S **argv) {
+ T i;
+ #pragma omp target parallel for num_threads // expected-error {{expected '(' after 'num_threads'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for num_threads () // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for num_threads ((argc > 0) ? argv[1] : argv[2]) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp target parallel for' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for num_threads (S) // expected-error {{'S' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for num_threads (argc)
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for num_threads (N) // expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return argc;
+}
+
+int main(int argc, char **argv) {
+ int i;
+ #pragma omp target parallel for num_threads // expected-error {{expected '(' after 'num_threads'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for num_threads () // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for num_threads (argc > 0 ? argv[1] : argv[2]) // expected-error {{integral }}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp target parallel for' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for num_threads (S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for num_threads (num_threads(tmain<int, char, -1>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} expected-note {{in instantiation of function template specialization 'tmain<int, char, -1>' requested here}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return tmain<int, char, 3>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char, 3>' requested here}}
+}
diff --git a/test/OpenMP/target_parallel_for_ordered_messages.cpp b/test/OpenMP/target_parallel_for_ordered_messages.cpp
new file mode 100644
index 0000000000000..36eb8371e0252
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_ordered_messages.cpp
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
+#pragma omp target parallel for ordered
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - ST];
+#pragma omp target parallel for ordered( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - ST];
+#pragma omp target parallel for ordered() // expected-error {{expected expression}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - ST];
+// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+// expected-error@+2 2 {{expression is not an integral constant expression}}
+// expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}}
+#pragma omp target parallel for ordered(argc
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - ST];
+// expected-error@+1 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
+#pragma omp target parallel for ordered(ST // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - ST];
+#pragma omp target parallel for ordered(1)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - ST];
+#pragma omp target parallel for ordered((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'ordered' clause}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp target parallel for', but found only 1}}
+// expected-error@+3 2 {{directive '#pragma omp target parallel for' cannot contain more than one 'ordered' clause}}
+// expected-error@+2 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
+// expected-error@+1 2 {{expression is not an integral constant expression}}
+#pragma omp target parallel for ordered(foobool(argc)), ordered(true), ordered(-5)
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - ST];
+#pragma omp target parallel for ordered(S) // expected-error {{'S' does not refer to a value}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - ST];
+// expected-error@+1 2 {{expression is not an integral constant expression}}
+#pragma omp target parallel for ordered(argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - ST];
+#pragma omp target parallel for ordered(1)
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - ST];
+#pragma omp target parallel for ordered(N) // expected-error {{argument to 'ordered' clause must be a strictly positive integer value}}
+ for (T i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - ST];
+#pragma omp target parallel for ordered(2) // expected-note {{as specified in 'ordered' clause}}
+ foo(); // expected-error {{expected 2 for loops after '#pragma omp target parallel for'}}
+ return argc;
+}
+
+int main(int argc, char **argv) {
+#pragma omp target parallel for ordered
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - 4];
+#pragma omp target parallel for ordered( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - 4];
+#pragma omp target parallel for ordered() // expected-error {{expected expression}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - 4];
+#pragma omp target parallel for ordered(4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'ordered' clause}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - 4]; // expected-error {{expected 4 for loops after '#pragma omp target parallel for', but found only 1}}
+#pragma omp target parallel for ordered(2 + 2)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} expected-note {{as specified in 'ordered' clause}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - 4]; // expected-error {{expected 4 for loops after '#pragma omp target parallel for', but found only 1}}
+#pragma omp target parallel for ordered(foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - 4];
+// expected-error@+3 {{expression is not an integral constant expression}}
+// expected-error@+2 2 {{directive '#pragma omp target parallel for' cannot contain more than one 'ordered' clause}}
+// expected-error@+1 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
+#pragma omp target parallel for ordered(foobool(argc)), ordered(true), ordered(-5)
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - 4];
+#pragma omp target parallel for ordered(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - 4];
+// expected-error@+1 {{expression is not an integral constant expression}}
+#pragma omp target parallel for ordered(argv[1] = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - 4];
+// expected-error@+3 {{statement after '#pragma omp target parallel for' must be a for loop}}
+// expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+#pragma omp target parallel for ordered(ordered(tmain < int, char, -1, -2 > (argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+ foo();
+#pragma omp target parallel for ordered(2) // expected-note {{as specified in 'ordered' clause}}
+ foo(); // expected-error {{expected 2 for loops after '#pragma omp target parallel for'}}
+ // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
+ return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/target_parallel_for_private_messages.cpp b/test/OpenMP/target_parallel_for_private_messages.cpp
new file mode 100644
index 0000000000000..1d6381a1d5d3e
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_private_messages.cpp
@@ -0,0 +1,231 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+
+public:
+ S2() : a(0) {}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+
+public:
+ S3() : a(0) {}
+};
+const S3 ca[5];
+class S4 {
+ int a;
+ S4(); // expected-note {{implicitly declared private here}}
+
+public:
+ S4(int v) : a(v) {
+#pragma omp target parallel for private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+};
+class S5 {
+ int a;
+ S5() : a(0) {} // expected-note {{implicitly declared private here}}
+
+public:
+ S5(int v) : a(v) {}
+ S5 &operator=(S5 &s) {
+#pragma omp target parallel for private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S6 {
+public:
+ T a;
+
+ S6() : a(0) {}
+ S6(T v) : a(v) {
+#pragma omp target parallel for private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+ S6 &operator=(S6 &s) {
+#pragma omp target parallel for private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S7 : public T {
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(T v) : a(v) {
+#pragma omp target parallel for private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp target parallel for private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(I argc, C **argv) {
+ I e(4);
+ I g(5);
+ int i;
+ int &j = i;
+#pragma omp target parallel for private // expected-error {{expected '(' after 'private'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for private() // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for private(argc)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for private(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for private(argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for private(e, g)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp parallel
+ {
+ int v = 0;
+ int i;
+#pragma omp target parallel for private(i)
+ for (int k = 0; k < argc; ++k) {
+ i = k;
+ v += i;
+ }
+ }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp target parallel for private(j)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for private(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+ return 0;
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ S4 e(4);
+ S5 g(5);
+ S6<float> s6(0.0) , s6_0(1.0);
+ S7<S6<float> > s7(0.0) , s7_0(1.0);
+ int i;
+ int &j = i;
+#pragma omp target parallel for private // expected-error {{expected '(' after 'private'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for private() // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for private(argc)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for private(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for private(argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for private(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp parallel
+ {
+ int i;
+#pragma omp target parallel for private(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+ }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp target parallel for private(j)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for private(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+ static int m;
+#pragma omp target parallel for private(m)
+ for (int k = 0; k < argc; ++k)
+ m = k + 2;
+
+ s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}}
+ s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}}
+ return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
+}
+
diff --git a/test/OpenMP/target_parallel_for_proc_bind_messages.cpp b/test/OpenMP/target_parallel_for_proc_bind_messages.cpp
new file mode 100644
index 0000000000000..eeb232aeca811
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_proc_bind_messages.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo();
+
+int main(int argc, char **argv) {
+ int i;
+#pragma omp target parallel for proc_bind // expected-error {{expected '(' after 'proc_bind'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for proc_bind( // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for proc_bind() // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for proc_bind(master // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for proc_bind(close), proc_bind(spread) // expected-error {{directive '#pragma omp target parallel for' cannot contain more than one 'proc_bind' clause}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for proc_bind(x) // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+
+#pragma omp target parallel for proc_bind(master)
+ for (i = 0; i < argc; ++i)
+ foo();
+
+#pragma omp parallel proc_bind(close)
+#pragma omp target parallel for proc_bind(spread)
+ for (i = 0; i < argc; ++i)
+ foo();
+ return 0;
+}
diff --git a/test/OpenMP/target_parallel_for_reduction_messages.cpp b/test/OpenMP/target_parallel_for_reduction_messages.cpp
new file mode 100644
index 0000000000000..16697a98733b4
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_reduction_messages.cpp
@@ -0,0 +1,313 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+ S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}}
+
+public:
+ S2() : a(0) {}
+ S2(S2 &s2) : a(s2.a) {}
+ static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
+ static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+S2 b; // expected-note 3 {{'b' defined here}}
+const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
+class S3 {
+ int a;
+
+public:
+ int b;
+ S3() : a(0) {}
+ S3(const S3 &s3) : a(s3.a) {}
+ S3 operator+(const S3 &arg1) { return arg1; }
+};
+int operator+(const S3 &arg1, const S3 &arg2) { return 5; }
+S3 c; // expected-note 3 {{'c' defined here}}
+const S3 ca[5]; // expected-note 2 {{'ca' defined here}}
+extern const int f; // expected-note 4 {{'f' declared here}}
+class S4 {
+ int a;
+ S4(); // expected-note {{implicitly declared private here}}
+ S4(const S4 &s4);
+ S4 &operator+(const S4 &arg) { return (*this); }
+
+public:
+ S4(int v) : a(v) {}
+};
+S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; }
+class S5 {
+ int a;
+ S5() : a(0) {} // expected-note {{implicitly declared private here}}
+ S5(const S5 &s5) : a(s5.a) {}
+ S5 &operator+(const S5 &arg);
+
+public:
+ S5(int v) : a(v) {}
+};
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+#if __cplusplus >= 201103L // C++11 or later
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
+#endif
+ int a;
+
+public:
+ S6() : a(6) {}
+ operator int() { return 6; }
+} o;
+
+S3 h, k;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class T> // expected-note {{declared here}}
+T tmain(T argc) {
+ const T d = T(); // expected-note 4 {{'d' defined here}}
+ const T da[5] = {T()}; // expected-note 2 {{'da' defined here}}
+ T qa[5] = {T()};
+ T i;
+ T &j = i; // expected-note 4 {{'j' defined here}}
+ S3 &p = k; // expected-note 2 {{'p' defined here}}
+ const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}}
+ T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}}
+ T fl;
+#pragma omp target parallel for reduction // expected-error {{expected '(' after 'reduction'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(&& : argc)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel private(k)
+#pragma omp target parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp target parallel for reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel private(fl)
+#pragma omp target parallel for reduction(+ : fl)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel reduction(* : fl)
+#pragma omp target parallel for reduction(+ : fl)
+ for (int i = 0; i < 10; ++i)
+ foo();
+
+ return T();
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5; // expected-note 2 {{'d' defined here}}
+ const int da[5] = {0}; // expected-note {{'da' defined here}}
+ int qa[5] = {0};
+ S4 e(4);
+ S5 g(5);
+ int i;
+ int &j = i; // expected-note 2 {{'j' defined here}}
+ S3 &p = k; // expected-note 2 {{'p' defined here}}
+ const int &r = da[i]; // expected-note {{'r' defined here}}
+ int &q = qa[i]; // expected-note {{'q' defined here}}
+ float fl;
+#pragma omp target parallel for reduction // expected-error {{expected '(' after 'reduction'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(~ : argc) // expected-error {{expected unqualified-id}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(&& : argc)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(+ : o) // expected-error {{no viable overloaded '='}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel private(k)
+#pragma omp target parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp target parallel for reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel private(fl)
+#pragma omp target parallel for reduction(+ : fl)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel reduction(* : fl)
+#pragma omp target parallel for reduction(+ : fl)
+ for (int i = 0; i < 10; ++i)
+ foo();
+ static int m;
+#pragma omp target parallel for reduction(+ : m) // OK
+ for (int i = 0; i < 10; ++i)
+ m++;
+
+ return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}}
+}
diff --git a/test/OpenMP/target_parallel_for_schedule_messages.cpp b/test/OpenMP/target_parallel_for_schedule_messages.cpp
new file mode 100644
index 0000000000000..075e1df7827c5
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_schedule_messages.cpp
@@ -0,0 +1,91 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) {
+ #pragma omp target parallel for schedule // expected-error {{expected '(' after 'schedule'}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for schedule (runtime, 3) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+ #pragma omp target parallel for schedule (guided argc
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-error@+1 2 {{argument to 'schedule' clause must be a strictly positive integer value}}
+ #pragma omp target parallel for schedule (static, ST // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for schedule (dynamic, 1)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for schedule (guided, (ST > 0) ? 1 + ST : 2)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-error@+2 2 {{directive '#pragma omp target parallel for' cannot contain more than one 'schedule' clause}}
+ // expected-error@+1 {{argument to 'schedule' clause must be a strictly positive integer value}}
+ #pragma omp target parallel for schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for schedule (static, S) // expected-error {{'S' does not refer to a value}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-error@+1 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ #pragma omp target parallel for schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for schedule (dynamic, 1)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for schedule (static, N) // expected-error {{argument to 'schedule' clause must be a strictly positive integer value}}
+ for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ return argc;
+}
+
+int main(int argc, char **argv) {
+ #pragma omp target parallel for schedule // expected-error {{expected '(' after 'schedule'}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for schedule (runtime, 3) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for schedule (guided, 4 // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for schedule (static, 2+2)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for schedule (dynamic, foobool(1) > 0 ? 1 : 2)
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+2 2 {{directive '#pragma omp target parallel for' cannot contain more than one 'schedule' clause}}
+ // expected-error@+1 {{argument to 'schedule' clause must be a strictly positive integer value}}
+ #pragma omp target parallel for schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5)
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for schedule (guided, S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ #pragma omp target parallel for schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+3 {{statement after '#pragma omp target parallel for' must be a for loop}}
+ // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+ #pragma omp target parallel for schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+ foo();
+ // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
+ return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/target_parallel_for_simd_aligned_messages.cpp b/test/OpenMP/target_parallel_for_simd_aligned_messages.cpp
new file mode 100644
index 0000000000000..669cafeae1ea3
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_aligned_messages.cpp
@@ -0,0 +1,203 @@
+// RUN: %clang_cc1 -x c++ -std=c++11 -verify -fopenmp %s
+
+struct B {
+ static int ib[20]; // expected-note 0 {{'B::ib' declared here}}
+ static constexpr int bfoo() { return 8; }
+};
+namespace X {
+ B x; // expected-note {{'x' defined here}}
+};
+constexpr int bfoo() { return 4; }
+
+int **z;
+const int C1 = 1;
+const int C2 = 2;
+void test_aligned_colons(int *&rp)
+{
+ int *B = 0;
+ #pragma omp target parallel for simd aligned(B:bfoo())
+ for (int i = 0; i < 10; ++i) ;
+ // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'}}
+ #pragma omp target parallel for simd aligned(B::ib:B:bfoo())
+ for (int i = 0; i < 10; ++i) ;
+ #pragma omp target parallel for simd aligned(B:B::bfoo())
+ for (int i = 0; i < 10; ++i) ;
+ // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
+ #pragma omp target parallel for simd aligned(z:B:bfoo())
+ for (int i = 0; i < 10; ++i) ;
+ #pragma omp target parallel for simd aligned(B:B::bfoo())
+ for (int i = 0; i < 10; ++i) ;
+ // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'int **'}}
+ // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'B'}}
+ #pragma omp target parallel for simd aligned(X::x : ::z)
+ for (int i = 0; i < 10; ++i) ;
+ // expected-error@+1 {{integral constant expression must have integral or unscoped enumeration type, not 'B'}}
+ #pragma omp target parallel for simd aligned(B,rp,::z: X::x)
+ for (int i = 0; i < 10; ++i) ;
+ #pragma omp target parallel for simd aligned(::z)
+ for (int i = 0; i < 10; ++i) ;
+ // expected-error@+1 {{expected variable name}}
+ #pragma omp target parallel for simd aligned(B::bfoo())
+ for (int i = 0; i < 10; ++i) ;
+ // expected-warning@+1 {{aligned clause will be ignored because the requested alignment is not a power of 2}}
+ #pragma omp target parallel for simd aligned(B::ib,B:C1+C2)
+ for (int i = 0; i < 10; ++i) ;
+}
+
+// expected-note@+1 {{'num' defined here}}
+template<int L, class T, class N> T test_template(T* arr, N num) {
+ N i;
+ T sum = (T)0;
+ T ind2 = - num * L;
+ // Negative number is passed as L.
+ // expected-error@+1 {{argument to 'aligned' clause must be a strictly positive integer value}}
+ #pragma omp target parallel for simd aligned(arr:L)
+ for (i = 0; i < num; ++i) {
+ T cur = arr[(int)ind2];
+ ind2 += L;
+ sum += cur;
+ }
+ // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+ #pragma omp target parallel for simd aligned(num:4)
+ for (i = 0; i < num; ++i);
+ return T();
+}
+
+template<int LEN> int test_warn() {
+ int *ind2 = 0;
+ // expected-error@+1 {{argument to 'aligned' clause must be a strictly positive integer value}}
+ #pragma omp target parallel for simd aligned(ind2:LEN)
+ for (int i = 0; i < 100; i++) {
+ ind2 += LEN;
+ }
+ return 0;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+extern S1 a; // expected-note {{'a' declared here}}
+class S2 {
+ mutable int a;
+public:
+ S2():a(0) { }
+};
+const S2 b; // expected-note 1 {{'b' defined here}}
+const S2 ba[5];
+class S3 {
+ int a;
+public:
+ S3():a(0) { }
+};
+const S3 ca[5];
+class S4 {
+ int a;
+ S4();
+public:
+ S4(int v):a(v) { }
+};
+class S5 {
+ int a;
+ S5():a(0) {}
+public:
+ S5(int v):a(v) { }
+};
+
+S3 h; // expected-note 2 {{'h' defined here}}
+#pragma omp threadprivate(h)
+
+template<class I, class C> int foomain(I argc, C **argv) {
+ I e(argc);
+ I g(argc);
+ int i; // expected-note {{declared here}} expected-note {{'i' defined here}}
+ // expected-note@+2 {{declared here}}
+ // expected-note@+1 {{reference to 'i' is not a constant expression}}
+ int &j = i;
+ #pragma omp target parallel for simd aligned // expected-error {{expected '(' after 'aligned'}}
+ for (I k = 0; k < argc; ++k) ++k;
+ #pragma omp target parallel for simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (I k = 0; k < argc; ++k) ++k;
+ #pragma omp target parallel for simd aligned () // expected-error {{expected expression}}
+ for (I k = 0; k < argc; ++k) ++k;
+ #pragma omp target parallel for simd aligned (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (I k = 0; k < argc; ++k) ++k;
+ #pragma omp target parallel for simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (I k = 0; k < argc; ++k) ++k;
+ #pragma omp target parallel for simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (I k = 0; k < argc; ++k) ++k;
+ #pragma omp target parallel for simd aligned (argc : 5) // expected-warning {{aligned clause will be ignored because the requested alignment is not a power of 2}}
+ for (I k = 0; k < argc; ++k) ++k;
+ #pragma omp target parallel for simd aligned (S1) // expected-error {{'S1' does not refer to a value}}
+ for (I k = 0; k < argc; ++k) ++k;
+ #pragma omp target parallel for simd aligned (argv[1]) // expected-error {{expected variable name}}
+ for (I k = 0; k < argc; ++k) ++k;
+ #pragma omp target parallel for simd aligned(e, g)
+ for (I k = 0; k < argc; ++k) ++k;
+ // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}}
+ #pragma omp target parallel for simd aligned(h)
+ for (I k = 0; k < argc; ++k) ++k;
+ // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+ #pragma omp target parallel for simd aligned(i)
+ for (I k = 0; k < argc; ++k) ++k;
+ #pragma omp parallel
+ {
+ int *v = 0;
+ I i;
+ #pragma omp target parallel for simd aligned(v:16)
+ for (I k = 0; k < argc; ++k) { i = k; v += 2; }
+ }
+ float *f;
+ #pragma omp target parallel for simd aligned(f)
+ for (I k = 0; k < argc; ++k) ++k;
+ int v = 0;
+ // expected-note@+2 {{initializer of 'j' is not a constant expression}}
+ // expected-error@+1 {{expression is not an integral constant expression}}
+ #pragma omp target parallel for simd aligned(f:j)
+ for (I k = 0; k < argc; ++k) { ++k; v += j; }
+ #pragma omp target parallel for simd aligned(f)
+ for (I k = 0; k < argc; ++k) ++k;
+ return 0;
+}
+
+// expected-note@+1 2 {{'argc' defined here}}
+int main(int argc, char **argv) {
+ double darr[100];
+ // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}}
+ test_template<-4>(darr, 4);
+ test_warn<4>(); // ok
+ // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}}
+ test_warn<0>();
+
+ int i;
+ int &j = i;
+ #pragma omp target parallel for simd aligned // expected-error {{expected '(' after 'aligned'}}
+ for (int k = 0; k < argc; ++k) ++k;
+ #pragma omp target parallel for simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k) ++k;
+ #pragma omp target parallel for simd aligned () // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k) ++k;
+ #pragma omp target parallel for simd aligned (argv // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k) ++k;
+ // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+ #pragma omp target parallel for simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k) ++k;
+ #pragma omp target parallel for simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k) ++k;
+ // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+ #pragma omp target parallel for simd aligned (argc)
+ for (int k = 0; k < argc; ++k) ++k;
+ #pragma omp target parallel for simd aligned (S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k) ++k;
+ // expected-error@+2 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S1'}}
+ // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S2'}}
+ #pragma omp target parallel for simd aligned (a, b)
+ for (int k = 0; k < argc; ++k) ++k;
+ #pragma omp target parallel for simd aligned (argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k) ++k;
+ // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}}
+ #pragma omp target parallel for simd aligned(h)
+ for (int k = 0; k < argc; ++k) ++k;
+ int *pargc = &argc;
+ // expected-note@+1 {{in instantiation of function template specialization 'foomain<int *, char>' requested here}}
+ foomain<int*,char>(pargc,argv);
+ return 0;
+}
+
diff --git a/test/OpenMP/target_parallel_for_simd_ast_print.cpp b/test/OpenMP/target_parallel_for_simd_ast_print.cpp
new file mode 100644
index 0000000000000..e25f93fbaefe9
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_ast_print.cpp
@@ -0,0 +1,308 @@
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+struct S {
+ S(): a(0) {}
+ S(int v) : a(v) {}
+ int a;
+ typedef int type;
+};
+
+template <typename T>
+class S7 : public T {
+protected:
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(typename T::type v) : a(v) {
+#pragma omp target parallel for simd private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp target parallel for simd private(a) private(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp target parallel for simd private(this->a) private(this->a) private(this->S::a)
+// CHECK: #pragma omp target parallel for simd private(this->a) private(this->a) private(T::a)
+// CHECK: #pragma omp target parallel for simd private(this->a) private(this->a)
+
+class S8 : public S7<S> {
+ S8() {}
+
+public:
+ S8(int v) : S7<S>(v){
+#pragma omp target parallel for simd private(a) private(this->a) private(S7<S>::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S8 &operator=(S8 &s) {
+#pragma omp target parallel for simd private(a) private(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp target parallel for simd private(this->a) private(this->a) private(this->S7<S>::a)
+// CHECK: #pragma omp target parallel for simd private(this->a) private(this->a)
+
+template <class T, int N>
+T tmain(T argc, T *argv) {
+ T b = argc, c, d, e, f, h;
+ T arr[N][10], arr1[N];
+ T i, j;
+ T s;
+ static T a;
+// CHECK: static T a;
+ static T g;
+ const T clen = 5;
+// CHECK: T clen = 5;
+#pragma omp threadprivate(g)
+#pragma omp target parallel for simd schedule(dynamic) default(none) linear(a)
+ // CHECK: #pragma omp target parallel for simd schedule(dynamic) default(none) linear(a)
+ for (T i = 0; i < 2; ++i)
+ a = 2;
+// CHECK-NEXT: for (T i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp target parallel for simd private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered(N) if (parallel :argc) num_threads(N) default(shared) shared(e) reduction(+ : h)
+ for (int i = 0; i < 2; ++i)
+ for (int j = 0; j < 2; ++j)
+ for (int j = 0; j < 2; ++j)
+ for (int j = 0; j < 2; ++j)
+ for (int j = 0; j < 2; ++j)
+ foo();
+ // CHECK-NEXT: #pragma omp target parallel for simd private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered(N) if(parallel: argc) num_threads(N) default(shared) shared(e) reduction(+: h)
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: for (int j = 0; j < 2; ++j)
+ // CHECK-NEXT: foo();
+
+#pragma omp target parallel for simd default(none), private(argc,b) firstprivate(argv) shared (d) if(parallel:argc > 0) num_threads(N) proc_bind(master) reduction(+:c, arr1[argc]) reduction(max:e, arr[:N][0:10])
+ for (T i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(N) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:N][0:10])
+ // CHECK-NEXT: for (T i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd if(N) num_threads(s) proc_bind(close) reduction(^:e, f, arr[0:N][:argc]) reduction(&& : h)
+ for (T i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd if(N) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:N][:argc]) reduction(&&: h)
+ // CHECK-NEXT: for (T i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd if(target:argc > 0)
+ for (T i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd if(target: argc > 0)
+ // CHECK-NEXT: for (T i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd if(parallel:argc > 0)
+ for (T i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd if(parallel: argc > 0)
+ // CHECK-NEXT: for (T i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd if(N)
+ for (T i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd if(N)
+ // CHECK-NEXT: for (T i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd map(i)
+ for (T i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd map(tofrom: i)
+ // CHECK-NEXT: for (T i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd map(arr1[0:10], i)
+ for (T i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd map(tofrom: arr1[0:10],i)
+ // CHECK-NEXT: for (T i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd map(to: i) map(from: j)
+ for (T i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd map(to: i) map(from: j)
+ // CHECK-NEXT: for (T i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd map(always,alloc: i)
+ for (T i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd map(always,alloc: i)
+ // CHECK-NEXT: for (T i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd nowait
+ for (T i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd nowait
+ // CHECK-NEXT: for (T i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd depend(in : argc, arr[i:argc], arr1[:])
+ for (T i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd depend(in : argc,arr[i:argc],arr1[:])
+ // CHECK-NEXT: for (T i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd defaultmap(tofrom: scalar)
+ for (T i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd defaultmap(tofrom: scalar)
+ // CHECK-NEXT: for (T i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd safelen(clen-1)
+ for (T i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd safelen(clen - 1)
+ // CHECK-NEXT: for (T i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd simdlen(clen-1)
+ for (T i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd simdlen(clen - 1)
+ // CHECK-NEXT: for (T i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd aligned(arr1:N-1)
+ for (T i = 0; i < N; ++i) {}
+ // CHECK: #pragma omp target parallel for simd aligned(arr1: N - 1)
+ // CHECK-NEXT: for (T i = 0; i < N; ++i) {
+ // CHECK-NEXT: }
+
+ return T();
+}
+
+int main(int argc, char **argv) {
+ int b = argc, c, d, e, f, h;
+ int arr[5][10], arr1[5];
+ int i, j;
+ int s;
+ static int a;
+// CHECK: static int a;
+ const int clen = 5;
+// CHECK: int clen = 5;
+ static float g;
+#pragma omp threadprivate(g)
+#pragma omp target parallel for simd schedule(guided, argc) default(none) linear(a)
+ // CHECK: #pragma omp target parallel for simd schedule(guided, argc) default(none) linear(a)
+ for (int i = 0; i < 2; ++i)
+ a = 2;
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+
+#pragma omp target parallel for simd private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) ordered if (target: argc) num_threads(a) default(shared) shared(e) reduction(+ : h) linear(a:-5)
+ for (int i = 0; i < 10; ++i)
+ for (int j = 0; j < 10; ++j)
+ foo();
+ // CHECK: #pragma omp target parallel for simd private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) ordered if(target: argc) num_threads(a) default(shared) shared(e) reduction(+: h) linear(a: -5)
+ // CHECK-NEXT: for (int i = 0; i < 10; ++i)
+ // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+ // CHECK-NEXT: foo();
+
+#pragma omp target parallel for simd default(none), private(argc,b) firstprivate(argv) shared (d) if (parallel:argc > 0) num_threads(5) proc_bind(master) reduction(+:c, arr1[argc]) reduction(max:e, arr[:5][0:10])
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(5) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:5][0:10])
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd if (5) num_threads(s) proc_bind(close) reduction(^:e, f, arr[0:5][:argc]) reduction(&& : h)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd if(5) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:5][:argc]) reduction(&&: h)
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd if (target:argc > 0)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd if(target: argc > 0)
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd if (parallel:argc > 0)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd if(parallel: argc > 0)
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd if (5)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd if(5)
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd map(i)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd map(tofrom: i)
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd map(arr1[0:10], i)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd map(tofrom: arr1[0:10],i)
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd map(to: i) map(from: j)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd map(to: i) map(from: j)
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd map(always,alloc: i)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd map(always,alloc: i)
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd nowait
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd nowait
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd depend(in : argc, arr[i:argc], arr1[:])
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd depend(in : argc,arr[i:argc],arr1[:])
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd defaultmap(tofrom: scalar)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd defaultmap(tofrom: scalar)
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd safelen(clen-1)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd safelen(clen - 1)
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd simdlen(clen-1)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd simdlen(clen - 1)
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+#pragma omp target parallel for simd aligned(arr1:4)
+ for (int i = 0; i < 2; ++i) {}
+ // CHECK: #pragma omp target parallel for simd aligned(arr1: 4)
+ // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
+ // CHECK-NEXT: }
+
+ return (tmain<int, 5>(argc, &argc));
+}
+
+#endif
diff --git a/test/OpenMP/target_parallel_for_simd_collapse_messages.cpp b/test/OpenMP/target_parallel_for_simd_collapse_messages.cpp
new file mode 100644
index 0000000000000..ecf2d6e7889e9
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_collapse_messages.cpp
@@ -0,0 +1,101 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+#if __cplusplus >= 201103L
+ // expected-note@+2 4 {{declared here}}
+#endif
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
+ int j; // expected-note {{declared here}}
+ #pragma omp target parallel for simd collapse // expected-error {{expected '(' after 'collapse'}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd collapse () // expected-error {{expected expression}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+ // expected-error@+2 2 {{expression is not an integral constant expression}}
+ // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}}
+ #pragma omp target parallel for simd collapse (argc
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ #pragma omp target parallel for simd collapse (ST // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp target parallel for simd', but found only 1}}
+#if __cplusplus >= 201103L
+ // expected-note@+5 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+ // expected-error@+3 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'collapse' clause}}
+ // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+1 2 {{expression is not an integral constant expression}}
+ #pragma omp target parallel for simd collapse (foobool(argc)), collapse (true), collapse (-5)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd collapse (S) // expected-error {{'S' does not refer to a value}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-note@+2 {{read of non-const variable 'j' is not allowed in a constant expression}}
+ // expected-error@+1 {{expression is not an integral constant expression}}
+ #pragma omp target parallel for simd collapse (j=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd collapse (1)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd collapse (N) // expected-error {{argument to 'collapse' clause must be a strictly positive integer value}}
+ for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd collapse (2) // expected-note {{as specified in 'collapse' clause}}
+ foo(); // expected-error {{expected 2 for loops after '#pragma omp target parallel for simd'}}
+ return argc;
+}
+
+int main(int argc, char **argv) {
+ int j; // expected-note {{declared here}}
+ #pragma omp target parallel for simd collapse // expected-error {{expected '(' after 'collapse'}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for simd collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for simd collapse () // expected-error {{expected expression}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for simd collapse (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'collapse' clause}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp target parallel for simd', but found only 1}}
+ #pragma omp target parallel for simd collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} expected-note {{as specified in 'collapse' clause}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp target parallel for simd', but found only 1}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+ #pragma omp target parallel for simd collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+#if __cplusplus >= 201103L
+ // expected-note@+5 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+ // expected-error@+3 {{expression is not an integral constant expression}}
+ // expected-error@+2 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'collapse' clause}}
+ // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ #pragma omp target parallel for simd collapse (foobool(argc)), collapse (true), collapse (-5)
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for simd collapse (S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-note@+2 {{read of non-const variable 'j' is not allowed in a constant expression}}
+ // expected-error@+1 {{expression is not an integral constant expression}}
+ #pragma omp target parallel for simd collapse (j=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+3 {{statement after '#pragma omp target parallel for simd' must be a for loop}}
+ // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+ #pragma omp target parallel for simd collapse(collapse(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+ foo();
+ #pragma omp target parallel for simd collapse (2) // expected-note {{as specified in 'collapse' clause}}
+ foo(); // expected-error {{expected 2 for loops after '#pragma omp target parallel for simd'}}
+ // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
+ return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/target_parallel_for_simd_default_messages.cpp b/test/OpenMP/target_parallel_for_simd_default_messages.cpp
new file mode 100644
index 0000000000000..5d41cbcb457e1
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_default_messages.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo();
+
+int main(int argc, char **argv) {
+ int i;
+#pragma omp target parallel for simd default // expected-error {{expected '(' after 'default'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd default(none // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+ foo();
+#pragma omp target parallel for simd default(shared), default(shared) // expected-error {{directive '#pragma omp target parallel for simd' cannot contain more than one 'default' clause}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+
+#pragma omp target parallel for simd default(none)
+ for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+ foo();
+
+#pragma omp parallel default(none)
+#pragma omp target parallel for simd default(shared)
+ for (i = 0; i < argc; ++i)
+ foo();
+
+ return 0;
+}
diff --git a/test/OpenMP/target_parallel_for_simd_defaultmap_messages.cpp b/test/OpenMP/target_parallel_for_simd_defaultmap_messages.cpp
new file mode 100644
index 0000000000000..e922e0a000b45
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_defaultmap_messages.cpp
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+template <class T, typename S, int N, int ST>
+T tmain(T argc, S **argv) {
+ int i;
+ #pragma omp target parallel for simd defaultmap // expected-error {{expected '(' after 'defaultmap'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return argc;
+}
+
+int main(int argc, char **argv) {
+ int i;
+ #pragma omp target parallel for simd defaultmap // expected-error {{expected '(' after 'defaultmap'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd defaultmap ( // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd defaultmap () // expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd defaultmap (tofrom // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd defaultmap (tofrom: // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd defaultmap (tofrom) // expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd defaultmap (tofrom scalar) // expected-warning {{missing ':' after defaultmap modifier - ignoring}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd defaultmap (tofrom, // expected-error {{expected ')'}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd defaultmap (scalar: // expected-error {{expected ')'}} expected-error {{expected 'tofrom' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd defaultmap (tofrom, scalar // expected-error {{expected ')'}} expected-warning {{missing ':' after defaultmap modifier - ignoring}} expected-error {{expected 'scalar' in OpenMP clause 'defaultmap'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/target_parallel_for_simd_depend_messages.cpp b/test/OpenMP/target_parallel_for_simd_depend_messages.cpp
new file mode 100644
index 0000000000000..0504cabd0f017
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_depend_messages.cpp
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+class vector {
+ public:
+ int operator[](int index) { return 0; }
+};
+
+int main(int argc, char **argv, char *env[]) {
+ vector vec;
+ typedef float V __attribute__((vector_size(16)));
+ V a;
+ auto arr = x; // expected-error {{use of undeclared identifier 'x'}}
+ int i;
+
+ #pragma omp target parallel for simd depend // expected-error {{expected '(' after 'depend'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend (out: ) // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend (out :S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend (in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend (in : argv[0])
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend (in : ) // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend (in : main) // expected-error {{expected variable name, array element or array section}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend (in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend (in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend (in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend (in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend(in : argv[ : argc][1 : argc - 1])
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd depend(in : arr[0])
+ for (i = 0; i < argc; ++i) foo();
+
+ return 0;
+}
diff --git a/test/OpenMP/target_parallel_for_simd_device_messages.cpp b/test/OpenMP/target_parallel_for_simd_device_messages.cpp
new file mode 100644
index 0000000000000..2c9d43f07b257
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_device_messages.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+int main(int argc, char **argv) {
+ int i;
+ #pragma omp target parallel for simd device // expected-error {{expected '(' after 'device'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd device () // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd device (argc + argc)
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd device (argc), device (argc+1) // expected-error {{directive '#pragma omp target parallel for simd' cannot contain more than one 'device' clause}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd device (S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd device (-10u)
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return 0;
+}
diff --git a/test/OpenMP/target_parallel_for_simd_firstprivate_messages.cpp b/test/OpenMP/target_parallel_for_simd_firstprivate_messages.cpp
new file mode 100644
index 0000000000000..9397314d87cc6
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_firstprivate_messages.cpp
@@ -0,0 +1,261 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+
+public:
+ S2() : a(0) {}
+ S2(const S2 &s2) : a(s2.a) {}
+ static float S2s;
+ static const float S2sc;
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+ S3 &operator=(const S3 &s3);
+
+public:
+ S3() : a(0) {}
+ S3(const S3 &s3) : a(s3.a) {}
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 {
+ int a;
+ S4();
+ S4(const S4 &s4); // expected-note 2 {{implicitly declared private here}}
+
+public:
+ S4(int v) : a(v) {}
+};
+class S5 {
+ int a;
+ S5(const S5 &s5) : a(s5.a) {} // expected-note 4 {{implicitly declared private here}}
+
+public:
+ S5() : a(0) {}
+ S5(int v) : a(v) {}
+};
+class S6 {
+ int a;
+ S6() : a(0) {}
+
+public:
+ S6(const S6 &s6) : a(s6.a) {}
+ S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+ I e(4);
+ C g(5);
+ int i;
+ int &j = i;
+#pragma omp target parallel for simd firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd firstprivate() // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd firstprivate(argc)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd firstprivate(argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp parallel
+ {
+ int v = 0;
+ int i;
+#pragma omp target parallel for simd firstprivate(i)
+ for (int k = 0; k < argc; ++k) {
+ i = k;
+ v += i;
+ }
+ }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp target parallel for simd firstprivate(j)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd firstprivate(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp parallel private(i)
+#pragma omp target parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be firstprivate, predetermined as private}}
+ foo();
+#pragma omp parallel reduction(+ : i)
+#pragma omp target parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be firstprivate, predetermined as private}}
+ foo();
+ return 0;
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5;
+ const int da[5] = {0};
+ S4 e(4);
+ S5 g(5);
+ S3 m;
+ S6 n(2);
+ int i;
+ int &j = i;
+#pragma omp target parallel for simd firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd firstprivate() // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd firstprivate(argc)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd firstprivate(argv[1]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd firstprivate(2 * 2) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd firstprivate(ba) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd firstprivate(ca) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd firstprivate(da) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+ int xa;
+#pragma omp target parallel for simd firstprivate(xa) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd firstprivate(S2::S2s) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd firstprivate(S2::S2sc) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd safelen(5) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd firstprivate(m) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd firstprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be firstprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be firstprivate, predetermined as private}}
+ foo();
+#pragma omp parallel shared(xa)
+#pragma omp target parallel for simd firstprivate(xa) // OK: may be firstprivate
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd firstprivate(j)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd lastprivate(g) firstprivate(g) // expected-error {{calling a private constructor of class 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd lastprivate(n) firstprivate(n) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp parallel
+ {
+ int v = 0;
+ int i;
+#pragma omp target parallel for simd firstprivate(i)
+ for (int k = 0; k < argc; ++k) {
+ i = k;
+ v += i;
+ }
+ }
+#pragma omp parallel private(i)
+#pragma omp target parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be firstprivate, predetermined as private}}
+ foo();
+#pragma omp parallel reduction(+ : i)
+#pragma omp target parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}}
+ for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be firstprivate, predetermined as private}}
+ foo();
+ static int si;
+#pragma omp target parallel for simd firstprivate(si) // OK
+ for (i = 0; i < argc; ++i)
+ si = i + 1;
+
+ return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/target_parallel_for_simd_if_messages.cpp b/test/OpenMP/target_parallel_for_simd_if_messages.cpp
new file mode 100644
index 0000000000000..b9e2891575b24
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_if_messages.cpp
@@ -0,0 +1,105 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, class S> // expected-note {{declared here}}
+int tmain(T argc, S **argv) {
+ int i;
+ #pragma omp target parallel for simd if // expected-error {{expected '(' after 'if'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if () // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if (argc > 0 ? argv[1] : argv[2])
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target parallel for simd' cannot contain more than one 'if' clause}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if (S) // expected-error {{'S' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if(argc)
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if(target : argc)
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if(parallel : argc)
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if(target : argc) if(parallel : argc)
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target parallel for simd'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if(target : argc) if (target :argc) // expected-error {{directive '#pragma omp target parallel for simd' cannot contain more than one 'if' clause with 'target' name modifier}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if(parallel : argc) if (parallel :argc) // expected-error {{directive '#pragma omp target parallel for simd' cannot contain more than one 'if' clause with 'parallel' name modifier}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if(target : argc) if (argc) // expected-error {{expected 'parallel' directive name modifier}} expected-note {{previous clause with directive name modifier specified here}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if(target : argc) if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} expected-note {{previous clause with directive name modifier specified here}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ int i;
+ #pragma omp target parallel for simd if // expected-error {{expected '(' after 'if'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if () // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if (argc > 0 ? argv[1] : argv[2])
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target parallel for simd' cannot contain more than one 'if' clause}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if (S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if(parallel : argc)
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if(target : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target parallel for simd'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if(target : argc) if (target :argc) // expected-error {{directive '#pragma omp target parallel for simd' cannot contain more than one 'if' clause with 'target' name modifier}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if(parallel : argc) if (parallel :argc) // expected-error {{directive '#pragma omp target parallel for simd' cannot contain more than one 'if' clause with 'parallel' name modifier}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if(target : argc) if (argc) // expected-error {{expected 'parallel' directive name modifier}} expected-note {{previous clause with directive name modifier specified here}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd if(target : argc) if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} expected-note {{previous clause with directive name modifier specified here}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return tmain(argc, argv);
+}
diff --git a/test/OpenMP/target_parallel_for_simd_lastprivate_messages.cpp b/test/OpenMP/target_parallel_for_simd_lastprivate_messages.cpp
new file mode 100644
index 0000000000000..51fc72464c9ab
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_lastprivate_messages.cpp
@@ -0,0 +1,238 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+
+public:
+ S2() : a(0) {}
+ S2(S2 &s2) : a(s2.a) {}
+ S2 &operator=(const S2 &);
+ const S2 &operator=(const S2 &) const;
+ static float S2s; // expected-note {{static data member is predetermined as shared}}
+ static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+ S3 &operator=(const S3 &s3); // expected-note 2 {{implicitly declared private here}}
+
+public:
+ S3() : a(0) {}
+ S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c; // expected-note {{global variable is predetermined as shared}}
+const S3 ca[5]; // expected-note {{global variable is predetermined as shared}}
+extern const int f; // expected-note {{global variable is predetermined as shared}}
+class S4 {
+ int a;
+ S4(); // expected-note 3 {{implicitly declared private here}}
+ S4(const S4 &s4);
+
+public:
+ S4(int v) : a(v) {}
+};
+class S5 {
+ int a;
+ S5() : a(0) {} // expected-note {{implicitly declared private here}}
+
+public:
+ S5(const S5 &s5) : a(s5.a) {}
+ S5(int v) : a(v) {}
+};
+class S6 {
+ int a;
+ S6() : a(0) {}
+
+public:
+ S6(const S6 &s6) : a(s6.a) {}
+ S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+ I e(4);
+ I g(5);
+ int i;
+ int &j = i;
+#pragma omp target parallel for simd lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd lastprivate() // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd lastprivate(argc)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd lastprivate(argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp parallel
+ {
+ int v = 0;
+ int i;
+#pragma omp target parallel for simd lastprivate(i)
+ for (int k = 0; k < argc; ++k) {
+ i = k;
+ v += i;
+ }
+ }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp target parallel for simd lastprivate(j)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd lastprivate(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+ return 0;
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5; // expected-note {{constant variable is predetermined as shared}}
+ const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+ S4 e(4);
+ S5 g(5);
+ S3 m;
+ S6 n(2);
+ int i;
+ int &j = i;
+#pragma omp target parallel for simd lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd lastprivate() // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd lastprivate(argc)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd lastprivate(argv[1]) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd lastprivate(2 * 2) // expected-error {{expected variable name}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd lastprivate(ba)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+ int xa;
+#pragma omp target parallel for simd lastprivate(xa) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd safelen(5) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd lastprivate(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be lastprivate}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd lastprivate(i)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp parallel private(xa)
+#pragma omp target parallel for simd lastprivate(xa)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp parallel reduction(+ : xa)
+#pragma omp target parallel for simd lastprivate(xa)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd lastprivate(j)
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd firstprivate(m) lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd lastprivate(n) firstprivate(n) // OK
+ for (i = 0; i < argc; ++i)
+ foo();
+ static int si;
+#pragma omp target parallel for simd lastprivate(si) // OK
+ for (i = 0; i < argc; ++i)
+ si = i + 2;
+
+ return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/target_parallel_for_simd_linear_messages.cpp b/test/OpenMP/target_parallel_for_simd_linear_messages.cpp
new file mode 100644
index 0000000000000..e17f15550e653
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_linear_messages.cpp
@@ -0,0 +1,269 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+namespace X {
+int x;
+};
+
+struct B {
+ static int ib; // expected-note {{'B::ib' declared here}}
+ static int bfoo() { return 8; }
+};
+
+int bfoo() { return 4; }
+
+int z;
+const int C1 = 1;
+const int C2 = 2;
+void test_linear_colons() {
+ int B = 0;
+#pragma omp target parallel for simd linear(B : bfoo())
+ for (int i = 0; i < 10; ++i)
+ ;
+// expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'}}
+#pragma omp target parallel for simd linear(B::ib : B : bfoo())
+ for (int i = 0; i < 10; ++i)
+ ;
+// expected-error@+1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+#pragma omp target parallel for simd linear(B : ib)
+ for (int i = 0; i < 10; ++i)
+ ;
+// expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
+#pragma omp target parallel for simd linear(z : B : ib)
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target parallel for simd linear(B : B::bfoo())
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target parallel for simd linear(X::x : ::z)
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target parallel for simd linear(B, ::z, X::x)
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target parallel for simd linear(::z)
+ for (int i = 0; i < 10; ++i)
+ ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp target parallel for simd linear(B::bfoo())
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp target parallel for simd linear(B::ib, B : C1 + C2)
+ for (int i = 0; i < 10; ++i)
+ ;
+}
+
+template <int L, class T, class N>
+T test_template(T *arr, N num) {
+ N i;
+ T sum = (T)0;
+ T ind2 = -num * L; // expected-note {{'ind2' defined here}}
+// expected-error@+1 {{argument of a linear clause should be of integral or pointer type}}
+#pragma omp target parallel for simd linear(ind2 : L)
+ for (i = 0; i < num; ++i) {
+ T cur = arr[(int)ind2];
+ ind2 += L;
+ sum += cur;
+ }
+ return T();
+}
+
+template <int LEN>
+int test_warn() {
+ int ind2 = 0;
+// expected-warning@+1 {{zero linear step (ind2 should probably be const)}}
+#pragma omp target parallel for simd linear(ind2 : LEN)
+ for (int i = 0; i < 100; i++) {
+ ind2 += LEN;
+ }
+ return ind2;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+
+public:
+ S2() : a(0) {}
+};
+const S2 b; // expected-note 2 {{'b' defined here}}
+const S2 ba[5];
+class S3 {
+ int a;
+
+public:
+ S3() : a(0) {}
+};
+const S3 ca[5];
+class S4 {
+ int a;
+ S4();
+
+public:
+ S4(int v) : a(v) {}
+};
+class S5 {
+ int a;
+ S5() : a(0) {}
+
+public:
+ S5(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(I argc, C **argv) {
+ I e(4);
+ I g(5);
+ int i;
+ int &j = i;
+#pragma omp target parallel for simd linear // expected-error {{expected '(' after 'linear'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd linear( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd linear() // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd linear(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd linear(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd linear(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd linear(argc : 5)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd linear(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+// expected-error@+2 {{linear variable with incomplete type 'S1'}}
+// expected-error@+1 {{const-qualified variable cannot be linear}}
+#pragma omp target parallel for simd linear(a, b : B::ib)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd linear(argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd linear(e, g)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd linear(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp parallel
+ {
+ int v = 0;
+ int i;
+#pragma omp target parallel for simd linear(v : i)
+ for (int k = 0; k < argc; ++k) {
+ i = k;
+ v += i;
+ }
+ }
+#pragma omp target parallel for simd linear(j)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+ int v = 0;
+#pragma omp target parallel for simd linear(v : j)
+ for (int k = 0; k < argc; ++k) {
+ ++k;
+ v += j;
+ }
+#pragma omp target parallel for simd linear(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+ return 0;
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace C {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ double darr[100];
+ // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}}
+ test_template<-4>(darr, 4);
+ // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}}
+ test_warn<0>();
+
+ S4 e(4); // expected-note {{'e' defined here}}
+ S5 g(5); // expected-note {{'g' defined here}}
+ int i;
+ int &j = i;
+#pragma omp target parallel for simd linear // expected-error {{expected '(' after 'linear'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd linear( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd linear() // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd linear(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd linear(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd linear(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd linear(argc)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd linear(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+// expected-error@+2 {{linear variable with incomplete type 'S1'}}
+// expected-error@+1 {{const-qualified variable cannot be linear}}
+#pragma omp target parallel for simd linear(a, b)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd linear(argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+// expected-error@+2 {{argument of a linear clause should be of integral or pointer type, not 'S4'}}
+// expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S5'}}
+#pragma omp target parallel for simd linear(e, g)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp parallel
+ {
+ int i;
+#pragma omp target parallel for simd linear(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd linear(i : 4)
+ for (int k = 0; k < argc; ++k) {
+ ++k;
+ i += 4;
+ }
+ }
+#pragma omp target parallel for simd linear(j)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd linear(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+
+ foomain<int, char>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
+ return 0;
+}
+
diff --git a/test/OpenMP/target_parallel_for_simd_loop_messages.cpp b/test/OpenMP/target_parallel_for_simd_loop_messages.cpp
new file mode 100644
index 0000000000000..c0dceeded4540
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_loop_messages.cpp
@@ -0,0 +1,627 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s
+
+class S {
+ int a;
+ S() : a(0) {}
+
+public:
+ S(int v) : a(v) {}
+ S(const S &s) : a(s.a) {}
+};
+
+static int sii;
+// expected-note@+1 {{defined as threadprivate or thread local}}
+#pragma omp threadprivate(sii)
+static int globalii;
+
+int test_iteration_spaces() {
+ const int N = 100;
+ float a[N], b[N], c[N];
+ int ii, jj, kk;
+ float fii;
+ double dii;
+#pragma omp target parallel for simd
+ for (int i = 0; i < 10; i += 1) {
+ c[i] = a[i] + b[i];
+ }
+#pragma omp target parallel for simd
+ for (char i = 0; i < 10; i++) {
+ c[i] = a[i] + b[i];
+ }
+#pragma omp target parallel for simd
+ for (char i = 0; i < 10; i += '\1') {
+ c[i] = a[i] + b[i];
+ }
+#pragma omp target parallel for simd
+ for (long long i = 0; i < 10; i++) {
+ c[i] = a[i] + b[i];
+ }
+// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}}
+#pragma omp target parallel for simd
+ for (long long i = 0; i < 10; i += 1.5) {
+ c[i] = a[i] + b[i];
+ }
+#pragma omp target parallel for simd
+ for (long long i = 0; i < 'z'; i += 1u) {
+ c[i] = a[i] + b[i];
+ }
+// expected-error@+2 {{variable must be of integer or random access iterator type}}
+#pragma omp target parallel for simd
+ for (float fi = 0; fi < 10.0; fi++) {
+ c[(int)fi] = a[(int)fi] + b[(int)fi];
+ }
+// expected-error@+2 {{variable must be of integer or random access iterator type}}
+#pragma omp target parallel for simd
+ for (double fi = 0; fi < 10.0; fi++) {
+ c[(int)fi] = a[(int)fi] + b[(int)fi];
+ }
+// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for simd
+ for (int &ref = ii; ref < 10; ref++) {
+ }
+// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for simd
+ for (int i; i < 10; i++)
+ c[i] = a[i];
+
+// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for simd
+ for (int i = 0, j = 0; i < 10; ++i)
+ c[i] = a[i];
+
+// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for simd
+ for (; ii < 10; ++ii)
+ c[ii] = a[ii];
+
+// expected-warning@+3 {{expression result unused}}
+// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for simd
+ for (ii + 1; ii < 10; ++ii)
+ c[ii] = a[ii];
+
+// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for simd
+ for (c[ii] = 0; ii < 10; ++ii)
+ c[ii] = a[ii];
+
+// Ok to skip parenthesises.
+#pragma omp target parallel for simd
+ for (((ii)) = 0; ii < 10; ++ii)
+ c[ii] = a[ii];
+
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp target parallel for simd
+ for (int i = 0; i; i++)
+ c[i] = a[i];
+
+// expected-error@+3 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}}
+#pragma omp target parallel for simd
+ for (int i = 0; jj < kk; ii++)
+ c[i] = a[i];
+
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp target parallel for simd
+ for (int i = 0; !!i; i++)
+ c[i] = a[i];
+
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp target parallel for simd
+ for (int i = 0; i != 1; i++)
+ c[i] = a[i];
+
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp target parallel for simd
+ for (int i = 0;; i++)
+ c[i] = a[i];
+
+// Ok.
+#pragma omp target parallel for simd
+ for (int i = 11; i > 10; i--)
+ c[i] = a[i];
+
+// Ok.
+#pragma omp target parallel for simd
+ for (int i = 0; i < 10; ++i)
+ c[i] = a[i];
+
+// Ok.
+#pragma omp target parallel for simd
+ for (ii = 0; ii < 10; ++ii)
+ c[ii] = a[ii];
+
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp target parallel for simd
+ for (ii = 0; ii < 10; ++jj)
+ c[ii] = a[jj];
+
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp target parallel for simd
+ for (ii = 0; ii < 10; ++++ii)
+ c[ii] = a[ii];
+
+// Ok but undefined behavior (in general, cannot check that incr
+// is really loop-invariant).
+#pragma omp target parallel for simd
+ for (ii = 0; ii < 10; ii = ii + ii)
+ c[ii] = a[ii];
+
+// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'float'}}
+#pragma omp target parallel for simd
+ for (ii = 0; ii < 10; ii = ii + 1.0f)
+ c[ii] = a[ii];
+
+// Ok - step was converted to integer type.
+#pragma omp target parallel for simd
+ for (ii = 0; ii < 10; ii = ii + (int)1.1f)
+ c[ii] = a[ii];
+
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp target parallel for simd
+ for (ii = 0; ii < 10; jj = ii + 2)
+ c[ii] = a[ii];
+
+// expected-warning@+3 {{relational comparison result unused}}
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp target parallel for simd
+ for (ii = 0; ii<10; jj> kk + 2)
+ c[ii] = a[ii];
+
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp target parallel for simd
+ for (ii = 0; ii < 10;)
+ c[ii] = a[ii];
+
+// expected-warning@+3 {{expression result unused}}
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp target parallel for simd
+ for (ii = 0; ii < 10; !ii)
+ c[ii] = a[ii];
+
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp target parallel for simd
+ for (ii = 0; ii < 10; ii ? ++ii : ++jj)
+ c[ii] = a[ii];
+
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp target parallel for simd
+ for (ii = 0; ii < 10; ii = ii < 10)
+ c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp target parallel for simd
+ for (ii = 0; ii < 10; ii = ii + 0)
+ c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp target parallel for simd
+ for (ii = 0; ii < 10; ii = ii + (int)(0.8 - 0.45))
+ c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp target parallel for simd
+ for (ii = 0; (ii) < 10; ii -= 25)
+ c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp target parallel for simd
+ for (ii = 0; (ii < 10); ii -= 0)
+ c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+#pragma omp target parallel for simd
+ for (ii = 0; ii > 10; (ii += 0))
+ c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp target parallel for simd
+ for (ii = 0; ii < 10; (ii) = (1 - 1) + (ii))
+ c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+#pragma omp target parallel for simd
+ for ((ii = 0); ii > 10; (ii -= 0))
+ c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp target parallel for simd
+ for (ii = 0; (ii < 10); (ii -= 0))
+ c[ii] = a[ii];
+
+// expected-note@+2 {{defined as firstprivate}}
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be firstprivate, predetermined as private}}
+#pragma omp target parallel for simd firstprivate(ii)
+ for (ii = 0; ii < 10; ii++)
+ c[ii] = a[ii];
+
+// expected-note@+2 {{defined as linear}}
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be linear, predetermined as private}}
+#pragma omp target parallel for simd linear(ii)
+ for (ii = 0; ii < 10; ii++)
+ c[ii] = a[ii];
+
+#pragma omp target parallel for simd private(ii)
+ for (ii = 0; ii < 10; ii++)
+ c[ii] = a[ii];
+
+#pragma omp target parallel for simd lastprivate(ii)
+ for (ii = 0; ii < 10; ii++)
+ c[ii] = a[ii];
+
+ {
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp target parallel for simd' directive may not be threadprivate or thread local, predetermined as private}}
+#pragma omp target parallel for simd
+ for (sii = 0; sii < 10; sii += 1)
+ c[sii] = a[sii];
+ }
+
+ {
+#pragma omp target parallel for simd
+ for (globalii = 0; globalii < 10; globalii += 1)
+ c[globalii] = a[globalii];
+ }
+
+ {
+#pragma omp target parallel for simd collapse(2)
+ for (ii = 0; ii < 10; ii += 1)
+ for (globalii = 0; globalii < 10; globalii += 1)
+ c[globalii] += a[globalii] + ii;
+ }
+
+// expected-error@+2 {{statement after '#pragma omp target parallel for simd' must be a for loop}}
+#pragma omp target parallel for simd
+ for (auto &item : a) {
+ item = item + 1;
+ }
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'i' to increase on each iteration of OpenMP for loop}}
+#pragma omp target parallel for simd
+ for (unsigned i = 9; i < 10; i--) {
+ c[i] = a[i] + b[i];
+ }
+
+ int(*lb)[4] = nullptr;
+#pragma omp target parallel for simd
+ for (int(*p)[4] = lb; p < lb + 8; ++p) {
+ }
+
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for simd
+ for (int a{0}; a < 10; ++a) {
+ }
+
+ return 0;
+}
+
+// Iterators allowed in openmp for-loops.
+namespace std {
+struct random_access_iterator_tag {};
+template <class Iter>
+struct iterator_traits {
+ typedef typename Iter::difference_type difference_type;
+ typedef typename Iter::iterator_category iterator_category;
+};
+template <class Iter>
+typename iterator_traits<Iter>::difference_type
+distance(Iter first, Iter last) { return first - last; }
+}
+class Iter0 {
+public:
+ Iter0() {}
+ Iter0(const Iter0 &) {}
+ Iter0 operator++() { return *this; }
+ Iter0 operator--() { return *this; }
+ bool operator<(Iter0 a) { return true; }
+};
+// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'Iter0' for 1st argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'Iter0' for 1st argument}}
+int operator-(Iter0 a, Iter0 b) { return 0; }
+class Iter1 {
+public:
+ Iter1(float f = 0.0f, double d = 0.0) {}
+ Iter1(const Iter1 &) {}
+ Iter1 operator++() { return *this; }
+ Iter1 operator--() { return *this; }
+ bool operator<(Iter1 a) { return true; }
+ bool operator>=(Iter1 a) { return false; }
+};
+class GoodIter {
+public:
+ GoodIter() {}
+ GoodIter(const GoodIter &) {}
+ GoodIter(int fst, int snd) {}
+ GoodIter &operator=(const GoodIter &that) { return *this; }
+ GoodIter &operator=(const Iter0 &that) { return *this; }
+ GoodIter &operator+=(int x) { return *this; }
+ GoodIter &operator-=(int x) { return *this; }
+ explicit GoodIter(void *) {}
+ GoodIter operator++() { return *this; }
+ GoodIter operator--() { return *this; }
+ bool operator!() { return true; }
+ bool operator<(GoodIter a) { return true; }
+ bool operator<=(GoodIter a) { return true; }
+ bool operator>=(GoodIter a) { return false; }
+ typedef int difference_type;
+ typedef std::random_access_iterator_tag iterator_category;
+};
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
+int operator-(GoodIter a, GoodIter b) { return 0; }
+// expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}}
+GoodIter operator-(GoodIter a) { return a; }
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
+GoodIter operator-(GoodIter a, int v) { return GoodIter(); }
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}}
+GoodIter operator+(GoodIter a, int v) { return GoodIter(); }
+// expected-note@+2 {{candidate function not viable: no known conversion from 'GoodIter' to 'int' for 1st argument}}
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'int' for 1st argument}}
+GoodIter operator-(int v, GoodIter a) { return GoodIter(); }
+// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 1st argument}}
+GoodIter operator+(int v, GoodIter a) { return GoodIter(); }
+
+int test_with_random_access_iterator() {
+ GoodIter begin, end;
+ Iter0 begin0, end0;
+#pragma omp target parallel for simd
+ for (GoodIter I = begin; I < end; ++I)
+ ++I;
+// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for simd
+ for (GoodIter &I = begin; I < end; ++I)
+ ++I;
+#pragma omp target parallel for simd
+ for (GoodIter I = begin; I >= end; --I)
+ ++I;
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for simd
+ for (GoodIter I(begin); I < end; ++I)
+ ++I;
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for simd
+ for (GoodIter I(nullptr); I < end; ++I)
+ ++I;
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for simd
+ for (GoodIter I(0); I < end; ++I)
+ ++I;
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for simd
+ for (GoodIter I(1, 2); I < end; ++I)
+ ++I;
+#pragma omp target parallel for simd
+ for (begin = GoodIter(0); begin < end; ++begin)
+ ++begin;
+// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}}
+// expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
+#pragma omp target parallel for simd
+ for (begin = begin0; begin < end; ++begin)
+ ++begin;
+// expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for simd
+ for (++begin; begin < end; ++begin)
+ ++begin;
+#pragma omp target parallel for simd
+ for (begin = end; begin < end; ++begin)
+ ++begin;
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+#pragma omp target parallel for simd
+ for (GoodIter I = begin; I - I; ++I)
+ ++I;
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+#pragma omp target parallel for simd
+ for (GoodIter I = begin; begin < end; ++I)
+ ++I;
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+#pragma omp target parallel for simd
+ for (GoodIter I = begin; !I; ++I)
+ ++I;
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp target parallel for simd
+ for (GoodIter I = begin; I >= end; I = I + 1)
+ ++I;
+#pragma omp target parallel for simd
+ for (GoodIter I = begin; I >= end; I = I - 1)
+ ++I;
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+#pragma omp target parallel for simd
+ for (GoodIter I = begin; I >= end; I = -I)
+ ++I;
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp target parallel for simd
+ for (GoodIter I = begin; I >= end; I = 2 + I)
+ ++I;
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+#pragma omp target parallel for simd
+ for (GoodIter I = begin; I >= end; I = 2 - I)
+ ++I;
+// expected-error@+2 {{invalid operands to binary expression ('Iter0' and 'int')}}
+#pragma omp target parallel for simd
+ for (Iter0 I = begin0; I < end0; ++I)
+ ++I;
+// Initializer is constructor without params.
+// expected-error@+3 {{invalid operands to binary expression ('Iter0' and 'int')}}
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for simd
+ for (Iter0 I; I < end0; ++I)
+ ++I;
+ Iter1 begin1, end1;
+// expected-error@+3 {{invalid operands to binary expression ('Iter1' and 'Iter1')}}
+// expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
+#pragma omp target parallel for simd
+ for (Iter1 I = begin1; I < end1; ++I)
+ ++I;
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp target parallel for simd
+ for (Iter1 I = begin1; I >= end1; ++I)
+ ++I;
+// expected-error@+5 {{invalid operands to binary expression ('Iter1' and 'float')}}
+// expected-error@+4 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
+// Initializer is constructor with all default params.
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp target parallel for simd
+ for (Iter1 I; I < end1; ++I) {
+ }
+ return 0;
+}
+
+template <typename IT, int ST>
+class TC {
+public:
+ int dotest_lt(IT begin, IT end) {
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+#pragma omp target parallel for simd
+ for (IT I = begin; I < end; I = I + ST) {
+ ++I;
+ }
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+#pragma omp target parallel for simd
+ for (IT I = begin; I <= end; I += ST) {
+ ++I;
+ }
+#pragma omp target parallel for simd
+ for (IT I = begin; I < end; ++I) {
+ ++I;
+ }
+ }
+
+ static IT step() {
+ return IT(ST);
+ }
+};
+template <typename IT, int ST = 0>
+int dotest_gt(IT begin, IT end) {
+// expected-note@+3 2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp target parallel for simd
+ for (IT I = begin; I >= end; I = I + ST) {
+ ++I;
+ }
+// expected-note@+3 2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp target parallel for simd
+ for (IT I = begin; I >= end; I += ST) {
+ ++I;
+ }
+
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp target parallel for simd
+ for (IT I = begin; I >= end; ++I) {
+ ++I;
+ }
+
+#pragma omp target parallel for simd
+ for (IT I = begin; I < end; I += TC<int, ST>::step()) {
+ ++I;
+ }
+}
+
+void test_with_template() {
+ GoodIter begin, end;
+ TC<GoodIter, 100> t1;
+ TC<GoodIter, -100> t2;
+ t1.dotest_lt(begin, end);
+ t2.dotest_lt(begin, end); // expected-note {{in instantiation of member function 'TC<GoodIter, -100>::dotest_lt' requested here}}
+ dotest_gt(begin, end); // expected-note {{in instantiation of function template specialization 'dotest_gt<GoodIter, 0>' requested here}}
+ dotest_gt<unsigned, -10>(0, 100); // expected-note {{in instantiation of function template specialization 'dotest_gt<unsigned int, -10>' requested here}}
+}
+
+void test_loop_break() {
+ const int N = 100;
+ float a[N], b[N], c[N];
+#pragma omp target parallel for simd
+ for (int i = 0; i < 10; i++) {
+ c[i] = a[i] + b[i];
+ for (int j = 0; j < 10; ++j) {
+ if (a[i] > b[j])
+ break; // OK in nested loop
+ }
+ switch (i) {
+ case 1:
+ b[i]++;
+ break;
+ default:
+ break;
+ }
+ if (c[i] > 10)
+ break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+
+ if (c[i] > 11)
+ break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+ }
+
+#pragma omp target parallel for simd
+ for (int i = 0; i < 10; i++) {
+ for (int j = 0; j < 10; j++) {
+ c[i] = a[i] + b[i];
+ if (c[i] > 10) {
+ if (c[i] < 20) {
+ break; // OK
+ }
+ }
+ }
+ }
+}
+
+void test_loop_eh() {
+ const int N = 100;
+ float a[N], b[N], c[N];
+#pragma omp target parallel for simd
+ for (int i = 0; i < 10; i++) {
+ c[i] = a[i] + b[i];
+ try {
+ for (int j = 0; j < 10; ++j) {
+ if (a[i] > b[j])
+ throw a[i];
+ }
+ throw a[i];
+ } catch (float f) {
+ if (f > 0.1)
+ throw a[i];
+ return; // expected-error {{cannot return from OpenMP region}}
+ }
+ switch (i) {
+ case 1:
+ b[i]++;
+ break;
+ default:
+ break;
+ }
+ for (int j = 0; j < 10; j++) {
+ if (c[i] > 10)
+ throw c[i];
+ }
+ }
+ if (c[9] > 10)
+ throw c[9]; // OK
+
+#pragma omp target parallel for simd
+ for (int i = 0; i < 10; ++i) {
+ struct S {
+ void g() { throw 0; }
+ };
+ }
+}
+
+void test_loop_firstprivate_lastprivate() {
+ S s(4);
+#pragma omp target parallel for simd lastprivate(s) firstprivate(s)
+ for (int i = 0; i < 16; ++i)
+ ;
+}
diff --git a/test/OpenMP/target_parallel_for_simd_map_messages.cpp b/test/OpenMP/target_parallel_for_simd_map_messages.cpp
new file mode 100644
index 0000000000000..f44639e86cab2
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_map_messages.cpp
@@ -0,0 +1,273 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+extern S1 a;
+class S2 {
+ mutable int a;
+public:
+ S2():a(0) { }
+ S2(S2 &s2):a(s2.a) { }
+ static float S2s; // expected-note 4 {{mappable type cannot contain static members}}
+ static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}}
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+public:
+ S3():a(0) { }
+ S3(S3 &s3):a(s3.a) { }
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 {
+ int a;
+ S4();
+ S4(const S4 &s4);
+public:
+ S4(int v):a(v) { }
+};
+class S5 {
+ int a;
+ S5():a(0) {}
+ S5(const S5 &s5):a(s5.a) { }
+public:
+ S5(int v):a(v) { }
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+typedef int from;
+
+template <typename T, int I> // expected-note {{declared here}}
+T tmain(T argc) {
+ const T d = 5;
+ const T da[5] = { 0 };
+ S4 e(4);
+ S5 g(5);
+ T i, t[20];
+ T &j = i;
+ T *k = &j;
+ T x;
+ T y;
+ T to, tofrom, always;
+ const T (&l)[5] = da;
+
+
+#pragma omp target parallel for simd map // expected-error {{expected '(' after 'map'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map() // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(to:) // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(x)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(tofrom: t[:I])
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(T: a) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} expected-error {{incomplete type 'S1' where a complete type is required}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(T) // expected-error {{'T' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(S2::S2s)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(S2::S2sc)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(x)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(to: x)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(to: to)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(to)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(to, x)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(to x) // expected-error {{expected ',' or ')' in 'map' clause}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(argc)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(ca)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(da)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(S2::S2s)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(S2::S2sc)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(e, g)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(k), map(k) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(k), map(k[:5]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} expected-note 2 {{used here}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(da)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(da[:4])
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target data map(k, j, l) // expected-note 2 {{used here}}
+#pragma omp target parallel for simd map(k[:4]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(j)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(l) map(l[:5]) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target data map(k[:4], j, l[:5]) // expected-note 4 {{used here}}
+{
+#pragma omp target parallel for simd map(k) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(j)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(l) // expected-error 2 {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}}
+ for (i = 0; i < argc; ++i) foo();
+}
+
+#pragma omp target parallel for simd map(always, tofrom: x)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(always: x) // expected-error {{missing map type}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(always, tofrom: always, tofrom, x)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5;
+ const int da[5] = { 0 };
+ S4 e(4);
+ S5 g(5);
+ int i;
+ int &j = i;
+ int *k = &j;
+ int x;
+ int y;
+ int to, tofrom, always;
+ const int (&l)[5] = da;
+
+#pragma omp target parallel for simd map // expected-error {{expected '(' after 'map'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map() // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(to:) // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(x)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(to: x)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(to: to)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(to)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(to, x)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(to x) // expected-error {{expected ',' or ')' in 'map' clause}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(argc)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(argv[1])
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(ca)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(da)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(S2::S2s)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(S2::S2sc)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(e, g)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(k), map(k) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(k), map(k[:5]) // expected-error {{pointer cannot be mapped along with a section derived from itself}} expected-note {{used here}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(da)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(da[:4])
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target data map(k, j, l) // expected-note {{used here}}
+#pragma omp target parallel for simd map(k[:4]) // expected-error {{pointer cannot be mapped along with a section derived from itself}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(j)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(l) map(l[:5]) // expected-error 1 {{variable already marked as mapped in current construct}} expected-note 1 {{used here}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}}
+{
+#pragma omp target parallel for simd map(k) // expected-error {{pointer cannot be mapped along with a section derived from itself}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(j)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(l) // expected-error {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}}
+ for (i = 0; i < argc; ++i) foo();
+}
+
+#pragma omp target parallel for simd map(always, tofrom: x)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(always: x) // expected-error {{missing map type}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(always, tofrom: always, tofrom, x)
+ for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return tmain<int, 3>(argc)+tmain<from, 4>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<int, 4>' requested here}}
+}
+
diff --git a/test/OpenMP/target_parallel_for_simd_messages.cpp b/test/OpenMP/target_parallel_for_simd_messages.cpp
new file mode 100644
index 0000000000000..0e1a0fea7e619
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_messages.cpp
@@ -0,0 +1,92 @@
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+static int pvt;
+#pragma omp threadprivate(pvt)
+
+#pragma omp target parallel for simd // expected-error {{unexpected OpenMP directive '#pragma omp target parallel for simd'}}
+
+int main(int argc, char **argv) {
+#pragma omp target parallel for simd { // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (int i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd ( // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (int i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd[ // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (int i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd] // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (int i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (int i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd } // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (int i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd
+ for (int i = 0; i < argc; ++i)
+ foo();
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+#pragma omp target parallel for simd unknown()
+ for (int i = 0; i < argc; ++i)
+ foo();
+L1:
+ for (int i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd
+ for (int i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd
+ for (int i = 0; i < argc; ++i) {
+ goto L1; // expected-error {{use of undeclared label 'L1'}}
+ argc++;
+ }
+
+ for (int i = 0; i < 10; ++i) {
+ switch (argc) {
+ case (0):
+#pragma omp target parallel for simd
+ for (int i = 0; i < argc; ++i) {
+ foo();
+ break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+ continue;
+ }
+ default:
+ break;
+ }
+ }
+#pragma omp target parallel for simd default(none)
+ for (int i = 0; i < 10; ++i)
+ ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+
+ goto L2; // expected-error {{use of undeclared label 'L2'}}
+#pragma omp target parallel for simd
+ for (int i = 0; i < argc; ++i)
+ L2:
+ foo();
+#pragma omp target parallel for simd
+ for (int i = 0; i < argc; ++i) {
+ return 1; // expected-error {{cannot return from OpenMP region}}
+ }
+
+ [[]] // expected-error {{an attribute list cannot appear here}}
+#pragma omp target parallel for simd
+ for (int n = 0; n < 100; ++n) {
+ }
+
+#pragma omp target parallel for simd copyin(pvt) // expected-error {{unexpected OpenMP clause 'copyin' in directive '#pragma omp target parallel for simd'}}
+ for (int n = 0; n < 100; ++n) {}
+
+ return 0;
+}
+
+void test_ordered() {
+#pragma omp target parallel for simd ordered ordered // expected-error {{directive '#pragma omp target parallel for simd' cannot contain more than one 'ordered' clause}}
+ for (int i = 0; i < 16; ++i)
+ ;
+}
+
diff --git a/test/OpenMP/target_parallel_for_simd_misc_messages.c b/test/OpenMP/target_parallel_for_simd_misc_messages.c
new file mode 100644
index 0000000000000..2adc6f85116e6
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_misc_messages.c
@@ -0,0 +1,495 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp -verify %s
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp target parallel for simd'}}
+#pragma omp target parallel for simd
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp target parallel for simd'}}
+#pragma omp target parallel for simd foo
+
+void test_no_clause() {
+ int i;
+#pragma omp target parallel for simd
+ for (i = 0; i < 16; ++i)
+ ;
+
+// expected-error@+2 {{statement after '#pragma omp target parallel for simd' must be a for loop}}
+#pragma omp target parallel for simd
+ ++i;
+}
+
+void test_branch_protected_scope() {
+ int i = 0;
+L1:
+ ++i;
+
+ int x[24];
+
+#pragma omp target parallel for simd
+ for (i = 0; i < 16; ++i) {
+ if (i == 5)
+ goto L1; // expected-error {{use of undeclared label 'L1'}}
+ else if (i == 6)
+ return; // expected-error {{cannot return from OpenMP region}}
+ else if (i == 7)
+ goto L2;
+ else if (i == 8) {
+ L2:
+ x[i]++;
+ }
+ }
+
+ if (x[0] == 0)
+ goto L2; // expected-error {{use of undeclared label 'L2'}}
+ else if (x[1] == 1)
+ goto L1;
+}
+
+void test_invalid_clause() {
+ int i;
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+#pragma omp target parallel for simd foo bar
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+void test_non_identifiers() {
+ int i, x;
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+#pragma omp target parallel for simd;
+ for (i = 0; i < 16; ++i)
+ ;
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+#pragma omp target parallel for simd private(x);
+ for (i = 0; i < 16; ++i)
+ ;
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+#pragma omp target parallel for simd, private(x);
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+extern int foo();
+
+void test_collapse() {
+ int i;
+// expected-error@+1 {{expected '('}}
+#pragma omp target parallel for simd collapse
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for simd collapse(
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target parallel for simd collapse()
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for simd collapse(,
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for simd collapse(, )
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-warning@+2 {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+// expected-error@+1 {{expected '('}}
+#pragma omp target parallel for simd collapse 4)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target parallel for simd collapse(4
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for simd', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target parallel for simd collapse(4,
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for simd', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target parallel for simd collapse(4, )
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for simd', but found only 1}}
+// expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target parallel for simd collapse(4)
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for simd', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target parallel for simd collapse(4 4)
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for simd', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target parallel for simd collapse(4, , 4)
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for simd', but found only 1}}
+#pragma omp target parallel for simd collapse(4)
+ for (int i1 = 0; i1 < 16; ++i1)
+ for (int i2 = 0; i2 < 16; ++i2)
+ for (int i3 = 0; i3 < 16; ++i3)
+ for (int i4 = 0; i4 < 16; ++i4)
+ foo();
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp target parallel for simd collapse(4, 8)
+ for (i = 0; i < 16; ++i)
+ ; // expected-error {{expected 4 for loops after '#pragma omp target parallel for simd', but found only 1}}
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp target parallel for simd collapse(2.5)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp target parallel for simd collapse(foo())
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp target parallel for simd collapse(-5)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp target parallel for simd collapse(0)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
+#pragma omp target parallel for simd collapse(5 - 5)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-note@+1 {{defined as firstprivate}}
+#pragma omp target parallel for simd collapse(2) firstprivate(i)
+ for (i = 0; i < 16; ++i)
+// expected-note@+1 {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp for' directive into a parallel or another task region?}}
+ for (int j = 0; j < 16; ++j)
+// expected-error@+2 2 {{reduction variable must be shared}}
+// expected-error@+1 {{region cannot be closely nested inside 'target parallel for simd' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+#pragma omp for reduction(+ : i, j)
+ for (int k = 0; k < 16; ++k)
+ i += j;
+}
+
+void test_private() {
+ int i;
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for simd private(
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp target parallel for simd private(,
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 2 {{expected expression}}
+#pragma omp target parallel for simd private(, )
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target parallel for simd private()
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target parallel for simd private(int)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp target parallel for simd private(0)
+ for (i = 0; i < 16; ++i)
+ ;
+
+ int x, y, z;
+#pragma omp target parallel for simd private(x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target parallel for simd private(x, y)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target parallel for simd private(x, y, z)
+ for (i = 0; i < 16; ++i) {
+ x = y * i + z;
+ }
+}
+
+void test_lastprivate() {
+ int i;
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp target parallel for simd lastprivate(
+ for (i = 0; i < 16; ++i)
+ ;
+
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp target parallel for simd lastprivate(,
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 2 {{expected expression}}
+#pragma omp target parallel for simd lastprivate(, )
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target parallel for simd lastprivate()
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target parallel for simd lastprivate(int)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp target parallel for simd lastprivate(0)
+ for (i = 0; i < 16; ++i)
+ ;
+
+ int x, y, z;
+#pragma omp target parallel for simd lastprivate(x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target parallel for simd lastprivate(x, y)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target parallel for simd lastprivate(x, y, z)
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+void test_firstprivate() {
+ int i;
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp target parallel for simd firstprivate(
+ for (i = 0; i < 16; ++i)
+ ;
+
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp target parallel for simd firstprivate(,
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 2 {{expected expression}}
+#pragma omp target parallel for simd firstprivate(, )
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target parallel for simd firstprivate()
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target parallel for simd firstprivate(int)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp target parallel for simd firstprivate(0)
+ for (i = 0; i < 16; ++i)
+ ;
+
+ int x, y, z;
+#pragma omp target parallel for simd lastprivate(x) firstprivate(x)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target parallel for simd lastprivate(x, y) firstprivate(x, y)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target parallel for simd lastprivate(x, y, z) firstprivate(x, y, z)
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+void test_loop_messages() {
+ float a[100], b[100], c[100];
+// expected-error@+2 {{variable must be of integer or pointer type}}
+#pragma omp target parallel for simd
+ for (float fi = 0; fi < 10.0; fi++) {
+ c[(int)fi] = a[(int)fi] + b[(int)fi];
+ }
+// expected-error@+2 {{variable must be of integer or pointer type}}
+#pragma omp target parallel for simd
+ for (double fi = 0; fi < 10.0; fi++) {
+ c[(int)fi] = a[(int)fi] + b[(int)fi];
+ }
+}
+
+void test_safelen() {
+ int i;
+// expected-error@+1 {{expected '('}}
+#pragma omp target parallel for simd safelen
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for simd safelen(
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target parallel for simd safelen()
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for simd safelen(,
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for simd safelen(, )
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-warning@+2 {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+// expected-error@+1 {{expected '('}}
+#pragma omp target parallel for simd safelen 4)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for simd safelen(4
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for simd safelen(4,
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for simd safelen(4, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target parallel for simd safelen(4)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for simd safelen(4 4)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for simd safelen(4, , 4)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target parallel for simd safelen(4)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for simd safelen(4, 8)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp target parallel for simd safelen(2.5)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp target parallel for simd safelen(foo())
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}}
+#pragma omp target parallel for simd safelen(-5)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}}
+#pragma omp target parallel for simd safelen(0)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}}
+#pragma omp target parallel for simd safelen(5 - 5)
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+void test_simdlen() {
+ int i;
+// expected-error@+1 {{expected '('}}
+#pragma omp target parallel for simd simdlen
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for simd simdlen(
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}}
+#pragma omp target parallel for simd simdlen()
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for simd simdlen(,
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for simd simdlen(, )
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-warning@+2 {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+// expected-error@+1 {{expected '('}}
+#pragma omp target parallel for simd simdlen 4)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for simd simdlen(4
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for simd simdlen(4,
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for simd simdlen(4, )
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target parallel for simd simdlen(4)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for simd simdlen(4 4)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for simd simdlen(4, , 4)
+ for (i = 0; i < 16; ++i)
+ ;
+#pragma omp target parallel for simd simdlen(4)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp target parallel for simd simdlen(4, 8)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp target parallel for simd simdlen(2.5)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp target parallel for simd simdlen(foo())
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+#pragma omp target parallel for simd simdlen(-5)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+#pragma omp target parallel for simd simdlen(0)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+#pragma omp target parallel for simd simdlen(5 - 5)
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+void test_safelen_simdlen() {
+ int i;
+// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}}
+#pragma omp target parallel for simd simdlen(6) safelen(5)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}}
+#pragma omp target parallel for simd safelen(5) simdlen(6)
+ for (i = 0; i < 16; ++i)
+ ;
+}
diff --git a/test/OpenMP/target_parallel_for_simd_nowait_messages.cpp b/test/OpenMP/target_parallel_for_simd_nowait_messages.cpp
new file mode 100644
index 0000000000000..3c4b512048177
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_nowait_messages.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+int main(int argc, char **argv) {
+ int i;
+ #pragma omp target parallel for simd nowait( // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd nowait device (-10u)
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return 0;
+}
diff --git a/test/OpenMP/target_parallel_for_simd_num_threads_messages.cpp b/test/OpenMP/target_parallel_for_simd_num_threads_messages.cpp
new file mode 100644
index 0000000000000..1076b86ea5e67
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_num_threads_messages.cpp
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N> // expected-note {{declared here}}
+T tmain(T argc, S **argv) {
+ T i;
+ #pragma omp target parallel for simd num_threads // expected-error {{expected '(' after 'num_threads'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd num_threads () // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd num_threads ((argc > 0) ? argv[1] : argv[2]) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd num_threads (S) // expected-error {{'S' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd num_threads (argc)
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd num_threads (N) // expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return argc;
+}
+
+int main(int argc, char **argv) {
+ int i;
+ #pragma omp target parallel for simd num_threads // expected-error {{expected '(' after 'num_threads'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd num_threads () // expected-error {{expected expression}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd num_threads (argc > 0 ? argv[1] : argv[2]) // expected-error {{integral }}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd num_threads (S1) // expected-error {{'S1' does not refer to a value}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ for (i = 0; i < argc; ++i) foo();
+ #pragma omp target parallel for simd num_threads (num_threads(tmain<int, char, -1>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} expected-note {{in instantiation of function template specialization 'tmain<int, char, -1>' requested here}}
+ for (i = 0; i < argc; ++i) foo();
+
+ return tmain<int, char, 3>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char, 3>' requested here}}
+}
diff --git a/test/OpenMP/target_parallel_for_simd_ordered_messages.cpp b/test/OpenMP/target_parallel_for_simd_ordered_messages.cpp
new file mode 100644
index 0000000000000..70a3b4ef62454
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_ordered_messages.cpp
@@ -0,0 +1,122 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+#if __cplusplus >= 201103L
+ // expected-note@+2 4 {{declared here}}
+#endif
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
+ int j; // expected-note {{declared here}}
+#pragma omp target parallel for simd ordered
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - ST];
+#pragma omp target parallel for simd ordered( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - ST];
+#pragma omp target parallel for simd ordered() // expected-error {{expected expression}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - ST];
+// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+// expected-error@+2 2 {{expression is not an integral constant expression}}
+// expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}}
+#pragma omp target parallel for simd ordered(argc
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - ST];
+// expected-error@+1 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
+#pragma omp target parallel for simd ordered(ST // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - ST];
+#pragma omp target parallel for simd ordered(1)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - ST];
+#pragma omp target parallel for simd ordered((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'ordered' clause}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp target parallel for simd', but found only 1}}
+#if __cplusplus >= 201103L
+ // expected-note@+5 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+// expected-error@+3 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'ordered' clause}}
+// expected-error@+2 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
+// expected-error@+1 2 {{expression is not an integral constant expression}}
+#pragma omp target parallel for simd ordered(foobool(argc)), ordered(true), ordered(-5)
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - ST];
+#pragma omp target parallel for simd ordered(S) // expected-error {{'S' does not refer to a value}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - ST];
+// expected-note@+2 {{read of non-const variable 'j' is not allowed in a constant expression}}
+// expected-error@+1 {{expression is not an integral constant expression}}
+#pragma omp target parallel for simd ordered(j = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - ST];
+#pragma omp target parallel for simd ordered(1)
+ for (int i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - ST];
+#pragma omp target parallel for simd ordered(N) // expected-error {{argument to 'ordered' clause must be a strictly positive integer value}}
+ for (T i = ST; i < N; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - ST];
+#pragma omp target parallel for simd ordered(2) // expected-note {{as specified in 'ordered' clause}}
+ foo(); // expected-error {{expected 2 for loops after '#pragma omp target parallel for simd'}}
+ return argc;
+}
+
+int main(int argc, char **argv) {
+ int j; // expected-note {{declared here}}
+#pragma omp target parallel for simd ordered
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - 4];
+#pragma omp target parallel for simd ordered( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - 4];
+#pragma omp target parallel for simd ordered() // expected-error {{expected expression}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - 4];
+#pragma omp target parallel for simd ordered(4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'ordered' clause}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - 4]; // expected-error {{expected 4 for loops after '#pragma omp target parallel for simd', but found only 1}}
+#pragma omp target parallel for simd ordered(2 + 2)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} expected-note {{as specified in 'ordered' clause}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - 4]; // expected-error {{expected 4 for loops after '#pragma omp target parallel for simd', but found only 1}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target parallel for simd ordered(foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - 4];
+#if __cplusplus >= 201103L
+ // expected-note@+5 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+// expected-error@+3 {{expression is not an integral constant expression}}
+// expected-error@+2 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'ordered' clause}}
+// expected-error@+1 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
+#pragma omp target parallel for simd ordered(foobool(argc)), ordered(true), ordered(-5)
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - 4];
+#pragma omp target parallel for simd ordered(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - 4];
+// expected-note@+2 {{read of non-const variable 'j' is not allowed in a constant expression}}
+// expected-error@+1 {{expression is not an integral constant expression}}
+#pragma omp target parallel for simd ordered(j = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++)
+ argv[0][i] = argv[0][i] - argv[0][i - 4];
+// expected-error@+3 {{statement after '#pragma omp target parallel for simd' must be a for loop}}
+// expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+#pragma omp target parallel for simd ordered(ordered(tmain < int, char, -1, -2 > (argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+ foo();
+#pragma omp target parallel for simd ordered(2) // expected-note {{as specified in 'ordered' clause}}
+ foo(); // expected-error {{expected 2 for loops after '#pragma omp target parallel for simd'}}
+ // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
+ return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/target_parallel_for_simd_private_messages.cpp b/test/OpenMP/target_parallel_for_simd_private_messages.cpp
new file mode 100644
index 0000000000000..57262a58598c5
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_private_messages.cpp
@@ -0,0 +1,231 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+
+public:
+ S2() : a(0) {}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+
+public:
+ S3() : a(0) {}
+};
+const S3 ca[5];
+class S4 {
+ int a;
+ S4(); // expected-note {{implicitly declared private here}}
+
+public:
+ S4(int v) : a(v) {
+#pragma omp target parallel for simd private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+};
+class S5 {
+ int a;
+ S5() : a(0) {} // expected-note {{implicitly declared private here}}
+
+public:
+ S5(int v) : a(v) {}
+ S5 &operator=(S5 &s) {
+#pragma omp target parallel for simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S6 {
+public:
+ T a;
+
+ S6() : a(0) {}
+ S6(T v) : a(v) {
+#pragma omp target parallel for simd private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+ S6 &operator=(S6 &s) {
+#pragma omp target parallel for simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S7 : public T {
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(T v) : a(v) {
+#pragma omp target parallel for simd private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp target parallel for simd private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(I argc, C **argv) {
+ I e(4);
+ I g(5);
+ int i;
+ int &j = i;
+#pragma omp target parallel for simd private // expected-error {{expected '(' after 'private'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd private() // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd private(argc)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd private(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd private(argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd private(e, g)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp parallel
+ {
+ int v = 0;
+ int i;
+#pragma omp target parallel for simd private(i)
+ for (int k = 0; k < argc; ++k) {
+ i = k;
+ v += i;
+ }
+ }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp target parallel for simd private(j)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd private(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+ return 0;
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ S4 e(4);
+ S5 g(5);
+ S6<float> s6(0.0) , s6_0(1.0);
+ S7<S6<float> > s7(0.0) , s7_0(1.0);
+ int i;
+ int &j = i;
+#pragma omp target parallel for simd private // expected-error {{expected '(' after 'private'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd private() // expected-error {{expected expression}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd private(argc)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd private(S1) // expected-error {{'S1' does not refer to a value}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd private(argv[1]) // expected-error {{expected variable name}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd private(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}}
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp parallel
+ {
+ int i;
+#pragma omp target parallel for simd private(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+ }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp target parallel for simd private(j)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+#pragma omp target parallel for simd private(i)
+ for (int k = 0; k < argc; ++k)
+ ++k;
+ static int m;
+#pragma omp target parallel for simd private(m)
+ for (int k = 0; k < argc; ++k)
+ m = k + 2;
+
+ s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}}
+ s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}}
+ return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
+}
+
diff --git a/test/OpenMP/target_parallel_for_simd_proc_bind_messages.cpp b/test/OpenMP/target_parallel_for_simd_proc_bind_messages.cpp
new file mode 100644
index 0000000000000..5bb6d92cd7e9e
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_proc_bind_messages.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo();
+
+int main(int argc, char **argv) {
+ int i;
+#pragma omp target parallel for simd proc_bind // expected-error {{expected '(' after 'proc_bind'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd proc_bind( // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd proc_bind() // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd proc_bind(master // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd proc_bind(close), proc_bind(spread) // expected-error {{directive '#pragma omp target parallel for simd' cannot contain more than one 'proc_bind' clause}}
+ for (i = 0; i < argc; ++i)
+ foo();
+#pragma omp target parallel for simd proc_bind(x) // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+ for (i = 0; i < argc; ++i)
+ foo();
+
+#pragma omp target parallel for simd proc_bind(master)
+ for (i = 0; i < argc; ++i)
+ foo();
+
+#pragma omp parallel proc_bind(close)
+#pragma omp target parallel for simd proc_bind(spread)
+ for (i = 0; i < argc; ++i)
+ foo();
+ return 0;
+}
diff --git a/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp b/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp
new file mode 100644
index 0000000000000..3999d38162843
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp
@@ -0,0 +1,313 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+ S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}}
+
+public:
+ S2() : a(0) {}
+ S2(S2 &s2) : a(s2.a) {}
+ static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
+ static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+S2 b; // expected-note 3 {{'b' defined here}}
+const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
+class S3 {
+ int a;
+
+public:
+ int b;
+ S3() : a(0) {}
+ S3(const S3 &s3) : a(s3.a) {}
+ S3 operator+(const S3 &arg1) { return arg1; }
+};
+int operator+(const S3 &arg1, const S3 &arg2) { return 5; }
+S3 c; // expected-note 3 {{'c' defined here}}
+const S3 ca[5]; // expected-note 2 {{'ca' defined here}}
+extern const int f; // expected-note 4 {{'f' declared here}}
+class S4 {
+ int a;
+ S4(); // expected-note {{implicitly declared private here}}
+ S4(const S4 &s4);
+ S4 &operator+(const S4 &arg) { return (*this); }
+
+public:
+ S4(int v) : a(v) {}
+};
+S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; }
+class S5 {
+ int a;
+ S5() : a(0) {} // expected-note {{implicitly declared private here}}
+ S5(const S5 &s5) : a(s5.a) {}
+ S5 &operator+(const S5 &arg);
+
+public:
+ S5(int v) : a(v) {}
+};
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+#if __cplusplus >= 201103L // C++11 or later
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
+#endif
+ int a;
+
+public:
+ S6() : a(6) {}
+ operator int() { return 6; }
+} o;
+
+S3 h, k;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class T> // expected-note {{declared here}}
+T tmain(T argc) {
+ const T d = T(); // expected-note 4 {{'d' defined here}}
+ const T da[5] = {T()}; // expected-note 2 {{'da' defined here}}
+ T qa[5] = {T()};
+ T i;
+ T &j = i; // expected-note 4 {{'j' defined here}}
+ S3 &p = k; // expected-note 2 {{'p' defined here}}
+ const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}}
+ T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}}
+ T fl;
+#pragma omp target parallel for simd reduction // expected-error {{expected '(' after 'reduction'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(&& : argc)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel private(k)
+#pragma omp target parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp target parallel for simd reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel private(fl)
+#pragma omp target parallel for simd reduction(+ : fl)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel reduction(* : fl)
+#pragma omp target parallel for simd reduction(+ : fl)
+ for (int i = 0; i < 10; ++i)
+ foo();
+
+ return T();
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5; // expected-note 2 {{'d' defined here}}
+ const int da[5] = {0}; // expected-note {{'da' defined here}}
+ int qa[5] = {0};
+ S4 e(4);
+ S5 g(5);
+ int i;
+ int &j = i; // expected-note 2 {{'j' defined here}}
+ S3 &p = k; // expected-note 2 {{'p' defined here}}
+ const int &r = da[i]; // expected-note {{'r' defined here}}
+ int &q = qa[i]; // expected-note {{'q' defined here}}
+ float fl;
+#pragma omp target parallel for simd reduction // expected-error {{expected '(' after 'reduction'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(~ : argc) // expected-error {{expected unqualified-id}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(&& : argc)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(+ : o) // expected-error {{no viable overloaded '='}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel private(k)
+#pragma omp target parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp target parallel for simd reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp target parallel for simd reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel private(fl)
+#pragma omp target parallel for simd reduction(+ : fl)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel reduction(* : fl)
+#pragma omp target parallel for simd reduction(+ : fl)
+ for (int i = 0; i < 10; ++i)
+ foo();
+ static int m;
+#pragma omp target parallel for simd reduction(+ : m) // OK
+ for (int i = 0; i < 10; ++i)
+ m++;
+
+ return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}}
+}
diff --git a/test/OpenMP/target_parallel_for_simd_safelen_messages.cpp b/test/OpenMP/target_parallel_for_simd_safelen_messages.cpp
new file mode 100644
index 0000000000000..f99010179dc30
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_safelen_messages.cpp
@@ -0,0 +1,102 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
+ #pragma omp target parallel for simd safelen // expected-error {{expected '(' after 'safelen'}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd safelen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd safelen () // expected-error {{expected expression}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+ // expected-error@+2 2 {{expression is not an integral constant expression}}
+ // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}}
+ #pragma omp target parallel for simd safelen (argc
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}}
+ #pragma omp target parallel for simd safelen (ST // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd safelen (1)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd safelen ((ST > 0) ? 1 + ST : 2)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-error@+6 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'safelen' clause}}
+ // expected-error@+5 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+ #pragma omp target parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd safelen (S) // expected-error {{'S' does not refer to a value}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+#if __cplusplus <= 199711L
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+ #pragma omp target parallel for simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd safelen (4)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd safelen (N) // expected-error {{argument to 'safelen' clause must be a strictly positive integer value}}
+ for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ return argc;
+}
+
+int main(int argc, char **argv) {
+ #pragma omp target parallel for simd safelen // expected-error {{expected '(' after 'safelen'}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for simd safelen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for simd safelen () // expected-error {{expected expression}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for simd safelen (4 // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for simd safelen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+ #pragma omp target parallel for simd safelen (foobool(1) > 0 ? 1 : 2)
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+ // expected-error@+2 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'safelen' clause}}
+ // expected-error@+1 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+ #pragma omp target parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5)
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for simd safelen (S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+#if __cplusplus <= 199711L
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+ #pragma omp target parallel for simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+3 {{statement after '#pragma omp target parallel for simd' must be a for loop}}
+ // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+ #pragma omp target parallel for simd safelen(safelen(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+ foo();
+ // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 12, 4>' requested here}}
+ return tmain<int, char, 12, 4>(argc, argv);
+}
+
diff --git a/test/OpenMP/target_parallel_for_simd_schedule_messages.cpp b/test/OpenMP/target_parallel_for_simd_schedule_messages.cpp
new file mode 100644
index 0000000000000..f0d86e952de6a
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_schedule_messages.cpp
@@ -0,0 +1,91 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) {
+ #pragma omp target parallel for simd schedule // expected-error {{expected '(' after 'schedule'}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd schedule (runtime, 3) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+ #pragma omp target parallel for simd schedule (guided argc
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-error@+1 2 {{argument to 'schedule' clause must be a strictly positive integer value}}
+ #pragma omp target parallel for simd schedule (static, ST // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd schedule (dynamic, 1)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd schedule (guided, (ST > 0) ? 1 + ST : 2)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-error@+2 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'schedule' clause}}
+ // expected-error@+1 {{argument to 'schedule' clause must be a strictly positive integer value}}
+ #pragma omp target parallel for simd schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd schedule (static, S) // expected-error {{'S' does not refer to a value}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ // expected-error@+1 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ #pragma omp target parallel for simd schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd schedule (dynamic, 1)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp target parallel for simd schedule (static, N) // expected-error {{argument to 'schedule' clause must be a strictly positive integer value}}
+ for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ return argc;
+}
+
+int main(int argc, char **argv) {
+ #pragma omp target parallel for simd schedule // expected-error {{expected '(' after 'schedule'}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for simd schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for simd schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for simd schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for simd schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto', 'runtime', 'monotonic', 'nonmonotonic' or 'simd' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for simd schedule (auto, // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for simd schedule (runtime, 3) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for simd schedule (guided, 4 // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for simd schedule (static, 2+2)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for simd schedule (dynamic, foobool(1) > 0 ? 1 : 2)
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+2 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'schedule' clause}}
+ // expected-error@+1 {{argument to 'schedule' clause must be a strictly positive integer value}}
+ #pragma omp target parallel for simd schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5)
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ #pragma omp target parallel for simd schedule (guided, S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ #pragma omp target parallel for simd schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+ // expected-error@+3 {{statement after '#pragma omp target parallel for simd' must be a for loop}}
+ // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+ #pragma omp target parallel for simd schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+ foo();
+ // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
+ return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/target_parallel_for_simd_simdlen_messages.cpp b/test/OpenMP/target_parallel_for_simd_simdlen_messages.cpp
new file mode 100644
index 0000000000000..e51e67b6b45f2
--- /dev/null
+++ b/test/OpenMP/target_parallel_for_simd_simdlen_messages.cpp
@@ -0,0 +1,142 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
+
+void foo() {
+}
+
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
+#pragma omp target parallel for simd simdlen // expected-error {{expected '(' after 'simdlen'}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target parallel for simd simdlen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target parallel for simd simdlen () // expected-error {{expected expression}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+// expected-error@+2 2 {{expression is not an integral constant expression}}
+// expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}}
+#pragma omp target parallel for simd simdlen (argc
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+#pragma omp target parallel for simd simdlen (ST // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target parallel for simd simdlen (1)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target parallel for simd simdlen ((ST > 0) ? 1 + ST : 2)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+ // expected-error@+6 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'simdlen' clause}}
+ // expected-error@+5 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target parallel for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target parallel for simd simdlen (S) // expected-error {{'S' does not refer to a value}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#if __cplusplus <= 199711L
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target parallel for simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+ #pragma omp target parallel for simd simdlen (4)
+ for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+ #pragma omp target parallel for simd simdlen (N) // expected-error {{argument to 'simdlen' clause must be a strictly positive integer value}}
+ for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target parallel for simd simdlen (2), safelen (4) // OK
+ for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target parallel for simd simdlen (4), safelen (4) // OK
+ for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+#pragma omp target parallel for simd simdlen (8), safelen (4) // expected-error{{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}}
+ for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+
+ return argc;
+}
+
+int main(int argc, char **argv) {
+#pragma omp target parallel for simd simdlen // expected-error {{expected '(' after 'simdlen'}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target parallel for simd simdlen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target parallel for simd simdlen () // expected-error {{expected expression}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target parallel for simd simdlen (4 // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target parallel for simd simdlen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+#pragma omp target parallel for simd simdlen (foobool(1) > 0 ? 1 : 2)
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+// expected-error@+2 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'simdlen' clause}}
+// expected-error@+1 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+#pragma omp target parallel for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5)
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target parallel for simd simdlen (S1) // expected-error {{'S1' does not refer to a value}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#if __cplusplus <= 199711L
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
+#pragma omp target parallel for simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+// expected-error@+3 {{statement after '#pragma omp target parallel for simd' must be a for loop}}
+// expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+#pragma omp target parallel for simd simdlen(simdlen(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+ foo();
+
+#pragma omp target parallel for simd simdlen (2), safelen (4) // OK
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target parallel for simd simdlen (4), safelen (4) // OK
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+#pragma omp target parallel for simd simdlen (8), safelen (4) // expected-error{{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}}
+ for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+
+ // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 12, 4>' requested here}}
+ return tmain<int, char, 12, 4>(argc, argv);
+}
+
diff --git a/test/OpenMP/target_parallel_if_messages.cpp b/test/OpenMP/target_parallel_if_messages.cpp
new file mode 100644
index 0000000000000..e22eb8150af65
--- /dev/null
+++ b/test/OpenMP/target_parallel_if_messages.cpp
@@ -0,0 +1,103 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, class S> // expected-note {{declared here}}
+int tmain(T argc, S **argv) {
+ #pragma omp target parallel if // expected-error {{expected '(' after 'if'}}
+ foo();
+ #pragma omp target parallel if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel if () // expected-error {{expected expression}}
+ foo();
+ #pragma omp target parallel if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}}
+ foo();
+ #pragma omp target parallel if (argc > 0 ? argv[1] : argv[2])
+ foo();
+ #pragma omp target parallel if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target parallel' cannot contain more than one 'if' clause}}
+ foo();
+ #pragma omp target parallel if (S) // expected-error {{'S' does not refer to a value}}
+ foo();
+ #pragma omp target parallel if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel if(argc)
+ foo();
+ #pragma omp target parallel if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel if(target : argc)
+ foo();
+ #pragma omp target parallel if(parallel : argc)
+ foo();
+ #pragma omp target parallel if(target : argc) if(parallel : argc)
+ foo();
+ #pragma omp target parallel if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target parallel'}}
+ foo();
+ #pragma omp target parallel if(target : argc) if (target :argc) // expected-error {{directive '#pragma omp target parallel' cannot contain more than one 'if' clause with 'target' name modifier}}
+ foo();
+ #pragma omp target parallel if(parallel : argc) if (parallel :argc) // expected-error {{directive '#pragma omp target parallel' cannot contain more than one 'if' clause with 'parallel' name modifier}}
+ foo();
+ #pragma omp target parallel if(target : argc) if (argc) // expected-error {{expected 'parallel' directive name modifier}} expected-note {{previous clause with directive name modifier specified here}}
+ foo();
+ #pragma omp target parallel if(target : argc) if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} expected-note {{previous clause with directive name modifier specified here}}
+ foo();
+
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ #pragma omp target parallel if // expected-error {{expected '(' after 'if'}}
+ foo();
+ #pragma omp target parallel if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel if () // expected-error {{expected expression}}
+ foo();
+ #pragma omp target parallel if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}}
+ foo();
+ #pragma omp target parallel if (argc > 0 ? argv[1] : argv[2])
+ foo();
+ #pragma omp target parallel if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target parallel' cannot contain more than one 'if' clause}}
+ foo();
+ #pragma omp target parallel if (S1) // expected-error {{'S1' does not refer to a value}}
+ foo();
+ #pragma omp target parallel if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel if(parallel : argc)
+ foo();
+ #pragma omp target parallel if(target : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target parallel'}}
+ foo();
+ #pragma omp target parallel if(target : argc) if (target :argc) // expected-error {{directive '#pragma omp target parallel' cannot contain more than one 'if' clause with 'target' name modifier}}
+ foo();
+ #pragma omp target parallel if(parallel : argc) if (parallel :argc) // expected-error {{directive '#pragma omp target parallel' cannot contain more than one 'if' clause with 'parallel' name modifier}}
+ foo();
+ #pragma omp target parallel if(target : argc) if (argc) // expected-error {{expected 'parallel' directive name modifier}} expected-note {{previous clause with directive name modifier specified here}}
+ foo();
+ #pragma omp target parallel if(target : argc) if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}} expected-note {{previous clause with directive name modifier specified here}}
+ foo();
+
+ return tmain(argc, argv);
+}
diff --git a/test/OpenMP/target_parallel_map_messages.cpp b/test/OpenMP/target_parallel_map_messages.cpp
new file mode 100644
index 0000000000000..ff20567185bf5
--- /dev/null
+++ b/test/OpenMP/target_parallel_map_messages.cpp
@@ -0,0 +1,272 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+extern S1 a;
+class S2 {
+ mutable int a;
+public:
+ S2():a(0) { }
+ S2(S2 &s2):a(s2.a) { }
+ static float S2s; // expected-note 4 {{mappable type cannot contain static members}}
+ static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}}
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+public:
+ S3():a(0) { }
+ S3(S3 &s3):a(s3.a) { }
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 {
+ int a;
+ S4();
+ S4(const S4 &s4);
+public:
+ S4(int v):a(v) { }
+};
+class S5 {
+ int a;
+ S5():a(0) {}
+ S5(const S5 &s5):a(s5.a) { }
+public:
+ S5(int v):a(v) { }
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+typedef int from;
+
+template <typename T, int I> // expected-note {{declared here}}
+T tmain(T argc) {
+ const T d = 5;
+ const T da[5] = { 0 };
+ S4 e(4);
+ S5 g(5);
+ T i, t[20];
+ T &j = i;
+ T *k = &j;
+ T x;
+ T y;
+ T to, tofrom, always;
+ const T (&l)[5] = da;
+
+
+#pragma omp target parallel map // expected-error {{expected '(' after 'map'}}
+ foo();
+#pragma omp target parallel map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+ foo();
+#pragma omp target parallel map() // expected-error {{expected expression}}
+ foo();
+#pragma omp target parallel map(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+ foo();
+#pragma omp target parallel map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}}
+ foo();
+#pragma omp target parallel map(to:) // expected-error {{expected expression}}
+ foo();
+#pragma omp target parallel map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+#pragma omp target parallel map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+ foo();
+#pragma omp target parallel map(x)
+ foo();
+#pragma omp target parallel map(tofrom: t[:I])
+ foo();
+#pragma omp target parallel map(T: a) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} expected-error {{incomplete type 'S1' where a complete type is required}}
+ foo();
+#pragma omp target parallel map(T) // expected-error {{'T' does not refer to a value}}
+ foo();
+#pragma omp target parallel map(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
+ foo();
+#pragma omp target parallel map(S2::S2s)
+ foo();
+#pragma omp target parallel map(S2::S2sc)
+ foo();
+#pragma omp target parallel map(x)
+ foo();
+#pragma omp target parallel map(to: x)
+ foo();
+#pragma omp target parallel map(to: to)
+ foo();
+#pragma omp target parallel map(to)
+ foo();
+#pragma omp target parallel map(to, x)
+ foo();
+#pragma omp target parallel map(to x) // expected-error {{expected ',' or ')' in 'map' clause}}
+ foo();
+#pragma omp target parallel map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
+ foo();
+#pragma omp target parallel map(argc)
+ foo();
+#pragma omp target parallel map(S1) // expected-error {{'S1' does not refer to a value}}
+ foo();
+#pragma omp target parallel map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+ foo();
+#pragma omp target parallel map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+ foo();
+#pragma omp target parallel map(ca)
+ foo();
+#pragma omp target parallel map(da)
+ foo();
+#pragma omp target parallel map(S2::S2s)
+ foo();
+#pragma omp target parallel map(S2::S2sc)
+ foo();
+#pragma omp target parallel map(e, g)
+ foo();
+#pragma omp target parallel map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
+ foo();
+#pragma omp target parallel map(k), map(k) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
+ foo();
+#pragma omp target parallel map(k), map(k[:5]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}} expected-note 2 {{used here}}
+ foo();
+#pragma omp target parallel map(da)
+ foo();
+#pragma omp target parallel map(da[:4])
+ foo();
+#pragma omp target data map(k, j, l) // expected-note 2 {{used here}}
+#pragma omp target parallel map(k[:4]) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}}
+ foo();
+#pragma omp target parallel map(j)
+ foo();
+#pragma omp target parallel map(l) map(l[:5]) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
+ foo();
+#pragma omp target data map(k[:4], j, l[:5]) // expected-note 4 {{used here}}
+{
+#pragma omp target parallel map(k) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}}
+ foo();
+#pragma omp target parallel map(j)
+ foo();
+#pragma omp target parallel map(l) // expected-error 2 {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}}
+ foo();
+}
+
+#pragma omp target parallel map(always, tofrom: x)
+ foo();
+#pragma omp target parallel map(always: x) // expected-error {{missing map type}}
+ foo();
+#pragma omp target parallel map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+ foo();
+#pragma omp target parallel map(always, tofrom: always, tofrom, x)
+ foo();
+#pragma omp target parallel map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}}
+ foo();
+
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5;
+ const int da[5] = { 0 };
+ S4 e(4);
+ S5 g(5);
+ int i;
+ int &j = i;
+ int *k = &j;
+ int x;
+ int y;
+ int to, tofrom, always;
+ const int (&l)[5] = da;
+#pragma omp target parallel map // expected-error {{expected '(' after 'map'}}
+ foo();
+#pragma omp target parallel map( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}}
+ foo();
+#pragma omp target parallel map() // expected-error {{expected expression}}
+ foo();
+#pragma omp target parallel map(alloc) // expected-error {{use of undeclared identifier 'alloc'}}
+ foo();
+#pragma omp target parallel map(to argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected ',' or ')' in 'map' clause}}
+ foo();
+#pragma omp target parallel map(to:) // expected-error {{expected expression}}
+ foo();
+#pragma omp target parallel map(from: argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+#pragma omp target parallel map(x: y) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+ foo();
+#pragma omp target parallel map(x)
+ foo();
+#pragma omp target parallel map(to: x)
+ foo();
+#pragma omp target parallel map(to: to)
+ foo();
+#pragma omp target parallel map(to)
+ foo();
+#pragma omp target parallel map(to, x)
+ foo();
+#pragma omp target parallel map(to x) // expected-error {{expected ',' or ')' in 'map' clause}}
+ foo();
+#pragma omp target parallel map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}}
+ foo();
+#pragma omp target parallel map(argc)
+ foo();
+#pragma omp target parallel map(S1) // expected-error {{'S1' does not refer to a value}}
+ foo();
+#pragma omp target parallel map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+ foo();
+#pragma omp target parallel map(argv[1])
+ foo();
+#pragma omp target parallel map(ba) // expected-error 2 {{type 'S2' is not mappable to target}}
+ foo();
+#pragma omp target parallel map(ca)
+ foo();
+#pragma omp target parallel map(da)
+ foo();
+#pragma omp target parallel map(S2::S2s)
+ foo();
+#pragma omp target parallel map(S2::S2sc)
+ foo();
+#pragma omp target parallel map(e, g)
+ foo();
+#pragma omp target parallel map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}}
+ foo();
+#pragma omp target parallel map(k), map(k) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
+ foo();
+#pragma omp target parallel map(k), map(k[:5]) // expected-error {{pointer cannot be mapped along with a section derived from itself}} expected-note {{used here}}
+ foo();
+#pragma omp target parallel map(da)
+ foo();
+#pragma omp target parallel map(da[:4])
+ foo();
+#pragma omp target data map(k, j, l) // expected-note {{used here}}
+#pragma omp target parallel map(k[:4]) // expected-error {{pointer cannot be mapped along with a section derived from itself}}
+ foo();
+#pragma omp target parallel map(j)
+ foo();
+#pragma omp target parallel map(l) map(l[:5]) // expected-error 1 {{variable already marked as mapped in current construct}} expected-note 1 {{used here}}
+ foo();
+#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}}
+{
+#pragma omp target parallel map(k) // expected-error {{pointer cannot be mapped along with a section derived from itself}}
+ foo();
+#pragma omp target parallel map(j)
+ foo();
+#pragma omp target parallel map(l) // expected-error {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}}
+ foo();
+}
+
+#pragma omp target parallel map(always, tofrom: x)
+ foo();
+#pragma omp target parallel map(always: x) // expected-error {{missing map type}}
+ foo();
+#pragma omp target parallel map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+ foo();
+#pragma omp target parallel map(always, tofrom: always, tofrom, x)
+ foo();
+#pragma omp target parallel map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}}
+ foo();
+
+ return tmain<int, 3>(argc)+tmain<from, 4>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<int, 4>' requested here}}
+}
+
diff --git a/test/OpenMP/target_parallel_messages.cpp b/test/OpenMP/target_parallel_messages.cpp
new file mode 100644
index 0000000000000..b6763d8f09e03
--- /dev/null
+++ b/test/OpenMP/target_parallel_messages.cpp
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -o - %s
+// RUN: not %clang_cc1 -fopenmp -std=c++11 -fopenmp-targets=aaa-bbb-ccc-ddd -o - %s 2>&1 | FileCheck %s
+// CHECK: error: OpenMP target is invalid: 'aaa-bbb-ccc-ddd'
+
+void foo() {
+}
+
+static int pvt;
+#pragma omp threadprivate(pvt)
+
+#pragma omp target parallel // expected-error {{unexpected OpenMP directive '#pragma omp target parallel'}}
+
+int main(int argc, char **argv) {
+ #pragma omp target parallel { // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}}
+ foo();
+ #pragma omp target parallel ( // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}}
+ foo();
+ #pragma omp target parallel [ // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}}
+ foo();
+ #pragma omp target parallel ] // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}}
+ foo();
+ #pragma omp target parallel ) // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}}
+ foo();
+ #pragma omp target parallel } // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}}
+ foo();
+ #pragma omp target parallel
+ foo();
+ // expected-warning@+1 {{extra tokens at the end of '#pragma omp target parallel' are ignored}}
+ #pragma omp target parallel unknown()
+ foo();
+ L1:
+ foo();
+ #pragma omp target parallel
+ ;
+ #pragma omp target parallel
+ {
+ goto L1; // expected-error {{use of undeclared label 'L1'}}
+ argc++;
+ }
+
+ for (int i = 0; i < 10; ++i) {
+ switch(argc) {
+ case (0):
+ #pragma omp target parallel
+ {
+ foo();
+ break; // expected-error {{'break' statement not in loop or switch statement}}
+ continue; // expected-error {{'continue' statement not in loop statement}}
+ }
+ default:
+ break;
+ }
+ }
+
+ goto L2; // expected-error {{use of undeclared label 'L2'}}
+ #pragma omp target parallel
+ L2:
+ foo();
+ #pragma omp target parallel
+ {
+ return 1; // expected-error {{cannot return from OpenMP region}}
+ }
+
+ [[]] // expected-error {{an attribute list cannot appear here}}
+ #pragma omp target parallel
+ for (int n = 0; n < 100; ++n) {}
+
+ #pragma omp target parallel copyin(pvt) // expected-error {{unexpected OpenMP clause 'copyin' in directive '#pragma omp target parallel'}}
+ foo();
+
+ return 0;
+}
+
diff --git a/test/OpenMP/target_parallel_nowait_messages.cpp b/test/OpenMP/target_parallel_nowait_messages.cpp
new file mode 100644
index 0000000000000..91e26f20819f6
--- /dev/null
+++ b/test/OpenMP/target_parallel_nowait_messages.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+int main(int argc, char **argv) {
+ #pragma omp target parallel nowait( // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}}
+ foo();
+ #pragma omp target parallel nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}}
+ foo();
+ #pragma omp target parallel nowait device (-10u)
+ foo();
+ #pragma omp target parallel nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}}
+ foo();
+
+ return 0;
+}
diff --git a/test/OpenMP/target_parallel_num_threads_messages.cpp b/test/OpenMP/target_parallel_num_threads_messages.cpp
new file mode 100644
index 0000000000000..95797caf29622
--- /dev/null
+++ b/test/OpenMP/target_parallel_num_threads_messages.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+#define redef_num_threads(a, b) num_threads(a)
+
+template <class T, typename S, int N> // expected-note {{declared here}}
+T tmain(T argc, S **argv) {
+ #pragma omp target parallel num_threads // expected-error {{expected '(' after 'num_threads'}}
+ foo();
+ #pragma omp target parallel num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel num_threads () // expected-error {{expected expression}}
+ foo();
+ #pragma omp target parallel num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}}
+ foo();
+ #pragma omp target parallel num_threads ((argc > 0) ? argv[1] : argv[2]) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ foo();
+ #pragma omp target parallel num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp target parallel' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}}
+ foo();
+ #pragma omp target parallel num_threads (S) // expected-error {{'S' does not refer to a value}}
+ foo();
+ #pragma omp target parallel num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ foo();
+ #pragma omp target parallel num_threads (argc)
+ foo();
+ #pragma omp target parallel num_threads (N) // expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}}
+ foo();
+ #pragma omp target parallel redef_num_threads (argc, argc)
+ foo();
+
+ return argc;
+}
+
+int main(int argc, char **argv) {
+ #pragma omp target parallel num_threads // expected-error {{expected '(' after 'num_threads'}}
+ foo();
+ #pragma omp target parallel num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel num_threads () // expected-error {{expected expression}}
+ foo();
+ #pragma omp target parallel num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}}
+ foo();
+ #pragma omp target parallel num_threads (argc > 0 ? argv[1] : argv[2]) // expected-error {{integral }}
+ foo();
+ #pragma omp target parallel num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp target parallel' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a strictly positive integer value}}
+ foo();
+ #pragma omp target parallel num_threads (S1) // expected-error {{'S1' does not refer to a value}}
+ foo();
+ #pragma omp target parallel num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+ foo();
+ #pragma omp target parallel num_threads (num_threads(tmain<int, char, -1>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} expected-note {{in instantiation of function template specialization 'tmain<int, char, -1>' requested here}}
+ foo();
+ #pragma omp target parallel redef_num_threads (argc, argc)
+ foo();
+
+ return tmain<int, char, 3>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char, 3>' requested here}}
+}
diff --git a/test/OpenMP/target_parallel_private_messages.cpp b/test/OpenMP/target_parallel_private_messages.cpp
new file mode 100644
index 0000000000000..fabd37d4b3950
--- /dev/null
+++ b/test/OpenMP/target_parallel_private_messages.cpp
@@ -0,0 +1,222 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+void foo() {
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}} expected-note 1 {{forward declaration of 'S1'}} expected-note {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+
+public:
+ S2() : a(0) {}
+ static float S2s; // expected-note {{static data member is predetermined as shared}} expected-note 1 {{static data member is predetermined as shared}}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+
+public:
+ S3() : a(0) {}
+};
+const S3 c; // expected-note {{global variable is predetermined as shared}} expected-note 1 {{global variable is predetermined as shared}}
+const S3 ca[5]; // expected-note {{global variable is predetermined as shared}} expected-note 1 {{global variable is predetermined as shared}}
+extern const int f; // expected-note {{global variable is predetermined as shared}} expected-note 1 {{global variable is predetermined as shared}}
+
+int threadvar;
+#pragma omp threadprivate(threadvar) // expected-note {{defined as threadprivate or thread local}} expected-note 1 {{defined as threadprivate or thread local}}
+
+class S4 {
+ int a;
+ S4(); // expected-note {{implicitly declared private here}} expected-note 1 {{implicitly declared private here}}
+
+public:
+ S4(int v) : a(v) {}
+};
+class S5 {
+ int a;
+ S5() : a(0) {} // expected-note {{implicitly declared private here}} expected-note 1 {{implicitly declared private here}}
+
+public:
+ S5(int v) : a(v) {}
+};
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}} expected-note 1 {{defined as threadprivate or thread local}} expected-note 2 {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C, class D, class E>
+int foomain(I argc, C **argv) {
+ const I d = 5; // expected-note {{constant variable is predetermined as shared}}
+ const I da[5] = { 0 }; // expected-note {{constant variable is predetermined as shared}}
+ D e(4);
+ E g[] = {5, 6};
+ I i;
+ I &j = i;
+#pragma omp target parallel private // expected-error {{expected '(' after 'private'}}
+{}
+#pragma omp target parallel private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+{}
+#pragma omp target parallel private() // expected-error {{expected expression}}
+{}
+#pragma omp target parallel private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+{}
+#pragma omp target parallel private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+{}
+#pragma omp target parallel private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+{}
+#pragma omp target parallel private(argc argv) // expected-error {{expected ',' or ')' in 'private' clause}}
+{}
+#pragma omp target parallel private(argc)
+{}
+#pragma omp target parallel private(S1) // expected-error {{'S1' does not refer to a value}}
+{}
+#pragma omp target parallel private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+{}
+#pragma omp target parallel private (a, b, c, d, f) // expected-error {{a private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}}
+{}
+#pragma omp target parallel private(argv[1]) // expected-error {{expected variable name}}
+{}
+#pragma omp target parallel private(ba)
+{}
+#pragma omp target parallel private(ca) // expected-error {{shared variable cannot be private}}
+{}
+#pragma omp target parallel private(da) // expected-error {{shared variable cannot be private}}
+{}
+#pragma omp target parallel private(S2::S2s) // expected-error {{shared variable cannot be private}}
+{}
+#pragma omp target parallel private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+{}
+ #pragma omp target parallel private(threadvar, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}}
+ {}
+ #pragma omp target parallel shared(i), private(i) // expected-error {{shared variable cannot be private}} expected-note {{defined as shared}}
+ foo();
+ #pragma omp target parallel firstprivate(i) private(i) // expected-error {{firstprivate variable cannot be private}} expected-note {{defined as firstprivate}}
+ foo();
+ #pragma omp target parallel private(i)
+ {}
+ #pragma omp target parallel private(j)
+ foo();
+ #pragma omp parallel firstprivate(i)
+ for (int k = 0; k < 10; ++k) {
+ #pragma omp target parallel private(i)
+ foo();
+ }
+ static int m;
+ #pragma omp target parallel private(m) // OK
+ foo();
+#pragma omp target parallel private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+{}
+#pragma omp target parallel private(B::x) // expected-error {{threadprivate or thread local variable cannot be private}}
+#pragma omp parallel
+ {
+ int v = 0;
+ int i;
+ }
+#pragma omp target parallel shared(i)
+{}
+#pragma omp target parallel private(i)
+{}
+#pragma omp target parallel private(j)
+{}
+#pragma omp target parallel private(i)
+{}
+ static int si;
+#pragma omp target parallel private(si) // OK
+ {}
+ return 0;
+}
+
+void bar(S4 a[2]) {
+#pragma omp parallel
+#pragma omp target parallel private(a)
+ {}
+}
+
+int main(int argc, char **argv) {
+ const int d = 5; // expected-note {{constant variable is predetermined as shared}}
+ const int da[5] = { 0 }; // expected-note {{constant variable is predetermined as shared}}
+ S4 e(4);
+ S5 g[] = {5, 6};
+ int i;
+ int &j = i;
+#pragma omp target parallel private // expected-error {{expected '(' after 'private'}}
+{}
+#pragma omp target parallel private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+{}
+#pragma omp target parallel private() // expected-error {{expected expression}}
+{}
+#pragma omp target parallel private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+{}
+#pragma omp target parallel private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+{}
+#pragma omp target parallel private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+{}
+#pragma omp target parallel private(argc argv) // expected-error {{expected ',' or ')' in 'private' clause}}
+{}
+#pragma omp target parallel private(argc)
+{}
+#pragma omp target parallel private(S1) // expected-error {{'S1' does not refer to a value}}
+{}
+#pragma omp target parallel private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+{}
+#pragma omp target parallel private (a, b, c, d, f) // expected-error {{a private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}}
+{}
+#pragma omp target parallel private(argv[1]) // expected-error {{expected variable name}}
+{}
+#pragma omp target parallel private(ba)
+{}
+#pragma omp target parallel private(ca) // expected-error {{shared variable cannot be private}}
+{}
+#pragma omp target parallel private(da) // expected-error {{shared variable cannot be private}}
+{}
+#pragma omp target parallel private(S2::S2s) // expected-error {{shared variable cannot be private}}
+{}
+#pragma omp target parallel private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+{}
+ #pragma omp target parallel private(threadvar, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be private}}
+ {}
+ #pragma omp target parallel shared(i), private(i) // expected-error {{shared variable cannot be private}} expected-note {{defined as shared}}
+ foo();
+ #pragma omp target parallel firstprivate(i) private(i) // expected-error {{firstprivate variable cannot be private}} expected-note {{defined as firstprivate}}
+ foo();
+ #pragma omp target parallel private(i)
+ {}
+ #pragma omp target parallel private(j)
+ foo();
+ #pragma omp parallel firstprivate(i)
+ for (int k = 0; k < 10; ++k) {
+ #pragma omp target parallel private(i)
+ foo();
+ }
+ static int m;
+ #pragma omp target parallel private(m) // OK
+ foo();
+#pragma omp target parallel private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+{}
+#pragma omp target parallel private(B::x) // expected-error {{threadprivate or thread local variable cannot be private}}
+#pragma omp parallel
+ {
+ int i;
+ }
+#pragma omp target parallel shared(i)
+{}
+#pragma omp target parallel private(i)
+{}
+#pragma omp target parallel private(j)
+{}
+#pragma omp target parallel private(i)
+{}
+ static int si;
+#pragma omp target parallel private(si) // OK
+ {}
+ return foomain<int, char, S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char, S4, S5>' requested here}}
+}
+
diff --git a/test/OpenMP/target_parallel_proc_bind_messages.cpp b/test/OpenMP/target_parallel_proc_bind_messages.cpp
new file mode 100644
index 0000000000000..56292ad437032
--- /dev/null
+++ b/test/OpenMP/target_parallel_proc_bind_messages.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s
+
+void foo();
+
+int main(int argc, char **argv) {
+ #pragma omp target parallel proc_bind // expected-error {{expected '(' after 'proc_bind'}}
+ foo();
+ #pragma omp target parallel proc_bind ( // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel proc_bind () // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+ foo();
+ #pragma omp target parallel proc_bind (master // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel proc_bind (close), proc_bind(spread) // expected-error {{directive '#pragma omp target parallel' cannot contain more than one 'proc_bind' clause}}
+ foo();
+ #pragma omp target parallel proc_bind (x) // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+ foo();
+
+ #pragma omp target parallel proc_bind(master)
+ ++argc;
+
+ #pragma omp target parallel proc_bind(close)
+ foo();
+ #pragma omp target parallel proc_bind(spread)
+ ++argc;
+ return 0;
+}
diff --git a/test/OpenMP/target_parallel_reduction_messages.cpp b/test/OpenMP/target_parallel_reduction_messages.cpp
new file mode 100644
index 0000000000000..c9434e76245b9
--- /dev/null
+++ b/test/OpenMP/target_parallel_reduction_messages.cpp
@@ -0,0 +1,263 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+ S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}}
+
+public:
+ S2() : a(0) {}
+ S2(S2 &s2) : a(s2.a) {}
+ static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
+ static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+S2 b; // expected-note 3 {{'b' defined here}}
+const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
+class S3 {
+ int a;
+
+public:
+ int b;
+ S3() : a(0) {}
+ S3(const S3 &s3) : a(s3.a) {}
+ S3 operator+(const S3 &arg1) { return arg1; }
+};
+int operator+(const S3 &arg1, const S3 &arg2) { return 5; }
+S3 c; // expected-note 3 {{'c' defined here}}
+const S3 ca[5]; // expected-note 2 {{'ca' defined here}}
+extern const int f; // expected-note 4 {{'f' declared here}}
+class S4 {
+ int a;
+ S4(); // expected-note {{implicitly declared private here}}
+ S4(const S4 &s4);
+ S4 &operator+(const S4 &arg) { return (*this); }
+
+public:
+ S4(int v) : a(v) {}
+};
+S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; }
+class S5 {
+ int a;
+ S5() : a(0) {} // expected-note {{implicitly declared private here}}
+ S5(const S5 &s5) : a(s5.a) {}
+ S5 &operator+(const S5 &arg);
+
+public:
+ S5(int v) : a(v) {}
+};
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+#if __cplusplus >= 201103L // C++11 or later
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
+#endif
+ int a;
+
+public:
+ S6() : a(6) {}
+ operator int() { return 6; }
+} o;
+
+S3 h, k;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class T> // expected-note {{declared here}}
+T tmain(T argc) {
+ const T d = T(); // expected-note 4 {{'d' defined here}}
+ const T da[5] = {T()}; // expected-note 2 {{'da' defined here}}
+ T qa[5] = {T()};
+ T i;
+ T &j = i; // expected-note 4 {{'j' defined here}}
+ S3 &p = k; // expected-note 2 {{'p' defined here}}
+ const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}}
+ T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}}
+ T fl;
+#pragma omp target parallel reduction // expected-error {{expected '(' after 'reduction'}}
+ foo();
+#pragma omp target parallel reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}}
+ foo();
+#pragma omp target parallel reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+#pragma omp target parallel reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+#pragma omp target parallel reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ foo();
+#pragma omp target parallel reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+ foo();
+#pragma omp target parallel reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ foo();
+#pragma omp target parallel reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ foo();
+#pragma omp target parallel reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ foo();
+#pragma omp target parallel reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}}
+ foo();
+#pragma omp target parallel reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
+ foo();
+#pragma omp target parallel reduction(&& : argc)
+ foo();
+#pragma omp target parallel reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+ foo();
+#pragma omp target parallel reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+ foo();
+#pragma omp target parallel reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp target parallel reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+ foo();
+#pragma omp target parallel reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp target parallel reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp target parallel reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp target parallel reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ foo();
+#pragma omp target parallel reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+ foo();
+#pragma omp target parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp target parallel reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+ foo();
+#pragma omp target parallel reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
+ foo();
+#pragma omp target parallel private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ foo();
+#pragma omp parallel private(k)
+#pragma omp target parallel reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ foo();
+#pragma omp target parallel reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
+ foo();
+#pragma omp target parallel reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp target parallel shared(i)
+ foo();
+#pragma omp parallel reduction(min : i)
+#pragma omp target parallel reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ foo();
+#pragma omp target parallel
+#pragma omp for private(fl)
+ for (int i = 0; i < 10; ++i)
+ {}
+#pragma omp target parallel reduction(+ : fl)
+ foo();
+#pragma omp target parallel
+#pragma omp for reduction(- : fl)
+ for (int i = 0; i < 10; ++i)
+ {}
+#pragma omp target parallel reduction(+ : fl)
+ foo();
+
+ return T();
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5; // expected-note 2 {{'d' defined here}}
+ const int da[5] = {0}; // expected-note {{'da' defined here}}
+ int qa[5] = {0};
+ S4 e(4);
+ S5 g(5);
+ int i;
+ int &j = i; // expected-note 2 {{'j' defined here}}
+ S3 &p = k; // expected-note 2 {{'p' defined here}}
+ const int &r = da[i]; // expected-note {{'r' defined here}}
+ int &q = qa[i]; // expected-note {{'q' defined here}}
+ float fl;
+#pragma omp target parallel reduction // expected-error {{expected '(' after 'reduction'}}
+ foo();
+#pragma omp target parallel reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}}
+ foo();
+#pragma omp target parallel reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+#pragma omp target parallel reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+#pragma omp target parallel reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ foo();
+#pragma omp target parallel reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+ foo();
+#pragma omp target parallel reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ foo();
+#pragma omp target parallel reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+ foo();
+#pragma omp target parallel reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+#pragma omp target parallel reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}}
+ foo();
+#pragma omp target parallel reduction(~ : argc) // expected-error {{expected unqualified-id}}
+ foo();
+#pragma omp target parallel reduction(&& : argc)
+ foo();
+#pragma omp target parallel reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+ foo();
+#pragma omp target parallel reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+ foo();
+#pragma omp target parallel reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp target parallel reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+ foo();
+#pragma omp target parallel reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp target parallel reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp target parallel reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp target parallel reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ foo();
+#pragma omp target parallel reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+ foo();
+#pragma omp target parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp target parallel reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+ foo();
+#pragma omp target parallel reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
+ foo();
+#pragma omp target parallel reduction(+ : o) // expected-error {{no viable overloaded '='}}
+ foo();
+#pragma omp target parallel private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ foo();
+#pragma omp parallel private(k)
+#pragma omp target parallel reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ foo();
+#pragma omp target parallel reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
+ foo();
+#pragma omp target parallel reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp target parallel shared(i)
+ foo();
+#pragma omp parallel reduction(min : i)
+#pragma omp target parallel reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+ foo();
+#pragma omp target parallel
+#pragma omp for private(fl)
+ for (int i = 0; i < 10; ++i)
+ {}
+#pragma omp target parallel reduction(+ : fl)
+ foo();
+#pragma omp target parallel
+#pragma omp for reduction(- : fl)
+ for (int i = 0; i < 10; ++i)
+ {}
+#pragma omp target parallel reduction(+ : fl)
+ foo();
+ static int m;
+#pragma omp target parallel reduction(+ : m) // OK
+ m++;
+
+ return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}}
+}
diff --git a/test/OpenMP/target_parallel_shared_messages.cpp b/test/OpenMP/target_parallel_shared_messages.cpp
new file mode 100644
index 0000000000000..302a09239d341
--- /dev/null
+++ b/test/OpenMP/target_parallel_shared_messages.cpp
@@ -0,0 +1,110 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+extern S1 a;
+class S2 {
+ mutable int a;
+public:
+ S2():a(0) { }
+ S2(S2 &s2):a(s2.a) { }
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+public:
+ S3():a(0) { }
+ S3(S3 &s3):a(s3.a) { }
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 {
+ int a;
+ S4();
+ S4(const S4 &s4);
+public:
+ S4(int v):a(v) { }
+};
+class S5 {
+ int a;
+ S5():a(0) {}
+ S5(const S5 &s5):a(s5.a) { }
+public:
+ S5(int v):a(v) { }
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note {{defined as threadprivate or thread local}}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5;
+ const int da[5] = { 0 };
+ S4 e(4);
+ S5 g(5);
+ int i;
+ int &j = i;
+ #pragma omp target parallel shared // expected-error {{expected '(' after 'shared'}}
+ foo();
+ #pragma omp target parallel shared ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel shared () // expected-error {{expected expression}}
+ foo();
+ #pragma omp target parallel shared (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel shared (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+ #pragma omp target parallel shared (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+ foo();
+ #pragma omp target parallel shared (argc)
+ foo();
+ #pragma omp target parallel shared (S1) // expected-error {{'S1' does not refer to a value}}
+ foo();
+ #pragma omp target parallel shared (a, b, c, d, f)
+ foo();
+ #pragma omp target parallel shared (argv[1]) // expected-error {{expected variable name}}
+ foo();
+ #pragma omp target parallel shared(ba)
+ foo();
+ #pragma omp target parallel shared(ca)
+ foo();
+ #pragma omp target parallel shared(da)
+ foo();
+ #pragma omp target parallel shared(e, g)
+ foo();
+ #pragma omp target parallel shared(h, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be shared}}
+ foo();
+ #pragma omp target parallel private(i), shared(i) // expected-error {{private variable cannot be shared}} expected-note {{defined as private}}
+ foo();
+ #pragma omp target parallel firstprivate(i), shared(i) // expected-error {{firstprivate variable cannot be shared}} expected-note {{defined as firstprivate}}
+ foo();
+ #pragma omp target parallel private(i)
+ foo();
+ #pragma omp target parallel shared(i)
+ foo();
+ #pragma omp target parallel shared(j)
+ foo();
+ #pragma omp target parallel firstprivate(i)
+ foo();
+ #pragma omp target parallel shared(i)
+ foo();
+ #pragma omp target parallel shared(j)
+ foo();
+
+ return 0;
+}
diff --git a/test/OpenMP/target_private_codegen.cpp b/test/OpenMP/target_private_codegen.cpp
new file mode 100644
index 0000000000000..5c738ee5930f9
--- /dev/null
+++ b/test/OpenMP/target_private_codegen.cpp
@@ -0,0 +1,264 @@
+// Only test codegen on target side, as private clause does not require any action on the host side
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+template<typename tx, typename ty>
+struct TT{
+ tx X;
+ ty Y;
+};
+
+// TCHECK: [[TT:%.+]] = type { i64, i8 }
+// TCHECK: [[S1:%.+]] = type { double }
+
+int foo(int n) {
+ int a = 0;
+ short aa = 0;
+ float b[10];
+ float bn[n];
+ double c[5][10];
+ double cn[5][n];
+ TT<long long, char> d;
+
+ #pragma omp target private(a)
+ {
+ }
+
+ // TCHECK: define void @__omp_offloading_{{.+}}()
+ // TCHECK: [[A:%.+]] = alloca i{{[0-9]+}},
+ // TCHECK-NOT: store {{.+}}, {{.+}} [[A]],
+ // TCHECK: ret void
+
+#pragma omp target private(a)
+ {
+ a = 1;
+ }
+
+ // TCHECK: define void @__omp_offloading_{{.+}}()
+ // TCHECK: [[A:%.+]] = alloca i{{[0-9]+}},
+ // TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[A]],
+ // TCHECK: ret void
+
+ #pragma omp target private(a, aa)
+ {
+ a = 1;
+ aa = 1;
+ }
+
+ // TCHECK: define void @__omp_offloading_{{.+}}()
+ // TCHECK: [[A:%.+]] = alloca i{{[0-9]+}},
+ // TCHECK: [[A2:%.+]] = alloca i{{[0-9]+}},
+ // TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[A]],
+ // TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[A2]],
+ // TCHECK: ret void
+
+ #pragma omp target private(a, b, bn, c, cn, d)
+ {
+ a = 1;
+ b[2] = 1.0;
+ bn[3] = 1.0;
+ c[1][2] = 1.0;
+ cn[1][3] = 1.0;
+ d.X = 1;
+ d.Y = 1;
+ }
+ // make sure that private variables are generated in all cases and that we use those instances for operations inside the
+ // target region
+ // TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[VLA:%.+]], i{{[0-9]+}} [[VLA1:%.+]], i{{[0-9]+}} [[VLA3:%.+]])
+ // TCHECK: [[VLA_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // TCHECK: [[VLA_ADDR2:%.+]] = alloca i{{[0-9]+}},
+ // TCHECK: [[VLA_ADDR4:%.+]] = alloca i{{[0-9]+}},
+ // TCHECK: [[A:%.+]] = alloca i{{[0-9]+}},
+ // TCHECK: [[B:%.+]] = alloca [10 x float],
+ // TCHECK: [[SSTACK:%.+]] = alloca i8*,
+ // TCHECK: [[C:%.+]] = alloca [5 x [10 x double]],
+ // TCHECK: [[D:%.+]] = alloca [[TT]],
+ // TCHECK: store i{{[0-9]+}} [[VLA]], i{{[0-9]+}}* [[VLA_ADDR]],
+ // TCHECK: store i{{[0-9]+}} [[VLA1]], i{{[0-9]+}}* [[VLA_ADDR2]],
+ // TCHECK: store i{{[0-9]+}} [[VLA3]], i{{[0-9]+}}* [[VLA_ADDR4]],
+ // TCHECK: [[VLA_ADDR_REF:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[VLA_ADDR]],
+ // TCHECK: [[VLA_ADDR_REF2:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[VLA_ADDR2]],
+ // TCHECK: [[VLA_ADDR_REF4:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[VLA_ADDR4]],
+ // TCHECK: [[RET_STACK:%.+]] = call i8* @llvm.stacksave()
+ // TCHECK: store i8* [[RET_STACK]], i8** [[SSTACK]],
+ // TCHECK: [[VLA5:%.+]] = alloca float, i{{[0-9]+}} [[VLA_ADDR_REF]],
+ // TCHECK: [[VLA6_SIZE:%.+]] = mul{{.+}} i{{[0-9]+}} [[VLA_ADDR_REF2]], [[VLA_ADDR_REF4]]
+ // TCHECK: [[VLA6:%.+]] = alloca double, i{{[0-9]+}} [[VLA6_SIZE]],
+
+ // a = 1
+ // TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[A]],
+
+ // b[2] = 1.0
+ // TCHECK: [[B_GEP:%.+]] = getelementptr inbounds [10 x float], [10 x float]* [[B]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // TCHECK: store float 1.0{{.*}}, float* [[B_GEP]],
+
+ // bn[3] = 1.0
+ // TCHECK: [[BN_GEP:%.+]] = getelementptr inbounds float, float* [[VLA5]], i{{[0-9]+}} 3
+ // TCHECK: store float 1.0{{.*}}, float* [[BN_GEP]],
+
+ // c[1][2] = 1.0
+ // TCHECK: [[C_GEP1:%.+]] = getelementptr inbounds [5 x [10 x double]], [5 x [10 x double]]* [[C]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // TCHECK: [[C_GEP2:%.+]] = getelementptr inbounds [10 x double], [10 x double]* [[C_GEP1]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // TCHECK: store double 1.0{{.*}}, double* [[C_GEP2]],
+
+ // cn[1][3] = 1.0
+ // TCHECK: [[CN_IND:%.+]] = mul{{.+}} i{{[0-9]+}} 1, [[VLA_ADDR_REF4]]
+ // TCHECK: [[CN_GEP_IND:%.+]] = getelementptr inbounds double, double* [[VLA6]], i{{[0-9]+}} [[CN_IND]]
+ // TCHECK: [[CN_GEP_3:%.+]] = getelementptr inbounds double, double* [[CN_GEP_IND]], i{{[0-9]+}} 3
+ // TCHECK: store double 1.0{{.*}}, double* [[CN_GEP_3]],
+
+ // d.X = 1
+ // [[X_FIELD:%.+]] = getelementptr inbounds [[TT]] [[TT]]* [[D]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // store i{{[0-9]+}} 1, i{{[0-9]+}}* [[X_FIELD]],
+
+ // d.Y = 1
+ // [[Y_FIELD:%.+]] = getelementptr inbounds [[TT]] [[TT]]* [[D]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // store i{{[0-9]+}} 1, i{{[0-9]+}}* [[Y_FIELD]],
+
+ // finish
+ // [[RELOAD_SSTACK:%.+]] = load i8*, i8** [[SSTACK]],
+ // call ovid @llvm.stackrestore(i8* [[RELOAD_SSTACK]])
+ // ret void
+
+ return a;
+}
+
+
+template<typename tx>
+tx ftemplate(int n) {
+ tx a = 0;
+ short aa = 0;
+ tx b[10];
+
+#pragma omp target private(a,aa,b)
+ {
+ a = 1;
+ aa = 1;
+ b[2] = 1;
+ }
+
+ return a;
+}
+
+static
+int fstatic(int n) {
+ int a = 0;
+ short aa = 0;
+ char aaa = 0;
+ int b[10];
+
+#pragma omp target private(a,aa,aaa,b)
+ {
+ a = 1;
+ aa = 1;
+ aaa = 1;
+ b[2] = 1;
+ }
+
+ return a;
+}
+
+// TCHECK: define void @__omp_offloading_{{.+}}()
+// TCHECK: [[A:%.+]] = alloca i{{[0-9]+}},
+// TCHECK: [[A2:%.+]] = alloca i{{[0-9]+}},
+// TCHECK: [[A3:%.+]] = alloca i{{[0-9]+}},
+// TCHECK: [[B:%.+]] = alloca [10 x i{{[0-9]+}}],
+// TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[A]],
+// TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[A2]],
+// TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[A3]],
+// TCHECK: [[B_GEP:%.+]] = getelementptr inbounds [10 x i{{[0-9]+}}], [10 x i{{[0-9]+}}]* [[B]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[B_GEP]],
+// TCHECK: ret void
+
+struct S1 {
+ double a;
+
+ int r1(int n){
+ int b = n+1;
+ short int c[2][n];
+
+#pragma omp target private(b,c)
+ {
+ this->a = (double)b + 1.5;
+ c[1][1] = ++a;
+ }
+
+ return c[1][1] + (int)b;
+ }
+
+ // TCHECK: define void @__omp_offloading_{{.+}}([[S1]]* [[TH:%.+]], i{{[0-9]+}} [[VLA:%.+]], i{{[0-9]+}} [[VLA1:%.+]])
+ // TCHECK: [[TH_ADDR:%.+]] = alloca [[S1]]*,
+ // TCHECK: [[VLA_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // TCHECK: [[VLA_ADDR2:%.+]] = alloca i{{[0-9]+}},
+ // TCHECK: [[B:%.+]] = alloca i{{[0-9]+}},
+ // TCHECK: [[SSTACK:%.+]] = alloca i8*,
+ // TCHECK: store [[S1]]* [[TH]], [[S1]]** [[TH_ADDR]],
+ // TCHECK: store i{{[0-9]+}} [[VLA]], i{{[0-9]+}}* [[VLA_ADDR]],
+ // TCHECK: store i{{[0-9]+}} [[VLA1]], i{{[0-9]+}}* [[VLA_ADDR2]],
+ // TCHECK: [[TH_ADDR_REF:%.+]] = load [[S1]]*, [[S1]]** [[TH_ADDR]],
+ // TCHECK: [[VLA_ADDR_REF:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[VLA_ADDR]],
+ // TCHECK: [[VLA_ADDR_REF2:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[VLA_ADDR2]],
+ // TCHECK: [[RET_STACK:%.+]] = call i8* @llvm.stacksave()
+ // TCHECK: store i8* [[RET_STACK:%.+]], i8** [[SSTACK]],
+
+ // this->a = (double)b + 1.5;
+ // TCHECK: [[VLA_IND:%.+]] = mul{{.+}} i{{[0-9]+}} [[VLA_ADDR_REF]], [[VLA_ADDR_REF2]]
+ // TCHECK: [[VLA3:%.+]] = alloca i{{[0-9]+}}, i{{[0-9]+}} [[VLA_IND]],
+ // TCHECK: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B]],
+ // TCHECK: [[B_CONV:%.+]] = sitofp i{{[0-9]+}} [[B_VAL]] to double
+ // TCHECK: [[NEW_A_VAL:%.+]] = fadd double [[B_CONV]], 1.5{{.+}}+00
+ // TCHECK: [[A_FIELD:%.+]] = getelementptr inbounds [[S1]], [[S1]]* [[TH_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // TCHECK: store double [[NEW_A_VAL]], double* [[A_FIELD]],
+
+ // c[1][1] = ++a;
+ // TCHECK: [[A_FIELD4:%.+]] = getelementptr inbounds [[S1]], [[S1]]* [[TH_ADDR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // TCHECK: [[A_FIELD4_VAL:%.+]] = load double, double* [[A_FIELD4]],
+ // TCHECK: [[A_FIELD_INC:%.+]] = fadd double [[A_FIELD4_VAL]], 1.0{{.+}}+00
+ // TCHECK: store double [[A_FIELD_INC]], double* [[A_FIELD4]],
+ // TCHECK: [[A_FIELD_INC_CONV:%.+]] = fptosi double [[A_FIELD_INC]] to i{{[0-9]+}}
+ // TCHECK: [[C_IND:%.+]] = mul{{.+}} i{{[0-9]+}} 1, [[VLA_ADDR_REF2]]
+ // TCHECK: [[C_1_REF:%.+]] = getelementptr inbounds i{{[0-9]+}}, i{{[0-9]+}}* [[VLA3]], i{{[0-9]+}} [[C_IND]]
+ // TCHECK: [[C_1_1_REF:%.+]] = getelementptr inbounds i{{[0-9]+}}, i{{[0-9]+}}* [[C_1_REF]], i{{[0-9]+}} 1
+ // TCHECK: store i{{[0-9]+}} [[A_FIELD_INC_CONV]], i{{[0-9]+}}* [[C_1_1_REF]],
+
+ // finish
+ // TCHECK: [[RELOAD_SSTACK:%.+]] = load i8*, i8** [[SSTACK]],
+ // TCHECK: call void @llvm.stackrestore(i8* [[RELOAD_SSTACK]])
+ // TCHECK: ret void
+};
+
+
+int bar(int n){
+ int a = 0;
+ a += foo(n);
+ S1 S;
+ a += S.r1(n);
+ a += fstatic(n);
+ a += ftemplate<int>(n);
+
+ return a;
+}
+
+// template
+// TCHECK: define void @__omp_offloading_{{.+}}()
+// TCHECK: [[A:%.+]] = alloca i{{[0-9]+}},
+// TCHECK: [[A2:%.+]] = alloca i{{[0-9]+}},
+// TCHECK: [[B:%.+]] = alloca [10 x i{{[0-9]+}}],
+// TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[A]],
+// TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[A2]],
+// TCHECK: [[B_GEP:%.+]] = getelementptr inbounds [10 x i{{[0-9]+}}], [10 x i{{[0-9]+}}]* [[B]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// TCHECK: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[B_GEP]],
+// TCHECK: ret void
+
+#endif
diff --git a/test/OpenMP/target_private_messages.cpp b/test/OpenMP/target_private_messages.cpp
new file mode 100644
index 0000000000000..a093a87056272
--- /dev/null
+++ b/test/OpenMP/target_private_messages.cpp
@@ -0,0 +1,198 @@
+// RUN: %clang_cc1 -verify -fopenmp %s
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+
+public:
+ S2() : a(0) {}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+
+public:
+ S3() : a(0) {}
+};
+const S3 ca[5];
+class S4 {
+ int a;
+ S4(); // expected-note {{implicitly declared private here}}
+
+public:
+ S4(int v) : a(v) {
+#pragma omp target private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+};
+class S5 {
+ int a;
+ S5() : a(0) {} // expected-note {{implicitly declared private here}}
+
+public:
+ S5(int v) : a(v) {}
+ S5 &operator=(S5 &s) {
+#pragma omp target private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S6 {
+public:
+ T a;
+
+ S6() : a(0) {}
+ S6(T v) : a(v) {
+#pragma omp target private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+ S6 &operator=(S6 &s) {
+#pragma omp target private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S7 : public T {
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(T v) : a(v) {
+#pragma omp target private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp target private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(I argc, C **argv) {
+ I e(4);
+ I g(5);
+ int i;
+ int &j = i;
+#pragma omp target private // expected-error {{expected '(' after 'private'}}
+{}
+#pragma omp target private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+{}
+#pragma omp target private() // expected-error {{expected expression}}
+{}
+#pragma omp target private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+{}
+#pragma omp target private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+{}
+#pragma omp target private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+{}
+#pragma omp target private(argc)
+{}
+#pragma omp target private(S1) // expected-error {{'S1' does not refer to a value}}
+{}
+#pragma omp target private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+{}
+#pragma omp target private(argv[1]) // expected-error {{expected variable name}}
+{}
+#pragma omp target private(e, g)
+{}
+#pragma omp target private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+{}
+#pragma omp target shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp target'}}
+#pragma omp parallel
+ {
+ int v = 0;
+ int i;
+ }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp target private(j)
+{}
+#pragma omp target private(i)
+ {}
+ return 0;
+}
+
+void bar(S4 a[2]) {
+#pragma omp parallel
+#pragma omp target private(a)
+ {}
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ S4 e(4);
+ S5 g(5);
+ S6<float> s6(0.0) , s6_0(1.0);
+ S7<S6<float> > s7(0.0) , s7_0(1.0);
+ int i;
+ int &j = i;
+#pragma omp target private // expected-error {{expected '(' after 'private'}}
+{}
+#pragma omp target private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+{}
+#pragma omp target private() // expected-error {{expected expression}}
+{}
+#pragma omp target private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+{}
+#pragma omp target private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+{}
+#pragma omp target private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+{}
+#pragma omp target private(argc)
+{}
+#pragma omp target private(S1) // expected-error {{'S1' does not refer to a value}}
+{}
+#pragma omp target private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+{}
+#pragma omp target private(argv[1]) // expected-error {{expected variable name}}
+{}
+#pragma omp target private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}}
+{}
+#pragma omp target private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+{}
+#pragma omp target private(B::x) // expected-error {{threadprivate or thread local variable cannot be private}}
+{}
+#pragma omp target shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp target'}}
+#pragma omp parallel
+ {
+ int i;
+ }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp target private(j)
+{}
+#pragma omp target private(i)
+ {}
+ static int si;
+#pragma omp target private(si) // OK
+ {}
+#pragma omp target map(i) private(i) // expected-error {{private variable cannot be in a map clause in '#pragma omp target' directive}}
+ {}
+ s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}}
+ s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}}
+ return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
+}
+
diff --git a/test/OpenMP/target_update_ast_print.cpp b/test/OpenMP/target_update_ast_print.cpp
new file mode 100644
index 0000000000000..3a98f54a0770f
--- /dev/null
+++ b/test/OpenMP/target_update_ast_print.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+template <class T, class U>
+T foo(T targ, U uarg) {
+ static T a;
+ U b;
+ int l;
+#pragma omp target update to(a) if(l>5) device(l) nowait depend(inout:l)
+
+#pragma omp target update from(b) if(l<5) device(l-1) nowait depend(inout:l)
+ return a + targ + (T)b;
+}
+// CHECK: static int a;
+// CHECK-NEXT: float b;
+// CHECK-NEXT: int l;
+// CHECK-NEXT: #pragma omp target update to(a) if(l > 5) device(l) nowait depend(inout : l)
+// CHECK-NEXT: #pragma omp target update from(b) if(l < 5) device(l - 1) nowait depend(inout : l)
+// CHECK: static char a;
+// CHECK-NEXT: float b;
+// CHECK-NEXT: int l;
+// CHECK-NEXT: #pragma omp target update to(a) if(l > 5) device(l) nowait depend(inout : l)
+// CHECK-NEXT: #pragma omp target update from(b) if(l < 5) device(l - 1) nowait depend(inout : l)
+// CHECK: static T a;
+// CHECK-NEXT: U b;
+// CHECK-NEXT: int l;
+// CHECK-NEXT: #pragma omp target update to(a) if(l > 5) device(l) nowait depend(inout : l)
+// CHECK-NEXT: #pragma omp target update from(b) if(l < 5) device(l - 1) nowait depend(inout : l)
+
+int main(int argc, char **argv) {
+ static int a;
+ int n;
+ float f;
+
+// CHECK: static int a;
+// CHECK-NEXT: int n;
+// CHECK-NEXT: float f;
+#pragma omp target update to(a) if(f>0.0) device(n) nowait depend(in:n)
+// CHECK-NEXT: #pragma omp target update to(a) if(f > 0.) device(n) nowait depend(in : n)
+#pragma omp target update from(f) if(f<0.0) device(n+1) nowait depend(in:n)
+// CHECK-NEXT: #pragma omp target update from(f) if(f < 0.) device(n + 1) nowait depend(in : n)
+ return foo(argc, f) + foo(argv[0][0], f) + a;
+}
+
+#endif
diff --git a/test/OpenMP/target_update_codegen.cpp b/test/OpenMP/target_update_codegen.cpp
new file mode 100644
index 0000000000000..f74ed49975374
--- /dev/null
+++ b/test/OpenMP/target_update_codegen.cpp
@@ -0,0 +1,245 @@
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+///==========================================================================///
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+#ifdef CK1
+
+// CK1: [[ST:%.+]] = type { i32, double* }
+template <typename T>
+struct ST {
+ T a;
+ double *b;
+};
+
+ST<int> gb;
+double gc[100];
+
+// CK1: [[SIZE00:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 800]
+// CK1: [[MTYPE00:@.+]] = {{.+}}constant [1 x i32] [i32 34]
+
+// CK1: [[SIZE02:@.+]] = {{.+}}constant [1 x i[[sz]]] [i[[sz]] 4]
+// CK1: [[MTYPE02:@.+]] = {{.+}}constant [1 x i32] [i32 33]
+
+// CK1: [[MTYPE03:@.+]] = {{.+}}constant [1 x i32] [i32 34]
+
+// CK1: [[SIZE04:@.+]] = {{.+}}constant [2 x i[[sz]]] [i[[sz]] {{8|4}}, i[[sz]] 24]
+// CK1: [[MTYPE04:@.+]] = {{.+}}constant [2 x i32] [i32 33, i32 17]
+
+// CK1-LABEL: _Z3fooi
+void foo(int arg) {
+ int la;
+ float lb[arg];
+
+ // Region 00
+ // CK1-DAG: call void @__tgt_target_data_update(i32 [[DEV:%[^,]+]], i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00]]{{.+}})
+ // CK1-DAG: [[DEV]] = load i32, i32* %{{[^,]+}},
+ // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: store i8* bitcast ([100 x double]* @gc to i8*), i8** [[BP0]]
+ // CK1-DAG: store i8* bitcast ([100 x double]* @gc to i8*), i8** [[P0]]
+
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ #pragma omp target update if(1+3-5) device(arg) from(gc)
+ {++arg;}
+
+ // Region 01
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ #pragma omp target update to(la) if(1+3-4)
+ {++arg;}
+
+ // Region 02
+ // CK1: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+ // CK1: [[IFTHEN]]
+ // CK1-DAG: call void @__tgt_target_data_update(i32 4, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE02]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE02]]{{.+}})
+ // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK1-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK1-DAG: [[CBPVAL0]] = bitcast i32* [[VAR0:%.+]] to i8*
+ // CK1-DAG: [[CPVAL0]] = bitcast i32* [[VAR0]] to i8*
+ // CK1: br label %[[IFEND:[^,]+]]
+
+ // CK1: [[IFELSE]]
+ // CK1: br label %[[IFEND]]
+ // CK1: [[IFEND]]
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ #pragma omp target update to(arg) if(arg) device(4)
+ {++arg;}
+
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ {++arg;}
+
+ // Region 03
+ // CK1-DAG: call void @__tgt_target_data_update(i32 -1, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i[[sz]]* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE03]]{{.+}})
+ // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+ // CK1-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]]
+
+ // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+ // CK1-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+ // CK1-DAG: store i[[sz]] [[CSVAL0:%[^,]+]], i[[sz]]* [[S0]]
+ // CK1-DAG: [[CBPVAL0]] = bitcast float* [[VAR0:%.+]] to i8*
+ // CK1-DAG: [[CPVAL0]] = bitcast float* [[VAR0]] to i8*
+ // CK1-DAG: [[CSVAL0]] = mul nuw i[[sz]] %{{[^,]+}}, 4
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ // CK1-NOT: __tgt_target_data_end
+ #pragma omp target update from(lb)
+ {++arg;}
+
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ {++arg;}
+
+ // Region 04
+ // CK1-DAG: call void @__tgt_target_data_update(i32 -1, i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE04]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE04]]{{.+}})
+ // CK1-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+ // CK1-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+ // CK1-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+ // CK1-DAG: store i8* bitcast ([[ST]]* @gb to i8*), i8** [[BP0]]
+ // CK1-DAG: store i8* bitcast (double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1) to i8*), i8** [[P0]]
+
+
+ // CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+ // CK1-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+ // CK1-DAG: store i8* bitcast (double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1) to i8*), i8** [[BP1]]
+ // CK1-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+ // CK1-DAG: [[CPVAL1]] = bitcast double* [[SEC1:%.+]] to i8*
+ // CK1-DAG: [[SEC1]] = getelementptr inbounds {{.+}}double* [[SEC11:%[^,]+]], i{{.+}} 0
+ // CK1-DAG: [[SEC11]] = load double*, double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1),
+
+ // CK1: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ // CK1-NOT: __tgt_target_data_end
+ #pragma omp target update to(gb.b[:3])
+ {++arg;}
+}
+#endif
+///==========================================================================///
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+#ifdef CK2
+
+// CK2: [[ST:%.+]] = type { i32, double* }
+template <typename T>
+struct ST {
+ T a;
+ double *b;
+
+ T foo(T arg) {
+ // Region 00
+ #pragma omp target update from(b[1:3]) if(a>123) device(arg)
+ {arg++;}
+ return arg;
+ }
+};
+
+// CK2: [[SIZE00:@.+]] = {{.+}}constant [2 x i[[sz:64|32]]] [i{{64|32}} {{8|4}}, i{{64|32}} 24]
+// CK2: [[MTYPE00:@.+]] = {{.+}}constant [2 x i32] [i32 34, i32 18]
+
+// CK2-LABEL: _Z3bari
+int bar(int arg){
+ ST<int> A;
+ return A.foo(arg);
+}
+
+// Region 00
+// CK2: br i1 %{{[^,]+}}, label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
+// CK2: [[IFTHEN]]
+// CK2-DAG: call void @__tgt_target_data_update(i32 [[DEV:%[^,]+]], i32 2, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[SIZE00]], {{.+}}getelementptr {{.+}}[2 x i{{.+}}]* [[MTYPE00]]{{.+}})
+// CK2-DAG: [[DEV]] = load i32, i32* %{{[^,]+}},
+// CK2-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
+// CK2-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
+
+// CK2-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0
+// CK2-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0
+// CK2-DAG: store i8* [[CBPVAL0:%[^,]+]], i8** [[BP0]]
+// CK2-DAG: store i8* [[CPVAL0:%[^,]+]], i8** [[P0]]
+// CK2-DAG: [[CBPVAL0]] = bitcast [[ST]]* [[VAR0:%.+]] to i8*
+// CK2-DAG: [[CPVAL0]] = bitcast double** [[SEC0:%[^,]+]] to i8*
+// CK2-DAG: [[SEC0]] = getelementptr inbounds {{.*}}[[ST]]* [[VAR0]], i32 0, i32 1
+
+
+// CK2-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
+// CK2-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
+// CK2-DAG: store i8* [[CBPVAL1:%[^,]+]], i8** [[BP1]]
+// CK2-DAG: store i8* [[CPVAL1:%[^,]+]], i8** [[P1]]
+// CK2-DAG: [[CBPVAL1]] = bitcast double** [[SEC0]] to i8*
+// CK2-DAG: [[CPVAL1]] = bitcast double* [[SEC1:%[^,]+]] to i8*
+// CK2-DAG: [[SEC1]] = getelementptr inbounds {{.*}}double* [[SEC11:%[^,]+]], i{{.+}} 1
+// CK2-DAG: [[SEC11]] = load double*, double** [[SEC111:%[^,]+]],
+// CK2-DAG: [[SEC111]] = getelementptr inbounds {{.*}}[[ST]]* [[VAR0]], i32 0, i32 1
+
+// CK2: br label %[[IFEND:[^,]+]]
+
+// CK2: [[IFELSE]]
+// CK2: br label %[[IFEND]]
+// CK2: [[IFEND]]
+// CK2: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+#endif
+///==========================================================================///
+// RUN: %clang_cc1 -DCK3 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64
+// RUN: %clang_cc1 -DCK3 -verify -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32
+#ifdef CK3
+
+// CK3-LABEL: no_target_devices
+void no_target_devices(int arg) {
+ // CK3-NOT: tgt_target_data_update
+ // CK3: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ // CK3: ret
+ #pragma omp target update to(arg) if(arg) device(4)
+ {++arg;}
+}
+#endif
+///==========================================================================///
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64
+// RUN: %clang_cc1 -DCK4 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32
+// RUN: %clang_cc1 -DCK4 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32
+
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCK4 --check-prefix TCK4-64
+// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCK4 --check-prefix TCK4-64
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCK4 --check-prefix TCK4-32
+// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCK4 --check-prefix TCK4-32
+#ifdef CK4
+
+// CK4-LABEL: device_side_scan
+void device_side_scan(int arg) {
+ // CK4: tgt_target_data_update
+ // CK4: %{{.+}} = add nsw i32 %{{[^,]+}}, 1
+ // CK4: ret
+ // TCK4-NOT: tgt_target_data_update
+ #pragma omp target update from(arg) if(arg) device(4)
+ {++arg;}
+}
+#endif
+#endif
diff --git a/test/OpenMP/target_update_depend_messages.cpp b/test/OpenMP/target_update_depend_messages.cpp
new file mode 100644
index 0000000000000..fe3325d80fe47
--- /dev/null
+++ b/test/OpenMP/target_update_depend_messages.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+
+class vector {
+ public:
+ int operator[](int index) { return 0; }
+};
+
+template <class T, class S, class R>
+int tmain(T argc, S **argv, R *env[]) {
+ vector vec;
+ typedef float V __attribute__((vector_size(16)));
+ V a;
+ char *arr;
+ int i, z;
+
+ #pragma omp depend target update to(z) // expected-error{{expected an OpenMP directive}}
+ #pragma omp depend(out:argc) target update to(z) // expected-error{{expected an OpenMP directive}}
+ #pragma omp target depend(in:argc) update to(z) // expected-error{{unexpected OpenMP clause 'update' in directive '#pragma omp target'}} expected-error{{unexpected OpenMP clause 'to' in directive '#pragma omp target'}}
+ {}
+
+ #pragma omp target update to(z) depend // expected-error {{expected '(' after 'depend'}}
+ #pragma omp target update to(z) depend( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target update to(z) depend() // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target update to(z) depend(argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target update to(z) depend(source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+ #pragma omp target update to(z) depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target update to(z) depend(in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
+ #pragma omp target update to(z) depend(out: ) // expected-error {{expected expression}}
+ #pragma omp target update to(z) depend(inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+ #pragma omp target update to(z) depend(out :S1) // expected-error {{'S1' does not refer to a value}}
+ #pragma omp target update to(z) depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target update to(z) depend(in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target update to(z) depend(in : argv[0])
+ #pragma omp target update to(z) depend(in : ) // expected-error {{expected expression}}
+ #pragma omp target update to(z) depend(in : tmain) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target update to(z) depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+ #pragma omp target update to(z) depend(in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
+ #pragma omp target update to(z) depend(in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ #pragma omp target update to(z) depend(in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ #pragma omp target update to(z) depend(in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target update to(z) depend(in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ #pragma omp target update to(z) depend(in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target update to(z) depend(in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}}
+ #pragma omp target update to(z) depend(in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}}
+ #pragma omp target update to(z) depend(in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ #pragma omp target update to(z) depend(in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}}
+ #pragma omp target update to(z) depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}}
+ #pragma omp target update to(z) depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}}
+ #pragma omp target update to(z) depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ #pragma omp target update to(z) depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}}
+ #pragma omp target update to(z) depend(in : argv[ : argc][1 : argc - 1])
+ #pragma omp target update to(z) depend(in : arr[0])
+
+ return 0;
+}
+
+int main(int argc, char **argv, char *env[]) {
+ vector vec;
+ typedef float V __attribute__((vector_size(16)));
+ V a;
+ auto arr = x; // expected-error {{use of undeclared identifier 'x'}}
+ int z;
+
+ #pragma omp depend target update to(z) // expected-error{{expected an OpenMP directive}}
+ #pragma omp depend(out:argc) target update to(z) // expected-error{{expected an OpenMP directive}}
+ #pragma omp target depend(in:argc) update to(z) // expected-error{{unexpected OpenMP clause 'update' in directive '#pragma omp target'}} expected-error{{unexpected OpenMP clause 'to' in directive '#pragma omp target'}}
+ {}
+
+ #pragma omp target update to(z) depend // expected-error {{expected '(' after 'depend'}}
+ #pragma omp target update to(z) depend( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target update to(z) depend() // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target update to(z) depend(argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target update to(z) depend(source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+ #pragma omp target update to(z) depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target update to(z) depend(in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
+ #pragma omp target update to(z) depend(out: ) // expected-error {{expected expression}}
+ #pragma omp target update to(z) depend(inout : foobool(argc)), depend (in, argc) // expected-error {{expected variable name, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
+ #pragma omp target update to(z) depend(out :S1) // expected-error {{'S1' does not refer to a value}}
+ #pragma omp target update to(z) depend(in : argv[1][1] = '2') // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target update to(z) depend(in : vec[1]) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target update to(z) depend(in : argv[0])
+ #pragma omp target update to(z) depend(in : ) // expected-error {{expected expression}}
+ #pragma omp target update to(z) depend(in : main) // expected-error {{expected variable name, array element or array section}}
+ #pragma omp target update to(z) depend(in : a[0]) // expected-error{{expected variable name, array element or array section}}
+ #pragma omp target update to(z) depend(in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
+ #pragma omp target update to(z) depend(in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ #pragma omp target update to(z) depend(in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ #pragma omp target update to(z) depend(in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target update to(z) depend(in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
+ #pragma omp target update to(z) depend(in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target update to(z) depend(in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}}
+ #pragma omp target update to(z) depend(in : argv[-1:0]) // expected-error {{section lower bound is evaluated to a negative value -1}}
+ #pragma omp target update to(z) depend(in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ #pragma omp target update to(z) depend(in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}}
+ #pragma omp target update to(z) depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}}
+ #pragma omp target update to(z) depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}}
+ #pragma omp target update to(z) depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+ #pragma omp target update to(z) depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}}
+ #pragma omp target update to(z) depend(in : argv[ : argc][1 : argc - 1])
+ #pragma omp target update to(z) depend(in : arr[0])
+
+ return tmain(argc, argv, env); // expected-note {{in instantiation of function template specialization 'tmain<int, char, char>' requested here}}
+}
diff --git a/test/OpenMP/target_update_device_messages.cpp b/test/OpenMP/target_update_device_messages.cpp
new file mode 100644
index 0000000000000..37112755805cc
--- /dev/null
+++ b/test/OpenMP/target_update_device_messages.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+
+template <class T, class S>
+int tmain(T argc, S **argv) {
+ int i;
+#pragma omp target update to(i) device // expected-error {{expected '(' after 'device'}}
+#pragma omp target update to(i) device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target update to(i) device () // expected-error {{expected expression}}
+#pragma omp target update to(i) device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target update to(i) device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
+#pragma omp target update from(i) device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp target update from(i) device (argc + argc)
+#pragma omp target update from(i) device (argc), device (argc+1) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'device' clause}}
+#pragma omp target update from(i) device (S1) // expected-error {{'S1' does not refer to a value}}
+#pragma omp target update from(i) device (3.14) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'double'}}
+#pragma omp target update from(i) device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}}
+}
+
+int main(int argc, char **argv) {
+ int j;
+#pragma omp target update to(j) device // expected-error {{expected '(' after 'device'}}
+#pragma omp target update from(j) device ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target update to(j) device () // expected-error {{expected expression}}
+#pragma omp target update from(j) device (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target update to(j) device (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
+#pragma omp target update from(j) device (argc > 0 ? argv[1] : argv[2]) // expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+#pragma omp target update to(j) device (argc + argc)
+#pragma omp target update from(j) device (argc), device (argc+1) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'device' clause}}
+#pragma omp target update to(j) device (S1) // expected-error {{'S1' does not refer to a value}}
+#pragma omp target update from(j) device (-2) // expected-error {{argument to 'device' clause must be a non-negative integer value}}
+#pragma omp target update to(j) device (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
+
+ return tmain(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char>' requested here}}
+}
diff --git a/test/OpenMP/target_update_from_messages.cpp b/test/OpenMP/target_update_from_messages.cpp
new file mode 100644
index 0000000000000..6aff083b6a487
--- /dev/null
+++ b/test/OpenMP/target_update_from_messages.cpp
@@ -0,0 +1,176 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+extern S1 a;
+class S2 {
+ mutable int a;
+public:
+ S2():a(0) { }
+ S2(S2 &s2):a(s2.a) { }
+ static float S2s; // expected-note 4 {{mappable type cannot contain static members}}
+ static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}}
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+public:
+ S3():a(0) { }
+ S3(S3 &s3):a(s3.a) { }
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 {
+ int a;
+ S4();
+ S4(const S4 &s4);
+public:
+ S4(int v):a(v) { }
+};
+class S5 {
+ int a;
+ S5():a(0) {}
+ S5(const S5 &s5):a(s5.a) { }
+public:
+ S5(int v):a(v) { }
+};
+struct S6 {
+ int ii;
+ int aa[30];
+ float xx;
+ double *pp;
+};
+struct S7 {
+ int i;
+ int a[50];
+ float x;
+ S6 s6[5];
+ double *p;
+ unsigned bfa : 4;
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+typedef int to;
+
+template <typename T, int I> // expected-note {{declared here}}
+T tmain(T argc) {
+ const T d = 5;
+ const T da[5] = { 0 };
+ S4 e(4);
+ S5 g(5);
+ T i, t[20];
+ T &j = i;
+ T *k = &j;
+ T x;
+ T y;
+ T from;
+ const T (&l)[5] = da;
+ T *m;
+ S7 s7;
+
+#pragma omp target update from // expected-error {{expected '(' after 'from'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from() // expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update() // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(alloc) // expected-error {{use of undeclared identifier 'alloc'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(x)
+#pragma omp target update from(t[:I])
+#pragma omp target update from(T) // expected-error {{'T' does not refer to a value}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
+#pragma omp target update from(S2::S2s)
+#pragma omp target update from(S2::S2sc)
+#pragma omp target update from(from)
+#pragma omp target update from(y x) // expected-error {{expected ',' or ')' in 'from' clause}}
+#pragma omp target update from(argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
+#pragma omp target update from(S1) // expected-error {{'S1' does not refer to a value}}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target update from(ba) // expected-error 2 {{type 'S2' is not mappable to target}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(h) // expected-error {{threadprivate variables are not allowed in 'from' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(k), to(k) // expected-error 2 {{variable can appear only once in OpenMP 'target update' construct}} expected-note 2 {{used here}}
+#pragma omp target update from(t), from(t[:5]) // expected-error 2 {{variable can appear only once in OpenMP 'target update' construct}} expected-note 2 {{used here}}
+#pragma omp target update from(da)
+#pragma omp target update from(da[:4])
+
+#pragma omp target update from(x, a[:2]) // expected-error {{subscripted value is not an array or pointer}}
+#pragma omp target update from(x, c[:]) // expected-error {{subscripted value is not an array or pointer}}
+#pragma omp target update from(x, (m+1)[2]) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
+#pragma omp target update from(s7.i, s7.a[:3])
+#pragma omp target update from(s7.s6[1].aa[0:5])
+#pragma omp target update from(x, s7.s6[:5].aa[6]) // expected-error {{OpenMP array section is not allowed here}}
+#pragma omp target update from(x, s7.s6[:5].aa[:6]) // expected-error {{OpenMP array section is not allowed here}}
+#pragma omp target update from(s7.p[:10])
+#pragma omp target update from(x, s7.bfa) // expected-error {{bit fields cannot be used to specify storage in a 'from' clause}}
+#pragma omp target update from(x, s7.p[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+#pragma omp target data map(to: s7.i)
+ {
+#pragma omp target update from(s7.x)
+ }
+
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5;
+ const int da[5] = { 0 };
+ S4 e(4);
+ S5 g(5);
+ int i, t[20];
+ int &j = i;
+ int *k = &j;
+ int x;
+ int y;
+ int from;
+ const int (&l)[5] = da;
+ int *m;
+ S7 s7;
+
+#pragma omp target update from // expected-error {{expected '(' after 'from'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from() // expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update() // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(alloc) // expected-error {{use of undeclared identifier 'alloc'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(x)
+#pragma omp target update from(t[:i])
+#pragma omp target update from(S2::S2s)
+#pragma omp target update from(S2::S2sc)
+#pragma omp target update from(from)
+#pragma omp target update from(y x) // expected-error {{expected ',' or ')' in 'from' clause}}
+#pragma omp target update from(argc > 0 ? x : y) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(S1) // expected-error {{'S1' does not refer to a value}}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target update from(ba) // expected-error 2 {{type 'S2' is not mappable to target}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(h) // expected-error {{threadprivate variables are not allowed in 'from' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(k), to(k) // expected-error {{variable can appear only once in OpenMP 'target update' construct}} expected-note {{used here}}
+#pragma omp target update from(t), from(t[:5]) // expected-error {{variable can appear only once in OpenMP 'target update' construct}} expected-note {{used here}}
+#pragma omp target update from(da)
+#pragma omp target update from(da[:4])
+
+#pragma omp target update from(x, a[:2]) // expected-error {{subscripted value is not an array or pointer}}
+#pragma omp target update from(x, c[:]) // expected-error {{subscripted value is not an array or pointer}}
+#pragma omp target update from(x, (m+1)[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}}
+#pragma omp target update from(s7.i, s7.a[:3])
+#pragma omp target update from(s7.s6[1].aa[0:5])
+#pragma omp target update from(x, s7.s6[:5].aa[6]) // expected-error {{OpenMP array section is not allowed here}}
+#pragma omp target update from(x, s7.s6[:5].aa[:6]) // expected-error {{OpenMP array section is not allowed here}}
+#pragma omp target update from(s7.p[:10])
+#pragma omp target update from(x, s7.bfa) // expected-error {{bit fields cannot be used to specify storage in a 'from' clause}}
+#pragma omp target update from(x, s7.p[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+#pragma omp target data map(to: s7.i)
+ {
+#pragma omp target update from(s7.x)
+ }
+
+ return tmain<int, 3>(argc)+tmain<to, 4>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<int, 4>' requested here}}
+}
+
diff --git a/test/OpenMP/target_update_if_messages.cpp b/test/OpenMP/target_update_if_messages.cpp
new file mode 100644
index 0000000000000..97715e072422a
--- /dev/null
+++ b/test/OpenMP/target_update_if_messages.cpp
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, class S> // expected-note {{declared here}}
+int tmain(T argc, S **argv) {
+ int n;
+#pragma omp target update to(n) if // expected-error {{expected '(' after 'if'}}
+#pragma omp target update from(n) if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target update to(n) if () // expected-error {{expected expression}}
+#pragma omp target update from(n) if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target update to(n) if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
+#pragma omp target update from(n) if (argc > 0 ? argv[1] : argv[2])
+#pragma omp target update to(n) if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'if' clause}}
+#pragma omp target update from(n) if (S) // expected-error {{'S' does not refer to a value}}
+#pragma omp target update to(n) if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target update from(n) if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target update to(n) if(argc)
+#pragma omp target update from(n) if(target update // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target update to(n) if(target update : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target update from(n) if(target update : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target update to(n) if(target update : argc)
+#pragma omp target update from(n) if(target update : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target update'}}
+#pragma omp target update to(n) if(target update : argc) if (target update:argc) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'if' clause with 'target update' name modifier}}
+#pragma omp target update from(n) if(target update : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}}
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ int m;
+#pragma omp target update to(m) if // expected-error {{expected '(' after 'if'}}
+#pragma omp target update from(m) if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target update to(m) if () // expected-error {{expected expression}}
+#pragma omp target update from(m) if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target update to(m) if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
+#pragma omp target update from(m) if (argc > 0 ? argv[1] : argv[2])
+#pragma omp target update to(m) if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'if' clause}}
+#pragma omp target update from(m) if (S1) // expected-error {{'S1' does not refer to a value}}
+#pragma omp target update to(m) if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target update from(m) if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target update to(m) if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target update from(m) if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target update to(m) if(target update // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target update from(m) if(target update : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target update to(m) if(target update : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target update from(m) if(target update : argc)
+#pragma omp target update to(m) if(target update : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target update'}}
+#pragma omp target update from(m) if(target update : argc) if (target update:argc) // expected-error {{directive '#pragma omp target update' cannot contain more than one 'if' clause with 'target update' name modifier}}
+#pragma omp target update to(m) if(target update : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}}
+ return tmain(argc, argv);
+}
diff --git a/test/OpenMP/target_update_messages.cpp b/test/OpenMP/target_update_messages.cpp
new file mode 100644
index 0000000000000..73f1eeca8efec
--- /dev/null
+++ b/test/OpenMP/target_update_messages.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // Aexpected-note {{declared here}}
+
+template <class T, class S> // Aexpected-note {{declared here}}
+int tmain(T argc, S **argv) {
+ int n;
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ int m;
+ #pragma omp target update // expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ #pragma omp target update to(m) { // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
+ #pragma omp target update to(m) ( // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
+ #pragma omp target update to(m) [ // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
+ #pragma omp target update to(m) ] // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
+ #pragma omp target update to(m) ) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
+
+ #pragma omp target update from(m) // OK
+ {
+ foo();
+ }
+ return tmain(argc, argv);
+}
diff --git a/test/OpenMP/target_update_nowait_messages.cpp b/test/OpenMP/target_update_nowait_messages.cpp
new file mode 100644
index 0000000000000..19bc58ea467e6
--- /dev/null
+++ b/test/OpenMP/target_update_nowait_messages.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+int main(int argc, char **argv) {
+ int i;
+
+ #pragma omp nowait target update to(i) // expected-error {{expected an OpenMP directive}}
+ #pragma omp target nowait update to(i) // expected-error {{unexpected OpenMP clause 'update' in directive '#pragma omp target'}} expected-error {{unexpected OpenMP clause 'to' in directive '#pragma omp target'}}
+ {}
+ #pragma omp target update nowait() to(i) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+ #pragma omp target update to(i) nowait( // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
+ #pragma omp target update to(i) nowait (argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
+ #pragma omp target update to(i) nowait device (-10u)
+ #pragma omp target update to(i) nowait (3.14) device (-10u) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
+ #pragma omp target update to(i) nowait nowait // expected-error {{directive '#pragma omp target update' cannot contain more than one 'nowait' clause}}
+ #pragma omp target update nowait to(i) nowait // expected-error {{directive '#pragma omp target update' cannot contain more than one 'nowait' clause}}
+ return 0;
+}
diff --git a/test/OpenMP/target_update_to_messages.cpp b/test/OpenMP/target_update_to_messages.cpp
new file mode 100644
index 0000000000000..641d0bd949a2c
--- /dev/null
+++ b/test/OpenMP/target_update_to_messages.cpp
@@ -0,0 +1,175 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+extern S1 a;
+class S2 {
+ mutable int a;
+public:
+ S2():a(0) { }
+ S2(S2 &s2):a(s2.a) { }
+ static float S2s; // expected-note 4 {{mappable type cannot contain static members}}
+ static const float S2sc; // expected-note 4 {{mappable type cannot contain static members}}
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+ int a;
+public:
+ S3():a(0) { }
+ S3(S3 &s3):a(s3.a) { }
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 {
+ int a;
+ S4();
+ S4(const S4 &s4);
+public:
+ S4(int v):a(v) { }
+};
+class S5 {
+ int a;
+ S5():a(0) {}
+ S5(const S5 &s5):a(s5.a) { }
+public:
+ S5(int v):a(v) { }
+};
+struct S6 {
+ int ii;
+ int aa[30];
+ float xx;
+ double *pp;
+};
+struct S7 {
+ int i;
+ int a[50];
+ float x;
+ S6 s6[5];
+ double *p;
+ unsigned bfa : 4;
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+typedef int from;
+
+template <typename T, int I> // expected-note {{declared here}}
+T tmain(T argc) {
+ const T d = 5;
+ const T da[5] = { 0 };
+ S4 e(4);
+ S5 g(5);
+ T *m;
+ T i, t[20];
+ T &j = i;
+ T *k = &j;
+ T x;
+ T y;
+ T to;
+ const T (&l)[5] = da;
+ S7 s7;
+
+#pragma omp target update to // expected-error {{expected '(' after 'to'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to() // expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update() // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(alloc) // expected-error {{use of undeclared identifier 'alloc'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(x)
+#pragma omp target update to(t[:I])
+#pragma omp target update to(T) // expected-error {{'T' does not refer to a value}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
+#pragma omp target update to(S2::S2s)
+#pragma omp target update to(S2::S2sc)
+#pragma omp target update to(to)
+#pragma omp target update to(y x) // expected-error {{expected ',' or ')' in 'to' clause}}
+#pragma omp target update to(argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
+#pragma omp target update to(S1) // expected-error {{'S1' does not refer to a value}}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target update to(ba) // expected-error 2 {{type 'S2' is not mappable to target}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(h) // expected-error {{threadprivate variables are not allowed in 'to' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(k), from(k) // expected-error 2 {{variable can appear only once in OpenMP 'target update' construct}} expected-note 2 {{used here}}
+#pragma omp target update to(t), to(t[:5]) // expected-error 2 {{variable can appear only once in OpenMP 'target update' construct}} expected-note 2 {{used here}}
+#pragma omp target update to(da)
+#pragma omp target update to(da[:4])
+
+#pragma omp target update to(x, a[:2]) // expected-error {{subscripted value is not an array or pointer}}
+#pragma omp target update to(x, c[:]) // expected-error {{subscripted value is not an array or pointer}}
+#pragma omp target update to(x, (m+1)[2]) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}}
+#pragma omp target update to(s7.i, s7.a[:3])
+#pragma omp target update to(s7.s6[1].aa[0:5])
+#pragma omp target update to(x, s7.s6[:5].aa[6]) // expected-error {{OpenMP array section is not allowed here}}
+#pragma omp target update to(x, s7.s6[:5].aa[:6]) // expected-error {{OpenMP array section is not allowed here}}
+#pragma omp target update to(s7.p[:10])
+#pragma omp target update to(x, s7.bfa) // expected-error {{bit fields cannot be used to specify storage in a 'to' clause}}
+#pragma omp target update to(x, s7.p[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+#pragma omp target data map(to: s7.i)
+ {
+#pragma omp target update to(s7.x)
+ }
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5;
+ const int da[5] = { 0 };
+ S4 e(4);
+ S5 g(5);
+ int i, t[20];
+ int &j = i;
+ int *k = &j;
+ int x;
+ int y;
+ int to;
+ const int (&l)[5] = da;
+ S7 s7;
+ int *m;
+
+#pragma omp target update to // expected-error {{expected '(' after 'to'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to() // expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update() // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(alloc) // expected-error {{use of undeclared identifier 'alloc'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(x)
+#pragma omp target update to(t[:i])
+#pragma omp target update to(S2::S2s)
+#pragma omp target update to(S2::S2sc)
+#pragma omp target update to(to)
+#pragma omp target update to(y x) // expected-error {{expected ',' or ')' in 'to' clause}}
+#pragma omp target update to(argc > 0 ? x : y) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(S1) // expected-error {{'S1' does not refer to a value}}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}}
+#pragma omp target update to(ba) // expected-error 2 {{type 'S2' is not mappable to target}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(h) // expected-error {{threadprivate variables are not allowed in 'to' clause}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(k), from(k) // expected-error {{variable can appear only once in OpenMP 'target update' construct}} expected-note {{used here}}
+#pragma omp target update to(t), to(t[:5]) // expected-error {{variable can appear only once in OpenMP 'target update' construct}} expected-note {{used here}}
+#pragma omp target update to(da)
+#pragma omp target update to(da[:4])
+
+#pragma omp target update to(x, a[:2]) // expected-error {{subscripted value is not an array or pointer}}
+#pragma omp target update to(x, c[:]) // expected-error {{subscripted value is not an array or pointer}}
+#pragma omp target update to(x, (m+1)[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}}
+#pragma omp target update to(s7.i, s7.a[:3])
+#pragma omp target update to(s7.s6[1].aa[0:5])
+#pragma omp target update to(x, s7.s6[:5].aa[6]) // expected-error {{OpenMP array section is not allowed here}}
+#pragma omp target update to(x, s7.s6[:5].aa[:6]) // expected-error {{OpenMP array section is not allowed here}}
+#pragma omp target update to(s7.p[:10])
+#pragma omp target update to(x, s7.bfa) // expected-error {{bit fields cannot be used to specify storage in a 'to' clause}}
+#pragma omp target update to(x, s7.p[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
+#pragma omp target data map(to: s7.i)
+ {
+#pragma omp target update to(s7.x)
+ }
+
+ return tmain<int, 3>(argc)+tmain<from, 4>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 3>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<int, 4>' requested here}}
+}
+
diff --git a/test/OpenMP/task_ast_print.cpp b/test/OpenMP/task_ast_print.cpp
index 723139b081832..37e5833dec5e5 100644
--- a/test/OpenMP/task_ast_print.cpp
+++ b/test/OpenMP/task_ast_print.cpp
@@ -8,6 +8,57 @@
void foo() {}
+struct S1 {
+ S1(): a(0) {}
+ S1(int v) : a(v) {}
+ int a;
+ typedef int type;
+};
+
+template <typename T>
+class S7 : public T {
+protected:
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(typename T::type v) : a(v) {
+#pragma omp task private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp task private(a) private(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp task private(this->a) private(this->a) private(this->S1::a)
+// CHECK: #pragma omp task private(this->a) private(this->a) private(T::a)
+// CHECK: #pragma omp task private(this->a) private(this->a)
+
+class S8 : public S7<S1> {
+ S8() {}
+
+public:
+ S8(int v) : S7<S1>(v){
+#pragma omp task private(a) private(this->a) private(S7<S1>::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S8 &operator=(S8 &s) {
+#pragma omp task private(a) private(this->a)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp task private(this->a) private(this->a) private(this->S7<S1>::a)
+// CHECK: #pragma omp task private(this->a) private(this->a)
+
template <class T>
struct S {
operator T() { return T(); }
@@ -98,4 +149,7 @@ int main(int argc, char **argv) {
return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x);
}
+extern template int S<int>::TS;
+extern template long S<long>::TS;
+
#endif
diff --git a/test/OpenMP/task_codegen.cpp b/test/OpenMP/task_codegen.cpp
index 23dc014aad3b1..08c9ce33d8e8e 100644
--- a/test/OpenMP/task_codegen.cpp
+++ b/test/OpenMP/task_codegen.cpp
@@ -9,7 +9,7 @@
// CHECK-DAG: [[IDENT_T:%.+]] = type { i32, i32, i32, i32, i8* }
// CHECK-DAG: [[STRUCT_SHAREDS:%.+]] = type { i8*, [2 x [[STRUCT_S:%.+]]]* }
// CHECK-DAG: [[STRUCT_SHAREDS1:%.+]] = type { [2 x [[STRUCT_S:%.+]]]* }
-// CHECK-DAG: [[KMP_TASK_T:%.+]] = type { i8*, i32 (i32, i8*)*, i32, i32 (i32, i8*)* }
+// CHECK-DAG: [[KMP_TASK_T:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}} }
// CHECK-DAG: [[KMP_DEPEND_INFO:%.+]] = type { i64, i64, i8 }
struct S {
int a;
@@ -30,15 +30,16 @@ int main() {
// CHECK: store i8* [[B]], i8** [[B_REF]]
// CHECK: [[S_REF:%.+]] = getelementptr inbounds [[STRUCT_SHAREDS]], [[STRUCT_SHAREDS]]* [[CAPTURES]], i32 0, i32 1
// CHECK: store [2 x [[STRUCT_S]]]* [[S]], [2 x [[STRUCT_S]]]** [[S_REF]]
-// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 1, i64 32, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_T]]{{.*}}*)* [[TASK_ENTRY1:@.+]] to i32 (i32, i8*)*))
+// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 33, i64 40, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_T]]{{.*}}*)* [[TASK_ENTRY1:@.+]] to i32 (i32, i8*)*))
// CHECK: [[SHAREDS_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]], [[KMP_TASK_T]]* [[TASK_PTR:%.+]], i32 0, i32 0
// CHECK: [[SHAREDS_REF:%.+]] = load i8*, i8** [[SHAREDS_REF_PTR]]
// CHECK: [[BITCAST:%.+]] = bitcast [[STRUCT_SHAREDS]]* [[CAPTURES]] to i8*
// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[SHAREDS_REF]], i8* [[BITCAST]], i64 16, i32 8, i1 false)
-// CHECK: [[DESTRUCTORS_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]], [[KMP_TASK_T]]* [[TASK_PTR]], i32 0, i32 3
-// CHECK: store i32 (i32, i8*)* null, i32 (i32, i8*)** [[DESTRUCTORS_REF_PTR]]
+// CHECK: [[PRIORITY_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]], [[KMP_TASK_T]]* [[TASK_PTR]], i32 0, i32 4
+// CHECK: [[PRIORITY:%.+]] = bitcast %union{{.+}}* [[PRIORITY_REF_PTR]] to i32*
+// CHECK: store i32 {{.+}}, i32* [[PRIORITY]]
// CHECK: call i32 @__kmpc_omp_task([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]])
-#pragma omp task shared(a, b, s)
+#pragma omp task shared(a, b, s) priority(b)
{
a = 15;
b = a;
@@ -46,13 +47,11 @@ int main() {
}
// CHECK: [[S_REF:%.+]] = getelementptr inbounds [[STRUCT_SHAREDS1]], [[STRUCT_SHAREDS1]]* [[CAPTURES:%.+]], i32 0, i32 0
// CHECK: store [2 x [[STRUCT_S]]]* [[S]], [2 x [[STRUCT_S]]]** [[S_REF]]
-// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{[^,]+}}, i32 [[GTID]], i32 1, i64 32, i64 8,
+// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{[^,]+}}, i32 [[GTID]], i32 1, i64 40, i64 8,
// CHECK: [[SHAREDS_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]], [[KMP_TASK_T]]* [[TASK_PTR:%.+]], i32 0, i32 0
// CHECK: [[SHAREDS_REF:%.+]] = load i8*, i8** [[SHAREDS_REF_PTR]]
// CHECK: [[BITCAST:%.+]] = bitcast [[STRUCT_SHAREDS1]]* [[CAPTURES]] to i8*
// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[SHAREDS_REF]], i8* [[BITCAST]], i64 8, i32 8, i1 false)
-// CHECK: [[DESTRUCTORS_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]], [[KMP_TASK_T]]* [[TASK_PTR]], i32 0, i32 3
-// CHECK: store i32 (i32, i8*)* null, i32 (i32, i8*)** [[DESTRUCTORS_REF_PTR]]
// CHECK: [[DEP:%.*]] = getelementptr inbounds [4 x [[KMP_DEPEND_INFO]]], [4 x [[KMP_DEPEND_INFO]]]* [[DEPENDENCIES:%.*]], i64 0, i64 0
// CHECK: [[T0:%.*]] = getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* [[DEP]], i32 0, i32 0
// CHECK: store i64 ptrtoint (i32* @{{.+}} to i64), i64* [[T0]]
@@ -100,17 +99,13 @@ int main() {
a = 15;
s[1].a = 10;
}
-// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 0, i64 32, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_T]]{{.*}}*)* [[TASK_ENTRY2:@.+]] to i32 (i32, i8*)*))
-// CHECK: [[DESTRUCTORS_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]]{{.*}}* {{%.+}}, i32 0, i32 3
-// CHECK: store i32 (i32, i8*)* null, i32 (i32, i8*)** [[DESTRUCTORS_REF_PTR]]
+// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 0, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_T]]{{.*}}*)* [[TASK_ENTRY2:@.+]] to i32 (i32, i8*)*))
// CHECK: call i32 @__kmpc_omp_task([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]])
#pragma omp task untied
{
a = 1;
}
-// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 0, i64 32, i64 1,
-// CHECK: [[DESTRUCTORS_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]]{{.*}}* {{%.+}}, i32 0, i32 3
-// CHECK: store i32 (i32, i8*)* null, i32 (i32, i8*)** [[DESTRUCTORS_REF_PTR]]
+// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 0, i64 40, i64 1,
// CHECK: getelementptr inbounds [2 x [[STRUCT_S]]], [2 x [[STRUCT_S]]]* [[S]], i64 0, i64 0
// CHECK: getelementptr inbounds [2 x [[KMP_DEPEND_INFO]]], [2 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i64 0, i64 0
// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 0
@@ -120,15 +115,15 @@ int main() {
// CHECK: store i64 4, i64*
// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2
// CHECK: store i8 3, i8*
+// CHECK: [[B_VAL:%.+]] = load i8, i8* [[B]]
+// CHECK: [[IDX2:%.+]] = sext i8 [[B_VAL]] to i64
// CHECK: [[IDX1:%.+]] = mul nsw i64 4, [[A_VAL]]
// CHECK: [[START:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]]
+// CHECK: [[START1:%.+]] = getelementptr inbounds i32, i32* [[START]], i64 [[IDX2]]
// CHECK: [[B_VAL:%.+]] = load i8, i8* [[B]]
// CHECK: [[IDX2:%.+]] = sext i8 [[B_VAL]] to i64
-// CHECK: [[START1:%.+]] = getelementptr inbounds i32, i32* [[START]], i64 [[IDX2]]
// CHECK: [[IDX1:%.+]] = mul nsw i64 9, [[A_VAL]]
// CHECK: [[END:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]]
-// CHECK: [[B_VAL:%.+]] = load i8, i8* [[B]]
-// CHECK: [[IDX2:%.+]] = sext i8 [[B_VAL]] to i64
// CHECK: [[END1:%.+]] = getelementptr inbounds i32, i32* [[END]], i64 [[IDX2]]
// CHECK: [[END2:%.+]] = getelementptr i32, i32* [[END1]], i32 1
// CHECK: [[START_INT:%.+]] = ptrtoint i32* [[START1]] to i64
@@ -149,9 +144,7 @@ int main() {
{
a = 1;
}
-// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 3, i64 32, i64 1,
-// CHECK: [[DESTRUCTORS_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]]{{.*}}* {{%.+}}, i32 0, i32 3
-// CHECK: store i32 (i32, i8*)* null, i32 (i32, i8*)** [[DESTRUCTORS_REF_PTR]]
+// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 3, i64 40, i64 1,
// CHECK: getelementptr inbounds [3 x [[KMP_DEPEND_INFO]]], [3 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i64 0, i64 0
// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 0
// CHECK: store i64 ptrtoint (i32* @{{.+}} to i64), i64*
@@ -173,12 +166,12 @@ int main() {
// CHECK: [[START1:%.+]] = getelementptr inbounds i32, i32* [[START]], i64 3
// CHECK: [[NEW_A_VAL:%.+]] = load i32, i32* @{{.+}},
// CHECK: [[NEW_A_VAL_I64:%.+]] = sext i32 [[NEW_A_VAL]] to i64
+// CHECK: [[IDX2:%.+]] = sub nsw i64 [[NEW_A_VAL_I64]], 1
+// CHECK: [[NEW_A_VAL:%.+]] = load i32, i32* @{{.+}},
+// CHECK: [[NEW_A_VAL_I64:%.+]] = sext i32 [[NEW_A_VAL]] to i64
// CHECK: [[SUB:%.+]] = add nsw i64 -1, [[NEW_A_VAL_I64]]
// CHECK: [[IDX1:%.+]] = mul nsw i64 [[SUB]], [[A_VAL]]
// CHECK: [[END:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]]
-// CHECK: [[NEW_A_VAL:%.+]] = load i32, i32* @{{.+}},
-// CHECK: [[NEW_A_VAL_I64:%.+]] = sext i32 [[NEW_A_VAL]] to i64
-// CHECK: [[IDX2:%.+]] = sub nsw i64 [[NEW_A_VAL_I64]], 1
// CHECK: [[END1:%.+]] = getelementptr inbounds i32, i32* [[END]], i64 [[IDX2]]
// CHECK: [[END2:%.+]] = getelementptr i32, i32* [[END1]], i32 1
// CHECK: [[START_INT:%.+]] = ptrtoint i32* [[START1]] to i64
@@ -199,17 +192,13 @@ int main() {
{
a = 2;
}
-// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 3, i64 32, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_T]]{{.*}}*)* [[TASK_ENTRY3:@.+]] to i32 (i32, i8*)*))
-// CHECK: [[DESTRUCTORS_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]]{{.*}}* {{%.+}}, i32 0, i32 3
-// CHECK: store i32 (i32, i8*)* null, i32 (i32, i8*)** [[DESTRUCTORS_REF_PTR]]
+// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 3, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_T]]{{.*}}*)* [[TASK_ENTRY3:@.+]] to i32 (i32, i8*)*))
// CHECK: call i32 @__kmpc_omp_task([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]])
#pragma omp task final(true)
{
a = 2;
}
-// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 1, i64 32, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_T]]{{.*}}*)* [[TASK_ENTRY4:@.+]] to i32 (i32, i8*)*))
-// CHECK: [[DESTRUCTORS_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]]{{.*}}* {{%.*}}, i32 0, i32 3
-// CHECK: store i32 (i32, i8*)* null, i32 (i32, i8*)** [[DESTRUCTORS_REF_PTR]]
+// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 1, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_T]]{{.*}}*)* [[TASK_ENTRY4:@.+]] to i32 (i32, i8*)*))
// CHECK: call i32 @__kmpc_omp_task([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]])
const bool flag = false;
#pragma omp task final(flag)
@@ -220,9 +209,7 @@ int main() {
// CHECK: [[CMP:%.+]] = icmp ne i8 [[B_VAL]], 0
// CHECK: [[FINAL:%.+]] = select i1 [[CMP]], i32 2, i32 0
// CHECK: [[FLAGS:%.+]] = or i32 [[FINAL]], 1
-// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 [[FLAGS]], i64 32, i64 8, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_T]]{{.*}}*)* [[TASK_ENTRY5:@.+]] to i32 (i32, i8*)*))
-// CHECK: [[DESTRUCTORS_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]]{{.*}}* {{%.+}}, i32 0, i32 3
-// CHECK: store i32 (i32, i8*)* null, i32 (i32, i8*)** [[DESTRUCTORS_REF_PTR]]
+// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 [[FLAGS]], i64 40, i64 8, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_T]]{{.*}}*)* [[TASK_ENTRY5:@.+]] to i32 (i32, i8*)*))
// CHECK: call i32 @__kmpc_omp_task([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]])
int c __attribute__((aligned(128)));
#pragma omp task final(b) shared(c)
@@ -230,6 +217,17 @@ int main() {
a = 4;
c = 5;
}
+// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 0, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_T]]{{.*}}*)* [[TASK_ENTRY6:@.+]] to i32 (i32, i8*)*))
+// CHECK: call i32 @__kmpc_omp_task([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]])
+#pragma omp task untied
+ {
+ S s1;
+#pragma omp task
+ a = 4;
+#pragma omp taskyield
+ s1 = S();
+#pragma omp taskwait
+ }
return a;
}
// CHECK: define internal i32 [[TASK_ENTRY1]](i32, [[KMP_TASK_T]]{{.*}}* noalias)
@@ -240,16 +238,41 @@ int main() {
// CHECK: store i32 10, i32* %{{.+}}
// CHECK: define internal i32 [[TASK_ENTRY2]](i32, [[KMP_TASK_T]]{{.*}}* noalias)
-// CHECK: store i32 1, i32* [[A_PTR:@.+]]
+// CHECK: store i32 1, i32* [[A_PTR]]
// CHECK: define internal i32 [[TASK_ENTRY3]](i32, [[KMP_TASK_T]]{{.*}}* noalias)
-// CHECK: store i32 2, i32* [[A_PTR:@.+]]
+// CHECK: store i32 2, i32* [[A_PTR]]
// CHECK: define internal i32 [[TASK_ENTRY4]](i32, [[KMP_TASK_T]]{{.*}}* noalias)
-// CHECK: store i32 3, i32* [[A_PTR:@.+]]
+// CHECK: store i32 3, i32* [[A_PTR]]
// CHECK: define internal i32 [[TASK_ENTRY5]](i32, [[KMP_TASK_T]]{{.*}}* noalias)
-// CHECK: store i32 4, i32* [[A_PTR:@.+]]
+// CHECK: store i32 4, i32* [[A_PTR]]
// CHECK: store i32 5, i32* [[C_PTR:%.+]], align 128
+
+// CHECK: define internal i32
+// CHECK: store i32 4, i32* [[A_PTR]]
+
+// CHECK: define internal i32 [[TASK_ENTRY6]](i32, [[KMP_TASK_T]]{{.*}}* noalias)
+// CHECK: switch i32 %{{.+}}, label
+// CHECK: load i32*, i32** %
+// CHECK: store i32 1, i32* %
+// CHECK: call i32 @__kmpc_omp_task(%
+
+// CHECK: call i8* @__kmpc_omp_task_alloc(
+// CHECK: call i32 @__kmpc_omp_task(%
+// CHECK: load i32*, i32** %
+// CHECK: store i32 2, i32* %
+// CHECK: call i32 @__kmpc_omp_task(%
+
+// CHECK: call i32 @__kmpc_omp_taskyield(%
+// CHECK: load i32*, i32** %
+// CHECK: store i32 3, i32* %
+// CHECK: call i32 @__kmpc_omp_task(%
+
+// CHECK: call i32 @__kmpc_omp_taskwait(%
+// CHECK: load i32*, i32** %
+// CHECK: store i32 4, i32* %
+// CHECK: call i32 @__kmpc_omp_task(%
#endif
diff --git a/test/OpenMP/task_firstprivate_codegen.cpp b/test/OpenMP/task_firstprivate_codegen.cpp
index e2244140d1e14..0d8e1c4afe4e5 100644
--- a/test/OpenMP/task_firstprivate_codegen.cpp
+++ b/test/OpenMP/task_firstprivate_codegen.cpp
@@ -24,10 +24,10 @@ struct S {
volatile double g;
-// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, i32 (i32, i8*)* }
+// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}} }
// CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double }
// CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [2 x [[S_DOUBLE_TY]]], [[S_DOUBLE_TY]], i32, [2 x i32]
-// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { [2 x i32]*, i32*, [2 x [[S_DOUBLE_TY]]]*, [[S_DOUBLE_TY]]*, i{{[0-9]+}}* }
+// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type {{.*}}{ [2 x i32]*, i32, {{.*}}[2 x [[S_DOUBLE_TY]]]*, [[S_DOUBLE_TY]]*, i{{[0-9]+}}
// CHECK-DAG: [[KMP_TASK_MAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [[PRIVATES_MAIN_TY]] }
// CHECK-DAG: [[S_INT_TY:%.+]] = type { i32 }
// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { [2 x i32]*, i32*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* }
@@ -58,18 +58,16 @@ int main() {
// LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]](
[&]() {
// LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
- // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 48, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+ // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 56, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
// LAMBDA: [[G_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0
// LAMBDA: [[G_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 0
-// LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_ADDR_REF]]
-// LAMBDA: [[G_VAL:%.+]] = load volatile double, double* [[G_REF]]
+// LAMBDA: [[G_VAL:%.+]] = load volatile double, double* [[G_ADDR_REF]]
// LAMBDA: store volatile double [[G_VAL]], double* [[G_PRIVATE_ADDR]]
// LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1
// LAMBDA: [[SIVAR_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
-// LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_ADDR_REF]]
-// LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]]
+// LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_ADDR_REF]]
// LAMBDA: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]]
// LAMBDA: call i32 @__kmpc_omp_task(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]])
@@ -104,18 +102,16 @@ int main() {
// BLOCKS: call void {{%.+}}(i8
^{
// BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
- // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 48, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+ // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 56, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
// BLOCKS: [[G_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0
// BLOCKS: [[G_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 0
- // BLOCKS: [[G_REF:%.+]] = load double*, double** [[G_ADDR_REF]]
- // BLOCKS: [[G_VAL:%.+]] = load volatile double, double* [[G_REF]]
+ // BLOCKS: [[G_VAL:%.+]] = load volatile double, double* [[G_ADDR_REF]]
// BLOCKS: store volatile double [[G_VAL]], double* [[G_PRIVATE_ADDR]]
// BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1
// BLOCKS: [[SIVAR_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
- // BLOCKS: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_ADDR_REF]]
- // BLOCKS: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]]
+ // BLOCKS: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_ADDR_REF]]
// BLOCKS: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]]
// BLOCKS: call i32 @__kmpc_omp_task(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]])
// BLOCKS: ret
@@ -180,20 +176,22 @@ int main() {
// CHECK: [[VEC_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0
// CHECK: store [2 x i32]* [[VEC_ADDR]], [2 x i32]** [[VEC_REF]],
// CHECK: [[T_VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1
-// CHECK: store i32* [[T_VAR_ADDR]], i32** [[T_VAR_REF]],
-// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK: [[T_VAR:%.+]] = load i32, i32* [[T_VAR_ADDR]],
+// CHECK: store i32 [[T_VAR]], i32* [[T_VAR_REF]],
+// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3
// CHECK: store [2 x [[S_DOUBLE_TY]]]* [[S_ARR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[S_ARR_REF]],
-// CHECK: [[VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3
+// CHECK: [[VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 4
// CHECK: store [[S_DOUBLE_TY]]* [[VAR_ADDR]], [[S_DOUBLE_TY]]** [[VAR_REF]],
-// CHECK: [[SIVAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 4
-// CHECK: store i{{[0-9]+}}* [[SIVAR]], i{{[0-9]+}}** [[SIVAR_REF]],
+// CHECK: [[SIVAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 5
+// CHECK: [[SIVAR_VAL:%.+]] = load i32, i32* [[SIVAR]],
+// CHECK: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_REF]],
// Allocate task.
// Returns struct kmp_task_t {
// [[KMP_TASK_T]] task_data;
// [[KMP_TASK_MAIN_TY]] privates;
// };
-// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 1, i64 72, i64 40, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 80, i64 40, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_MAIN_TY]]*
// Fill kmp_task_t->shareds by copying from original capture argument.
@@ -211,7 +209,7 @@ int main() {
// Constructors for s_arr and var.
// s_arr;
// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
-// CHECK: [[S_ARR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 2
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 3
// CHECK: load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[S_ARR_ADDR_REF]],
// CHECK: call void [[S_DOUBLE_TY_COPY_CONSTR]]([[S_DOUBLE_TY]]* [[S_ARR_CUR:%[^,]+]],
// CHECK: getelementptr [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* [[S_ARR_CUR]], i{{.+}} 1
@@ -221,14 +219,13 @@ int main() {
// var;
// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1
-// CHECK: [[VAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 3
+// CHECK: [[VAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 4
// CHECK: [[VAR_REF:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[VAR_ADDR_REF]],
// CHECK: call void [[S_DOUBLE_TY_COPY_CONSTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF]], [[S_DOUBLE_TY]]* {{.*}}[[VAR_REF]],
// t_var;
// CHECK: [[PRIVATE_T_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
-// CHECK: [[T_VAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 1
-// CHECK: [[T_VAR_REF:%.+]] = load i{{.+}}*, i{{.+}}** [[T_VAR_ADDR_REF]],
+// CHECK: [[T_VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 1
// CHECK: [[T_VAR:%.+]] = load i{{.+}}, i{{.+}}* [[T_VAR_REF]],
// CHECK: store i32 [[T_VAR]], i32* [[PRIVATE_T_VAR_REF]],
@@ -239,14 +236,14 @@ int main() {
// sivar;
// CHECK: [[PRIVATE_SIVAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 4
-// CHECK: [[SIVAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 4
-// CHECK: [[SIVAR_REF:%.+]] = load i{{.+}}*, i{{.+}}** [[SIVAR_ADDR_REF]],
+// CHECK: [[SIVAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 5
// CHECK: [[SIVAR:%.+]] = load i{{.+}}, i{{.+}}* [[SIVAR_REF]],
// CHECK: store i32 [[SIVAR]], i32* [[PRIVATE_SIVAR_REF]],
// Provide pointer to destructor function, which will destroy private variables at the end of the task.
// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3
-// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_REF]],
+// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)**
+// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]],
// Start task.
// CHECK: call i32 @__kmpc_omp_task([[LOC]], i32 [[GTID]], i8* [[RES]])
@@ -347,7 +344,7 @@ int main() {
// [[KMP_TASK_T_TY]] task_data;
// [[KMP_TASK_TMAIN_TY]] privates;
// };
-// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 1, i64 256, i64 32, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 256, i64 32, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_TMAIN_TY]]*
// Fill kmp_task_t->shareds by copying from original capture argument.
@@ -391,7 +388,8 @@ int main() {
// Provide pointer to destructor function, which will destroy private variables at the end of the task.
// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3
-// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_REF]],
+// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)**
+// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]],
// Start task.
// CHECK: call i32 @__kmpc_omp_task([[LOC]], i32 [[GTID]], i8* [[RES]])
@@ -422,11 +420,11 @@ int main() {
// CHECK: ret void
// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_TMAIN_TY]]* noalias)
-
-// CHECK: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*,
-// CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*,
-// CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
-// CHECK: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
+// CHECK: alloca i32*,
+// CHECK-DAG: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*,
+// CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*,
+// CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]],
// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]],
// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]])
diff --git a/test/OpenMP/task_firstprivate_messages.cpp b/test/OpenMP/task_firstprivate_messages.cpp
index ef5f3856430a3..11d8c5789879a 100644
--- a/test/OpenMP/task_firstprivate_messages.cpp
+++ b/test/OpenMP/task_firstprivate_messages.cpp
@@ -7,6 +7,17 @@ bool foobool(int argc) {
return argc;
}
+template <typename T>
+struct S {
+ T b;
+ S(T a, T c) {
+#pragma omp task default(none) firstprivate(a, b)
+ a = b = c; // expected-error {{variable 'c' must have explicitly specified data sharing attributes}}
+ }
+};
+
+S<int> s(3, 4); // expected-note {{in instantiation of member function 'S<int>::S' requested here}}
+
struct S1; // expected-note {{declared here}} expected-note{{forward declaration of 'S1'}}
extern S1 a;
class S2 {
diff --git a/test/OpenMP/task_if_codegen.cpp b/test/OpenMP/task_if_codegen.cpp
index 5992be02a84a9..4226dceda86e9 100644
--- a/test/OpenMP/task_if_codegen.cpp
+++ b/test/OpenMP/task_if_codegen.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix=CHECK %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
// REQUIRES: x86-registered-target
// expected-no-diagnostics
#ifndef HEADER
@@ -63,11 +63,11 @@ int tmain(T Arg) {
// CHECK-LABEL: @main
int main() {
// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(
-// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc({{[^,]+}}, i32 [[GTID]], i32 1, i64 32, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN7:[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc({{[^,]+}}, i32 [[GTID]], i32 1, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN7:[^ ]+]] to i32 (i32, i8*)*))
// CHECK: call i32 @__kmpc_omp_task(%{{.+}}* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]])
#pragma omp task if (true)
fn7();
-// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc({{[^,]+}}, i32 [[GTID]], i32 1, i64 32, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN8:[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc({{[^,]+}}, i32 [[GTID]], i32 1, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN8:[^ ]+]] to i32 (i32, i8*)*))
// CHECK: [[TASK_PTR:%.+]] = bitcast i8* [[ORIG_TASK_PTR]] to
// CHECK: call void @__kmpc_omp_task_begin_if0(%{{.+}}* @{{.+}}, i{{.+}} [[GTID]], i8* [[ORIG_TASK_PTR]])
// CHECK: call i32 [[CAP_FN8]](i32 [[GTID]], %{{.+}}* [[TASK_PTR]])
@@ -75,7 +75,7 @@ int main() {
#pragma omp task if (false)
fn8();
-// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc({{[^,]+}}, i32 [[GTID]], i32 1, i64 32, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN9:[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc({{[^,]+}}, i32 [[GTID]], i32 1, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN9:[^ ]+]] to i32 (i32, i8*)*))
// CHECK: [[TASK_PTR:%.+]] = bitcast i8* [[ORIG_TASK_PTR]] to
// CHECK: br i1 %{{.+}}, label %[[OMP_THEN:.+]], label %[[OMP_ELSE:.+]]
// CHECK: [[OMP_THEN]]
@@ -89,7 +89,7 @@ int main() {
// CHECK: [[OMP_END]]
#pragma omp task if (Arg)
fn9();
-// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc({{[^,]+}}, i32 [[GTID]], i32 1, i64 32, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN10:[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc({{[^,]+}}, i32 [[GTID]], i32 1, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN10:[^ ]+]] to i32 (i32, i8*)*))
// CHECK: [[TASK_PTR:%.+]] = bitcast i8* [[ORIG_TASK_PTR]] to
// CHECK: br i1 %{{.+}}, label %[[OMP_THEN:.+]], label %[[OMP_ELSE:.+]]
// CHECK: [[OMP_THEN]]
@@ -126,7 +126,7 @@ int main() {
// CHECK-LABEL: define {{.+}} @{{.+}}tmain
// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(
-// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^,]+}}, i32 [[GTID]], i32 1, i64 32, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN1:[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^,]+}}, i32 [[GTID]], i32 1, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN1:[^ ]+]] to i32 (i32, i8*)*))
// CHECK: call i32 @__kmpc_omp_task(%{{.+}}* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]])
// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc(
@@ -135,7 +135,7 @@ int main() {
// CHECK: call i32 [[CAP_FN2:@.+]](i32 [[GTID]], %{{.+}}* [[TASK_PTR]])
// CHECK: call void @__kmpc_omp_task_complete_if0(%{{.+}}* @{{.+}}, i{{.+}} [[GTID]], i8* [[ORIG_TASK_PTR]])
-// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^,]+}}, i32 [[GTID]], i32 1, i64 32, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN3:[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^,]+}}, i32 [[GTID]], i32 1, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN3:[^ ]+]] to i32 (i32, i8*)*))
// CHECK: [[TASK_PTR:%.+]] = bitcast i8* [[ORIG_TASK_PTR]] to
// CHECK: br i1 %{{.+}}, label %[[OMP_THEN:.+]], label %[[OMP_ELSE:.+]]
// CHECK: [[OMP_THEN]]
@@ -148,7 +148,7 @@ int main() {
// CHECK: br label %[[OMP_END]]
// CHECK: [[OMP_END]]
-// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^,]+}}, i32 [[GTID]], i32 1, i64 32, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN4:[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^,]+}}, i32 [[GTID]], i32 1, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN4:[^ ]+]] to i32 (i32, i8*)*))
// CHECK: [[TASK_PTR:%.+]] = bitcast i8* [[ORIG_TASK_PTR]] to
// CHECK: br i1 %{{.+}}, label %[[OMP_THEN:.+]], label %[[OMP_ELSE:.+]]
// CHECK: [[OMP_THEN]]
@@ -162,7 +162,7 @@ int main() {
// CHECK: br label %[[OMP_END]]
// CHECK: [[OMP_END]]
-// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^,]+}}, i32 [[GTID]], i32 1, i64 32, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN5:[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^,]+}}, i32 [[GTID]], i32 1, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN5:[^ ]+]] to i32 (i32, i8*)*))
// CHECK: [[TASK_PTR:%.+]] = bitcast i8* [[ORIG_TASK_PTR]] to
// CHECK: br i1 %{{.+}}, label %[[OMP_THEN:.+]], label %[[OMP_ELSE:.+]]
// CHECK: [[OMP_THEN]]
@@ -176,7 +176,7 @@ int main() {
// CHECK: br label %[[OMP_END]]
// CHECK: [[OMP_END]]
-// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^,]+}}, i32 [[GTID]], i32 1, i64 32, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN6:[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^,]+}}, i32 [[GTID]], i32 1, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[CAP_FN6:[^ ]+]] to i32 (i32, i8*)*))
// CHECK: [[TASK_PTR:%.+]] = bitcast i8* [[ORIG_TASK_PTR]] to
// CHECK: br i1 %{{.+}}, label %[[OMP_THEN:.+]], label %[[OMP_ELSE:.+]]
// CHECK: [[OMP_THEN]]
diff --git a/test/OpenMP/task_messages.cpp b/test/OpenMP/task_messages.cpp
index 64bf8a40f025d..f42a37ae1daad 100644
--- a/test/OpenMP/task_messages.cpp
+++ b/test/OpenMP/task_messages.cpp
@@ -60,11 +60,10 @@ int foo() {
// expected-error@+1 2 {{calling a private constructor of class 'S'}}
#pragma omp parallel shared(a, b)
++a, ++b;
-// expected-note@+1 3 {{defined as reduction}}
+// expected-note@+1 2 {{defined as reduction}}
#pragma omp parallel reduction(+ : r)
-// expected-error@+1 {{argument of a reduction clause of a parallel construct must not appear in a firstprivate clause on a task construct}}
+// expected-error@+1 2 {{argument of a reduction clause of a parallel construct must not appear in a firstprivate clause on a task construct}}
#pragma omp task firstprivate(r)
- // expected-error@+1 2 {{reduction variables may not be accessed in an explicit task}}
++r;
// expected-note@+1 2 {{defined as reduction}}
#pragma omp parallel reduction(+ : r)
@@ -77,12 +76,11 @@ int foo() {
// expected-error@+1 2 {{reduction variables may not be accessed in an explicit task}}
++r;
#pragma omp parallel
-// expected-note@+1 3 {{defined as reduction}}
+// expected-note@+1 2 {{defined as reduction}}
#pragma omp for reduction(+ : r)
for (int i = 0; i < 10; ++i)
-// expected-error@+1 {{argument of a reduction clause of a for construct must not appear in a firstprivate clause on a task construct}}
+// expected-error@+1 2 {{argument of a reduction clause of a for construct must not appear in a firstprivate clause on a task construct}}
#pragma omp task firstprivate(r)
- // expected-error@+1 2 {{reduction variables may not be accessed in an explicit task}}
++r;
#pragma omp parallel
// expected-note@+1 2 {{defined as reduction}}
diff --git a/test/OpenMP/task_private_codegen.cpp b/test/OpenMP/task_private_codegen.cpp
index 1455fd11a91d9..97155a73f1bd0 100644
--- a/test/OpenMP/task_private_codegen.cpp
+++ b/test/OpenMP/task_private_codegen.cpp
@@ -24,7 +24,7 @@ struct S {
volatile double g;
-// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, i32 (i32, i8*)* }
+// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}} }
// CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double }
// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { i8 }
// CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [2 x [[S_DOUBLE_TY]]], [[S_DOUBLE_TY]], i32, [2 x i32]
@@ -56,10 +56,8 @@ int main() {
// LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]](
[&]() {
// LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
- // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 48, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+ // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 56, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
-// LAMBDA: [[G_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0
-// LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1
// LAMBDA: call i32 @__kmpc_omp_task(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]])
// LAMBDA: ret
#pragma omp task private(g, sivar)
@@ -94,10 +92,8 @@ int main() {
// BLOCKS: call void {{%.+}}(i8
^{
// BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
- // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 48, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+ // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 56, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
- // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0
- // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1
// BLOCKS: call i32 @__kmpc_omp_task(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]])
// BLOCKS: ret
#pragma omp task private(g, sivar)
@@ -162,7 +158,7 @@ int main() {
// [[KMP_TASK_T_TY]] task_data;
// [[KMP_TASK_MAIN_TY]] privates;
// };
-// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 1, i64 72, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 80, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_MAIN_TY]]*
// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
@@ -186,7 +182,8 @@ int main() {
// Provide pointer to destructor function, which will destroy private variables at the end of the task.
// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3
-// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_REF]],
+// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)**
+// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]],
// Start task.
// CHECK: call i32 @__kmpc_omp_task([[LOC]], i32 [[GTID]], i8* [[RES]])
@@ -275,7 +272,7 @@ int main() {
// [[KMP_TASK_T_TY]] task_data;
// [[KMP_TASK_TMAIN_TY]] privates;
// };
-// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 1, i64 256, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 256, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_TMAIN_TY]]*
// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
@@ -299,7 +296,8 @@ int main() {
// Provide pointer to destructor function, which will destroy private variables at the end of the task.
// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3
-// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_REF]],
+// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)**
+// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]],
// Start task.
// CHECK: call i32 @__kmpc_omp_task([[LOC]], i32 [[GTID]], i8* [[RES]])
@@ -331,10 +329,11 @@ int main() {
// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_TMAIN_TY]]* noalias)
-// CHECK: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*,
-// CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*,
-// CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
-// CHECK: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
+// CHECK: alloca i32*,
+// CHECK-DAG: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*,
+// CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*,
+// CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]],
// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]],
// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]])
diff --git a/test/OpenMP/taskgroup_codegen.cpp b/test/OpenMP/taskgroup_codegen.cpp
index d1bc2aafc7b4b..0f6e81b3ba0b7 100644
--- a/test/OpenMP/taskgroup_codegen.cpp
+++ b/test/OpenMP/taskgroup_codegen.cpp
@@ -32,6 +32,7 @@ int main() {
foo();
// CHECK-NOT: call {{.*}}void @__kmpc_taskgroup
// CHECK-NOT: call {{.*}}void @__kmpc_end_taskgroup
+// CHECK: ret
return a;
}
diff --git a/test/OpenMP/taskloop_codegen.cpp b/test/OpenMP/taskloop_codegen.cpp
new file mode 100644
index 0000000000000..e585fcec10d5d
--- /dev/null
+++ b/test/OpenMP/taskloop_codegen.cpp
@@ -0,0 +1,192 @@
+// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c++ -emit-llvm %s -o - -femit-all-decls | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls | FileCheck %s
+// expected-no-diagnostics
+// REQUIRES: x86-registered-target
+#ifndef HEADER
+#define HEADER
+
+// CHECK-LABEL: @main
+int main(int argc, char **argv) {
+// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%ident_t* [[DEFLOC:@.+]])
+// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 33, i64 72, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK1:@.+]] to i32 (i32, i8*)*))
+// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]*
+// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0
+// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5
+// CHECK: store i64 0, i64* [[DOWN]],
+// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 6
+// CHECK: store i64 9, i64* [[UP]],
+// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 7
+// CHECK: store i64 1, i64* [[ST]],
+// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
+// CHECK: call void @__kmpc_taskloop(%ident_t* [[DEFLOC]], i32 [[GTID]], i8* [[TASKV]], i32 1, i64* [[DOWN]], i64* [[UP]], i64 [[ST_VAL]], i32 0, i32 0, i64 0, i8* null)
+#pragma omp taskloop priority(argc)
+ for (int i = 0; i < 10; ++i)
+ ;
+// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 72, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK2:@.+]] to i32 (i32, i8*)*))
+// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]*
+// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0
+// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5
+// CHECK: store i64 0, i64* [[DOWN]],
+// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 6
+// CHECK: store i64 9, i64* [[UP]],
+// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 7
+// CHECK: store i64 1, i64* [[ST]],
+// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
+// CHECK: [[GRAINSIZE:%.+]] = zext i32 %{{.+}} to i64
+// CHECK: call void @__kmpc_taskloop(%ident_t* [[DEFLOC]], i32 [[GTID]], i8* [[TASKV]], i32 1, i64* [[DOWN]], i64* [[UP]], i64 [[ST_VAL]], i32 1, i32 1, i64 [[GRAINSIZE]], i8* null)
+#pragma omp taskloop nogroup grainsize(argc)
+ for (int i = 0; i < 10; ++i)
+ ;
+// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 72, i64 24, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK3:@.+]] to i32 (i32, i8*)*))
+// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]*
+// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0
+// CHECK: [[IF:%.+]] = icmp ne i32 %{{.+}}, 0
+// CHECK: [[IF_INT:%.+]] = sext i1 [[IF]] to i32
+// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5
+// CHECK: store i64 0, i64* [[DOWN]],
+// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 6
+// CHECK: store i64 %{{.+}}, i64* [[UP]],
+// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 7
+// CHECK: store i64 1, i64* [[ST]],
+// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
+// CHECK: call void @__kmpc_taskloop(%ident_t* [[DEFLOC]], i32 [[GTID]], i8* [[TASKV]], i32 [[IF_INT]], i64* [[DOWN]], i64* [[UP]], i64 [[ST_VAL]], i32 0, i32 2, i64 4, i8* null)
+ int i;
+#pragma omp taskloop if(argc) shared(argc, argv) collapse(2) num_tasks(4)
+ for (i = 0; i < argc; ++i)
+ for (int j = argc; j < argv[argc][argc]; ++j)
+ ;
+}
+
+// CHECK: define internal i32 [[TASK1]](
+// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* %{{.+}}, i32 0, i32 5
+// CHECK: [[DOWN_VAL:%.+]] = load i64, i64* [[DOWN]],
+// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 6
+// CHECK: [[UP_VAL:%.+]] = load i64, i64* [[UP]],
+// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 7
+// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
+// CHECK: [[LITER:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 8
+// CHECK: [[LITER_VAL:%.+]] = load i32, i32* [[LITER]],
+// CHECK: store i64 [[DOWN_VAL]], i64* [[LB:%[^,]+]],
+// CHECK: store i64 [[UP_VAL]], i64* [[UB:%[^,]+]],
+// CHECK: store i64 [[ST_VAL]], i64* [[ST:%[^,]+]],
+// CHECK: store i32 [[LITER_VAL]], i32* [[LITER:%[^,]+]],
+// CHECK: [[LB_VAL:%.+]] = load i64, i64* [[LB]],
+// CHECK: [[LB_I32:%.+]] = trunc i64 [[LB_VAL]] to i32
+// CHECK: store i32 [[LB_I32]], i32* [[CNT:%.+]],
+// CHECK: br label
+// CHECK: [[VAL:%.+]] = load i32, i32* [[CNT]],
+// CHECK: [[VAL_I64:%.+]] = sext i32 [[VAL]] to i64
+// CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]],
+// CHECK: [[CMP:%.+]] = icmp ule i64 [[VAL_I64]], [[UB_VAL]]
+// CHECK: br i1 [[CMP]], label %{{.+}}, label %{{.+}}
+// CHECK: load i32, i32* %
+// CHECK: store i32 %
+// CHECK: load i32, i32* %
+// CHECK: add nsw i32 %{{.+}}, 1
+// CHECK: store i32 %{{.+}}, i32* %
+// CHECK: br label %
+// CHECK: ret i32 0
+
+// CHECK: define internal i32 [[TASK2]](
+// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* %{{.+}}, i32 0, i32 5
+// CHECK: [[DOWN_VAL:%.+]] = load i64, i64* [[DOWN]],
+// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 6
+// CHECK: [[UP_VAL:%.+]] = load i64, i64* [[UP]],
+// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 7
+// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
+// CHECK: [[LITER:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 8
+// CHECK: [[LITER_VAL:%.+]] = load i32, i32* [[LITER]],
+// CHECK: store i64 [[DOWN_VAL]], i64* [[LB:%[^,]+]],
+// CHECK: store i64 [[UP_VAL]], i64* [[UB:%[^,]+]],
+// CHECK: store i64 [[ST_VAL]], i64* [[ST:%[^,]+]],
+// CHECK: store i32 [[LITER_VAL]], i32* [[LITER:%[^,]+]],
+// CHECK: [[LB_VAL:%.+]] = load i64, i64* [[LB]],
+// CHECK: [[LB_I32:%.+]] = trunc i64 [[LB_VAL]] to i32
+// CHECK: store i32 [[LB_I32]], i32* [[CNT:%.+]],
+// CHECK: br label
+// CHECK: [[VAL:%.+]] = load i32, i32* [[CNT]],
+// CHECK: [[VAL_I64:%.+]] = sext i32 [[VAL]] to i64
+// CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]],
+// CHECK: [[CMP:%.+]] = icmp ule i64 [[VAL_I64]], [[UB_VAL]]
+// CHECK: br i1 [[CMP]], label %{{.+}}, label %{{.+}}
+// CHECK: load i32, i32* %
+// CHECK: store i32 %
+// CHECK: load i32, i32* %
+// CHECK: add nsw i32 %{{.+}}, 1
+// CHECK: store i32 %{{.+}}, i32* %
+// CHECK: br label %
+// CHECK: ret i32 0
+
+// CHECK: define internal i32 [[TASK3]](
+// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* %{{.+}}, i32 0, i32 5
+// CHECK: [[DOWN_VAL:%.+]] = load i64, i64* [[DOWN]],
+// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 6
+// CHECK: [[UP_VAL:%.+]] = load i64, i64* [[UP]],
+// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 7
+// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
+// CHECK: [[LITER:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 8
+// CHECK: [[LITER_VAL:%.+]] = load i32, i32* [[LITER]],
+// CHECK: store i64 [[DOWN_VAL]], i64* [[LB:%[^,]+]],
+// CHECK: store i64 [[UP_VAL]], i64* [[UB:%[^,]+]],
+// CHECK: store i64 [[ST_VAL]], i64* [[ST:%[^,]+]],
+// CHECK: store i32 [[LITER_VAL]], i32* [[LITER:%[^,]+]],
+// CHECK: [[LB_VAL:%.+]] = load i64, i64* [[LB]],
+// CHECK: store i64 [[LB_VAL]], i64* [[CNT:%.+]],
+// CHECK: br label
+// CHECK: ret i32 0
+
+// CHECK-LABEL: @_ZN1SC2Ei
+struct S {
+ int a;
+ S(int c) {
+// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%ident_t* [[DEFLOC:@.+]])
+// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 72, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK4:@.+]] to i32 (i32, i8*)*))
+// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]*
+// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0
+// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5
+// CHECK: store i64 0, i64* [[DOWN]],
+// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 6
+// CHECK: store i64 %{{.+}}, i64* [[UP]],
+// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 7
+// CHECK: store i64 1, i64* [[ST]],
+// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
+// CHECK: [[NUM_TASKS:%.+]] = zext i32 %{{.+}} to i64
+// CHECK: call void @__kmpc_taskloop(%ident_t* [[DEFLOC]], i32 [[GTID]], i8* [[TASKV]], i32 1, i64* [[DOWN]], i64* [[UP]], i64 [[ST_VAL]], i32 0, i32 2, i64 [[NUM_TASKS]], i8* null)
+#pragma omp taskloop shared(c) num_tasks(a)
+ for (a = 0; a < c; ++a)
+ ;
+ }
+} s(1);
+
+// CHECK: define internal i32 [[TASK4]](
+// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* %{{.+}}, i32 0, i32 5
+// CHECK: [[DOWN_VAL:%.+]] = load i64, i64* [[DOWN]],
+// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 6
+// CHECK: [[UP_VAL:%.+]] = load i64, i64* [[UP]],
+// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 7
+// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
+// CHECK: [[LITER:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 8
+// CHECK: [[LITER_VAL:%.+]] = load i32, i32* [[LITER]],
+// CHECK: store i64 [[DOWN_VAL]], i64* [[LB:%[^,]+]],
+// CHECK: store i64 [[UP_VAL]], i64* [[UB:%[^,]+]],
+// CHECK: store i64 [[ST_VAL]], i64* [[ST:%[^,]+]],
+// CHECK: store i32 [[LITER_VAL]], i32* [[LITER:%[^,]+]],
+// CHECK: [[LB_VAL:%.+]] = load i64, i64* [[LB]],
+// CHECK: [[LB_I32:%.+]] = trunc i64 [[LB_VAL]] to i32
+// CHECK: store i32 [[LB_I32]], i32* [[CNT:%.+]],
+// CHECK: br label
+// CHECK: [[VAL:%.+]] = load i32, i32* [[CNT]],
+// CHECK: [[VAL_I64:%.+]] = sext i32 [[VAL]] to i64
+// CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]],
+// CHECK: [[CMP:%.+]] = icmp ule i64 [[VAL_I64]], [[UB_VAL]]
+// CHECK: br i1 [[CMP]], label %{{.+}}, label %{{.+}}
+// CHECK: load i32, i32* %
+// CHECK: store i32 %
+// CHECK: load i32, i32* %
+// CHECK: add nsw i32 %{{.+}}, 1
+// CHECK: store i32 %{{.+}}, i32* %
+// CHECK: br label %
+// CHECK: ret i32 0
+
+#endif
diff --git a/test/OpenMP/taskloop_collapse_messages.cpp b/test/OpenMP/taskloop_collapse_messages.cpp
index f33da11f5ed96..1a5620e77db0a 100644
--- a/test/OpenMP/taskloop_collapse_messages.cpp
+++ b/test/OpenMP/taskloop_collapse_messages.cpp
@@ -1,8 +1,13 @@
// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
void foo() {
}
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
bool foobool(int argc) {
return argc;
}
@@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp taskloop collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp taskloop', but found only 1}}
- // expected-error@+3 2 {{directive '#pragma omp taskloop' cannot contain more than one 'collapse' clause}}
- // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+ // expected-error@+6 2 {{directive '#pragma omp taskloop' cannot contain more than one 'collapse' clause}}
+ // expected-error@+5 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
#pragma omp taskloop collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp taskloop collapse (S) // expected-error {{'S' does not refer to a value}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp taskloop collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp taskloop collapse (1)
@@ -59,16 +71,27 @@ int main(int argc, char **argv) {
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp taskloop', but found only 1}}
#pragma omp taskloop collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop' are ignored}} expected-note {{as specified in 'collapse' clause}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp taskloop', but found only 1}}
- #pragma omp taskloop collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+ #pragma omp taskloop collapse (foobool(1) > 0 ? 1 : 2)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+3 {{expression is not an integral constant expression}}
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
// expected-error@+2 2 {{directive '#pragma omp taskloop' cannot contain more than one 'collapse' clause}}
// expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp taskloop collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp taskloop collapse (S1) // expected-error {{'S1' does not refer to a value}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+1 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp taskloop collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
// expected-error@+3 {{statement after '#pragma omp taskloop' must be a for loop}}
diff --git a/test/OpenMP/taskloop_firstprivate_codegen.cpp b/test/OpenMP/taskloop_firstprivate_codegen.cpp
new file mode 100644
index 0000000000000..822a5c687dc76
--- /dev/null
+++ b/test/OpenMP/taskloop_firstprivate_codegen.cpp
@@ -0,0 +1,511 @@
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=ARRAY %s
+// expected-no-diagnostics
+// REQUIRES: x86-registered-target
+// It doesn't pass on win32.
+// REQUIRES: shell
+#ifndef ARRAY
+#ifndef HEADER
+#define HEADER
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a) {}
+ S() : f() {}
+ S(const S &s, T t = T()) : f(s.f + t) {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+volatile double g;
+
+// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32 }
+// CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double }
+// CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [2 x [[S_DOUBLE_TY]]], [[S_DOUBLE_TY]], i32, [2 x i32]
+// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type {{.*}}{ [2 x i32]*, i32, {{.*}}[2 x [[S_DOUBLE_TY]]]*, [[S_DOUBLE_TY]]*, i{{[0-9]+}}
+// CHECK-DAG: [[KMP_TASK_MAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [[PRIVATES_MAIN_TY]] }
+// CHECK-DAG: [[S_INT_TY:%.+]] = type { i32 }
+// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { [2 x i32]*, i32*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* }
+// CHECK-DAG: [[PRIVATES_TMAIN_TY:%.+]] = type { i32, [2 x i32], [2 x [[S_INT_TY]]], [[S_INT_TY]], [104 x i8] }
+// CHECK-DAG: [[KMP_TASK_TMAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [{{[0-9]+}} x i8], [[PRIVATES_TMAIN_TY]] }
+template <typename T>
+T tmain() {
+ S<T> ttt;
+ S<T> test(ttt);
+ T t_var __attribute__((aligned(128))) = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> var(3);
+#pragma omp taskloop firstprivate(t_var, vec, s_arr, s_arr, var, var)
+ for (int i = 0; i < 10; ++i) {
+ vec[0] = t_var;
+ s_arr[0] = var;
+ }
+ return T();
+}
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA: [[G:@.+]] = global double
+ // LAMBDA: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0,
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
+// LAMBDA: [[G_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0
+// LAMBDA: [[G_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 0
+// LAMBDA: [[G_VAL:%.+]] = load volatile double, double* [[G_ADDR_REF]]
+// LAMBDA: store volatile double [[G_VAL]], double* [[G_PRIVATE_ADDR]]
+
+// LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1
+// LAMBDA: [[SIVAR_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
+// LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_ADDR_REF]]
+// LAMBDA: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]]
+
+// LAMBDA: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* null)
+// LAMBDA: ret
+#pragma omp taskloop firstprivate(g, sivar)
+ for (int i = 0; i < 10; ++i) {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]]
+
+ // LAMBDA: store double* %{{.+}}, double** %{{.+}},
+ // LAMBDA: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}* noalias)
+ g = 1;
+ sivar = 11;
+ // LAMBDA: store double 1.0{{.+}}, double* %{{.+}},
+ // LAMBDA: store i{{[0-9]+}} 11, i{{[0-9]+}}* %{{.+}},
+ // LAMBDA: call void [[INNER_LAMBDA]](%
+ // LAMBDA: ret
+ [&]() {
+ g = 2;
+ sivar = 22;
+ }();
+ }
+ }();
+ return 0;
+#elif defined(BLOCKS)
+ // BLOCKS: [[G:@.+]] = global double
+ // BLOCKS-LABEL: @main
+ // BLOCKS: call void {{%.+}}(i8
+ ^{
+ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
+ // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+ // BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
+ // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0
+ // BLOCKS: [[G_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 0
+ // BLOCKS: [[G_VAL:%.+]] = load volatile double, double* [[G_ADDR_REF]]
+ // BLOCKS: store volatile double [[G_VAL]], double* [[G_PRIVATE_ADDR]]
+
+ // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1
+ // BLOCKS: [[SIVAR_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
+ // BLOCKS: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_ADDR_REF]]
+ // BLOCKS: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]]
+ // BLOCKS: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* null)
+ // BLOCKS: ret
+#pragma omp taskloop firstprivate(g, sivar)
+ for (int i = 0; i < 10; ++i) {
+ // BLOCKS: define {{.+}} void {{@.+}}(i8*
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS: store double 2.0{{.+}}, double*
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS-NOT: [[ISVAR]]{{[[^:word:]]}}
+ // BLOCKS: store i{{[0-9]+}} 22, i{{[0-9]+}}*
+ // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}
+ // BLOCKS: ret
+
+ // BLOCKS: store double* %{{.+}}, double** %{{.+}},
+ // BLOCKS: store i{{[0-9]+}}* %{{.+}}, i{{[0-9]+}}** %{{.+}},
+ // BLOCKS: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}* noalias)
+ g = 1;
+ sivar = 11;
+ // BLOCKS: store double 1.0{{.+}}, double* %{{.+}},
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS: store i{{[0-9]+}} 11, i{{[0-9]+}}* %{{.+}},
+ // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}
+ // BLOCKS: call void {{%.+}}(i8
+ ^{
+ g = 2;
+ sivar = 22;
+ }();
+ }
+ }();
+ return 0;
+#else
+ S<double> ttt;
+ S<double> test(ttt);
+ int t_var = 0;
+ int vec[] = {1, 2};
+ S<double> s_arr[] = {1, 2};
+ S<double> var(3);
+#pragma omp taskloop firstprivate(var, t_var, s_arr, vec, s_arr, var, sivar)
+ for (int i = 0; i < 10; ++i) {
+ vec[0] = t_var;
+ s_arr[0] = var;
+ sivar = 33;
+ }
+ return tmain<int>();
+#endif
+}
+
+// CHECK: [[SIVAR:.+]] = internal global i{{[0-9]+}} 0,
+// CHECK: define i{{[0-9]+}} @main()
+// CHECK: alloca [[S_DOUBLE_TY]],
+// CHECK: [[TEST:%.+]] = alloca [[S_DOUBLE_TY]],
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32],
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]],
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]],
+// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[LOC:%.+]])
+
+// CHECK: call {{.*}} [[S_DOUBLE_TY_COPY_CONSTR:@.+]]([[S_DOUBLE_TY]]* [[TEST]],
+
+// Store original variables in capture struct.
+// CHECK: [[VEC_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: store [2 x i32]* [[VEC_ADDR]], [2 x i32]** [[VEC_REF]],
+// CHECK: [[T_VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1
+// CHECK: [[T_VAR_VAL:%.+]] = load i32, i32* [[T_VAR_ADDR]],
+// CHECK: store i32 [[T_VAR_VAL]], i32* [[T_VAR_REF]],
+// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3
+// CHECK: store [2 x [[S_DOUBLE_TY]]]* [[S_ARR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[S_ARR_REF]],
+// CHECK: [[VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 4
+// CHECK: store [[S_DOUBLE_TY]]* [[VAR_ADDR]], [[S_DOUBLE_TY]]** [[VAR_REF]],
+// CHECK: [[SIVAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 5
+// CHECK: [[SIVAR_VAL:%.+]] = load i32, i32* [[SIVAR]],
+// CHECK: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_REF]],
+
+// Allocate task.
+// Returns struct kmp_task_t {
+// [[KMP_TASK_T]] task_data;
+// [[KMP_TASK_MAIN_TY]] privates;
+// };
+// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 112, i64 40, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_MAIN_TY]]*
+
+// Fill kmp_task_t->shareds by copying from original capture argument.
+// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[SHAREDS_REF_ADDR:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[SHAREDS_REF:%.+]] = load i8*, i8** [[SHAREDS_REF_ADDR]],
+// CHECK: [[CAPTURES_ADDR:%.+]] = bitcast [[CAP_MAIN_TY]]* %{{.+}} to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[SHAREDS_REF]], i8* [[CAPTURES_ADDR]], i64 40, i32 8, i1 false)
+
+// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes).
+// Also copy address of private copy to the corresponding shareds reference.
+// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+// CHECK: [[SHAREDS:%.+]] = bitcast i8* [[SHAREDS_REF]] to [[CAP_MAIN_TY]]*
+
+// Constructors for s_arr and var.
+// s_arr;
+// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 3
+// CHECK: load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[S_ARR_ADDR_REF]],
+// CHECK: call void [[S_DOUBLE_TY_COPY_CONSTR]]([[S_DOUBLE_TY]]* [[S_ARR_CUR:%[^,]+]],
+// CHECK: getelementptr [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* [[S_ARR_CUR]], i{{.+}} 1
+// CHECK: getelementptr [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} 1
+// CHECK: icmp eq
+// CHECK: br i1
+
+// var;
+// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1
+// CHECK: [[VAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 4
+// CHECK: [[VAR_REF:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[VAR_ADDR_REF]],
+// CHECK: call void [[S_DOUBLE_TY_COPY_CONSTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF]], [[S_DOUBLE_TY]]* {{.*}}[[VAR_REF]],
+
+// t_var;
+// CHECK: [[PRIVATE_T_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK: [[T_VAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 1
+// CHECK: [[T_VAR:%.+]] = load i{{.+}}, i{{.+}}* [[T_VAR_ADDR_REF]],
+// CHECK: store i32 [[T_VAR]], i32* [[PRIVATE_T_VAR_REF]],
+
+// vec;
+// CHECK: [[PRIVATE_VEC_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: [[VEC_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 0
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(
+
+// sivar;
+// CHECK: [[PRIVATE_SIVAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 4
+// CHECK: [[SIVAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 5
+// CHECK: [[SIVAR:%.+]] = load i{{.+}}, i{{.+}}* [[SIVAR_ADDR_REF]],
+// CHECK: store i32 [[SIVAR]], i32* [[PRIVATE_SIVAR_REF]],
+
+// Provide pointer to destructor function, which will destroy private variables at the end of the task.
+// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3
+// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)**
+// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]],
+
+// Start task.
+// CHECK: call void @__kmpc_taskloop([[LOC]], i32 [[GTID]], i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_MAIN_TY]]*, [[KMP_TASK_MAIN_TY]]*, i32)* [[MAIN_DUP:@.+]] to i8*))
+
+// CHECK: = call i{{.+}} [[TMAIN_INT:@.+]]()
+
+// No destructors must be called for private copies of s_arr and var.
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: call void [[S_DOUBLE_TY_DESTR:@.+]]([[S_DOUBLE_TY]]*
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: ret
+//
+
+// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_MAIN_TY]]* noalias, [[S_DOUBLE_TY]]** noalias, i32** noalias, [2 x [[S_DOUBLE_TY]]]** noalias, [2 x i32]** noalias, i32** noalias)
+// CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_MAIN_TY]]*, [[PRIVATES_MAIN_TY]]**
+// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 0
+// CHECK: [[ARG3:%.+]] = load [2 x [[S_DOUBLE_TY]]]**, [2 x [[S_DOUBLE_TY]]]*** %{{.+}},
+// CHECK: store [2 x [[S_DOUBLE_TY]]]* [[PRIV_S_VAR]], [2 x [[S_DOUBLE_TY]]]** [[ARG3]],
+// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 1
+// CHECK: [[ARG1:%.+]] = load [[S_DOUBLE_TY]]**, [[S_DOUBLE_TY]]*** {{.+}},
+// CHECK: store [[S_DOUBLE_TY]]* [[PRIV_VAR]], [[S_DOUBLE_TY]]** [[ARG1]],
+// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 2
+// CHECK: [[ARG2:%.+]] = load i32**, i32*** %{{.+}},
+// CHECK: store i32* [[PRIV_T_VAR]], i32** [[ARG2]],
+// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 3
+// CHECK: [[ARG4:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}},
+// CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG4]],
+// CHECK: [[PRIV_SIVAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 4
+// CHECK: [[ARG5:%.+]] = load i{{[0-9]+}}**, i{{[0-9]+}}*** %{{.+}},
+// CHECK: store i{{[0-9]+}}* [[PRIV_SIVAR]], i{{[0-9]+}}** [[ARG5]],
+// CHECK: ret void
+
+// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_MAIN_TY]]* noalias)
+
+// CHECK: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]]*,
+// CHECK: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*,
+// CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*,
+// CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*,
+// CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*,
+// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]],
+// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]],
+
+// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]])
+
+// CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]],
+// CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]],
+// CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]],
+// CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]],
+// CHECK: [[PRIV_SIVAR:%.+]] = load i32*, i32** [[PRIV_SIVAR_ADDR]],
+
+// Privates actually are used.
+// CHECK-DAG: [[PRIV_VAR]]
+// CHECK-DAG: [[PRIV_T_VAR]]
+// CHECK-DAG: [[PRIV_S_ARR]]
+// CHECK-DAG: [[PRIV_VEC]]
+// CHECK-DAG: [[PRIV_SIVAR]]
+
+// CHECK: ret
+
+// CHECK: define internal void [[MAIN_DUP]]([[KMP_TASK_MAIN_TY]]*, [[KMP_TASK_MAIN_TY]]*, i32)
+// CHECK: getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* %{{.+}}, i32 0, i32 1
+// CHECK: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* %{{.+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* %{{.+}}, i32 0, i32 0
+// CHECK: getelementptr [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i64 2
+// CHECK: br i1 %
+
+// CHECK: phi [[S_DOUBLE_TY]]*
+// CHECK: call {{.*}} [[S_DOUBLE_TY_COPY_CONSTR]]([[S_DOUBLE_TY]]*
+// CHECK: getelementptr [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i32 1
+// CHECK: icmp eq [[S_DOUBLE_TY]]* %
+// CHECK: br i1 %
+
+// CHECK: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* %{{.+}}, i32 0, i32 1
+// CHECK: call {{.*}} [[S_DOUBLE_TY_COPY_CONSTR]]([[S_DOUBLE_TY]]*
+// CHECK: ret void
+
+// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_MAIN_TY]]* noalias)
+// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0
+// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1
+// CHECK: call void [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF]])
+// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0
+// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} 2
+// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} -1
+// CHECK: call void [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_S_ARR_ELEM_REF]])
+// CHECK: icmp eq
+// CHECK: br i1
+// CHECK: ret i32
+
+// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
+// CHECK: alloca [[S_INT_TY]],
+// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32, align 128
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32],
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[LOC:%.+]])
+
+// CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]],
+
+// Store original variables in capture struct.
+// CHECK: [[VEC_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: store [2 x i32]* [[VEC_ADDR]], [2 x i32]** [[VEC_REF]],
+// CHECK: [[T_VAR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1
+// CHECK: store i32* [[T_VAR_ADDR]], i32** [[T_VAR_REF]],
+// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK: store [2 x [[S_INT_TY]]]* [[S_ARR_ADDR]], [2 x [[S_INT_TY]]]** [[S_ARR_REF]],
+// CHECK: [[VAR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3
+// CHECK: store [[S_INT_TY]]* [[VAR_ADDR]], [[S_INT_TY]]** [[VAR_REF]],
+
+// Allocate task.
+// Returns struct kmp_task_t {
+// [[KMP_TASK_T_TY]] task_data;
+// [[KMP_TASK_TMAIN_TY]] privates;
+// };
+// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 256, i64 32, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_TMAIN_TY]]*
+
+// Fill kmp_task_t->shareds by copying from original capture argument.
+// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[SHAREDS_REF_ADDR:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[SHAREDS_REF:%.+]] = load i8*, i8** [[SHAREDS_REF_ADDR]],
+// CHECK: [[CAPTURES_ADDR:%.+]] = bitcast [[CAP_TMAIN_TY]]* %{{.+}} to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[SHAREDS_REF]], i8* [[CAPTURES_ADDR]], i64 32, i32 8, i1 false)
+
+// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes).
+// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK: [[SHAREDS:%.+]] = bitcast i8* [[SHAREDS_REF]] to [[CAP_TMAIN_TY]]*
+
+// t_var;
+// CHECK: [[PRIVATE_T_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0
+// CHECK: [[T_VAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 1
+// CHECK: [[T_VAR_REF:%.+]] = load i{{.+}}*, i{{.+}}** [[T_VAR_ADDR_REF]],
+// CHECK: [[T_VAR:%.+]] = load i{{.+}}, i{{.+}}* [[T_VAR_REF]], align 128
+// CHECK: store i32 [[T_VAR]], i32* [[PRIVATE_T_VAR_REF]], align 128
+
+// vec;
+// CHECK: [[PRIVATE_VEC_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1
+// CHECK: [[VEC_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 0
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(
+
+// Constructors for s_arr and var.
+// a_arr;
+// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 2
+// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0
+// CHECK: getelementptr [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} 2
+// CHECK: call void [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* [[S_ARR_CUR:%[^,]+]],
+// CHECK: getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_CUR]], i{{.+}} 1
+// CHECK: icmp eq
+// CHECK: br i1
+
+// var;
+// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: [[VAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 3
+// CHECK: call void [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* [[PRIVATE_VAR_REF]],
+
+// Provide pointer to destructor function, which will destroy private variables at the end of the task.
+// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3
+// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)**
+// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]],
+
+// Start task.
+// CHECK: call void @__kmpc_taskloop([[LOC]], i32 [[GTID]], i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_TMAIN_TY]]*, [[KMP_TASK_TMAIN_TY]]*, i32)* [[TMAIN_DUP:@.+]] to i8*))
+
+// No destructors must be called for private copies of s_arr and var.
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: ret
+//
+
+// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_TMAIN_TY]]* noalias, i32** noalias, [2 x i32]** noalias, [2 x [[S_INT_TY]]]** noalias, [[S_INT_TY]]** noalias)
+// CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_TMAIN_TY]]*, [[PRIVATES_TMAIN_TY]]**
+// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 0
+// CHECK: [[ARG1:%.+]] = load i32**, i32*** %{{.+}},
+// CHECK: store i32* [[PRIV_T_VAR]], i32** [[ARG1]],
+// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 1
+// CHECK: [[ARG2:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}},
+// CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG2]],
+// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 2
+// CHECK: [[ARG3:%.+]] = load [2 x [[S_INT_TY]]]**, [2 x [[S_INT_TY]]]*** %{{.+}},
+// CHECK: store [2 x [[S_INT_TY]]]* [[PRIV_S_VAR]], [2 x [[S_INT_TY]]]** [[ARG3]],
+// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 3
+// CHECK: [[ARG4:%.+]] = load [[S_INT_TY]]**, [[S_INT_TY]]*** {{.+}},
+// CHECK: store [[S_INT_TY]]* [[PRIV_VAR]], [[S_INT_TY]]** [[ARG4]],
+// CHECK: ret void
+
+// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_TMAIN_TY]]* noalias)
+// CHECK: alloca i32*,
+// CHECK-DAG: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*,
+// CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*,
+// CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
+// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]],
+// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]],
+// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]])
+// CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]],
+// CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]],
+// CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]],
+// CHECK: [[PRIV_VAR:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[PRIV_VAR_ADDR]],
+
+// Privates actually are used.
+// CHECK-DAG: [[PRIV_VAR]]
+// CHECK-DAG: [[PRIV_T_VAR]]
+// CHECK-DAG: [[PRIV_S_ARR]]
+// CHECK-DAG: [[PRIV_VEC]]
+
+// CHECK: ret
+
+// CHECK: define internal void [[TMAIN_DUP]]([[KMP_TASK_TMAIN_TY]]*, [[KMP_TASK_TMAIN_TY]]*, i32)
+// CHECK: getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* %{{.+}}, i32 0, i32 2
+// CHECK: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* %{{.+}}, i32 0, i32 2
+// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* %{{.+}}, i32 0, i32 0
+// CHECK: getelementptr [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i64 2
+// CHECK: br i1 %
+
+// CHECK: phi [[S_INT_TY]]*
+// CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]*
+// CHECK: getelementptr [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i32 1
+// CHECK: icmp eq [[S_INT_TY]]* %
+// CHECK: br i1 %
+
+// CHECK: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* %{{.+}}, i32 0, i32 3
+// CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]*
+// CHECK: ret void
+
+// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_TMAIN_TY]]* noalias)
+// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[PRIVATE_VAR_REF]])
+// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0
+// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} 2
+// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} -1
+// CHECK: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[PRIVATE_S_ARR_ELEM_REF]])
+// CHECK: icmp eq
+// CHECK: br i1
+// CHECK: ret i32
+
+#endif
+#else
+// ARRAY-LABEL: array_func
+struct St {
+ int a, b;
+ St() : a(0), b(0) {}
+ St(const St &) {}
+ ~St() {}
+};
+
+void array_func(int n, float a[n], St s[2]) {
+// ARRAY: call i8* @__kmpc_omp_task_alloc(
+// ARRAY: call void @__kmpc_taskloop(
+// ARRAY: store float** %{{.+}}, float*** %{{.+}},
+// ARRAY: store %struct.St** %{{.+}}, %struct.St*** %{{.+}},
+#pragma omp taskloop firstprivate(a, s)
+ for (int i = 0; i < 10; ++i)
+ ;
+}
+#endif
+
diff --git a/test/OpenMP/taskloop_firstprivate_messages.cpp b/test/OpenMP/taskloop_firstprivate_messages.cpp
index e2e87e4697a5d..fe22311f650cd 100644
--- a/test/OpenMP/taskloop_firstprivate_messages.cpp
+++ b/test/OpenMP/taskloop_firstprivate_messages.cpp
@@ -295,9 +295,9 @@ int main(int argc, char **argv) {
#pragma omp taskloop firstprivate(i) // expected-note {{defined as firstprivate}}
for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp taskloop' directive may not be firstprivate, predetermined as private}}
foo();
-#pragma omp parallel reduction(+ : i)
-#pragma omp taskloop firstprivate(i) // expected-note {{defined as firstprivate}}
- for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp taskloop' directive may not be firstprivate, predetermined as private}}
+#pragma omp parallel reduction(+ : i) // expected-note 4 {{defined as reduction}}
+#pragma omp taskloop firstprivate(i) //expected-error {{argument of a reduction clause of a parallel construct must not appear in a firstprivate clause on a task construct}}
+ for (i = 0; i < argc; ++i) // expected-error 3 {{reduction variables may not be accessed in an explicit task}}
foo();
#pragma omp parallel
#pragma omp taskloop firstprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
diff --git a/test/OpenMP/taskloop_lastprivate_codegen.cpp b/test/OpenMP/taskloop_lastprivate_codegen.cpp
new file mode 100644
index 0000000000000..8414b6f963f98
--- /dev/null
+++ b/test/OpenMP/taskloop_lastprivate_codegen.cpp
@@ -0,0 +1,519 @@
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=ARRAY %s
+// expected-no-diagnostics
+// REQUIRES: x86-registered-target
+// It doesn't pass on win32.
+// REQUIRES: shell
+#ifndef ARRAY
+#ifndef HEADER
+#define HEADER
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a) {}
+ S() : f() {}
+ S(const S &s, T t = T()) : f(s.f + t) {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+volatile double g;
+
+// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32 }
+// CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double }
+// CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [2 x [[S_DOUBLE_TY]]], [[S_DOUBLE_TY]], i32, [2 x i32]
+// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { [2 x i32]*, i32*, [2 x [[S_DOUBLE_TY]]]*, [[S_DOUBLE_TY]]*, i{{[0-9]+}}* }
+// CHECK-DAG: [[KMP_TASK_MAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [[PRIVATES_MAIN_TY]] }
+// CHECK-DAG: [[S_INT_TY:%.+]] = type { i32 }
+// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { [2 x i32]*, i32*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* }
+// CHECK-DAG: [[PRIVATES_TMAIN_TY:%.+]] = type { i32, [2 x i32], [2 x [[S_INT_TY]]], [[S_INT_TY]], [104 x i8] }
+// CHECK-DAG: [[KMP_TASK_TMAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [{{[0-9]+}} x i8], [[PRIVATES_TMAIN_TY]] }
+template <typename T>
+T tmain() {
+ S<T> ttt;
+ S<T> test;
+ T t_var __attribute__((aligned(128))) = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> var(3);
+#pragma omp taskloop lastprivate(t_var, vec, s_arr, s_arr, var, var)
+ for (int i = 0; i < 10; ++i) {
+ vec[0] = t_var;
+ s_arr[0] = var;
+ }
+ return T();
+}
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA: [[G:@.+]] = global double
+ // LAMBDA: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0,
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
+
+// LAMBDA: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_MAIN_TY:%[^*]+]]*, [[KMP_TASK_MAIN_TY]]*, i32)* [[MAIN_DUP:@.+]] to i8*))
+// LAMBDA: ret
+#pragma omp taskloop lastprivate(g, sivar)
+ for (int i = 0; i < 10; ++i) {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]]
+
+ // LAMBDA: store double* %{{.+}}, double** %{{.+}},
+ // LAMBDA: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}* noalias)
+ g = 1;
+ sivar = 11;
+ // LAMBDA: store double 1.0{{.+}}, double* %{{.+}},
+ // LAMBDA: store i{{[0-9]+}} 11, i{{[0-9]+}}* %{{.+}},
+ // LAMBDA: call void [[INNER_LAMBDA]](%
+ // LAMBDA: icmp ne i32 %{{.+}}, 0
+ // LAMBDA: br i1
+ // LAMBDA: load double, double* %
+ // LAMBDA: store volatile double %
+ // LAMBDA: load i32, i32* %
+ // LAMBDA: store i32 %
+ // LAMBDA: ret
+ [&]() {
+ g = 2;
+ sivar = 22;
+ }();
+ }
+ }();
+ return 0;
+#elif defined(BLOCKS)
+ // BLOCKS: [[G:@.+]] = global double
+ // BLOCKS-LABEL: @main
+ // BLOCKS: call void {{%.+}}(i8
+ ^{
+ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
+ // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+ // BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
+ // BLOCKS: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_MAIN_TY:%[^*]+]]*, [[KMP_TASK_MAIN_TY]]*, i32)* [[MAIN_DUP:@.+]] to i8*))
+ // BLOCKS: ret
+#pragma omp taskloop lastprivate(g, sivar)
+ for (int i = 0; i < 10; ++i) {
+ // BLOCKS: define {{.+}} void {{@.+}}(i8*
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS: store double 2.0{{.+}}, double*
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS-NOT: [[ISVAR]]{{[[^:word:]]}}
+ // BLOCKS: store i{{[0-9]+}} 22, i{{[0-9]+}}*
+ // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}
+ // BLOCKS: ret
+
+ // BLOCKS: store double* %{{.+}}, double** %{{.+}},
+ // BLOCKS: store i{{[0-9]+}}* %{{.+}}, i{{[0-9]+}}** %{{.+}},
+ // BLOCKS: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}* noalias)
+ g = 1;
+ sivar = 11;
+ // BLOCKS: store double 1.0{{.+}}, double* %{{.+}},
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS: store i{{[0-9]+}} 11, i{{[0-9]+}}* %{{.+}},
+ // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}
+ // BLOCKS: call void {{%.+}}(i8
+ // BLOCKS: icmp ne i32 %{{.+}}, 0
+ // BLOCKS: br i1
+ // BLOCKS: load double, double* %
+ // BLOCKS: store volatile double %
+ // BLOCKS: load i32, i32* %
+ // BLOCKS: store i32 %
+ ^{
+ g = 2;
+ sivar = 22;
+ }();
+ }
+ }();
+ return 0;
+#else
+ S<double> ttt;
+ S<double> test;
+ int t_var = 0;
+ int vec[] = {1, 2};
+ S<double> s_arr[] = {1, 2};
+ S<double> var(3);
+#pragma omp taskloop lastprivate(var, t_var, s_arr, vec, s_arr, var, sivar)
+ for (int i = 0; i < 10; ++i) {
+ vec[0] = t_var;
+ s_arr[0] = var;
+ sivar = 33;
+ }
+ return tmain<int>();
+#endif
+}
+
+// CHECK: [[SIVAR:.+]] = internal global i{{[0-9]+}} 0,
+// CHECK: define i{{[0-9]+}} @main()
+// CHECK: alloca [[S_DOUBLE_TY]],
+// CHECK: [[TEST:%.+]] = alloca [[S_DOUBLE_TY]],
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32],
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]],
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]],
+// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[LOC:%.+]])
+
+// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR:@.+]]([[S_DOUBLE_TY]]* [[TEST]])
+
+// Store original variables in capture struct.
+// CHECK: [[VEC_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: store [2 x i32]* [[VEC_ADDR]], [2 x i32]** [[VEC_REF]],
+// CHECK: [[T_VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1
+// CHECK: store i32* [[T_VAR_ADDR]], i32** [[T_VAR_REF]],
+// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK: store [2 x [[S_DOUBLE_TY]]]* [[S_ARR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[S_ARR_REF]],
+// CHECK: [[VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3
+// CHECK: store [[S_DOUBLE_TY]]* [[VAR_ADDR]], [[S_DOUBLE_TY]]** [[VAR_REF]],
+// CHECK: [[SIVAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 4
+// CHECK: store i{{[0-9]+}}* [[SIVAR]], i{{[0-9]+}}** [[SIVAR_REF]],
+
+// Allocate task.
+// Returns struct kmp_task_t {
+// [[KMP_TASK_T]] task_data;
+// [[KMP_TASK_MAIN_TY]] privates;
+// };
+// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 112, i64 40, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_MAIN_TY]]*
+
+// Fill kmp_task_t->shareds by copying from original capture argument.
+// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[SHAREDS_REF_ADDR:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[SHAREDS_REF:%.+]] = load i8*, i8** [[SHAREDS_REF_ADDR]],
+// CHECK: [[CAPTURES_ADDR:%.+]] = bitcast [[CAP_MAIN_TY]]* %{{.+}} to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[SHAREDS_REF]], i8* [[CAPTURES_ADDR]], i64 40, i32 8, i1 false)
+
+// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes).
+// Also copy address of private copy to the corresponding shareds reference.
+// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+
+// Constructors for s_arr and var.
+// s_arr;
+// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR]]([[S_DOUBLE_TY]]* [[S_ARR_CUR:%[^,]+]])
+// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* [[S_ARR_CUR]], i{{.+}} 1
+// CHECK: icmp eq
+// CHECK: br i1
+
+// var;
+// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1
+// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF]])
+
+// t_var;
+// vec;
+// sivar;
+
+// Provide pointer to destructor function, which will destroy private variables at the end of the task.
+// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3
+// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)**
+// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]],
+
+// Start task.
+// CHECK: call void @__kmpc_taskloop([[LOC]], i32 [[GTID]], i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_MAIN_TY]]*, [[KMP_TASK_MAIN_TY]]*, i32)* [[MAIN_DUP:@.+]] to i8*))
+
+// CHECK: = call i{{.+}} [[TMAIN_INT:@.+]]()
+
+// No destructors must be called for private copies of s_arr and var.
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: call void [[S_DOUBLE_TY_DESTR:@.+]]([[S_DOUBLE_TY]]*
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: ret
+//
+
+// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_MAIN_TY]]* noalias, [[S_DOUBLE_TY]]** noalias, i32** noalias, [2 x [[S_DOUBLE_TY]]]** noalias, [2 x i32]** noalias, i32** noalias)
+// CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_MAIN_TY]]*, [[PRIVATES_MAIN_TY]]**
+// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 0
+// CHECK: [[ARG3:%.+]] = load [2 x [[S_DOUBLE_TY]]]**, [2 x [[S_DOUBLE_TY]]]*** %{{.+}},
+// CHECK: store [2 x [[S_DOUBLE_TY]]]* [[PRIV_S_VAR]], [2 x [[S_DOUBLE_TY]]]** [[ARG3]],
+// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 1
+// CHECK: [[ARG1:%.+]] = load [[S_DOUBLE_TY]]**, [[S_DOUBLE_TY]]*** {{.+}},
+// CHECK: store [[S_DOUBLE_TY]]* [[PRIV_VAR]], [[S_DOUBLE_TY]]** [[ARG1]],
+// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 2
+// CHECK: [[ARG2:%.+]] = load i32**, i32*** %{{.+}},
+// CHECK: store i32* [[PRIV_T_VAR]], i32** [[ARG2]],
+// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 3
+// CHECK: [[ARG4:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}},
+// CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG4]],
+// CHECK: [[PRIV_SIVAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 4
+// CHECK: [[ARG5:%.+]] = load i{{[0-9]+}}**, i{{[0-9]+}}*** %{{.+}},
+// CHECK: store i{{[0-9]+}}* [[PRIV_SIVAR]], i{{[0-9]+}}** [[ARG5]],
+// CHECK: ret void
+
+// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_MAIN_TY]]* noalias)
+
+// CHECK: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]]*,
+// CHECK: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*,
+// CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*,
+// CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*,
+// CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*,
+// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]],
+// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]],
+
+// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]])
+
+// CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]],
+// CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]],
+// CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]],
+// CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]],
+// CHECK: [[PRIV_SIVAR:%.+]] = load i32*, i32** [[PRIV_SIVAR_ADDR]],
+
+// Privates actually are used.
+// CHECK-DAG: [[PRIV_VAR]]
+// CHECK-DAG: [[PRIV_T_VAR]]
+// CHECK-DAG: [[PRIV_S_ARR]]
+// CHECK-DAG: [[PRIV_VEC]]
+// CHECK-DAG: [[PRIV_SIVAR]]
+
+// CHECK: icmp ne i32 %{{.+}}, 0
+// CHECK-NEXT: br i1
+// CHECK: bitcast [[S_DOUBLE_TY]]* %{{.+}} to i8*
+// CHECK: bitcast [[S_DOUBLE_TY]]* %{{.+}} to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %
+// CHECK: load i32, i32* %
+// CHECK: store i32 %{{.+}}, i32* %
+// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* %
+// CHECK: phi [[S_DOUBLE_TY]]*
+// CHECK: phi [[S_DOUBLE_TY]]*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %
+// CHECK: icmp eq [[S_DOUBLE_TY]]* %
+// CHECK-NEXT: br i1
+// CHECK: bitcast [2 x i32]* %{{.+}} to i8*
+// CHECK: bitcast [2 x i32]* %{{.+}} to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %
+// CHECK: load i32, i32* %
+// CHECK: store i32 %{{.+}}, i32* %
+// CHECK: br label
+// CHECK: ret
+
+// CHECK: define internal void [[MAIN_DUP]]([[KMP_TASK_MAIN_TY]]*, [[KMP_TASK_MAIN_TY]]*, i32)
+// CHECK: getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* %{{.+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* %{{.+}}, i32 0, i32 8
+// CHECK: load i32, i32* %
+// CHECK: store i32 %{{.+}}, i32* %
+// CHECK: getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* %{{.+}}, i32 0, i32 1
+// CHECK: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* %{{.+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* %{{.+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i64 2
+// CHECK: br label %
+
+// CHECK: phi [[S_DOUBLE_TY]]*
+// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR]]([[S_DOUBLE_TY]]*
+// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i64 1
+// CHECK: icmp eq [[S_DOUBLE_TY]]* %
+// CHECK: br i1 %
+
+// CHECK: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* %{{.+}}, i32 0, i32 1
+// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR]]([[S_DOUBLE_TY]]*
+// CHECK: ret void
+
+// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_MAIN_TY]]* noalias)
+// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0
+// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1
+// CHECK: call {{.*}} [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF]])
+// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0
+// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} 2
+// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} -1
+// CHECK: call {{.*}} [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_S_ARR_ELEM_REF]])
+// CHECK: icmp eq
+// CHECK: br i1
+// CHECK: ret i32
+
+// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
+// CHECK: alloca [[S_INT_TY]],
+// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32, align 128
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32],
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[LOC:%.+]])
+
+// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
+
+// Store original variables in capture struct.
+// CHECK: [[VEC_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: store [2 x i32]* [[VEC_ADDR]], [2 x i32]** [[VEC_REF]],
+// CHECK: [[T_VAR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1
+// CHECK: store i32* [[T_VAR_ADDR]], i32** [[T_VAR_REF]],
+// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK: store [2 x [[S_INT_TY]]]* [[S_ARR_ADDR]], [2 x [[S_INT_TY]]]** [[S_ARR_REF]],
+// CHECK: [[VAR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3
+// CHECK: store [[S_INT_TY]]* [[VAR_ADDR]], [[S_INT_TY]]** [[VAR_REF]],
+
+// Allocate task.
+// Returns struct kmp_task_t {
+// [[KMP_TASK_T_TY]] task_data;
+// [[KMP_TASK_TMAIN_TY]] privates;
+// };
+// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 256, i64 32, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_TMAIN_TY]]*
+
+// Fill kmp_task_t->shareds by copying from original capture argument.
+// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[SHAREDS_REF_ADDR:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[SHAREDS_REF:%.+]] = load i8*, i8** [[SHAREDS_REF_ADDR]],
+// CHECK: [[CAPTURES_ADDR:%.+]] = bitcast [[CAP_TMAIN_TY]]* %{{.+}} to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[SHAREDS_REF]], i8* [[CAPTURES_ADDR]], i64 32, i32 8, i1 false)
+
+// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes).
+// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+
+// t_var;
+// vec;
+
+// Constructors for s_arr and var.
+// a_arr;
+// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0
+// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} 2
+// CHECK: call {{.*}} [[S_INT_TY_CONSTR]]([[S_INT_TY]]* [[S_ARR_CUR:%[^,]+]])
+// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_CUR]], i{{.+}} 1
+// CHECK: icmp eq
+// CHECK: br i1
+
+// var;
+// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: call {{.*}} [[S_INT_TY_CONSTR]]([[S_INT_TY]]* [[PRIVATE_VAR_REF]])
+
+// Provide pointer to destructor function, which will destroy private variables at the end of the task.
+// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3
+// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)**
+// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]],
+
+// Start task.
+// CHECK: call void @__kmpc_taskloop([[LOC]], i32 [[GTID]], i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_TMAIN_TY]]*, [[KMP_TASK_TMAIN_TY]]*, i32)* [[TMAIN_DUP:@.+]] to i8*))
+
+// No destructors must be called for private copies of s_arr and var.
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: ret
+//
+
+// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_TMAIN_TY]]* noalias, i32** noalias, [2 x i32]** noalias, [2 x [[S_INT_TY]]]** noalias, [[S_INT_TY]]** noalias)
+// CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_TMAIN_TY]]*, [[PRIVATES_TMAIN_TY]]**
+// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 0
+// CHECK: [[ARG1:%.+]] = load i32**, i32*** %{{.+}},
+// CHECK: store i32* [[PRIV_T_VAR]], i32** [[ARG1]],
+// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 1
+// CHECK: [[ARG2:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}},
+// CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG2]],
+// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 2
+// CHECK: [[ARG3:%.+]] = load [2 x [[S_INT_TY]]]**, [2 x [[S_INT_TY]]]*** %{{.+}},
+// CHECK: store [2 x [[S_INT_TY]]]* [[PRIV_S_VAR]], [2 x [[S_INT_TY]]]** [[ARG3]],
+// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 3
+// CHECK: [[ARG4:%.+]] = load [[S_INT_TY]]**, [[S_INT_TY]]*** {{.+}},
+// CHECK: store [[S_INT_TY]]* [[PRIV_VAR]], [[S_INT_TY]]** [[ARG4]],
+// CHECK: ret void
+
+// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_TMAIN_TY]]* noalias)
+// CHECK: alloca i32*,
+// CHECK-DAG: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*,
+// CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*,
+// CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
+// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]],
+// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]],
+// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]])
+// CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]],
+// CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]],
+// CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]],
+// CHECK: [[PRIV_VAR:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[PRIV_VAR_ADDR]],
+
+// Privates actually are used.
+// CHECK-DAG: [[PRIV_VAR]]
+// CHECK-DAG: [[PRIV_T_VAR]]
+// CHECK-DAG: [[PRIV_S_ARR]]
+// CHECK-DAG: [[PRIV_VEC]]
+
+// CHECK: icmp ne i32 %{{.+}}, 0
+// CHECK-NEXT: br i1
+// CHECK: load i32, i32* %
+// CHECK: store i32 %{{.+}}, i32* %
+// CHECK: bitcast [2 x i32]* %{{.+}} to i8*
+// CHECK: bitcast [2 x i32]* %{{.+}} to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %
+// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* %
+// CHECK: phi [[S_INT_TY]]*
+// CHECK: phi [[S_INT_TY]]*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %
+// CHECK: icmp eq [[S_INT_TY]]* %
+// CHECK-NEXT: br i1
+// CHECK: bitcast [[S_INT_TY]]* %{{.+}} to i8*
+// CHECK: bitcast [[S_INT_TY]]* %{{.+}} to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %
+// CHECK: br label
+// CHECK: ret
+
+// CHECK: define internal void [[TMAIN_DUP]]([[KMP_TASK_TMAIN_TY]]*, [[KMP_TASK_TMAIN_TY]]*, i32)
+// CHECK: getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* %{{.+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* %{{.+}}, i32 0, i32 8
+// CHECK: load i32, i32* %
+// CHECK: store i32 %{{.+}}, i32* %
+// CHECK: getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* %{{.+}}, i32 0, i32 2
+// CHECK: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* %{{.+}}, i32 0, i32 2
+// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* %{{.+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i64 2
+// CHECK: br label %
+
+// CHECK: phi [[S_INT_TY]]*
+// CHECK: call {{.*}} [[S_INT_TY_CONSTR]]([[S_INT_TY]]*
+// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i64 1
+// CHECK: icmp eq [[S_INT_TY]]* %
+// CHECK: br i1 %
+
+// CHECK: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* %{{.+}}, i32 0, i32 3
+// CHECK: call {{.*}} [[S_INT_TY_CONSTR]]([[S_INT_TY]]*
+// CHECK: ret void
+
+// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_TMAIN_TY]]* noalias)
+// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[PRIVATE_VAR_REF]])
+// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0
+// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} 2
+// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} -1
+// CHECK: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[PRIVATE_S_ARR_ELEM_REF]])
+// CHECK: icmp eq
+// CHECK: br i1
+// CHECK: ret i32
+
+#endif
+#else
+// ARRAY-LABEL: array_func
+struct St {
+ int a, b;
+ St() : a(0), b(0) {}
+ St(const St &) {}
+ ~St() {}
+};
+
+void array_func(int n, float a[n], St s[2]) {
+// ARRAY: call i8* @__kmpc_omp_task_alloc(
+// ARRAY: call void @__kmpc_taskloop(
+// ARRAY: store float** %{{.+}}, float*** %{{.+}},
+// ARRAY: store %struct.St** %{{.+}}, %struct.St*** %{{.+}},
+// ARRAY: icmp ne i32 %{{.+}}, 0
+// ARRAY: store float* %{{.+}}, float** %{{.+}},
+// ARRAY: store %struct.St* %{{.+}}, %struct.St** %{{.+}},
+#pragma omp taskloop lastprivate(a, s)
+ for (int i = 0; i < 10; ++i)
+ ;
+}
+#endif
+
diff --git a/test/OpenMP/taskloop_loop_messages.cpp b/test/OpenMP/taskloop_loop_messages.cpp
index 02518e572f3af..291cbdbe718c9 100644
--- a/test/OpenMP/taskloop_loop_messages.cpp
+++ b/test/OpenMP/taskloop_loop_messages.cpp
@@ -427,12 +427,12 @@ public:
typedef int difference_type;
typedef std::random_access_iterator_tag iterator_category;
};
-// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 2nd argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}}
// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
int operator-(GoodIter a, GoodIter b) { return 0; }
// expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}}
GoodIter operator-(GoodIter a) { return a; }
-// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 2nd argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}}
// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
GoodIter operator-(GoodIter a, int v) { return GoodIter(); }
// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}}
@@ -483,7 +483,7 @@ int test_with_random_access_iterator() {
#pragma omp taskloop
for (begin = GoodIter(0); begin < end; ++begin)
++begin;
-// expected-error@+4 {{invalid operands to binary expression ('GoodIter' and 'Iter0')}}
+// expected-error@+4 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}}
// expected-error@+3 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
#pragma omp parallel
#pragma omp taskloop
diff --git a/test/OpenMP/taskloop_private_codegen.cpp b/test/OpenMP/taskloop_private_codegen.cpp
new file mode 100644
index 0000000000000..38b20c579393b
--- /dev/null
+++ b/test/OpenMP/taskloop_private_codegen.cpp
@@ -0,0 +1,420 @@
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=ARRAY %s
+// expected-no-diagnostics
+// REQUIRES: x86-registered-target
+// It doesn't pass on win32. Investigating.
+// REQUIRES: shell
+
+#ifndef ARRAY
+#ifndef HEADER
+#define HEADER
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a) {}
+ S() : f() {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+volatile double g;
+
+// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32 }
+// CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double }
+// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { i8 }
+// CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [2 x [[S_DOUBLE_TY]]], [[S_DOUBLE_TY]], i32, [2 x i32]
+// CHECK-DAG: [[KMP_TASK_MAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [[PRIVATES_MAIN_TY]] }
+// CHECK-DAG: [[S_INT_TY:%.+]] = type { i32 }
+// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { i8 }
+// CHECK-DAG: [[PRIVATES_TMAIN_TY:%.+]] = type { i32, [2 x i32], [2 x [[S_INT_TY]]], [[S_INT_TY]], [104 x i8] }
+// CHECK-DAG: [[KMP_TASK_TMAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [{{[0-9]+}} x i8], [[PRIVATES_TMAIN_TY]] }
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var __attribute__((aligned(128))) = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> var(3);
+#pragma omp taskloop private(t_var, vec, s_arr, s_arr, var, var)
+ for (int i = 0; i < 10; ++i) {
+ vec[0] = t_var;
+ s_arr[0] = var;
+ }
+ return T();
+}
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA: [[G:@.+]] = global double
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
+// LAMBDA: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* null)
+// LAMBDA: ret
+#pragma omp taskloop private(g, sivar)
+ for (int i = 0; i < 10; ++i) {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]]
+ // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 3, i{{[0-9]+}}* [[SIVAR_REF]]
+
+ // LAMBDA: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}* noalias)
+ g = 1;
+ sivar = 2;
+ // LAMBDA: store double 1.0{{.+}}, double* %{{.+}},
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* %{{.+}},
+ // LAMBDA: call void [[INNER_LAMBDA]](%
+ // LAMBDA: ret
+ [&]() {
+ g = 2;
+ sivar = 3;
+ }();
+ }
+ }();
+ return 0;
+#elif defined(BLOCKS)
+ // BLOCKS: [[G:@.+]] = global double
+ // BLOCKS-LABEL: @main
+ // BLOCKS: call void {{%.+}}(i8
+ ^{
+ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
+ // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+ // BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
+ // BLOCKS: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* null)
+ // BLOCKS: ret
+#pragma omp taskloop private(g, sivar)
+ for (int i = 0; i < 10; ++i) {
+ // BLOCKS: define {{.+}} void {{@.+}}(i8*
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS: store double 2.0{{.+}}, double*
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}
+ // BLOCKS: store i{{[0-9]+}} 4, i{{[0-9]+}}*
+ // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}
+ // BLOCKS: ret
+
+ // BLOCKS: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}* noalias)
+ g = 1;
+ sivar = 3;
+ // BLOCKS: store double 1.0{{.+}}, double* %{{.+}},
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS: store i{{[0-9]+}} 3, i{{[0-9]+}}* %{{.+}},
+ // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}
+ // BLOCKS: call void {{%.+}}(i8
+ ^{
+ g = 2;
+ sivar = 4;
+ }();
+ }
+ }();
+ return 0;
+#else
+ S<double> test;
+ int t_var = 0;
+ int vec[] = {1, 2};
+ S<double> s_arr[] = {1, 2};
+ S<double> var(3);
+#pragma omp taskloop private(var, t_var, s_arr, vec, s_arr, var, sivar)
+ for (int i = 0; i < 10; ++i) {
+ vec[0] = t_var;
+ s_arr[0] = var;
+ sivar = 8;
+ }
+#pragma omp task
+ g+=1;
+ return tmain<int>();
+#endif
+}
+
+// CHECK: define i{{[0-9]+}} @main()
+// CHECK: [[TEST:%.+]] = alloca [[S_DOUBLE_TY]],
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32],
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]],
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]],
+// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[LOC:%.+]])
+
+// CHECK: call {{.*}} [[S_DOUBLE_TY_DEF_CONSTR:@.+]]([[S_DOUBLE_TY]]* [[TEST]])
+
+// Do not store original variables in capture struct.
+// CHECK-NOT: getelementptr inbounds [[CAP_MAIN_TY]],
+
+// Allocate task.
+// Returns struct kmp_task_t {
+// [[KMP_TASK_T_TY]] task_data;
+// [[KMP_TASK_MAIN_TY]] privates;
+// };
+// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 112, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_MAIN_TY]]*
+
+// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes).
+// Also copy address of private copy to the corresponding shareds reference.
+// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+
+// Constructors for s_arr and var.
+// a_arr;
+// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0
+// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} 2
+// CHECK: call void [[S_DOUBLE_TY_DEF_CONSTR]]([[S_DOUBLE_TY]]* [[S_ARR_CUR:%.+]])
+// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* [[S_ARR_CUR]], i{{.+}} 1
+// CHECK: icmp eq
+// CHECK: br i1
+
+// var;
+// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1
+// CHECK: call void [[S_DOUBLE_TY_DEF_CONSTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF:%.+]])
+
+// Provide pointer to destructor function, which will destroy private variables at the end of the task.
+// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3
+// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)**
+// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]],
+
+// Start task.
+// CHECK: call void @__kmpc_taskloop([[LOC]], i32 [[GTID]], i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_MAIN_TY]]*, [[KMP_TASK_MAIN_TY]]*, i32)* [[MAIN_DUP:@.+]] to i8*))
+// CHECK: call i32 @__kmpc_omp_task([[LOC]], i32 [[GTID]], i8*
+
+// CHECK: = call i{{.+}} [[TMAIN_INT:@.+]]()
+
+// No destructors must be called for private copies of s_arr and var.
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: call void [[S_DOUBLE_TY_DESTR:@.+]]([[S_DOUBLE_TY]]*
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: ret
+//
+
+// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_MAIN_TY]]* noalias, [[S_DOUBLE_TY]]** noalias, i32** noalias, [2 x [[S_DOUBLE_TY]]]** noalias, [2 x i32]** noalias, i32** noalias)
+// CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_MAIN_TY]]*, [[PRIVATES_MAIN_TY]]**
+// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 0
+// CHECK: [[ARG3:%.+]] = load [2 x [[S_DOUBLE_TY]]]**, [2 x [[S_DOUBLE_TY]]]*** %{{.+}},
+// CHECK: store [2 x [[S_DOUBLE_TY]]]* [[PRIV_S_VAR]], [2 x [[S_DOUBLE_TY]]]** [[ARG3]],
+// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 1
+// CHECK: [[ARG1:%.+]] = load [[S_DOUBLE_TY]]**, [[S_DOUBLE_TY]]*** {{.+}},
+// CHECK: store [[S_DOUBLE_TY]]* [[PRIV_VAR]], [[S_DOUBLE_TY]]** [[ARG1]],
+// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 2
+// CHECK: [[ARG2:%.+]] = load i32**, i32*** %{{.+}},
+// CHECK: store i32* [[PRIV_T_VAR]], i32** [[ARG2]],
+// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 3
+// CHECK: [[ARG4:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}},
+// CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG4]],
+// CHECK: ret void
+
+// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_MAIN_TY]]* noalias)
+
+// CHECK: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]]*,
+// CHECK: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*,
+// CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*,
+// CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*,
+// CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*,
+// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]],
+// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]],
+// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]])
+// CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]],
+// CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]],
+// CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]],
+// CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]],
+// CHECK: [[PRIV_SIVAR:%.+]] = load i32*, i32** [[PRIV_SIVAR_ADDR]],
+
+// Privates actually are used.
+// CHECK-DAG: [[PRIV_VAR]]
+// CHECK-DAG: [[PRIV_T_VAR]]
+// CHECK-DAG: [[PRIV_S_ARR]]
+// CHECK-DAG: [[PRIV_VEC]]
+// CHECK_DAG: [[PRIV_SIVAR]]
+
+// CHECK: ret
+
+// CHECK: define internal void [[MAIN_DUP]]([[KMP_TASK_MAIN_TY]]*, [[KMP_TASK_MAIN_TY]]*, i32)
+// CHECK: getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* %{{.+}}, i32 0, i32 1
+// CHECK: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* %{{.+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* %{{.+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i64 2
+// CHECK: br label %
+
+// CHECK: phi [[S_DOUBLE_TY]]*
+// CHECK: call {{.*}} [[S_DOUBLE_TY_DEF_CONSTR]]([[S_DOUBLE_TY]]*
+// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i64 1
+// CHECK: icmp eq [[S_DOUBLE_TY]]* %
+// CHECK: br i1 %
+
+// CHECK: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* %{{.+}}, i32 0, i32 1
+// CHECK: call {{.*}} [[S_DOUBLE_TY_DEF_CONSTR]]([[S_DOUBLE_TY]]*
+// CHECK: ret void
+
+// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_MAIN_TY]]* noalias)
+// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0
+// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1
+// CHECK: call void [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF]])
+// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0
+// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} 2
+// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} -1
+// CHECK: call void [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_S_ARR_ELEM_REF]])
+// CHECK: icmp eq
+// CHECK: br i1
+// CHECK: ret i32
+
+// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
+// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32],
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[LOC:%.+]])
+
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
+
+// Do not store original variables in capture struct.
+// CHECK-NOT: getelementptr inbounds [[CAP_TMAIN_TY]],
+
+// Allocate task.
+// Returns struct kmp_task_t {
+// [[KMP_TASK_T_TY]] task_data;
+// [[KMP_TASK_TMAIN_TY]] privates;
+// };
+// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 256, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_TMAIN_TY]]*
+
+// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+
+// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes).
+// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+
+// Constructors for s_arr and var.
+// a_arr;
+// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0
+// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} 2
+// CHECK: call void [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[S_ARR_CUR:%.+]])
+// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_CUR]], i{{.+}} 1
+// CHECK: icmp eq
+// CHECK: br i1
+
+// var;
+// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: call void [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[PRIVATE_VAR_REF:%.+]])
+
+// Provide pointer to destructor function, which will destroy private variables at the end of the task.
+// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3
+// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)**
+// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]],
+
+// Start task.
+// CHECK: call void @__kmpc_taskloop([[LOC]], i32 [[GTID]], i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_TMAIN_TY]]*, [[KMP_TASK_TMAIN_TY]]*, i32)* [[TMAIN_DUP:@.+]] to i8*))
+
+// No destructors must be called for private copies of s_arr and var.
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: ret
+//
+
+// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_TMAIN_TY]]* noalias, i32** noalias, [2 x i32]** noalias, [2 x [[S_INT_TY]]]** noalias, [[S_INT_TY]]** noalias)
+// CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_TMAIN_TY]]*, [[PRIVATES_TMAIN_TY]]**
+// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 0
+// CHECK: [[ARG1:%.+]] = load i32**, i32*** %{{.+}},
+// CHECK: store i32* [[PRIV_T_VAR]], i32** [[ARG1]],
+// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 1
+// CHECK: [[ARG2:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}},
+// CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG2]],
+// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 2
+// CHECK: [[ARG3:%.+]] = load [2 x [[S_INT_TY]]]**, [2 x [[S_INT_TY]]]*** %{{.+}},
+// CHECK: store [2 x [[S_INT_TY]]]* [[PRIV_S_VAR]], [2 x [[S_INT_TY]]]** [[ARG3]],
+// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 3
+// CHECK: [[ARG4:%.+]] = load [[S_INT_TY]]**, [[S_INT_TY]]*** {{.+}},
+// CHECK: store [[S_INT_TY]]* [[PRIV_VAR]], [[S_INT_TY]]** [[ARG4]],
+// CHECK: ret void
+
+// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_TMAIN_TY]]* noalias)
+
+// CHECK: alloca i32*,
+// CHECK-DAG: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*,
+// CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*,
+// CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
+// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]],
+// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]],
+// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]])
+// CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]],
+// CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]],
+// CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]],
+// CHECK: [[PRIV_VAR:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[PRIV_VAR_ADDR]],
+
+// Privates actually are used.
+// CHECK-DAG: [[PRIV_VAR]]
+// CHECK-DAG: [[PRIV_T_VAR]]
+// CHECK-DAG: [[PRIV_S_ARR]]
+// CHECK-DAG: [[PRIV_VEC]]
+
+// CHECK: ret
+
+// CHECK: define internal void [[TMAIN_DUP]]([[KMP_TASK_TMAIN_TY]]*, [[KMP_TASK_TMAIN_TY]]*, i32)
+// CHECK: getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* %{{.+}}, i32 0, i32 2
+// CHECK: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* %{{.+}}, i32 0, i32 2
+// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* %{{.+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i64 2
+// CHECK: br label %
+
+// CHECK: phi [[S_INT_TY]]*
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]*
+// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i64 1
+// CHECK: icmp eq [[S_INT_TY]]* %
+// CHECK: br i1 %
+
+// CHECK: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* %{{.+}}, i32 0, i32 3
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]*
+// CHECK: ret void
+
+// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_TMAIN_TY]]* noalias)
+// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[PRIVATE_VAR_REF]])
+// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0
+// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} 2
+// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} -1
+// CHECK: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[PRIVATE_S_ARR_ELEM_REF]])
+// CHECK: icmp eq
+// CHECK: br i1
+// CHECK: ret i32
+
+#endif
+#else
+// ARRAY-LABEL: array_func
+struct St {
+ int a, b;
+ St() : a(0), b(0) {}
+ St &operator=(const St &) { return *this; };
+ ~St() {}
+};
+
+void array_func(int n, float a[n], St s[2]) {
+// ARRAY: call i8* @__kmpc_omp_task_alloc(
+// ARRAY: call void @__kmpc_taskloop(
+// ARRAY: store float** %{{.+}}, float*** %{{.+}},
+// ARRAY: store %struct.St** %{{.+}}, %struct.St*** %{{.+}},
+#pragma omp taskloop private(a, s)
+ for (int i = 0; i < 10; ++i)
+ ;
+}
+#endif
+
diff --git a/test/OpenMP/taskloop_private_messages.cpp b/test/OpenMP/taskloop_private_messages.cpp
index 3d00d3f252b38..367d59da69597 100644
--- a/test/OpenMP/taskloop_private_messages.cpp
+++ b/test/OpenMP/taskloop_private_messages.cpp
@@ -29,7 +29,11 @@ class S4 {
S4(); // expected-note {{implicitly declared private here}}
public:
- S4(int v) : a(v) {}
+ S4(int v) : a(v) {
+#pragma omp taskloop private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
};
class S5 {
int a;
@@ -37,6 +41,50 @@ class S5 {
public:
S5(int v) : a(v) {}
+ S5 &operator=(S5 &s) {
+#pragma omp taskloop private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S6 {
+public:
+ T a;
+
+ S6() : a(0) {}
+ S6(T v) : a(v) {
+#pragma omp taskloop private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+ S6 &operator=(S6 &s) {
+#pragma omp taskloop private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S7 : public T {
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(T v) : a(v) {
+#pragma omp taskloop private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp taskloop private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
};
S3 h;
@@ -126,6 +174,8 @@ using A::x;
int main(int argc, char **argv) {
S4 e(4);
S5 g(5);
+ S6<float> s6(0.0) , s6_0(1.0);
+ S7<S6<float> > s7(0.0) , s7_0(1.0);
int i;
int &j = i;
#pragma omp taskloop private // expected-error {{expected '(' after 'private'}}
@@ -190,6 +240,8 @@ int main(int argc, char **argv) {
for(int k = 0; k < argc; ++k)
si = k + 1;
- return 0;
+ s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}}
+ s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}}
+ return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
}
diff --git a/test/OpenMP/taskloop_simd_aligned_messages.cpp b/test/OpenMP/taskloop_simd_aligned_messages.cpp
index b62af044c60f1..b45f44fe1cf8b 100644
--- a/test/OpenMP/taskloop_simd_aligned_messages.cpp
+++ b/test/OpenMP/taskloop_simd_aligned_messages.cpp
@@ -196,6 +196,7 @@ int main(int argc, char **argv) {
#pragma omp taskloop simd aligned(h)
for (int k = 0; k < argc; ++k) ++k;
int *pargc = &argc;
+ // expected-note@+1 {{in instantiation of function template specialization 'foomain<int *, char>' requested here}}
foomain<int*,char>(pargc,argv);
return 0;
}
diff --git a/test/OpenMP/taskloop_simd_codegen.cpp b/test/OpenMP/taskloop_simd_codegen.cpp
new file mode 100644
index 0000000000000..dc60009ff2bd1
--- /dev/null
+++ b/test/OpenMP/taskloop_simd_codegen.cpp
@@ -0,0 +1,203 @@
+// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c++ -emit-llvm %s -o - -femit-all-decls | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls | FileCheck %s
+// expected-no-diagnostics
+// REQUIRES: x86-registered-target
+#ifndef HEADER
+#define HEADER
+
+// CHECK-LABEL: @main
+int main(int argc, char **argv) {
+// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%ident_t* [[DEFLOC:@.+]])
+// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 33, i64 72, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK1:@.+]] to i32 (i32, i8*)*))
+// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]*
+// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0
+// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5
+// CHECK: store i64 0, i64* [[DOWN]],
+// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 6
+// CHECK: store i64 9, i64* [[UP]],
+// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 7
+// CHECK: store i64 1, i64* [[ST]],
+// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
+// CHECK: call void @__kmpc_taskloop(%ident_t* [[DEFLOC]], i32 [[GTID]], i8* [[TASKV]], i32 1, i64* [[DOWN]], i64* [[UP]], i64 [[ST_VAL]], i32 0, i32 0, i64 0, i8* null)
+#pragma omp taskloop simd priority(argc)
+ for (int i = 0; i < 10; ++i)
+ ;
+// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 72, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK2:@.+]] to i32 (i32, i8*)*))
+// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]*
+// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0
+// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5
+// CHECK: store i64 0, i64* [[DOWN]],
+// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 6
+// CHECK: store i64 9, i64* [[UP]],
+// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 7
+// CHECK: store i64 1, i64* [[ST]],
+// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
+// CHECK: [[GRAINSIZE:%.+]] = zext i32 %{{.+}} to i64
+// CHECK: call void @__kmpc_taskloop(%ident_t* [[DEFLOC]], i32 [[GTID]], i8* [[TASKV]], i32 1, i64* [[DOWN]], i64* [[UP]], i64 [[ST_VAL]], i32 1, i32 1, i64 [[GRAINSIZE]], i8* null)
+#pragma omp taskloop simd nogroup grainsize(argc) simdlen(4)
+ for (int i = 0; i < 10; ++i)
+ ;
+// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 72, i64 24, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK3:@.+]] to i32 (i32, i8*)*))
+// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]*
+// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0
+// CHECK: [[IF:%.+]] = icmp ne i32 %{{.+}}, 0
+// CHECK: [[IF_INT:%.+]] = sext i1 [[IF]] to i32
+// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5
+// CHECK: store i64 0, i64* [[DOWN]],
+// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 6
+// CHECK: store i64 %{{.+}}, i64* [[UP]],
+// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 7
+// CHECK: store i64 1, i64* [[ST]],
+// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
+// CHECK: call void @__kmpc_taskloop(%ident_t* [[DEFLOC]], i32 [[GTID]], i8* [[TASKV]], i32 [[IF_INT]], i64* [[DOWN]], i64* [[UP]], i64 [[ST_VAL]], i32 0, i32 2, i64 4, i8* null)
+ int i;
+#pragma omp taskloop simd if(argc) shared(argc, argv) collapse(2) num_tasks(4) safelen(32)
+ for (i = 0; i < argc; ++i)
+ for (int j = argc; j < argv[argc][argc]; ++j)
+ ;
+}
+
+// CHECK: define internal i32 [[TASK1]](
+// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* %{{.+}}, i32 0, i32 5
+// CHECK: [[DOWN_VAL:%.+]] = load i64, i64* [[DOWN]],
+// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 6
+// CHECK: [[UP_VAL:%.+]] = load i64, i64* [[UP]],
+// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 7
+// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
+// CHECK: [[LITER:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 8
+// CHECK: [[LITER_VAL:%.+]] = load i32, i32* [[LITER]],
+// CHECK: store i64 [[DOWN_VAL]], i64* [[LB:%[^,]+]],
+// CHECK: store i64 [[UP_VAL]], i64* [[UB:%[^,]+]],
+// CHECK: store i64 [[ST_VAL]], i64* [[ST:%[^,]+]],
+// CHECK: store i32 [[LITER_VAL]], i32* [[LITER:%[^,]+]],
+// CHECK: [[LB_VAL:%.+]] = load i64, i64* [[LB]],
+// CHECK: [[LB_I32:%.+]] = trunc i64 [[LB_VAL]] to i32
+// CHECK: store i32 [[LB_I32]], i32* [[CNT:%.+]],
+// CHECK: br label
+// CHECK: [[VAL:%.+]] = load i32, i32* [[CNT]],{{.*}}!llvm.mem.parallel_loop_access [[LOOP1:!.+]]
+// CHECK: [[VAL_I64:%.+]] = sext i32 [[VAL]] to i64
+// CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]],{{.*}}!llvm.mem.parallel_loop_access [[LOOP1]]
+// CHECK: [[CMP:%.+]] = icmp ule i64 [[VAL_I64]], [[UB_VAL]]
+// CHECK: br i1 [[CMP]], label %{{.+}}, label %{{.+}}
+// CHECK: load i32, i32* %{{.*}}!llvm.mem.parallel_loop_access [[LOOP1]]
+// CHECK: store i32 %{{.*}}!llvm.mem.parallel_loop_access [[LOOP1]]
+// CHECK: load i32, i32* %{{.*}}!llvm.mem.parallel_loop_access [[LOOP1]]
+// CHECK: add nsw i32 %{{.+}}, 1
+// CHECK: store i32 %{{.+}}, i32* %{{.*}}!llvm.mem.parallel_loop_access [[LOOP1]]
+// CHECK: br label %{{.*}}!llvm.loop [[LOOP1]]
+// CHECK: ret i32 0
+
+// CHECK: define internal i32 [[TASK2]](
+// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* %{{.+}}, i32 0, i32 5
+// CHECK: [[DOWN_VAL:%.+]] = load i64, i64* [[DOWN]],
+// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 6
+// CHECK: [[UP_VAL:%.+]] = load i64, i64* [[UP]],
+// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 7
+// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
+// CHECK: [[LITER:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 8
+// CHECK: [[LITER_VAL:%.+]] = load i32, i32* [[LITER]],
+// CHECK: store i64 [[DOWN_VAL]], i64* [[LB:%[^,]+]],
+// CHECK: store i64 [[UP_VAL]], i64* [[UB:%[^,]+]],
+// CHECK: store i64 [[ST_VAL]], i64* [[ST:%[^,]+]],
+// CHECK: store i32 [[LITER_VAL]], i32* [[LITER:%[^,]+]],
+// CHECK: [[LB_VAL:%.+]] = load i64, i64* [[LB]],
+// CHECK: [[LB_I32:%.+]] = trunc i64 [[LB_VAL]] to i32
+// CHECK: store i32 [[LB_I32]], i32* [[CNT:%.+]],
+// CHECK: br label
+// CHECK: [[VAL:%.+]] = load i32, i32* [[CNT]],{{.*}}!llvm.mem.parallel_loop_access [[LOOP2:!.+]]
+// CHECK: [[VAL_I64:%.+]] = sext i32 [[VAL]] to i64
+// CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]],{{.*}}!llvm.mem.parallel_loop_access [[LOOP2]]
+// CHECK: [[CMP:%.+]] = icmp ule i64 [[VAL_I64]], [[UB_VAL]]
+// CHECK: br i1 [[CMP]], label %{{.+}}, label %{{.+}}
+// CHECK: load i32, i32* %{{.*}}!llvm.mem.parallel_loop_access [[LOOP2]]
+// CHECK: store i32 %{{.*}}!llvm.mem.parallel_loop_access [[LOOP2]]
+// CHECK: load i32, i32* %{{.*}}!llvm.mem.parallel_loop_access [[LOOP2]]
+// CHECK: add nsw i32 %{{.+}}, 1
+// CHECK: store i32 %{{.+}}, i32* %{{.*}}!llvm.mem.parallel_loop_access [[LOOP2]]
+// CHECK: br label %{{.*}}!llvm.loop [[LOOP2]]
+// CHECK: ret i32 0
+
+// CHECK: define internal i32 [[TASK3]](
+// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* %{{.+}}, i32 0, i32 5
+// CHECK: [[DOWN_VAL:%.+]] = load i64, i64* [[DOWN]],
+// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 6
+// CHECK: [[UP_VAL:%.+]] = load i64, i64* [[UP]],
+// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 7
+// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
+// CHECK: [[LITER:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 8
+// CHECK: [[LITER_VAL:%.+]] = load i32, i32* [[LITER]],
+// CHECK: store i64 [[DOWN_VAL]], i64* [[LB:%[^,]+]],
+// CHECK: store i64 [[UP_VAL]], i64* [[UB:%[^,]+]],
+// CHECK: store i64 [[ST_VAL]], i64* [[ST:%[^,]+]],
+// CHECK: store i32 [[LITER_VAL]], i32* [[LITER:%[^,]+]],
+// CHECK: [[LB_VAL:%.+]] = load i64, i64* [[LB]],
+// CHECK: store i64 [[LB_VAL]], i64* [[CNT:%.+]],
+// CHECK: br label
+// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK: br label %{{.*}}!llvm.loop
+// CHECK: ret i32 0
+
+// CHECK-LABEL: @_ZN1SC2Ei
+struct S {
+ int a;
+ S(int c) {
+// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%ident_t* [[DEFLOC:@.+]])
+// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 72, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK4:@.+]] to i32 (i32, i8*)*))
+// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]*
+// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0
+// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5
+// CHECK: store i64 0, i64* [[DOWN]],
+// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 6
+// CHECK: store i64 %{{.+}}, i64* [[UP]],
+// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 7
+// CHECK: store i64 1, i64* [[ST]],
+// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
+// CHECK: [[NUM_TASKS:%.+]] = zext i32 %{{.+}} to i64
+// CHECK: call void @__kmpc_taskloop(%ident_t* [[DEFLOC]], i32 [[GTID]], i8* [[TASKV]], i32 1, i64* [[DOWN]], i64* [[UP]], i64 [[ST_VAL]], i32 0, i32 2, i64 [[NUM_TASKS]], i8* null)
+#pragma omp taskloop simd shared(c) num_tasks(a) simdlen(64) safelen(8)
+ for (a = 0; a < c; ++a)
+ ;
+ }
+} s(1);
+
+// CHECK: define internal i32 [[TASK4]](
+// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* %{{.+}}, i32 0, i32 5
+// CHECK: [[DOWN_VAL:%.+]] = load i64, i64* [[DOWN]],
+// CHECK: [[UP:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 6
+// CHECK: [[UP_VAL:%.+]] = load i64, i64* [[UP]],
+// CHECK: [[ST:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 7
+// CHECK: [[ST_VAL:%.+]] = load i64, i64* [[ST]],
+// CHECK: [[LITER:%.+]] = getelementptr inbounds [[TD_TY]], [[TD_TY]]* %{{.+}}, i32 0, i32 8
+// CHECK: [[LITER_VAL:%.+]] = load i32, i32* [[LITER]],
+// CHECK: store i64 [[DOWN_VAL]], i64* [[LB:%[^,]+]],
+// CHECK: store i64 [[UP_VAL]], i64* [[UB:%[^,]+]],
+// CHECK: store i64 [[ST_VAL]], i64* [[ST:%[^,]+]],
+// CHECK: store i32 [[LITER_VAL]], i32* [[LITER:%[^,]+]],
+// CHECK: [[LB_VAL:%.+]] = load i64, i64* [[LB]],
+// CHECK: [[LB_I32:%.+]] = trunc i64 [[LB_VAL]] to i32
+// CHECK: store i32 [[LB_I32]], i32* [[CNT:%.+]],
+// CHECK: br label
+// CHECK: [[VAL:%.+]] = load i32, i32* [[CNT]],
+// CHECK: [[VAL_I64:%.+]] = sext i32 [[VAL]] to i64
+// CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]],
+// CHECK: [[CMP:%.+]] = icmp ule i64 [[VAL_I64]], [[UB_VAL]]
+// CHECK: br i1 [[CMP]], label %{{.+}}, label %{{.+}}
+// CHECK: load i32, i32* %
+// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK: store i32 %
+// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK: load i32, i32* %
+// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK: add nsw i32 %{{.+}}, 1
+// CHECK: store i32 %{{.+}}, i32* %
+// CHECK-NOT: !llvm.mem.parallel_loop_access
+// CHECK: br label %{{.*}}!llvm.loop
+// CHECK: ret i32 0
+
+// CHECK: !{!"llvm.loop.vectorize.enable", i1 true}
+// CHECK: !{!"llvm.loop.vectorize.width", i32 4}
+// CHECK: !{!"llvm.loop.vectorize.width", i32 32}
+// CHECK: !{!"llvm.loop.vectorize.width", i32 64}
+
+#endif
diff --git a/test/OpenMP/taskloop_simd_collapse_messages.cpp b/test/OpenMP/taskloop_simd_collapse_messages.cpp
index d178c0834d626..e4ce0c1df41ab 100644
--- a/test/OpenMP/taskloop_simd_collapse_messages.cpp
+++ b/test/OpenMP/taskloop_simd_collapse_messages.cpp
@@ -1,8 +1,13 @@
// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
void foo() {
}
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
bool foobool(int argc) {
return argc;
}
@@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp taskloop simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp taskloop simd', but found only 1}}
- // expected-error@+3 2 {{directive '#pragma omp taskloop simd' cannot contain more than one 'collapse' clause}}
- // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+ // expected-error@+6 2 {{directive '#pragma omp taskloop simd' cannot contain more than one 'collapse' clause}}
+ // expected-error@+5 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
#pragma omp taskloop simd collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp taskloop simd collapse (S) // expected-error {{'S' does not refer to a value}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp taskloop simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp taskloop simd collapse (1)
@@ -59,16 +71,27 @@ int main(int argc, char **argv) {
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp taskloop simd', but found only 1}}
#pragma omp taskloop simd collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}} expected-note {{as specified in 'collapse' clause}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp taskloop simd', but found only 1}}
- #pragma omp taskloop simd collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+ #pragma omp taskloop simd collapse (foobool(1) > 0 ? 1 : 2)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+3 {{expression is not an integral constant expression}}
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
// expected-error@+2 2 {{directive '#pragma omp taskloop simd' cannot contain more than one 'collapse' clause}}
// expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp taskloop simd collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp taskloop simd collapse (S1) // expected-error {{'S1' does not refer to a value}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+1 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp taskloop simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
// expected-error@+3 {{statement after '#pragma omp taskloop simd' must be a for loop}}
diff --git a/test/OpenMP/taskloop_simd_firstprivate_codegen.cpp b/test/OpenMP/taskloop_simd_firstprivate_codegen.cpp
new file mode 100644
index 0000000000000..0b87ddd9acb12
--- /dev/null
+++ b/test/OpenMP/taskloop_simd_firstprivate_codegen.cpp
@@ -0,0 +1,511 @@
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=ARRAY %s
+// expected-no-diagnostics
+// REQUIRES: x86-registered-target
+// It doesn't pass on win32.
+// REQUIRES: shell
+#ifndef ARRAY
+#ifndef HEADER
+#define HEADER
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a) {}
+ S() : f() {}
+ S(const S &s, T t = T()) : f(s.f + t) {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+volatile double g;
+
+// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32 }
+// CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double }
+// CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [2 x [[S_DOUBLE_TY]]], [[S_DOUBLE_TY]], i32, [2 x i32]
+// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type {{.*}}{ [2 x i32]*, i32, {{.*}}[2 x [[S_DOUBLE_TY]]]*, [[S_DOUBLE_TY]]*, i{{[0-9]+}}
+// CHECK-DAG: [[KMP_TASK_MAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [[PRIVATES_MAIN_TY]] }
+// CHECK-DAG: [[S_INT_TY:%.+]] = type { i32 }
+// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { [2 x i32]*, i32*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* }
+// CHECK-DAG: [[PRIVATES_TMAIN_TY:%.+]] = type { i32, [2 x i32], [2 x [[S_INT_TY]]], [[S_INT_TY]], [104 x i8] }
+// CHECK-DAG: [[KMP_TASK_TMAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [{{[0-9]+}} x i8], [[PRIVATES_TMAIN_TY]] }
+template <typename T>
+T tmain() {
+ S<T> ttt;
+ S<T> test(ttt);
+ T t_var __attribute__((aligned(128))) = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> var(3);
+#pragma omp taskloop simd firstprivate(t_var, vec, s_arr, s_arr, var, var)
+ for (int i = 0; i < 10; ++i) {
+ vec[0] = t_var;
+ s_arr[0] = var;
+ }
+ return T();
+}
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA: [[G:@.+]] = global double
+ // LAMBDA: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0,
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
+// LAMBDA: [[G_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0
+// LAMBDA: [[G_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 0
+// LAMBDA: [[G_VAL:%.+]] = load volatile double, double* [[G_ADDR_REF]]
+// LAMBDA: store volatile double [[G_VAL]], double* [[G_PRIVATE_ADDR]]
+
+// LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1
+// LAMBDA: [[SIVAR_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
+// LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_ADDR_REF]]
+// LAMBDA: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]]
+
+// LAMBDA: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* null)
+// LAMBDA: ret
+#pragma omp taskloop simd firstprivate(g, sivar)
+ for (int i = 0; i < 10; ++i) {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]]
+
+ // LAMBDA: store double* %{{.+}}, double** %{{.+}},
+ // LAMBDA: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}* noalias)
+ g = 1;
+ sivar = 11;
+ // LAMBDA: store double 1.0{{.+}}, double* %{{.+}},
+ // LAMBDA: store i{{[0-9]+}} 11, i{{[0-9]+}}* %{{.+}},
+ // LAMBDA: call void [[INNER_LAMBDA]](%
+ // LAMBDA: ret
+ [&]() {
+ g = 2;
+ sivar = 22;
+ }();
+ }
+ }();
+ return 0;
+#elif defined(BLOCKS)
+ // BLOCKS: [[G:@.+]] = global double
+ // BLOCKS-LABEL: @main
+ // BLOCKS: call void {{%.+}}(i8
+ ^{
+ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
+ // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+ // BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
+ // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0
+ // BLOCKS: [[G_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 0
+ // BLOCKS: [[G_VAL:%.+]] = load volatile double, double* [[G_ADDR_REF]]
+ // BLOCKS: store volatile double [[G_VAL]], double* [[G_PRIVATE_ADDR]]
+
+ // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1
+ // BLOCKS: [[SIVAR_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
+ // BLOCKS: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_ADDR_REF]]
+ // BLOCKS: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]]
+ // BLOCKS: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* null)
+ // BLOCKS: ret
+#pragma omp taskloop simd firstprivate(g, sivar)
+ for (int i = 0; i < 10; ++i) {
+ // BLOCKS: define {{.+}} void {{@.+}}(i8*
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS: store double 2.0{{.+}}, double*
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS-NOT: [[ISVAR]]{{[[^:word:]]}}
+ // BLOCKS: store i{{[0-9]+}} 22, i{{[0-9]+}}*
+ // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}
+ // BLOCKS: ret
+
+ // BLOCKS: store double* %{{.+}}, double** %{{.+}},
+ // BLOCKS: store i{{[0-9]+}}* %{{.+}}, i{{[0-9]+}}** %{{.+}},
+ // BLOCKS: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}* noalias)
+ g = 1;
+ sivar = 11;
+ // BLOCKS: store double 1.0{{.+}}, double* %{{.+}},
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS: store i{{[0-9]+}} 11, i{{[0-9]+}}* %{{.+}},
+ // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}
+ // BLOCKS: call void {{%.+}}(i8
+ ^{
+ g = 2;
+ sivar = 22;
+ }();
+ }
+ }();
+ return 0;
+#else
+ S<double> ttt;
+ S<double> test(ttt);
+ int t_var = 0;
+ int vec[] = {1, 2};
+ S<double> s_arr[] = {1, 2};
+ S<double> var(3);
+#pragma omp taskloop simd firstprivate(var, t_var, s_arr, vec, s_arr, var, sivar)
+ for (int i = 0; i < 10; ++i) {
+ vec[0] = t_var;
+ s_arr[0] = var;
+ sivar = 33;
+ }
+ return tmain<int>();
+#endif
+}
+
+// CHECK: [[SIVAR:.+]] = internal global i{{[0-9]+}} 0,
+// CHECK: define i{{[0-9]+}} @main()
+// CHECK: alloca [[S_DOUBLE_TY]],
+// CHECK: [[TEST:%.+]] = alloca [[S_DOUBLE_TY]],
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32],
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]],
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]],
+// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[LOC:%.+]])
+
+// CHECK: call {{.*}} [[S_DOUBLE_TY_COPY_CONSTR:@.+]]([[S_DOUBLE_TY]]* [[TEST]],
+
+// Store original variables in capture struct.
+// CHECK: [[VEC_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: store [2 x i32]* [[VEC_ADDR]], [2 x i32]** [[VEC_REF]],
+// CHECK: [[T_VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1
+// CHECK: [[T_VAR_VAL:%.+]] = load i32, i32* [[T_VAR_ADDR]],
+// CHECK: store i32 [[T_VAR_VAL]], i32* [[T_VAR_REF]],
+// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3
+// CHECK: store [2 x [[S_DOUBLE_TY]]]* [[S_ARR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[S_ARR_REF]],
+// CHECK: [[VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 4
+// CHECK: store [[S_DOUBLE_TY]]* [[VAR_ADDR]], [[S_DOUBLE_TY]]** [[VAR_REF]],
+// CHECK: [[SIVAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 5
+// CHECK: [[SIVAR_VAL:%.+]] = load i32, i32* [[SIVAR]],
+// CHECK: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_REF]],
+
+// Allocate task.
+// Returns struct kmp_task_t {
+// [[KMP_TASK_T]] task_data;
+// [[KMP_TASK_MAIN_TY]] privates;
+// };
+// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 112, i64 40, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_MAIN_TY]]*
+
+// Fill kmp_task_t->shareds by copying from original capture argument.
+// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[SHAREDS_REF_ADDR:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[SHAREDS_REF:%.+]] = load i8*, i8** [[SHAREDS_REF_ADDR]],
+// CHECK: [[CAPTURES_ADDR:%.+]] = bitcast [[CAP_MAIN_TY]]* %{{.+}} to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[SHAREDS_REF]], i8* [[CAPTURES_ADDR]], i64 40, i32 8, i1 false)
+
+// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes).
+// Also copy address of private copy to the corresponding shareds reference.
+// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+// CHECK: [[SHAREDS:%.+]] = bitcast i8* [[SHAREDS_REF]] to [[CAP_MAIN_TY]]*
+
+// Constructors for s_arr and var.
+// s_arr;
+// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 3
+// CHECK: load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[S_ARR_ADDR_REF]],
+// CHECK: call void [[S_DOUBLE_TY_COPY_CONSTR]]([[S_DOUBLE_TY]]* [[S_ARR_CUR:%[^,]+]],
+// CHECK: getelementptr [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* [[S_ARR_CUR]], i{{.+}} 1
+// CHECK: getelementptr [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} 1
+// CHECK: icmp eq
+// CHECK: br i1
+
+// var;
+// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1
+// CHECK: [[VAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 4
+// CHECK: [[VAR_REF:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[VAR_ADDR_REF]],
+// CHECK: call void [[S_DOUBLE_TY_COPY_CONSTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF]], [[S_DOUBLE_TY]]* {{.*}}[[VAR_REF]],
+
+// t_var;
+// CHECK: [[PRIVATE_T_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK: [[T_VAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 1
+// CHECK: [[T_VAR:%.+]] = load i{{.+}}, i{{.+}}* [[T_VAR_ADDR_REF]],
+// CHECK: store i32 [[T_VAR]], i32* [[PRIVATE_T_VAR_REF]],
+
+// vec;
+// CHECK: [[PRIVATE_VEC_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: [[VEC_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 0
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(
+
+// sivar;
+// CHECK: [[PRIVATE_SIVAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 4
+// CHECK: [[SIVAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 5
+// CHECK: [[SIVAR:%.+]] = load i{{.+}}, i{{.+}}* [[SIVAR_ADDR_REF]],
+// CHECK: store i32 [[SIVAR]], i32* [[PRIVATE_SIVAR_REF]],
+
+// Provide pointer to destructor function, which will destroy private variables at the end of the task.
+// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3
+// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)**
+// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]],
+
+// Start task.
+// CHECK: call void @__kmpc_taskloop([[LOC]], i32 [[GTID]], i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_MAIN_TY]]*, [[KMP_TASK_MAIN_TY]]*, i32)* [[MAIN_DUP:@.+]] to i8*))
+
+// CHECK: = call i{{.+}} [[TMAIN_INT:@.+]]()
+
+// No destructors must be called for private copies of s_arr and var.
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: call void [[S_DOUBLE_TY_DESTR:@.+]]([[S_DOUBLE_TY]]*
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: ret
+//
+
+// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_MAIN_TY]]* noalias, [[S_DOUBLE_TY]]** noalias, i32** noalias, [2 x [[S_DOUBLE_TY]]]** noalias, [2 x i32]** noalias, i32** noalias)
+// CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_MAIN_TY]]*, [[PRIVATES_MAIN_TY]]**
+// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 0
+// CHECK: [[ARG3:%.+]] = load [2 x [[S_DOUBLE_TY]]]**, [2 x [[S_DOUBLE_TY]]]*** %{{.+}},
+// CHECK: store [2 x [[S_DOUBLE_TY]]]* [[PRIV_S_VAR]], [2 x [[S_DOUBLE_TY]]]** [[ARG3]],
+// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 1
+// CHECK: [[ARG1:%.+]] = load [[S_DOUBLE_TY]]**, [[S_DOUBLE_TY]]*** {{.+}},
+// CHECK: store [[S_DOUBLE_TY]]* [[PRIV_VAR]], [[S_DOUBLE_TY]]** [[ARG1]],
+// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 2
+// CHECK: [[ARG2:%.+]] = load i32**, i32*** %{{.+}},
+// CHECK: store i32* [[PRIV_T_VAR]], i32** [[ARG2]],
+// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 3
+// CHECK: [[ARG4:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}},
+// CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG4]],
+// CHECK: [[PRIV_SIVAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 4
+// CHECK: [[ARG5:%.+]] = load i{{[0-9]+}}**, i{{[0-9]+}}*** %{{.+}},
+// CHECK: store i{{[0-9]+}}* [[PRIV_SIVAR]], i{{[0-9]+}}** [[ARG5]],
+// CHECK: ret void
+
+// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_MAIN_TY]]* noalias)
+
+// CHECK: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]]*,
+// CHECK: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*,
+// CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*,
+// CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*,
+// CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*,
+// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]],
+// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]],
+
+// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]])
+
+// CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]],
+// CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]],
+// CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]],
+// CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]],
+// CHECK: [[PRIV_SIVAR:%.+]] = load i32*, i32** [[PRIV_SIVAR_ADDR]],
+
+// Privates actually are used.
+// CHECK-DAG: [[PRIV_VAR]]
+// CHECK-DAG: [[PRIV_T_VAR]]
+// CHECK-DAG: [[PRIV_S_ARR]]
+// CHECK-DAG: [[PRIV_VEC]]
+// CHECK-DAG: [[PRIV_SIVAR]]
+
+// CHECK: ret
+
+// CHECK: define internal void [[MAIN_DUP]]([[KMP_TASK_MAIN_TY]]*, [[KMP_TASK_MAIN_TY]]*, i32)
+// CHECK: getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* %{{.+}}, i32 0, i32 1
+// CHECK: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* %{{.+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* %{{.+}}, i32 0, i32 0
+// CHECK: getelementptr [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i64 2
+// CHECK: br i1 %
+
+// CHECK: phi [[S_DOUBLE_TY]]*
+// CHECK: call {{.*}} [[S_DOUBLE_TY_COPY_CONSTR]]([[S_DOUBLE_TY]]*
+// CHECK: getelementptr [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i32 1
+// CHECK: icmp eq [[S_DOUBLE_TY]]* %
+// CHECK: br i1 %
+
+// CHECK: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* %{{.+}}, i32 0, i32 1
+// CHECK: call {{.*}} [[S_DOUBLE_TY_COPY_CONSTR]]([[S_DOUBLE_TY]]*
+// CHECK: ret void
+
+// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_MAIN_TY]]* noalias)
+// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0
+// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1
+// CHECK: call void [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF]])
+// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0
+// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} 2
+// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} -1
+// CHECK: call void [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_S_ARR_ELEM_REF]])
+// CHECK: icmp eq
+// CHECK: br i1
+// CHECK: ret i32
+
+// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
+// CHECK: alloca [[S_INT_TY]],
+// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32, align 128
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32],
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[LOC:%.+]])
+
+// CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]],
+
+// Store original variables in capture struct.
+// CHECK: [[VEC_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: store [2 x i32]* [[VEC_ADDR]], [2 x i32]** [[VEC_REF]],
+// CHECK: [[T_VAR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1
+// CHECK: store i32* [[T_VAR_ADDR]], i32** [[T_VAR_REF]],
+// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK: store [2 x [[S_INT_TY]]]* [[S_ARR_ADDR]], [2 x [[S_INT_TY]]]** [[S_ARR_REF]],
+// CHECK: [[VAR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3
+// CHECK: store [[S_INT_TY]]* [[VAR_ADDR]], [[S_INT_TY]]** [[VAR_REF]],
+
+// Allocate task.
+// Returns struct kmp_task_t {
+// [[KMP_TASK_T_TY]] task_data;
+// [[KMP_TASK_TMAIN_TY]] privates;
+// };
+// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 256, i64 32, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_TMAIN_TY]]*
+
+// Fill kmp_task_t->shareds by copying from original capture argument.
+// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[SHAREDS_REF_ADDR:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[SHAREDS_REF:%.+]] = load i8*, i8** [[SHAREDS_REF_ADDR]],
+// CHECK: [[CAPTURES_ADDR:%.+]] = bitcast [[CAP_TMAIN_TY]]* %{{.+}} to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[SHAREDS_REF]], i8* [[CAPTURES_ADDR]], i64 32, i32 8, i1 false)
+
+// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes).
+// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK: [[SHAREDS:%.+]] = bitcast i8* [[SHAREDS_REF]] to [[CAP_TMAIN_TY]]*
+
+// t_var;
+// CHECK: [[PRIVATE_T_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0
+// CHECK: [[T_VAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 1
+// CHECK: [[T_VAR_REF:%.+]] = load i{{.+}}*, i{{.+}}** [[T_VAR_ADDR_REF]],
+// CHECK: [[T_VAR:%.+]] = load i{{.+}}, i{{.+}}* [[T_VAR_REF]], align 128
+// CHECK: store i32 [[T_VAR]], i32* [[PRIVATE_T_VAR_REF]], align 128
+
+// vec;
+// CHECK: [[PRIVATE_VEC_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1
+// CHECK: [[VEC_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 0
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(
+
+// Constructors for s_arr and var.
+// a_arr;
+// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK: [[S_ARR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 2
+// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0
+// CHECK: getelementptr [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} 2
+// CHECK: call void [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* [[S_ARR_CUR:%[^,]+]],
+// CHECK: getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_CUR]], i{{.+}} 1
+// CHECK: icmp eq
+// CHECK: br i1
+
+// var;
+// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: [[VAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 3
+// CHECK: call void [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* [[PRIVATE_VAR_REF]],
+
+// Provide pointer to destructor function, which will destroy private variables at the end of the task.
+// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3
+// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)**
+// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]],
+
+// Start task.
+// CHECK: call void @__kmpc_taskloop([[LOC]], i32 [[GTID]], i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_TMAIN_TY]]*, [[KMP_TASK_TMAIN_TY]]*, i32)* [[TMAIN_DUP:@.+]] to i8*))
+
+// No destructors must be called for private copies of s_arr and var.
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: ret
+//
+
+// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_TMAIN_TY]]* noalias, i32** noalias, [2 x i32]** noalias, [2 x [[S_INT_TY]]]** noalias, [[S_INT_TY]]** noalias)
+// CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_TMAIN_TY]]*, [[PRIVATES_TMAIN_TY]]**
+// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 0
+// CHECK: [[ARG1:%.+]] = load i32**, i32*** %{{.+}},
+// CHECK: store i32* [[PRIV_T_VAR]], i32** [[ARG1]],
+// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 1
+// CHECK: [[ARG2:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}},
+// CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG2]],
+// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 2
+// CHECK: [[ARG3:%.+]] = load [2 x [[S_INT_TY]]]**, [2 x [[S_INT_TY]]]*** %{{.+}},
+// CHECK: store [2 x [[S_INT_TY]]]* [[PRIV_S_VAR]], [2 x [[S_INT_TY]]]** [[ARG3]],
+// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 3
+// CHECK: [[ARG4:%.+]] = load [[S_INT_TY]]**, [[S_INT_TY]]*** {{.+}},
+// CHECK: store [[S_INT_TY]]* [[PRIV_VAR]], [[S_INT_TY]]** [[ARG4]],
+// CHECK: ret void
+
+// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_TMAIN_TY]]* noalias)
+// CHECK: alloca i32*,
+// CHECK-DAG: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*,
+// CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*,
+// CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
+// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]],
+// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]],
+// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]])
+// CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]],
+// CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]],
+// CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]],
+// CHECK: [[PRIV_VAR:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[PRIV_VAR_ADDR]],
+
+// Privates actually are used.
+// CHECK-DAG: [[PRIV_VAR]]
+// CHECK-DAG: [[PRIV_T_VAR]]
+// CHECK-DAG: [[PRIV_S_ARR]]
+// CHECK-DAG: [[PRIV_VEC]]
+
+// CHECK: ret
+
+// CHECK: define internal void [[TMAIN_DUP]]([[KMP_TASK_TMAIN_TY]]*, [[KMP_TASK_TMAIN_TY]]*, i32)
+// CHECK: getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* %{{.+}}, i32 0, i32 2
+// CHECK: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* %{{.+}}, i32 0, i32 2
+// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* %{{.+}}, i32 0, i32 0
+// CHECK: getelementptr [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i64 2
+// CHECK: br i1 %
+
+// CHECK: phi [[S_INT_TY]]*
+// CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]*
+// CHECK: getelementptr [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i32 1
+// CHECK: icmp eq [[S_INT_TY]]* %
+// CHECK: br i1 %
+
+// CHECK: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* %{{.+}}, i32 0, i32 3
+// CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]*
+// CHECK: ret void
+
+// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_TMAIN_TY]]* noalias)
+// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[PRIVATE_VAR_REF]])
+// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0
+// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} 2
+// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} -1
+// CHECK: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[PRIVATE_S_ARR_ELEM_REF]])
+// CHECK: icmp eq
+// CHECK: br i1
+// CHECK: ret i32
+
+#endif
+#else
+// ARRAY-LABEL: array_func
+struct St {
+ int a, b;
+ St() : a(0), b(0) {}
+ St(const St &) {}
+ ~St() {}
+};
+
+void array_func(int n, float a[n], St s[2]) {
+// ARRAY: call i8* @__kmpc_omp_task_alloc(
+// ARRAY: call void @__kmpc_taskloop(
+// ARRAY: store float** %{{.+}}, float*** %{{.+}},
+// ARRAY: store %struct.St** %{{.+}}, %struct.St*** %{{.+}},
+#pragma omp taskloop simd firstprivate(a, s)
+ for (int i = 0; i < 10; ++i)
+ ;
+}
+#endif
+
diff --git a/test/OpenMP/taskloop_simd_firstprivate_messages.cpp b/test/OpenMP/taskloop_simd_firstprivate_messages.cpp
index 83946695204b8..18cefc1beeb25 100644
--- a/test/OpenMP/taskloop_simd_firstprivate_messages.cpp
+++ b/test/OpenMP/taskloop_simd_firstprivate_messages.cpp
@@ -295,9 +295,9 @@ int main(int argc, char **argv) {
#pragma omp taskloop simd firstprivate(i) // expected-note {{defined as firstprivate}}
for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp taskloop simd' directive may not be firstprivate, predetermined as linear}}
foo();
-#pragma omp parallel reduction(+ : i)
-#pragma omp taskloop simd firstprivate(i) // expected-note {{defined as firstprivate}}
- for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp taskloop simd' directive may not be firstprivate, predetermined as linear}}
+#pragma omp parallel reduction(+ : i) // expected-note 4 {{defined as reduction}}
+#pragma omp taskloop simd firstprivate(i) // expected-error {{argument of a reduction clause of a parallel construct must not appear in a firstprivate clause on a task construct}}
+ for (i = 0; i < argc; ++i) // expected-error 3 {{reduction variables may not be accessed in an explicit task}}
foo();
#pragma omp parallel
#pragma omp taskloop simd firstprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
diff --git a/test/OpenMP/taskloop_simd_lastprivate_codegen.cpp b/test/OpenMP/taskloop_simd_lastprivate_codegen.cpp
new file mode 100644
index 0000000000000..e3562a8f0c62d
--- /dev/null
+++ b/test/OpenMP/taskloop_simd_lastprivate_codegen.cpp
@@ -0,0 +1,519 @@
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=ARRAY %s
+// expected-no-diagnostics
+// REQUIRES: x86-registered-target
+// It doesn't pass on win32.
+// REQUIRES: shell
+#ifndef ARRAY
+#ifndef HEADER
+#define HEADER
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a) {}
+ S() : f() {}
+ S(const S &s, T t = T()) : f(s.f + t) {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+volatile double g;
+
+// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32 }
+// CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double }
+// CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [2 x [[S_DOUBLE_TY]]], [[S_DOUBLE_TY]], i32, [2 x i32]
+// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { [2 x i32]*, i32*, [2 x [[S_DOUBLE_TY]]]*, [[S_DOUBLE_TY]]*, i{{[0-9]+}}* }
+// CHECK-DAG: [[KMP_TASK_MAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [[PRIVATES_MAIN_TY]] }
+// CHECK-DAG: [[S_INT_TY:%.+]] = type { i32 }
+// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { [2 x i32]*, i32*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* }
+// CHECK-DAG: [[PRIVATES_TMAIN_TY:%.+]] = type { i32, [2 x i32], [2 x [[S_INT_TY]]], [[S_INT_TY]], [104 x i8] }
+// CHECK-DAG: [[KMP_TASK_TMAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [{{[0-9]+}} x i8], [[PRIVATES_TMAIN_TY]] }
+template <typename T>
+T tmain() {
+ S<T> ttt;
+ S<T> test;
+ T t_var __attribute__((aligned(128))) = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> var(3);
+#pragma omp taskloop simd lastprivate(t_var, vec, s_arr, s_arr, var, var)
+ for (int i = 0; i < 10; ++i) {
+ vec[0] = t_var;
+ s_arr[0] = var;
+ }
+ return T();
+}
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA: [[G:@.+]] = global double
+ // LAMBDA: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0,
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
+
+// LAMBDA: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_MAIN_TY:%[^*]+]]*, [[KMP_TASK_MAIN_TY]]*, i32)* [[MAIN_DUP:@.+]] to i8*))
+// LAMBDA: ret
+#pragma omp taskloop simd lastprivate(g, sivar)
+ for (int i = 0; i < 10; ++i) {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]]
+
+ // LAMBDA: store double* %{{.+}}, double** %{{.+}},
+ // LAMBDA: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}* noalias)
+ g = 1;
+ sivar = 11;
+ // LAMBDA: store double 1.0{{.+}}, double* %{{.+}},
+ // LAMBDA: store i{{[0-9]+}} 11, i{{[0-9]+}}* %{{.+}},
+ // LAMBDA: call void [[INNER_LAMBDA]](%
+ // LAMBDA: icmp ne i32 %{{.+}}, 0
+ // LAMBDA: br i1
+ // LAMBDA: load double, double* %
+ // LAMBDA: store volatile double %
+ // LAMBDA: load i32, i32* %
+ // LAMBDA: store i32 %
+ // LAMBDA: ret
+ [&]() {
+ g = 2;
+ sivar = 22;
+ }();
+ }
+ }();
+ return 0;
+#elif defined(BLOCKS)
+ // BLOCKS: [[G:@.+]] = global double
+ // BLOCKS-LABEL: @main
+ // BLOCKS: call void {{%.+}}(i8
+ ^{
+ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
+ // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+ // BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
+ // BLOCKS: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_MAIN_TY:%[^*]+]]*, [[KMP_TASK_MAIN_TY]]*, i32)* [[MAIN_DUP:@.+]] to i8*))
+ // BLOCKS: ret
+#pragma omp taskloop simd lastprivate(g, sivar)
+ for (int i = 0; i < 10; ++i) {
+ // BLOCKS: define {{.+}} void {{@.+}}(i8*
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS: store double 2.0{{.+}}, double*
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS-NOT: [[ISVAR]]{{[[^:word:]]}}
+ // BLOCKS: store i{{[0-9]+}} 22, i{{[0-9]+}}*
+ // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}
+ // BLOCKS: ret
+
+ // BLOCKS: store double* %{{.+}}, double** %{{.+}},
+ // BLOCKS: store i{{[0-9]+}}* %{{.+}}, i{{[0-9]+}}** %{{.+}},
+ // BLOCKS: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}* noalias)
+ g = 1;
+ sivar = 11;
+ // BLOCKS: store double 1.0{{.+}}, double* %{{.+}},
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS: store i{{[0-9]+}} 11, i{{[0-9]+}}* %{{.+}},
+ // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}
+ // BLOCKS: call void {{%.+}}(i8
+ // BLOCKS: icmp ne i32 %{{.+}}, 0
+ // BLOCKS: br i1
+ // BLOCKS: load double, double* %
+ // BLOCKS: store volatile double %
+ // BLOCKS: load i32, i32* %
+ // BLOCKS: store i32 %
+ ^{
+ g = 2;
+ sivar = 22;
+ }();
+ }
+ }();
+ return 0;
+#else
+ S<double> ttt;
+ S<double> test;
+ int t_var = 0;
+ int vec[] = {1, 2};
+ S<double> s_arr[] = {1, 2};
+ S<double> var(3);
+#pragma omp taskloop simd lastprivate(var, t_var, s_arr, vec, s_arr, var, sivar)
+ for (int i = 0; i < 10; ++i) {
+ vec[0] = t_var;
+ s_arr[0] = var;
+ sivar = 33;
+ }
+ return tmain<int>();
+#endif
+}
+
+// CHECK: [[SIVAR:.+]] = internal global i{{[0-9]+}} 0,
+// CHECK: define i{{[0-9]+}} @main()
+// CHECK: alloca [[S_DOUBLE_TY]],
+// CHECK: [[TEST:%.+]] = alloca [[S_DOUBLE_TY]],
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32],
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]],
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]],
+// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[LOC:%.+]])
+
+// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR:@.+]]([[S_DOUBLE_TY]]* [[TEST]])
+
+// Store original variables in capture struct.
+// CHECK: [[VEC_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: store [2 x i32]* [[VEC_ADDR]], [2 x i32]** [[VEC_REF]],
+// CHECK: [[T_VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1
+// CHECK: store i32* [[T_VAR_ADDR]], i32** [[T_VAR_REF]],
+// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK: store [2 x [[S_DOUBLE_TY]]]* [[S_ARR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[S_ARR_REF]],
+// CHECK: [[VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3
+// CHECK: store [[S_DOUBLE_TY]]* [[VAR_ADDR]], [[S_DOUBLE_TY]]** [[VAR_REF]],
+// CHECK: [[SIVAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 4
+// CHECK: store i{{[0-9]+}}* [[SIVAR]], i{{[0-9]+}}** [[SIVAR_REF]],
+
+// Allocate task.
+// Returns struct kmp_task_t {
+// [[KMP_TASK_T]] task_data;
+// [[KMP_TASK_MAIN_TY]] privates;
+// };
+// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 112, i64 40, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_MAIN_TY]]*
+
+// Fill kmp_task_t->shareds by copying from original capture argument.
+// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[SHAREDS_REF_ADDR:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[SHAREDS_REF:%.+]] = load i8*, i8** [[SHAREDS_REF_ADDR]],
+// CHECK: [[CAPTURES_ADDR:%.+]] = bitcast [[CAP_MAIN_TY]]* %{{.+}} to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[SHAREDS_REF]], i8* [[CAPTURES_ADDR]], i64 40, i32 8, i1 false)
+
+// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes).
+// Also copy address of private copy to the corresponding shareds reference.
+// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+
+// Constructors for s_arr and var.
+// s_arr;
+// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR]]([[S_DOUBLE_TY]]* [[S_ARR_CUR:%[^,]+]])
+// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* [[S_ARR_CUR]], i{{.+}} 1
+// CHECK: icmp eq
+// CHECK: br i1
+
+// var;
+// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1
+// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF]])
+
+// t_var;
+// vec;
+// sivar;
+
+// Provide pointer to destructor function, which will destroy private variables at the end of the task.
+// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3
+// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)**
+// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]],
+
+// Start task.
+// CHECK: call void @__kmpc_taskloop([[LOC]], i32 [[GTID]], i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_MAIN_TY]]*, [[KMP_TASK_MAIN_TY]]*, i32)* [[MAIN_DUP:@.+]] to i8*))
+
+// CHECK: = call i{{.+}} [[TMAIN_INT:@.+]]()
+
+// No destructors must be called for private copies of s_arr and var.
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: call void [[S_DOUBLE_TY_DESTR:@.+]]([[S_DOUBLE_TY]]*
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: ret
+//
+
+// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_MAIN_TY]]* noalias, [[S_DOUBLE_TY]]** noalias, i32** noalias, [2 x [[S_DOUBLE_TY]]]** noalias, [2 x i32]** noalias, i32** noalias)
+// CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_MAIN_TY]]*, [[PRIVATES_MAIN_TY]]**
+// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 0
+// CHECK: [[ARG3:%.+]] = load [2 x [[S_DOUBLE_TY]]]**, [2 x [[S_DOUBLE_TY]]]*** %{{.+}},
+// CHECK: store [2 x [[S_DOUBLE_TY]]]* [[PRIV_S_VAR]], [2 x [[S_DOUBLE_TY]]]** [[ARG3]],
+// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 1
+// CHECK: [[ARG1:%.+]] = load [[S_DOUBLE_TY]]**, [[S_DOUBLE_TY]]*** {{.+}},
+// CHECK: store [[S_DOUBLE_TY]]* [[PRIV_VAR]], [[S_DOUBLE_TY]]** [[ARG1]],
+// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 2
+// CHECK: [[ARG2:%.+]] = load i32**, i32*** %{{.+}},
+// CHECK: store i32* [[PRIV_T_VAR]], i32** [[ARG2]],
+// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 3
+// CHECK: [[ARG4:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}},
+// CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG4]],
+// CHECK: [[PRIV_SIVAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 4
+// CHECK: [[ARG5:%.+]] = load i{{[0-9]+}}**, i{{[0-9]+}}*** %{{.+}},
+// CHECK: store i{{[0-9]+}}* [[PRIV_SIVAR]], i{{[0-9]+}}** [[ARG5]],
+// CHECK: ret void
+
+// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_MAIN_TY]]* noalias)
+
+// CHECK: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]]*,
+// CHECK: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*,
+// CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*,
+// CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*,
+// CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*,
+// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]],
+// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]],
+
+// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]])
+
+// CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]],
+// CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]],
+// CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]],
+// CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]],
+// CHECK: [[PRIV_SIVAR:%.+]] = load i32*, i32** [[PRIV_SIVAR_ADDR]],
+
+// Privates actually are used.
+// CHECK-DAG: [[PRIV_VAR]]
+// CHECK-DAG: [[PRIV_T_VAR]]
+// CHECK-DAG: [[PRIV_S_ARR]]
+// CHECK-DAG: [[PRIV_VEC]]
+// CHECK-DAG: [[PRIV_SIVAR]]
+
+// CHECK: icmp ne i32 %{{.+}}, 0
+// CHECK-NEXT: br i1
+// CHECK: bitcast [[S_DOUBLE_TY]]* %{{.+}} to i8*
+// CHECK: bitcast [[S_DOUBLE_TY]]* %{{.+}} to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %
+// CHECK: load i32, i32* %
+// CHECK: store i32 %{{.+}}, i32* %
+// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* %
+// CHECK: phi [[S_DOUBLE_TY]]*
+// CHECK: phi [[S_DOUBLE_TY]]*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %
+// CHECK: icmp eq [[S_DOUBLE_TY]]* %
+// CHECK-NEXT: br i1
+// CHECK: bitcast [2 x i32]* %{{.+}} to i8*
+// CHECK: bitcast [2 x i32]* %{{.+}} to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %
+// CHECK: load i32, i32* %
+// CHECK: store i32 %{{.+}}, i32* %
+// CHECK: br label
+// CHECK: ret
+
+// CHECK: define internal void [[MAIN_DUP]]([[KMP_TASK_MAIN_TY]]*, [[KMP_TASK_MAIN_TY]]*, i32)
+// CHECK: getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* %{{.+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* %{{.+}}, i32 0, i32 8
+// CHECK: load i32, i32* %
+// CHECK: store i32 %{{.+}}, i32* %
+// CHECK: getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* %{{.+}}, i32 0, i32 1
+// CHECK: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* %{{.+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* %{{.+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i64 2
+// CHECK: br label %
+
+// CHECK: phi [[S_DOUBLE_TY]]*
+// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR]]([[S_DOUBLE_TY]]*
+// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i64 1
+// CHECK: icmp eq [[S_DOUBLE_TY]]* %
+// CHECK: br i1 %
+
+// CHECK: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* %{{.+}}, i32 0, i32 1
+// CHECK: call {{.*}} [[S_DOUBLE_TY_CONSTR]]([[S_DOUBLE_TY]]*
+// CHECK: ret void
+
+// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_MAIN_TY]]* noalias)
+// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0
+// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1
+// CHECK: call {{.*}} [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF]])
+// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0
+// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} 2
+// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} -1
+// CHECK: call {{.*}} [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_S_ARR_ELEM_REF]])
+// CHECK: icmp eq
+// CHECK: br i1
+// CHECK: ret i32
+
+// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
+// CHECK: alloca [[S_INT_TY]],
+// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32, align 128
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32],
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[LOC:%.+]])
+
+// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
+
+// Store original variables in capture struct.
+// CHECK: [[VEC_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: store [2 x i32]* [[VEC_ADDR]], [2 x i32]** [[VEC_REF]],
+// CHECK: [[T_VAR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1
+// CHECK: store i32* [[T_VAR_ADDR]], i32** [[T_VAR_REF]],
+// CHECK: [[S_ARR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK: store [2 x [[S_INT_TY]]]* [[S_ARR_ADDR]], [2 x [[S_INT_TY]]]** [[S_ARR_REF]],
+// CHECK: [[VAR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3
+// CHECK: store [[S_INT_TY]]* [[VAR_ADDR]], [[S_INT_TY]]** [[VAR_REF]],
+
+// Allocate task.
+// Returns struct kmp_task_t {
+// [[KMP_TASK_T_TY]] task_data;
+// [[KMP_TASK_TMAIN_TY]] privates;
+// };
+// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 256, i64 32, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_TMAIN_TY]]*
+
+// Fill kmp_task_t->shareds by copying from original capture argument.
+// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[SHAREDS_REF_ADDR:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[SHAREDS_REF:%.+]] = load i8*, i8** [[SHAREDS_REF_ADDR]],
+// CHECK: [[CAPTURES_ADDR:%.+]] = bitcast [[CAP_TMAIN_TY]]* %{{.+}} to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[SHAREDS_REF]], i8* [[CAPTURES_ADDR]], i64 32, i32 8, i1 false)
+
+// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes).
+// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+
+// t_var;
+// vec;
+
+// Constructors for s_arr and var.
+// a_arr;
+// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0
+// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} 2
+// CHECK: call {{.*}} [[S_INT_TY_CONSTR]]([[S_INT_TY]]* [[S_ARR_CUR:%[^,]+]])
+// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_CUR]], i{{.+}} 1
+// CHECK: icmp eq
+// CHECK: br i1
+
+// var;
+// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: call {{.*}} [[S_INT_TY_CONSTR]]([[S_INT_TY]]* [[PRIVATE_VAR_REF]])
+
+// Provide pointer to destructor function, which will destroy private variables at the end of the task.
+// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3
+// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)**
+// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]],
+
+// Start task.
+// CHECK: call void @__kmpc_taskloop([[LOC]], i32 [[GTID]], i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_TMAIN_TY]]*, [[KMP_TASK_TMAIN_TY]]*, i32)* [[TMAIN_DUP:@.+]] to i8*))
+
+// No destructors must be called for private copies of s_arr and var.
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: ret
+//
+
+// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_TMAIN_TY]]* noalias, i32** noalias, [2 x i32]** noalias, [2 x [[S_INT_TY]]]** noalias, [[S_INT_TY]]** noalias)
+// CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_TMAIN_TY]]*, [[PRIVATES_TMAIN_TY]]**
+// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 0
+// CHECK: [[ARG1:%.+]] = load i32**, i32*** %{{.+}},
+// CHECK: store i32* [[PRIV_T_VAR]], i32** [[ARG1]],
+// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 1
+// CHECK: [[ARG2:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}},
+// CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG2]],
+// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 2
+// CHECK: [[ARG3:%.+]] = load [2 x [[S_INT_TY]]]**, [2 x [[S_INT_TY]]]*** %{{.+}},
+// CHECK: store [2 x [[S_INT_TY]]]* [[PRIV_S_VAR]], [2 x [[S_INT_TY]]]** [[ARG3]],
+// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 3
+// CHECK: [[ARG4:%.+]] = load [[S_INT_TY]]**, [[S_INT_TY]]*** {{.+}},
+// CHECK: store [[S_INT_TY]]* [[PRIV_VAR]], [[S_INT_TY]]** [[ARG4]],
+// CHECK: ret void
+
+// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_TMAIN_TY]]* noalias)
+// CHECK: alloca i32*,
+// CHECK-DAG: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*,
+// CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*,
+// CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
+// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]],
+// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]],
+// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]])
+// CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]],
+// CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]],
+// CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]],
+// CHECK: [[PRIV_VAR:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[PRIV_VAR_ADDR]],
+
+// Privates actually are used.
+// CHECK-DAG: [[PRIV_VAR]]
+// CHECK-DAG: [[PRIV_T_VAR]]
+// CHECK-DAG: [[PRIV_S_ARR]]
+// CHECK-DAG: [[PRIV_VEC]]
+
+// CHECK: icmp ne i32 %{{.+}}, 0
+// CHECK-NEXT: br i1
+// CHECK: load i32, i32* %
+// CHECK: store i32 %{{.+}}, i32* %
+// CHECK: bitcast [2 x i32]* %{{.+}} to i8*
+// CHECK: bitcast [2 x i32]* %{{.+}} to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %
+// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* %
+// CHECK: phi [[S_INT_TY]]*
+// CHECK: phi [[S_INT_TY]]*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %
+// CHECK: icmp eq [[S_INT_TY]]* %
+// CHECK-NEXT: br i1
+// CHECK: bitcast [[S_INT_TY]]* %{{.+}} to i8*
+// CHECK: bitcast [[S_INT_TY]]* %{{.+}} to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %
+// CHECK: br label
+// CHECK: ret
+
+// CHECK: define internal void [[TMAIN_DUP]]([[KMP_TASK_TMAIN_TY]]*, [[KMP_TASK_TMAIN_TY]]*, i32)
+// CHECK: getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* %{{.+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* %{{.+}}, i32 0, i32 8
+// CHECK: load i32, i32* %
+// CHECK: store i32 %{{.+}}, i32* %
+// CHECK: getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* %{{.+}}, i32 0, i32 2
+// CHECK: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* %{{.+}}, i32 0, i32 2
+// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* %{{.+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i64 2
+// CHECK: br label %
+
+// CHECK: phi [[S_INT_TY]]*
+// CHECK: call {{.*}} [[S_INT_TY_CONSTR]]([[S_INT_TY]]*
+// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i64 1
+// CHECK: icmp eq [[S_INT_TY]]* %
+// CHECK: br i1 %
+
+// CHECK: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* %{{.+}}, i32 0, i32 3
+// CHECK: call {{.*}} [[S_INT_TY_CONSTR]]([[S_INT_TY]]*
+// CHECK: ret void
+
+// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_TMAIN_TY]]* noalias)
+// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[PRIVATE_VAR_REF]])
+// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0
+// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} 2
+// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} -1
+// CHECK: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[PRIVATE_S_ARR_ELEM_REF]])
+// CHECK: icmp eq
+// CHECK: br i1
+// CHECK: ret i32
+
+#endif
+#else
+// ARRAY-LABEL: array_func
+struct St {
+ int a, b;
+ St() : a(0), b(0) {}
+ St(const St &) {}
+ ~St() {}
+};
+
+void array_func(int n, float a[n], St s[2]) {
+// ARRAY: call i8* @__kmpc_omp_task_alloc(
+// ARRAY: call void @__kmpc_taskloop(
+// ARRAY: store float** %{{.+}}, float*** %{{.+}},
+// ARRAY: store %struct.St** %{{.+}}, %struct.St*** %{{.+}},
+// ARRAY: icmp ne i32 %{{.+}}, 0
+// ARRAY: store float* %{{.+}}, float** %{{.+}},
+// ARRAY: store %struct.St* %{{.+}}, %struct.St** %{{.+}},
+#pragma omp taskloop simd lastprivate(a, s)
+ for (int i = 0; i < 10; ++i)
+ ;
+}
+#endif
+
diff --git a/test/OpenMP/taskloop_simd_loop_messages.cpp b/test/OpenMP/taskloop_simd_loop_messages.cpp
index 47318721102fd..3326e6ff61cd8 100644
--- a/test/OpenMP/taskloop_simd_loop_messages.cpp
+++ b/test/OpenMP/taskloop_simd_loop_messages.cpp
@@ -428,12 +428,12 @@ public:
typedef int difference_type;
typedef std::random_access_iterator_tag iterator_category;
};
-// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 2nd argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}}
// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
int operator-(GoodIter a, GoodIter b) { return 0; }
// expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}}
GoodIter operator-(GoodIter a) { return a; }
-// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 2nd argument}}
+// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}}
// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
GoodIter operator-(GoodIter a, int v) { return GoodIter(); }
// expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}}
@@ -484,7 +484,7 @@ int test_with_random_access_iterator() {
#pragma omp taskloop simd
for (begin = GoodIter(0); begin < end; ++begin)
++begin;
-// expected-error@+4 {{invalid operands to binary expression ('GoodIter' and 'Iter0')}}
+// expected-error@+4 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}}
// expected-error@+3 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
#pragma omp parallel
#pragma omp taskloop simd
diff --git a/test/OpenMP/taskloop_simd_private_codegen.cpp b/test/OpenMP/taskloop_simd_private_codegen.cpp
new file mode 100644
index 0000000000000..557601e9c93e4
--- /dev/null
+++ b/test/OpenMP/taskloop_simd_private_codegen.cpp
@@ -0,0 +1,420 @@
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=ARRAY %s
+// expected-no-diagnostics
+// REQUIRES: x86-registered-target
+// It doesn't pass on win32. Investigating.
+// REQUIRES: shell
+
+#ifndef ARRAY
+#ifndef HEADER
+#define HEADER
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a) {}
+ S() : f() {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+volatile double g;
+
+// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32 }
+// CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double }
+// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { i8 }
+// CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [2 x [[S_DOUBLE_TY]]], [[S_DOUBLE_TY]], i32, [2 x i32]
+// CHECK-DAG: [[KMP_TASK_MAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [[PRIVATES_MAIN_TY]] }
+// CHECK-DAG: [[S_INT_TY:%.+]] = type { i32 }
+// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { i8 }
+// CHECK-DAG: [[PRIVATES_TMAIN_TY:%.+]] = type { i32, [2 x i32], [2 x [[S_INT_TY]]], [[S_INT_TY]], [104 x i8] }
+// CHECK-DAG: [[KMP_TASK_TMAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [{{[0-9]+}} x i8], [[PRIVATES_TMAIN_TY]] }
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var __attribute__((aligned(128))) = T();
+ T vec[] = {1, 2};
+ S<T> s_arr[] = {1, 2};
+ S<T> var(3);
+#pragma omp taskloop simd private(t_var, vec, s_arr, s_arr, var, var)
+ for (int i = 0; i < 10; ++i) {
+ vec[0] = t_var;
+ s_arr[0] = var;
+ }
+ return T();
+}
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA: [[G:@.+]] = global double
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
+// LAMBDA: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* null)
+// LAMBDA: ret
+#pragma omp taskloop simd private(g, sivar)
+ for (int i = 0; i < 10; ++i) {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]]
+ // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]]
+ // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 3, i{{[0-9]+}}* [[SIVAR_REF]]
+
+ // LAMBDA: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}* noalias)
+ g = 1;
+ sivar = 2;
+ // LAMBDA: store double 1.0{{.+}}, double* %{{.+}},
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* %{{.+}},
+ // LAMBDA: call void [[INNER_LAMBDA]](%
+ // LAMBDA: ret
+ [&]() {
+ g = 2;
+ sivar = 3;
+ }();
+ }
+ }();
+ return 0;
+#elif defined(BLOCKS)
+ // BLOCKS: [[G:@.+]] = global double
+ // BLOCKS-LABEL: @main
+ // BLOCKS: call void {{%.+}}(i8
+ ^{
+ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
+ // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+ // BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
+ // BLOCKS: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* null)
+ // BLOCKS: ret
+#pragma omp taskloop simd private(g, sivar)
+ for (int i = 0; i < 10; ++i) {
+ // BLOCKS: define {{.+}} void {{@.+}}(i8*
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS: store double 2.0{{.+}}, double*
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}
+ // BLOCKS: store i{{[0-9]+}} 4, i{{[0-9]+}}*
+ // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}
+ // BLOCKS: ret
+
+ // BLOCKS: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}* noalias)
+ g = 1;
+ sivar = 3;
+ // BLOCKS: store double 1.0{{.+}}, double* %{{.+}},
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS: store i{{[0-9]+}} 3, i{{[0-9]+}}* %{{.+}},
+ // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}}
+ // BLOCKS: call void {{%.+}}(i8
+ ^{
+ g = 2;
+ sivar = 4;
+ }();
+ }
+ }();
+ return 0;
+#else
+ S<double> test;
+ int t_var = 0;
+ int vec[] = {1, 2};
+ S<double> s_arr[] = {1, 2};
+ S<double> var(3);
+#pragma omp taskloop simd private(var, t_var, s_arr, vec, s_arr, var, sivar)
+ for (int i = 0; i < 10; ++i) {
+ vec[0] = t_var;
+ s_arr[0] = var;
+ sivar = 8;
+ }
+#pragma omp task
+ g+=1;
+ return tmain<int>();
+#endif
+}
+
+// CHECK: define i{{[0-9]+}} @main()
+// CHECK: [[TEST:%.+]] = alloca [[S_DOUBLE_TY]],
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32],
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]],
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]],
+// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[LOC:%.+]])
+
+// CHECK: call {{.*}} [[S_DOUBLE_TY_DEF_CONSTR:@.+]]([[S_DOUBLE_TY]]* [[TEST]])
+
+// Do not store original variables in capture struct.
+// CHECK-NOT: getelementptr inbounds [[CAP_MAIN_TY]],
+
+// Allocate task.
+// Returns struct kmp_task_t {
+// [[KMP_TASK_T_TY]] task_data;
+// [[KMP_TASK_MAIN_TY]] privates;
+// };
+// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 112, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_MAIN_TY]]*
+
+// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes).
+// Also copy address of private copy to the corresponding shareds reference.
+// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+
+// Constructors for s_arr and var.
+// a_arr;
+// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0
+// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} 2
+// CHECK: call void [[S_DOUBLE_TY_DEF_CONSTR]]([[S_DOUBLE_TY]]* [[S_ARR_CUR:%.+]])
+// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* [[S_ARR_CUR]], i{{.+}} 1
+// CHECK: icmp eq
+// CHECK: br i1
+
+// var;
+// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1
+// CHECK: call void [[S_DOUBLE_TY_DEF_CONSTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF:%.+]])
+
+// Provide pointer to destructor function, which will destroy private variables at the end of the task.
+// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3
+// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)**
+// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]],
+
+// Start task.
+// CHECK: call void @__kmpc_taskloop([[LOC]], i32 [[GTID]], i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_MAIN_TY]]*, [[KMP_TASK_MAIN_TY]]*, i32)* [[MAIN_DUP:@.+]] to i8*))
+// CHECK: call i32 @__kmpc_omp_task([[LOC]], i32 [[GTID]], i8*
+
+// CHECK: = call i{{.+}} [[TMAIN_INT:@.+]]()
+
+// No destructors must be called for private copies of s_arr and var.
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: call void [[S_DOUBLE_TY_DESTR:@.+]]([[S_DOUBLE_TY]]*
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: ret
+//
+
+// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_MAIN_TY]]* noalias, [[S_DOUBLE_TY]]** noalias, i32** noalias, [2 x [[S_DOUBLE_TY]]]** noalias, [2 x i32]** noalias, i32** noalias)
+// CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_MAIN_TY]]*, [[PRIVATES_MAIN_TY]]**
+// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 0
+// CHECK: [[ARG3:%.+]] = load [2 x [[S_DOUBLE_TY]]]**, [2 x [[S_DOUBLE_TY]]]*** %{{.+}},
+// CHECK: store [2 x [[S_DOUBLE_TY]]]* [[PRIV_S_VAR]], [2 x [[S_DOUBLE_TY]]]** [[ARG3]],
+// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 1
+// CHECK: [[ARG1:%.+]] = load [[S_DOUBLE_TY]]**, [[S_DOUBLE_TY]]*** {{.+}},
+// CHECK: store [[S_DOUBLE_TY]]* [[PRIV_VAR]], [[S_DOUBLE_TY]]** [[ARG1]],
+// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 2
+// CHECK: [[ARG2:%.+]] = load i32**, i32*** %{{.+}},
+// CHECK: store i32* [[PRIV_T_VAR]], i32** [[ARG2]],
+// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 3
+// CHECK: [[ARG4:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}},
+// CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG4]],
+// CHECK: ret void
+
+// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_MAIN_TY]]* noalias)
+
+// CHECK: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]]*,
+// CHECK: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*,
+// CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*,
+// CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*,
+// CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*,
+// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]],
+// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]],
+// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]])
+// CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]],
+// CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]],
+// CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]],
+// CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]],
+// CHECK: [[PRIV_SIVAR:%.+]] = load i32*, i32** [[PRIV_SIVAR_ADDR]],
+
+// Privates actually are used.
+// CHECK-DAG: [[PRIV_VAR]]
+// CHECK-DAG: [[PRIV_T_VAR]]
+// CHECK-DAG: [[PRIV_S_ARR]]
+// CHECK-DAG: [[PRIV_VEC]]
+// CHECK_DAG: [[PRIV_SIVAR]]
+
+// CHECK: ret
+
+// CHECK: define internal void [[MAIN_DUP]]([[KMP_TASK_MAIN_TY]]*, [[KMP_TASK_MAIN_TY]]*, i32)
+// CHECK: getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* %{{.+}}, i32 0, i32 1
+// CHECK: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* %{{.+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* %{{.+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i64 2
+// CHECK: br label %
+
+// CHECK: phi [[S_DOUBLE_TY]]*
+// CHECK: call {{.*}} [[S_DOUBLE_TY_DEF_CONSTR]]([[S_DOUBLE_TY]]*
+// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i64 1
+// CHECK: icmp eq [[S_DOUBLE_TY]]* %
+// CHECK: br i1 %
+
+// CHECK: getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* %{{.+}}, i32 0, i32 1
+// CHECK: call {{.*}} [[S_DOUBLE_TY_DEF_CONSTR]]([[S_DOUBLE_TY]]*
+// CHECK: ret void
+
+// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_MAIN_TY]]* noalias)
+// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0
+// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1
+// CHECK: call void [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_VAR_REF]])
+// CHECK: getelementptr inbounds [2 x [[S_DOUBLE_TY]]], [2 x [[S_DOUBLE_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0
+// CHECK: getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} 2
+// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_DOUBLE_TY]], [[S_DOUBLE_TY]]* %{{.+}}, i{{.+}} -1
+// CHECK: call void [[S_DOUBLE_TY_DESTR]]([[S_DOUBLE_TY]]* [[PRIVATE_S_ARR_ELEM_REF]])
+// CHECK: icmp eq
+// CHECK: br i1
+// CHECK: ret i32
+
+// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
+// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[T_VAR_ADDR:%.+]] = alloca i32,
+// CHECK: [[VEC_ADDR:%.+]] = alloca [2 x i32],
+// CHECK: [[S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]],
+// CHECK: [[VAR_ADDR:%.+]] = alloca [[S_INT_TY]],
+// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[LOC:%.+]])
+
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
+
+// Do not store original variables in capture struct.
+// CHECK-NOT: getelementptr inbounds [[CAP_TMAIN_TY]],
+
+// Allocate task.
+// Returns struct kmp_task_t {
+// [[KMP_TASK_T_TY]] task_data;
+// [[KMP_TASK_TMAIN_TY]] privates;
+// };
+// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 256, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_TMAIN_TY]]*
+
+// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+
+// Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes).
+// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+
+// Constructors for s_arr and var.
+// a_arr;
+// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0
+// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} 2
+// CHECK: call void [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[S_ARR_CUR:%.+]])
+// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_CUR]], i{{.+}} 1
+// CHECK: icmp eq
+// CHECK: br i1
+
+// var;
+// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: call void [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[PRIVATE_VAR_REF:%.+]])
+
+// Provide pointer to destructor function, which will destroy private variables at the end of the task.
+// CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3
+// CHECK: [[DESTRUCTORS_PTR:%.+]] = bitcast %union{{.+}}* [[DESTRUCTORS_REF]] to i32 (i32, i8*)**
+// CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_TMAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_PTR]],
+
+// Start task.
+// CHECK: call void @__kmpc_taskloop([[LOC]], i32 [[GTID]], i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_TMAIN_TY]]*, [[KMP_TASK_TMAIN_TY]]*, i32)* [[TMAIN_DUP:@.+]] to i8*))
+
+// No destructors must be called for private copies of s_arr and var.
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK-NOT: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: ret
+//
+
+// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_TMAIN_TY]]* noalias, i32** noalias, [2 x i32]** noalias, [2 x [[S_INT_TY]]]** noalias, [[S_INT_TY]]** noalias)
+// CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_TMAIN_TY]]*, [[PRIVATES_TMAIN_TY]]**
+// CHECK: [[PRIV_T_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 0
+// CHECK: [[ARG1:%.+]] = load i32**, i32*** %{{.+}},
+// CHECK: store i32* [[PRIV_T_VAR]], i32** [[ARG1]],
+// CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 1
+// CHECK: [[ARG2:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}},
+// CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG2]],
+// CHECK: [[PRIV_S_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 2
+// CHECK: [[ARG3:%.+]] = load [2 x [[S_INT_TY]]]**, [2 x [[S_INT_TY]]]*** %{{.+}},
+// CHECK: store [2 x [[S_INT_TY]]]* [[PRIV_S_VAR]], [2 x [[S_INT_TY]]]** [[ARG3]],
+// CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i32 0, i32 3
+// CHECK: [[ARG4:%.+]] = load [[S_INT_TY]]**, [[S_INT_TY]]*** {{.+}},
+// CHECK: store [[S_INT_TY]]* [[PRIV_VAR]], [[S_INT_TY]]** [[ARG4]],
+// CHECK: ret void
+
+// CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_TMAIN_TY]]* noalias)
+
+// CHECK: alloca i32*,
+// CHECK-DAG: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*,
+// CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*,
+// CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*,
+// CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*,
+// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]],
+// CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]],
+// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]])
+// CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]],
+// CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]],
+// CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]],
+// CHECK: [[PRIV_VAR:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[PRIV_VAR_ADDR]],
+
+// Privates actually are used.
+// CHECK-DAG: [[PRIV_VAR]]
+// CHECK-DAG: [[PRIV_T_VAR]]
+// CHECK-DAG: [[PRIV_S_ARR]]
+// CHECK-DAG: [[PRIV_VEC]]
+
+// CHECK: ret
+
+// CHECK: define internal void [[TMAIN_DUP]]([[KMP_TASK_TMAIN_TY]]*, [[KMP_TASK_TMAIN_TY]]*, i32)
+// CHECK: getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* %{{.+}}, i32 0, i32 2
+// CHECK: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* %{{.+}}, i32 0, i32 2
+// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* %{{.+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i64 2
+// CHECK: br label %
+
+// CHECK: phi [[S_INT_TY]]*
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]*
+// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i64 1
+// CHECK: icmp eq [[S_INT_TY]]* %
+// CHECK: br i1 %
+
+// CHECK: getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* %{{.+}}, i32 0, i32 3
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]*
+// CHECK: ret void
+
+// CHECK: define internal i32 [[DESTRUCTORS]](i32, [[KMP_TASK_TMAIN_TY]]* noalias)
+// CHECK: [[PRIVATES:%.+]] = getelementptr inbounds [[KMP_TASK_TMAIN_TY]], [[KMP_TASK_TMAIN_TY]]* [[RES_KMP_TASK:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2
+// CHECK: [[PRIVATE_S_ARR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// CHECK: [[PRIVATE_VAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_TMAIN_TY]], [[PRIVATES_TMAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 3
+// CHECK: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[PRIVATE_VAR_REF]])
+// CHECK: getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[PRIVATE_S_ARR_REF]], i{{.+}} 0, i{{.+}} 0
+// CHECK: getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} 2
+// CHECK: [[PRIVATE_S_ARR_ELEM_REF:%.+]] = getelementptr inbounds [[S_INT_TY]], [[S_INT_TY]]* %{{.+}}, i{{.+}} -1
+// CHECK: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[PRIVATE_S_ARR_ELEM_REF]])
+// CHECK: icmp eq
+// CHECK: br i1
+// CHECK: ret i32
+
+#endif
+#else
+// ARRAY-LABEL: array_func
+struct St {
+ int a, b;
+ St() : a(0), b(0) {}
+ St &operator=(const St &) { return *this; };
+ ~St() {}
+};
+
+void array_func(int n, float a[n], St s[2]) {
+// ARRAY: call i8* @__kmpc_omp_task_alloc(
+// ARRAY: call void @__kmpc_taskloop(
+// ARRAY: store float** %{{.+}}, float*** %{{.+}},
+// ARRAY: store %struct.St** %{{.+}}, %struct.St*** %{{.+}},
+#pragma omp taskloop simd private(a, s)
+ for (int i = 0; i < 10; ++i)
+ ;
+}
+#endif
+
diff --git a/test/OpenMP/taskloop_simd_private_messages.cpp b/test/OpenMP/taskloop_simd_private_messages.cpp
index 4a9b08a7e9e29..ba9e8da17e205 100644
--- a/test/OpenMP/taskloop_simd_private_messages.cpp
+++ b/test/OpenMP/taskloop_simd_private_messages.cpp
@@ -29,7 +29,11 @@ class S4 {
S4(); // expected-note {{implicitly declared private here}}
public:
- S4(int v) : a(v) {}
+ S4(int v) : a(v) {
+#pragma omp taskloop simd private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
};
class S5 {
int a;
@@ -37,6 +41,50 @@ class S5 {
public:
S5(int v) : a(v) {}
+ S5 &operator=(S5 &s) {
+#pragma omp taskloop simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S6 {
+public:
+ T a;
+
+ S6() : a(0) {}
+ S6(T v) : a(v) {
+#pragma omp taskloop simd private(a) private(this->a)
+ for (int k = 0; k < v; ++k)
+ ++this->a;
+ }
+ S6 &operator=(S6 &s) {
+#pragma omp taskloop simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a; ++k)
+ ++s.a;
+ return *this;
+ }
+};
+
+template <typename T>
+class S7 : public T {
+ T a;
+ S7() : a(0) {}
+
+public:
+ S7(T v) : a(v) {
+#pragma omp taskloop simd private(a) private(this->a) private(T::a)
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp taskloop simd private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}}
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
};
S3 h;
@@ -126,6 +174,8 @@ using A::x;
int main(int argc, char **argv) {
S4 e(4);
S5 g(5);
+ S6<float> s6(0.0) , s6_0(1.0);
+ S7<S6<float> > s7(0.0) , s7_0(1.0);
int i;
int &j = i;
#pragma omp taskloop simd private // expected-error {{expected '(' after 'private'}}
@@ -190,6 +240,8 @@ int main(int argc, char **argv) {
for(int k = 0; k < argc; ++k)
si = k + 1;
- return 0;
+ s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}}
+ s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}}
+ return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
}
diff --git a/test/OpenMP/taskloop_simd_safelen_messages.cpp b/test/OpenMP/taskloop_simd_safelen_messages.cpp
index 3182c8af80fa3..729f31407bfaa 100644
--- a/test/OpenMP/taskloop_simd_safelen_messages.cpp
+++ b/test/OpenMP/taskloop_simd_safelen_messages.cpp
@@ -1,8 +1,13 @@
// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
void foo() {
}
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
bool foobool(int argc) {
return argc;
}
@@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp taskloop simd safelen ((ST > 0) ? 1 + ST : 2)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error@+3 2 {{directive '#pragma omp taskloop simd' cannot contain more than one 'safelen' clause}}
- // expected-error@+2 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+ // expected-error@+6 2 {{directive '#pragma omp taskloop simd' cannot contain more than one 'safelen' clause}}
+ // expected-error@+5 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
#pragma omp taskloop simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp taskloop simd safelen (S) // expected-error {{'S' does not refer to a value}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp taskloop simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp taskloop simd safelen (4)
@@ -57,16 +69,27 @@ int main(int argc, char **argv) {
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp taskloop simd safelen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- #pragma omp taskloop simd safelen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+ #pragma omp taskloop simd safelen (foobool(1) > 0 ? 1 : 2)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+3 {{expression is not an integral constant expression}}
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
// expected-error@+2 2 {{directive '#pragma omp taskloop simd' cannot contain more than one 'safelen' clause}}
// expected-error@+1 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
#pragma omp taskloop simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp taskloop simd safelen (S1) // expected-error {{'S1' does not refer to a value}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+1 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp taskloop simd safelen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
// expected-error@+3 {{statement after '#pragma omp taskloop simd' must be a for loop}}
diff --git a/test/OpenMP/taskloop_simd_simdlen_messages.cpp b/test/OpenMP/taskloop_simd_simdlen_messages.cpp
index ba3f20e23cfe1..79655ba9c275b 100644
--- a/test/OpenMP/taskloop_simd_simdlen_messages.cpp
+++ b/test/OpenMP/taskloop_simd_simdlen_messages.cpp
@@ -1,8 +1,13 @@
// RUN: %clang_cc1 -verify -fopenmp %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s
void foo() {
}
+#if __cplusplus >= 201103L
+// expected-note@+2 4 {{declared here}}
+#endif
bool foobool(int argc) {
return argc;
}
@@ -29,14 +34,21 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp taskloop simd simdlen ((ST > 0) ? 1 + ST : 2)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error@+3 2 {{directive '#pragma omp taskloop simd' cannot contain more than one 'simdlen' clause}}
- // expected-error@+2 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+ // expected-error@+6 2 {{directive '#pragma omp taskloop simd' cannot contain more than one 'simdlen' clause}}
+ // expected-error@+5 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
#pragma omp taskloop simd simdlen (foobool(argc)), simdlen (true), simdlen (-5)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp taskloop simd simdlen (S) // expected-error {{'S' does not refer to a value}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
- // expected-error@+1 2 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 2 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp taskloop simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp taskloop simd simdlen (4)
@@ -57,16 +69,27 @@ int main(int argc, char **argv) {
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp taskloop simd simdlen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp taskloop simd' are ignored}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- #pragma omp taskloop simd simdlen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
+ #pragma omp taskloop simd simdlen (foobool(1) > 0 ? 1 : 2)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+3 {{expression is not an integral constant expression}}
+ // expected-error@+6 {{expression is not an integral constant expression}}
+#if __cplusplus >= 201103L
+ // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+#endif
// expected-error@+2 2 {{directive '#pragma omp taskloop simd' cannot contain more than one 'simdlen' clause}}
// expected-error@+1 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
#pragma omp taskloop simd simdlen (foobool(argc)), simdlen (true), simdlen (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp taskloop simd simdlen (S1) // expected-error {{'S1' does not refer to a value}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
- // expected-error@+1 {{expression is not an integral constant expression}}
+#if __cplusplus <= 199711L
+ // expected-error@+4 {{expression is not an integral constant expression}}
+#else
+ // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'char *'}}
+#endif
#pragma omp taskloop simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
// expected-error@+3 {{statement after '#pragma omp taskloop simd' must be a for loop}}
diff --git a/test/OpenMP/teams_ast_print.cpp b/test/OpenMP/teams_ast_print.cpp
index 292586ae530d9..f3d577cafcd35 100644
--- a/test/OpenMP/teams_ast_print.cpp
+++ b/test/OpenMP/teams_ast_print.cpp
@@ -109,4 +109,6 @@ int main (int argc, char **argv) {
return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x);
}
+extern template int S<int>::TS;
+extern template long S<long>::TS;
#endif
diff --git a/test/OpenMP/teams_codegen.cpp b/test/OpenMP/teams_codegen.cpp
new file mode 100644
index 0000000000000..8aaa206abc3b4
--- /dev/null
+++ b/test/OpenMP/teams_codegen.cpp
@@ -0,0 +1,353 @@
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+// Test host codegen.
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+#ifdef CK1
+
+int Gbla;
+long long Gblb;
+int &Gblc = Gbla;
+
+// CK1-LABEL: teams_argument_global_local
+int teams_argument_global_local(int a){
+ int comp = 1;
+
+ int la = 23;
+ float lc = 25.0;
+
+ // CK1: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // CK1: call void @{{.+}}(i{{64|32}} %{{.+}})
+ #pragma omp target
+ #pragma omp teams
+ {
+ ++comp;
+ }
+
+ // CK1: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // CK1: call void @{{.+}}(i{{64|32}} %{{.+}})
+ #pragma omp target
+ {{{
+ #pragma omp teams
+ {
+ ++comp;
+ }
+ }}}
+
+ // CK1-DAG: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 [[NT:%[^,]+]], i32 0)
+ // CK1-DAG: [[NT]] = load i32, i32* [[NTA:%[^,]+]],
+
+ // CK1: call void @{{.+}}(i{{64|32}} %{{.+}})
+ #pragma omp target
+ #pragma omp teams num_teams(la)
+ {
+ ++comp;
+ }
+
+ // CK1-DAG: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 [[NT:%[^,]+]])
+ // CK1-DAG: [[NT]] = load i32, i32* [[NTA:%[^,]+]],
+
+ // CK1: call void @{{.+}}(i{{64|32}} %{{.+}})
+ #pragma omp target
+ #pragma omp teams thread_limit(la)
+ {
+ ++comp;
+ }
+
+ // CK1-DAG: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 5, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 [[NT:%[^,]+]], i32 [[TL:%[^,]+]])
+
+ // CK1-DAG: [[NT]] = add nsw i32 [[NTA:%[^,]+]], [[NTB:%[^,]+]]
+ // CK1-DAG: [[NTA]] = load i32, i32* @Gbla,
+ // CK1-DAG: [[NTB]] = load i32, i32* %{{.+}},
+
+ // CK1-DAG: [[TL]] = trunc i64 [[TLA:%[^,]+]] to i32
+ // CK1-DAG: [[TLA]] = add nsw i64 [[TLB:%[^,]+]], [[TLC:%[^,]+]]
+ // CK1-DAG: [[TLC]] = fptosi float [[TLD:%[^,]+]] to i64
+ // CK1-DAG: [[TLD]] = load float, float* %{{.+}},
+ // CK1-DAG: [[TLB]] = load i64, i64* @Gblb,
+
+ // CK1: call void @{{.+}}(i{{.+}} {{.+}}, i{{.+}} {{.+}}, i{{.+}} {{.+}}, i{{.+}} {{.+}}, i{{.+}} {{.+}})
+ #pragma omp target
+ #pragma omp teams num_teams(Gbla+a) thread_limit(Gblb+(long long)lc)
+ {
+ ++comp;
+ }
+
+ // CK1-DAG: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 {{.+}}, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 [[NT:%[^,]+]], i32 [[TL:%[^,]+]])
+
+ // CK1-DAG: [[NT]] = add nsw i32 [[NTA:%[^,]+]], 1
+ // CK1-DAG: [[NTA]] = load i32, i32* @Gbla,
+
+ // CK1-DAG: [[TL]] = add nsw i32 [[TLA:%[^,]+]], 2
+ // CK1-DAG: [[TLA]] = load i32, i32* @Gbla,
+
+ // CK1: call void @{{.+}}(i{{.+}} {{.+}}
+ #pragma omp target
+ #pragma omp teams num_teams(Gblc+1) thread_limit(Gblc+2)
+ {
+ comp += Gblc;
+ }
+
+ return comp;
+}
+
+#endif // CK1
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+#ifdef CK2
+
+// CK2-DAG: [[SSI:%.+]] = type { i32, float }
+// CK2-DAG: [[SSL:%.+]] = type { i64, float }
+template <typename T>
+struct SS{
+ T a;
+ float b;
+};
+
+SS<int> Gbla;
+SS<long long> Gblb;
+
+// CK2-LABEL: teams_template_arg
+int teams_template_arg(void) {
+ int comp = 1;
+
+ SS<int> la;
+ SS<long long> lb;
+
+ // CK2-DAG: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 [[NT:%[^,]+]], i32 [[TL:%[^,]+]])
+
+ // CK2-DAG: [[NT]] = load i32, i32* getelementptr inbounds ([[SSI]], [[SSI]]* @Gbla, i32 0, i32 0)
+
+ // CK2-DAG: [[TL]] = trunc i64 [[TLA:%[^,]+]] to i32
+ // CK2-DAG: [[TLA]] = fptosi float [[TLB:%[^,]+]] to i64
+ // CK2-DAG: [[TLB]] = load float, float* [[TLC:%[^,]+]],
+ // CK2-DAG: [[TLC]] = getelementptr inbounds [[SSI]], [[SSI]]* %{{.+}}, i32 0, i32 1
+
+ // CK2: call void @{{.+}}({{.+}} {{.+}}, {{.+}} {{.+}}, {{.+}} {{.+}})
+ #pragma omp target
+ #pragma omp teams num_teams(Gbla.a) thread_limit((long long)la.b)
+ {
+ ++comp;
+ }
+
+ // CK2-DAG: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 [[NT:%[^,]+]], i32 [[TL:%[^,]+]])
+
+ // CK2-DAG: [[TL]] = trunc i64 [[TLD:%[^,]+]] to i32
+ // CK2-DAG: [[TLD]] = load i64, i64* getelementptr inbounds ([[SSL]], [[SSL]]* @Gblb, i32 0, i32 0),
+
+ // CK2-DAG: [[NT]] = trunc i64 [[NTA:%[^,]+]] to i32
+ // CK2-DAG: [[NTA]] = fptosi float [[NTB:%[^,]+]] to i64
+ // CK2-DAG: [[NTB]] = load float, float* [[NTC:%[^,]+]],
+ // CK2-DAG: [[NTC]] = getelementptr inbounds [[SSL]], [[SSL]]* %{{.+}}, i32 0, i32 1
+
+ // CK2: call void @{{.+}}({{.+}} {{.+}}, {{.+}} {{.+}}, {{.+}} {{.+}})
+ #pragma omp target
+ #pragma omp teams num_teams((long long)lb.b) thread_limit(Gblb.a)
+ {
+ ++comp;
+ }
+ return comp;
+}
+#endif // CK2
+
+// Test host codegen.
+// RUN: %clang_cc1 -DCK3 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-64
+// RUN: %clang_cc1 -DCK3 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DCK3 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK3 --check-prefix CK3-32
+#ifdef CK3
+
+// CK3: [[SSI:%.+]] = type { i32, float }
+// CK3-LABEL: teams_template_struct
+
+template <typename T, int X, long long Y>
+struct SS{
+ T a;
+ float b;
+
+ int foo(void) {
+ int comp = 1;
+
+ // CK3-DAG: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 [[NT:%[^,]+]], i32 123)
+
+ // CK3-DAG: [[NT]] = load i32, i32* [[NTA:%[^,]+]],
+ // CK3-DAG: [[NTA]] = getelementptr inbounds [[SSI]], [[SSI]]* [[NTB:%[^,]+]], i32 0, i32 0
+ // CK3-DAG: [[NTB]] = load [[SSI]]*, [[SSI]]** %{{.+}},
+
+ // CK3: call void @{{.+}}({{.+}} {{.+}}, {{.+}} {{.+}})
+ #pragma omp target
+ #pragma omp teams num_teams(a) thread_limit(X)
+ {
+ ++comp;
+ }
+
+ // CK3-DAG: call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 456, i32 [[TL:%[^,]+]])
+
+ // CK3-DAG: [[TL]] = add nsw i32 [[TLA:%[^,]+]], 123
+ // CK3-DAG: [[TLA]] = fptosi float [[TLB:%[^,]+]] to i32
+ // CK3-DAG: [[TLB]] = load float, float* [[TLC:%[^,]+]],
+ // CK3-DAG: [[TLC]] = getelementptr inbounds [[SSI]], [[SSI]]* [[THIS:%[^,]+]], i32 0, i32 1
+
+ // CK3: call void @{{.+}}({{.+}} {{.+}}, {{.+}} {{.+}})
+ #pragma omp target
+ #pragma omp teams num_teams(Y) thread_limit((int)b+X)
+ {
+ ++comp;
+ }
+ return comp;
+ }
+};
+
+int teams_template_struct(void) {
+ SS<int, 123, 456> V;
+ return V.foo();
+
+}
+#endif // CK3
+
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64
+// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-64
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32
+// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -DCK4 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK4 --check-prefix CK4-32
+
+#ifdef CK4
+
+// CK4-DAG: %ident_t = type { i32, i32, i32, i32, i8* }
+// CK4-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
+// CK4-DAG: [[DEF_LOC_0:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
+// CK4-DEBUG-DAG: [[LOC1:@.+]] = private unnamed_addr constant [{{.+}} x i8] c";{{.*}}teams_codegen.cpp;main;[[@LINE+14]];9;;\00"
+// CK4-DEBUG-DAG: [[LOC2:@.+]] = private unnamed_addr constant [{{.+}} x i8] c";{{.*}}teams_codegen.cpp;tmain;[[@LINE+7]];9;;\00"
+
+template <typename T>
+int tmain(T argc) {
+#pragma omp target
+#pragma omp teams
+ argc = 0;
+ return 0;
+}
+
+int main (int argc, char **argv) {
+#pragma omp target
+#pragma omp teams
+ argc = 0;
+ return tmain(argv);
+}
+
+// CK4: define {{.*}}void @{{[^,]+}}(i{{.+}} %[[ARGC:.+]])
+// CK4: [[ARGCADDR:%.+]] = alloca i{{.+}}
+// CK4: store i{{.+}} %[[ARGC]], i{{.+}}* [[ARGCADDR]]
+// CK4-64: [[CONV:%.+]] = bitcast i64* [[ARGCADDR]] to i32*
+// CK4-64: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC_0]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* {{.+}} to void (i32*, i32*, ...)*), i32* [[CONV]])
+// CK4-32: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC_0]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* {{.+}} to void (i32*, i32*, ...)*), i32* [[ARGCADDR]])
+// CK4: ret void
+// CK4-NEXT: }
+
+// CK4: define {{.*}}void @{{[^,]+}}(i8** [[ARGC1:%.+]])
+// CK4: [[ARGCADDR1:%.+]] = alloca i8**
+// CK4: store i8** [[ARGC1]], i8*** [[ARGCADDR1]]
+// CK4: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC_0]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i8***)* {{.+}} to void (i32*, i32*, ...)*), i8*** [[ARGCADDR1]])
+
+
+#endif // CK4
+
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -DCK5 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -DCK5 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-64
+// RUN: %clang_cc1 -DCK5 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
+// RUN: %clang_cc1 -DCK5 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-64
+// RUN: %clang_cc1 -DCK5 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -DCK5 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-32
+// RUN: %clang_cc1 -DCK5 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
+// RUN: %clang_cc1 -DCK5 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK5 --check-prefix CK5-32
+
+// expected-no-diagnostics
+#ifdef CK5
+
+// CK5-DAG: %ident_t = type { i32, i32, i32, i32, i8* }
+// CK5-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
+// CK5-DAG: [[DEF_LOC_0:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
+// CK5-DEBUG-DAG: [[LOC1:@.+]] = private unnamed_addr constant [{{.+}} x i8] c";{{.*}}teams_codegen.cpp;main;[[@LINE+14]];9;;\00"
+// CK5-DEBUG-DAG: [[LOC2:@.+]] = private unnamed_addr constant [{{.+}} x i8] c";{{.*}}teams_codegen.cpp;tmain;[[@LINE+7]];9;;\00"
+
+template <typename T>
+int tmain(T argc) {
+ int a = 10;
+ int b = 5;
+#pragma omp target
+#pragma omp teams num_teams(a) thread_limit(b)
+ {
+ argc = 0;
+ }
+ return 0;
+}
+
+int main (int argc, char **argv) {
+ int a = 20;
+ int b = 5;
+#pragma omp target
+#pragma omp teams num_teams(a) thread_limit(b)
+ {
+ argc = 0;
+ }
+ return tmain(argv);
+}
+
+// CK5: define {{.*}}void @{{[^,]+}}(i{{.+}} [[AP:%.+]], i{{.+}} [[BP:%.+]], i{{.+}} [[ARGC:.+]])
+// CK5: [[AADDR:%.+]] = alloca i{{.+}}
+// CK5: [[BADDR:%.+]] = alloca i{{.+}}
+// CK5: [[ARGCADDR:%.+]] = alloca i{{.+}}
+// CK5: [[GBL_TH_NUM:%.+]] = call i32 @__kmpc_global_thread_num(%ident_t* [[DEF_LOC_0]])
+// CK5: store i{{.+}} [[AP]], i{{.+}}* [[AADDR]]
+// CK5: store i{{.+}} [[BP]], i{{.+}}* [[BADDR]]
+// CK5: store i{{.+}} [[ARGC]], i{{.+}}* [[ARGCADDR]]
+// CK5-64: [[ACONV:%.+]] = bitcast i64* [[AADDR]] to i32*
+// CK5-64: [[BCONV:%.+]] = bitcast i64* [[BADDR]] to i32*
+// CK5-64: [[CONV:%.+]] = bitcast i64* [[ARGCADDR]] to i32*
+// CK5-64: [[ACONVVAL:%.+]] = load i32, i32* [[ACONV]]
+// CK5-64: [[BCONVVAL:%.+]] = load i32, i32* [[BCONV]]
+// CK5-32: [[ACONVVAL:%.+]] = load i32, i32* [[AADDR]]
+// CK5-32: [[BCONVVAL:%.+]] = load i32, i32* [[BADDR]]
+// CK5: {{.+}} = call i32 @__kmpc_push_num_teams(%ident_t* [[DEF_LOC_0]], i32 [[GBL_TH_NUM]], i32 [[ACONVVAL]], i32 [[BCONVVAL]])
+// CK5-64: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC_0]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* [[CONV]])
+// CK5-32: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC_0]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* [[ARGCADDR]])
+
+// CK5: define {{.*}}void @{{[^,]+}}(i{{.+}} [[AP:%.+]], i{{.+}} [[BP:%.+]], i{{.+}}** [[ARGC:%.+]])
+// CK5: [[AADDR:%.+]] = alloca i{{.+}}
+// CK5: [[BADDR:%.+]] = alloca i{{.+}}
+// CK5: [[ARGCADDR:%.+]] = alloca i{{.+}}**
+// CK5: [[GBL_TH_NUM:%.+]] = call i32 @__kmpc_global_thread_num(%ident_t* [[DEF_LOC_0]])
+// CK5: store i{{.+}} [[AP]], i{{.+}}* [[AADDR]]
+// CK5: store i{{.+}} [[BP]], i{{.+}}* [[BADDR]]
+// CK5: store i{{.+}}** [[ARGC]], i{{.+}}*** [[ARGCADDR]]
+// CK5-64: [[ACONV:%.+]] = bitcast i64* [[AADDR]] to i32*
+// CK5-64: [[BCONV:%.+]] = bitcast i64* [[BADDR]] to i32*
+// CK5-64: [[ACONVVAL:%.+]] = load i32, i32* [[ACONV]]
+// CK5-64: [[BCONVVAL:%.+]] = load i32, i32* [[BCONV]]
+// CK5-64: {{.+}} = call i32 @__kmpc_push_num_teams(%ident_t* [[DEF_LOC_0]], i32 [[GBL_TH_NUM]], i32 [[ACONVVAL]], i32 [[BCONVVAL]])
+// CK5-32: [[A_VAL:%.+]] = load i32, i32* [[AADDR]]
+// CK5-32: [[B_VAL:%.+]] = load i32, i32* [[BADDR]]
+// CK5-32: {{.+}} = call i32 @__kmpc_push_num_teams(%ident_t* [[DEF_LOC_0]], i32 [[GBL_TH_NUM]], i32 [[A_VAL]], i32 [[B_VAL]])
+// CK5: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%ident_t* [[DEF_LOC_0]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i{{.+}})* @.omp_outlined.{{.+}} to void (i32*, i32*, ...)*), i{{.+}}*** [[ARGCADDR]])
+// CK5: ret void
+// CK5-NEXT: }
+
+#endif // CK5
+#endif
diff --git a/test/OpenMP/teams_firstprivate_codegen.cpp b/test/OpenMP/teams_firstprivate_codegen.cpp
new file mode 100644
index 0000000000000..3248bfeebd91f
--- /dev/null
+++ b/test/OpenMP/teams_firstprivate_codegen.cpp
@@ -0,0 +1,283 @@
+// Test host codegen.
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+
+// RUN: %clang_cc1 -DARRAY -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix ARRAY --check-prefix ARRAY-64
+// RUN: %clang_cc1 -DARRAY -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DARRAY -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix ARRAY --check-prefix ARRAY-64
+// RUN: %clang_cc1 -DARRAY -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix ARRAY --check-prefix ARRAY-32
+// RUN: %clang_cc1 -DARRAY -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DARRAY -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix ARRAY --check-prefix ARRAY-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+#ifndef ARRAY
+struct St {
+ int a, b;
+ St() : a(0), b(0) {}
+ St(const St &st) : a(st.a + st.b), b(0) {}
+ ~St() {}
+};
+
+volatile int g __attribute__((aligned(128))) = 1212;
+
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a + g) {}
+ S() : f(g) {}
+ S(const S &s, St t = St()) : f(s.f + t.a) {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+// CHECK-DAG: [[ST_TY:%.+]] = type { i{{[0-9]+}}, i{{[0-9]+}} }
+
+template <typename T>
+T tmain() {
+ S<T> test;
+ T t_var __attribute__((aligned(128))) = T();
+ T vec[] __attribute__((aligned(128))) = {1, 2};
+ S<T> s_arr[] __attribute__((aligned(128))) = {1, 2};
+ S<T> var __attribute__((aligned(128))) (3);
+ #pragma omp target
+ #pragma omp teams firstprivate(t_var, vec, s_arr, var)
+ {
+ vec[0] = t_var;
+ s_arr[0] = var;
+ }
+#pragma omp target
+#pragma omp teams firstprivate(t_var)
+ {}
+ return T();
+}
+
+int main() {
+ static int sivar;
+#ifdef LAMBDA
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 2, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* {{.+}}, {{.+}})
+ #pragma omp target
+ #pragma omp teams firstprivate(g, sivar)
+ {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) [[G_IN:%.+]], i{{64|32}} {{.*}}[[SIVAR_IN:%.+]])
+ // LAMBDA: store i{{[0-9]+}}* [[G_IN]], i{{[0-9]+}}** [[G_ADDR:%.+]],
+ // LAMBDA: store i{{[0-9]+}} [[SIVAR_IN]], i{{[0-9]+}}* [[SIVAR_ADDR:%.+]],
+ // LAMBDA: [[G_ADDR_VAL:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_ADDR]],
+ // LAMBDA-64: [[SIVAR_CONV:%.+]] = bitcast i64* [[SIVAR_ADDR]] to i32*
+ // LAMBDA: [[G_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[G_ADDR_VAL]],
+ // LAMBDA: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_LOCAL:%.+]],
+ g = 1;
+ sivar = 2;
+ // LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_LOCAL]],
+ // LAMBDA-64: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_CONV]],
+ // LAMBDA-32: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_ADDR]],
+ // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: store i{{[0-9]+}}* [[G_LOCAL]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]]
+ // LAMBDA: [[SIVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA-64: store i{{[0-9]+}}* [[SIVAR_CONV]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA-32: store i{{[0-9]+}}* [[SIVAR_ADDR]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]]
+ // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ sivar = 4;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]]
+ // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]]
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]]
+ }();
+ }
+ }();
+ return 0;
+#else
+ S<float> test;
+ int t_var = 0;
+ int vec[] = {1, 2};
+ S<float> s_arr[] = {1, 2};
+ S<float> var(3);
+ #pragma omp target
+ #pragma omp teams firstprivate(t_var, vec, s_arr, var, sivar)
+ {
+ vec[0] = t_var;
+ s_arr[0] = var;
+ sivar = 2;
+ }
+ #pragma omp target
+ #pragma omp teams firstprivate(t_var)
+ {}
+ return tmain<int>();
+#endif
+}
+
+// CHECK: define internal {{.*}}void [[OMP_OFFLOADING:@.+]](
+// CHECK: call {{.*}}void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x i32]*, i{{32|64}}, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, i{{[0-9]+}})* [[OMP_OUTLINED:@.+]] to void
+// CHECK: ret
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, i{{32|64}} {{.*}}%{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(8) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}}, i{{32|64}} {{.*}}[[SIVAR:%.+]])
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[SIVAR7_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+
+// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** %
+// CHECK-64: [[T_VAR_CONV:%.+]] = bitcast i64* [[T_VAR_PRIV]] to i32*
+// CHECK: [[S_ARR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** %
+// CHECK: [[VAR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %
+// CHECK-64: [[SIVAR7_CONV:%.+]] = bitcast i64* [[SIVAR7_PRIV]] to i32*
+// CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_REF]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST]], i8* [[VEC_SRC]],
+// CHECK: [[S_ARR_PRIV_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_BEGIN:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_REF]] to [[S_FLOAT_TY]]*
+// CHECK: [[S_ARR_PRIV_END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_PRIV_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_PRIV_BEGIN]], [[S_ARR_PRIV_END]]
+// CHECK: br i1 [[IS_EMPTY]], label %[[S_ARR_BODY_DONE:.+]], label %[[S_ARR_BODY:.+]]
+// CHECK: [[S_ARR_BODY]]
+// CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR:@.+]]([[ST_TY]]* [[ST_TY_TEMP:%.+]])
+// CHECK: call {{.*}} [[S_FLOAT_TY_COPY_CONSTR:@.+]]([[S_FLOAT_TY]]* {{.+}}, [[S_FLOAT_TY]]* {{.+}}, [[ST_TY]]* [[ST_TY_TEMP]])
+// CHECK: call {{.*}} [[ST_TY_DESTR:@.+]]([[ST_TY]]* [[ST_TY_TEMP]])
+// CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]]
+// CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]])
+// CHECK: call {{.*}} [[S_FLOAT_TY_COPY_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]], [[S_FLOAT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]])
+// CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]])
+
+// CHECK-64: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR7_CONV]],
+// CHECK-32: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR7_PRIV]],
+
+// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
+// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]*
+// CHECK: ret void
+
+// CHECK: define internal {{.*}}void [[OMP_OFFLOADING_1:@.+]](
+// CHECK: call {{.*}}void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i{{[0-9]+}})* [[OMP_OUTLINED_1:@.+]] to void
+// CHECK: ret
+
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED_1]](i{{[0-9]+}}* noalias {{%.+}}, i{{[0-9]+}}* noalias {{%.+}}, i{{32|64}} {{.*}}[[T_VAR:%.+]])
+// CHECK: [[T_VAR_LOC:%.+]] = alloca i{{[0-9]+}},
+// CHECK: store i{{[0-9]+}} [[T_VAR]], i{{[0-9]+}}* [[T_VAR_LOC]],
+// CHECK: ret
+
+// CHECK: define internal {{.*}}void [[OMP_OFFLOADING_2:@.+]](i{{[0-9]+}}* {{.+}} {{%.+}}, [2 x i32]* {{.+}} {{%.+}}, [2 x [[S_INT_TY]]]* {{.+}} {{%.+}}, [[S_INT_TY]]* {{.+}} {{%.+}})
+// CHECK: call {{.*}}void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x i32]*, i32*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[OMP_OUTLINED_2:@.+]] to void
+// CHECK: ret
+
+//
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED_2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, i32* dereferenceable(4) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(8) %{{.+}}, [[S_INT_TY]]* dereferenceable(4) %{{.+}})
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, align 128
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], align 128
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]], align 128
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]], align 128
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+
+// CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** %
+// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %
+// CHECK: [[S_ARR_REF:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** %
+// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** %
+
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]], align 128
+// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]], align 128
+// CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_REF]] to i8*
+// CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST]], i8* [[VEC_SRC]], i{{[0-9]+}} {{[0-9]+}}, i{{[0-9]+}} 128,
+// CHECK: [[S_ARR_PRIV_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+// CHECK: [[S_ARR_BEGIN:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_REF]] to [[S_INT_TY]]*
+// CHECK: [[S_ARR_PRIV_END:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_PRIV_BEGIN]], i{{[0-9]+}} 2
+// CHECK: [[IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_PRIV_BEGIN]], [[S_ARR_PRIV_END]]
+// CHECK: br i1 [[IS_EMPTY]], label %[[S_ARR_BODY_DONE:.+]], label %[[S_ARR_BODY:.+]]
+// CHECK: [[S_ARR_BODY]]
+// CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]])
+// CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR:@.+]]([[S_INT_TY]]* {{.+}}, [[S_INT_TY]]* {{.+}}, [[ST_TY]]* [[ST_TY_TEMP]])
+// CHECK: call {{.*}} [[ST_TY_DESTR:@.+]]([[ST_TY]]* [[ST_TY_TEMP]])
+// CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]]
+// CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]])
+// CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]])
+// CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]])
+// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* [[VAR_PRIV]])
+// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]*
+// CHECK: ret void
+
+// CHECK: define internal {{.*}}void [[OMP_OFFLOADING_3:@.+]](
+// CHECK: call {{.*}}void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i{{[0-9]+}}*)* [[OMP_OUTLINED_3:@.+]] to void
+// CHECK: ret
+
+// CHECK: define internal {{.*}}void [[OMP_OUTLINED_3]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i32* dereferenceable(4) [[T_VAR:%.+]])
+// CHECK: [[T_VAR_LOC:%.+]] = alloca i{{[0-9]+}},
+// CHECK: store i{{[0-9]+}}* [[T_VAR]], i{{[0-9]+}}** [[T_VAR_ADDR:%.+]],
+// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_ADDR]],
+// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]],
+// CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_LOC]],
+// CHECK: ret
+
+#else
+struct St {
+ int a, b;
+ St() : a(0), b(0) {}
+ St(const St &) { }
+ ~St() {}
+ void St_func(St s[2], int n, long double vla1[n]) {
+ double vla2[n][n] __attribute__((aligned(128)));
+ a = b;
+ #pragma omp target
+ #pragma omp teams firstprivate(s, vla1, vla2)
+ vla1[b] = vla2[1][n - 1] = a = b;
+ }
+};
+
+void array_func(float a[3], St s[2], int n, long double vla1[n]) {
+ double vla2[n][n] __attribute__((aligned(128)));
+// ARRAY: call {{.+}} @__kmpc_fork_teams(
+// ARRAY-DAG: [[PRIV_S:%.+]] = alloca %struct.St*,
+// ARRAY-64-DAG: [[PRIV_VLA1:%.+]] = alloca ppc_fp128*,
+// ARRAY-32-DAG: [[PRIV_VLA1:%.+]] = alloca x86_fp80*,
+// ARRAY-DAG: [[PRIV_A:%.+]] = alloca float*,
+// ARRAY-DAG: [[PRIV_VLA2:%.+]] = alloca double*,
+// ARRAY-DAG: store float* %{{.+}}, float** [[PRIV_A]],
+// ARRAY-DAG: store %struct.St* %{{.+}}, %struct.St** [[PRIV_S]],
+// ARRAY-64-DAG: store ppc_fp128* %{{.+}}, ppc_fp128** [[PRIV_VLA1]],
+// ARRAY-32-DAG: store x86_fp80* %{{.+}}, x86_fp80** [[PRIV_VLA1]],
+// ARRAY-DAG: store double* %{{.+}}, double** [[PRIV_VLA2]],
+// ARRAY: call i8* @llvm.stacksave()
+// ARRAY: [[SIZE:%.+]] = mul nuw i{{[0-9]+}} %{{.+}}, 8
+// ARRAY: call void @llvm.memcpy.p0i8.p0i8.i{{[0-9]+}}(i8* %{{.+}}, i8* %{{.+}}, i{{[0-9]+}} [[SIZE]], i32 128, i1 false)
+ #pragma omp target
+ #pragma omp teams firstprivate(a, s, vla1, vla2)
+ s[0].St_func(s, n, vla1);
+ ;
+}
+
+// ARRAY: @__kmpc_fork_teams(
+// ARRAY-DAG: [[PRIV_S:%.+]] = alloca %struct.St*,
+// ARRAY-64-DAG: [[PRIV_VLA1:%.+]] = alloca ppc_fp128*,
+// ARRAY-32-DAG: [[PRIV_VLA1:%.+]] = alloca x86_fp80*,
+// ARRAY-DAG: [[PRIV_VLA2:%.+]] = alloca double*,
+// ARRAY-DAG: store %struct.St* %{{.+}}, %struct.St** [[PRIV_S]],
+// ARRAY-64-DAG: store ppc_fp128* %{{.+}}, ppc_fp128** [[PRIV_VLA1]],
+// ARRAY-32-DAG: store x86_fp80* %{{.+}}, x86_fp80** [[PRIV_VLA1]],
+// ARRAY-DAG: store double* %{{.+}}, double** [[PRIV_VLA2]],
+// ARRAY: call i8* @llvm.stacksave()
+// ARRAY: [[SIZE:%.+]] = mul nuw i{{[0-9]+}} %{{.+}}, 8
+// ARRAY: call void @llvm.memcpy.p0i8.p0i8.i{{[0-9]+}}(i8* %{{.+}}, i8* %{{.+}}, i{{[0-9]+}} [[SIZE]], i32 128, i1 false)
+#endif
+#endif
diff --git a/test/OpenMP/teams_private_codegen.cpp b/test/OpenMP/teams_private_codegen.cpp
new file mode 100644
index 0000000000000..1ba010fa5c3cc
--- /dev/null
+++ b/test/OpenMP/teams_private_codegen.cpp
@@ -0,0 +1,298 @@
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-64
+// RUN: %clang_cc1 -DLAMBDA -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -DLAMBDA -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix LAMBDA --check-prefix LAMBDA-32
+
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+template <class T>
+struct S {
+ T f;
+ S(T a) : f(a) {}
+ S() : f() {}
+ operator T() { return T(); }
+ ~S() {}
+};
+
+volatile int g __attribute__((aligned(128))) = 1212;
+
+struct SS {
+ int a;
+ int b : 4;
+ int &c;
+ SS(int &d) : a(0), b(0), c(d) {
+#pragma omp target
+#pragma omp teams private(a, b, c)
+#ifdef LAMBDA
+ [&]() {
+ ++this->a, --b, (this)->c /= 1;
+ }();
+#else
+ ++this->a, --b, c /= 1;
+#endif
+ }
+};
+
+template<typename T>
+struct SST {
+ T a;
+ SST() : a(T()) {
+#pragma omp target
+#pragma omp teams private(a)
+#ifdef LAMBDA
+ [&]() {
+ [&]() {
+ ++this->a;
+ }();
+ }();
+#else
+ ++(this)->a;
+#endif
+ }
+};
+
+// CHECK: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8
+// LAMBDA: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8
+// LAMBDA: [[CAP_0_TY:%.+]] = type { [[SS_TY]]*, i{{[0-9]+}}*,
+// LAMBDA: [[CAP_1_TY:%.+]] = type { i{{[0-9]+}}*, i{{[0-9]+}}* }
+// CHECK: [[S_FLOAT_TY:%.+]] = type { float }
+// CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
+// CHECK: [[SST_TY:%.+]] = type { i{{[0-9]+}} }
+template <typename T>
+T tmain() {
+ S<T> test;
+ SST<T> sst;
+ T t_var __attribute__((aligned(128))) = T();
+ T vec[] __attribute__((aligned(128))) = {1, 2};
+ S<T> s_arr[] __attribute__((aligned(128))) = {1, 2};
+ S<T> var __attribute__((aligned(128))) (3);
+#pragma omp target
+#pragma omp teams private(t_var, vec, s_arr, var)
+ {
+ vec[0] = t_var;
+ s_arr[0] = var;
+ }
+ return T();
+}
+
+int main() {
+ static int sivar;
+ SS ss(sivar);
+#ifdef LAMBDA
+ // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
+ // LAMBDA: define {{.+}} @main()
+ // LAMBDA: alloca [[SS_TY]],
+ // LAMBDA: alloca [[CAP_TY:%.+]],
+
+ // LAMBDA: call{{.*}} [[ST_CONSTR_INIT:@.+]]([[SS_TY]]*
+ // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@[^(]+]]([[CAP_TY]]*
+
+ // lambda and target region in main
+ // LAMBDA: define {{.+}} [[OUTER_LAMBDA]]([[CAP_TY]]* {{.+}})
+ // LAMBDA: call void @[[OMP_OFFLOADING:.+]](i{{[0-9]+}}* {{.+}}, i{{[0-9]+}} {{.+}}
+
+ // target region in struct constructor
+ // LAMBDA: define{{.*}} void [[ST_CONSTR:@.+]]([[SS_TY]]* %this,
+ // LAMBDA: call void [[OMP_OFFLOADING_1:@.+]]([[SS_TY]]
+
+ // offloading function in struct constructor
+ // LAMBDA: define{{.*}} void [[OMP_OFFLOADING_1]]([[SS_TY]]
+ // LAMBDA: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[OMP_OUTLINED:@.+]] to void
+
+ // outlined teams region in struct constructor
+ // LAMBDA: define{{.*}} void [[OMP_OUTLINED]](i{{[0-9]+}}* {{.+}}, i{{[0-9]+}}* {{.+}}, [[SS_TY]]*
+ // LAMBDA: [[THIS_ADDR:%.+]] = alloca [[SS_TY]]*,
+ // LAMBDA: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[THIS_REF:%.+]] = load [[SS_TY]]*, [[SS_TY]]** [[THIS_ADDR]],
+ // LAMBDA: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[A_TMP_REF:%.+]],
+ // LAMBDA: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[C_TMP_REF:%.+]],
+ // LAMBDA: [[CAP_THIS_REF:%.+]] = getelementptr {{.+}} [[CAP_0_TY]], [[CAP_0_TY]]* {{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: store [[SS_TY]]* [[THIS_REF]], [[SS_TY]]** [[CAP_THIS_REF]],
+ // LAMBDA: [[CAP_A_REF:%.+]] = getelementptr {{.+}} [[CAP_0_TY]], [[CAP_0_TY]]* {{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[A_TMP_VAL:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[A_TMP_REF]],
+ // LAMBDA: store i{{[0-9]+}}* [[A_TMP_VAL]], i{{[0-9]+}}** [[CAP_A_REF]],
+ // LAMBDA: [[CAP_B_REF:%.+]] = getelementptr {{.+}} [[CAP_0_TY]], [[CAP_0_TY]]* {{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: store i{{[0-9]+}}* [[B_PRIV]], i{{[0-9]+}}** [[CAP_B_REF]],
+ // LAMBDA: [[CAP_C_REF:%.+]] = getelementptr {{.+}} [[CAP_0_TY]], [[CAP_0_TY]]* {{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: [[C_TMP_VAL:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[C_TMP_REF]],
+ // LAMBDA: store i{{[0-9]+}}* [[C_TMP_VAL]], i{{[0-9]+}}** [[CAP_C_REF]],
+ // call void [[INNER_LAMBDA_CONSTR:@.+]]([[CAP_0_TY]]*
+
+ // inner lambda in struct constructor
+ // define{{.*}} void [[INNER_LAMBDA_CONSTR]]([[CAP_0_TY]]*
+ // LAMBDA: [[CAP_A_REF_1:%.+]] = getelementptr {{.+}} [[CAP_0_TY]], [[CAP_0_TY]]* {{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // LAMBDA: [[A_REF_FROM_CAP:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[CAP_A_REF_1]],
+ // LAMBDA: [[A_VAL_FROM_CAP:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_REF_FROM_CAP]],
+ // LAMBDA: [[A_INC_VAL:%.+]] = add {{.+}} i{{[0-9]+}} [[A_VAL_FROM_CAP]], 1
+ // LAMBDA: store i{{[0-9]+}} [[A_INC_VAL]], i{{[0-9]+}}* [[A_REF_FROM_CAP]],
+
+ // LAMBDA: [[CAP_B_REF_1:%.+]] = getelementptr {{.+}} [[CAP_0_TY]], [[CAP_0_TY]]* {{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2
+ // LAMBDA: [[B_REF_FROM_CAP:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[CAP_B_REF_1]],
+ // LAMBDA: [[B_VAL_FROM_CAP:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_REF_FROM_CAP]],
+ // LAMBDA: [[B_DEC_VAL:%.+]] = add {{.+}} i{{[0-9]+}} [[B_VAL_FROM_CAP]], -1
+ // LAMBDA: store i{{[0-9]+}} [[B_DEC_VAL]], i{{[0-9]+}}* [[B_REF_FROM_CAP]],
+
+ // LAMBDA: [[CAP_C_REF_1:%.+]] = getelementptr {{.+}} [[CAP_0_TY]], [[CAP_0_TY]]* {{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3
+ // LAMBDA: [[C_REF_FROM_CAP:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[CAP_C_REF_1]],
+ // LAMBDA: [[C_VAL_FROM_CAP:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_REF_FROM_CAP]],
+ // LAMBDA: [[C_DEC_VAL:%.+]] = sdiv{{.*}} i{{[0-9]+}} [[C_VAL_FROM_CAP]], 1
+ // LAMBDA: store i{{[0-9]+}} [[C_DEC_VAL]], i{{[0-9]+}}* [[C_REF_FROM_CAP]],
+ // ret
+
+ [&]() {
+#pragma omp target
+#pragma omp teams private(g, sivar)
+ {
+ // LAMBDA: define{{.+}} @[[OMP_OFFLOADING]](i{{[0-9]+}}* {{.+}} [[G_IN:%.+]], i{{[0-9]+}} [[SIVAR_IN:%.+]]
+ // LAMBDA: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[OMP_OUTLINED_1:@.+]] to void
+
+ // LAMBDA: define {{.+}} [[OMP_OUTLINED_1]](i{{[0-9]+}}* {{.+}}, i{{[0-9]+}}* {{.+}}
+ // LAMBDA: [[G_LOC_OUTER:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: [[SIVAR_LOC_OUTER:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_LOC_OUTER]]
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_LOC_OUTER]]
+ // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@[^(]+]]([[CAP_1_TY]]*
+ // LAMBDA: ret
+ g = 1;
+ sivar = 2;
+ [&]() {
+ // LAMBDA: define {{.+}} [[INNER_LAMBDA]]([[CAP_1_TY]]* {{.+}})
+ g = 2;
+ sivar = 4;
+ // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}*
+ // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}*
+ }();
+ }
+ }();
+ return 0;
+#else
+ S<float> test;
+ int t_var = 0;
+ int vec[] = {1, 2};
+ S<float> s_arr[] = {1, 2};
+ S<float> var(3);
+#pragma omp target
+#pragma omp teams private(t_var, vec, s_arr, var, sivar)
+ {
+ vec[0] = t_var;
+ s_arr[0] = var;
+ sivar = 3;
+ }
+ return tmain<int>();
+#endif
+}
+
+// CHECK: define{{.*}} i{{[0-9]+}} @main()
+// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
+// CHECK: [[OFF_IN:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* {{%.+}},
+// CHECK: call void @[[OMP_OFFLOADING:.+]](i{{[0-9]+}} [[OFF_IN]]
+// CHECK: = call{{.*}} i{{.+}} [[TMAIN_INT:@.+]]()
+// CHECK: call void [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]*
+// CHECK: ret
+
+// target region in main function
+// CHECK: define{{.+}} @[[OMP_OFFLOADING]](i{{[0-9]+}}
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[OMP_OUTLINED:@.+]] to void
+
+// CHECK: define internal void [[OMP_OUTLINED]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}})
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}],
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+// CHECK: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]]
+// CHECK-NOT: [[T_VAR_PRIV]]
+// CHECK-NOT: [[VEC_PRIV]]
+// CHECK: {{.+}}:
+// CHECK: [[S_ARR_PRIV_ITEM:%.+]] = phi [[S_FLOAT_TY]]*
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[S_ARR_PRIV_ITEM]])
+// CHECK-NOT: [[T_VAR_PRIV]]
+// CHECK-NOT: [[VEC_PRIV]]
+// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
+// CHECK-DAG: call void [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
+// CHECK-DAG: call void [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]*
+// CHECK: ret void
+
+// template tmain
+// CHECK: define{{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
+// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
+// CHECK: call void [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* {{.+}}, i{{[0-9]+}}{{.*}} 3)
+// CHECK: call void [[OMP_OFFLOADING_TMAIN:@.+]]()
+
+// target in SS constructor
+// CHECK: define{{.+}} [[OMP_OFFLOADING_SS:@.+]]([[SS_TY]]*
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[OMP_OUTLINED_SS:@.+]] to void
+
+// CHECK: define{{.*}} void [[OMP_OUTLINED_SS]](i{{[0-9]+}}* {{.+}}, i{{[0-9]+}}* {{.+}}, [[SS_TY]]*
+// CHECK: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[A_REF:%.+]],
+// CHECK: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[C_REF:%.+]],
+// CHECK: [[A_REF_VAL:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[A_REF]]
+// CHECK: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_REF_VAL]]
+// CHECK: [[A_INC:%.+]] = add{{.*}} i{{[0-9]+}} [[A_VAL]], 1
+// CHECK: store i{{[0-9]+}} [[A_INC]], i{{[0-9]+}}* [[A_REF_VAL]],
+// CHECK: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]]
+// CHECK: [[B_DEC:%.+]] = add{{.*}} i{{[0-9]+}} [[B_VAL]], -1
+// CHECK: store i{{[0-9]+}} [[B_DEC]], i{{[0-9]+}}* [[B_PRIV]],
+// CHECK: [[C_REF_VAL:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[C_REF]]
+// CHECK: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_REF_VAL]]
+// CHECK: [[C_DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1
+// CHECK: store i{{[0-9]+}} [[C_DIV]], i{{[0-9]+}}* [[C_REF_VAL]],
+// CHECK: ret
+
+// target in tmain template
+// CHECK: define{{.+}} [[OMP_OFFLOADING_TMAIN]]()
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 0, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*)* [[OMP_OUTLINED_TMAIN:@.+]] to void
+
+// CHECK: define{{.*}} void [[OMP_OUTLINED_TMAIN]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}})
+// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, align 128
+// CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], align 128
+// CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]], align 128
+// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]], align 128
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]]
+// CHECK-NOT: [[T_VAR_PRIV]]
+// CHECK-NOT: [[VEC_PRIV]]
+// CHECK: {{.+}}:
+// CHECK: [[S_ARR_PRIV_ITEM:%.+]] = phi [[S_INT_TY]]*
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[S_ARR_PRIV_ITEM]])
+// CHECK-NOT: [[T_VAR_PRIV]]
+// CHECK-NOT: [[VEC_PRIV]]
+// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]])
+// CHECK-DAG: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* [[VAR_PRIV]])
+// CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]*
+// CHECK: ret
+
+// SST constructor
+// CHECK: define{{.+}} [[SST_CONST:@.+]]([[SST_TY]]* {{.+}})
+// CHECK: call void [[OMP_OFFLOADING_SST:@.+]]([[SST_TY]]* {{.+}})
+
+// target in SST constructor
+// CHECK: define{{.+}} [[OMP_OFFLOADING_SST]]([[SST_TY]]* {{.+}})
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_teams(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SST_TY]]*)* [[OMP_OUTLINED_SST:@.+]] to void
+
+// CHECK: define{{.+}} [[OMP_OUTLINED_SST]](i{{[0-9]+}}* {{.+}}, i{{[0-9]+}}* noalias %{{.+}}, [[SST_TY]]* {{.+}})
+// CHECK: [[A_PRIV_1:%.+]] = alloca i{{[0-9]+}},
+// CHECK: store i{{[0-9]+}}* [[A_PRIV_1]], i{{[0-9]+}}** [[A_REF_1:%.+]],
+// CHECK: [[A_REF_VAL_1:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[A_REF_1]]
+// CHECK: [[A_VAL_1:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_REF_VAL_1]]
+// CHECK: [[A_INC_1:%.+]] = add{{.*}} i{{[0-9]+}} [[A_VAL_1]], 1
+// CHECK: store i{{[0-9]+}} [[A_INC_1]], i{{[0-9]+}}* [[A_REF_VAL_1]],
+// CHECK: ret
+
+#endif
+
diff --git a/test/OpenMP/teams_reduction_messages.cpp b/test/OpenMP/teams_reduction_messages.cpp
index 87d03485c17b1..0420b010bb65b 100644
--- a/test/OpenMP/teams_reduction_messages.cpp
+++ b/test/OpenMP/teams_reduction_messages.cpp
@@ -13,7 +13,7 @@ struct S1; // expected-note {{declared here}} expected-note 4 {{forward declarat
extern S1 a;
class S2 {
mutable int a;
- S2 &operator+(const S2 &arg) { return (*this); } // expected-note 4 {{implicitly declared private here}}
+ S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}}
public:
S2() : a(0) {}
@@ -22,7 +22,7 @@ public:
static const float S2sc;
};
const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
-S2 b; // expected-note 2 {{'b' defined here}}
+S2 b; // expected-note 3 {{'b' defined here}}
const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
class S3 {
int a;
@@ -34,7 +34,7 @@ public:
S3 operator+(const S3 &arg1) { return arg1; }
};
int operator+(const S3 &arg1, const S3 &arg2) { return 5; }
-S3 c; // expected-note 2 {{'c' defined here}}
+S3 c; // expected-note 3 {{'c' defined here}}
const S3 ca[5]; // expected-note 2 {{'ca' defined here}}
extern const int f; // expected-note 4 {{'f' declared here}}
class S4 {
@@ -56,9 +56,9 @@ class S5 {
public:
S5(int v) : a(v) {}
};
-class S6 { // expected-note 2 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
#if __cplusplus >= 201103L // C++11 or later
-// expected-note@-2 2 {{candidate function (the implicit move assignment operator) not viable}}
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
#endif
int a;
@@ -112,7 +112,7 @@ T tmain(T argc) {
#pragma omp teams reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}}
foo();
#pragma omp target
-#pragma omp teams reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+#pragma omp teams reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
foo();
#pragma omp target
#pragma omp teams reduction(&& : argc)
@@ -121,22 +121,22 @@ T tmain(T argc) {
#pragma omp teams reduction(^ : T) // expected-error {{'T' does not refer to a value}}
foo();
#pragma omp target
-#pragma omp teams reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}}
+#pragma omp teams reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
foo();
#pragma omp target
-#pragma omp teams reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+#pragma omp teams reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
foo();
#pragma omp target
#pragma omp teams reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
foo();
#pragma omp target
-#pragma omp teams reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}}
+#pragma omp teams reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
foo();
#pragma omp target
-#pragma omp teams reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}}
+#pragma omp teams reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
foo();
#pragma omp target
-#pragma omp teams reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}}
+#pragma omp teams reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
foo();
#pragma omp target
#pragma omp teams reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -151,7 +151,7 @@ T tmain(T argc) {
#pragma omp teams reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
foo();
#pragma omp target
-#pragma omp teams reduction(+ : o) // expected-error {{no viable overloaded '='}}
+#pragma omp teams reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
foo();
#pragma omp target
#pragma omp teams private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
@@ -161,7 +161,7 @@ T tmain(T argc) {
#pragma omp teams reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
foo();
#pragma omp target
-#pragma omp teams reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}}
+#pragma omp teams reduction(+ : p), reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
foo();
#pragma omp target
#pragma omp teams reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
@@ -175,6 +175,7 @@ T tmain(T argc) {
#pragma omp teams
#pragma omp parallel for private(fl)
for (int i = 0; i < 10; ++i)
+ {}
#pragma omp target
#pragma omp teams reduction(+ : fl)
foo();
@@ -182,6 +183,7 @@ T tmain(T argc) {
#pragma omp teams
#pragma omp parallel for reduction(- : fl)
for (int i = 0; i < 10; ++i)
+ {}
#pragma omp target
#pragma omp teams reduction(+ : fl)
foo();
@@ -258,13 +260,13 @@ int main(int argc, char **argv) {
#pragma omp teams reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
foo();
#pragma omp target
-#pragma omp teams reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}}
+#pragma omp teams reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
foo();
#pragma omp target
-#pragma omp teams reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}}
+#pragma omp teams reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
foo();
#pragma omp target
-#pragma omp teams reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}}
+#pragma omp teams reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
foo();
#pragma omp target
#pragma omp teams reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
@@ -306,6 +308,7 @@ int main(int argc, char **argv) {
#pragma omp teams
#pragma omp parallel for private(fl)
for (int i = 0; i < 10; ++i)
+ {}
#pragma omp target
#pragma omp teams reduction(+ : fl)
foo();
@@ -313,6 +316,7 @@ int main(int argc, char **argv) {
#pragma omp teams
#pragma omp parallel for reduction(- : fl)
for (int i = 0; i < 10; ++i)
+ {}
#pragma omp target
#pragma omp teams reduction(+ : fl)
foo();
diff --git a/test/OpenMP/threadprivate_ast_print.cpp b/test/OpenMP/threadprivate_ast_print.cpp
index 2d876c1909fa9..f789c2f277d34 100644
--- a/test/OpenMP/threadprivate_ast_print.cpp
+++ b/test/OpenMP/threadprivate_ast_print.cpp
@@ -69,4 +69,5 @@ int main () {
return (foo<int>());
}
+extern template int ST<int>::m;
#endif
diff --git a/test/OpenMP/threadprivate_codegen.cpp b/test/OpenMP/threadprivate_codegen.cpp
index 53d7ef7083850..273f0488220ce 100644
--- a/test/OpenMP/threadprivate_codegen.cpp
+++ b/test/OpenMP/threadprivate_codegen.cpp
@@ -221,7 +221,7 @@ static S1 gs1(5);
// CHECK-DEBUG: store i8* %0, i8** [[ARG_ADDR:%.*]],
// CHECK-DEBUG: [[ARG:%.+]] = load i8*, i8** [[ARG_ADDR]]
// CHECK-DEBUG: [[RES:%.*]] = bitcast i8* [[ARG]] to [[S1]]*
-// CHECK-DEBUG-NEXT: call {{.*}} [[S1_CTOR:@.+]]([[S1]]* [[RES]], {{.*}} 5)
+// CHECK-DEBUG-NEXT: call {{.*}} [[S1_CTOR:@.+]]([[S1]]* [[RES]], {{.*}} 5){{.*}}, !dbg
// CHECK-DEBUG: [[ARG:%.+]] = load i8*, i8** [[ARG_ADDR]]
// CHECK-DEBUG: ret i8* [[ARG]]
// CHECK-DEBUG-NEXT: }
@@ -230,7 +230,7 @@ static S1 gs1(5);
// CHECK-DEBUG: store i8* %0, i8** [[ARG_ADDR:%.*]],
// CHECK-DEBUG: [[ARG:%.+]] = load i8*, i8** [[ARG_ADDR]]
// CHECK-DEBUG: [[RES:%.*]] = bitcast i8* [[ARG]] to [[S1]]*
-// CHECK-DEBUG-NEXT: call {{.*}} [[S1_DTOR:@.+]]([[S1]]* [[RES]])
+// CHECK-DEBUG-NEXT: call {{.*}} [[S1_DTOR:@.+]]([[S1]]* [[RES]]){{.*}}, !dbg
// CHECK-DEBUG-NEXT: ret void
// CHECK-DEBUG-NEXT: }
// CHECK-DEBUG: define {{.*}} [[S1_DTOR]]([[S1]]* {{.*}})
@@ -617,7 +617,7 @@ int main() {
// CHECK-DEBUG: call {{.*}} [[SMAIN_DTOR:@.+]]([[SMAIN]]*
// CHECK-DEBUG: }
// CHECK-DEBUG: define {{.*}} [[SMAIN_DTOR]]([[SMAIN]]* {{.*}})
-// CHECK-TLS: define internal [[S1]]* [[GS1_TLS_INITD]] {
+// CHECK-TLS: define internal [[S1]]* [[GS1_TLS_INITD]] {{#[0-9]+}} {
// CHECK-TLS-NEXT: call void [[GS1_TLS_INIT]]
// CHECK-TLS-NEXT: ret [[S1]]* [[GS1]]
// CHECK-TLS-NEXT: }
@@ -639,15 +639,15 @@ int main() {
// CHECK-TLS: call void [[ARR_X_TLS_INIT]]
// CHECK-TLS: ret [2 x [3 x [[S1]]]]* [[ARR_X]]
// CHECK-TLS: }
-// CHECK-TLS: define {{.*}} i32* [[ST_INT_ST_TLS_INITD]] {
+// CHECK-TLS: define {{.*}} i32* [[ST_INT_ST_TLS_INITD]] {{#[0-9]+}} {
// CHECK-TLS: call void [[ST_INT_ST_TLS_INIT]]
// CHECK-TLS: ret i32* [[ST_INT_ST]]
// CHECK-TLS: }
-// CHECK-TLS: define {{.*}} float* [[ST_FLOAT_ST_TLS_INITD]] {
+// CHECK-TLS: define {{.*}} float* [[ST_FLOAT_ST_TLS_INITD]] {{#[0-9]+}} {
// CHECK-TLS: call void [[ST_FLOAT_ST_TLS_INIT]]
// CHECK-TLS: ret float* [[ST_FLOAT_ST]]
// CHECK-TLS: }
-// CHECK-TLS: define {{.*}} [[S4]]* [[ST_S4_ST_TLS_INITD]] {
+// CHECK-TLS: define {{.*}} [[S4]]* [[ST_S4_ST_TLS_INITD]] {{#[0-9]+}} {
// CHECK-TLS: call void [[ST_S4_ST_TLS_INIT]]
// CHECK-TLS: ret [[S4]]* [[ST_S4_ST]]
// CHECK-TLS: }
@@ -948,5 +948,5 @@ int foobar() {
// CHECK-TLS: call void [[ST_S4_ST_CXX_INIT]]
// CHECK-TLS: [[DONE_LABEL]]
-// CHECK-TLS: declare {{.*}} void [[GS3_TLS_INIT]]
-// CHECK-TLS: declare {{.*}} void [[STATIC_S_TLS_INIT]]
+// CHECK-TLS-DAG: declare {{.*}} void [[GS3_TLS_INIT]]
+// CHECK-TLS-DAG: declare {{.*}} void [[STATIC_S_TLS_INIT]]
diff --git a/test/OpenMP/threadprivate_messages.cpp b/test/OpenMP/threadprivate_messages.cpp
index 8c442f47ad5ee..9775bfa458f49 100644
--- a/test/OpenMP/threadprivate_messages.cpp
+++ b/test/OpenMP/threadprivate_messages.cpp
@@ -70,7 +70,7 @@ class TestClass {
namespace ns {
int m;
-#pragma omp threadprivate (m)
+#pragma omp threadprivate (m, m)
}
#pragma omp threadprivate (m) // expected-error {{use of undeclared identifier 'm'}}
#pragma omp threadprivate (ns::m)