]> granicus.if.org Git - clang/commitdiff
[OPENMP5.0]Allow multiple context selectors in the context selector
authorAlexey Bataev <a.bataev@hotmail.com>
Wed, 18 Sep 2019 16:24:31 +0000 (16:24 +0000)
committerAlexey Bataev <a.bataev@hotmail.com>
Wed, 18 Sep 2019 16:24:31 +0000 (16:24 +0000)
sets.

According to OpenMP 5.0, context selector set might include several
context selectors, separated with commas. Patch fixes this problem.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@372235 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Parse/Parser.h
include/clang/Sema/Sema.h
lib/Parse/ParseOpenMP.cpp
lib/Sema/SemaOpenMP.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
test/OpenMP/declare_variant_ast_print.c
test/OpenMP/declare_variant_ast_print.cpp
test/OpenMP/declare_variant_messages.c
test/OpenMP/declare_variant_messages.cpp

index 5c0a831db6d24f3c590456ff728f00bc5938bb05..d80ece998ded3921fff08b998362c720a2f4fcae 100644 (file)
@@ -2834,10 +2834,15 @@ private:
   DeclGroupPtrTy ParseOMPDeclareSimdClauses(DeclGroupPtrTy Ptr,
                                             CachedTokens &Toks,
                                             SourceLocation Loc);
+  /// Parses OpenMP context selectors and calls \p Callback for each
+  /// successfully parsed context selector.
+  bool
+  parseOpenMPContextSelectors(SourceLocation Loc,
+                              llvm::function_ref<void(SourceRange)> Callback);
+
   /// Parse clauses for '#pragma omp declare variant'.
-  DeclGroupPtrTy ParseOMPDeclareVariantClauses(DeclGroupPtrTy Ptr,
-                                               CachedTokens &Toks,
-                                               SourceLocation Loc);
+  void ParseOMPDeclareVariantClauses(DeclGroupPtrTy Ptr, CachedTokens &Toks,
+                                     SourceLocation Loc);
   /// Parse clauses for '#pragma omp declare target'.
   DeclGroupPtrTy ParseOMPDeclareTargetClauses();
   /// Parse '#pragma omp end declare target'.
index c7f15f38dfc40fd1b21ee44aec55c31afa7effa4..7faea280b7310dfedde7d41cde2fc7c475697b43 100644 (file)
@@ -9529,15 +9529,26 @@ public:
       ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
       ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR);
 
+  /// Checks '\#pragma omp declare variant' variant function and original
+  /// functions after parsing of the associated method/function.
+  /// \param DG Function declaration to which declare variant directive is
+  /// applied to.
+  /// \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<std::pair<FunctionDecl *, Expr *>>
+  checkOpenMPDeclareVariantFunction(DeclGroupPtrTy DG, Expr *VariantRef,
+                                    SourceRange SR);
+
   /// Called on well-formed '\#pragma omp declare variant' after parsing of
   /// the associated method/function.
-  /// \param DG Function declaration to which declare variant directive is
+  /// \param FD Function declaration to which declare variant directive is
   /// applied to.
   /// \param VariantRef Expression that references the variant function, which
   /// must be used instead of the original one, specified in \p DG.
-  DeclGroupPtrTy ActOnOpenMPDeclareVariantDirective(DeclGroupPtrTy DG,
-                                                    Expr *VariantRef,
-                                                    SourceRange SR);
+  void ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, Expr *VariantRef,
+                                          SourceRange SR);
 
   OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
                                          Expr *Expr,
index 293660ec4cd8c20d179cf8c86a66a470047e6625..8d852b5dcb5b8498610bdab368c318f9e247c8ad 100644 (file)
@@ -788,65 +788,53 @@ Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
 
 /// Parses clauses for 'declare variant' directive.
 /// clause:
-/// 'match' '('
 /// <selector_set_name> '=' '{' <context_selectors> '}'
