aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/cp-tree.h
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2022-09-29 09:18:11 -0400
committerPatrick Palka <ppalka@redhat.com>2022-09-29 09:18:11 -0400
commit817e878a31671fcb68492bce35aa1ac87e08efdb (patch)
tree12b20c83ddd71f33a87747f21776d27673da7295 /gcc/cp/cp-tree.h
parentdf7f2736509cfe5e1dd7d9f263355c5043347a9c (diff)
downloadgcc-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.h18
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);