OSDN Git Service

* calls.c (expand_call): Convert structure_value_addr to Pmode if
[pf3gnuchains/gcc-fork.git] / gcc / gcov.c
index 5a2f429..4c92170 100644 (file)
@@ -53,6 +53,7 @@ Boston, MA 02111-1307, USA.  */
 
 #define IN_GCOV 1
 #include "gcov-io.h"
+#include "gcov-io.c"
 
 /* The bbg file is generated by -ftest-coverage option. The da file is
    generated by a program compiled with -fprofile-arcs. Their formats
@@ -167,6 +168,7 @@ typedef struct function_info
 {
   /* Name of function.  */
   char *name;
+  unsigned ident;
   unsigned checksum;
 
   /* Array of basic blocks.  */
@@ -321,7 +323,7 @@ static void print_usage PARAMS ((int)) ATTRIBUTE_NORETURN;
 static void print_version PARAMS ((void)) ATTRIBUTE_NORETURN;
 static void process_file PARAMS ((const char *));
 static void create_file_names PARAMS ((const char *));
-static source_t *find_source PARAMS ((char *));
+static source_t *find_source PARAMS ((const char *));
 static int read_graph_file PARAMS ((void));
 static int read_count_file PARAMS ((void));
 static void solve_flow_graph PARAMS ((function_t *));
@@ -360,14 +362,13 @@ main (argc, argv)
 }
 
 static void
-fnotice VPARAMS ((FILE *file, const char *msgid, ...))
+fnotice (FILE *file, const char *msgid, ...)
 {
-  VA_OPEN (ap, msgid);
-  VA_FIXEDARG (ap, FILE *, file);
-  VA_FIXEDARG (ap, const char *, msgid);
-
+  va_list ap;
+  
+  va_start (ap, msgid);
   vfprintf (file, _(msgid), ap);
-  VA_CLOSE (ap);
+  va_end (ap);
 }
 
 /* More 'friendly' abort that prints the line and file.
@@ -444,6 +445,7 @@ static const struct option options[] =
   { "object-directory",     required_argument, NULL, 'o' },
   { "object-file",          required_argument, NULL, 'o' },
   { "unconditional-branches", no_argument,     NULL, 'u' },
+  { 0, 0, 0, 0 }
 };
 
 /* Process args, return index to first non-arg.  */
@@ -673,31 +675,29 @@ create_file_names (file_name)
   return;
 }
 
-/* Find or create a source file structure for FILE_NAME. Free
-   FILE_NAME appropriately */
+/* Find or create a source file structure for FILE_NAME. Copies
+   FILE_NAME on creation */
 
 static source_t *
 find_source (file_name)
-     char *file_name;
+     const char *file_name;
 {
-
   source_t *src;
+
+  if (!file_name)
+    file_name = "<unknown>";
   
   for (src = sources; src; src = src->next)
     if (!strcmp (file_name, src->name))
-      {
-       free (file_name);
-       break;
-      }
-  if (!src)
-    {
-      src = (source_t *)xcalloc (1, sizeof (source_t));
-      src->name = file_name;
-      src->coverage.name = file_name;
-      src->index = sources ? sources->index + 1 : 1;
-      src->next = sources;
-      sources = src;
-    }
+      return src;
+  
+  src = (source_t *)xcalloc (1, sizeof (source_t));
+  src->name = xstrdup (file_name);
+  src->coverage.name = src->name;
+  src->index = sources ? sources->index + 1 : 1;
+  src->next = sources;
+  sources = src;
+
   return src;
 }
 
