This patch hides the underlying nested TREE_LIST structure of context
selectors behind accessor macros that have more meaningful names than
the generic TREE_PURPOSE/TREE_VALUE accessors.  There is a slight
change to the representation in that the score expression in
trait-selectors has a distinguished tag and is separated from the
ordinary properties, although internally it is still represented as
the first item in the TREE_VALUE of the selector.  This patch also renames
some local variables with slightly more descriptive names so it is easier
to track whether something is a selector-set, selector, or property.

gcc/ChangeLog
        * omp-general.h (OMP_TS_SCORE_NODE): New.
        (OMP_TSS_ID, OMP_TSS_TRAIT_SELECTORS): New.
        (OMP_TS_ID, OMP_TS_SCORE, OMP_TS_PROPERTIES): New.
        (OMP_TP_NAME, OMP_TP_VALUE): New.
        (make_trait_set_selector): Declare.
        (make_trait_selector): Declare.
        (make_trait_property): Declare.
        (omp_constructor_traits_to_codes): Rename to
        omp_construct_traits_to_codes.
        * omp-general.cc (omp_constructor_traits_to_codes): Rename
        to omp_construct_traits_to_codes.  Use new accessors.
        (omp_check_context_selector): Use new accessors.
        (make_trait_set_selector): New.
        (make_trait_selector): New.
        (make_trait_property): New.
        (omp_context_name_list_prop): Use new accessors.
        (omp_context_selector_matches): Use new accessors.
        (omp_context_selector_props_compare): Use new accessors.
        (omp_context_selector_set_compare): Use new accessors.
        (omp_get_context_selector): Use new accessors.
        (omp_context_compute_score): Use new accessors.
        * gimplify.cc (omp_construct_selector_matches): Adjust for renaming
        of omp_constructor_traits_to_codes.

gcc/c/ChangeLog
        * c-parser.cc (c_parser_omp_context_selector): Use new constructors.

gcc/cp/ChangeLog
        * parser.cc (cp_parser_omp_context_selector): Use new constructors.
        * pt.cc: Include omp-general.h.
        (tsubst_attribute): Use new context selector accessors and
         constructors.

gcc/fortran/ChangeLog
        * trans-openmp.cc (gfc_trans_omp_declare_variant): Use new
        constructors.
---
 gcc/c/c-parser.cc           |  27 ++--
 gcc/cp/parser.cc            |  30 ++--
 gcc/cp/pt.cc                |  82 ++++++----
 gcc/fortran/trans-openmp.cc |  27 ++--
 gcc/gimplify.cc             |   4 +-
 gcc/omp-general.cc          | 293 ++++++++++++++++++------------------
 gcc/omp-general.h           |  48 +++++-
 7 files changed, 297 insertions(+), 214 deletions(-)

diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 703f9570dbc..fcbacd461c7 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -24032,7 +24032,10 @@ static const char *const omp_user_selectors[] = {
      trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
 
    trait-score:
-     score(score-expression)  */
+     score(score-expression)
+
+   Note that this function returns a list of trait selectors for the
+   trait-selector-set SET.  */
 
 static tree
 c_parser_omp_context_selector (c_parser *parser, tree set, tree parms)
@@ -24051,6 +24054,7 @@ c_parser_omp_context_selector (c_parser *parser, tree 
set, tree parms)
        }
 
       tree properties = NULL_TREE;
+      tree scoreval = NULL_TREE;
       const char *const *selectors = NULL;
       bool allow_score = true;
       bool allow_user = false;
@@ -24157,8 +24161,7 @@ c_parser_omp_context_selector (c_parser *parser, tree 
set, tree parms)
                    error_at (token->location, "score argument must be "
                              "non-negative");
                  else
-                   properties = tree_cons (get_identifier (" score"),
-                                           score, properties);
+                   scoreval = score;
                }
              token = c_parser_peek_token (parser);
            }
@@ -24171,7 +24174,8 @@ c_parser_omp_context_selector (c_parser *parser, tree 
set, tree parms)
                {
                  t = c_parser_expr_no_commas (parser, NULL).value;
                  if (TREE_CODE (t) == STRING_CST)
-                   properties = tree_cons (NULL_TREE, t, properties);
+                   properties = make_trait_property (NULL_TREE, t,
+                                                     properties);
                  else if (t != error_mark_node)
                    {
                      mark_exp_read (t);
@@ -24182,7 +24186,8 @@ c_parser_omp_context_selector (c_parser *parser, tree 
set, tree parms)
                                  "constant integer expression or string "
                                  "literal");
                      else
-                       properties = tree_cons (NULL_TREE, t, properties);
+                       properties = make_trait_property (NULL_TREE, t,
+                                                         properties);
                    }
                  else
                    return error_mark_node;
@@ -24200,7 +24205,8 @@ c_parser_omp_context_selector (c_parser *parser, tree 
set, tree parms)
                {
                  tree prop = c_parser_peek_token (parser)->value;
                  c_parser_consume_token (parser);
-                 properties = tree_cons (prop, NULL_TREE, properties);
+                 properties = make_trait_property (prop, NULL_TREE,
+                                                   properties);
                }
              else
                {
@@ -24228,7 +24234,7 @@ c_parser_omp_context_selector (c_parser *parser, tree 
set, tree parms)
                      return error_mark_node;
                    }
 
-                 properties = tree_cons (prop, value, properties);
+                 properties = make_trait_property (prop, value, properties);
 
                  if (c_parser_next_token_is (parser, CPP_COMMA))
                    c_parser_consume_token (parser);
@@ -24248,7 +24254,8 @@ c_parser_omp_context_selector (c_parser *parser, tree 
set, tree parms)
                    error_at (token->location, "property must be "
                              "constant integer expression");
                  else
-                   properties = tree_cons (NULL_TREE, t, properties);
+                   properties = make_trait_property (NULL_TREE, t,
+                                                     properties);
                }
              else
                return error_mark_node;
@@ -24286,7 +24293,7 @@ c_parser_omp_context_selector (c_parser *parser, tree 
set, tree parms)
          return error_mark_node;
        }
 
-      ret = tree_cons (selector, properties, ret);
+      ret = make_trait_selector (selector, scoreval, properties, ret);
 
       if (c_parser_next_token_is (parser, CPP_COMMA))
        c_parser_consume_token (parser);
@@ -24362,7 +24369,7 @@ c_parser_omp_context_selector_specification (c_parser 
*parser, tree parms)
       if (selectors == error_mark_node)
        ret = error_mark_node;
       else if (ret != error_mark_node)
