This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Refactor fileptr_type_node handling
- From: Marc Glisse <marc dot glisse at inria dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 22 Jun 2017 10:46:16 +0200 (CEST)
- Subject: Refactor fileptr_type_node handling
- Authentication-results: sourceware.org; auth=none
Hello,
I was asked to handle (const) fenv_t and fexcept_t the same way as FILE
and const tm. Since these have special handling in quite a few places, it
seems necessary to make their support a bit more generic first. If I
didn't mess up, this patch should not change anything.
Bootstrap + testsuite on powerpc64le-unknown-linux-gnu.
2017-06-22 Marc Glisse <marc.glisse@inria.fr>
gcc/
* tree.h (predeclared_type): New type.
(predeclared_types): Declare new array.
* tree.c (predeclared_types): New array.
(free_lang_data, build_common_tree_nodes): Use it.
gcc/c-family/
* c-common.c (c_common_nodes_and_builtins): Use predeclared_types.
gcc/cp/
* decl.c (duplicate_decls): Use predeclared_types.
gcc/lto/
* lto-lang.c (lto_init): Use predeclared_types.
--
Marc Glisse
Index: gcc/c-family/c-common.c
===================================================================
--- gcc/c-family/c-common.c (revision 249495)
+++ gcc/c-family/c-common.c (working copy)
@@ -4174,24 +4174,27 @@ c_common_nodes_and_builtins (void)
lang_hooks.decls.pushdecl
(build_decl (UNKNOWN_LOCATION,
TYPE_DECL,
get_identifier (buf),
COMPLEX_FLOATN_NX_TYPE_NODE (i)));
}
if (c_dialect_cxx ())
{
/* For C++, make fileptr_type_node a distinct void * type until
- FILE type is defined. */
- fileptr_type_node = build_variant_type_copy (ptr_type_node);
- /* Likewise for const struct tm*. */
- const_tm_ptr_type_node = build_variant_type_copy (const_ptr_type_node);
+ FILE type is defined. Likewise for const struct tm*. */
+ for (unsigned i = 0;
+ i < sizeof (predeclared_types) / sizeof (predeclared_type);
+ ++i)
+ predeclared_types[i].node =
+ build_variant_type_copy (predeclared_types[i].base);
+
}
record_builtin_type (RID_VOID, NULL, void_type_node);
/* Set the TYPE_NAME for any variants that were built before
record_builtin_type gave names to the built-in types. */
{
tree void_name = TYPE_NAME (void_type_node);
TYPE_NAME (void_type_node) = NULL_TREE;
TYPE_NAME (build_qualified_type (void_type_node, TYPE_QUAL_CONST))
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c (revision 249495)
+++ gcc/cp/decl.c (working copy)
@@ -1463,67 +1463,55 @@ duplicate_decls (tree newdecl, tree oldd
is also extern "C". */
gcc_assert (DECL_IS_BUILTIN (olddecl));
gcc_assert (DECL_EXTERN_C_P (olddecl));
if (!DECL_EXTERN_C_P (newdecl))
return NULL_TREE;
for (t1 = TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
t2 = TYPE_ARG_TYPES (TREE_TYPE (olddecl));
t1 || t2;
t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
- if (!t1 || !t2)
- break;
- /* Deal with fileptr_type_node. FILE type is not known
- at the time we create the builtins. */
- else if (TREE_VALUE (t2) == fileptr_type_node)
- {
- tree t = TREE_VALUE (t1);
-
- if (TYPE_PTR_P (t)
- && TYPE_IDENTIFIER (TREE_TYPE (t))
- == get_identifier ("FILE")
- && compparms (TREE_CHAIN (t1), TREE_CHAIN (t2)))
+ {
+ if (!t1 || !t2)
+ break;
+ /* FILE, tm types are not known at the time
+ we create the builtins. */
+ for (unsigned i = 0;
+ i < sizeof (predeclared_types)
+ / sizeof (predeclared_type);
+ ++i)
+ if (TREE_VALUE (t2) == predeclared_types[i].node)
{
- tree oldargs = TYPE_ARG_TYPES (TREE_TYPE (olddecl));
+ tree t = TREE_VALUE (t1);
- TYPE_ARG_TYPES (TREE_TYPE (olddecl))
- = TYPE_ARG_TYPES (TREE_TYPE (newdecl));
- types_match = decls_match (newdecl, olddecl);
- if (types_match)
- return duplicate_decls (newdecl, olddecl,
- newdecl_is_friend);
- TYPE_ARG_TYPES (TREE_TYPE (olddecl)) = oldargs;
+ if (TYPE_PTR_P (t)
+ && TYPE_IDENTIFIER (TREE_TYPE (t))
+ == get_identifier (predeclared_types[i].str)
+ && compparms (TREE_CHAIN (t1), TREE_CHAIN (t2)))
+ {
+ tree oldargs = TYPE_ARG_TYPES (TREE_TYPE (olddecl));
+
+ TYPE_ARG_TYPES (TREE_TYPE (olddecl))
+ = TYPE_ARG_TYPES (TREE_TYPE (newdecl));
+ types_match = decls_match (newdecl, olddecl);
+ if (types_match)
+ return duplicate_decls (newdecl, olddecl,
+ newdecl_is_friend);
+ TYPE_ARG_TYPES (TREE_TYPE (olddecl)) = oldargs;
+ }
+ goto next_arg;
}
- }
- /* Likewise for const struct tm*. */
- else if (TREE_VALUE (t2) == const_tm_ptr_type_node)
- {
- tree t = TREE_VALUE (t1);
-
- if (TYPE_PTR_P (t)
- && TYPE_IDENTIFIER (TREE_TYPE (t))
- == get_identifier ("tm")
- && compparms (TREE_CHAIN (t1), TREE_CHAIN (t2)))
- {
- tree oldargs = TYPE_ARG_TYPES (TREE_TYPE (olddecl));
- TYPE_ARG_TYPES (TREE_TYPE (olddecl))
- = TYPE_ARG_TYPES (TREE_TYPE (newdecl));
- types_match = decls_match (newdecl, olddecl);
- if (types_match)
- return duplicate_decls (newdecl, olddecl,
- newdecl_is_friend);
- TYPE_ARG_TYPES (TREE_TYPE (olddecl)) = oldargs;
- }
- }
- else if (! same_type_p (TREE_VALUE (t1), TREE_VALUE (t2)))
- break;
+ if (! same_type_p (TREE_VALUE (t1), TREE_VALUE (t2)))
+ break;
+next_arg:;
+ }
warning_at (DECL_SOURCE_LOCATION (newdecl),
OPT_Wbuiltin_declaration_mismatch,
"declaration of %q+#D conflicts with built-in "
"declaration %q#D", newdecl, olddecl);
}
else if ((DECL_EXTERN_C_P (newdecl)
&& DECL_EXTERN_C_P (olddecl))
|| compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
TYPE_ARG_TYPES (TREE_TYPE (olddecl))))
Index: gcc/lto/lto-lang.c
===================================================================
--- gcc/lto/lto-lang.c (revision 249495)
+++ gcc/lto/lto-lang.c (working copy)
@@ -1213,27 +1213,30 @@ lto_init (void)
/* The global tree for the main identifier is filled in by
language-specific front-end initialization that is not run in the
LTO back-end. It appears that all languages that perform such
initialization currently do so in the same way, so we do it here. */
if (main_identifier_node == NULL_TREE)
main_identifier_node = get_identifier ("main");
/* In the C++ front-end, fileptr_type_node is defined as a variant
copy of ptr_type_node, rather than ptr_node itself. The
distinction should only be relevant to the front-end, so we
- always use the C definition here in lto1. */
- gcc_assert (fileptr_type_node == ptr_type_node);
- gcc_assert (TYPE_MAIN_VARIANT (fileptr_type_node) == ptr_type_node);
- /* Likewise for const struct tm*. */
- gcc_assert (const_tm_ptr_type_node == const_ptr_type_node);
- gcc_assert (TYPE_MAIN_VARIANT (const_tm_ptr_type_node)
- == const_ptr_type_node);
+ always use the C definition here in lto1.
+ Likewise for const struct tm*. */
+ for (unsigned i = 0;
+ i < sizeof (predeclared_types) / sizeof (predeclared_type);
+ ++i)
+ {
+ gcc_assert (predeclared_types[i].node == predeclared_types[i].base);
+ gcc_assert (TYPE_MAIN_VARIANT (predeclared_types[i].node)
+ == predeclared_types[i].base);
+ }
lto_build_c_type_nodes ();
gcc_assert (va_list_type_node);
if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
{
tree x = build_pointer_type (TREE_TYPE (va_list_type_node));
lto_define_builtins (x, x);
}
else
Index: gcc/tree.c
===================================================================
--- gcc/tree.c (revision 249495)
+++ gcc/tree.c (working copy)
@@ -5976,22 +5976,24 @@ free_lang_data (void)
while the slots are still in the way the frontends generated them. */
for (i = 0; i < itk_none; ++i)
if (integer_types[i])
TYPE_ALIAS_SET (integer_types[i]) = get_alias_set (integer_types[i]);
/* Traverse the IL resetting language specific information for
operands, expressions, etc. */
free_lang_data_in_cgraph ();
/* Create gimple variants for common types. */
- fileptr_type_node = ptr_type_node;
- const_tm_ptr_type_node = const_ptr_type_node;
+ for (unsigned i = 0;
+ i < sizeof (predeclared_types) / sizeof (predeclared_type);
+ ++i)
+ predeclared_types[i].node = predeclared_types[i].base;
/* Reset some langhooks. Do not reset types_compatible_p, it may
still be used indirectly via the get_alias_set langhook. */
lang_hooks.dwarf_name = lhd_dwarf_name;
lang_hooks.decl_printable_name = gimple_decl_printable_name;
lang_hooks.gimplify_expr = lhd_gimplify_expr;
/* We do not want the default decl_assembler_name implementation,
rather if we have fixed everything we want a wrapper around it
asserting that all non-local symbols already got their assembler
@@ -10442,22 +10444,24 @@ build_common_tree_nodes (bool signed_cha
void_node = make_node (VOID_CST);
TREE_TYPE (void_node) = void_type_node;
null_pointer_node = build_int_cst (build_pointer_type (void_type_node), 0);
layout_type (TREE_TYPE (null_pointer_node));
ptr_type_node = build_pointer_type (void_type_node);
const_ptr_type_node
= build_pointer_type (build_type_variant (void_type_node, 1, 0));
- fileptr_type_node = ptr_type_node;
- const_tm_ptr_type_node = const_ptr_type_node;
+ for (unsigned i = 0;
+ i < sizeof (predeclared_types) / sizeof (predeclared_type);
+ ++i)
+ predeclared_types[i].node = predeclared_types[i].base;
pointer_sized_int_node = build_nonstandard_integer_type (POINTER_SIZE, 1);
float_type_node = make_node (REAL_TYPE);
TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE;
layout_type (float_type_node);
double_type_node = make_node (REAL_TYPE);
TYPE_PRECISION (double_type_node) = DOUBLE_TYPE_SIZE;
layout_type (double_type_node);
@@ -14537,20 +14541,30 @@ get_nonnull_args (const_tree fntype)
for (tree idx = TREE_VALUE (attrs); idx; idx = TREE_CHAIN (idx))
{
unsigned int val = TREE_INT_CST_LOW (TREE_VALUE (idx)) - 1;
bitmap_set_bit (argmap, val);
}
}
return argmap;
}
+/* List of pointer types used to declare builtins before we have seen their
+ real declaration.
+
+ Keep the size up to date in tree.h ! */
+const predeclared_type predeclared_types[2] =
+{
+ { fileptr_type_node, ptr_type_node, "FILE" },
+ { const_tm_ptr_type_node, const_ptr_type_node, "tm" }
+};
+
#if CHECKING_P
namespace selftest {
/* Selftests for tree. */
/* Verify that integer constants are sane. */
static void
test_integer_constants ()
Index: gcc/tree.h
===================================================================
--- gcc/tree.h (revision 249495)
+++ gcc/tree.h (working copy)
@@ -5516,11 +5516,20 @@ desired_pro_or_demotion_p (const_tree to
unsigned int to_type_precision = TYPE_PRECISION (to_type);
/* OK to promote if to_type is no bigger than word_mode. */
if (to_type_precision <= GET_MODE_PRECISION (word_mode))
return true;
/* Otherwise, allow only if narrowing or same precision conversions. */
return to_type_precision <= TYPE_PRECISION (from_type);
}
+/* Pointer type used to declare builtins before we have seen its real
+ declaration. */
+struct predeclared_type
+{
+ tree& node;
+ tree& base;
+ const char *str;
+};
+extern const predeclared_type predeclared_types[2];
#endif /* GCC_TREE_H */