Clean up diagnostics for static ctors/dtors

Chip Salzenberg chip@valinux.com
Sun Feb 27 00:39:00 GMT 2000


According to Mark Mitchell:
> Chip> Fine, but: Would it be acceptable to generate dinky little
> Chip> ctor functions and dinkly little dtor functions separately,
> Chip> rather than dinky little dual-purpose SSDFs?  
> 
> I don't think it's worth it for two reasons: 1) eventually, for
> maximum performance, the C++ front-end needs to be able to calculate
> the neededness of things without help from the back-end, 2) under the
> new ABI there won't be any destructor functions anyhow.

Good reasons!

> I think your patch is fine.  But, I can't install it -- the patch
> doesn't apply cleanly.  Please post an updated version against the
> current sources.

Thanks, and here you go ... but I don't understand why it failed.
The diffs are unchanged, except for line numbers.

--------------------------------------------------------------------
2000-02-27  Chip Salzenberg  <chip@valinux.com>

	Clean up diagnostics involving static ctors/dtors.

	* tree.h (file_function_name_type): Declare new function.
	(get_file_function_name): Remove redundant declarations.
	* tree.c (file_function_name_type): Define new function.
	(file_function_format): Define new static var.
	(get_file_function_long): Use it.
	(get_file_function): Document that other types besides 'I' and 'D'
	can exist, but have no universally defined meaning.
	
	* diagnostic.c (default_print_error_function): Use
	file_function_name_type().  Don't print raw file function names;
	print their types, or nothing if their types are unknown.

	* cp/decl2.c (SSDF_IDENTIFIER): Remove.
	(start_static_storage_duration_function): Get function name from
	get_file_function_name_long() instead of rolling our own.

	* cp/error.c (dump_file_function): Rename from dump_global_iord.
	Add TYPE (file function type) parameter.  Handle unknown file
	function types gracefully.
	(dump_decl): Use dump_file_function.
	(GLOBAL_THING, GLOBAL_IORD_P): Remove.

Index: tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tree.h,v
retrieving revision 1.125
diff -u -2 -r1.125 tree.h
--- tree.h	2000/02/24 04:04:05	1.125
+++ tree.h	2000/02/27 08:35:11
@@ -2095,4 +2095,5 @@
 extern tree get_file_function_name		PARAMS ((int));
 extern tree get_file_function_name_long 	PARAMS ((const char *));
+extern char *file_function_name_type		PARAMS ((tree));
 extern tree get_set_constructor_bits		PARAMS ((tree, char *, int));
 extern tree get_set_constructor_bytes		PARAMS ((tree,
@@ -2342,5 +2343,4 @@
 extern void temporary_allocation	PARAMS ((void));
 extern void resume_temporary_allocation	PARAMS ((void));
-extern tree get_file_function_name	PARAMS ((int));
 extern void set_identifier_size		PARAMS ((int));
 extern int int_fits_type_p		PARAMS ((tree, tree));
@@ -2522,9 +2522,4 @@
 extern void lang_print_xnode 		PARAMS ((FILE *, tree, int));
 #endif
-
-
-/* If KIND=='I', return a suitable global initializer (constructor) name.
-   If KIND=='D', return a suitable global clean-up (destructor) name.  */
-extern tree get_file_function_name PARAMS ((int));
 
 /* Interface of the DWARF2 unwind info support.  */
Index: tree.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tree.c,v
retrieving revision 1.119
diff -u -2 -r1.119 tree.c
--- tree.c	2000/02/24 04:04:05	1.119
+++ tree.c	2000/02/27 08:35:21
@@ -5058,4 +5058,5 @@
 #endif	/* NO_DOLLAR_IN_LABEL */
 
+static char file_function_format[] = FILE_FUNCTION_FORMAT;
 extern char *first_global_object_name;
 extern char *weak_global_object_name;
@@ -5139,12 +5140,12 @@
     }
 
-  buf = (char *) alloca (sizeof (FILE_FUNCTION_FORMAT) + strlen (p)
-			 + strlen (type));
-
   /* Set up the name of the file-level functions we may need. 
      Use a global object (which is already required to be unique over
      the program) rather than the file name (which imposes extra
      constraints).  */
-  sprintf (buf, FILE_FUNCTION_FORMAT, type, p);
+
+  buf = (char *) alloca (FILE_FUNCTION_PREFIX_LEN + 4
+			 + strlen (type) + strlen (p));
+  sprintf (buf, file_function_format, type, p);
 
   /* Don't need to pull weird characters out of global names.  */
@@ -5173,5 +5174,6 @@
 
 /* If KIND=='I', return a suitable global initializer (constructor) name.
-   If KIND=='D', return a suitable global clean-up (destructor) name.  */
+   If KIND=='D', return a suitable global destructor (clean-up) name.
+   Other KINDs are legal but have no set meaning (yet).  */
 
 tree
@@ -5185,4 +5187,21 @@
 
   return get_file_function_name_long (p);
+}
+
+/* If the given identifier looks like it was created by
+   get_file_function_long(), return a pointer to the beginning
+   of the unique part (the "kind").  */
+
+char *
+file_function_name_type (id)
+     tree id;
+{
+  if (IDENTIFIER_LENGTH (id) > FILE_FUNCTION_PREFIX_LEN)
+    {
+      char *p = IDENTIFIER_POINTER(id);
+      if (!bcmp (file_function_format, p, FILE_FUNCTION_PREFIX_LEN))
+	return p + FILE_FUNCTION_PREFIX_LEN;
+    }
+  return NULL;
 }
 
