Skip to content

Commit 77861b3

Browse files
authored
[OpenMP][clang] 6.0: parsing/sema for message/severity for parallel (#146093)
Implement parsing and semantic analysis support for the message and severity clauses that have been added to the parallel directive in OpenMP 6.0, 12.1.
1 parent 1ace9fa commit 77861b3

File tree

6 files changed

+183
-21
lines changed

6 files changed

+183
-21
lines changed

clang/include/clang/AST/OpenMPClause.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1776,7 +1776,8 @@ class OMPAtClause final : public OMPClause {
17761776
}
17771777
};
17781778

1779-
/// This represents 'severity' clause in the '#pragma omp error' directive
1779+
/// This represents the 'severity' clause in the '#pragma omp error' and the
1780+
/// '#pragma omp parallel' directives.
17801781
///
17811782
/// \code
17821783
/// #pragma omp error severity(fatal)
@@ -1856,7 +1857,8 @@ class OMPSeverityClause final : public OMPClause {
18561857
}
18571858
};
18581859

1859-
/// This represents 'message' clause in the '#pragma omp error' directive
1860+
/// This represents the 'message' clause in the '#pragma omp error' and the
1861+
/// '#pragma omp parallel' directives.
18601862
///
18611863
/// \code
18621864
/// #pragma omp error message("GNU compiler required.")