-       ret = tree_cons (set, selectors, ret);
+       ret = make_trait_set_selector (set, selectors, ret);
 
       braces.skip_until_found_close (parser);
 
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index d1104336215..dd773570981 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -47271,7 +47271,10 @@ static const char *const omp_user_selectors[] = {
      trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
 
    trait-score:
-     score(score-expression)  */
+     score(score-expression)
+
+   Note that this function returns a list of trait selectors for the
+   trait-selector-set SET.  */
 
 static tree
 cp_parser_omp_context_selector (cp_parser *parser, tree set, bool has_parms_p)
@@ -47290,6 +47293,7 @@ cp_parser_omp_context_selector (cp_parser *parser, tree 
set, bool has_parms_p)
        }
 
       tree properties = NULL_TREE;
+      tree scoreval = NULL_TREE;
       const char *const *selectors = NULL;
       bool allow_score = true;
       bool allow_user = false;
@@ -47396,8 +47400,7 @@ cp_parser_omp_context_selector (cp_parser *parser, tree 
set, bool has_parms_p)
                    {
                      score = fold_non_dependent_expr (score);
                      if (value_dependent_expression_p (score))
-                       properties = tree_cons (get_identifier (" score"),
-                                               score, properties);
+                       scoreval = score;
                      else if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
                               || TREE_CODE (score) != INTEGER_CST)
                        error_at (token->location, "score argument must be "
@@ -47406,8 +47409,7 @@ cp_parser_omp_context_selector (cp_parser *parser, tree 
set, bool has_parms_p)
                        error_at (token->location, "score argument must be "
                                  "non-negative");
                      else
-                       properties = tree_cons (get_identifier (" score"),
-                                               score, properties);
+                       scoreval = score;
                    }
                }
              else
@@ -47427,7 +47429,8 @@ cp_parser_omp_context_selector (cp_parser *parser, tree 
set, bool has_parms_p)
                    {
                      t = fold_non_dependent_expr (t);
                      if (TREE_CODE (t) == STRING_CST)
-                       properties = tree_cons (NULL_TREE, t, properties);
+                       properties = make_trait_property (NULL_TREE, t,
+                                                         properties);
                      else if (!value_dependent_expression_p (t)
                               && (!INTEGRAL_TYPE_P (TREE_TYPE (t))
                                   || !tree_fits_shwi_p (t)))
@@ -47435,7 +47438,8 @@ cp_parser_omp_context_selector (cp_parser *parser, tree 
set, bool has_parms_p)
                                  "constant integer expression or string "
                                  "literal");
                      else
-                       properties = tree_cons (NULL_TREE, t, properties);
+                       properties = make_trait_property (NULL_TREE, t,
+                                                         properties);
                    }
                  else
                    return error_mark_node;
@@ -47453,7 +47457,8 @@ cp_parser_omp_context_selector (cp_parser *parser, tree 
set, bool has_parms_p)
                {
                  tree prop = cp_lexer_peek_token (parser->lexer)->u.value;
                  cp_lexer_consume_token (parser->lexer);
-                 properties = tree_cons (prop, NULL_TREE, properties);
+                 properties = make_trait_property (prop, NULL_TREE,
+                                                   properties);
                }
              else
                {
@@ -47482,7 +47487,7 @@ cp_parser_omp_context_selector (cp_parser *parser, tree 
set, bool has_parms_p)
                      return error_mark_node;
                    }
 
-                 properties = tree_cons (prop, value, properties);
+                 properties = make_trait_property (prop, value, properties);
 
                  if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
                    cp_lexer_consume_token (parser->lexer);
@@ -47502,7 +47507,8 @@ cp_parser_omp_context_selector (cp_parser *parser, tree 
set, bool has_parms_p)
                    error_at (token->location, "property must be "
                              "constant integer expression");
                  else
-                   properties = tree_cons (NULL_TREE, t, properties);
+                   properties = make_trait_property (NULL_TREE, t,
+                                                     properties);
                }
              else
                return error_mark_node;
@@ -47537,7 +47543,7 @@ cp_parser_omp_context_selector (cp_parser *parser, tree 
set, bool has_parms_p)
          return error_mark_node;
        }
 
-      ret = tree_cons (selector, properties, ret);
+      ret = make_trait_selector (selector, scoreval, properties, ret);
 
       if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
        cp_lexer_consume_token (parser->lexer);
@@ -47619,7 +47625,7 @@ cp_parser_omp_context_selector_specification (cp_parser 
*parser,
          ret = error_mark_node;
        }
       else if (ret != error_mark_node)
-       ret = tree_cons (set, selectors, ret);
+       ret = make_trait_set_selector (set, selectors, ret);
 
       braces.require_close (parser);
 
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 324f6f01555..3af793dfe20 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "selftest.h"
 #include "target.h"
 #include "builtins.h"
+#include "omp-general.h"
 
 /* The type of functions taking a tree, and some additional data, and
    returning an int.  */
