From patchwork Tue Oct 17 11:27:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ken Matsui X-Patchwork-Id: 154089 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:2908:b0:403:3b70:6f57 with SMTP id ib8csp4067542vqb; Tue, 17 Oct 2023 04:34:22 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGUKwHdHxZiqouALjOvkRzGZnPrLT3sdRDQTxVCGjj05c2tR7C+CndZ/WjyKCZzQVoD5bUF X-Received: by 2002:a05:620a:a18:b0:774:1c49:2d72 with SMTP id i24-20020a05620a0a1800b007741c492d72mr1746642qka.76.1697542462441; Tue, 17 Oct 2023 04:34:22 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1697542462; cv=pass; d=google.com; s=arc-20160816; b=YKej9p+37m1Rb85d0b0RqwSd4qZKjZWTsIuEOZ+z2LStTSQ+wKtoA8cTE9qzyW8IZ/ Kt46CVdT45G6swjFit35Qt85E0mPmKKFWfCcFXPGZo0jOgZpZdPPszariXDe5MTxYfMd XoEe7N+eersb6va7emEvHn5TyLAziS1sPPq/WwwPVLwSqCFY1h3BwNBxmo2hfhcRqYcP hWE9dQKGgiKtgwF4zmA2JOrvE/8KFN4cP9hVLSLv6ht2IceRsEsQEcpDq02w6VZy56hO mUTQv4CN6ZLZSNPr7sgRkPd+KReb016UTJ3QRZouIHvzyJLFyqBpdJ4KmuoQuDtVQlJZ ECGw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:arc-filter:dmarc-filter:delivered-to:dkim-signature :dkim-filter; bh=XzQ6JaLHSfbRkzy9sMHe6fCo10/gBbC7RRRFQ9rcaoo=; fh=gWaPAOlkBn4NfXWp5OzPJhAUieocQfCW2y/drQDuE0I=; b=b6AhHGazgBq9UTqR0yPURDlBU6vJvjP/hF+wDdJq9q3dFymhnxEXlStVT2COu/iXZN S3kJBL/H+Rr9njYIpxhprdkEOStmzdbdu7pZwNftnNJfvyY5E/99uTSmAi8JIjRqK20s vxxdS0VOEJj6G9bGh2vE8kH+IgN3V3rx0aBVIuO7qRktDYLKZBewfK4Pd6OvTfrqyR6i CxxDypgatf0H/TIVChhIYszJ+aLq2NI8CwZqeYzo278LH9DOad4yWi17jxqq3QBG+Pnh 3oRcAKdXF/yo8L3nQPJPmikHoaz6vfr+iISYCG+9XiT0H3nxIJhsbsn+MSbWg3KKk6Fx XHww== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=LFQ27aVF; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id g3-20020a05620a218300b00774382daec1si904754qka.536.2023.10.17.04.34.22 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 17 Oct 2023 04:34:22 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=LFQ27aVF; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2CB9F3858418 for ; Tue, 17 Oct 2023 11:34:22 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2CB9F3858418 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1697542462; bh=XzQ6JaLHSfbRkzy9sMHe6fCo10/gBbC7RRRFQ9rcaoo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=LFQ27aVFo4Quh31QT/TqlxMAHpNsR1Rq96BLEPFX7Au4vA1/IpSVBGfbRks9aiXGS GeQlFAIrDm9IIQoaVjQ/d0fAhzaNJiEJBlKo52nEwUOIKZilkoKT1HNUAJIBxKPaSK LZMNV0TcemnBBFXvf28j8pMv9cwtIhB6oVC+vBMc= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0a-00641c01.pphosted.com (mx0a-00641c01.pphosted.com [205.220.165.146]) by sourceware.org (Postfix) with ESMTPS id 0EC233858C52; Tue, 17 Oct 2023 11:33:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0EC233858C52 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=gcc.gnu.org Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=gcc.gnu.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 0EC233858C52 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=205.220.165.146 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1697542419; cv=none; b=qPUKp/78+b7YwhWi0HQyOJBHNtiaij59ZawczjIkR8MILLxahe8Pug9DLFhFGnk9P3LJMivwkvMKRO9WT7MH1d5ZXE4X8WyMu4hrAQar4shSjKUB7p2l5qfCf/rjlxVwF2eJMtRhweCbo14jerQLJwEf4/A4bkmh03SKQniOGpQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1697542419; c=relaxed/simple; bh=a9doAL8xaU26Jq7Wrb8cklSUyV+ncv7L4Jw4Kidz8BU=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=I61tDBXuo+MYLKTNT9n5ed13202Sc0DrkIKPs7jPBQZ6P5z32sVFc5TGfnxhpASGy5eZxhhF5eMIjTm/ugGGn6eEc4cniOvkdMDVYZG0OzND72+14KvTwRT49zqCteRMmev1nIlSsn6x/6qM8ynZz3BurePuWtEEXTcF0NTP2BM= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from pps.filterd (m0247475.ppops.net [127.0.0.1]) by mx0a-00641c01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 39HBTqDM023863; Tue, 17 Oct 2023 11:33:35 GMT Received: from mxout26.s.uw.edu (mxout26.s.uw.edu [140.142.234.176]) by mx0a-00641c01.pphosted.com (PPS) with ESMTPS id 3tseh6tra5-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 17 Oct 2023 11:33:35 +0000 Received: from smtp.washington.edu (smtp.washington.edu [140.142.234.157]) by mxout26.s.uw.edu (8.14.4+UW20.07/8.14.4+UW22.04) with ESMTP id 39HBXIFF011883 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 17 Oct 2023 04:33:18 -0700 X-Auth-Received: from kmatsui-ThinkPad-X1-Carbon-Gen-9.dhcp4.washington.edu ([10.19.18.191]) (authenticated authid=kmatsui) by smtp.washington.edu (8.16.1+UW21.10/8.14.4+UW19.10) with ESMTPSA id 39HBWiME001840 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 17 Oct 2023 04:33:18 -0700 X-UW-Orig-Sender: kmatsui@smtp.washington.edu From: Ken Matsui To: gcc-patches@gcc.gnu.org Cc: libstdc++@gcc.gnu.org, Ken Matsui , Patrick Palka Subject: [PATCH v21 01/30] c-family, c++: Look up built-in traits via identifier node Date: Tue, 17 Oct 2023 04:27:32 -0700 Message-ID: <20231017113242.664523-2-kmatsui@gcc.gnu.org> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20231017113242.664523-1-kmatsui@gcc.gnu.org> References: <20231016001227.2717180-1-kmatsui@gcc.gnu.org> <20231017113242.664523-1-kmatsui@gcc.gnu.org> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: PiYVRsMQrHhSCtU2HLGHFD3yy0qsqo0l X-Proofpoint-GUID: PiYVRsMQrHhSCtU2HLGHFD3yy0qsqo0l X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.980,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-10-16_13,2023-10-17_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 bulkscore=0 priorityscore=1501 clxscore=1034 mlxscore=0 mlxlogscore=999 malwarescore=0 lowpriorityscore=0 spamscore=0 adultscore=0 suspectscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2309180000 definitions=main-2310170097 X-Spam-Status: No, score=-13.1 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_NEUTRAL, 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 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1779868979596920251 X-GMAIL-MSGID: 1780002284860666338 Since RID_MAX soon reaches 255 and all built-in traits are used approximately once in a C++ translation unit, this patch removes all RID values for built-in traits and uses the identifier node to look up the specific trait. Rather than holding traits as keywords, we set all trait identifiers as cik_trait, which is a new cp_identifier_kind. As cik_reserved_for_udlit was unused and cp_identifier_kind is 3 bits, we replaced the unused field with the new cik_trait. Also, the later patch handles a subsequent token to the built-in identifier so that we accept the use of non-function-like built-in trait identifiers. gcc/c-family/ChangeLog: * c-common.cc (c_common_reswords): Remove all mappings of built-in traits. * c-common.h (enum rid): Remove all RID values for built-in traits. gcc/cp/ChangeLog: * cp-objcp-common.cc (names_builtin_p): Remove all RID value cases for built-in traits. Check for built-in traits via the new cik_trait kind. * cp-tree.h (enum cp_trait_kind): Set its underlying type to addr_space_t. (struct cp_trait): New struct to hold trait information. (cp_traits): New array to hold a mapping to all traits. (num_cp_traits): New variable to hold the size of cp_traits. (cik_reserved_for_udlit): Rename to ... (cik_trait): ... this. (IDENTIFIER_ANY_OP_P): Exclude cik_trait. (IDENTIFIER_TRAIT_P): New macro to detect cik_trait. * lex.cc (init_cp_traits): New function to set cik_trait and IDENTIFIER_CP_INDEX for all built-in trait identifiers. (cxx_init): Call init_cp_traits function. * parser.cc (cp_traits): Define its values, declared in cp-tree.h. (num_cp_traits): Define its value, declared in cp-tree.h. (cp_lexer_lookup_trait): New function to look up a built-in trait by IDENTIFIER_CP_INDEX. (cp_lexer_lookup_trait_expr): Likewise, look up an expression-yielding built-in trait. (cp_lexer_lookup_trait_type): Likewise, look up a type-yielding built-in trait. (cp_keyword_starts_decl_specifier_p): Remove all RID value cases for built-in traits. (cp_lexer_next_token_is_decl_specifier_keyword): Handle type-yielding built-in traits. (cp_parser_primary_expression): Remove all RID value cases for built-in traits. Handle expression-yielding built-in traits. (cp_parser_trait): Handle cp_trait instead of enum rid. (cp_parser_simple_type_specifier): Remove all RID value cases for built-in traits. Handle type-yielding built-in traits. Co-authored-by: Patrick Palka Signed-off-by: Ken Matsui --- gcc/c-family/c-common.cc | 7 --- gcc/c-family/c-common.h | 5 -- gcc/cp/cp-objcp-common.cc | 8 +-- gcc/cp/cp-tree.h | 33 ++++++++--- gcc/cp/lex.cc | 21 +++++++ gcc/cp/parser.cc | 120 +++++++++++++++++++++++++------------- 6 files changed, 129 insertions(+), 65 deletions(-) diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc index f044db5b797..21fd333ef57 100644 --- a/gcc/c-family/c-common.cc +++ b/gcc/c-family/c-common.cc @@ -508,13 +508,6 @@ const struct c_common_resword c_common_reswords[] = { "wchar_t", RID_WCHAR, D_CXXONLY }, { "while", RID_WHILE, 0 }, -#define DEFTRAIT(TCC, CODE, NAME, ARITY) \ - { NAME, RID_##CODE, D_CXXONLY }, -#include "cp/cp-trait.def" -#undef DEFTRAIT - /* An alias for __is_same. */ - { "__is_same_as", RID_IS_SAME, D_CXXONLY }, - /* C++ transactional memory. */ { "synchronized", RID_SYNCHRONIZED, D_CXX_OBJC | D_TRANSMEM }, { "atomic_noexcept", RID_ATOMIC_NOEXCEPT, D_CXXONLY | D_TRANSMEM }, diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 1fdba7ef3ea..051a442e0f4 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -168,11 +168,6 @@ enum rid RID_BUILTIN_LAUNDER, RID_BUILTIN_BIT_CAST, -#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/cp-objcp-common.cc b/gcc/cp/cp-objcp-common.cc index 93b027b80ce..b1adacfec07 100644 --- a/gcc/cp/cp-objcp-common.cc +++ b/gcc/cp/cp-objcp-common.cc @@ -421,6 +421,10 @@ names_builtin_p (const char *name) } } + /* Check for built-in traits. */ + if (IDENTIFIER_TRAIT_P (id)) + return true; + /* Also detect common reserved C++ words that aren't strictly built-in functions. */ switch (C_RID_CODE (id)) @@ -434,10 +438,6 @@ names_builtin_p (const char *name) case RID_BUILTIN_ASSOC_BARRIER: case RID_BUILTIN_BIT_CAST: case RID_OFFSETOF: -#define DEFTRAIT(TCC, CODE, NAME, ARITY) \ - case RID_##CODE: -#include "cp-trait.def" -#undef DEFTRAIT return true; default: break; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index efcd2de54e5..81a5c06a574 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1226,7 +1226,7 @@ enum cp_identifier_kind { cik_simple_op = 4, /* Non-assignment operator name. */ cik_assign_op = 5, /* An assignment operator name. */ cik_conv_op = 6, /* Conversion operator name. */ - cik_reserved_for_udlit = 7, /* Not yet in use */ + cik_trait = 7, /* Built-in trait name. */ cik_max }; @@ -1271,9 +1271,9 @@ enum cp_identifier_kind { & IDENTIFIER_KIND_BIT_0 (NODE)) /* True if this identifier is for any operator name (including - conversions). Value 4, 5, 6 or 7. */ + conversions). Value 4, 5, or 6. */ #define IDENTIFIER_ANY_OP_P(NODE) \ - (IDENTIFIER_KIND_BIT_2 (NODE)) + (IDENTIFIER_KIND_BIT_2 (NODE) && !IDENTIFIER_TRAIT_P (NODE)) /* True if this identifier is for an overloaded operator. Values 4, 5. */ #define IDENTIFIER_OVL_OP_P(NODE) \ @@ -1286,12 +1286,18 @@ enum cp_identifier_kind { & IDENTIFIER_KIND_BIT_0 (NODE)) /* True if this identifier is the name of a type-conversion - operator. Value 7. */ + operator. Value 6. */ #define IDENTIFIER_CONV_OP_P(NODE) \ (IDENTIFIER_ANY_OP_P (NODE) \ & IDENTIFIER_KIND_BIT_1 (NODE) \ & (!IDENTIFIER_KIND_BIT_0 (NODE))) +/* True if this identifier is the name of a built-in trait. */ +#define IDENTIFIER_TRAIT_P(NODE) \ + (IDENTIFIER_KIND_BIT_0 (NODE) \ + && IDENTIFIER_KIND_BIT_1 (NODE) \ + && IDENTIFIER_KIND_BIT_2 (NODE)) + /* True if this identifier is a new or delete operator. */ #define IDENTIFIER_NEWDEL_OP_P(NODE) \ (IDENTIFIER_OVL_OP_P (NODE) \ @@ -1375,16 +1381,27 @@ struct GTY (()) tree_argument_pack_select { int index; }; -/* The different kinds of traits that we encounter. */ - -enum cp_trait_kind -{ +/* The different kinds of traits that we encounter. The size is limited to + addr_space_t since a trait is looked up by IDENTIFIER_CP_INDEX. */ +enum cp_trait_kind : addr_space_t { #define DEFTRAIT(TCC, CODE, NAME, ARITY) \ CPTK_##CODE, #include "cp-trait.def" #undef DEFTRAIT }; +/* The trait type. */ +struct cp_trait { + const char *name; + cp_trait_kind kind; + short arity; + bool type; +}; + +/* The trait table. */ +extern const struct cp_trait cp_traits[]; +extern const addr_space_t num_cp_traits; + /* The types that we are processing. */ #define TRAIT_EXPR_TYPE1(NODE) \ (((struct tree_trait_expr *)TRAIT_EXPR_CHECK (NODE))->type1) diff --git a/gcc/cp/lex.cc b/gcc/cp/lex.cc index 64bcfb18196..872ca970545 100644 --- a/gcc/cp/lex.cc +++ b/gcc/cp/lex.cc @@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see #include "langhooks.h" static int interface_strcmp (const char *); +static void init_cp_traits (void); static void init_cp_pragma (void); static tree parse_strconst_pragma (const char *, int); @@ -283,6 +284,25 @@ init_reswords (void) } } +/* Initialize the C++ traits. */ +static void +init_cp_traits (void) +{ + tree id; + + for (unsigned int i = 0; i < num_cp_traits; ++i) + { + id = get_identifier (cp_traits[i].name); + IDENTIFIER_CP_INDEX (id) = cp_traits[i].kind; + set_identifier_kind (id, cik_trait); + } + + /* An alias for __is_same. */ + id = get_identifier ("__is_same_as"); + IDENTIFIER_CP_INDEX (id) = CPTK_IS_SAME; + set_identifier_kind (id, cik_trait); +} + static void init_cp_pragma (void) { @@ -324,6 +344,7 @@ cxx_init (void) input_location = BUILTINS_LOCATION; init_reswords (); + init_cp_traits (); init_tree (); init_cp_semantics (); init_operators (); diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 59b9852895e..ece238c2072 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -246,6 +246,12 @@ static void cp_lexer_start_debugging (cp_lexer *) ATTRIBUTE_UNUSED; static void cp_lexer_stop_debugging (cp_lexer *) ATTRIBUTE_UNUSED; +static const cp_trait *cp_lexer_lookup_trait + (const cp_token *); +static const cp_trait *cp_lexer_lookup_trait_expr + (const cp_token *); +static const cp_trait *cp_lexer_lookup_trait_type + (const cp_token *); static cp_token_cache *cp_token_cache_new (cp_token *, cp_token *); @@ -279,6 +285,21 @@ static FILE *cp_lexer_debug_stream; sizeof, typeof, or alignof. */ int cp_unevaluated_operand; +/* The trait table, declared in cp-tree.h. */ +const cp_trait cp_traits[] = +{ +#define DEFTRAIT(TCC, CODE, NAME, ARITY) \ + { NAME, CPTK_##CODE, ARITY, (TCC == tcc_type) }, +#include "cp-trait.def" +#undef DEFTRAIT +}; +const addr_space_t num_cp_traits = ARRAY_SIZE (cp_traits); + +/* The trait table cannot have more than 255 (addr_space_t) entries since + the index is retrieved through IDENTIFIER_CP_INDEX. */ +static_assert(num_cp_traits <= 255, + "cp_traits array cannot have more than 255 entries"); + /* Dump up to NUM tokens in BUFFER to FILE starting with token START_TOKEN. If START_TOKEN is NULL, the dump starts with the first token in BUFFER. If NUM is 0, dump all the tokens. If @@ -1167,12 +1188,6 @@ cp_keyword_starts_decl_specifier_p (enum rid keyword) case RID_CONSTEVAL: return true; -#define DEFTRAIT_TYPE(CODE, NAME, ARITY) \ - case RID_##CODE: -#include "cp-trait.def" -#undef DEFTRAIT_TYPE - return true; - default: if (keyword >= RID_FIRST_INT_N && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS @@ -1182,6 +1197,44 @@ cp_keyword_starts_decl_specifier_p (enum rid keyword) } } +/* Look ups the corresponding built-in trait if a given token is + a built-in trait. Otherwise, returns nullptr. */ + +static const cp_trait * +cp_lexer_lookup_trait (const cp_token *token) +{ + if (token->type == CPP_NAME && IDENTIFIER_TRAIT_P (token->u.value)) + return &cp_traits[IDENTIFIER_CP_INDEX (token->u.value)]; + + return nullptr; +} + +/* Similarly, but only if the token is an expression-yielding + built-in trait. */ + +static const cp_trait * +cp_lexer_lookup_trait_expr (const cp_token *token) +{ + const cp_trait *trait = cp_lexer_lookup_trait (token); + if (trait && !trait->type) + return trait; + + return nullptr; +} + +/* Similarly, but only if the token is a type-yielding + built-in trait. */ + +static const cp_trait * +cp_lexer_lookup_trait_type (const cp_token *token) +{ + const cp_trait *trait = cp_lexer_lookup_trait (token); + if (trait && trait->type) + return trait; + + return nullptr; +} + /* Return true if the next token is a keyword for a decl-specifier. */ static bool @@ -1190,6 +1243,8 @@ cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer *lexer) cp_token *token; token = cp_lexer_peek_token (lexer); + if (cp_lexer_lookup_trait_type (token)) + return true; return cp_keyword_starts_decl_specifier_p (token->keyword); } @@ -2854,7 +2909,7 @@ static void cp_parser_late_parsing_default_args static tree cp_parser_sizeof_operand (cp_parser *, enum rid); static cp_expr cp_parser_trait - (cp_parser *, enum rid); + (cp_parser *, const cp_trait *); static bool cp_parser_declares_only_class_p (cp_parser *); static void cp_parser_set_storage_class @@ -6029,12 +6084,6 @@ cp_parser_primary_expression (cp_parser *parser, case RID_OFFSETOF: return cp_parser_builtin_offsetof (parser); -#define DEFTRAIT_EXPR(CODE, NAME, ARITY) \ - case RID_##CODE: -#include "cp-trait.def" -#undef DEFTRAIT_EXPR - return cp_parser_trait (parser, token->keyword); - // C++ concepts case RID_REQUIRES: return cp_parser_requires_expression (parser); @@ -6073,6 +6122,9 @@ cp_parser_primary_expression (cp_parser *parser, `::' as the beginning of a qualified-id, or the "operator" keyword. */ case CPP_NAME: + if (const cp_trait* trait = cp_lexer_lookup_trait_expr (token)) + return cp_parser_trait (parser, trait); + /* FALLTHRU */ case CPP_SCOPE: case CPP_TEMPLATE_ID: case CPP_NESTED_NAME_SPECIFIER: @@ -11041,28 +11093,13 @@ cp_parser_builtin_offsetof (cp_parser *parser) /* Parse a builtin trait expression or type. */ static cp_expr -cp_parser_trait (cp_parser* parser, enum rid keyword) +cp_parser_trait (cp_parser* parser, const cp_trait* trait) { - cp_trait_kind kind; + const cp_trait_kind kind = trait->kind; tree type1, type2 = NULL_TREE; - bool binary = false; - bool variadic = false; - bool type = false; - - switch (keyword) - { -#define DEFTRAIT(TCC, CODE, NAME, ARITY) \ - case RID_##CODE: \ - kind = CPTK_##CODE; \ - binary = (ARITY == 2); \ - variadic = (ARITY == -1); \ - type = (TCC == tcc_type); \ - break; -#include "cp-trait.def" -#undef DEFTRAIT - default: - gcc_unreachable (); - } + const bool binary = (trait->arity == 2); + const bool variadic = (trait->arity == -1); + const bool type = trait->type; /* Get location of initial token. */ location_t start_loc = cp_lexer_peek_token (parser->lexer)->location; @@ -20089,20 +20126,21 @@ cp_parser_simple_type_specifier (cp_parser* parser, return type; -#define DEFTRAIT_TYPE(CODE, NAME, ARITY) \ - case RID_##CODE: -#include "cp-trait.def" -#undef DEFTRAIT_TYPE - type = cp_parser_trait (parser, token->keyword); + default: + break; + } + + /* If token is a type-yielding built-in traits, parse it. */ + const cp_trait* trait = cp_lexer_lookup_trait_type (token); + if (trait) + { + type = cp_parser_trait (parser, trait); if (decl_specs) cp_parser_set_decl_spec_type (decl_specs, type, token, /*type_definition_p=*/false); return type; - - default: - break; } /* If token is an already-parsed decltype not followed by ::,