-/// ')'
-static bool parseDeclareVariantClause(Parser &P) {
-  Token Tok = P.getCurToken();
-  // Parse 'match'.
-  if (!Tok.is(tok::identifier) ||
-      P.getPreprocessor().getSpelling(Tok).compare("match")) {
-    P.Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
-        << "match";
-    while (!P.SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch))
-      ;
-    return true;
-  }
-  (void)P.ConsumeToken();
-  // Parse '('.
-  BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openmp_end);
-  if (T.expectAndConsume(diag::err_expected_lparen_after, "match"))
-    return true;
-  // Parse inner context selector.
-  Tok = P.getCurToken();
-  if (!Tok.is(tok::identifier)) {
-    P.Diag(Tok.getLocation(), diag::err_omp_declare_variant_no_ctx_selector)
-        << "match";
-    return true;
-  }
-  SmallString<16> Buffer;
-  StringRef CtxSelectorName = P.getPreprocessor().getSpelling(Tok, Buffer);
-  // Parse '='.
-  (void)P.ConsumeToken();
-  Tok = P.getCurToken();
-  if (Tok.isNot(tok::equal)) {
-    P.Diag(Tok.getLocation(), diag::err_omp_declare_variant_equal_expected)
-        << CtxSelectorName;
-    return true;
-  }
-  (void)P.ConsumeToken();
-  // Unknown selector - just ignore it completely.
-  {
-    // Parse '{'.
-    BalancedDelimiterTracker TBr(P, tok::l_brace, tok::annot_pragma_openmp_end);
-    if (TBr.expectAndConsume(diag::err_expected_lbrace_after, "="))
+/// [ ',' <selector_set_name> '=' '{' <context_selectors> '}' ]
+bool Parser::parseOpenMPContextSelectors(
+    SourceLocation Loc, llvm::function_ref<void(SourceRange)> Callback) {
+  do {
+    // Parse inner context selector set name.
+    if (!Tok.is(tok::identifier)) {
+      Diag(Tok.getLocation(), diag::err_omp_declare_variant_no_ctx_selector)
+          << "match";
       return true;
-    while (!P.SkipUntil(tok::r_brace, tok::r_paren,
-                        tok::annot_pragma_openmp_end, Parser::StopBeforeMatch))
-      ;
-    // Parse '}'.
-    (void)TBr.consumeClose();
-  }
-  // Parse ')'.
-  (void)T.consumeClose();
-  // TBD: add parsing of known context selectors.
+    }
+    SmallString<16> Buffer;
+    StringRef CtxSelectorName = PP.getSpelling(Tok, Buffer);
+    // Parse '='.
+    (void)ConsumeToken();
+    if (Tok.isNot(tok::equal)) {
+      Diag(Tok.getLocation(), diag::err_omp_declare_variant_equal_expected)
+          << CtxSelectorName;
+      return true;
+    }
+    (void)ConsumeToken();
+    // TBD: add parsing of known context selectors.
+    // Unknown selector - just ignore it completely.
+    {
+      // 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))
+        ;
+      // Parse '}'.
+      (void)TBr.consumeClose();
+    }
+    Callback(SourceRange(Loc, Tok.getLocation()));
+    // Consume ','
+    if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end))
+      (void)ExpectAndConsume(tok::comma);
+  } while (Tok.isAnyIdentifier());
   return false;
 }
 
 /// Parse clauses for '#pragma omp declare variant ( variant-func-id ) clause'.
-Parser::DeclGroupPtrTy
-Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,
-                                      CachedTokens &Toks, SourceLocation Loc) {
+void Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,
+                                           CachedTokens &Toks,
+                                           SourceLocation Loc) {
   PP.EnterToken(Tok, /*IsReinject*/ true);
   PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
                       /*IsReinject*/ true);
@@ -868,23 +856,53 @@ Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,
         ;
     // Skip the last annot_pragma_openmp_end.
     (void)ConsumeAnnotationToken();
-    return Ptr;
+    return;
   }
+  Optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
+      Actions.checkOpenMPDeclareVariantFunction(
+          Ptr, AssociatedFunction.get(), SourceRange(Loc, Tok.getLocation()));
 