@@ -706,67 +706,62 @@ find_source (file_name)
 static int
 read_graph_file ()
 {
-  unsigned magic, version;
+  unsigned version;
   unsigned current_tag = 0;
-  unsigned tag;
   struct function_info *fn = NULL;
   source_t *src = NULL;
   unsigned ix;
-
+  unsigned tag;
+  
   if (!gcov_open (bbg_file_name, 1))
     {
       fnotice (stderr, "%s:cannot open graph file\n", bbg_file_name);
       return 1;
     }
   bbg_file_time = gcov_time ();
-  if (gcov_read_unsigned (&magic) || magic != GCOV_GRAPH_MAGIC)
+  if (gcov_read_unsigned () != GCOV_GRAPH_MAGIC)
     {
       fnotice (stderr, "%s:not a gcov graph file\n", bbg_file_name);
       gcov_close ();
       return 1;
     }
 
-  if (gcov_read_unsigned (&version) || version != GCOV_VERSION)
+  version = gcov_read_unsigned ();
+  if (version != GCOV_VERSION)
     {
       char v[4], e[4];
-
-      magic = GCOV_VERSION;
+      unsigned required = GCOV_VERSION;
       
-      for (ix = 4; ix--; magic >>= 8, version >>= 8)
+      for (ix = 4; ix--; required >>= 8, version >>= 8)
        {
          v[ix] = version;
-         e[ix] = magic;
+         e[ix] = required;
        }
       fnotice (stderr, "%s:version `%.4s', prefer `%.4s'\n",
               bbg_file_name, v, e);
     }
   
-  while (!gcov_read_unsigned (&tag))
+  while ((tag = gcov_read_unsigned ()))
     {
-      unsigned length;
-      long base;
-
-      if (gcov_read_unsigned (&length))
-       goto corrupt;
-
-      base = gcov_save_position ();
+      unsigned length = gcov_read_unsigned ();
+      gcov_position_t base = gcov_position ();
 
       if (tag == GCOV_TAG_FUNCTION)
        {
-         char *function_name = NULL;
-         char *function_file = NULL;
-         unsigned checksum, lineno;
+         char *function_name;
+         unsigned ident, checksum, lineno;
          source_t *src;
          function_t *probe, *prev;
 
-         if (gcov_read_string (&function_name)
-             || gcov_read_unsigned (&checksum)
-             || gcov_read_string (&function_file)
-             || gcov_read_unsigned (&lineno))
-           goto corrupt;
-         src = find_source (function_file);
+         ident = gcov_read_unsigned ();
+         checksum = gcov_read_unsigned ();
+         function_name = xstrdup (gcov_read_string ());
+         src = find_source (gcov_read_string ());
+         lineno = gcov_read_unsigned ();
+         
          fn = (function_t *)xcalloc (1, sizeof (function_t));
          fn->name = function_name;
+         fn->ident = ident;
          fn->checksum = checksum;
          fn->src = src;
          fn->line = lineno;
@@ -803,33 +798,24 @@ read_graph_file ()
              fn->blocks
                = (block_t *)xcalloc (fn->num_blocks, sizeof (block_t));
              for (ix = 0; ix != num_blocks; ix++)
-               {
-                 unsigned flags;
-                 
-                 if (gcov_read_unsigned (&flags))
-                   goto corrupt;
-                 fn->blocks[ix].flags = flags;
-               }
+               fn->blocks[ix].flags = gcov_read_unsigned ();
            }
        }
       else if (fn && tag == GCOV_TAG_ARCS)
        {
-         unsigned src;
+         unsigned src = gcov_read_unsigned ();
          unsigned num_dests = (length - 4) / 8;
-         unsigned dest, flags;
 
-         if (gcov_read_unsigned (&src)
-             || src >= fn->num_blocks
-             || fn->blocks[src].succ)
+         if (src >= fn->num_blocks || fn->blocks[src].succ)
            goto corrupt;
          
          while (num_dests--)
            {
              struct arc_info *arc;
+             unsigned dest = gcov_read_unsigned ();
+             unsigned flags = gcov_read_unsigned ();
              
-             if (gcov_read_unsigned (&dest)
-                 || gcov_read_unsigned (&flags)
-                 || dest >= fn->num_blocks)
+             if (dest >= fn->num_blocks)
                goto corrupt;
              arc = (arc_t *) xcalloc (1, sizeof (arc_t));
              
@@ -875,21 +861,17 @@ read_graph_file ()
        }
       else if (fn && tag == GCOV_TAG_LINES)
        {
-         unsigned blockno;
+         unsigned blockno = gcov_read_unsigned ();
          unsigned *line_nos
            = (unsigned *)xcalloc ((length - 4) / 4, sizeof (unsigned));
 
-         if (gcov_read_unsigned (&blockno)
-             || blockno >= fn->num_blocks
-             || fn->blocks[blockno].u.line.encoding)
+         if (blockno >= fn->num_blocks || fn->blocks[blockno].u.line.encoding)
            goto corrupt;
          
          for (ix = 0; ;  )
            {
-             unsigned lineno;
+             unsigned lineno = gcov_read_unsigned ();
              
-             if (gcov_read_unsigned (&lineno))
-               goto corrupt;
              if (lineno)
                {
                  if (!ix)
@@ -903,10 +885,8 @@ read_graph_file ()
                }
              else
                {
-                 char *file_name = NULL;
+                 const char *file_name = gcov_read_string ();
                  
-                 if (gcov_read_string (&file_name))
-                   goto corrupt;
                  if (!file_name)
                    break;
                  src = find_source (file_name);
@@ -924,13 +904,16 @@ read_graph_file ()
          fn = NULL;
          current_tag = 0;
        }
-      if (gcov_resync (base, length))
-       {
-       corrupt:;
-         fnotice (stderr, "%s:corrupted\n", bbg_file_name);
-         gcov_close ();
-         return 1;
-       }
+      gcov_sync (base, length);
+      if (gcov_is_error ())
+       break;
+    }
+  if (!gcov_is_eof ())
+    {
+    corrupt:;
+      fnotice (stderr, "%s:corrupted\n", bbg_file_name);
+      gcov_close ();
+      return 1;
     }
   gcov_close ();
   
@@ -994,72 +977,51 @@ static int
 read_count_file ()
 {
   unsigned ix;
-  char *function_name_buffer = NULL;
-  unsigned magic, version;
+  unsigned version;
+  unsigned tag;
   function_t *fn = NULL;
+  int error = 0;
 
   if (!gcov_open (da_file_name, 1))
     {
       fnotice (stderr, "%s:cannot open data file\n", da_file_name);
       return 1;
     }
-  if (gcov_read_unsigned (&magic) || magic != GCOV_DATA_MAGIC)
+  if (gcov_read_unsigned () != GCOV_DATA_MAGIC)
     {
       fnotice (stderr, "%s:not a gcov data file\n", da_file_name);
     cleanup:;
-      free (function_name_buffer);
       gcov_close ();
       return 1;
     }
-  if (gcov_read_unsigned (&version) || version != GCOV_VERSION)
+  version = gcov_read_unsigned ();
+  if (version != GCOV_VERSION)
     {
       char v[4], e[4];
+      unsigned desired = GCOV_VERSION;
       
-      magic = GCOV_VERSION;
-      for (ix = 4; ix--; magic >>= 8, version >>= 8)
+      for (ix = 4; ix--; desired >>= 8, version >>= 8)
        {
          v[ix] = version;
-         e[ix] = magic;
+         e[ix] = desired;
        }
       fnotice (stderr, "%s:version `%.4s', prefer version `%.4s'\n",
               da_file_name, v, e);
     }
   
-  while (1)
+  while ((tag = gcov_read_unsigned ()))
     {
-      unsigned tag, length;
-      long base;
-      
-      if (gcov_read_unsigned (&tag)
-         || gcov_read_unsigned (&length))
-       {
-         if (gcov_eof ())
-           break;
-         
-       corrupt:;
-         fnotice (stderr, "%s:corrupted\n", da_file_name);
-         goto cleanup;
-       }
-      base = gcov_save_position ();
+      unsigned length = gcov_read_unsigned ();
+      unsigned long base = gcov_position ();
+
       if (tag == GCOV_TAG_OBJECT_SUMMARY)
-       {
-         if (gcov_read_summary (&object_summary))
-           goto corrupt;
-       }
-      else if (tag == GCOV_TAG_PROGRAM_SUMMARY
-              || tag == GCOV_TAG_INCORRECT_SUMMARY)
-       {
-         program_count++;
-         gcov_resync (base, length);
-       }
+       gcov_read_summary (&object_summary);
+      else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
+       program_count++;
       else if (tag == GCOV_TAG_FUNCTION)
        {
-         unsigned checksum;
+         unsigned ident = gcov_read_unsigned ();
          struct function_info *fn_n = functions;
-         
-         if (gcov_read_string (&function_name_buffer)
-             || gcov_read_unsigned (&checksum))
-           goto corrupt;
 
          for (fn = fn ? fn->next : NULL; ; fn = fn->next)
            {
@@ -1069,25 +1031,25 @@ read_count_file ()
                fn_n = NULL;
              else
                {
-                 fnotice (stderr, "%s:unknown function `%s'\n",
-                          da_file_name, function_name_buffer);
+                 fnotice (stderr, "%s:unknown function `%u'\n",
+                          da_file_name, ident);
                  break;
                }
-             if (!strcmp (fn->name, function_name_buffer))
+             if (fn->ident == ident)
                break;
            }
 
          if (!fn)
            ;
-         else if (checksum != fn->checksum)
+         else if (gcov_read_unsigned () != fn->checksum)
            {
            mismatch:;
              fnotice (stderr, "%s:profile mismatch for `%s'\n",
-                      da_file_name, function_name_buffer);
+                      da_file_name, fn->name);
              goto cleanup;
            }
        }
-      else if (tag == GCOV_TAG_ARC_COUNTS && fn)
+      else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_ARCS) && fn)
        {
          if (length != 8 * fn->num_counts)
            goto mismatch;
@@ -1097,20 +1059,21 @@ read_count_file ()
              = (gcov_type *)xcalloc (fn->num_counts, sizeof (gcov_type));
          
          for (ix = 0; ix != fn->num_counts; ix++)
-           {
-             gcov_type count;
-             
-             if (gcov_read_counter (&count))
-               goto corrupt;
-             fn->counts[ix] += count;
-           }
+           fn->counts[ix] += gcov_read_counter ();
        }
-      else
-       gcov_resync (base, length);
+      gcov_sync (base, length);
+      if ((error = gcov_is_error ()))
+       break;
     }
 
+  if (!gcov_is_eof ())
+    {
+      fnotice (stderr, error < 0 ? "%s:overflowed\n" : "%s:corrupted\n",
+              da_file_name);
+      goto cleanup;
+    }
+  
   gcov_close ();
-  free (function_name_buffer);
   return 0;
 }
 