@@ -11841,50 +11842,72 @@ tsubst_attribute (tree t, tree *decl_p, tree args,
       location_t match_loc = cp_expr_loc_or_input_loc (TREE_PURPOSE (chain));
       tree ctx = copy_list (TREE_VALUE (val));
       tree simd = get_identifier ("simd");
-      tree score = get_identifier (" score");
       tree condition = get_identifier ("condition");
-      for (tree t1 = ctx; t1; t1 = TREE_CHAIN (t1))
+      for (tree tss = ctx; tss; tss = TREE_CHAIN (tss))
        {
-         const char *set = IDENTIFIER_POINTER (TREE_PURPOSE (t1));
-         TREE_VALUE (t1) = copy_list (TREE_VALUE (t1));
-         for (tree t2 = TREE_VALUE (t1); t2; t2 = TREE_CHAIN (t2))
+         const char *set = IDENTIFIER_POINTER (OMP_TSS_ID (tss));
+         tree selectors = NULL_TREE;
+         for (tree ts = OMP_TSS_TRAIT_SELECTORS (tss); ts;
+              ts = TREE_CHAIN (ts))
            {
-             if (TREE_PURPOSE (t2) == simd && set[0] == 'c')
+             tree properties = NULL_TREE;
+             tree scoreval = NULL_TREE;
+             if (OMP_TS_ID (ts) == simd && set[0] == 'c')
                {
-                 tree clauses = TREE_VALUE (t2);
+                 tree clauses = OMP_TS_PROPERTIES (ts);
                  clauses = tsubst_omp_clauses (clauses,
                                                C_ORT_OMP_DECLARE_SIMD, args,
                                                complain, in_decl);
                  c_omp_declare_simd_clauses_to_decls (*decl_p, clauses);
                  clauses = finish_omp_clauses (clauses, 
C_ORT_OMP_DECLARE_SIMD);
-                 TREE_VALUE (t2) = clauses;
+                 properties = clauses;
                }
              else
                {
-                 TREE_VALUE (t2) = copy_list (TREE_VALUE (t2));
-                 for (tree t3 = TREE_VALUE (t2); t3; t3 = TREE_CHAIN (t3))
-                   if (TREE_VALUE (t3))
+                 tree v = OMP_TS_SCORE (ts);
+                 if (v)
+                   {
+                     v = tsubst_expr (v, args, complain, in_decl);
+                     v = fold_non_dependent_expr (v);
+                     if (!INTEGRAL_TYPE_P (TREE_TYPE (v))
+                         || TREE_CODE (v) != INTEGER_CST)
+                       {
+                         location_t loc
+                           = cp_expr_loc_or_loc (OMP_TS_SCORE (ts),
+                                                 match_loc);
+                         error_at (loc, "score argument must be "
+                                   "constant integer expression");
+                         return NULL_TREE;
+                       }
+                     else if (tree_int_cst_sgn (v) < 0)
+                       {
+                         location_t loc
+                           = cp_expr_loc_or_loc (OMP_TS_SCORE (ts),
+                                                 match_loc);
+                         error_at (loc, "score argument must be "
+                                   "non-negative");
+                         return NULL_TREE;
+                       }
+                     scoreval = v;
+                   }
+                 properties = copy_list (OMP_TS_PROPERTIES (ts));
+                 for (tree p = properties; p; p = TREE_CHAIN (p))
+                   if (OMP_TP_VALUE (p))
                      {
                        bool allow_string
-                         = ((TREE_PURPOSE (t2) != condition || set[0] != 'u')
-                            && TREE_PURPOSE (t3) != score);
-                       tree v = TREE_VALUE (t3);
+                         = (OMP_TS_ID (ts) != condition || set[0] != 'u');
+                       tree v = OMP_TP_VALUE (p);
                        if (TREE_CODE (v) == STRING_CST && allow_string)
                          continue;
                        v = tsubst_expr (v, args, complain, in_decl);
                        v = fold_non_dependent_expr (v);
                        if (!INTEGRAL_TYPE_P (TREE_TYPE (v))
-                           || (TREE_PURPOSE (t3) == score
-                               ? TREE_CODE (v) != INTEGER_CST
-                               : !tree_fits_shwi_p (v)))
+                           || !tree_fits_shwi_p (v))
                          {
                            location_t loc
-                             = cp_expr_loc_or_loc (TREE_VALUE (t3),
+                             = cp_expr_loc_or_loc (OMP_TP_VALUE (p),
                                                    match_loc);
-                           if (TREE_PURPOSE (t3) == score)
-                             error_at (loc, "score argument must be "
-                                            "constant integer expression");
-                           else if (allow_string)
+                           if (allow_string)
                              error_at (loc, "property must be constant "
                                             "integer expression or string "
                                             "literal");
@@ -11893,20 +11916,13 @@ tsubst_attribute (tree t, tree *decl_p, tree args,
                                             "integer expression");
                            return NULL_TREE;
                          }
-                       else if (TREE_PURPOSE (t3) == score
-                                && tree_int_cst_sgn (v) < 0)
-                         {
-                           location_t loc
-                             = cp_expr_loc_or_loc (TREE_VALUE (t3),
-                                                   match_loc);
-                           error_at (loc, "score argument must be "
-                                          "non-negative");
-                           return NULL_TREE;
-                         }
-                       TREE_VALUE (t3) = v;
+                       OMP_TP_VALUE (p) = v;
                      }
                }
+             selectors = make_trait_selector (OMP_TS_ID (ts), scoreval,
+                                              properties, selectors);
            }
+         OMP_TSS_TRAIT_SELECTORS (tss) = nreverse (selectors);
        }
       val = tree_cons (varid, ctx, chain);
     }
diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index 82bbc41b388..fe8044a57cd 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -8210,6 +8210,7 @@ gfc_trans_omp_declare_variant (gfc_namespace *ns)
          gfc_omp_selector *os;
          for (os = oss->trait_selectors; os; os = os->next)
            {
+             tree scoreval = NULL_TREE;
              tree properties = NULL_TREE;
              gfc_omp_trait_property *otp;
 
@@ -8223,13 +8224,14 @@ gfc_trans_omp_declare_variant (gfc_namespace *ns)
                        gfc_se se;
                        gfc_init_se (&se, NULL);
                        gfc_conv_expr (&se, otp->expr);
-                       properties = tree_cons (NULL_TREE, se.expr,
-                                               properties);
+                       properties = make_trait_property (NULL_TREE, se.expr,
+                                                         properties);
                      }
                      break;
                    case CTX_PROPERTY_ID:
-                     properties = tree_cons (get_identifier (otp->name),
-                                             NULL_TREE, properties);
+                     properties
+                       = make_trait_property (get_identifier (otp->name),
+                                              NULL_TREE, properties);
                      break;
                    case CTX_PROPERTY_NAME_LIST:
                      {
@@ -8239,7 +8241,8 @@ gfc_trans_omp_declare_variant (gfc_namespace *ns)
                        else
                          value = gfc_conv_constant_to_tree (otp->expr);
 
-                       properties = tree_cons (prop, value, properties);
+                       properties = make_trait_property (prop, value,
+                                                         properties);
                      }
                      break;
                    case CTX_PROPERTY_SIMD:
@@ -8256,17 +8259,17 @@ gfc_trans_omp_declare_variant (gfc_namespace *ns)
                  gfc_se se;
                  gfc_init_se (&se, NULL);
                  gfc_conv_expr (&se, os->score);
-                 properties = tree_cons (get_identifier (" score"),
-                                         se.expr, properties);
+                 scoreval = se.expr;
                }
 
-             selectors = tree_cons (get_identifier (os->trait_selector_name),
-                                    properties, selectors);
+             tree ts_name = get_identifier (os->trait_selector_name);
+             selectors = make_trait_selector (ts_name, scoreval,
+                                              properties, selectors);
            }
 