-  bool IsError = parseDeclareVariantClause(*this);
-  // Need to check for extra tokens.
-  if (Tok.isNot(tok::annot_pragma_openmp_end)) {
-    Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
-        << getOpenMPDirectiveName(OMPD_declare_variant);
-    while (Tok.isNot(tok::annot_pragma_openmp_end))
-      ConsumeAnyToken();
+  // Parse 'match'.
+  if (!Tok.is(tok::identifier) || PP.getSpelling(Tok).compare("match")) {
+    Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
+        << "match";
+    while (!SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch))
+      ;
+    // Skip the last annot_pragma_openmp_end.
+    (void)ConsumeAnnotationToken();
+    return;
+  }
+  (void)ConsumeToken();
+  // Parse '('.
+  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
+  if (T.expectAndConsume(diag::err_expected_lparen_after, "match")) {
+    while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch))
+      ;
+    // Skip the last annot_pragma_openmp_end.
+    (void)ConsumeAnnotationToken();
+    return;
+  }
+
+  // Parse inner context selectors.
+  if (!parseOpenMPContextSelectors(Loc, [this, &DeclVarData](SourceRange SR) {
+        if (DeclVarData.hasValue())
+          Actions.ActOnOpenMPDeclareVariantDirective(
+              DeclVarData.getValue().first, DeclVarData.getValue().second, SR);
+      })) {
+    // Parse ')'.
+    (void)T.consumeClose();
+    // Need to check for extra tokens.
+    if (Tok.isNot(tok::annot_pragma_openmp_end)) {
+      Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
+          << getOpenMPDirectiveName(OMPD_declare_variant);
+    }
   }
+
+  // Skip last tokens.
+  while (Tok.isNot(tok::annot_pragma_openmp_end))
+    ConsumeAnyToken();
   // Skip the last annot_pragma_openmp_end.
-  SourceLocation EndLoc = ConsumeAnnotationToken();
-  if (IsError)
-    return Ptr;
-  return Actions.ActOnOpenMPDeclareVariantDirective(
-      Ptr, AssociatedFunction.get(), SourceRange(Loc, EndLoc));
+  (void)ConsumeAnnotationToken();
 }
 
 /// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
@@ -1248,7 +1266,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
       return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
     assert(DKind == OMPD_declare_variant &&
            "Expected declare variant directive only");
-    return ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
+    ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
+    return Ptr;
   }
   case OMPD_declare_target: {
     SourceLocation DTLoc = ConsumeAnyToken();
index cd343bd13d846c6d02445c1e9256d1319478e0fc..6f788fbb86dff1e5066931bb88e79708672ea189 100644 (file)
@@ -4892,18 +4892,18 @@ Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
   return DG;
 }
 
