[OPENMP50]Multiple vendors in vendor context must be treated as logical
and of vendors, not or.

If several vendors are provided in the same vendor context trait, the
context shall match only if all vendors are matching, not one of them.
This is per OpenMP 5.0, 2.3.3 Matching and Scoring Context Selectors,
all selectors in the construct, device, and implementation sets of the
context selector appear in the corresponding trait set of the OpenMP
context.

llvm-svn: 374107
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index e9cf692..d2f18a5 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -11172,7 +11172,8 @@
 bool checkContext<OMPDeclareVariantAttr::CtxSetImplementation,
                   OMPDeclareVariantAttr::CtxVendor>(
     const OMPDeclareVariantAttr *A) {
-  return !A->getImplVendor().compare("llvm");
+  return llvm::all_of(A->implVendors(),
+                      [](StringRef S) { return !S.compare_lower("llvm"); });
 }
 
 static bool greaterCtxScore(ASTContext &Ctx, const Expr *LHS, const Expr *RHS) {
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index f667b83..82a4e70 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -853,6 +853,7 @@
     (void)T.expectAndConsume(diag::err_expected_lparen_after,
                              CtxSelectorName.data());
     const ExprResult Score = parseContextScore(P);
+    SmallVector<llvm::SmallString<16>, 4> Vendors;
     do {
       // Parse <vendor>.
       StringRef VendorName;
@@ -860,18 +861,14 @@
         Buffer.clear();
         VendorName = P.getPreprocessor().getSpelling(P.getCurToken(), Buffer);
         (void)P.ConsumeToken();
+        if (!VendorName.empty())
+          Vendors.push_back(VendorName);
       } else {
         P.Diag(Tok.getLocation(), diag::err_omp_declare_variant_item_expected)
             << "vendor identifier"
             << "vendor"
             << "implementation";
       }
-      if (!VendorName.empty()) {
-        Sema::OpenMPDeclareVariantCtsSelectorData Data(
-            OMPDeclareVariantAttr::CtxSetImplementation, CSKind, VendorName,
-            Score);
-        Callback(SourceRange(Loc, Tok.getLocation()), Data);
-      }
       if (!P.TryConsumeToken(tok::comma) && Tok.isNot(tok::r_paren)) {
         P.Diag(Tok, diag::err_expected_punc)
             << (VendorName.empty() ? "vendor name" : VendorName);
@@ -879,6 +876,15 @@
     } while (Tok.is(tok::identifier));
     // Parse ')'.
     (void)T.consumeClose();
+    if (!Vendors.empty()) {
+      SmallVector<StringRef, 4> ImplVendors(Vendors.size());
+      for (int I = 0, E = Vendors.size(); I < E; ++I)
+        ImplVendors[I] = Vendors[I];
+      Sema::OpenMPDeclareVariantCtsSelectorData Data(
+          OMPDeclareVariantAttr::CtxSetImplementation, CSKind, ImplVendors,
+          Score);
+      Callback(SourceRange(Loc, Tok.getLocation()), Data);
+    }
     break;
   }
   case OMPDeclareVariantAttr::CtxUnknown:
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index ff7e1c0..5ceee81 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -5136,8 +5136,8 @@
     }
   }
   auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
-      Context, VariantRef, Score, Data.CtxSet, ST, Data.Ctx, Data.ImplVendor,
-      SR);
+      Context, VariantRef, Score, Data.CtxSet, ST, Data.Ctx,
+      Data.ImplVendors.begin(), Data.ImplVendors.size(), SR);
   FD->addAttr(NewAttr);
 }
 
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 881b4fd..818548c 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -399,9 +399,11 @@
   if (!DeclVarData)
     return;
   // Instantiate the attribute.
-  Sema::OpenMPDeclareVariantCtsSelectorData Data(Attr.getCtxSelectorSet(),
-                                                 Attr.getCtxSelector(),
-                                                 Attr.getImplVendor(), Score);
+  Sema::OpenMPDeclareVariantCtsSelectorData Data(
+      Attr.getCtxSelectorSet(), Attr.getCtxSelector(),
+      llvm::makeMutableArrayRef(Attr.implVendors_begin(),
+                                Attr.implVendors_size()),
+      Score);
   S.ActOnOpenMPDeclareVariantDirective(DeclVarData.getValue().first,
                                        DeclVarData.getValue().second,
                                        Attr.getRange(), Data);