-         set_selectors
-           = tree_cons (get_identifier (oss->trait_set_selector_name),
-                        selectors, set_selectors);
+         tree tss_name = get_identifier (oss->trait_set_selector_name);
+         set_selectors = make_trait_set_selector (tss_name, selectors,
+                                                  set_selectors);
        }
 
       const char *variant_proc_name = odv->variant_proc_symtree->name;
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 77f07af6ec5..757654d5434 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -13541,8 +13541,8 @@ omp_construct_selector_matches (enum tree_code 
*constructs, int nconstructs,
       int variant_nconstructs = 0;
       if (!target_seen)
        variant_nconstructs
-         = omp_constructor_traits_to_codes (TREE_VALUE (attr),
-                                            variant_constructs);
+         = omp_construct_traits_to_codes (TREE_VALUE (attr),
+                                          variant_constructs);
       for (int i = 0; i < variant_nconstructs; i++)
        {
          ++cnt;
diff --git a/gcc/omp-general.cc b/gcc/omp-general.cc
index b88d5930aab..4ea0d971273 100644
--- a/gcc/omp-general.cc
+++ b/gcc/omp-general.cc
@@ -1017,13 +1017,13 @@ omp_max_simt_vf (void)
    return their number.  */
 
 int
-omp_constructor_traits_to_codes (tree ctx, enum tree_code *constructs)
+omp_construct_traits_to_codes (tree ctx, enum tree_code *constructs)
 {
   int nconstructs = list_length (ctx);
   int i = nconstructs - 1;
-  for (tree t2 = ctx; t2; t2 = TREE_CHAIN (t2), i--)
+  for (tree ts = ctx; ts; ts = TREE_CHAIN (ts), i--)
     {
-      const char *sel = IDENTIFIER_POINTER (TREE_PURPOSE (t2));
+      const char *sel = IDENTIFIER_POINTER (OMP_TS_ID (ts));
       if (!strcmp (sel, "target"))
        constructs[i] = OMP_TARGET;
       else if (!strcmp (sel, "teams"))
@@ -1125,38 +1125,40 @@ omp_check_context_selector (location_t loc, tree ctx)
      There are just 4 set names.  */
   for (tree t1 = ctx; t1; t1 = TREE_CHAIN (t1))
     for (tree t2 = TREE_CHAIN (t1); t2; t2 = TREE_CHAIN (t2))
-      if (TREE_PURPOSE (t1) == TREE_PURPOSE (t2))
+      if (OMP_TSS_ID (t1) == OMP_TSS_ID (t2))
        {
          error_at (loc, "selector set %qs specified more than once",
-                   IDENTIFIER_POINTER (TREE_PURPOSE (t1)));
+                   IDENTIFIER_POINTER (OMP_TSS_ID (t1)));
          return error_mark_node;
        }
-  for (tree t = ctx; t; t = TREE_CHAIN (t))
+  for (tree tss = ctx; tss; tss = TREE_CHAIN (tss))
     {
       /* Each trait-selector-name can only be specified once.  */
-      if (list_length (TREE_VALUE (t)) < 5)
+      if (list_length (OMP_TSS_TRAIT_SELECTORS (tss)) < 5)
        {
-         for (tree t1 = TREE_VALUE (t); t1; t1 = TREE_CHAIN (t1))
-           for (tree t2 = TREE_CHAIN (t1); t2; t2 = TREE_CHAIN (t2))
-             if (TREE_PURPOSE (t1) == TREE_PURPOSE (t2))
+         for (tree ts1 = OMP_TSS_TRAIT_SELECTORS (tss); ts1;
+              ts1 = TREE_CHAIN (ts1))
+           for (tree ts2 = TREE_CHAIN (ts1); ts2; ts2 = TREE_CHAIN (ts2))
+             if (OMP_TS_ID (ts1) == OMP_TS_ID (ts2))
                {
                  error_at (loc,
                            "selector %qs specified more than once in set %qs",
-                           IDENTIFIER_POINTER (TREE_PURPOSE (t1)),
-                           IDENTIFIER_POINTER (TREE_PURPOSE (t)));
+                           IDENTIFIER_POINTER (OMP_TS_ID (ts1)),
+                           IDENTIFIER_POINTER (OMP_TSS_ID (tss)));
                  return error_mark_node;
                }
        }
       else
        {
          hash_set<tree> pset;
-         for (tree t1 = TREE_VALUE (t); t1; t1 = TREE_CHAIN (t1))
-           if (pset.add (TREE_PURPOSE (t1)))
+         for (tree ts = OMP_TSS_TRAIT_SELECTORS (tss); ts;
+              ts = TREE_CHAIN (ts))
+           if (pset.add (OMP_TS_ID (ts)))
              {
                error_at (loc,
                          "selector %qs specified more than once in set %qs",
-                         IDENTIFIER_POINTER (TREE_PURPOSE (t1)),
-                         IDENTIFIER_POINTER (TREE_PURPOSE (t)));
+                         IDENTIFIER_POINTER (OMP_TS_ID (ts)),
+                         IDENTIFIER_POINTER (OMP_TSS_ID (tss)));
                return error_mark_node;
              }
        }
@@ -1177,49 +1179,45 @@ omp_check_context_selector (location_t loc, tree ctx)
        { "implementation", "extension", extension },
        { "implementation", "atomic_default_mem_order",
          atomic_default_mem_order } };
-      for (tree t1 = TREE_VALUE (t); t1; t1 = TREE_CHAIN (t1))
+      for (tree ts = OMP_TSS_TRAIT_SELECTORS (tss); ts; ts = TREE_CHAIN (ts))
        for (unsigned i = 0; i < ARRAY_SIZE (props); i++)
-         if (!strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t1)),
+         if (!strcmp (IDENTIFIER_POINTER (OMP_TS_ID (ts)),
                                           props[i].selector)
-             && !strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t)),
+             && !strcmp (IDENTIFIER_POINTER (OMP_TSS_ID (tss)),
                                              props[i].set))
-           for (tree t2 = TREE_VALUE (t1); t2; t2 = TREE_CHAIN (t2))
+           for (tree p = OMP_TS_PROPERTIES (ts); p; p = TREE_CHAIN (p))
              for (unsigned j = 0; ; j++)
                {
                  if (props[i].props[j] == NULL)
                    {
-                     if (TREE_PURPOSE (t2)
-                         && !strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t2)),
-                                     " score"))
-                       break;
                      if (props[i].props == atomic_default_mem_order)
                        {
                          error_at (loc,
                                    "incorrect property %qs of %qs selector",
-                                   IDENTIFIER_POINTER (TREE_PURPOSE (t2)),
+                                   IDENTIFIER_POINTER (TREE_PURPOSE (p)),
                                    "atomic_default_mem_order");
                          return error_mark_node;
                        }
