Skip to content

Commit 73ad78c

Browse files
authored
default clause replaced by otherwise clause for metadirective in OpenMP 5.2 (#125648)
This PR replaces the `default` clause with the `otherwise` clause for the `metadirective` in OpenMP. The `otherwise` clause serves as a fallback condition when no directive from the `when` clauses is selected. In the `when` clause, context selectors define traits evaluated to determine the directive to be applied.
1 parent 6d5ba79 commit 73ad78c

File tree

3 files changed

+67
-16
lines changed

3 files changed

+67
-16
lines changed

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1657,6 +1657,10 @@ def err_omp_expected_colon : Error<"missing ':' in %0">;
16571657
def err_omp_missing_comma : Error< "missing ',' after %0">;
16581658
def err_omp_expected_context_selector
16591659
: Error<"expected valid context selector in %0">;
1660+
def err_omp_unknown_clause
1661+
: Error<"unknown clause '%0' in %1">;
1662+
def warn_omp_default_deprecated : Warning<"'default' clause for"
1663+
" 'metadirective' is deprecated; use 'otherwise' instead">, InGroup<Deprecated>;
16601664
def err_omp_requires_out_inout_depend_type : Error<
16611665
"reserved locator 'omp_all_memory' requires 'out' or 'inout' "
16621666
"dependency types">;

clang/lib/Parse/ParseOpenMP.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2759,6 +2759,19 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
27592759
OpenMPClauseKind CKind = Tok.isAnnotation()
27602760
? OMPC_unknown
27612761
: getOpenMPClauseKind(PP.getSpelling(Tok));
2762+
// Check if the clause is unrecognized.
2763+
if (getLangOpts().OpenMP < 52 &&
2764+
(CKind == OMPC_unknown || CKind == OMPC_otherwise)) {
2765+
Diag(Tok, diag::err_omp_unknown_clause)
2766+
<< PP.getSpelling(Tok) << "metadirective";
2767+
}
2768+
if (getLangOpts().OpenMP >= 52 && CKind == OMPC_unknown) {
2769+
Diag(Tok, diag::err_omp_unknown_clause)
2770+
<< PP.getSpelling(Tok) << "metadirective";
2771+
}
2772+
if (CKind == OMPC_default && getLangOpts().OpenMP >= 52) {
2773+
Diag(Tok, diag::warn_omp_default_deprecated);
2774+
}
27622775
SourceLocation Loc = ConsumeToken();
27632776

27642777
// Parse '('.
@@ -2785,6 +2798,13 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
27852798
return Directive;
27862799
}
27872800
}
2801+
if (CKind == OMPC_otherwise) {
2802+
// Check for 'otherwise' keyword.
2803+
if (Tok.is(tok::identifier) &&
2804+
Tok.getIdentifierInfo()->getName() == "otherwise") {
2805+
ConsumeToken(); // Consume 'otherwise'
2806+
}
2807+
}
27882808
// Skip Directive for now. We will parse directive in the second iteration
27892809
int paren = 0;
27902810
while (Tok.isNot(tok::r_paren) || paren != 0) {

clang/test/OpenMP/metadirective_messages.cpp

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,48 @@
22

33
// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -verify -fopenmp-simd -x c++ -std=c++14 -fexceptions -fcxx-exceptions %s
44

5+
// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -ferror-limit 100 -o - %s -Wuninitialized
6+
57
void foo() {
6-
#pragma omp metadirective // expected-error {{expected expression}}
7-
;
8-
#pragma omp metadirective when() // expected-error {{expected valid context selector in when clause}} expected-error {{expected expression}} expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
9-
;
10-
#pragma omp metadirective when(device{}) // expected-warning {{expected '=' after the context set name "device"; '=' assumed}} expected-warning {{expected identifier or string literal describing a context selector; selector skipped}} expected-note {{context selector options are: 'kind' 'arch' 'isa'}} expected-note {{the ignored selector spans until here}} expected-error {{expected valid context selector in when clause}} expected-error {{expected expression}}
11-
;
12-
#pragma omp metadirective when(device{arch(nvptx)}) // expected-error {{missing ':' in when clause}} expected-error {{expected expression}} expected-warning {{expected '=' after the context set name "device"; '=' assumed}}
13-
;
14-
#pragma omp metadirective when(device{arch(nvptx)}: ) default() // expected-warning {{expected '=' after the context set name "device"; '=' assumed}}
15-
;
16-
#pragma omp metadirective when(device = {arch(nvptx)} : ) default(xyz) // expected-error {{expected an OpenMP directive}} expected-error {{use of undeclared identifier 'xyz'}}
17-
;
18-
#pragma omp metadirective when(device = {arch(nvptx)} : parallel default() // expected-error {{expected ',' or ')' in 'when' clause}} expected-error {{expected expression}}
19-
;
20-
#pragma omp metadirective when(device = {isa("some-unsupported-feature")} : parallel) default(single) // expected-warning {{isa trait 'some-unsupported-feature' is not known to the current target; verify the spelling or consider restricting the context selector with the 'arch' selector further}}
21-
;
8+
#if _OPENMP >= 202111
9+
#pragma omp metadirective // omp52-error {{expected expression}}
10+
;
11+
#pragma omp metadirective when() // omp52-error {{expected valid context selector in when clause}} expected-error {{expected expression}} expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
12+
;
13+
#pragma omp metadirective when(device{}) // omp52-warning {{expected '=' after the context set name "device"; '=' assumed}} expected-warning {{expected identifier or string literal describing a context selector; selector skipped}} expected-note {{context selector options are: 'kind' 'arch' 'isa'}} expected-note {{the ignored selector spans until here}} expected-error {{expected valid context selector in when clause}} expected-error {{expected expression}}
14+
;
15+
#pragma omp metadirective when(device{arch(nvptx)}) // omp52-error {{missing ':' in when clause}} expected-error {{expected expression}} expected-warning {{expected '=' after the context set name "device"; '=' assumed}}
16+
;
17+
#pragma omp metadirective when(device{arch(nvptx)}: ) otherwise() // omp52-warning {{expected '=' after the context set name "device"; '=' assumed}}
18+
;
19+
#pragma omp metadirective when(device = {arch(nvptx)} : ) otherwise(xyz) // omp52-error {{expected an OpenMP directive}} expected-error {{use of undeclared identifier 'xyz'}}
20+
;
21+
#pragma omp metadirective when(device = {arch(nvptx)} : parallel otherwise() // omp52-error {{expected ',' or ')' in 'when' clause}} expected-error {{expected expression}}
22+
;
23+
#pragma omp metadirective when(device = {isa("some-unsupported-feature")} : parallel) otherwise(single) // omp52-warning {{isa trait 'some-unsupported-feature' is not known to the current target; verify the spelling or consider restricting the context selector with the 'arch' selector further}}
24+
;
25+
#pragma omp metadirective when(device = {arch(nvptx)} : parallel) default() // omp52-warning {{'default' clause for 'metadirective' is deprecated; use 'otherwise' instead}}
26+
;
27+
#pragma omp metadirective when(device = {arch(nvptx)} : parallel) xyz() //omp52-error {{unknown clause 'xyz' in metadirective}}
28+
;
29+
#else
30+
#pragma omp metadirective // expected-error {{expected expression}}
31+
;
32+
#pragma omp metadirective when() // expected-error {{expected valid context selector in when clause}} expected-error {{expected expression}} expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
33+
;
34+
#pragma omp metadirective when(device{}) // expected-warning {{expected '=' after the context set name "device"; '=' assumed}} expected-warning {{expected identifier or string literal describing a context selector; selector skipped}} expected-note {{context selector options are: 'kind' 'arch' 'isa'}} expected-note {{the ignored selector spans until here}} expected-error {{expected valid context selector in when clause}} expected-error {{expected expression}}
35+
;
36+
#pragma omp metadirective when(device{arch(nvptx)}) // expected-error {{missing ':' in when clause}} expected-error {{expected expression}} expected-warning {{expected '=' after the context set name "device"; '=' assumed}}
37+
;
38+
#pragma omp metadirective when(device{arch(nvptx)}: ) default() // expected-warning {{expected '=' after the context set name "device"; '=' assumed}}
39+
;
40+
#pragma omp metadirective when(device = {arch(nvptx)} : ) default(xyz) // expected-error {{expected an OpenMP directive}} expected-error {{use of undeclared identifier 'xyz'}}
41+
;
42+
#pragma omp metadirective when(device = {arch(nvptx)} : parallel default() // expected-error {{expected ',' or ')' in 'when' clause}} expected-error {{expected expression}}
43+
;
44+
#pragma omp metadirective when(device = {isa("some-unsupported-feature")} : parallel) default(single) // expected-warning {{isa trait 'some-unsupported-feature' is not known to the current target; verify the spelling or consider restricting the context selector with the 'arch' selector further}}
45+
;
46+
#pragma omp metadirective when(device = {arch(nvptx)} : parallel) xyz() //expected-error {{unknown clause 'xyz' in metadirective}}
47+
;
48+
#endif
2249
}

0 commit comments

Comments
 (0)