From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 261D83857400 for ; Thu, 29 Sep 2022 15:09:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 261D83857400 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1664464194; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=oYcG1yJE0Jyrk2FH4pQd3FEnx4NKON309HxUVp5IyxY=; b=STMICAVT4+gu72gRl9LohjdD7b6RQjVwHiwd1qccEv62wBj2X80fnBUTxtfBwGg0VGp/38 fMZ+5ujoaKBCuTnptR4olCexXHsxbICmfClaTI73fTPdUdSNue8WtYHXot+GsFl4aVI5YI jlzzenLJZMWb9fQ8oAP1fnqjmHbYwy4= Received: from mail-qv1-f70.google.com (mail-qv1-f70.google.com [209.85.219.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-510-kcYU1vaQMiCD_cu-cYxzbA-1; Thu, 29 Sep 2022 11:09:53 -0400 X-MC-Unique: kcYU1vaQMiCD_cu-cYxzbA-1 Received: by mail-qv1-f70.google.com with SMTP id y14-20020a0cf14e000000b004afb3c6984bso482648qvl.21 for ; Thu, 29 Sep 2022 08:09:52 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=mime-version:references:message-id:in-reply-to:subject:cc:to:date :from:x-gm-message-state:from:to:cc:subject:date; bh=oYcG1yJE0Jyrk2FH4pQd3FEnx4NKON309HxUVp5IyxY=; b=dr1IbyvGgwXwoJFAhv3T/F45PH9MVcUs2inRU0uXsmjsGg/GJeE8NQAA7up52XoZX2 SdT7e3D8bG5jJEsmIFm8IR/fQA1BTFHhdbaY7HHdnouf3nje3QHPJhXpdV3nO1Qq2KnR YzDuD79wlycino1ZDa+IUk2PF6LXknNLJpkRtqeKDgkW4JNvXjC/VK/zBh9tjDZ0qI3n n9Bcx251zj4CnCBkQiYOotAcaAT0w7BGAdXWMyNlmXzVITflTR34M1nPtP1kTQbwzg9Z 0FeABy+rNsV73SlMEfGEvfi3vLE1NtFHZZi2J1E3SPsyAFdKRg7s/CI1TgJR1w8k4qhV c/8Q== X-Gm-Message-State: ACrzQf2sSxaBYlnPSn9d8s+orurzd6Kb5zhLBP0VShbQGvG3uFZFNkCN KToL4gv/Eh5bsiLbDvIuCmPfDbKj6DVyeKnx4RO2RG+9aZEUDPdtCebfCQApgPEWWweB5qITUxq raTEWC4pzC1zc1fSqQw== X-Received: by 2002:a05:6214:5197:b0:4ad:7a1f:b7e8 with SMTP id kl23-20020a056214519700b004ad7a1fb7e8mr2921468qvb.126.1664464190471; Thu, 29 Sep 2022 08:09:50 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4i3L/1ojLMQSndTDNzcSKQxN1kBFA661ajcDljhnuPwRR/kFJtiBzs6dNI/dzYA4lOE1JICQ== X-Received: by 2002:a05:6214:5197:b0:4ad:7a1f:b7e8 with SMTP id kl23-20020a056214519700b004ad7a1fb7e8mr2921435qvb.126.1664464190179; Thu, 29 Sep 2022 08:09:50 -0700 (PDT) Received: from [192.168.1.130] (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id o13-20020a05620a2a0d00b006ce622e6c96sm6357681qkp.30.2022.09.29.08.09.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Sep 2022 08:09:49 -0700 (PDT) From: Patrick Palka X-Google-Original-From: Patrick Palka Date: Thu, 29 Sep 2022 11:09:48 -0400 (EDT) To: Patrick Palka cc: gcc-patches@gcc.gnu.org, jason@redhat.com, jwakely@redhat.com Subject: Re: [PATCH RFC] c++: streamline process for adding new builtin trait In-Reply-To: <20220929150504.829703-1-ppalka@redhat.com> Message-ID: <67618f45-2183-e4a5-992a-193cb01729eb@idea> References: <20220929150504.829703-1-ppalka@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=US-ASCII X-Spam-Status: No, score=-14.2 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On Thu, 29 Sep 2022, Patrick Palka wrote: > Adding a new builtin trait currently involves some boilerplate (as can > be seen in r13-2956-g9ca147154074a0) of defining corresponding RID_ and > CPTK_ enumerators and adding them to various switch statements across > many files. The exact switch statements we need to change is determined > by whether the proposed trait yields a type or an expression. > > This RFC patch attempts to streamline this process via a centralized > cp-trait.def file for declaring the important parts about a builtin trait > (whether it yields a type or an expression, its code, its spelling and > its arity) and using this file to automate away the switch statement > addition boilerplate. It also converts 9 traits to use this approach > by way of example (we can convert all the traits once the design is > settled). > > After this change, the process of adding a new builtin trait is just > (modulo tests): declare it in cp-trait.def, define its behavior in > finish_trait_type/expr, and handle it in diagnose_trait_expr if it's > an expression-yielding trait (this last step is unfortunate but since > the switch has no default case, we'll at least get a diagnostic if we > forget to do it). Here's an example of adding e.g. __remove_const using this framework: gcc/cp/cp-trait.def | 1 + gcc/cp/semantics.cc | 3 +++ 2 files changed, 4 insertions(+) diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def index 817951f3e42..f6ad16e38cf 100644 --- a/gcc/cp/cp-trait.def +++ b/gcc/cp/cp-trait.def @@ -25,6 +25,7 @@ DEFTRAIT_EXPR (IS_NOTHROW_CONVERTIBLE, "__is_nothrow_convertible", 2) DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1) DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1) DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1) +DEFTRAIT_TYPE (REMOVE_CONST, "__remove_const", 1) #ifdef DEFTRAIT_EXPR_DEFAULTED #undef DEFTRAIT_EXPR diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index 66ee2186a84..eaf608085ae 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -12250,6 +12250,9 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2) if (TYPE_REF_P (type1)) type1 = TREE_TYPE (type1); return cv_unqualified (type1); + case CPTK_REMOVE_CONST: + return cp_build_qualified_type (type1, + cp_type_quals (type1) & ~TYPE_QUAL_CONST); default: gcc_unreachable (); } That's it! > > Does this look like a good approach? > > gcc/c-family/ChangeLog: > > * c-common.cc (c_common_reswords): Use cp/cp-trait.def > to handle C++ traits. > * c-common.h (enum rid): Likewise. > > gcc/cp/ChangeLog: > > * constraint.cc (diagnose_trait_expr): Likewise. > * cp-objcp-common.cc (names_builtin_p): Likewise. > * cp-tree.h (enum cp_trait_kind): Likewise. > * cxx-pretty-print (pp_cxx_trait): Likewise. > * parser.cc (cp_keyword_starts_decl_specifier_p): Likewise. > (cp_parser_primary_expression): Likewise. > (cp_parser_trait): Likewise. > (cp_parser_simple_type_specifier): Likewise. > * cp-trait.def: New file. > --- > gcc/c-family/c-common.cc | 13 +++----- > gcc/c-family/c-common.h | 8 ++--- > gcc/cp/constraint.cc | 7 ++-- > gcc/cp/cp-objcp-common.cc | 13 +++----- > gcc/cp/cp-trait.def | 37 +++++++++++++++++++++ > gcc/cp/cp-tree.h | 13 +++----- > gcc/cp/cxx-pretty-print.cc | 31 +++--------------- > gcc/cp/parser.cc | 67 ++++++++++++-------------------------- > 8 files changed, 82 insertions(+), 107 deletions(-) > create mode 100644 gcc/cp/cp-trait.def > > diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc > index 6e0af863a49..1b2fd37c583 100644 > --- a/gcc/c-family/c-common.cc > +++ b/gcc/c-family/c-common.cc > @@ -537,19 +537,14 @@ const struct c_common_resword c_common_reswords[] = > { "volatile", RID_VOLATILE, 0 }, > { "wchar_t", RID_WCHAR, D_CXXONLY }, > { "while", RID_WHILE, 0 }, > - { "__is_assignable", RID_IS_ASSIGNABLE, D_CXXONLY }, > - { "__is_constructible", RID_IS_CONSTRUCTIBLE, D_CXXONLY }, > - { "__is_nothrow_assignable", RID_IS_NOTHROW_ASSIGNABLE, D_CXXONLY }, > - { "__is_nothrow_constructible", RID_IS_NOTHROW_CONSTRUCTIBLE, D_CXXONLY }, > - { "__is_convertible", RID_IS_CONVERTIBLE, D_CXXONLY }, > - { "__is_nothrow_convertible", RID_IS_NOTHROW_CONVERTIBLE, D_CXXONLY }, > { "__reference_constructs_from_temporary", RID_REF_CONSTRUCTS_FROM_TEMPORARY, > D_CXXONLY }, > { "__reference_converts_from_temporary", RID_REF_CONVERTS_FROM_TEMPORARY, > D_CXXONLY }, > - { "__remove_cv", RID_REMOVE_CV, D_CXXONLY }, > - { "__remove_reference", RID_REMOVE_REFERENCE, D_CXXONLY }, > - { "__remove_cvref", RID_REMOVE_CVREF, D_CXXONLY }, > +#define DEFTRAIT(TCC, CODE, NAME, ARITY) \ > + { NAME, RID_##CODE, D_CXXONLY }, > +#include "cp/cp-trait.def" > +#undef DEFTRAIT > > /* C++ transactional memory. */ > { "synchronized", RID_SYNCHRONIZED, D_CXX_OBJC | D_TRANSMEM }, > diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h > index d5c98d306ce..b306815c23b 100644 > --- a/gcc/c-family/c-common.h > +++ b/gcc/c-family/c-common.h > @@ -182,12 +182,12 @@ enum rid > RID_IS_TRIVIALLY_ASSIGNABLE, RID_IS_TRIVIALLY_CONSTRUCTIBLE, > RID_IS_TRIVIALLY_COPYABLE, > RID_IS_UNION, RID_UNDERLYING_TYPE, > - RID_IS_ASSIGNABLE, RID_IS_CONSTRUCTIBLE, > - RID_IS_NOTHROW_ASSIGNABLE, RID_IS_NOTHROW_CONSTRUCTIBLE, > - RID_IS_CONVERTIBLE, RID_IS_NOTHROW_CONVERTIBLE, > RID_REF_CONSTRUCTS_FROM_TEMPORARY, > RID_REF_CONVERTS_FROM_TEMPORARY, > - RID_REMOVE_CV, RID_REMOVE_REFERENCE, RID_REMOVE_CVREF, > +#define DEFTRAIT(TCC, CODE, NAME, ARITY) \ > + RID_##CODE, > +#include "cp/cp-trait.def" > +#undef DEFTRAIT > > /* C++11 */ > RID_CONSTEXPR, RID_DECLTYPE, RID_NOEXCEPT, RID_NULLPTR, RID_STATIC_ASSERT, > diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc > index ca73aff3f38..9323bb091e1 100644 > --- a/gcc/cp/constraint.cc > +++ b/gcc/cp/constraint.cc > @@ -3714,9 +3714,10 @@ diagnose_trait_expr (tree expr, tree args) > case CPTK_BASES: > case CPTK_DIRECT_BASES: > case CPTK_UNDERLYING_TYPE: > - case CPTK_REMOVE_CV: > - case CPTK_REMOVE_REFERENCE: > - case CPTK_REMOVE_CVREF: > +#define DEFTRAIT_TYPE(CODE, NAME, ARITY) \ > + case CPTK_##CODE: > +#include "cp/cp-trait.def" > +#undef DEFTRAIT_TYPE > /* We shouldn't see these non-expression traits. */ > gcc_unreachable (); > /* We deliberately omit the default case so that when adding a new > diff --git a/gcc/cp/cp-objcp-common.cc b/gcc/cp/cp-objcp-common.cc > index 2d3f206b530..bc397a5447f 100644 > --- a/gcc/cp/cp-objcp-common.cc > +++ b/gcc/cp/cp-objcp-common.cc > @@ -458,18 +458,13 @@ names_builtin_p (const char *name) > case RID_IS_TRIVIALLY_CONSTRUCTIBLE: > case RID_IS_TRIVIALLY_COPYABLE: > case RID_IS_UNION: > - case RID_IS_ASSIGNABLE: > - case RID_IS_CONSTRUCTIBLE: > - case RID_IS_NOTHROW_ASSIGNABLE: > - case RID_IS_NOTHROW_CONSTRUCTIBLE: > case RID_UNDERLYING_TYPE: > - case RID_IS_CONVERTIBLE: > - case RID_IS_NOTHROW_CONVERTIBLE: > case RID_REF_CONSTRUCTS_FROM_TEMPORARY: > case RID_REF_CONVERTS_FROM_TEMPORARY: > - case RID_REMOVE_CV: > - case RID_REMOVE_REFERENCE: > - case RID_REMOVE_CVREF: > +#define DEFTRAIT(TCC, CODE, NAME, ARITY) \ > + case RID_##CODE: > +#include "cp/cp-trait.def" > +#undef DEFTRAIT > return true; > default: > break; > diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def > new file mode 100644 > index 00000000000..817951f3e42 > --- /dev/null > +++ b/gcc/cp/cp-trait.def > @@ -0,0 +1,37 @@ > +#ifdef DEFTRAIT > +#define DEFTRAIT_EXPR(CODE, NAME, ARITY) DEFTRAIT(tcc_expression, CODE, NAME, ARITY) > +#define DEFTRAIT_TYPE(CODE, NAME, ARITY) DEFTRAIT(tcc_type, CODE, NAME, ARITY) > +#define DEFTRAIT_EXPR_DEFAULTED > +#define DEFTRAIT_TYPE_DEFAULTED > +#endif > + > +#ifndef DEFTRAIT_EXPR > +#define DEFTRAIT_EXPR(CODE, NAME, ARITY) > +#define DEFTRAIT_EXPR_DEFAULTED > +#endif > + > +#ifndef DEFTRAIT_TYPE > +#define DEFTRAIT_TYPE(CODE, NAME, ARITY) > +#define DEFTRAIT_TYPE_DEFAULTED > +#endif > + > +DEFTRAIT_EXPR (IS_ASSIGNABLE, "__is_assignable", 2) > +DEFTRAIT_EXPR (IS_NOTHROW_ASSIGNABLE, "__is_nothrow_assignable", 2) > +DEFTRAIT_EXPR (IS_CONSTRUCTIBLE, "__is_constructible", -1) > +DEFTRAIT_EXPR (IS_NOTHROW_CONSTRUCTIBLE, "__is_nothrow_constructible", -1) > +DEFTRAIT_EXPR (IS_CONVERTIBLE, "__is_convertible", 2) > +DEFTRAIT_EXPR (IS_NOTHROW_CONVERTIBLE, "__is_nothrow_convertible", 2) > + > +DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1) > +DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1) > +DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1) > + > +#ifdef DEFTRAIT_EXPR_DEFAULTED > +#undef DEFTRAIT_EXPR > +#undef DEFTRAIT_EXPR_DEFAULTED > +#endif > + > +#ifdef DEFTRAIT_TYPE_DEFAULTED > +#undef DEFTRAIT_TYPE > +#undef DEFTRAIT_TYPE_DEFAULTED > +#endif > diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h > index 3cbcdf726ca..8c5a85ab5fe 100644 > --- a/gcc/cp/cp-tree.h > +++ b/gcc/cp/cp-tree.h > @@ -1405,17 +1405,12 @@ enum cp_trait_kind > CPTK_IS_TRIVIALLY_COPYABLE, > CPTK_IS_UNION, > CPTK_UNDERLYING_TYPE, > - CPTK_IS_ASSIGNABLE, > - CPTK_IS_CONSTRUCTIBLE, > - CPTK_IS_NOTHROW_ASSIGNABLE, > - CPTK_IS_NOTHROW_CONSTRUCTIBLE, > - CPTK_IS_CONVERTIBLE, > - CPTK_IS_NOTHROW_CONVERTIBLE, > CPTK_REF_CONSTRUCTS_FROM_TEMPORARY, > CPTK_REF_CONVERTS_FROM_TEMPORARY, > - CPTK_REMOVE_CV, > - CPTK_REMOVE_REFERENCE, > - CPTK_REMOVE_CVREF, > +#define DEFTRAIT(TCC, CODE, NAME, ARITY) \ > + CPTK_##CODE, > +#include "cp/cp-trait.def" > +#undef DEFTRAIT > }; > > /* The types that we are processing. */ > diff --git a/gcc/cp/cxx-pretty-print.cc b/gcc/cp/cxx-pretty-print.cc > index b91615439e4..a2ddbcb899a 100644 > --- a/gcc/cp/cxx-pretty-print.cc > +++ b/gcc/cp/cxx-pretty-print.cc > @@ -2701,24 +2701,6 @@ pp_cxx_trait (cxx_pretty_printer *pp, tree t) > case CPTK_IS_LITERAL_TYPE: > pp_cxx_ws_string (pp, "__is_literal_type"); > break; > - case CPTK_IS_ASSIGNABLE: > - pp_cxx_ws_string (pp, "__is_assignable"); > - break; > - case CPTK_IS_CONSTRUCTIBLE: > - pp_cxx_ws_string (pp, "__is_constructible"); > - break; > - case CPTK_IS_NOTHROW_ASSIGNABLE: > - pp_cxx_ws_string (pp, "__is_nothrow_assignable"); > - break; > - case CPTK_IS_NOTHROW_CONSTRUCTIBLE: > - pp_cxx_ws_string (pp, "__is_nothrow_constructible"); > - break; > - case CPTK_IS_CONVERTIBLE: > - pp_cxx_ws_string (pp, "__is_convertible"); > - break; > - case CPTK_IS_NOTHROW_CONVERTIBLE: > - pp_cxx_ws_string (pp, "__is_nothrow_convertible"); > - break; > case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY: > pp_cxx_ws_string (pp, "__reference_constructs_from_temporary"); > break; > @@ -2728,15 +2710,12 @@ pp_cxx_trait (cxx_pretty_printer *pp, tree t) > case CPTK_UNDERLYING_TYPE: > pp_cxx_ws_string (pp, "__underlying_type"); > break; > - case CPTK_REMOVE_CV: > - pp_cxx_ws_string (pp, "__remove_cv"); > - break; > - case CPTK_REMOVE_REFERENCE: > - pp_cxx_ws_string (pp, "__remove_reference"); > - break; > - case CPTK_REMOVE_CVREF: > - pp_cxx_ws_string (pp, "__remove_cvref"); > +#define DEFTRAIT(TCC, CODE, NAME, ARITY) \ > + case CPTK_##CODE: \ > + pp_cxx_ws_string (pp, NAME); \ > break; > +#include "cp/cp-trait.def" > +#undef DEFTRAIT > default: > gcc_unreachable (); > } > diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc > index d592d783250..138892716b4 100644 > --- a/gcc/cp/parser.cc > +++ b/gcc/cp/parser.cc > @@ -1147,9 +1147,10 @@ cp_keyword_starts_decl_specifier_p (enum rid keyword) > /* C++11 extensions. */ > case RID_DECLTYPE: > case RID_UNDERLYING_TYPE: > - case RID_REMOVE_CV: > - case RID_REMOVE_REFERENCE: > - case RID_REMOVE_CVREF: > +#define DEFTRAIT_TYPE(CODE, NAME, ARITY) \ > + case RID_##CODE: > +#include "cp/cp-trait.def" > +#undef DEFTRAIT_TYPE > case RID_CONSTEXPR: > /* C++20 extensions. */ > case RID_CONSTINIT: > @@ -5923,14 +5924,12 @@ cp_parser_primary_expression (cp_parser *parser, > case RID_IS_TRIVIALLY_CONSTRUCTIBLE: > case RID_IS_TRIVIALLY_COPYABLE: > case RID_IS_UNION: > - case RID_IS_ASSIGNABLE: > - case RID_IS_CONSTRUCTIBLE: > - case RID_IS_NOTHROW_ASSIGNABLE: > - case RID_IS_NOTHROW_CONSTRUCTIBLE: > - case RID_IS_CONVERTIBLE: > - case RID_IS_NOTHROW_CONVERTIBLE: > case RID_REF_CONSTRUCTS_FROM_TEMPORARY: > case RID_REF_CONVERTS_FROM_TEMPORARY: > +#define DEFTRAIT_EXPR(CODE, NAME, ARITY) \ > + case RID_##CODE: > +#include "cp/cp-trait.def" > +#undef DEFTRAIT_EXPR > return cp_parser_trait (parser, token->keyword); > > // C++ concepts > @@ -10998,30 +10997,6 @@ cp_parser_trait (cp_parser* parser, enum rid keyword) > case RID_DIRECT_BASES: > kind = CPTK_DIRECT_BASES; > break; > - case RID_IS_ASSIGNABLE: > - kind = CPTK_IS_ASSIGNABLE; > - binary = true; > - break; > - case RID_IS_CONSTRUCTIBLE: > - kind = CPTK_IS_CONSTRUCTIBLE; > - variadic = true; > - break; > - case RID_IS_NOTHROW_ASSIGNABLE: > - kind = CPTK_IS_NOTHROW_ASSIGNABLE; > - binary = true; > - break; > - case RID_IS_NOTHROW_CONSTRUCTIBLE: > - kind = CPTK_IS_NOTHROW_CONSTRUCTIBLE; > - variadic = true; > - break; > - case RID_IS_CONVERTIBLE: > - kind = CPTK_IS_CONVERTIBLE; > - binary = true; > - break; > - case RID_IS_NOTHROW_CONVERTIBLE: > - kind = CPTK_IS_NOTHROW_CONVERTIBLE; > - binary = true; > - break; > case RID_REF_CONSTRUCTS_FROM_TEMPORARY: > kind = CPTK_REF_CONSTRUCTS_FROM_TEMPORARY; > binary = true; > @@ -11030,18 +11005,15 @@ cp_parser_trait (cp_parser* parser, enum rid keyword) > kind = CPTK_REF_CONVERTS_FROM_TEMPORARY; > binary = true; > break; > - case RID_REMOVE_CV: > - kind = CPTK_REMOVE_CV; > - type = true; > - break; > - case RID_REMOVE_REFERENCE: > - kind = CPTK_REMOVE_REFERENCE; > - type = true; > - break; > - case RID_REMOVE_CVREF: > - kind = CPTK_REMOVE_CVREF; > - type = true; > +#define DEFTRAIT(TCC, CODE, NAME, ARITY) \ > + case RID_##CODE: \ > + type = (TCC == tcc_type); \ > + kind = CPTK_##CODE; \ > + binary = (ARITY == 2); \ > + variadic = (ARITY == -1); \ > break; > +#include "cp/cp-trait.def" > +#undef DEFTRAIT > default: > gcc_unreachable (); > } > @@ -19882,9 +19854,10 @@ cp_parser_simple_type_specifier (cp_parser* parser, > return type; > > case RID_UNDERLYING_TYPE: > - case RID_REMOVE_CV: > - case RID_REMOVE_REFERENCE: > - case RID_REMOVE_CVREF: > +#define DEFTRAIT_TYPE(CODE, NAME, ARITY) \ > + case RID_##CODE: > +#include "cp/cp-trait.def" > +#undef DEFTRAIT_TYPE > type = cp_parser_trait (parser, token->keyword); > if (decl_specs) > cp_parser_set_decl_spec_type (decl_specs, type, > -- > 2.38.0.rc2 > >