From 305058753c6d01bf18a1860d2e86a3946f1cc3bf Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Wed, 25 Sep 2019 19:43:37 +0000 Subject: [PATCH] [OPENMP50]Parsing/sema support for 'implementation/vendor' context selector. Added basic parsing/semantic support for 'implementation={vendor()}' context selector. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@372917 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/Attr.td | 37 ++++++- include/clang/Basic/DiagnosticParseKinds.td | 5 + include/clang/Basic/OpenMPKinds.def | 8 ++ include/clang/Parse/Parser.h | 8 +- include/clang/Sema/Sema.h | 28 ++++-- lib/Parse/ParseOpenMP.cpp | 101 +++++++++++++++++--- lib/Sema/SemaOpenMP.cpp | 13 ++- lib/Sema/SemaTemplateInstantiateDecl.cpp | 4 +- test/OpenMP/declare_variant_ast_print.c | 8 +- test/OpenMP/declare_variant_ast_print.cpp | 72 +++++++++----- test/OpenMP/declare_variant_messages.c | 6 +- test/OpenMP/declare_variant_messages.cpp | 4 + 12 files changed, 237 insertions(+), 57 deletions(-) diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index bca51f2f7d..6c71011ff2 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -3288,18 +3288,51 @@ def OMPDeclareVariant : Attr { let HasCustomParsing = 1; let Documentation = [OMPDeclareVariantDocs]; let Args = [ - ExprArgument<"VariantFuncRef"> + ExprArgument<"VariantFuncRef">, + EnumArgument<"CtxSelectorSet", "CtxSelectorSetType", + [ "", "implementation" + ], + [ + "CtxSetUnknown", "CtxSetImplementation" + ]>, + EnumArgument<"CtxSelector", "CtxSelectorType", + [ "", "vendor" + ], + [ + "CtxUnknown", "CtxVendor" + ]>, + StringArgument<"ImplVendor", 1> ]; let AdditionalMembers = [{ void printPrettyPragma(raw_ostream & OS, const PrintingPolicy &Policy) const { + assert(getCtxSelectorSet() != CtxSetUnknown && + getCtxSelector() != CtxUnknown && "Unknown context selector."); if (const Expr *E = getVariantFuncRef()) { OS << "("; E->printPretty(OS, nullptr, Policy); OS << ")"; } // TODO: add printing of real context selectors. - OS << " match(unknown={})"; + OS << " match("; + switch (getCtxSelectorSet()) { + case CtxSetImplementation: + OS << "implementation={"; + switch (getCtxSelector()) { + case CtxVendor: + OS << "vendor("; + OS << getImplVendor(); + OS << ")"; + break; + case CtxUnknown: + llvm_unreachable("Unknown context selector."); + } + OS << "}"; + break; + case CtxSetUnknown: + llvm_unreachable("Unknown context selector set."); + } + OS << ")"; } }]; } diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 66c40c0e9e..ac1c52504d 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -1206,6 +1206,11 @@ def err_omp_declare_variant_no_ctx_selector : Error< "expected context selector in '%0' clause on 'omp declare variant' directive">; def err_omp_declare_variant_equal_expected : Error< "expected '=' after '%0' context selector set name on 'omp declare variant' directive">; +def warn_omp_declare_variant_cs_name_expected : Warning< + "unknown context selector in '%0' context selector set of 'omp declare variant' directive, ignored">, + InGroup; +def err_omp_declare_variant_item_expected : Error< + "expected %0 in '%1' context selector of '%2' selector set of 'omp declare variant' directive">; def warn_omp_more_one_device_type_clause : Warning< "more than one 'device_type' clause is specified">, InGroup; diff --git a/include/clang/Basic/OpenMPKinds.def b/include/clang/Basic/OpenMPKinds.def index 2cd5b29672..e8a40de3e3 100644 --- a/include/clang/Basic/OpenMPKinds.def +++ b/include/clang/Basic/OpenMPKinds.def @@ -197,6 +197,9 @@ #ifndef OPENMP_DECLARE_VARIANT_CLAUSE #define OPENMP_DECLARE_VARIANT_CLAUSE(Name) #endif +#ifndef OPENMP_MATCH_KIND +#define OPENMP_MATCH_KIND(Name) +#endif // OpenMP directives. OPENMP_DIRECTIVE(threadprivate) @@ -965,6 +968,11 @@ OPENMP_DEVICE_TYPE_KIND(any) // Clauses allowed for OpenMP directive 'declare variant'. OPENMP_DECLARE_VARIANT_CLAUSE(match) +// Context selectors for 'match' clause. +// TODO: add other context selectors. +OPENMP_MATCH_KIND(implementation) + +#undef OPENMP_MATCH_KIND #undef OPENMP_DECLARE_VARIANT_CLAUSE #undef OPENMP_DEVICE_TYPE_KIND #undef OPENMP_ALLOCATE_CLAUSE diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index d80ece998d..920921f693 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -2836,9 +2836,11 @@ private: SourceLocation Loc); /// Parses OpenMP context selectors and calls \p Callback for each /// successfully parsed context selector. - bool - parseOpenMPContextSelectors(SourceLocation Loc, - llvm::function_ref Callback); + bool parseOpenMPContextSelectors( + SourceLocation Loc, + llvm::function_ref< + void(SourceRange, const Sema::OpenMPDeclareVariantCtsSelectorData &)> + Callback); /// Parse clauses for '#pragma omp declare variant'. void ParseOMPDeclareVariantClauses(DeclGroupPtrTy Ptr, CachedTokens &Toks, diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index da103ba75a..1c587cf5c1 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -9102,6 +9102,20 @@ private: bool MightBeOdrUse); public: + /// Struct to store the context selectors info for declare variant directive. + struct OpenMPDeclareVariantCtsSelectorData { + OMPDeclareVariantAttr::CtxSelectorSetType CtxSet = + OMPDeclareVariantAttr::CtxSetUnknown; + OMPDeclareVariantAttr::CtxSelectorType Ctx = + OMPDeclareVariantAttr::CtxUnknown; + StringRef ImplVendor; + explicit OpenMPDeclareVariantCtsSelectorData() = default; + explicit OpenMPDeclareVariantCtsSelectorData( + OMPDeclareVariantAttr::CtxSelectorSetType CtxSet, + OMPDeclareVariantAttr::CtxSelectorType Ctx, StringRef ImplVendor) + : CtxSet(CtxSet), Ctx(Ctx), ImplVendor(ImplVendor) {} + }; + /// Checks if the variant/multiversion functions are compatible. bool areMultiversionVariantFunctionsCompatible( const FunctionDecl *OldFD, const FunctionDecl *NewFD, @@ -9542,10 +9556,9 @@ public: /// \param VariantRef Expression that references the variant function, which /// must be used instead of the original one, specified in \p DG. /// \returns None, if the function/variant function are not compatible with - /// the pragma,pair of original function/variant ref expression otherwise. - Optional> - checkOpenMPDeclareVariantFunction(DeclGroupPtrTy DG, Expr *VariantRef, - SourceRange SR); + /// the pragma, pair of original function/variant ref expression otherwise. + Optional> checkOpenMPDeclareVariantFunction( + DeclGroupPtrTy DG, Expr *VariantRef, SourceRange SR); /// Called on well-formed '\#pragma omp declare variant' after parsing of /// the associated method/function. @@ -9553,8 +9566,11 @@ public: /// applied to. /// \param VariantRef Expression that references the variant function, which /// must be used instead of the original one, specified in \p DG. - void ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, Expr *VariantRef, - SourceRange SR); + /// \param Data Set of context-specific data for the specified context + /// selector. + void ActOnOpenMPDeclareVariantDirective( + FunctionDecl *FD, Expr *VariantRef, SourceRange SR, + const Sema::OpenMPDeclareVariantCtsSelectorData &Data); OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp index 570f246d19..46c8238168 100644 --- a/lib/Parse/ParseOpenMP.cpp +++ b/lib/Parse/ParseOpenMP.cpp @@ -786,12 +786,72 @@ Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr, LinModifiers, Steps, SourceRange(Loc, EndLoc)); } +/// Parse context selector for 'implementation' selector set: +/// 'vendor' '(' ')' +static void +parseImplementationSelector(Parser &P, + Sema::OpenMPDeclareVariantCtsSelectorData &Data) { + const Token &Tok = P.getCurToken(); + // Parse inner context selector set name, if any. + if (!Tok.is(tok::identifier)) { + P.Diag(Tok.getLocation(), diag::warn_omp_declare_variant_cs_name_expected) + << "implementation"; + // Skip until either '}', ')', or end of directive. + while (!P.SkipUntil(tok::r_brace, tok::r_paren, + tok::annot_pragma_openmp_end, Parser::StopBeforeMatch)) + ; + return; + } + SmallString<16> Buffer; + StringRef CtxSelectorName = P.getPreprocessor().getSpelling(Tok, Buffer); + OMPDeclareVariantAttr::CtxSelectorType CSKind = + OMPDeclareVariantAttr::CtxUnknown; + (void)OMPDeclareVariantAttr::ConvertStrToCtxSelectorType(CtxSelectorName, + CSKind); + (void)P.ConsumeToken(); + switch (CSKind) { + case OMPDeclareVariantAttr::CtxVendor: { + // Parse '('. + BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openmp_end); + (void)T.expectAndConsume(diag::err_expected_lparen_after, + CtxSelectorName.data()); + // Parse . + StringRef VendorName; + if (Tok.is(tok::identifier)) { + VendorName = P.getPreprocessor().getSpelling(P.getCurToken(), Buffer); + (void)P.ConsumeToken(); + } else { + P.Diag(Tok.getLocation(), diag::err_omp_declare_variant_item_expected) + << "vendor identifier" << "vendor" << "implementation"; + } + // Parse ')'. + (void)T.consumeClose(); + if (!VendorName.empty()) + Data.ImplVendor = VendorName; + break; + } + case OMPDeclareVariantAttr::CtxUnknown: + P.Diag(Tok.getLocation(), diag::warn_omp_declare_variant_cs_name_expected) + << "implementation"; + // Skip until either '}', ')', or end of directive. + while (!P.SkipUntil(tok::r_brace, tok::r_paren, + tok::annot_pragma_openmp_end, Parser::StopBeforeMatch)) + ; + return; + } + Data.CtxSet = OMPDeclareVariantAttr::CtxSetImplementation; + Data.Ctx = CSKind; +} + /// Parses clauses for 'declare variant' directive. /// clause: /// '=' '{' '}' /// [ ',' '=' '{' '}' ] bool Parser::parseOpenMPContextSelectors( - SourceLocation Loc, llvm::function_ref Callback) { + SourceLocation Loc, + llvm::function_ref + Callback) { do { // Parse inner context selector set name. if (!Tok.is(tok::identifier)) { @@ -800,30 +860,43 @@ bool Parser::parseOpenMPContextSelectors( return true; } SmallString<16> Buffer; - StringRef CtxSelectorName = PP.getSpelling(Tok, Buffer); + StringRef CtxSelectorSetName = PP.getSpelling(Tok, Buffer); // Parse '='. (void)ConsumeToken(); if (Tok.isNot(tok::equal)) { Diag(Tok.getLocation(), diag::err_omp_declare_variant_equal_expected) - << CtxSelectorName; + << CtxSelectorSetName; return true; } (void)ConsumeToken(); // TBD: add parsing of known context selectors. // Unknown selector - just ignore it completely. + Sema::OpenMPDeclareVariantCtsSelectorData Data; { // Parse '{'. BalancedDelimiterTracker TBr(*this, tok::l_brace, tok::annot_pragma_openmp_end); if (TBr.expectAndConsume(diag::err_expected_lbrace_after, "=")) return true; - while (!SkipUntil(tok::r_brace, tok::r_paren, - tok::annot_pragma_openmp_end, StopBeforeMatch)) - ; + OMPDeclareVariantAttr::CtxSelectorSetType CSSKind = + OMPDeclareVariantAttr::CtxSetUnknown; + (void)OMPDeclareVariantAttr::ConvertStrToCtxSelectorSetType( + CtxSelectorSetName, CSSKind); + switch (CSSKind) { + case OMPDeclareVariantAttr::CtxSetImplementation: + parseImplementationSelector(*this, Data); + break; + case OMPDeclareVariantAttr::CtxSetUnknown: + // Skip until either '}', ')', or end of directive. + while (!SkipUntil(tok::r_brace, tok::r_paren, + tok::annot_pragma_openmp_end, StopBeforeMatch)) + ; + break; + } // Parse '}'. (void)TBr.consumeClose(); } - Callback(SourceRange(Loc, Tok.getLocation())); + Callback(SourceRange(Loc, Tok.getLocation()), Data); // Consume ',' if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) (void)ExpectAndConsume(tok::comma); @@ -888,11 +961,15 @@ void Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr, } // Parse inner context selectors. - if (!parseOpenMPContextSelectors(Loc, [this, &DeclVarData](SourceRange SR) { - if (DeclVarData.hasValue()) - Actions.ActOnOpenMPDeclareVariantDirective( - DeclVarData.getValue().first, DeclVarData.getValue().second, SR); - })) { + if (!parseOpenMPContextSelectors( + Loc, [this, &DeclVarData]( + SourceRange SR, + const Sema::OpenMPDeclareVariantCtsSelectorData &Data) { + if (DeclVarData.hasValue()) + Actions.ActOnOpenMPDeclareVariantDirective( + DeclVarData.getValue().first, DeclVarData.getValue().second, + SR, Data); + })) { // Parse ')'. (void)T.consumeClose(); // Need to check for extra tokens. diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 34ce66c4e3..0403f11f6b 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -5101,11 +5101,14 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, return std::make_pair(FD, cast(DRE)); } -void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, - Expr *VariantRef, - SourceRange SR) { - auto *NewAttr = - OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, SR); +void Sema::ActOnOpenMPDeclareVariantDirective( + FunctionDecl *FD, Expr *VariantRef, SourceRange SR, + const Sema::OpenMPDeclareVariantCtsSelectorData &Data) { + if (Data.CtxSet == OMPDeclareVariantAttr::CtxSetUnknown || + Data.Ctx == OMPDeclareVariantAttr::CtxUnknown) + return; + auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( + Context, VariantRef, Data.CtxSet, Data.Ctx, Data.ImplVendor, SR); FD->addAttr(NewAttr); } diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 684254bcd0..f6cf3696e1 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -395,9 +395,11 @@ static void instantiateOMPDeclareVariantAttr( if (!DeclVarData) return; // Instantiate the attribute. + Sema::OpenMPDeclareVariantCtsSelectorData Data( + Attr.getCtxSelectorSet(), Attr.getCtxSelector(), Attr.getImplVendor()); S.ActOnOpenMPDeclareVariantDirective(DeclVarData.getValue().first, DeclVarData.getValue().second, - Attr.getRange()); + Attr.getRange(), Data); } static void instantiateDependentAMDGPUFlatWorkGroupSizeAttr( diff --git a/test/OpenMP/declare_variant_ast_print.c b/test/OpenMP/declare_variant_ast_print.c index eb30095726..4c91e2e541 100644 --- a/test/OpenMP/declare_variant_ast_print.c +++ b/test/OpenMP/declare_variant_ast_print.c @@ -8,10 +8,12 @@ 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(unknown)}) int bar(void); // CHECK: int foo(); -// CHECK-NEXT: #pragma omp declare variant(foo) match(unknown={}) -// CHECK-NEXT: #pragma omp declare variant(foo) match(unknown={}) -// CHECK-NEXT: #pragma omp declare variant(foo) match(unknown={}) +// 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/test/OpenMP/declare_variant_ast_print.cpp b/test/OpenMP/declare_variant_ast_print.cpp index c22ca2b8a3..a8dba5611a 100644 --- a/test/OpenMP/declare_variant_ast_print.cpp +++ b/test/OpenMP/declare_variant_ast_print.cpp @@ -17,20 +17,19 @@ T foofoo() { return T(); } // CHECK-NEXT: return int(); // CHECK-NEXT: } -// CHECK: #pragma omp declare variant(foofoo) match(unknown={}) -// CHECK-NEXT: #pragma omp declare variant(foofoo) match(unknown={}) +// CHECK: #pragma omp declare variant(foofoo) match(implementation={vendor(unknown)}) +// CHECK-NEXT: #pragma omp declare variant(foofoo) match(implementation={vendor(ibm)}) +// CHECK-NEXT: #pragma omp declare variant(foofoo) match(implementation={vendor(llvm)}) // CHECK-NEXT: int bar(); #pragma omp declare variant(foofoo ) match(xxx = {}) #pragma omp declare variant(foofoo ) match(xxx = {vvv}) +#pragma omp declare variant(foofoo ) match(implementation={vendor(ibm)}, implementation={vendor(llvm)}) +#pragma omp declare variant(foofoo ) match(implementation={vendor(unknown)}) int bar(); -// CHECK: #pragma omp declare variant(foofoo) match(unknown={}) -// CHECK-NEXT: #pragma omp declare variant(foofoo) match(unknown={}) -// CHECK-NEXT: #pragma omp declare variant(foofoo) match(unknown={}) -// CHECK-NEXT: #pragma omp declare variant(foofoo) match(unknown={}) -// CHECK-NEXT: #pragma omp declare variant(foofoo) match(unknown={}) -// CHECK-NEXT: #pragma omp declare variant(foofoo) match(unknown={}) -// CHECK-NEXT: #pragma omp declare variant(foofoo) match(unknown={}) +// CHECK: #pragma omp declare variant(foofoo) match(implementation={vendor(unknown)}) +// CHECK-NEXT: #pragma omp declare variant(foofoo) match(implementation={vendor(ibm)}) +// CHECK-NEXT: #pragma omp declare variant(foofoo) match(implementation={vendor(llvm)}) // CHECK-NEXT: template T barbar(); #pragma omp declare variant(foofoo ) match(xxx = {}) #pragma omp declare variant(foofoo ) match(xxx = {vvv}) @@ -38,16 +37,14 @@ int bar(); #pragma omp declare variant(foofoo ) match(user = {score() : condition()}, user = {condition()}) #pragma omp declare variant(foofoo ) match(user = {condition()}) #pragma omp declare variant(foofoo ) match(user = {condition()}) +#pragma omp declare variant(foofoo ) match(implementation={vendor(ibm)}, implementation={vendor(llvm)}) +#pragma omp declare variant(foofoo ) match(implementation={vendor(unknown)}) template T barbar(); -// CHECK: #pragma omp declare variant(foofoo) match(unknown={}) -// CHECK-NEXT: #pragma omp declare variant(foofoo) match(unknown={}) -// CHECK-NEXT: #pragma omp declare variant(foofoo) match(unknown={}) -// CHECK-NEXT: #pragma omp declare variant(foofoo) match(unknown={}) -// CHECK-NEXT: #pragma omp declare variant(foofoo) match(unknown={}) -// CHECK-NEXT: #pragma omp declare variant(foofoo) match(unknown={}) -// CHECK-NEXT: #pragma omp declare variant(foofoo) match(unknown={}) +// CHECK: #pragma omp declare variant(foofoo) match(implementation={vendor(unknown)}) +// CHECK-NEXT: #pragma omp declare variant(foofoo) match(implementation={vendor(ibm)}) +// CHECK-NEXT: #pragma omp declare variant(foofoo) match(implementation={vendor(llvm)}) // CHECK-NEXT: template<> int barbar(); // CHECK-NEXT: int baz() { @@ -67,15 +64,21 @@ template void h_ref(C *hp, C *hp2, C *hq, C *lin) { } -// CHECK: #pragma omp declare variant(h_ref) match(unknown={}) +// CHECK: #pragma omp declare variant(h_ref) match(implementation={vendor(unknown)}) +// CHECK-NEXT: #pragma omp declare variant(h_ref) match(implementation={vendor(ibm)}) +// CHECK-NEXT: #pragma omp declare variant(h_ref) match(implementation={vendor(llvm)}) // CHECK-NEXT: template void h(C *hp, C *hp2, C *hq, C *lin) { // CHECK-NEXT: } #pragma omp declare variant(h_ref ) match(xxx = {}) +#pragma omp declare variant(h_ref ) match(implementation={vendor(ibm)}, implementation={vendor(llvm)}) +#pragma omp declare variant(h_ref ) match(implementation={vendor(unknown)}) template void h(C *hp, C *hp2, C *hq, C *lin) { } -// CHECK: #pragma omp declare variant(h_ref) match(unknown={}) +// CHECK: #pragma omp declare variant(h_ref) match(implementation={vendor(unknown)}) +// CHECK-NEXT: #pragma omp declare variant(h_ref) match(implementation={vendor(ibm)}) +// CHECK-NEXT: #pragma omp declare variant(h_ref) match(implementation={vendor(llvm)}) // CHECK-NEXT: template<> void h(float *hp, float *hp2, float *hq, float *lin) { // CHECK-NEXT: } @@ -83,6 +86,8 @@ 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 ) match(xxx = {}) +#pragma omp declare variant(h_ref ) match(implementation={vendor(ibm)}, implementation={vendor(llvm)}) +#pragma omp declare variant(h_ref ) match(implementation={vendor(unknown)}) template <> void h(double *hp, double *hp2, double *hq, double *lin) { h((float *)hp, (float *)hp2, (float *)hq, (float *)lin); @@ -92,27 +97,39 @@ void h(double *hp, double *hp2, double *hq, double *lin) { int fn(); // CHECK: int fn(int); int fn(int); -// CHECK: #pragma omp declare variant(fn) match(unknown={}) +// 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(unknown)}) int overload(void); // CHECK: int fn_deduced_variant() { // CHECK-NEXT: return 0; // CHECK-NEXT: } auto fn_deduced_variant() { return 0; } -// CHECK: #pragma omp declare variant(fn_deduced_variant) match(unknown={}) +// 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(unknown)}) int fn_deduced(); // CHECK: int fn_deduced_variant1(); int fn_deduced_variant1(); -// CHECK: #pragma omp declare variant(fn_deduced_variant1) match(unknown={}) +// 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(unknown)}) auto fn_deduced1() { return 0; } // CHECK: struct SpecialFuncs { @@ -126,8 +143,9 @@ auto fn_deduced1() { return 0; } // CHECK-NEXT: } // CHECK-NEXT: void bar(int) { // CHECK-NEXT: } -// CHECK-NEXT: #pragma omp declare variant(SpecialFuncs::bar) match(unknown={}) -// CHECK-NEXT: #pragma omp declare variant(SpecialFuncs::baz) match(unknown={}) +// 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: } s; @@ -141,16 +159,22 @@ 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::baz) match(implementation={vendor(unknown)}) void foo1() {} } s; // CHECK: static void static_f_variant() { // CHECK-NEXT: } static void static_f_variant() {} -// CHECK: #pragma omp declare variant(static_f_variant) match(unknown={}) +// 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(unknown)}) static void static_f() {} // CHECK: void bazzzz() { diff --git a/test/OpenMP/declare_variant_messages.c b/test/OpenMP/declare_variant_messages.c index 13d5e6c1ed..4a1357c3fd 100644 --- a/test/OpenMP/declare_variant_messages.c +++ b/test/OpenMP/declare_variant_messages.c @@ -26,6 +26,10 @@ int foo(void); #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-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 ')'}} expected-note {{to match this '('}} +#pragma omp declare variant(foo) match(implementation={vendor(}) // expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp declare variant(foo) match(implementation={vendor()}) // expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} int bar(void); // expected-error@+2 {{'#pragma omp declare variant' can only be applied to functions}} @@ -89,7 +93,7 @@ void diff_ret(void); void marked(void); void not_marked(void); // expected-note@+1 {{marked as 'declare variant' here}} -#pragma omp declare variant(not_marked) match(xxx={}) +#pragma omp declare variant(not_marked) match(implementation={vendor(unknown)}) void marked_variant(void); // expected-warning@+1 {{variant function in '#pragma omp declare variant' is itself marked as '#pragma omp declare variant'}} #pragma omp declare variant(marked_variant) match(xxx={}) diff --git a/test/OpenMP/declare_variant_messages.cpp b/test/OpenMP/declare_variant_messages.cpp index 89ec84356d..bd01270b07 100644 --- a/test/OpenMP/declare_variant_messages.cpp +++ b/test/OpenMP/declare_variant_messages.cpp @@ -29,6 +29,10 @@ T foofoo(); #pragma omp declare variant(foofoo ) match(xxx = {vvv}) #pragma omp declare variant(foofoo ) 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 ) match(xxx = {vvv}) xxx // expected-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}} +#pragma omp declare variant(foofoo ) match(implementation={xxx}) // expected-warning {{unknown context selector in 'implementation' context selector set of 'omp declare variant' directive, ignored}} +#pragma omp declare variant(foofoo ) 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 ')'}} expected-note {{to match this '('}} +#pragma omp declare variant(foofoo ) match(implementation={vendor(}) // expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp declare variant(foofoo ) match(implementation={vendor()}) // expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} int bar(); #pragma omp declare variant // expected-error {{expected '(' after 'declare variant'}} -- 2.40.0