Author: abataev Date: Wed Oct 2 11:19:02 2019 New Revision: 373502 URL: http://llvm.org/viewvc/llvm-project?rev=373502&view=rev Log: [OPENMP50]Add parsing/sema analysis for declare variant score.
Context selectors may include optional score clause in format `score(<expr>):`, where `<expr>` must be a constant integer expression. Added parsing/sema analysis only. Modified: cfe/trunk/include/clang/Basic/Attr.td cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Parse/ParseOpenMP.cpp cfe/trunk/lib/Sema/SemaOpenMP.cpp cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp cfe/trunk/test/OpenMP/declare_variant_ast_print.c cfe/trunk/test/OpenMP/declare_variant_ast_print.cpp cfe/trunk/test/OpenMP/declare_variant_messages.c cfe/trunk/test/OpenMP/declare_variant_messages.cpp Modified: cfe/trunk/include/clang/Basic/Attr.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=373502&r1=373501&r2=373502&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/Attr.td (original) +++ cfe/trunk/include/clang/Basic/Attr.td Wed Oct 2 11:19:02 2019 @@ -3290,12 +3290,19 @@ def OMPDeclareVariant : InheritableAttr let Documentation = [OMPDeclareVariantDocs]; let Args = [ ExprArgument<"VariantFuncRef">, + ExprArgument<"Score">, EnumArgument<"CtxSelectorSet", "CtxSelectorSetType", [ "", "implementation" ], [ "CtxSetUnknown", "CtxSetImplementation" ]>, + EnumArgument<"CtxScore", "ScoreType", + [ "", "score" + ], + [ + "ScoreUnknown", "ScoreSpecified" + ]>, EnumArgument<"CtxSelector", "CtxSelectorType", [ "", "vendor" ], @@ -3305,6 +3312,13 @@ def OMPDeclareVariant : InheritableAttr StringArgument<"ImplVendor", 1> ]; let AdditionalMembers = [{ + void printScore(raw_ostream & OS, const PrintingPolicy &Policy) const { + if (const Expr *E = getScore()) { + OS << "score("; + E->printPretty(OS, nullptr, Policy); + OS << "):"; + } + } void printPrettyPragma(raw_ostream & OS, const PrintingPolicy &Policy) const { assert(getCtxSelectorSet() != CtxSetUnknown && @@ -3322,6 +3336,7 @@ def OMPDeclareVariant : InheritableAttr switch (getCtxSelector()) { case CtxVendor: OS << "vendor("; + printScore(OS, Policy); OS << getImplVendor(); OS << ")"; break; Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=373502&r1=373501&r2=373502&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Wed Oct 2 11:19:02 2019 @@ -9109,11 +9109,14 @@ public: OMPDeclareVariantAttr::CtxSelectorType Ctx = OMPDeclareVariantAttr::CtxUnknown; StringRef ImplVendor; + ExprResult CtxScore; explicit OpenMPDeclareVariantCtsSelectorData() = default; explicit OpenMPDeclareVariantCtsSelectorData( OMPDeclareVariantAttr::CtxSelectorSetType CtxSet, - OMPDeclareVariantAttr::CtxSelectorType Ctx, StringRef ImplVendor) - : CtxSet(CtxSet), Ctx(Ctx), ImplVendor(ImplVendor) {} + OMPDeclareVariantAttr::CtxSelectorType Ctx, StringRef ImplVendor, + ExprResult CtxScore) + : CtxSet(CtxSet), Ctx(Ctx), ImplVendor(ImplVendor), CtxScore(CtxScore) { + } }; /// Checks if the variant/multiversion functions are compatible. Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=373502&r1=373501&r2=373502&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original) +++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Wed Oct 2 11:19:02 2019 @@ -786,6 +786,31 @@ Parser::ParseOMPDeclareSimdClauses(Parse LinModifiers, Steps, SourceRange(Loc, EndLoc)); } +/// Parse optional 'score' '(' <expr> ')' ':'. +static ExprResult parseContextScore(Parser &P) { + ExprResult ScoreExpr; + SmallString<16> Buffer; + StringRef SelectorName = + P.getPreprocessor().getSpelling(P.getCurToken(), Buffer); + OMPDeclareVariantAttr::ScoreType ScoreKind = + OMPDeclareVariantAttr::ScoreUnknown; + (void)OMPDeclareVariantAttr::ConvertStrToScoreType(SelectorName, ScoreKind); + if (ScoreKind == OMPDeclareVariantAttr::ScoreUnknown) + return ScoreExpr; + assert(ScoreKind == OMPDeclareVariantAttr::ScoreSpecified && + "Expected \"score\" clause."); + (void)P.ConsumeToken(); + SourceLocation RLoc; + ScoreExpr = P.ParseOpenMPParensExpr(SelectorName, RLoc); + // Parse ':' + if (P.getCurToken().is(tok::colon)) + (void)P.ConsumeAnyToken(); + else + P.Diag(P.getCurToken(), diag::warn_pragma_expected_colon) + << "context selector score clause"; + return ScoreExpr; +} + /// Parse context selector for 'implementation' selector set: /// 'vendor' '(' <vendor> ')' static void @@ -815,6 +840,7 @@ parseImplementationSelector(Parser &P, BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openmp_end); (void)T.expectAndConsume(diag::err_expected_lparen_after, CtxSelectorName.data()); + Data.CtxScore = parseContextScore(P); // Parse <vendor>. StringRef VendorName; if (Tok.is(tok::identifier)) { Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=373502&r1=373501&r2=373502&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original) +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Wed Oct 2 11:19:02 2019 @@ -5112,8 +5112,23 @@ void Sema::ActOnOpenMPDeclareVariantDire if (Data.CtxSet == OMPDeclareVariantAttr::CtxSetUnknown || Data.Ctx == OMPDeclareVariantAttr::CtxUnknown) return; + Expr *Score = nullptr; + OMPDeclareVariantAttr::ScoreType ST = OMPDeclareVariantAttr::ScoreUnknown; + if (Data.CtxScore.isUsable()) { + ST = OMPDeclareVariantAttr::ScoreSpecified; + Score = Data.CtxScore.get(); + if (!Score->isTypeDependent() && !Score->isValueDependent() && + !Score->isInstantiationDependent() && + !Score->containsUnexpandedParameterPack()) { + llvm::APSInt Result; + ExprResult ICE = VerifyIntegerConstantExpression(Score, &Result); + if (ICE.isInvalid()) + return; + } + } auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( - Context, VariantRef, Data.CtxSet, Data.Ctx, Data.ImplVendor, SR); + Context, VariantRef, Score, Data.CtxSet, ST, Data.Ctx, Data.ImplVendor, + SR); FD->addAttr(NewAttr); } Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=373502&r1=373501&r2=373502&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Oct 2 11:19:02 2019 @@ -388,6 +388,10 @@ static void instantiateOMPDeclareVariant if (Expr *E = Attr.getVariantFuncRef()) VariantFuncRef = Subst(E); + ExprResult Score; + if (Expr *E = Attr.getScore()) + Score = Subst(E); + // Check function/variant ref. Optional<std::pair<FunctionDecl *, Expr *>> DeclVarData = S.checkOpenMPDeclareVariantFunction( @@ -395,8 +399,9 @@ static void instantiateOMPDeclareVariant if (!DeclVarData) return; // Instantiate the attribute. - Sema::OpenMPDeclareVariantCtsSelectorData Data( - Attr.getCtxSelectorSet(), Attr.getCtxSelector(), Attr.getImplVendor()); + Sema::OpenMPDeclareVariantCtsSelectorData Data(Attr.getCtxSelectorSet(), + Attr.getCtxSelector(), + Attr.getImplVendor(), Score); S.ActOnOpenMPDeclareVariantDirective(DeclVarData.getValue().first, DeclVarData.getValue().second, Attr.getRange(), Data); Modified: cfe/trunk/test/OpenMP/declare_variant_ast_print.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/declare_variant_ast_print.c?rev=373502&r1=373501&r2=373502&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/declare_variant_ast_print.c (original) +++ cfe/trunk/test/OpenMP/declare_variant_ast_print.c Wed Oct 2 11:19:02 2019 @@ -10,9 +10,11 @@ int foo(void); #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)}) +#pragma omp declare variant(foo) match(implementation={vendor(score(5): ibm)}) int bar(void); // CHECK: int foo(); +// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(score(5):ibm)}) // 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)}) Modified: cfe/trunk/test/OpenMP/declare_variant_ast_print.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/declare_variant_ast_print.cpp?rev=373502&r1=373501&r2=373502&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/declare_variant_ast_print.cpp (original) +++ cfe/trunk/test/OpenMP/declare_variant_ast_print.cpp Wed Oct 2 11:19:02 2019 @@ -17,7 +17,8 @@ T foofoo() { return T(); } // CHECK-NEXT: return int(); // CHECK-NEXT: } -// CHECK: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(unknown)}) +// 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(); @@ -25,12 +26,14 @@ T foofoo() { return T(); } #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(unknown)}) +#pragma omp declare variant(foofoo <int>) match(implementation={vendor(score(5): ibm)}) int bar(); -// CHECK: #pragma omp declare variant(foofoo<T>) match(implementation={vendor(unknown)}) +// CHECK: #pragma omp declare variant(foofoo<T>) match(implementation={vendor(score(C + 5):ibm)}) +// 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> T barbar(); +// 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>)}) @@ -39,19 +42,21 @@ int bar(); #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(unknown)}) -template <typename T> +#pragma omp declare variant(foofoo <T>) match(implementation={vendor(score(C+5): ibm)}) +template <typename T, int C> T barbar(); -// CHECK: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(unknown)}) +// CHECK: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(score(3 + 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: template<> int barbar<int>(); +// CHECK-NEXT: template<> int barbar<int, 3>(); // CHECK-NEXT: int baz() { -// CHECK-NEXT: return barbar<int>(); +// CHECK-NEXT: return barbar<int, 3>(); // CHECK-NEXT: } int baz() { - return barbar<int>(); + return barbar<int, 3>(); } // CHECK: template <class C> void h_ref(C *hp, C *hp2, C *hq, C *lin) { Modified: cfe/trunk/test/OpenMP/declare_variant_messages.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/declare_variant_messages.c?rev=373502&r1=373501&r2=373502&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/declare_variant_messages.c (original) +++ cfe/trunk/test/OpenMP/declare_variant_messages.c Wed Oct 2 11:19:02 2019 @@ -30,6 +30,11 @@ int foo(void); #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}} +#pragma omp declare variant(foo) match(implementation={vendor(score ibm)}) // expected-error {{expected '(' after 'score'}} expected-warning {{missing ':' after context selector score clause - ignoring}} +#pragma omp declare variant(foo) match(implementation={vendor(score( ibm)}) // 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 '('}} +#pragma omp declare variant(foo) match(implementation={vendor(score(2 ibm)}) // expected-error 2 {{expected ')'}} 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 2 {{to match this '('}} +#pragma omp declare variant(foo) match(implementation={vendor(score(foo()) ibm)}) // expected-warning {{missing ':' after context selector score clause - ignoring}} expected-error {{expression is not an integer constant expression}} +#pragma omp declare variant(foo) match(implementation={vendor(score(5): ibm)}) int bar(void); // expected-error@+2 {{'#pragma omp declare variant' can only be applied to functions}} Modified: cfe/trunk/test/OpenMP/declare_variant_messages.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/declare_variant_messages.cpp?rev=373502&r1=373501&r2=373502&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/declare_variant_messages.cpp (original) +++ cfe/trunk/test/OpenMP/declare_variant_messages.cpp Wed Oct 2 11:19:02 2019 @@ -8,7 +8,7 @@ int foo(); template <typename T> -T foofoo(); +T foofoo(); // expected-note 2 {{declared here}} #pragma omp declare variant // expected-error {{expected '(' after 'declare variant'}} #pragma omp declare variant( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -33,6 +33,11 @@ T foofoo(); #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 ')'}} expected-note {{to match this '('}} #pragma omp declare variant(foofoo <int>) 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 <int>) match(implementation={vendor()}) // expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} +#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 ')'}} 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 '('}} +#pragma omp declare variant(foofoo <int>) match(implementation={vendor(score(2 ibm)}) // expected-error 2 {{expected ')'}} 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 2 {{to match this '('}} +#pragma omp declare variant(foofoo <int>) match(implementation={vendor(score(foofoo <int>()) ibm)}) // expected-warning {{missing ':' after context selector score clause - ignoring}} expected-error {{expression is not an integral constant expression}} expected-note {{non-constexpr function 'foofoo<int>' cannot be used in a constant expression}} +#pragma omp declare variant(foofoo <int>) match(implementation={vendor(score(5): ibm)}) int bar(); #pragma omp declare variant // expected-error {{expected '(' after 'declare variant'}} @@ -57,7 +62,12 @@ int bar(); #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-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}} -template <typename T> +#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 ')'}} 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 '('}} +#pragma omp declare variant(foofoo <int>) match(implementation={vendor(score(C ibm)}) // expected-error 2 {{expected ')'}} 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 2 {{to match this '('}} +#pragma omp declare variant(foofoo <int>) match(implementation={vendor(score(foofoo <int>()) ibm)}) // expected-warning {{missing ':' after context selector score clause - ignoring}} expected-error {{expression is not an integral constant expression}} expected-note {{non-constexpr function 'foofoo<int>' cannot be used in a constant expression}} +#pragma omp declare variant(foofoo <int>) match(implementation={vendor(score(C+5): ibm)}) +template <typename T, int C> T barbar(); // expected-error@+2 {{'#pragma omp declare variant' can only be applied to functions}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits