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]

Patch: some cleanup in c-format.c


This patch is some cleanup in preparation for adding checking of the
diagnostics functions.

I split out into a separate function the extra code I had initially
stuffed into handle_format_attribute to process asm_fprintf setup.

Also if you look at the code I had there previously, you'll see that I
hardcoded the index for the "%w" modifier.  So in this patch I added a
lookup function to determine the index instead of assuming it lives at
location "1".

Tested on sparc-sun-solaris2.7 (minus java), no regressions.

Ok to install?

		Thanks,
		--Kaveh


2003-06-16  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>

	* c-format.c (dynamic_format_types): New pointer for dynamic data.
	(find_length_info_modifier_index, init_dynamic_asm_fprintf_info):
	New functions split out of...
	(handle_format_attribute): ...here.
	
diff -rup orig/egcc-CVS20030615/gcc/c-format.c egcc-CVS20030615/gcc/c-format.c
--- orig/egcc-CVS20030615/gcc/c-format.c	2003-06-13 10:06:48.000000000 -0400
+++ egcc-CVS20030615/gcc/c-format.c	2003-06-16 01:10:51.721321282 -0400
@@ -855,6 +855,8 @@ static const format_kind_info format_typ
    new data if necessary, while still allowing the original data to be
    const.  */
 static const format_kind_info *format_types = format_types_orig;
+/* We can modify this one.  */
+static format_kind_info *dynamic_format_types;
 
 /* Structure detailing the results of checking a format function call
    where the format expression may be a conditional expression with
@@ -2367,6 +2369,67 @@ check_format_types (status, types)
     }
 }
 
+/* Given a format_length_info array FLI, and a character C, this
+   function returns the index into the conversion_specs where that
+   modifier's data is located.  If the character isn't found it
+   aborts.  */
+static unsigned int
+find_length_info_modifier_index (const format_length_info *fli, int c)
+{
+  unsigned int i = 0;
+  
+  while (fli->name)
+    {
+      if (strchr (fli->name, c))
+	return i;
+      i++; fli++;
+    }
+  
+  /* We shouldn't be looking for a non-existent modifier.  */
+  abort ();
+}
+
+/* Determine the type of HOST_WIDE_INT in the code being compiled for
+   use in GCC's __asm_fprintf__ custom format attribute.  You must
+   have set dynamic_format_types before calling this function.  */
+static void
+init_dynamic_asm_fprintf_info (void)
+{
+  static tree hwi;
+      
+  if (!hwi)
+    {
+      format_length_info *new_asm_fprintf_length_specs;
+      unsigned int i;
+	  
+      /* Find the underlying type for HOST_WIDE_INT.  For the %w
+	 length modifier to work, one must have issued: "typedef
+	 HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
+	 prior to using that modifier.  */
+      if (!(hwi = maybe_get_identifier ("__gcc_host_wide_int__"))
+	  || !(hwi = DECL_ORIGINAL_TYPE (identifier_global_value (hwi))))
+	abort ();
+
+      /* Create a new (writable) copy of asm_fprintf_length_specs.  */
+      new_asm_fprintf_length_specs = xmemdup (asm_fprintf_length_specs,
+					      sizeof (asm_fprintf_length_specs),
+					      sizeof (asm_fprintf_length_specs));
+
+      /* HOST_WIDE_INT must be one of 'long' or 'long long'.  */
+      i = find_length_info_modifier_index (new_asm_fprintf_length_specs, 'w');
+      if (hwi == long_integer_type_node)
+	new_asm_fprintf_length_specs[i].index = FMT_LEN_l;
+      else if (hwi == long_long_integer_type_node)
+	new_asm_fprintf_length_specs[i].index = FMT_LEN_ll;
+      else
+	abort ();
+
+      /* Assign the new data for use.  */
+      dynamic_format_types[asm_fprintf_format_type].length_char_specs =
+	new_asm_fprintf_length_specs;
+    }
+}
+
 /* Handle a "format" attribute; arguments as in
    struct attribute_spec.handler.  */
 tree
@@ -2424,44 +2487,14 @@ handle_format_attribute (node, name, arg
      GCC's notion of HOST_WIDE_INT for checking %wd.  */
   if (info.format_type == asm_fprintf_format_type)
     {
-      static tree hwi;
-      tree orig;
-      
-      /* For this custom check to work, one must have issued:
-	 "typedef HOST_WIDE_INT __gcc_host_wide_int__;"
-	 in your source code prior to using this attribute.  */
-      if (!hwi)
-        {
-	  format_kind_info *new_format_types;
-	  format_length_info *new_asm_fprintf_length_specs;
-	  
-	  if (!(hwi = maybe_get_identifier ("__gcc_host_wide_int__")))
-	    abort ();
-
-	  /* Create a new (writable) copy of asm_fprintf_length_specs.  */
-	  new_asm_fprintf_length_specs =
-	    xmalloc (sizeof (asm_fprintf_length_specs));
-	  memcpy (new_asm_fprintf_length_specs, asm_fprintf_length_specs,
-		  sizeof (asm_fprintf_length_specs));
-
-	  /* Create a new (writable) copy of format_types.  */
-	  new_format_types = xmalloc (sizeof (format_types_orig));
-	  memcpy (new_format_types, format_types_orig, sizeof (format_types_orig));
-	  
-	  /* Find the underlying type for HOST_WIDE_INT.  */
-	  orig = DECL_ORIGINAL_TYPE (identifier_global_value (hwi));
-	  if (orig == long_integer_type_node)
-	    new_asm_fprintf_length_specs[1].index = FMT_LEN_l;
-	  else if (orig == long_long_integer_type_node)
-	    new_asm_fprintf_length_specs[1].index = FMT_LEN_ll;
-	  else
-	    abort ();
+      /* Our first time through, we have to make sure that our
+         format_type data is allocated dynamically and is modifiable.  */
+      if (!dynamic_format_types)
+	format_types = dynamic_format_types =
+	  xmemdup (format_types_orig, sizeof (format_types_orig),
+		   sizeof (format_types_orig));
 
-	  /* Assign the new data for use.  */
-	  new_format_types[asm_fprintf_format_type].length_char_specs =
-	    new_asm_fprintf_length_specs;
-	  format_types = new_format_types;
-	}
+      init_dynamic_asm_fprintf_info();
     }
 
   return NULL_TREE;


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