[OPENMP50]Generalize handling of context matching/scoring.

Summary:
Untie context matching/scoring from the attribute for declare variant
directive to simplify future uses in other context-dependent directives.

Reviewers: jdoerfert

Subscribers: guansong, kkwli0, caomhin, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D69952
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index e59b83d..8430e72 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -797,7 +797,7 @@
 /// Parse optional 'score' '(' <expr> ')' ':'.
 static ExprResult parseContextScore(Parser &P) {
   ExprResult ScoreExpr;
-  SmallString<16> Buffer;
+  Sema::OMPCtxStringType Buffer;
   StringRef SelectorName =
       P.getPreprocessor().getSpelling(P.getCurToken(), Buffer);
   if (!SelectorName.equals("score"))
@@ -817,11 +817,10 @@
 /// Parse context selector for 'implementation' selector set:
 /// 'vendor' '(' [ 'score' '(' <score _expr> ')' ':' ] <vendor> { ',' <vendor> }
 /// ')'
-static void parseImplementationSelector(
-    Parser &P, SourceLocation Loc, llvm::StringMap<SourceLocation> &UsedCtx,
-    llvm::function_ref<void(SourceRange,
-                            const Sema::OpenMPDeclareVariantCtsSelectorData &)>
-        Callback) {
+static void
+parseImplementationSelector(Parser &P, SourceLocation Loc,
+                            llvm::StringMap<SourceLocation> &UsedCtx,
+                            SmallVectorImpl<Sema::OMPCtxSelectorData> &Data) {
   const Token &Tok = P.getCurToken();
   // Parse inner context selector set name, if any.
   if (!Tok.is(tok::identifier)) {
@@ -833,7 +832,7 @@
       ;
     return;
   }
-  SmallString<16> Buffer;
+  Sema::OMPCtxStringType Buffer;
   StringRef CtxSelectorName = P.getPreprocessor().getSpelling(Tok, Buffer);
   auto Res = UsedCtx.try_emplace(CtxSelectorName, Tok.getLocation());
   if (!Res.second) {
@@ -844,19 +843,16 @@
     P.Diag(Res.first->getValue(), diag::note_omp_declare_variant_ctx_used_here)
         << CtxSelectorName;
   }
-  OMPDeclareVariantAttr::CtxSelectorType CSKind =
-      OMPDeclareVariantAttr::CtxUnknown;
-  (void)OMPDeclareVariantAttr::ConvertStrToCtxSelectorType(CtxSelectorName,
-                                                           CSKind);
+  OpenMPContextSelectorKind CSKind = getOpenMPContextSelector(CtxSelectorName);
   (void)P.ConsumeToken();
   switch (CSKind) {
-  case OMPDeclareVariantAttr::CtxVendor: {
+  case OMP_CTX_vendor: {
     // Parse '('.
     BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openmp_end);
     (void)T.expectAndConsume(diag::err_expected_lparen_after,
                              CtxSelectorName.data());
-    const ExprResult Score = parseContextScore(P);
-    llvm::UniqueVector<llvm::SmallString<16>> Vendors;
+    ExprResult Score = parseContextScore(P);
+    llvm::UniqueVector<Sema::OMPCtxStringType> Vendors;
     do {
       // Parse <vendor>.
       StringRef VendorName;
@@ -879,18 +875,11 @@
     } while (Tok.is(tok::identifier));
     // Parse ')'.
     (void)T.consumeClose();
-    if (!Vendors.empty()) {
-      SmallVector<StringRef, 4> ImplVendors(Vendors.size());
-      llvm::copy(Vendors, ImplVendors.begin());
-      Sema::OpenMPDeclareVariantCtsSelectorData Data(
-          OMPDeclareVariantAttr::CtxSetImplementation, CSKind,
-          llvm::makeMutableArrayRef(ImplVendors.begin(), ImplVendors.size()),
-          Score);
-      Callback(SourceRange(Loc, Tok.getLocation()), Data);
-    }
+    if (!Vendors.empty())
+      Data.emplace_back(OMP_CTX_SET_implementation, CSKind, Score, Vendors);
     break;
   }
-  case OMPDeclareVariantAttr::CtxUnknown:
+  case OMP_CTX_unknown:
     P.Diag(Tok.getLocation(), diag::warn_omp_declare_variant_cs_name_expected)
         << "implementation";
     // Skip until either '}', ')', or end of directive.
@@ -906,10 +895,7 @@
 /// <selector_set_name> '=' '{' <context_selectors> '}'
 /// [ ',' <selector_set_name> '=' '{' <context_selectors> '}' ]
 bool Parser::parseOpenMPContextSelectors(
-    SourceLocation Loc,
-    llvm::function_ref<void(SourceRange,
-                            const Sema::OpenMPDeclareVariantCtsSelectorData &)>
-        Callback) {
+    SourceLocation Loc, SmallVectorImpl<Sema::OMPCtxSelectorData> &Data) {
   llvm::StringMap<SourceLocation> UsedCtxSets;
   do {
     // Parse inner context selector set name.
@@ -918,7 +904,7 @@
           << getOpenMPClauseName(OMPC_match);
       return true;
     }
-    SmallString<16> Buffer;
+    Sema::OMPCtxStringType Buffer;
     StringRef CtxSelectorSetName = PP.getSpelling(Tok, Buffer);
     auto Res = UsedCtxSets.try_emplace(CtxSelectorSetName, Tok.getLocation());
     if (!Res.second) {
@@ -946,17 +932,15 @@
                                    tok::annot_pragma_openmp_end);
       if (TBr.expectAndConsume(diag::err_expected_lbrace_after, "="))
         return true;
-      OMPDeclareVariantAttr::CtxSelectorSetType CSSKind =
-          OMPDeclareVariantAttr::CtxSetUnknown;
-      (void)OMPDeclareVariantAttr::ConvertStrToCtxSelectorSetType(
-          CtxSelectorSetName, CSSKind);
+      OpenMPContextSelectorSetKind CSSKind =
+          getOpenMPContextSelectorSet(CtxSelectorSetName);
       llvm::StringMap<SourceLocation> UsedCtx;
       do {
         switch (CSSKind) {
-        case OMPDeclareVariantAttr::CtxSetImplementation:
-          parseImplementationSelector(*this, Loc, UsedCtx, Callback);
+        case OMP_CTX_SET_implementation:
+          parseImplementationSelector(*this, Loc, UsedCtx, Data);
           break;
-        case OMPDeclareVariantAttr::CtxSetUnknown:
+        case OMP_CTX_SET_unknown:
           // Skip until either '}', ')', or end of directive.
           while (!SkipUntil(tok::r_brace, tok::r_paren,
                             tok::annot_pragma_openmp_end, StopBeforeMatch))
@@ -1036,15 +1020,8 @@
   }
 
   // Parse inner context selectors.
-  if (!parseOpenMPContextSelectors(
-          Loc, [this, &DeclVarData](
-                   SourceRange SR,
-                   const Sema::OpenMPDeclareVariantCtsSelectorData &Data) {
-            if (DeclVarData.hasValue())
-              Actions.ActOnOpenMPDeclareVariantDirective(
-                  DeclVarData.getValue().first, DeclVarData.getValue().second,
-                  SR, Data);
-          })) {
+  SmallVector<Sema::OMPCtxSelectorData, 4> Data;
+  if (!parseOpenMPContextSelectors(Loc, Data)) {
     // Parse ')'.
     (void)T.consumeClose();
     // Need to check for extra tokens.
@@ -1057,6 +1034,10 @@
   // Skip last tokens.
   while (Tok.isNot(tok::annot_pragma_openmp_end))
     ConsumeAnyToken();
+  if (DeclVarData.hasValue())
+    Actions.ActOnOpenMPDeclareVariantDirective(
+        DeclVarData.getValue().first, DeclVarData.getValue().second,
+        SourceRange(Loc, Tok.getLocation()), Data);
   // Skip the last annot_pragma_openmp_end.
   (void)ConsumeAnnotationToken();
 }