diff options
author | Patrick Palka <ppalka@redhat.com> | 2022-09-29 09:18:11 -0400 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2022-09-29 09:18:11 -0400 |
commit | 817e878a31671fcb68492bce35aa1ac87e08efdb (patch) | |
tree | 12b20c83ddd71f33a87747f21776d27673da7295 /gcc/cp/cp-tree.h | |
parent | df7f2736509cfe5e1dd7d9f263355c5043347a9c (diff) | |
download | gcc-817e878a31671fcb68492bce35aa1ac87e08efdb.zip gcc-817e878a31671fcb68492bce35aa1ac87e08efdb.tar.gz gcc-817e878a31671fcb68492bce35aa1ac87e08efdb.tar.bz2 |
c++: introduce TRAIT_TYPE alongside TRAIT_EXPR
We already have generic support for predicate-like traits that yield a
boolean value via TRAIT_EXPR, but we lack the same support for traits
that yield a type instead of a value. Such support would streamline
implementing efficient builtins for the standard library type traits.
To that end this patch implements a generic TRAIT_TYPE type alongside
TRAIT_EXPR, and reimplements the existing UNDERLYING_TYPE builtin trait
using this new TRAIT_TYPE.
gcc/cp/ChangeLog:
* cp-objcp-common.cc (cp_common_init_ts): Replace
UNDERLYING_TYPE with TRAIT_TYPE.
* cp-tree.def (TRAIT_TYPE): Define.
(UNDERLYING_TYPE): Remove.
* cp-tree.h (TRAIT_TYPE_KIND_RAW): Define.
(TRAIT_TYPE_KIND): Define.
(TRAIT_TYPE_TYPE1): Define.
(TRAIT_TYPE_TYPE2): Define.
(WILDCARD_TYPE_P): Return true for TRAIT_TYPE.
(finish_trait_type): Declare.
* cxx-pretty-print.cc (cxx_pretty_printer::primary_expression):
Adjust after renaming pp_cxx_trait_expression.
(cxx_pretty_printer::simple_type_specifier) <case TRAIT_TYPE>:
New.
(cxx_pretty_printer::type_id): Replace UNDERLYING_TYPE with
TRAIT_TYPE.
(pp_cxx_trait_expression): Rename to ...
(pp_cxx_trait): ... this. Handle TRAIT_TYPE as well. Correct
pretty printing of the trailing arguments.
* cxx-pretty-print.h (pp_cxx_trait_expression): Rename to ...
(pp_cxx_trait_type): ... this.
* error.cc (dump_type) <case UNDERLYING_TYPE>: Remove.
<case TRAIT_TYPE>: New.
(dump_type_prefix): Replace UNDERLYING_WITH with TRAIT_TYPE.
(dump_type_suffix): Likewise.
* mangle.cc (write_type) <case UNDERLYING_TYPE>: Remove.
<case TRAIT_TYPE>: New.
* module.cc (trees_out::type_node) <case UNDERLYING_TYPE>:
Remove.
<case TRAIT_TYPE>: New.
(trees_in::tree_node): Likewise.
* parser.cc (cp_parser_primary_expression): Adjust after
renaming cp_parser_trait_expr.
(cp_parser_trait_expr): Rename to ...
(cp_parser_trait): ... this. Call finish_trait_type for traits
that yield a type.
(cp_parser_simple_type_specifier): Adjust after renaming
cp_parser_trait_expr.
* pt.cc (for_each_template_parm_r) <case UNDERLYING_TYPE>:
Remove.
<case TRAIT_TYPE>: New.
(tsubst): Likewise.
(unify): Replace UNDERLYING_TYPE with TRAIT_TYPE.
(dependent_type_p_r): Likewise.
* semantics.cc (finish_underlying_type): Don't return
UNDERLYING_TYPE anymore when processing_template_decl.
(finish_trait_type): Define.
* tree.cc (strip_typedefs) <case UNDERLYING_TYPE>: Remove.
<case TRAIT_TYPE>: New.
(cp_walk_subtrees): Likewise.
* typeck.cc (structural_comptypes): Likewise.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/alias-decl-59.C: Adjust expected error message.
* g++.dg/ext/underlying_type7.C: Likewise.
* g++.dg/ext/underlying_type13.C: New test.
* g++.dg/ext/underlying_type14.C: New test.
Diffstat (limited to 'gcc/cp/cp-tree.h')
-rw-r--r-- | gcc/cp/cp-tree.h | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index d0f1b18..ff9913c 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1437,6 +1437,22 @@ struct GTY (()) tree_trait_expr { enum cp_trait_kind kind; }; +/* An INTEGER_CST containing the kind of the trait type NODE. */ +#define TRAIT_TYPE_KIND_RAW(NODE) \ + TYPE_VALUES_RAW (TRAIT_TYPE_CHECK (NODE)) + +/* The kind of the trait type NODE. */ +#define TRAIT_TYPE_KIND(NODE) \ + ((enum cp_trait_kind) TREE_INT_CST_LOW (TRAIT_TYPE_KIND_RAW (NODE))) + +/* The first argument of the trait type NODE. */ +#define TRAIT_TYPE_TYPE1(NODE) \ + TYPE_MIN_VALUE_RAW (TRAIT_TYPE_CHECK (NODE)) + +/* The rest of the arguments of the trait type NODE. */ +#define TRAIT_TYPE_TYPE2(NODE) \ + TYPE_MAX_VALUE_RAW (TRAIT_TYPE_CHECK (NODE)) + /* Identifiers used for lambda types are almost anonymous. Use this spare flag to distinguish them (they also have the anonymous flag). */ #define IDENTIFIER_LAMBDA_P(NODE) \ @@ -2226,6 +2242,7 @@ enum languages { lang_c, lang_cplusplus }; || TREE_CODE (T) == TYPEOF_TYPE \ || TREE_CODE (T) == BOUND_TEMPLATE_TEMPLATE_PARM \ || TREE_CODE (T) == DECLTYPE_TYPE \ + || TREE_CODE (T) == TRAIT_TYPE \ || TREE_CODE (T) == DEPENDENT_OPERATOR_TYPE) /* Nonzero if T is a class (or struct or union) type. Also nonzero @@ -7736,6 +7753,7 @@ extern tree finish_decltype_type (tree, bool, tsubst_flags_t); extern tree fold_builtin_is_corresponding_member (location_t, int, tree *); extern tree fold_builtin_is_pointer_inverconvertible_with_class (location_t, int, tree *); extern tree finish_trait_expr (location_t, enum cp_trait_kind, tree, tree); +extern tree finish_trait_type (enum cp_trait_kind, tree, tree); extern tree build_lambda_expr (void); extern tree build_lambda_object (tree); extern tree begin_lambda_type (tree); |