-Sema::DeclGroupPtrTy
-Sema::ActOnOpenMPDeclareVariantDirective(Sema::DeclGroupPtrTy DG,
-                                         Expr *VariantRef, SourceRange SR) {
+Optional<std::pair<FunctionDecl *, Expr *>>
+Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
+                                        Expr *VariantRef, SourceRange SR) {
   if (!DG || DG.get().isNull())
-    return DeclGroupPtrTy();
+    return None;
 
   const int VariantId = 1;
   // Must be applied only to single decl.
   if (!DG.get().isSingleDecl()) {
     Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
         << VariantId << SR;
-    return DG;
+    return None;
   }
   Decl *ADecl = DG.get().getSingleDecl();
   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
@@ -4914,7 +4914,7 @@ Sema::ActOnOpenMPDeclareVariantDirective(Sema::DeclGroupPtrTy DG,
   if (!FD) {
     Diag(ADecl->getLocation(), diag::err_omp_function_expected)
         << VariantId << SR;
-    return DeclGroupPtrTy();
+    return None;
   }
 
   auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
@@ -4926,31 +4926,27 @@ Sema::ActOnOpenMPDeclareVariantDirective(Sema::DeclGroupPtrTy DG,
   if (HasMultiVersionAttributes(FD)) {
     Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
         << SR;
-    return DG;
+    return None;
   }
 
   // Allow #pragma omp declare variant only if the function is not used.
   if (FD->isUsed(false)) {
     Diag(SR.getBegin(), diag::err_omp_declare_variant_after_used)
         << FD->getLocation();
-    return DG;
+    return None;
   }
 
   // The VariantRef must point to function.
   if (!VariantRef) {
     Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
-    return DG;
+    return None;
   }
 
   // Do not check templates, wait until instantiation.
   if (VariantRef->isTypeDependent() || VariantRef->isValueDependent() ||
       VariantRef->containsUnexpandedParameterPack() ||
-      VariantRef->isInstantiationDependent() || FD->isDependentContext()) {
-    auto *NewAttr =
-        OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, SR);
-    FD->addAttr(NewAttr);
-    return DG;
-  }
+      VariantRef->isInstantiationDependent() || FD->isDependentContext())
+    return std::make_pair(FD, VariantRef);
 
   // Convert VariantRef expression to the type of the original function to
   // resolve possible conflicts.
@@ -4973,7 +4969,7 @@ Sema::ActOnOpenMPDeclareVariantDirective(Sema::DeclGroupPtrTy DG,
       if (!ER.isUsable()) {
         Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
             << VariantId << VariantRef->getSourceRange();
-        return DG;
+        return None;
       }
       VariantRef = ER.get();
     } else {
@@ -4990,12 +4986,12 @@ Sema::ActOnOpenMPDeclareVariantDirective(Sema::DeclGroupPtrTy DG,
       Diag(VariantRef->getExprLoc(),
            diag::err_omp_declare_variant_incompat_types)
           << VariantRef->getType() << FnPtrType << VariantRef->getSourceRange();
-      return DG;
+      return None;
     }
     VariantRefCast = PerformImplicitConversion(
         VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
     if (!VariantRefCast.isUsable())
-      return DG;
+      return None;
     // Drop previously built artificial addr_of unary op for member functions.
     if (Method && !Method->isStatic()) {
       Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
@@ -5012,7 +5008,7 @@ Sema::ActOnOpenMPDeclareVariantDirective(Sema::DeclGroupPtrTy DG,
       !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
         << VariantId << VariantRef->getSourceRange();
-    return DG;
+    return None;
   }
 
   // The VariantRef must point to function.
@@ -5020,13 +5016,13 @@ Sema::ActOnOpenMPDeclareVariantDirective(Sema::DeclGroupPtrTy DG,
   if (!DRE) {
     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
         << VariantId << VariantRef->getSourceRange();
-    return DG;
+    return None;
   }
   auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
   if (!NewFD) {
     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
         << VariantId << VariantRef->getSourceRange();
-    return DG;
+    return None;
   }
 
   // Check if variant function is not marked with declare variant directive.
@@ -5037,7 +5033,7 @@ Sema::ActOnOpenMPDeclareVariantDirective(Sema::DeclGroupPtrTy DG,
     SourceRange SR =
         NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
     Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
-    return DG;
+    return None;
   }
 
   enum DoesntSupport {
@@ -5053,38 +5049,38 @@ Sema::ActOnOpenMPDeclareVariantDirective(Sema::DeclGroupPtrTy DG,
     if (CXXFD->isVirtual()) {
       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
           << VirtFuncs;
-      return DG;
+      return None;
     }
 
     if (isa<CXXConstructorDecl>(FD)) {
       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
           << Constructors;
-      return DG;
+      return None;
     }
 
     if (isa<CXXDestructorDecl>(FD)) {
       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
           << Destructors;
-      return DG;
+      return None;
     }
   }
 
   if (FD->isDeleted()) {
     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
         << DeletedFuncs;
-    return DG;
+    return None;
   }
 
   if (FD->isDefaulted()) {
     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
         << DefaultedFuncs;
-    return DG;
+    return None;
   }
 
   if (FD->isConstexpr()) {
     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
         << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
-    return DG;
+    return None;
   }
 
   // Check general compatibility.
@@ -5100,11 +5096,16 @@ Sema::ActOnOpenMPDeclareVariantDirective(Sema::DeclGroupPtrTy DG,
                               PDiag(diag::err_omp_declare_variant_diff)
                                   << FD->getLocation()),
           /*TemplatesSupported=*/true, /*ConstexprSupported=*/false))
-    return DG;
+    return None;
+  return std::make_pair(FD, cast<Expr>(DRE));
+}
 
-  auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(Context, DRE, SR);
+void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD,
+                                              Expr *VariantRef,
+                                              SourceRange SR) {
+  auto *NewAttr =
+      OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, SR);
   FD->addAttr(NewAttr);
-  return DG;
 }
 
 void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc,
index 6585917925e2b3480f35d6b66a7adaa9220fffa6..5338242d2594a6d591c479469f247ea428fdcf46 100644 (file)
@@ -388,8 +388,16 @@ static void instantiateOMPDeclareVariantAttr(
   if (Expr *E = Attr.getVariantFuncRef())
     VariantFuncRef = Subst(E);
 
-  (void)S.ActOnOpenMPDeclareVariantDirective(
-      S.ConvertDeclToDeclGroup(New), VariantFuncRef.get(), Attr.getRange());
+  // Check function/variant ref.
+  Optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
+      S.checkOpenMPDeclareVariantFunction(
+          S.ConvertDeclToDeclGroup(New), VariantFuncRef.get(), Attr.getRange());
+  if (!DeclVarData)
+    return;
+  // Instantiate the attribute.
+  S.ActOnOpenMPDeclareVariantDirective(DeclVarData.getValue().first,
+                                       DeclVarData.getValue().second,
+                                       Attr.getRange());
 }
 
 static void instantiateDependentAMDGPUFlatWorkGroupSizeAttr(
index e1632bc80055464dece5764832e8df73f637a252..eb300957262ed9c9ab0825b8709868dd10c818e0 100644 (file)
@@ -6,11 +6,12 @@
 
 int foo(void);
 
-#pragma omp declare variant(foo) match(xxx={})
+#pragma omp declare variant(foo) match(xxx={}, yyy={ccc})
 #pragma omp declare variant(foo) match(xxx={vvv})
 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: int bar();
index b4b515d6b7e93be9fbc2dd7bfce2af2eef758df9..c22ca2b8a3a88ae414dac8e99e2069bb5df05188 100644 (file)
@@ -30,11 +30,12 @@ int bar();
 // CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(unknown={})
 // CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(unknown={})
 // CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(unknown={})
+// CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(unknown={})
 // CHECK-NEXT: template <typename T> 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>)})
+#pragma omp declare variant(foofoo <T>) match(user = {score(<expr>) : condition(<expr>)}, user = {condition(<expr>)})
 #pragma omp declare variant(foofoo <T>) match(user = {condition(<expr>)})
 #pragma omp declare variant(foofoo <T>) match(user = {condition(<expr>)})
 template <typename T>
@@ -46,6 +47,7 @@ T barbar();
 // CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(unknown={})
 // CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(unknown={})
 // CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(unknown={})
+// CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(unknown={})
 // CHECK-NEXT: template<> int barbar<int>();
 
 // CHECK-NEXT: int baz() {
index 93023fdd1f40feee1865b10ca8d7ee077d31a041..13d5e6c1ed72cd0261cb1ffab42c7f63d799f746 100644 (file)
@@ -16,15 +16,15 @@ int foo(void);
 #pragma omp declare variant(foo) xxx // expected-error {{expected 'match' clause on 'omp declare variant' directive}}
 #pragma omp declare variant(foo) match // expected-error {{expected '(' after 'match'}}
 #pragma omp declare variant(foo) match( // expected-error {{expected context selector in 'match' clause on 'omp declare variant' directive}}
-#pragma omp declare variant(foo) match() // expected-error {{expected context selector in 'match' clause on 'omp declare variant' directive}} expected-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}}
-#pragma omp declare variant(foo) match(xxx) // expected-error {{expected '=' after 'xxx' context selector set name on 'omp declare variant' directive}} expected-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}}}
-#pragma omp declare variant(foo) match(xxx=) // expected-error {{expected '{' after '='}} expected-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}}
-#pragma omp declare variant(foo) match(xxx=yyy) // expected-error {{expected '{' after '='}} expected-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}}
-#pragma omp declare variant(foo) match(xxx=yyy}) // expected-error {{expected '{' after '='}} expected-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}}
+#pragma omp declare variant(foo) match() // expected-error {{expected context selector in 'match' clause on 'omp declare variant' directive}}
+#pragma omp declare variant(foo) match(xxx) // expected-error {{expected '=' after 'xxx' context selector set name on 'omp declare variant' directive}}
+#pragma omp declare variant(foo) match(xxx=) // expected-error {{expected '{' after '='}}
+#pragma omp declare variant(foo) match(xxx=yyy) // expected-error {{expected '{' after '='}}
+#pragma omp declare variant(foo) match(xxx=yyy}) // expected-error {{expected '{' after '='}}
 #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-note {{to match this '('}}
+#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}}
 int bar(void);
 
index 42427ea1845b84eeccdcecb5887ede09cfced2f4..89ec84356dc2d49f6209d2cdbfe5c5f6a9eb3e66 100644 (file)
@@ -19,15 +19,15 @@ T foofoo();
 #pragma omp declare variant(foofoo <int>) xxx                // expected-error {{expected 'match' clause on 'omp declare variant' directive}}
 #pragma omp declare variant(foofoo <int>) match              // expected-error {{expected '(' after 'match'}}
 #pragma omp declare variant(foofoo <int>) match(             // expected-error {{expected context selector in 'match' clause on 'omp declare variant' directive}}
-#pragma omp declare variant(foofoo <int>) match()            // expected-error {{expected context selector in 'match' clause on 'omp declare variant' directive}} expected-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}}
-#pragma omp declare variant(foofoo <int>) match(xxx)         // expected-error {{expected '=' after 'xxx' context selector set name on 'omp declare variant' directive}} expected-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}}}
-#pragma omp declare variant(foofoo <int>) match(xxx =)       // expected-error {{expected '{' after '='}} expected-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}}
-#pragma omp declare variant(foofoo <int>) match(xxx = yyy)   // expected-error {{expected '{' after '='}} expected-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}}
-#pragma omp declare variant(foofoo <int>) match(xxx = yyy }) // expected-error {{expected '{' after '='}} expected-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}}
+#pragma omp declare variant(foofoo <int>) match()            // expected-error {{expected context selector in 'match' clause on 'omp declare variant' directive}}
+#pragma omp declare variant(foofoo <int>) match(xxx)         // expected-error {{expected '=' after 'xxx' context selector set name on 'omp declare variant' directive}}
+#pragma omp declare variant(foofoo <int>) match(xxx =)       // expected-error {{expected '{' after '='}}
+#pragma omp declare variant(foofoo <int>) match(xxx = yyy)   // expected-error {{expected '{' after '='}}
+#pragma omp declare variant(foofoo <int>) match(xxx = yyy }) // expected-error {{expected '{' after '='}}
 #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-note {{to match this '('}}
+#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-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}}
 int bar();
 
@@ -41,9 +41,9 @@ int bar();
 #pragma omp declare variant(foofoo <T>) xxx            // expected-error {{expected 'match' clause on 'omp declare variant' directive}}
 #pragma omp declare variant(foofoo <T>) match          // expected-error {{expected '(' after 'match'}}
 #pragma omp declare variant(foofoo <T>) match(         // expected-error {{expected context selector in 'match' clause on 'omp declare variant' directive}}
-#pragma omp declare variant(foofoo <T>) match()        // expected-error {{expected context selector in 'match' clause on 'omp declare variant' directive}} expected-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}}
-#pragma omp declare variant(foofoo <T>) match(xxx)     // expected-error {{expected '=' after 'xxx' context selector set name on 'omp declare variant' directive}} expected-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}}}
-#pragma omp declare variant(foofoo <T>) match(xxx =)   // expected-error {{expected '{' after '='}} expected-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}}
+#pragma omp declare variant(foofoo <T>) match()        // expected-error {{expected context selector in 'match' clause on 'omp declare variant' directive}}
+#pragma omp declare variant(foofoo <T>) match(xxx)     // expected-error {{expected '=' after 'xxx' context selector set name on 'omp declare variant' directive}}
+#pragma omp declare variant(foofoo <T>) match(xxx =)   // expected-error {{expected '{' after '='}}
 #pragma omp declare variant(foofoo <T>) match(xxx = {) // expected-error {{expected '}'}} expected-note {{to match this '{'}}
 #pragma omp declare variant(foofoo <T>) match(xxx = {})
 #pragma omp declare variant(foofoo <T>) match(xxx = {vvv})
@@ -51,7 +51,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-note {{to match this '('}}
+#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>
 T barbar();