Index: diagnostic.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/diagnostic.c,v
retrieving revision 1.9
diff -u -2 -r1.9 diagnostic.c
--- diagnostic.c	2000/02/23 12:17:57	1.9
+++ diagnostic.c	2000/02/27 08:35:23
@@ -1048,11 +1048,34 @@
 	  else
             {
-              if (doing_line_wrapping ())
-                output_printf
-                  (&buffer, "In function `%s':\n",
-                   (*decl_printable_name) (current_function_decl, 2));
-              else
-                notice ("In function `%s':\n",
-                        (*decl_printable_name) (current_function_decl, 2));
+	      const char *fmt = "In function `%s':\n";
+	      const char *p;
+
+	      p = file_function_name_type (DECL_NAME (current_function_decl));
+	      if (p)
+		{
+		  fmt = "In %s:\n";
+		  switch (*p)
+		    {
+		    case 'I':
+		      p = "static initialization";
+		      break;
+		    case 'D':
+		      p = "static destruction";
+		      break;
+		    default:
+		      p = NULL;	/* don't print confusing names */
+		      break;
+		    }
+		}
+	      else
+		p = (*decl_printable_name) (current_function_decl, 2);
+
+	      if (p)
+		{
+		  if (doing_line_wrapping ())
+		    output_printf (&buffer, fmt, p);
+		  else
+		    notice (fmt, p);
+		}
             }
 	}
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl2.c,v
retrieving revision 1.313
diff -u -2 -r1.313 decl2.c
--- decl2.c	2000/02/27 02:46:57	1.313
+++ decl2.c	2000/02/27 08:35:35
@@ -2888,8 +2888,4 @@
 #define PRIORITY_IDENTIFIER "__priority"
 
-/* The name of the function we create to handle initializations and
-   destructions for objects with static storage duration.  */
-#define SSDF_IDENTIFIER "__static_initialization_and_destruction"
-
 /* The declaration for the __INITIALIZE_P argument.  */
 static tree initialize_p_decl;
@@ -2898,5 +2894,7 @@
 static tree priority_decl;
 
-/* The declaration for the static storage duration function.  */
+/* The declaration for the static storage duration function, which we
+   create to handle initializations and destructions for objects with
+   static storage duration.  */
 static tree ssdf_decl;
 
@@ -2927,12 +2925,12 @@
   static unsigned ssdf_number;
 
+  char fftype[32];
+  tree name;
   tree parm_types;
   tree type;
   tree body;
-  char id[sizeof (SSDF_IDENTIFIER) + 1 /* '\0' */ + 32];
 
-  /* Create the identifier for this function.  It will be of the form
-     SSDF_IDENTIFIER_<number>.  */
-  sprintf (id, "%s_%u", SSDF_IDENTIFIER, ssdf_number++);
+  /* Create the identifier for this function.  */
+  sprintf (fftype, "S_%u", ssdf_number++);
   if (ssdf_number == 0)
     {
@@ -2942,4 +2940,5 @@
       my_friendly_abort (19990430);
     }
