diff options
-rw-r--r-- | clang/include/clang/Basic/DiagnosticParseKinds.td | 4 | ||||
-rw-r--r-- | clang/lib/Parse/ParseOpenMP.cpp | 11 | ||||
-rw-r--r-- | clang/test/OpenMP/declare_variant_ast_print.c | 3 | ||||
-rw-r--r-- | clang/test/OpenMP/declare_variant_ast_print.cpp | 30 | ||||
-rw-r--r-- | clang/test/OpenMP/declare_variant_messages.c | 2 | ||||
-rw-r--r-- | clang/test/OpenMP/declare_variant_messages.cpp | 4 |
6 files changed, 29 insertions, 25 deletions
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index ac1c52504df..c0b488d3057 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1211,6 +1211,10 @@ def warn_omp_declare_variant_cs_name_expected : Warning< InGroup<OpenMPClauses>; def err_omp_declare_variant_item_expected : Error< "expected %0 in '%1' context selector of '%2' selector set of 'omp declare variant' directive">; +def err_omp_declare_variant_ctx_set_mutiple_use : Error< + "context selector set '%0' is used already in the same 'omp declare variant' directive">; +def note_omp_declare_variant_ctx_set_used_here : Note< + "previously context selector set '%0' used here">; def warn_omp_more_one_device_type_clause : Warning< "more than one 'device_type' clause is specified">, InGroup<OpenMPClauses>; diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 998fae657a4..e487e0ab652 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -892,6 +892,7 @@ bool Parser::parseOpenMPContextSelectors( llvm::function_ref<void(SourceRange, const Sema::OpenMPDeclareVariantCtsSelectorData &)> Callback) { + llvm::StringMap<SourceLocation> UsedCtxSets; do { // Parse inner context selector set name. if (!Tok.is(tok::identifier)) { @@ -901,6 +902,16 @@ bool Parser::parseOpenMPContextSelectors( } SmallString<16> Buffer; StringRef CtxSelectorSetName = PP.getSpelling(Tok, Buffer); + auto Res = UsedCtxSets.try_emplace(CtxSelectorSetName, Tok.getLocation()); + if (!Res.second) { + // OpenMP 5.0, 2.3.2 Context Selectors, Restrictions. + // Each trait-set-selector-name can only be specified once. + Diag(Tok.getLocation(), diag::err_omp_declare_variant_ctx_set_mutiple_use) + << CtxSelectorSetName; + Diag(Res.first->getValue(), + diag::note_omp_declare_variant_ctx_set_used_here) + << CtxSelectorSetName; + } // Parse '='. (void)ConsumeToken(); if (Tok.isNot(tok::equal)) { diff --git a/clang/test/OpenMP/declare_variant_ast_print.c b/clang/test/OpenMP/declare_variant_ast_print.c index 07e55a9070a..0174c07aebe 100644 --- a/clang/test/OpenMP/declare_variant_ast_print.c +++ b/clang/test/OpenMP/declare_variant_ast_print.c @@ -8,7 +8,7 @@ int foo(void); #pragma omp declare variant(foo) match(xxx={}, yyy={ccc}) #pragma omp declare variant(foo) match(xxx={vvv}) -#pragma omp declare variant(foo) match(implementation={vendor(ibm)}, implementation={vendor(llvm)}) +#pragma omp declare variant(foo) match(implementation={vendor(llvm)}) #pragma omp declare variant(foo) match(implementation={vendor(unknown)}) #pragma omp declare variant(foo) match(implementation={vendor(score(5): ibm, xxx)}) int bar(void); @@ -17,6 +17,5 @@ int bar(void); // CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(score(5):ibm)}) // CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(score(5):xxx)}) // CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(unknown)}) -// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(ibm)}) // CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(llvm)}) // CHECK-NEXT: int bar(); diff --git a/clang/test/OpenMP/declare_variant_ast_print.cpp b/clang/test/OpenMP/declare_variant_ast_print.cpp index 984aafac762..879014b6132 100644 --- a/clang/test/OpenMP/declare_variant_ast_print.cpp +++ b/clang/test/OpenMP/declare_variant_ast_print.cpp @@ -19,12 +19,11 @@ T foofoo() { return T(); } // CHECK: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(score(5):ibm)}) // CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(unknown)}) -// CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(ibm)}) // CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(llvm)}) // CHECK-NEXT: int bar(); #pragma omp declare variant(foofoo <int>) match(xxx = {}) #pragma omp declare variant(foofoo <int>) match(xxx = {vvv}) -#pragma omp declare variant(foofoo <int>) match(implementation={vendor(ibm)}, implementation={vendor(llvm)}) +#pragma omp declare variant(foofoo <int>) match(implementation={vendor(llvm)}) #pragma omp declare variant(foofoo <int>) match(implementation={vendor(unknown)}) #pragma omp declare variant(foofoo <int>) match(implementation={vendor(score(5): ibm)}) int bar(); @@ -32,16 +31,15 @@ int bar(); // CHECK: #pragma omp declare variant(foofoo<T>) match(implementation={vendor(score(C + 5):ibm)}) // CHECK: #pragma omp declare variant(foofoo<T>) match(implementation={vendor(score(C + 5):xxx)}) // CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(implementation={vendor(unknown)}) -// CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(implementation={vendor(ibm)}) // CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(implementation={vendor(llvm)}) // CHECK-NEXT: template <typename T, int C> T barbar(); #pragma omp declare variant(foofoo <T>) match(xxx = {}) #pragma omp declare variant(foofoo <T>) match(xxx = {vvv}) #pragma omp declare variant(foofoo <T>) match(user = {score(<expr>) : condition(<expr>)}) -#pragma omp declare variant(foofoo <T>) match(user = {score(<expr>) : condition(<expr>)}, user = {condition(<expr>)}) +#pragma omp declare variant(foofoo <T>) match(user = {score(<expr>) : condition(<expr>)}) #pragma omp declare variant(foofoo <T>) match(user = {condition(<expr>)}) #pragma omp declare variant(foofoo <T>) match(user = {condition(<expr>)}) -#pragma omp declare variant(foofoo <T>) match(implementation={vendor(ibm)}, implementation={vendor(llvm)}) +#pragma omp declare variant(foofoo <T>) match(implementation={vendor(llvm)}) #pragma omp declare variant(foofoo <T>) match(implementation={vendor(unknown)}) #pragma omp declare variant(foofoo <T>) match(implementation={vendor(score(C+5): ibm, xxx)}) template <typename T, int C> @@ -50,7 +48,6 @@ T barbar(); // CHECK: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(score(3 + 5):ibm)}) // CHECK: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(score(3 + 5):xxx)}) // CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(unknown)}) -// CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(ibm)}) // CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(llvm)}) // CHECK-NEXT: template<> int barbar<int, 3>(); @@ -72,19 +69,17 @@ void h_ref(C *hp, C *hp2, C *hq, C *lin) { } // CHECK: #pragma omp declare variant(h_ref<C>) match(implementation={vendor(unknown)}) -// CHECK-NEXT: #pragma omp declare variant(h_ref<C>) match(implementation={vendor(ibm)}) // CHECK-NEXT: #pragma omp declare variant(h_ref<C>) match(implementation={vendor(llvm)}) // CHECK-NEXT: template <class C> void h(C *hp, C *hp2, C *hq, C *lin) { // CHECK-NEXT: } #pragma omp declare variant(h_ref <C>) match(xxx = {}) -#pragma omp declare variant(h_ref <C>) match(implementation={vendor(ibm)}, implementation={vendor(llvm)}) +#pragma omp declare variant(h_ref <C>) match(implementation={vendor(llvm)}) #pragma omp declare variant(h_ref <C>) match(implementation={vendor(unknown)}) template <class C> void h(C *hp, C *hp2, C *hq, C *lin) { } // CHECK: #pragma omp declare variant(h_ref<float>) match(implementation={vendor(unknown)}) -// CHECK-NEXT: #pragma omp declare variant(h_ref<float>) match(implementation={vendor(ibm)}) // CHECK-NEXT: #pragma omp declare variant(h_ref<float>) match(implementation={vendor(llvm)}) // CHECK-NEXT: template<> void h<float>(float *hp, float *hp2, float *hq, float *lin) { // CHECK-NEXT: } @@ -93,7 +88,7 @@ void h(C *hp, C *hp2, C *hq, C *lin) { // CHECK-NEXT: h((float *)hp, (float *)hp2, (float *)hq, (float *)lin); // CHECK-NEXT: } #pragma omp declare variant(h_ref <double>) match(xxx = {}) -#pragma omp declare variant(h_ref <double>) match(implementation={vendor(ibm)}, implementation={vendor(llvm)}) +#pragma omp declare variant(h_ref <double>) match(implementation={vendor(ibm)}) #pragma omp declare variant(h_ref <double>) match(implementation={vendor(unknown)}) template <> void h(double *hp, double *hp2, double *hq, double *lin) { @@ -105,11 +100,10 @@ int fn(); // CHECK: int fn(int); int fn(int); // CHECK: #pragma omp declare variant(fn) match(implementation={vendor(unknown)}) -// CHECK-NEXT: #pragma omp declare variant(fn) match(implementation={vendor(ibm)}) // CHECK-NEXT: #pragma omp declare variant(fn) match(implementation={vendor(llvm)}) // CHECK-NEXT: int overload(); #pragma omp declare variant(fn) match(xxx = {}) -#pragma omp declare variant(fn) match(implementation={vendor(ibm)}, implementation={vendor(llvm)}) +#pragma omp declare variant(fn) match(implementation={vendor(llvm)}) #pragma omp declare variant(fn) match(implementation={vendor(unknown)}) int overload(void); @@ -118,11 +112,10 @@ int overload(void); // CHECK-NEXT: } auto fn_deduced_variant() { return 0; } // CHECK: #pragma omp declare variant(fn_deduced_variant) match(implementation={vendor(unknown)}) -// CHECK-NEXT: #pragma omp declare variant(fn_deduced_variant) match(implementation={vendor(ibm)}) // CHECK-NEXT: #pragma omp declare variant(fn_deduced_variant) match(implementation={vendor(llvm)}) // CHECK-NEXT: int fn_deduced(); #pragma omp declare variant(fn_deduced_variant) match(xxx = {}) -#pragma omp declare variant(fn_deduced_variant) match(implementation={vendor(ibm)}, implementation={vendor(llvm)}) +#pragma omp declare variant(fn_deduced_variant) match(implementation={vendor(llvm)}) #pragma omp declare variant(fn_deduced_variant) match(implementation={vendor(unknown)}) int fn_deduced(); @@ -130,12 +123,11 @@ int fn_deduced(); int fn_deduced_variant1(); // CHECK: #pragma omp declare variant(fn_deduced_variant1) match(implementation={vendor(unknown)}) // CHECK-NEXT: #pragma omp declare variant(fn_deduced_variant1) match(implementation={vendor(ibm)}) -// CHECK-NEXT: #pragma omp declare variant(fn_deduced_variant1) match(implementation={vendor(llvm)}) // CHECK-NEXT: int fn_deduced1() { // CHECK-NEXT: return 0; // CHECK-NEXT: } #pragma omp declare variant(fn_deduced_variant1) match(xxx = {}) -#pragma omp declare variant(fn_deduced_variant1) match(implementation={vendor(ibm)}, implementation={vendor(llvm)}) +#pragma omp declare variant(fn_deduced_variant1) match(implementation={vendor(ibm)}) #pragma omp declare variant(fn_deduced_variant1) match(implementation={vendor(unknown)}) auto fn_deduced1() { return 0; } @@ -152,7 +144,6 @@ auto fn_deduced1() { return 0; } // CHECK-NEXT: } // CHECK-NEXT: #pragma omp declare variant(SpecialFuncs::baz) match(implementation={vendor(unknown)}) // CHECK-NEXT: #pragma omp declare variant(SpecialFuncs::bar) match(implementation={vendor(ibm)}) -// CHECK-NEXT: #pragma omp declare variant(SpecialFuncs::bar) match(implementation={vendor(llvm)}) // CHECK-NEXT: void foo1() { // CHECK-NEXT: } // CHECK-NEXT: #pragma omp declare variant(SpecialFuncs::baz) match(implementation={vendor(unknown)}) @@ -168,7 +159,7 @@ struct SpecialFuncs { void bar(int) {} #pragma omp declare variant(SpecialFuncs::baz) match(xxx = {}) #pragma omp declare variant(SpecialFuncs::bar) match(xxx = {}) -#pragma omp declare variant(SpecialFuncs::bar) match(implementation={vendor(ibm)}, implementation={vendor(llvm)}) +#pragma omp declare variant(SpecialFuncs::bar) match(implementation={vendor(ibm)}) #pragma omp declare variant(SpecialFuncs::baz) match(implementation={vendor(unknown)}) void foo1() {} #pragma omp declare variant(SpecialFuncs::baz) match(implementation={vendor(unknown)}) @@ -184,12 +175,11 @@ void SpecialFuncs::xxx() {} // CHECK-NEXT: } static void static_f_variant() {} // CHECK: #pragma omp declare variant(static_f_variant) match(implementation={vendor(unknown)}) -// CHECK-NEXT: #pragma omp declare variant(static_f_variant) match(implementation={vendor(ibm)}) // CHECK-NEXT: #pragma omp declare variant(static_f_variant) match(implementation={vendor(llvm)}) // CHECK-NEXT: static void static_f() { // CHECK-NEXT: } #pragma omp declare variant(static_f_variant) match(xxx = {}) -#pragma omp declare variant(static_f_variant) match(implementation={vendor(ibm)}, implementation={vendor(llvm)}) +#pragma omp declare variant(static_f_variant) match(implementation={vendor(llvm)}) #pragma omp declare variant(static_f_variant) match(implementation={vendor(unknown)}) static void static_f() {} diff --git a/clang/test/OpenMP/declare_variant_messages.c b/clang/test/OpenMP/declare_variant_messages.c index e8fed318f69..c6737f5cb11 100644 --- a/clang/test/OpenMP/declare_variant_messages.c +++ b/clang/test/OpenMP/declare_variant_messages.c @@ -24,7 +24,7 @@ int foo(void); #pragma omp declare variant(foo) match(xxx={) // expected-error {{expected '}'}} expected-note {{to match this '{'}} #pragma omp declare variant(foo) match(xxx={}) #pragma omp declare variant(foo) match(xxx={vvv}) -#pragma omp declare variant(foo) match(xxx={vvv} xxx) // expected-error {{expected ','}} expected-error {{expected '=' after 'xxx' context selector set name on 'omp declare variant' directive}} +#pragma omp declare variant(foo) match(xxx={vvv} xxx) // expected-error {{expected ','}} expected-error {{expected '=' after 'xxx' context selector set name on 'omp declare variant' directive}} expected-error {{context selector set 'xxx' is used already in the same 'omp declare variant' directive}} expected-note {{previously context selector set 'xxx' used here}} #pragma omp declare variant(foo) match(xxx={vvv}) xxx // expected-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}} #pragma omp declare variant(foo) match(implementation={xxx}) // expected-warning {{unknown context selector in 'implementation' context selector set of 'omp declare variant' directive, ignored}} #pragma omp declare variant(foo) match(implementation={vendor}) // expected-error {{expected '(' after 'vendor'}} expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} expected-error {{expected ')' or ',' after 'vendor name'}} expected-error {{expected ')'}} expected-note {{to match this '('}} diff --git a/clang/test/OpenMP/declare_variant_messages.cpp b/clang/test/OpenMP/declare_variant_messages.cpp index f80c93c312d..e986cd6b80c 100644 --- a/clang/test/OpenMP/declare_variant_messages.cpp +++ b/clang/test/OpenMP/declare_variant_messages.cpp @@ -27,7 +27,7 @@ T foofoo(); // expected-note 2 {{declared here}} #pragma omp declare variant(foofoo <int>) match(xxx = {) // expected-error {{expected '}'}} expected-note {{to match this '{'}} #pragma omp declare variant(foofoo <int>) match(xxx = {}) #pragma omp declare variant(foofoo <int>) match(xxx = {vvv}) -#pragma omp declare variant(foofoo <int>) match(xxx = {vvv} xxx) // expected-error {{expected ','}} expected-error {{expected '=' after 'xxx' context selector set name on 'omp declare variant' directive}} +#pragma omp declare variant(foofoo <int>) match(xxx = {vvv} xxx) // expected-error {{expected ','}} expected-error {{expected '=' after 'xxx' context selector set name on 'omp declare variant' directive}} expected-error {{context selector set 'xxx' is used already in the same 'omp declare variant' directive}} expected-note {{previously context selector set 'xxx' used here}} #pragma omp declare variant(foofoo <int>) match(xxx = {vvv}) xxx // expected-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}} #pragma omp declare variant(foofoo <int>) match(implementation={xxx}) // expected-warning {{unknown context selector in 'implementation' context selector set of 'omp declare variant' directive, ignored}} #pragma omp declare variant(foofoo <int>) match(implementation={vendor}) // expected-error {{expected '(' after 'vendor'}} expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} expected-error {{expected ')' or ',' after 'vendor name'}} expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -60,7 +60,7 @@ int bar(); #pragma omp declare variant(foofoo <T>) match(user = {score(<expr>) : condition(<expr>)}) #pragma omp declare variant(foofoo <T>) match(user = {condition(<expr>)}) #pragma omp declare variant(foofoo <T>) match(user = {condition(<expr>)}) -#pragma omp declare variant(foofoo <T>) match(xxx = {vvv} xxx) // expected-error {{expected ','}} expected-error {{expected '=' after 'xxx' context selector set name on 'omp declare variant' directive}} +#pragma omp declare variant(foofoo <T>) match(xxx = {vvv} xxx) // expected-error {{expected ','}} expected-error {{expected '=' after 'xxx' context selector set name on 'omp declare variant' directive}} expected-error {{context selector set 'xxx' is used already in the same 'omp declare variant' directive}} expected-note {{previously context selector set 'xxx' used here}} #pragma omp declare variant(foofoo <T>) match(xxx = {vvv}) xxx // expected-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}} #pragma omp declare variant(foofoo <int>) match(implementation={vendor(score ibm)}) // expected-error {{expected '(' after 'score'}} expected-warning {{missing ':' after context selector score clause - ignoring}} #pragma omp declare variant(foofoo <int>) match(implementation={vendor(score( ibm)}) // expected-error {{expected ')' or ',' after 'vendor name'}} expected-error {{expected ')'}} expected-error {{use of undeclared identifier 'ibm'}} expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} expected-warning {{missing ':' after context selector score clause - ignoring}} expected-note {{to match this '('}} |