This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Refactor fileptr_type_node handling


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  */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]