+  name = get_file_function_name_long (fftype);
 
   /* Create the parameters.  */
@@ -2950,7 +2949,5 @@
 
   /* Create the FUNCTION_DECL itself.  */
-  ssdf_decl = build_lang_decl (FUNCTION_DECL, 
-			       get_identifier (id),
-			       type);
+  ssdf_decl = build_lang_decl (FUNCTION_DECL, name, type);
   TREE_PUBLIC (ssdf_decl) = 0;
   DECL_ARTIFICIAL (ssdf_decl) = 1;
Index: cp/error.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/error.c,v
retrieving revision 1.104
diff -u -2 -r1.104 error.c
--- error.c	2000/02/26 20:15:45	1.104
+++ error.c	2000/02/27 08:35:39
@@ -84,5 +84,5 @@
 static void dump_function_name PARAMS ((tree, enum tree_string_flags));
 static void dump_expr_list PARAMS ((tree, enum tree_string_flags));
-static void dump_global_iord PARAMS ((tree));
+static void dump_file_function PARAMS ((tree, int));
 static enum pad dump_qualifiers PARAMS ((tree, enum pad));
 static void dump_char PARAMS ((int));
@@ -789,31 +789,26 @@
 }
 
-#ifndef NO_DOLLAR_IN_LABEL
-#  define GLOBAL_THING "_GLOBAL_$"
-#else
-#  ifndef NO_DOT_IN_LABEL
-#    define GLOBAL_THING "_GLOBAL_."
-#  else
-#    define GLOBAL_THING "_GLOBAL__"
-#  endif
-#endif
-
-#define GLOBAL_IORD_P(NODE) \
-  ! strncmp (IDENTIFIER_POINTER(NODE), GLOBAL_THING, sizeof (GLOBAL_THING) - 1)
-
 static void
-dump_global_iord (t)
-     tree t;
+dump_file_function (t, kind)
+     tree t ATTRIBUTE_UNUSED;
+     int kind;
 {
-  const char *name = IDENTIFIER_POINTER (t);
+  const char *desc;
 
-  OB_PUTS ("(static ");
-  if (name [sizeof (GLOBAL_THING) - 1] == 'I')
-    OB_PUTS ("initializers");
-  else if (name [sizeof (GLOBAL_THING) - 1] == 'D')
-    OB_PUTS ("destructors");
-  else
-    my_friendly_abort (352);
-  
+  switch (kind)
+    {
+    case 'I':
+      desc = "static initializers";
+      break;
+    case 'D':
+      desc = "static destructors";
+      break;
+    default:
+      desc = "internal function";
+      break;
+    }
+
+  OB_PUTC ('(');
+  OB_PUTS (desc);
   OB_PUTS (" for ");
   OB_PUTCP (input_filename);
@@ -967,12 +962,15 @@
 
     case FUNCTION_DECL:
-      if (GLOBAL_IORD_P (DECL_ASSEMBLER_NAME (t)))
-	dump_global_iord (DECL_ASSEMBLER_NAME (t));
-      else if (! DECL_LANG_SPECIFIC (t))
-	OB_PUTS ("{internal}");
-      else if (flags & TS_PEDANTIC_NAME)
-        dump_function_decl (t, flags | TS_FUNC_NORETURN | TS_DECL_TYPE);
-      else
-        dump_function_decl (t, flags);
+      {
+	const char *p;
+	if ((p = file_function_name_type (DECL_NAME (t))))
+	  dump_file_function (t, *p);
+	else if (! DECL_LANG_SPECIFIC (t))
+	  OB_PUTS ("{internal}");
+	else if (flags & TS_PEDANTIC_NAME)
+	  dump_function_decl (t, flags | TS_FUNC_NORETURN | TS_DECL_TYPE);
+	else
+	  dump_function_decl (t, flags);
+      }
       break;
 
--------------------------------------------------------------------

-- 
Chip Salzenberg              - a.k.a. -              <chip@valinux.com>
"I wanted to play hopscotch with the impenetrable mystery of existence,
    but he stepped in a wormhole and had to go in early."  // MST3K


More information about the Gcc-patches mailing list