-                     else if (TREE_PURPOSE (t2))
+                     else if (OMP_TP_NAME (p))
                        warning_at (loc, 0,
                                    "unknown property %qs of %qs selector",
-                                   IDENTIFIER_POINTER (TREE_PURPOSE (t2)),
+                                   IDENTIFIER_POINTER (OMP_TP_NAME (p)),
                                    props[i].selector);
                      else
                        warning_at (loc, 0,
                                    "unknown property %qE of %qs selector",
-                                   TREE_VALUE (t2), props[i].selector);
+                                   OMP_TP_VALUE (p), props[i].selector);
                      break;
                    }
-                 else if (TREE_PURPOSE (t2) == NULL_TREE)
+                 else if (OMP_TP_NAME (p) == NULL_TREE)
                    {
-                     const char *str = TREE_STRING_POINTER (TREE_VALUE (t2));
+                     const char *str = TREE_STRING_POINTER (OMP_TP_VALUE (p));
                      if (!strcmp (str, props[i].props[j])
-                         && ((size_t) TREE_STRING_LENGTH (TREE_VALUE (t2))
+                         && ((size_t) TREE_STRING_LENGTH (OMP_TP_VALUE (p))
                              == strlen (str) + (lang_GNU_Fortran () ? 0 : 1)))
                        break;
                    }
-                 else if (!strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t2)),
+                 else if (!strcmp (IDENTIFIER_POINTER (OMP_TP_NAME (p)),
                                    props[i].props[j]))
                    break;
                }
@@ -1254,18 +1252,43 @@ omp_mark_declare_variant (location_t loc, tree variant, 
tree construct)
 }
 
 
