16f9c2516SMike Rice // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \
26f9c2516SMike Rice // RUN:   -fsyntax-only -verify %s
36f9c2516SMike Rice 
46f9c2516SMike Rice // expected-no-diagnostics
56f9c2516SMike Rice 
66f9c2516SMike Rice // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \
76f9c2516SMike Rice // RUN:   -ast-print %s | FileCheck %s --check-prefix=PRINT
86f9c2516SMike Rice 
96f9c2516SMike Rice // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \
106f9c2516SMike Rice // RUN:   -ast-dump  %s | FileCheck %s --check-prefix=DUMP
116f9c2516SMike Rice 
126f9c2516SMike Rice // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \
136f9c2516SMike Rice // RUN:   -emit-pch -o %t %s
146f9c2516SMike Rice 
156f9c2516SMike Rice // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \
166f9c2516SMike Rice // RUN:   -include-pch %t -ast-dump-all %s | FileCheck %s --check-prefix=DUMP
176f9c2516SMike Rice 
186f9c2516SMike Rice // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=51 \
196f9c2516SMike Rice // RUN:   -include-pch %t -ast-print %s | FileCheck %s --check-prefix=PRINT
206f9c2516SMike Rice 
216f9c2516SMike Rice #ifndef HEADER
226f9c2516SMike Rice #define HEADER
236f9c2516SMike Rice 
246f9c2516SMike Rice //PRINT: template <typename T, int C> void templ_foo(T t) {
256f9c2516SMike Rice //PRINT:   T j, z;
26*4eac7bcfSMike Rice //PRINT:   #pragma omp loop collapse(C) reduction(+: z) lastprivate(j) bind(thread)
276f9c2516SMike Rice //PRINT:   for (T i = 0; i < t; ++i)
286f9c2516SMike Rice //PRINT:       for (j = 0; j < t; ++j)
296f9c2516SMike Rice //PRINT:           z += i + j;
306f9c2516SMike Rice //PRINT: }
316f9c2516SMike Rice //DUMP: FunctionTemplateDecl{{.*}}templ_foo
326f9c2516SMike Rice //DUMP: TemplateTypeParmDecl{{.*}}T
336f9c2516SMike Rice //DUMP: NonTypeTemplateParmDecl{{.*}}C
346f9c2516SMike Rice //DUMP: OMPGenericLoopDirective
356f9c2516SMike Rice //DUMP: OMPCollapseClause
366f9c2516SMike Rice //DUMP: DeclRefExpr{{.*}}'C' 'int'
376f9c2516SMike Rice //DUMP: OMPReductionClause
386f9c2516SMike Rice //DUMP: DeclRefExpr{{.*}}'z' 'T'
396f9c2516SMike Rice //DUMP: OMPLastprivateClause
406f9c2516SMike Rice //DUMP: DeclRefExpr{{.*}}'j' 'T'
41*4eac7bcfSMike Rice //DUMP: OMPBindClause
426f9c2516SMike Rice //DUMP: ForStmt
436f9c2516SMike Rice //DUMP: ForStmt
446f9c2516SMike Rice 
456f9c2516SMike Rice //PRINT: template<> void templ_foo<int, 2>(int t) {
466f9c2516SMike Rice //PRINT:     int j, z;
47*4eac7bcfSMike Rice //PRINT:     #pragma omp loop collapse(2) reduction(+: z) lastprivate(j) bind(thread)
486f9c2516SMike Rice //PRINT:         for (int i = 0; i < t; ++i)
496f9c2516SMike Rice //PRINT:             for (j = 0; j < t; ++j)
506f9c2516SMike Rice //PRINT:                 z += i + j;
516f9c2516SMike Rice //PRINT: }
526f9c2516SMike Rice //DUMP: FunctionDecl{{.*}}templ_foo 'void (int)'
536f9c2516SMike Rice //DUMP: TemplateArgument type 'int'
546f9c2516SMike Rice //DUMP: TemplateArgument integral 2
556f9c2516SMike Rice //DUMP: ParmVarDecl{{.*}}'int':'int'
566f9c2516SMike Rice //DUMP: OMPGenericLoopDirective
576f9c2516SMike Rice //DUMP: OMPCollapseClause
586f9c2516SMike Rice //DUMP: ConstantExpr{{.*}}'int'
596f9c2516SMike Rice //DUMP: value: Int 2
606f9c2516SMike Rice //DUMP: OMPReductionClause
616f9c2516SMike Rice //DUMP: DeclRefExpr{{.*}}'z' 'int':'int'
626f9c2516SMike Rice //DUMP: OMPLastprivateClause
636f9c2516SMike Rice //DUMP: DeclRefExpr{{.*}}'j' 'int':'int'
64*4eac7bcfSMike Rice //DUMP: OMPBindClause
656f9c2516SMike Rice //DUMP: ForStmt
666f9c2516SMike Rice template <typename T, int C>
templ_foo(T t)676f9c2516SMike Rice void templ_foo(T t) {
686f9c2516SMike Rice 
696f9c2516SMike Rice   T j,z;
70*4eac7bcfSMike Rice   #pragma omp loop collapse(C) reduction(+:z) lastprivate(j) bind(thread)
716f9c2516SMike Rice   for (T i = 0; i<t; ++i)
726f9c2516SMike Rice     for (j = 0; j<t; ++j)
736f9c2516SMike Rice       z += i+j;
746f9c2516SMike Rice }
756f9c2516SMike Rice 
766f9c2516SMike Rice 
776f9c2516SMike Rice //PRINT: void test() {
786f9c2516SMike Rice //DUMP: FunctionDecl {{.*}}test 'void ()'
test()796f9c2516SMike Rice void test() {
806f9c2516SMike Rice   constexpr int N = 100;
816f9c2516SMike Rice   float MTX[N][N];
826f9c2516SMike Rice   int aaa[1000];
836f9c2516SMike Rice 
846f9c2516SMike Rice   //PRINT: #pragma omp target teams distribute parallel for map(tofrom: MTX)
856f9c2516SMike Rice   //PRINT: #pragma omp loop
866f9c2516SMike Rice   //DUMP: OMPTargetTeamsDistributeParallelForDirective
876f9c2516SMike Rice   //DUMP: CapturedStmt
886f9c2516SMike Rice   //DUMP: ForStmt
896f9c2516SMike Rice   //DUMP: CompoundStmt
906f9c2516SMike Rice   //DUMP: OMPGenericLoopDirective
916f9c2516SMike Rice   #pragma omp target teams distribute parallel for map(MTX)
926f9c2516SMike Rice   for (auto i = 0; i < N; ++i) {
936f9c2516SMike Rice     #pragma omp loop
946f9c2516SMike Rice     for (auto j = 0; j < N; ++j) {
956f9c2516SMike Rice       MTX[i][j] = 0;
966f9c2516SMike Rice     }
976f9c2516SMike Rice   }
986f9c2516SMike Rice 
996f9c2516SMike Rice   //PRINT: #pragma omp target teams
1006f9c2516SMike Rice   //PRINT: #pragma omp loop
1016f9c2516SMike Rice   //DUMP: OMPTargetTeamsDirective
1026f9c2516SMike Rice   //DUMP: CapturedStmt
1036f9c2516SMike Rice   //DUMP: ForStmt
1046f9c2516SMike Rice   //DUMP: OMPGenericLoopDirective
1056f9c2516SMike Rice   #pragma omp target teams
1066f9c2516SMike Rice   for (int i=0; i<1000; ++i) {
1076f9c2516SMike Rice     #pragma omp loop
1086f9c2516SMike Rice     for (int j=0; j<100; j++) {
1096f9c2516SMike Rice       aaa[i] += i + j;
1106f9c2516SMike Rice     }
1116f9c2516SMike Rice   }
1126f9c2516SMike Rice 
1136f9c2516SMike Rice   int j, z, z1;
114*4eac7bcfSMike Rice   //PRINT: #pragma omp loop collapse(2) private(z) lastprivate(j) order(concurrent) reduction(+: z1) bind(parallel)
1156f9c2516SMike Rice   //DUMP: OMPGenericLoopDirective
1166f9c2516SMike Rice   //DUMP: OMPCollapseClause
1176f9c2516SMike Rice   //DUMP: IntegerLiteral{{.*}}2
1186f9c2516SMike Rice   //DUMP: OMPPrivateClause
1196f9c2516SMike Rice   //DUMP-NEXT: DeclRefExpr{{.*}}'z'
1206f9c2516SMike Rice   //DUMP: OMPLastprivateClause
1216f9c2516SMike Rice   //DUMP-NEXT: DeclRefExpr{{.*}}'j'
1226f9c2516SMike Rice   //DUMP: OMPOrderClause
1236f9c2516SMike Rice   //DUMP: OMPReductionClause
1246f9c2516SMike Rice   //DUMP-NEXT: DeclRefExpr{{.*}}'z1'
125*4eac7bcfSMike Rice   //DUMP: OMPBindClause
1266f9c2516SMike Rice   //DUMP: ForStmt
1276f9c2516SMike Rice   //DUMP: ForStmt
1286f9c2516SMike Rice   #pragma omp loop collapse(2) private(z) lastprivate(j) order(concurrent) \
129*4eac7bcfSMike Rice                    reduction(+:z1) bind(parallel)
1306f9c2516SMike Rice   for (auto i = 0; i < N; ++i) {
1316f9c2516SMike Rice     for (j = 0; j < N; ++j) {
1326f9c2516SMike Rice       z = i+j;
1336f9c2516SMike Rice       MTX[i][j] = z;
1346f9c2516SMike Rice       z1 += z;
1356f9c2516SMike Rice     }
1366f9c2516SMike Rice   }
137*4eac7bcfSMike Rice 
138*4eac7bcfSMike Rice   //PRINT: #pragma omp target teams
139*4eac7bcfSMike Rice   //PRINT: #pragma omp loop bind(teams)
140*4eac7bcfSMike Rice   //DUMP: OMPTargetTeamsDirective
141*4eac7bcfSMike Rice   //DUMP: OMPGenericLoopDirective
142*4eac7bcfSMike Rice   //DUMP: OMPBindClause
143*4eac7bcfSMike Rice   //DUMP: ForStmt
144*4eac7bcfSMike Rice   #pragma omp target teams
145*4eac7bcfSMike Rice   #pragma omp loop bind(teams)
146*4eac7bcfSMike Rice   for (auto i = 0; i < N; ++i) { }
147*4eac7bcfSMike Rice 
148*4eac7bcfSMike Rice   //PRINT: #pragma omp target
149*4eac7bcfSMike Rice   //PRINT: #pragma omp teams
150*4eac7bcfSMike Rice   //PRINT: #pragma omp loop bind(teams)
151*4eac7bcfSMike Rice   //DUMP: OMPTargetDirective
152*4eac7bcfSMike Rice   //DUMP: OMPTeamsDirective
153*4eac7bcfSMike Rice   //DUMP: OMPGenericLoopDirective
154*4eac7bcfSMike Rice   //DUMP: OMPBindClause
155*4eac7bcfSMike Rice   //DUMP: ForStmt
156*4eac7bcfSMike Rice   #pragma omp target
157*4eac7bcfSMike Rice   #pragma omp teams
158*4eac7bcfSMike Rice   #pragma omp loop bind(teams)
159*4eac7bcfSMike Rice   for (auto i = 0; i < N; ++i) { }
160*4eac7bcfSMike Rice }
161*4eac7bcfSMike Rice 
162*4eac7bcfSMike Rice //PRINT: void nobindingfunc() {
163*4eac7bcfSMike Rice //DUMP: FunctionDecl {{.*}}nobindingfunc 'void ()'
nobindingfunc()164*4eac7bcfSMike Rice void nobindingfunc()
165*4eac7bcfSMike Rice {
166*4eac7bcfSMike Rice   //PRINT: #pragma omp loop
167*4eac7bcfSMike Rice   //DUMP: OMPGenericLoopDirective
168*4eac7bcfSMike Rice   //DUMP: ForStmt
169*4eac7bcfSMike Rice   #pragma omp loop
170*4eac7bcfSMike Rice   for (int i=0; i<10; ++i) { }
1716f9c2516SMike Rice }
1726f9c2516SMike Rice 
bar()1736f9c2516SMike Rice void bar()
1746f9c2516SMike Rice {
1756f9c2516SMike Rice   templ_foo<int,2>(8);
1766f9c2516SMike Rice }
1776f9c2516SMike Rice 
1786f9c2516SMike Rice #endif // HEADER
179