clang/lib/Sema/SemaOpenMP.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6620,6 +6620,8 @@ StmtResult SemaOpenMP::ActOnOpenMPExecutableDirective(
66206620
case OMPC_affinity:
66216621
case OMPC_bind:
66226622
case OMPC_filter:
6623+
case OMPC_severity:
6624+
case OMPC_message:
66236625
continue;
66246626
case OMPC_allocator:
66256627
case OMPC_flush:
@@ -6637,8 +6639,6 @@ StmtResult SemaOpenMP::ActOnOpenMPExecutableDirective(
66376639
case OMPC_match:
66386640
case OMPC_when:
66396641
case OMPC_at:
6640-
case OMPC_severity:
6641-
case OMPC_message:
66426642
default:
66436643
llvm_unreachable("Unexpected clause");
66446644
}

clang/test/OpenMP/parallel_ast_print.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -173,13 +173,13 @@ T tmain(T argc, T *argv) {
173173
foo();
174174
#endif
175175
#ifdef OMP60
176-
#pragma omp parallel default(none), private(argc,b) firstprivate(argv) shared (d) if (parallel:argc > 0) num_threads(strict: C) copyin(S<T>::TS, thrp) proc_bind(primary) reduction(+:c, arr1[argc]) reduction(max:e, arr[:C][0:10])
176+
#pragma omp parallel default(none), private(argc,b) firstprivate(argv) shared (d) if (parallel:argc > 0) num_threads(strict: C) copyin(S<T>::TS, thrp) proc_bind(primary) reduction(+:c, arr1[argc]) reduction(max:e, arr[:C][0:10]) message("msg") severity(fatal)
177177
foo();
178178
#endif
179179
#pragma omp parallel if (C) num_threads(s) proc_bind(close) reduction(^:e, f, arr[0:C][:argc]) reduction(default, && : g) reduction(task,+:argc)
180180
foo();
181181
#ifdef OMP60
182-
#pragma omp parallel if (C) num_threads(strict: s) proc_bind(close) reduction(^:e, f, arr[0:C][:argc]) reduction(default, && : g) reduction(task,+:argc)
182+
#pragma omp parallel if (C) num_threads(strict: s) proc_bind(close) reduction(^:e, f, arr[0:C][:argc]) reduction(default, && : g) reduction(task,+:argc) message("msg") severity(warning)
183183
foo();
184184
#endif
185185
return 0;
@@ -196,11 +196,11 @@ T tmain(T argc, T *argv) {
196196
// CHECK-NEXT: foo()
197197
// OMP51-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(C) copyin(S<T>::TS,thrp) proc_bind(primary) reduction(+: c,arr1[argc]) reduction(max: e,arr[:C][0:10])
198198
// OMP51-NEXT: foo()
199-
// OMP60-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(strict: C) copyin(S<T>::TS,thrp) proc_bind(primary) reduction(+: c,arr1[argc]) reduction(max: e,arr[:C][0:10])
199+
// OMP60-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(strict: C) copyin(S<T>::TS,thrp) proc_bind(primary) reduction(+: c,arr1[argc]) reduction(max: e,arr[:C][0:10]) message("msg") severity(fatal)
200200
// OMP60-NEXT: foo()
201201
// CHECK-NEXT: #pragma omp parallel if(C) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:C][:argc]) reduction(default, &&: g) reduction(task, +: argc)
202202
// CHECK-NEXT: foo()
203-
// OMP60-NEXT: #pragma omp parallel if(C) num_threads(strict: s) proc_bind(close) reduction(^: e,f,arr[0:C][:argc]) reduction(default, &&: g) reduction(task, +: argc)
203+
// OMP60-NEXT: #pragma omp parallel if(C) num_threads(strict: s) proc_bind(close) reduction(^: e,f,arr[0:C][:argc]) reduction(default, &&: g) reduction(task, +: argc) message("msg") severity(warning)
204204
// OMP60-NEXT: foo()
205205
// CHECK: template<> int tmain<int, 5>(int argc, int *argv) {
206206
// CHECK-NEXT: int b = argc, c, d, e, f, g;
@@ -213,11 +213,11 @@ T tmain(T argc, T *argv) {
213213
// CHECK-NEXT: foo()
214214
// OMP51-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(5) copyin(S<int>::TS,thrp) proc_bind(primary) reduction(+: c,arr1[argc]) reduction(max: e,arr[:5][0:10])
215215
// OMP51-NEXT: foo()
216-
// OMP60-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(strict: 5) copyin(S<int>::TS,thrp) proc_bind(primary) reduction(+: c,arr1[argc]) reduction(max: e,arr[:5][0:10])
216+
// OMP60-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(strict: 5) copyin(S<int>::TS,thrp) proc_bind(primary) reduction(+: c,arr1[argc]) reduction(max: e,arr[:5][0:10]) message("msg") severity(fatal)
217217
// OMP60-NEXT: foo()
218218
// CHECK-NEXT: #pragma omp parallel if(5) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:5][:argc]) reduction(default, &&: g) reduction(task, +: argc)
219219
// CHECK-NEXT: foo()
220-
// OMP60-NEXT: #pragma omp parallel if(5) num_threads(strict: s) proc_bind(close) reduction(^: e,f,arr[0:5][:argc]) reduction(default, &&: g) reduction(task, +: argc)
220+
// OMP60-NEXT: #pragma omp parallel if(5) num_threads(strict: s) proc_bind(close) reduction(^: e,f,arr[0:5][:argc]) reduction(default, &&: g) reduction(task, +: argc) message("msg") severity(warning)
221221
// OMP60-NEXT: foo()
222222
// CHECK: template<> long tmain<long, 1>(long argc, long *argv) {
223223
// CHECK-NEXT: long b = argc, c, d, e, f, g;
@@ -230,11 +230,11 @@ T tmain(T argc, T *argv) {
230230
// CHECK-NEXT: foo()
231231
// OMP51-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(1) copyin(S<long>::TS,thrp) proc_bind(primary) reduction(+: c,arr1[argc]) reduction(max: e,arr[:1][0:10])
232232
// OMP51-NEXT: foo()
233-
// OMP60-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(strict: 1) copyin(S<long>::TS,thrp) proc_bind(primary) reduction(+: c,arr1[argc]) reduction(max: e,arr[:1][0:10])
233+
// OMP60-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(strict: 1) copyin(S<long>::TS,thrp) proc_bind(primary) reduction(+: c,arr1[argc]) reduction(max: e,arr[:1][0:10]) message("msg") severity(fatal)
234234
// OMP60-NEXT: foo()
235235
// CHECK-NEXT: #pragma omp parallel if(1) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:1][:argc]) reduction(default, &&: g) reduction(task, +: argc)
236236
// CHECK-NEXT: foo()
237-
// OMP60-NEXT: #pragma omp parallel if(1) num_threads(strict: s) proc_bind(close) reduction(^: e,f,arr[0:1][:argc]) reduction(default, &&: g) reduction(task, +: argc)
237+
// OMP60-NEXT: #pragma omp parallel if(1) num_threads(strict: s) proc_bind(close) reduction(^: e,f,arr[0:1][:argc]) reduction(default, &&: g) reduction(task, +: argc) message("msg") severity(warning)
238238
// OMP60-NEXT: foo()
239239

240240
enum Enum { };
@@ -256,8 +256,8 @@ int main (int argc, char **argv) {
256256
foo();
257257
// CHECK-NEXT: foo();
258258
#ifdef OMP60
259-
#pragma omp parallel default(none), private(argc,b) firstprivate(argv) if (parallel: argc > 0) num_threads(strict: ee) copyin(a) proc_bind(spread) reduction(| : c, d, arr1[argc]) reduction(* : e, arr[:10][0:argc]) allocate(e)
260-
// OMP60-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) if(parallel: argc > 0) num_threads(strict: ee) copyin(a) proc_bind(spread) reduction(|: c,d,arr1[argc]) reduction(*: e,arr[:10][0:argc]) allocate(e)
259+
#pragma omp parallel default(none), private(argc,b) firstprivate(argv) if (parallel: argc > 0) num_threads(strict: ee) copyin(a) proc_bind(spread) reduction(| : c, d, arr1[argc]) reduction(* : e, arr[:10][0:argc]) allocate(e) message("msg") severity(fatal)
260+
// OMP60-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) if(parallel: argc > 0) num_threads(strict: ee) copyin(a) proc_bind(spread) reduction(|: c,d,arr1[argc]) reduction(*: e,arr[:10][0:argc]) allocate(e) message("msg") severity(fatal)
261261
foo();
262262
// OMP60-NEXT: foo();
263263
#endif
@@ -266,8 +266,8 @@ int main (int argc, char **argv) {
266266
foo();
267267
// CHECK-NEXT: foo()
268268
#ifdef OMP60
269-
#pragma omp parallel allocate(e) if (b) num_threads(strict: c) proc_bind(close) reduction(^:e, f) reduction(&& : g, arr[0:argc][:10])
270-
// OMP60-NEXT: #pragma omp parallel allocate(e) if(b) num_threads(strict: c) proc_bind(close) reduction(^: e,f) reduction(&&: g,arr[0:argc][:10])
269+
#pragma omp parallel allocate(e) if (b) num_threads(strict: c) proc_bind(close) reduction(^:e, f) reduction(&& : g, arr[0:argc][:10]) message("msg") severity(warning)
270+
// OMP60-NEXT: #pragma omp parallel allocate(e) if(b) num_threads(strict: c) proc_bind(close) reduction(^: e,f) reduction(&&: g,arr[0:argc][:10]) message("msg") severity(warning)
271271
foo();
272272
// OMP60-NEXT: foo()
273273
#endif
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// RUN: %clang_cc1 -verify=expected -fopenmp -fopenmp-version=60 -ferror-limit 100 %s -Wuninitialized
2+
// RUN: %clang_cc1 -verify=expected -fopenmp-simd -fopenmp-version=60 -ferror-limit 100 %s -Wuninitialized
3+
4+
void foo() {}
5+
6+
template <class T, typename S, int N>
7+
T tmain(T argc, S **argv) {
8+
// Correct usage
9+
#pragma omp parallel message("correct message")
10+
11+
// Missing parentheses
12+
#pragma omp parallel message // expected-error {{expected '(' after 'message'}}
13+
14+
// Empty parentheses
15+
#pragma omp parallel message() // expected-error {{expected expression}}
16+
17+
// Non-string literal
18+
#pragma omp parallel message(123) // expected-warning {{expected string literal in 'clause message' - ignoring}}
19+
#pragma omp parallel message(argc) // expected-warning {{expected string literal in 'clause message' - ignoring}}
20+
#pragma omp parallel message(argv[0]) // expected-warning {{expected string literal in 'clause message' - ignoring}}
21+
22+
// Multiple arguments
23+
#pragma omp parallel message("msg1", "msg2") // expected-error {{expected ')'}} expected-note {{to match this '('}}
24+
25+
// Unterminated string
26+
// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-warning@+1 {{missing terminating '"' character}} expected-note@+1 {{to match this '('}}
27+
#pragma omp parallel message("unterminated
28+
29+
// Unterminated clause
30+
// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
31+
#pragma omp parallel message("msg"
32+
33+
// Extra tokens after clause
34+
#pragma omp parallel message("msg") extra // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
35+
36+
// Multiple message clauses
37+
#pragma omp parallel message("msg1") message("msg2") // expected-error {{directive '#pragma omp parallel' cannot contain more than one 'message' clause}}
38+
39+
// Message clause with other clauses (should be valid, but test for interaction)
40+
#pragma omp parallel message("msg") num_threads(2)
41+
42+
// Message clause with invalid clause
43+
#pragma omp parallel message("msg") invalid_clause // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
44+
45+
// Message clause with missing string and other clause
46+
#pragma omp parallel message() num_threads(2) // expected-error {{expected expression}}
47+
48+
// Message clause with macro that is not a string
49+
#define NOT_A_STRING 123
50+
#pragma omp parallel message(NOT_A_STRING) // expected-warning {{expected string literal in 'clause message' - ignoring}}
51+
52+
// Message clause with template parameter that is not a string
53+
#pragma omp parallel message(N) // expected-warning {{expected string literal in 'clause message' - ignoring}}
54+
55+
// Message clause with macro that is a string
56+
#define A_STRING "macro string"
57+
#pragma omp parallel message(A_STRING)
58+
59+
// Message clause with concatenated string literals
60+
#pragma omp parallel message("hello" " world")
61+
62+
// Message clause with wide string literal
63+
#pragma omp parallel message(L"wide string")
64+
65+
// Message clause with UTF-8 string literal
66+
#pragma omp parallel message(u8"utf8 string")
67+
68+
// Message clause with raw string literal
69+
#pragma omp parallel message(R"(raw string)")
70+
71+
foo();
72+
73+
return argc;
74+
}
75+
76+
int main(int argc, char **argv) {
77+
// Correct usage
78+
#pragma omp parallel message("main correct")
79+
80+
// Invalid: missing string
81+
#pragma omp parallel message() // expected-error {{expression}}
82+
83+
// Invalid: non-string
84+
#pragma omp parallel message(argc) // expected-warning {{expected string literal in 'clause message' - ignoring}}
85+
86+
foo();
87+
88+
return tmain<int, char, 3>(argc, argv);
89+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// RUN: %clang_cc1 -verify=expected -fopenmp -fopenmp-version=60 -ferror-limit 100 %s -Wuninitialized
2+
// RUN: %clang_cc1 -verify=expected -fopenmp-simd -fopenmp-version=60 -ferror-limit 100 %s -Wuninitialized
3+
4+
void foo() {}
5+
6+
template <class T, typename S, int N>
7+
T tmain(T argc, S **argv) {
8+
// Correct usages
9+
#pragma omp parallel severity(fatal)
10+
#pragma omp parallel severity(warning)
11+
12+
// Missing parentheses
13+
#pragma omp parallel severity // expected-error {{expected '(' after 'severity'}}
14+
15+
// Empty parentheses
16+
#pragma omp parallel severity() // expected-error {{expected 'fatal' or 'warning' in OpenMP clause 'severity'}}
17+
18+
// Invalid value
19+
#pragma omp parallel severity(error) // expected-error {{expected 'fatal' or 'warning' in OpenMP clause 'severity'}}
20+
#pragma omp parallel severity(unknown) // expected-error {{expected 'fatal' or 'warning' in OpenMP clause 'severity'}}
21+
22+
// Multiple arguments
23+
#pragma omp parallel severity(fatal, warning) // expected-error {{expected ')'}} expected-note {{to match this '('}}
24+
25+
// Unterminated clause
26+
// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
27+
#pragma omp parallel severity(fatal
28+
29+
// Extra tokens after clause
30+
#pragma omp parallel severity(fatal) extra // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
31+
32+
// Multiple severity clauses
33+
#pragma omp parallel severity(fatal) severity(warning) // expected-error {{directive '#pragma omp parallel' cannot contain more than one 'severity' clause}}
34+
35+
// Severity clause with other clauses (should be valid)
36+
#pragma omp parallel severity(warning) num_threads(2)
37+
38+
// Severity clause with invalid clause
39+
#pragma omp parallel severity(fatal) invalid_clause // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
40+
41+
// Severity clause with macro that is not a valid value
42+
#define NOT_A_SEVERITY 123
43+
#pragma omp parallel severity(NOT_A_SEVERITY) // expected-error {{expected 'fatal' or 'warning' in OpenMP clause 'severity'}}
44+
45+
// Severity clause with macro that is a valid value
46+
#define FATAL fatal
47+
#pragma omp parallel severity(FATAL)
48+
49+
// Severity clause with template parameter that is not a valid value
50+
#pragma omp parallel severity(N) // expected-error {{expected 'fatal' or 'warning' in OpenMP clause 'severity'}}
51+
52+
foo();
53+
54+
return argc;
55+
}
56+
57+
int main(int argc, char **argv) {
58+
// Correct usage
59+
#pragma omp parallel severity(fatal)
60+
61+
// Invalid: missing value
62+
#pragma omp parallel severity() // expected-error {{expected 'fatal' or 'warning' in OpenMP clause 'severity'}}
63+
64+
// Invalid: non-keyword
65+
#pragma omp parallel severity(argc) // expected-error {{expected 'fatal' or 'warning' in OpenMP clause 'severity'}}
66+
67+
foo();
68+
69+
return tmain<int, char, 3>(argc, argv);
70+
}

llvm/include/llvm/Frontend/OpenMP/OMP.td

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -955,11 +955,12 @@ def OMP_Parallel : Directive<[Spelling<"parallel">]> {
955955
VersionedClause<OMPC_Reduction>,
956956
VersionedClause<OMPC_Shared>,
957957
];
958-
let allowedOnceClauses = [
959-
VersionedClause<OMPC_Default>,
960-
VersionedClause<OMPC_If>,
961-
VersionedClause<OMPC_NumThreads>,
962-
VersionedClause<OMPC_ProcBind>,
958+
let allowedOnceClauses = [VersionedClause<OMPC_Default>,
959+
VersionedClause<OMPC_If>,
960+
VersionedClause<OMPC_NumThreads>,
961+
VersionedClause<OMPC_ProcBind>,
962+
VersionedClause<OMPC_Message, 60>,
963+
VersionedClause<OMPC_Severity, 60>,
963964
];
964965
let association = AS_Block;
965966
let category = CA_Executable;

0 commit comments

Comments
 (0)