+/* Constructors for context selectors.  */
+
+tree
+make_trait_set_selector (tree name, tree selectors, tree chain)
+{
+  return tree_cons (name, selectors, chain);
+}
+
+tree
+make_trait_selector (tree name, tree score, tree properties, tree chain)
+{
+  if (score == NULL_TREE)
+    return tree_cons (name, properties, chain);
+  else
+    return tree_cons (name,
+                     tree_cons (OMP_TS_SCORE_NODE, score, properties),
+                     chain);
+}
+
+tree
+make_trait_property (tree name, tree value, tree chain)
+{
+  return tree_cons (name, value, chain);
+}
+
 /* Return a name from PROP, a property in selectors accepting
    name lists.  */
 
 static const char *
 omp_context_name_list_prop (tree prop)
 {
-  if (TREE_PURPOSE (prop))
-    return IDENTIFIER_POINTER (TREE_PURPOSE (prop));
+  if (OMP_TP_NAME (prop))
+    return IDENTIFIER_POINTER (OMP_TP_NAME (prop));
   else
     {
-      const char *ret = TREE_STRING_POINTER (TREE_VALUE (prop));
-      if ((size_t) TREE_STRING_LENGTH (TREE_VALUE (prop))
+      const char *ret = TREE_STRING_POINTER (OMP_TP_VALUE (prop));
+      if ((size_t) TREE_STRING_LENGTH (OMP_TP_VALUE (prop))
          == strlen (ret) + (lang_GNU_Fortran () ? 0 : 1))
        return ret;
       return NULL;
@@ -1282,9 +1305,9 @@ int
 omp_context_selector_matches (tree ctx)
 {
   int ret = 1;
-  for (tree t1 = ctx; t1; t1 = TREE_CHAIN (t1))
+  for (tree tss = ctx; tss; tss = TREE_CHAIN (tss))
     {
-      char set = IDENTIFIER_POINTER (TREE_PURPOSE (t1))[0];
+      char set = IDENTIFIER_POINTER (OMP_TSS_ID (tss))[0];
       if (set == 'c')
        {
          /* For now, ignore the construct set.  While something can be
@@ -1302,7 +1325,8 @@ omp_context_selector_matches (tree ctx)
 
          enum tree_code constructs[5];
          int nconstructs
-           = omp_constructor_traits_to_codes (TREE_VALUE (t1), constructs);
+           = omp_construct_traits_to_codes (OMP_TSS_TRAIT_SELECTORS (tss),
+                                            constructs);
 
          if (cfun && (cfun->curr_properties & PROP_gimple_any) != 0)
            {
@@ -1333,20 +1357,19 @@ omp_context_selector_matches (tree ctx)
            ret = -1;
          continue;
        }
-      for (tree t2 = TREE_VALUE (t1); t2; t2 = TREE_CHAIN (t2))
+      for (tree ts = OMP_TSS_TRAIT_SELECTORS (tss); ts; ts = TREE_CHAIN (ts))
        {
-         const char *sel = IDENTIFIER_POINTER (TREE_PURPOSE (t2));
+         const char *sel = IDENTIFIER_POINTER (OMP_TS_ID (ts));
          switch (*sel)
            {
            case 'v':
              if (set == 'i' && !strcmp (sel, "vendor"))
-               for (tree t3 = TREE_VALUE (t2); t3; t3 = TREE_CHAIN (t3))
+               for (tree p = OMP_TS_PROPERTIES (ts); p; p = TREE_CHAIN (p))
                  {
-                   const char *prop = omp_context_name_list_prop (t3);
+                   const char *prop = omp_context_name_list_prop (p);
                    if (prop == NULL)
                      return 0;
-                   if ((!strcmp (prop, " score") && TREE_PURPOSE (t3))
-                       || !strcmp (prop, "gnu"))
+                   if (!strcmp (prop, "gnu"))
                      continue;
                    return 0;
                  }
@@ -1377,13 +1400,8 @@ omp_context_selector_matches (tree ctx)
                      else
                        omo = OMP_MEMORY_ORDER_RELAXED;
                    }
-                 tree t3 = TREE_VALUE (t2);
-                 const char *prop = IDENTIFIER_POINTER (TREE_PURPOSE (t3));
-                 if (!strcmp (prop, " score"))
-                   {
-                     t3 = TREE_CHAIN (t3);
-                     prop = IDENTIFIER_POINTER (TREE_PURPOSE (t3));
-                   }
+                 tree p = OMP_TS_PROPERTIES (ts);
+                 const char *prop = IDENTIFIER_POINTER (OMP_TP_NAME (p));
                  if (!strcmp (prop, "relaxed")
                      && omo != OMP_MEMORY_ORDER_RELAXED)
                    return 0;
@@ -1395,9 +1413,9 @@ omp_context_selector_matches (tree ctx)
                    return 0;
                }
              if (set == 'd' && !strcmp (sel, "arch"))
-               for (tree t3 = TREE_VALUE (t2); t3; t3 = TREE_CHAIN (t3))
+               for (tree p = OMP_TS_PROPERTIES (ts); p; p = TREE_CHAIN (p))
                  {
-                   const char *arch = omp_context_name_list_prop (t3);
+                   const char *arch = omp_context_name_list_prop (p);
                    if (arch == NULL)
                      return 0;
                    int r = 0;
@@ -1497,9 +1515,9 @@ omp_context_selector_matches (tree ctx)
              break;
            case 'k':
              if (set == 'd' && !strcmp (sel, "kind"))
-               for (tree t3 = TREE_VALUE (t2); t3; t3 = TREE_CHAIN (t3))
+               for (tree p = OMP_TS_PROPERTIES (ts); p; p = TREE_CHAIN (p))
                  {
-                   const char *prop = omp_context_name_list_prop (t3);
+                   const char *prop = omp_context_name_list_prop (p);
                    if (prop == NULL)
                      return 0;
                    if (!strcmp (prop, "any"))
@@ -1558,9 +1576,9 @@ omp_context_selector_matches (tree ctx)
              break;
            case 'i':
              if (set == 'd' && !strcmp (sel, "isa"))
-               for (tree t3 = TREE_VALUE (t2); t3; t3 = TREE_CHAIN (t3))
+               for (tree p = OMP_TS_PROPERTIES (ts); p; p = TREE_CHAIN (p))
                  {
-                   const char *isa = omp_context_name_list_prop (t3);
+                   const char *isa = omp_context_name_list_prop (p);
                    if (isa == NULL)
                      return 0;
                    int r = 0;
@@ -1611,12 +1629,12 @@ omp_context_selector_matches (tree ctx)
              break;
            case 'c':
              if (set == 'u' && !strcmp (sel, "condition"))
-               for (tree t3 = TREE_VALUE (t2); t3; t3 = TREE_CHAIN (t3))
-                 if (TREE_PURPOSE (t3) == NULL_TREE)
+               for (tree p = OMP_TS_PROPERTIES (ts); p; p = TREE_CHAIN (p))
+                 if (OMP_TP_NAME (p) == NULL_TREE)
                    {
-                     if (integer_zerop (TREE_VALUE (t3)))
+                     if (integer_zerop (OMP_TP_VALUE (p)))
                        return 0;
-                     if (integer_nonzerop (TREE_VALUE (t3)))
+                     if (integer_nonzerop (OMP_TP_VALUE (p)))
                        break;
                      ret = -1;
                    }
@@ -1747,6 +1765,7 @@ omp_construct_simd_compare (tree clauses1, tree clauses2)
 }
 
 /* Compare properties of selectors SEL from SET other than construct.
+   CTX1 and CTX2 are the lists of properties to compare.
    Return 0/-1/1/2 as in omp_context_selector_set_compare.
    Unlike set names or selector names, properties can have duplicates.  */
 
@@ -1756,57 +1775,37 @@ omp_context_selector_props_compare (const char *set, 
const char *sel,
 {
   int ret = 0;
   for (int pass = 0; pass < 2; pass++)
-    for (tree t1 = pass ? ctx2 : ctx1; t1; t1 = TREE_CHAIN (t1))
+    for (tree p1 = pass ? ctx2 : ctx1; p1; p1 = TREE_CHAIN (p1))
       {
-       tree t2;
-       for (t2 = pass ? ctx1 : ctx2; t2; t2 = TREE_CHAIN (t2))
-         if (TREE_PURPOSE (t1) == TREE_PURPOSE (t2))
+       tree p2;
+       for (p2 = pass ? ctx1 : ctx2; p2; p2 = TREE_CHAIN (p2))
+         if (OMP_TP_NAME (p1) == OMP_TP_NAME (p2))
            {
-             if (TREE_PURPOSE (t1) == NULL_TREE)
+             if (OMP_TP_NAME (p1) == NULL_TREE)
                {
                  if (set[0] == 'u' && strcmp (sel, "condition") == 0)
                    {
-                     if (integer_zerop (TREE_VALUE (t1))
-                         != integer_zerop (TREE_VALUE (t2)))
+                     if (integer_zerop (OMP_TP_VALUE (p1))
+                         != integer_zerop (OMP_TP_VALUE (p2)))
                        return 2;
                      break;
                    }
-                 if (simple_cst_equal (TREE_VALUE (t1), TREE_VALUE (t2)))
+                 if (simple_cst_equal (OMP_TP_VALUE (p1), OMP_TP_VALUE (p2)))
                    break;
                }
-             else if (strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t1)),
-                              " score") == 0)
-               {
-                 if (!simple_cst_equal (TREE_VALUE (t1), TREE_VALUE (t2)))
-                   return 2;
-                 break;
-               }
              else
                break;
            }
-         else if (TREE_PURPOSE (t1)
-                  && TREE_PURPOSE (t2) == NULL_TREE
-                  && TREE_CODE (TREE_VALUE (t2)) == STRING_CST)
-           {
-             const char *p1 = omp_context_name_list_prop (t1);
-             const char *p2 = omp_context_name_list_prop (t2);
-             if (p2
-                 && strcmp (p1, p2) == 0
-                 && strcmp (p1, " score"))
-               break;
-           }
-         else if (TREE_PURPOSE (t1) == NULL_TREE
-                  && TREE_PURPOSE (t2)
-                  && TREE_CODE (TREE_VALUE (t1)) == STRING_CST)
+         else
            {
-             const char *p1 = omp_context_name_list_prop (t1);
-             const char *p2 = omp_context_name_list_prop (t2);
-             if (p1
-                 && strcmp (p1, p2) == 0
-                 && strcmp (p1, " score"))
+             /* Handle string constant vs identifier comparison for
+                name-list properties.  */
+             const char *n1 = omp_context_name_list_prop (p1);
+             const char *n2 = omp_context_name_list_prop (p2);
+             if (n1 && n2 && !strcmp (n1, n2))
                break;
            }
-       if (t2 == NULL_TREE)
+       if (p2 == NULL_TREE)
          {
            int r = pass ? -1 : 1;
            if (ret && ret != r)
@@ -1824,6 +1823,7 @@ omp_context_selector_props_compare (const char *set, 
const char *sel,
 }
 
 /* Compare single context selector sets CTX1 and CTX2 with SET name.
+   CTX1 and CTX2 are lists of trait-selectors.
    Return 0 if CTX1 is equal to CTX2,
    -1 if CTX1 is a strict subset of CTX2,
    1 if CTX2 is a strict subset of CTX1, or
@@ -1845,26 +1845,26 @@ omp_context_selector_set_compare (const char *set, tree 
ctx1, tree ctx2)
     }
   if (set[0] == 'c')
     {
-      tree t1;
-      tree t2 = ctx2;
+      tree ts1;
+      tree ts2 = ctx2;
       tree simd = get_identifier ("simd");
       /* Handle construct set specially.  In this case the order
         of the selector matters too.  */
-      for (t1 = ctx1; t1; t1 = TREE_CHAIN (t1))
-       if (TREE_PURPOSE (t1) == TREE_PURPOSE (t2))
+      for (ts1 = ctx1; ts1; ts1 = TREE_CHAIN (ts1))
+       if (OMP_TS_ID (ts1) == OMP_TS_ID (ts2))
          {
            int r = 0;
-           if (TREE_PURPOSE (t1) == simd)
-             r = omp_construct_simd_compare (TREE_VALUE (t1),
-                                             TREE_VALUE (t2));
+           if (OMP_TS_ID (ts1) == simd)
+             r = omp_construct_simd_compare (OMP_TS_PROPERTIES (ts1),
+                                             OMP_TS_PROPERTIES (ts2));
            if (r == 2 || (ret && r && (ret < 0) != (r < 0)))
              return 2;
            if (ret == 0)
              ret = r;
-           t2 = TREE_CHAIN (t2);
-           if (t2 == NULL_TREE)
+           ts2 = TREE_CHAIN (ts2);
+           if (ts2 == NULL_TREE)
              {
-               t1 = TREE_CHAIN (t1);
+               ts1 = TREE_CHAIN (ts1);
                break;
              }
          }
@@ -1872,9 +1872,9 @@ omp_context_selector_set_compare (const char *set, tree 
ctx1, tree ctx2)
          return 2;
        else
          ret = 1;
-      if (t2 != NULL_TREE)
+      if (ts2 != NULL_TREE)
        return 2;
-      if (t1 != NULL_TREE)
+      if (ts1 != NULL_TREE)
        {
          if (ret < 0)
            return 2;
@@ -1884,16 +1884,21 @@ omp_context_selector_set_compare (const char *set, tree 
ctx1, tree ctx2)
        return 0;
       return swapped ? -ret : ret;
     }
-  for (tree t1 = ctx1; t1; t1 = TREE_CHAIN (t1))
+  for (tree ts1 = ctx1; ts1; ts1 = TREE_CHAIN (ts1))
     {
-      tree t2;
-      for (t2 = ctx2; t2; t2 = TREE_CHAIN (t2))
-       if (TREE_PURPOSE (t1) == TREE_PURPOSE (t2))
+      tree ts2;
+      for (ts2 = ctx2; ts2; ts2 = TREE_CHAIN (ts2))
+       if (OMP_TS_ID (ts1) == OMP_TS_ID (ts2))
          {
-           const char *sel = IDENTIFIER_POINTER (TREE_PURPOSE (t1));
+           tree score1 = OMP_TS_SCORE (ts1);
+           tree score2 = OMP_TS_SCORE (ts2);
+           if (score1 && score2 && !simple_cst_equal (score1, score2))
+             return 2;
+
+           const char *sel = IDENTIFIER_POINTER (OMP_TS_ID (ts1));
            int r = omp_context_selector_props_compare (set, sel,
-                                                       TREE_VALUE (t1),
-                                                       TREE_VALUE (t2));
+                                                       OMP_TS_PROPERTIES (ts1),
+                                                       OMP_TS_PROPERTIES 
(ts2));
            if (r == 2 || (ret && r && (ret < 0) != (r < 0)))
              return 2;
            if (ret == 0)
@@ -1901,7 +1906,7 @@ omp_context_selector_set_compare (const char *set, tree 
ctx1, tree ctx2)
            cnt++;
            break;
          }
-      if (t2 == NULL_TREE)
+      if (ts2 == NULL_TREE)
        {
          if (ret == -1)
            return 2;
@@ -1935,15 +1940,17 @@ omp_context_selector_compare (tree ctx1, tree ctx2)
       std::swap (ctx1, ctx2);
       std::swap (len1, len2);
     }
-  for (tree t1 = ctx1; t1; t1 = TREE_CHAIN (t1))
+  for (tree tss1 = ctx1; tss1; tss1 = TREE_CHAIN (tss1))
     {
-      tree t2;
-      for (t2 = ctx2; t2; t2 = TREE_CHAIN (t2))
-       if (TREE_PURPOSE (t1) == TREE_PURPOSE (t2))
+      tree tss2;
+      for (tss2 = ctx2; tss2; tss2 = TREE_CHAIN (tss2))
+       if (OMP_TSS_ID (tss1) == OMP_TSS_ID (tss2))
          {
-           const char *set = IDENTIFIER_POINTER (TREE_PURPOSE (t1));
-           int r = omp_context_selector_set_compare (set, TREE_VALUE (t1),
-                                                     TREE_VALUE (t2));
+           const char *set = IDENTIFIER_POINTER (OMP_TSS_ID (tss1));
+           int r
+             = omp_context_selector_set_compare
+                 (set, OMP_TSS_TRAIT_SELECTORS (tss1),
+                  OMP_TSS_TRAIT_SELECTORS (tss2));
            if (r == 2 || (ret && r && (ret < 0) != (r < 0)))
              return 2;
            if (ret == 0)
@@ -1951,7 +1958,7 @@ omp_context_selector_compare (tree ctx1, tree ctx2)
            cnt++;
            break;
          }
-      if (t2 == NULL_TREE)
+      if (tss2 == NULL_TREE)
        {
          if (ret == -1)
            return 2;
@@ -1974,14 +1981,14 @@ omp_get_context_selector (tree ctx, const char *set, 
const char *sel)
 {
   tree setid = get_identifier (set);
   tree selid = sel ? get_identifier (sel) : NULL_TREE;
-  for (tree t1 = ctx; t1; t1 = TREE_CHAIN (t1))
-    if (TREE_PURPOSE (t1) == setid)
+  for (tree tss = ctx; tss; tss = TREE_CHAIN (tss))
+    if (OMP_TSS_ID (tss) == setid)
       {
        if (sel == NULL)
-         return TREE_VALUE (t1);
-       for (tree t2 = TREE_VALUE (t1); t2; t2 = TREE_CHAIN (t2))
-         if (TREE_PURPOSE (t2) == selid)
-           return t2;
+         return OMP_TSS_TRAIT_SELECTORS (tss);
+       for (tree ts = OMP_TSS_TRAIT_SELECTORS (tss); ts; ts = TREE_CHAIN (ts))
+         if (OMP_TS_ID (ts) == selid)
+           return ts;
       }
   return NULL_TREE;
 }
@@ -2004,25 +2011,23 @@ omp_context_compute_score (tree ctx, score_wide_int 
*score, bool declare_simd)
   bool has_isa = omp_get_context_selector (ctx, "device", "isa");
   bool ret = false;
   *score = 1;
-  for (tree t1 = ctx; t1; t1 = TREE_CHAIN (t1))
-    if (TREE_VALUE (t1) != construct)
-      for (tree t2 = TREE_VALUE (t1); t2; t2 = TREE_CHAIN (t2))
-       if (tree t3 = TREE_VALUE (t2))
-         if (TREE_PURPOSE (t3)
-             && strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t3)), " score") == 0
-             && TREE_CODE (TREE_VALUE (t3)) == INTEGER_CST)
-           {
-             tree t4 = TREE_VALUE (t3);
-             *score += score_wide_int::from (wi::to_wide (t4),
-                                             TYPE_SIGN (TREE_TYPE (t4)));
-           }
+  for (tree tss = ctx; tss; tss = TREE_CHAIN (tss))
+    if (OMP_TSS_TRAIT_SELECTORS (tss) != construct)
+      for (tree ts = OMP_TSS_TRAIT_SELECTORS (tss); ts; ts = TREE_CHAIN (ts))
+       {
+         tree s = OMP_TS_SCORE (ts);
+         if (s && TREE_CODE (s) == INTEGER_CST)
+           *score += score_wide_int::from (wi::to_wide (s),
+                                           TYPE_SIGN (TREE_TYPE (s)));
+       }
+
   if (construct || has_kind || has_arch || has_isa)
     {
       int scores[12];
       enum tree_code constructs[5];
       int nconstructs = 0;
       if (construct)
-       nconstructs = omp_constructor_traits_to_codes (construct, constructs);
+       nconstructs = omp_construct_traits_to_codes (construct, constructs);
       if (omp_construct_selector_matches (constructs, nconstructs, scores)
          == 2)
        ret = true;
diff --git a/gcc/omp-general.h b/gcc/omp-general.h
index 1a52bfdb56b..28a9c0e6e17 100644
--- a/gcc/omp-general.h
+++ b/gcc/omp-general.h
@@ -92,6 +92,52 @@ struct omp_for_data
 
 #define OACC_FN_ATTRIB "oacc function"
 
+/* Accessors for OMP context selectors, used by variant directives.
+   These are represented internally by a multilevel TREE_LIST structure, but
+   these accessors should be used to avoid confusion.  The grammar is:
+
+   context-set-selector-specification:
+     trait-set-selector [, trait-set-selector [, ...]]
+   trait-set-selector:
+     trait-set-selector-name = { trait-selector [, trait-selector [, ... ]] }
+   trait-selector:
+     trait-selector-name [ ( [trait-score: ]
+                            trait-property [, trait-property  [, ...]] ) ]
+
+   trait-properties can variously be identifiers, strings, clauses, or
+   expressions.
+
+   All the lists are chained via TREE_CHAIN.  If a score is present, it is
+   internally tacked on to the properties with a TREE_PURPOSE of
+   OMP_TS_SCORE_NODE.  */
+
+#define OMP_TS_SCORE_NODE integer_minus_one_node
+
+#define OMP_TSS_ID(NODE) \
+  TREE_PURPOSE (NODE)
+#define OMP_TSS_TRAIT_SELECTORS(NODE) \
+  TREE_VALUE (NODE)
+#define OMP_TS_ID(NODE) \
+  TREE_PURPOSE (NODE)
+#define OMP_TS_SCORE(NODE) \
+  ((TREE_VALUE (NODE)                                        \
+    && TREE_CODE (TREE_VALUE (NODE)) == TREE_LIST            \
+    && TREE_PURPOSE (TREE_VALUE (NODE)) == OMP_TS_SCORE_NODE) \
+   ? TREE_VALUE (TREE_VALUE (NODE)) : NULL_TREE)
+#define OMP_TS_PROPERTIES(NODE) \
+  ((TREE_VALUE (NODE)                                        \
+    && TREE_CODE (TREE_VALUE (NODE)) == TREE_LIST            \
+    && TREE_PURPOSE (TREE_VALUE (NODE)) == OMP_TS_SCORE_NODE) \
+   ? TREE_CHAIN (TREE_VALUE (NODE)) : TREE_VALUE (NODE))
+#define OMP_TP_NAME(NODE) \
+  TREE_PURPOSE (NODE)
+#define OMP_TP_VALUE(NODE) \
+  TREE_VALUE (NODE)
+
+extern tree make_trait_set_selector (tree, tree, tree);
+extern tree make_trait_selector (tree, tree, tree, tree);
+extern tree make_trait_property (tree, tree, tree);
+
 extern tree omp_find_clause (tree clauses, enum omp_clause_code kind);
 extern bool omp_is_allocatable_or_ptr (tree decl);
 extern tree omp_check_optional_argument (tree decl, bool for_present_check);
@@ -106,7 +152,7 @@ extern gimple *omp_build_barrier (tree lhs);
 extern tree find_combined_omp_for (tree *, int *, void *);
 extern poly_uint64 omp_max_vf (void);
 extern int omp_max_simt_vf (void);
-extern int omp_constructor_traits_to_codes (tree, enum tree_code *);
+extern int omp_construct_traits_to_codes (tree, enum tree_code *);
 extern tree omp_check_context_selector (location_t loc, tree ctx);
 extern void omp_mark_declare_variant (location_t loc, tree variant,
                                      tree construct);
-- 
2.31.1


Reply via email to