@@ -1845,7 +1808,8 @@ output_lines (gcov_file, src)
   fprintf (gcov_file, "%9s:%5d:Source:%s\n", "-", 0, src->name);
   fprintf (gcov_file, "%9s:%5d:Graph:%s\n", "-", 0, bbg_file_name);
   fprintf (gcov_file, "%9s:%5d:Data:%s\n", "-", 0, da_file_name);
-  fprintf (gcov_file, "%9s:%5d:Runs:%u\n", "-", 0, object_summary.runs);
+  fprintf (gcov_file, "%9s:%5d:Runs:%u\n", "-", 0,
+          object_summary.ctrs[GCOV_COUNTER_ARCS].runs);
   fprintf (gcov_file, "%9s:%5d:Programs:%u\n", "-", 0, program_count);
   
   source_file = fopen (src->name, "r");
@@ -1907,16 +1871,13 @@ output_lines (gcov_file, src)
            {
              retval = fgets (string, STRING_SIZE, source_file);
              if (!retval)
-               {
-                 fnotice (stderr, "%s:unexpected EOF\n", src->name);
-                 break;
-               }
+               break;
              fputs (retval, gcov_file);
            }
          while (!retval[0] || retval[strlen (retval) - 1] != '\n');
        }
       if (!retval)
-       fputs ("??\n", gcov_file);
+       fputs ("/*EOF*/\n", gcov_file);
 
       if (flag_all_blocks)
        {