* config/arm/elf.h (ASM_OUTPUT_ALIGNED_COMMON): Remove definition.
[official-gcc.git] / gcc / coverage.c
blob9d7e0893905ea819b9c3acba61248bcbd6b985c0
1 /* Read and write coverage files, and associated functionality.
2 Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999,
3 2000, 2001, 2003 Free Software Foundation, Inc.
4 Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
5 based on some ideas from Dain Samples of UC Berkeley.
6 Further mangling by Bob Manson, Cygnus Support.
7 Further mangled by Nathan Sidwell, CodeSourcery
9 This file is part of GCC.
11 GCC is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 2, or (at your option) any later
14 version.
16 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 for more details.
21 You should have received a copy of the GNU General Public License
22 along with GCC; see the file COPYING. If not, write to the Free
23 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
24 02111-1307, USA. */
27 #define GCOV_LINKAGE
29 #include "config.h"
30 #include "system.h"
31 #include "coretypes.h"
32 #include "tm.h"
33 #include "rtl.h"
34 #include "tree.h"
35 #include "flags.h"
36 #include "output.h"
37 #include "regs.h"
38 #include "expr.h"
39 #include "function.h"
40 #include "toplev.h"
41 #include "ggc.h"
42 #include "target.h"
43 #include "coverage.h"
44 #include "libfuncs.h"
45 #include "langhooks.h"
46 #include "hashtab.h"
48 #include "gcov-io.c"
50 struct function_list
52 struct function_list *next; /* next function */
53 unsigned ident; /* function ident */
54 unsigned checksum; /* function checksum */
55 unsigned n_ctrs[GCOV_COUNTERS];/* number of counters. */
58 /* Counts information for a function. */
59 typedef struct counts_entry
61 /* We hash by */
62 unsigned ident;
63 unsigned ctr;
65 /* Store */
66 unsigned checksum;
67 gcov_type *counts;
68 struct gcov_ctr_summary summary;
70 /* Workspace */
71 struct counts_entry *chain;
73 } counts_entry_t;
75 static unsigned fn_ident = 1;
76 static struct function_list *functions_head = 0;
77 static struct function_list **functions_tail = &functions_head;
79 /* Cumulative counter information for whole program. */
80 static unsigned prg_ctr_mask; /* Mask of counter types generated. */
81 static unsigned prg_n_ctrs[GCOV_COUNTERS];
83 /* Counter information for current function. */
84 static unsigned fn_ctr_mask;
85 static unsigned fn_n_ctrs[GCOV_COUNTERS];
87 /* Name of the output file for coverage output file. */
88 static char *bbg_file_name;
89 static unsigned bbg_file_opened;
90 static int bbg_function_announced;
92 /* Name of the count data file. */
93 static char *da_file_name;
95 /* Hash table of count data. */
96 static htab_t counts_hash = NULL;
98 /* The names of the counter tables. */
99 static GTY(()) rtx ctr_labels[GCOV_COUNTERS];
101 /* Forward declarations. */
102 static hashval_t htab_counts_entry_hash PARAMS ((const void *));
103 static int htab_counts_entry_eq PARAMS ((const void *, const void *));
104 static void htab_counts_entry_del PARAMS ((void *));
105 static void read_counts_file PARAMS ((void));
106 static unsigned compute_checksum PARAMS ((void));
107 static unsigned checksum_string PARAMS ((unsigned, const char *));
108 static tree build_fn_info_type PARAMS ((unsigned));
109 static tree build_fn_info_value PARAMS ((const struct function_list *, tree));
110 static tree build_ctr_info_type PARAMS ((void));
111 static tree build_ctr_info_value PARAMS ((unsigned, tree));
112 static tree build_gcov_info PARAMS ((void));
113 static void create_coverage PARAMS ((void));
116 static hashval_t
117 htab_counts_entry_hash (of)
118 const void *of;
120 const counts_entry_t *entry = of;
122 return entry->ident * GCOV_COUNTERS + entry->ctr;
125 static int
126 htab_counts_entry_eq (of1, of2)
127 const void *of1;
128 const void *of2;
130 const counts_entry_t *entry1 = of1;
131 const counts_entry_t *entry2 = of2;
133 return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr;
136 static void
137 htab_counts_entry_del (of)
138 void *of;
140 counts_entry_t *entry = of;
142 free (entry->counts);
143 free (entry);
146 /* Read in the counts file, if available. */
148 static void
149 read_counts_file ()
151 unsigned fn_ident = 0;
152 unsigned version, ix, checksum = -1;
153 counts_entry_t *summaried = NULL;
154 unsigned seen_summary = 0;
156 if (!gcov_open (da_file_name, 1))
157 return;
159 if (gcov_read_unsigned () != GCOV_DATA_MAGIC)
161 warning ("`%s' is not a gcov data file", da_file_name);
162 gcov_close ();
163 return;
165 else if ((version = gcov_read_unsigned ()) != GCOV_VERSION)
167 char v[4], e[4];
168 unsigned required = GCOV_VERSION;
170 for (ix = 4; ix--; required >>= 8, version >>= 8)
172 v[ix] = version;
173 e[ix] = required;
175 warning ("`%s' is version `%.4s', expected version `%.4s'",
176 da_file_name, v, e);
177 gcov_close ();
178 return;
181 counts_hash = htab_create (10,
182 htab_counts_entry_hash, htab_counts_entry_eq,
183 htab_counts_entry_del);
184 while (!gcov_is_eof ())
186 unsigned tag, length;
187 unsigned long offset;
188 int error;
190 tag = gcov_read_unsigned ();
191 length = gcov_read_unsigned ();
192 offset = gcov_position ();
193 if (tag == GCOV_TAG_FUNCTION)
195 fn_ident = gcov_read_unsigned ();
196 checksum = gcov_read_unsigned ();
197 if (seen_summary)
199 /* We have already seen a summary, this means that this
200 new function begins a new set of program runs. We
201 must unlink the summaried chain. */
202 counts_entry_t *entry, *chain;
204 for (entry = summaried; entry; entry = chain)
206 chain = entry->chain;
207 entry->chain = NULL;
209 summaried = NULL;
210 seen_summary = 0;
213 else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
215 counts_entry_t *entry;
216 struct gcov_summary summary;
218 gcov_read_summary (&summary);
219 seen_summary = 1;
220 for (entry = summaried; entry; entry = entry->chain)
222 struct gcov_ctr_summary *csum = &summary.ctrs[entry->ctr];
224 entry->summary.runs += csum->runs;
225 entry->summary.sum_all += csum->sum_all;
226 if (entry->summary.run_max < csum->run_max)
227 entry->summary.run_max = csum->run_max;
228 entry->summary.sum_max += csum->sum_max;
231 else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident)
233 counts_entry_t **slot, *entry, elt;
234 unsigned n_counts = length / 8;
235 unsigned ix;
237 elt.ident = fn_ident;
238 elt.ctr = GCOV_COUNTER_FOR_TAG (tag);
240 slot = (counts_entry_t **) htab_find_slot
241 (counts_hash, &elt, INSERT);
242 entry = *slot;
243 if (!entry)
245 *slot = entry = xcalloc (1, sizeof (counts_entry_t));
246 entry->ident = elt.ident;
247 entry->ctr = elt.ctr;
248 entry->checksum = checksum;
249 entry->summary.num = n_counts;
250 entry->counts = xcalloc (n_counts, sizeof (gcov_type));
252 else if (entry->checksum != checksum
253 || entry->summary.num != n_counts)
255 warning ("coverage mismatch for function %u", fn_ident);
256 htab_delete (counts_hash);
257 break;
260 /* This should always be true for a just allocated entry,
261 and always false for an existing one. Check this way, in
262 case the gcov file is corrupt. */
263 if (!entry->chain || summaried != entry)
265 entry->chain = summaried;
266 summaried = entry;
268 for (ix = 0; ix != n_counts; ix++)
269 entry->counts[ix] += gcov_read_counter ();
271 gcov_seek (offset, length);
272 if ((error = gcov_is_error ()))
274 warning (error < 0 ? "`%s' has overflowed" : "`%s' is corrupted",
275 da_file_name);
276 htab_delete (counts_hash);
277 break;
281 gcov_close ();
284 /* Returns the counters for a particular tag. */
286 gcov_type *
287 get_coverage_counts (unsigned counter, unsigned expected,
288 const struct gcov_ctr_summary **summary)
290 counts_entry_t *entry, elt;
292 /* No hash table, no counts. */
293 if (!counts_hash)
295 static int warned = 0;
297 if (!warned++)
298 warning ("file %s not found, execution counts assumed to be zero",
299 da_file_name);
300 return NULL;
303 elt.ident = fn_ident;
304 elt.ctr = counter;
305 entry = htab_find (counts_hash, &elt);
306 if (!entry)
308 warning ("no coverage for function '%s' found.", IDENTIFIER_POINTER
309 (DECL_ASSEMBLER_NAME (current_function_decl)));
310 return 0;
313 if (expected != entry->summary.num
314 || compute_checksum () != entry->checksum)
316 warning ("coverage mismatch for `%s'", IDENTIFIER_POINTER
317 (DECL_ASSEMBLER_NAME (current_function_decl)));
318 return NULL;
321 if (summary)
322 *summary = &entry->summary;
324 return entry->counts;
327 /* Generate a MEM rtl to access COUNTER NO . */
330 coverage_counter_ref (unsigned counter, unsigned no)
332 enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
333 rtx ref;
335 if (!ctr_labels[counter])
337 /* Generate and save a copy of this so it can be shared. */
338 char buf[20];
340 ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", counter + 1);
341 ctr_labels[counter] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
343 if (no + 1 > fn_n_ctrs[counter])
345 fn_n_ctrs[counter] = no + 1;
346 fn_ctr_mask |= 1 << counter;
349 no += prg_n_ctrs[counter];
350 ref = plus_constant (ctr_labels[counter],
351 GCOV_TYPE_SIZE / BITS_PER_UNIT * no);
352 ref = gen_rtx_MEM (mode, ref);
353 set_mem_alias_set (ref, new_alias_set ());
355 return ref;
358 /* Generate a checksum for a string. CHKSUM is the current
359 checksum. */
361 static unsigned
362 checksum_string (unsigned chksum, const char *string)
366 unsigned value = *string << 24;
367 unsigned ix;
369 for (ix = 8; ix--; value <<= 1)
371 unsigned feedback;
373 feedback = (value ^ chksum) & 0x80000000 ? 0x04c11db7 : 0;
374 chksum <<= 1;
375 chksum ^= feedback;
378 while (*string++);
380 return chksum;
383 /* Compute checksum for the current function. We generate a CRC32. */
385 static unsigned
386 compute_checksum ()
388 unsigned chksum = DECL_SOURCE_LINE (current_function_decl);
390 chksum = checksum_string (chksum, DECL_SOURCE_FILE (current_function_decl));
391 chksum = checksum_string
392 (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
394 return chksum;
397 /* Begin output to the graph file for the current function.
398 Opens the output file, if not already done. Writes the
399 function header, if not already done. Returns non-zero if data
400 should be output. */
403 coverage_begin_output ()
405 if (!bbg_function_announced)
407 const char *file = DECL_SOURCE_FILE (current_function_decl);
408 unsigned line = DECL_SOURCE_LINE (current_function_decl);
409 unsigned long offset;
411 if (!bbg_file_opened)
413 if (!gcov_open (bbg_file_name, -1))
414 error ("cannot open %s", bbg_file_name);
415 else
417 gcov_write_unsigned (GCOV_GRAPH_MAGIC);
418 gcov_write_unsigned (GCOV_VERSION);
420 bbg_file_opened = 1;
423 /* Announce function */
424 offset = gcov_write_tag (GCOV_TAG_FUNCTION);
425 gcov_write_unsigned (fn_ident);
426 gcov_write_unsigned (compute_checksum ());
427 gcov_write_string (IDENTIFIER_POINTER
428 (DECL_ASSEMBLER_NAME (current_function_decl)));
429 gcov_write_string (file);
430 gcov_write_unsigned (line);
431 gcov_write_length (offset);
433 bbg_function_announced = 1;
435 return !gcov_is_error ();
438 /* Finish coverage data for the current function. Verify no output
439 error has occurred. Save function coverage counts. */
441 void
442 coverage_end_function ()
444 unsigned i;
446 if (bbg_file_opened > 1 && gcov_is_error ())
448 warning ("error writing `%s'", bbg_file_name);
449 bbg_file_opened = -1;
452 if (fn_ctr_mask)
454 struct function_list *item;
456 item = xmalloc (sizeof (struct function_list));
458 *functions_tail = item;
459 functions_tail = &item->next;
461 item->next = 0;
462 /* It would be nice to use the unique source location. */
463 item->ident = fn_ident;
464 item->checksum = compute_checksum ();
465 for (i = 0; i != GCOV_COUNTERS; i++)
467 item->n_ctrs[i] = fn_n_ctrs[i];
468 prg_n_ctrs[i] += fn_n_ctrs[i];
469 fn_n_ctrs[i] = 0;
471 prg_ctr_mask |= fn_ctr_mask;
472 fn_ctr_mask = 0;
474 bbg_function_announced = 0;
475 fn_ident++;
478 /* Creates the gcov_fn_info RECORD_TYPE. */
480 static tree
481 build_fn_info_type (counters)
482 unsigned counters;
484 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
485 tree field, fields;
486 tree array_type;
488 /* ident */
489 fields = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
491 /* checksum */
492 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
493 TREE_CHAIN (field) = fields;
494 fields = field;
496 array_type = build_index_type (build_int_2 (counters - 1, 0));
497 array_type = build_array_type (unsigned_type_node, array_type);
499 /* counters */
500 field = build_decl (FIELD_DECL, NULL_TREE, array_type);
501 TREE_CHAIN (field) = fields;
502 fields = field;
504 finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
506 return type;
509 /* Creates a CONSTRUCTOR for a gcov_fn_info. FUNCTION is
510 the function being processed and TYPE is the gcov_fn_info
511 RECORD_TYPE. */
513 static tree
514 build_fn_info_value (function, type)
515 const struct function_list *function;
516 tree type;
518 tree value = NULL_TREE;
519 tree fields = TYPE_FIELDS (type);
520 unsigned ix;
521 tree array_value = NULL_TREE;
523 /* ident */
524 value = tree_cons (fields,
525 convert (unsigned_type_node,
526 build_int_2 (function->ident, 0)),
527 value);
528 fields = TREE_CHAIN (fields);
530 /* checksum */
531 value = tree_cons (fields,
532 convert (unsigned_type_node,
533 build_int_2 (function->checksum, 0)),
534 value);
535 fields = TREE_CHAIN (fields);
537 /* counters */
538 for (ix = 0; ix != GCOV_COUNTERS; ix++)
539 if (prg_ctr_mask & (1 << ix))
541 tree counters = convert (unsigned_type_node,
542 build_int_2 (function->n_ctrs[ix], 0));
544 array_value = tree_cons (NULL_TREE, counters, array_value);
547 array_value = build_constructor (TREE_TYPE (fields), nreverse (array_value));
548 value = tree_cons (fields, array_value, value);
550 value = build_constructor (type, nreverse (value));
552 return value;
555 /* Creates the gcov_ctr_info RECORD_TYPE. */
557 static tree
558 build_ctr_info_type ()
560 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
561 tree field, fields = NULL_TREE;
563 /* counters */
564 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
565 TREE_CHAIN (field) = fields;
566 fields = field;
568 /* values */
569 field = build_decl (FIELD_DECL, NULL_TREE,
570 build_pointer_type (make_signed_type (GCOV_TYPE_SIZE)));
571 TREE_CHAIN (field) = fields;
572 fields = field;
574 finish_builtin_struct (type, "__gcov_ctr_info", fields, NULL_TREE);
576 return type;
579 /* Creates a CONSTRUCTOR for a gcov_ctr_info. COUNTER is
580 the counter being processed and TYPE is the gcov_ctr_info
581 RECORD_TYPE. */
583 static tree
584 build_ctr_info_value (counter, type)
585 unsigned counter;
586 tree type;
588 tree value = NULL_TREE;
589 tree fields = TYPE_FIELDS (type);
591 /* counters */
592 value = tree_cons (fields,
593 convert (unsigned_type_node,
594 build_int_2 (prg_n_ctrs[counter], 0)),
595 value);
596 fields = TREE_CHAIN (fields);
598 if (prg_n_ctrs[counter])
600 tree array_type, array;
602 array_type = build_index_type (build_int_2 (prg_n_ctrs[counter] - 1, 0));
603 array_type = build_array_type (TREE_TYPE (TREE_TYPE (fields)),
604 array_type);
606 array = build (VAR_DECL, array_type, NULL_TREE, NULL_TREE);
607 TREE_STATIC (array) = 1;
608 DECL_NAME (array) = get_identifier (XSTR (ctr_labels[counter], 0));
609 assemble_variable (array, 0, 0, 0);
611 value = tree_cons (fields,
612 build1 (ADDR_EXPR, TREE_TYPE (fields), array),
613 value);
615 else
616 value = tree_cons (fields, null_pointer_node, value);
618 value = build_constructor (type, nreverse (value));
620 return value;
623 /* Creates the gcov_info RECORD_TYPE and initializer for it. Returns a
624 CONSTRUCTOR. */
626 static tree
627 build_gcov_info ()
629 unsigned n_ctr_types, ix;
630 tree type, const_type;
631 tree fn_info_type, fn_info_value = NULL_TREE;
632 tree fn_info_ptr_type;
633 tree ctr_info_type, ctr_info_ary_type, ctr_info_value = NULL_TREE;
634 tree field, fields = NULL_TREE;
635 tree value = NULL_TREE;
636 tree filename_string;
637 char *filename;
638 int filename_len;
639 unsigned n_fns;
640 const struct function_list *fn;
641 tree string_type;
643 /* Count the number of active counters. */
644 for (n_ctr_types = 0, ix = 0; ix != GCOV_COUNTERS; ix++)
645 if (prg_ctr_mask & (1 << ix))
646 n_ctr_types++;
648 type = (*lang_hooks.types.make_type) (RECORD_TYPE);
649 const_type = build_qualified_type (type, TYPE_QUAL_CONST);
651 /* Version ident */
652 field = build_decl (FIELD_DECL, NULL_TREE, long_unsigned_type_node);
653 TREE_CHAIN (field) = fields;
654 fields = field;
655 value = tree_cons (field, convert (long_unsigned_type_node,
656 build_int_2 (GCOV_VERSION, 0)),
657 value);
659 /* next -- NULL */
660 field = build_decl (FIELD_DECL, NULL_TREE, build_pointer_type (const_type));
661 TREE_CHAIN (field) = fields;
662 fields = field;
663 value = tree_cons (field, null_pointer_node, value);
665 /* Filename */
666 string_type = build_pointer_type (build_qualified_type (char_type_node,
667 TYPE_QUAL_CONST));
668 field = build_decl (FIELD_DECL, NULL_TREE, string_type);
669 TREE_CHAIN (field) = fields;
670 fields = field;
671 filename = getpwd ();
672 filename = (filename && da_file_name[0] != '/'
673 ? concat (filename, "/", da_file_name, NULL)
674 : da_file_name);
675 filename_len = strlen (filename);
676 filename_string = build_string (filename_len + 1, filename);
677 if (filename != da_file_name)
678 free (filename);
679 TREE_TYPE (filename_string) =
680 build_array_type (char_type_node,
681 build_index_type (build_int_2 (filename_len, 0)));
682 value = tree_cons (field, build1 (ADDR_EXPR, string_type, filename_string),
683 value);
685 /* Build the fn_info type and initializer. */
686 fn_info_type = build_fn_info_type (n_ctr_types);
687 fn_info_ptr_type = build_pointer_type (build_qualified_type
688 (fn_info_type, TYPE_QUAL_CONST));
689 for (fn = functions_head, n_fns = 0; fn; fn = fn->next, n_fns++)
690 fn_info_value = tree_cons (NULL_TREE,
691 build_fn_info_value (fn, fn_info_type),
692 fn_info_value);
693 if (n_fns)
695 tree array_type;
697 array_type = build_index_type (build_int_2 (n_fns - 1, 0));
698 array_type = build_array_type (fn_info_type, array_type);
700 fn_info_value = build_constructor (array_type, nreverse (fn_info_value));
701 fn_info_value = build1 (ADDR_EXPR, fn_info_ptr_type, fn_info_value);
703 else
704 fn_info_value = null_pointer_node;
706 /* number of functions */
707 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
708 TREE_CHAIN (field) = fields;
709 fields = field;
710 value = tree_cons (field,
711 convert (unsigned_type_node, build_int_2 (n_fns, 0)),
712 value);
714 /* fn_info table */
715 field = build_decl (FIELD_DECL, NULL_TREE, fn_info_ptr_type);
716 TREE_CHAIN (field) = fields;
717 fields = field;
718 value = tree_cons (field, fn_info_value, value);
720 /* counter_mask */
721 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
722 TREE_CHAIN (field) = fields;
723 fields = field;
724 value = tree_cons (field,
725 convert (unsigned_type_node,
726 build_int_2 (prg_ctr_mask, 0)),
727 value);
729 /* counters */
730 ctr_info_type = build_ctr_info_type ();
731 ctr_info_ary_type = build_index_type (build_int_2 (n_ctr_types, 0));
732 ctr_info_ary_type = build_array_type (ctr_info_type, ctr_info_ary_type);
733 for (ix = 0; ix != GCOV_COUNTERS; ix++)
734 if (prg_ctr_mask & (1 << ix))
735 ctr_info_value = tree_cons (NULL_TREE,
736 build_ctr_info_value (ix, ctr_info_type),
737 ctr_info_value);
738 ctr_info_value = build_constructor (ctr_info_ary_type,
739 nreverse (ctr_info_value));
741 field = build_decl (FIELD_DECL, NULL_TREE, ctr_info_ary_type);
742 TREE_CHAIN (field) = fields;
743 fields = field;
744 value = tree_cons (field, ctr_info_value, value);
746 finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
748 value = build_constructor (type, nreverse (value));
750 return value;
753 /* Write out the structure which libgcov uses to locate all the
754 counters. The structures used here must match those defined in
755 gcov-io.h. Write out the constructor to call __gcov_init. */
757 static void
758 create_coverage ()
760 tree gcov_info, gcov_info_value;
761 char name[20];
762 char *ctor_name;
763 tree ctor;
764 rtx gcov_info_address;
765 int save_flag_inline_functions = flag_inline_functions;
767 if (!prg_ctr_mask)
768 return;
770 gcov_info_value = build_gcov_info ();
772 gcov_info = build (VAR_DECL, TREE_TYPE (gcov_info_value),
773 NULL_TREE, NULL_TREE);
774 DECL_INITIAL (gcov_info) = gcov_info_value;
776 TREE_STATIC (gcov_info) = 1;
777 ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 0);
778 DECL_NAME (gcov_info) = get_identifier (name);
780 /* Build structure. */
781 assemble_variable (gcov_info, 0, 0, 0);
783 /* Build the constructor function to invoke __gcov_init. */
784 ctor_name = concat (IDENTIFIER_POINTER (get_file_function_name ('I')),
785 "_GCOV", NULL);
786 ctor = build_decl (FUNCTION_DECL, get_identifier (ctor_name),
787 build_function_type (void_type_node, NULL_TREE));
788 free (ctor_name);
789 DECL_EXTERNAL (ctor) = 0;
791 /* It can be a static function as long as collect2 does not have
792 to scan the object file to find its ctor/dtor routine. */
793 TREE_PUBLIC (ctor) = ! targetm.have_ctors_dtors;
794 TREE_USED (ctor) = 1;
795 DECL_RESULT (ctor) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
797 ctor = (*lang_hooks.decls.pushdecl) (ctor);
798 rest_of_decl_compilation (ctor, 0, 1, 0);
799 announce_function (ctor);
800 current_function_decl = ctor;
801 DECL_INITIAL (ctor) = error_mark_node;
802 make_decl_rtl (ctor, NULL);
803 init_function_start (ctor, input_filename, lineno);
804 (*lang_hooks.decls.pushlevel) (0);
805 expand_function_start (ctor, 0);
806 cfun->arc_profile = 0;
808 /* Actually generate the code to call __gcov_init. */
809 gcov_info_address = force_reg (Pmode, XEXP (DECL_RTL (gcov_info), 0));
810 emit_library_call (gcov_init_libfunc, LCT_NORMAL, VOIDmode, 1,
811 gcov_info_address, Pmode);
813 expand_function_end (input_filename, lineno, 0);
814 (*lang_hooks.decls.poplevel) (1, 0, 1);
816 /* Since ctor isn't in the list of globals, it would never be emitted
817 when it's considered to be 'safe' for inlining, so turn off
818 flag_inline_functions. */
819 flag_inline_functions = 0;
821 rest_of_compilation (ctor);
823 /* Reset flag_inline_functions to its original value. */
824 flag_inline_functions = save_flag_inline_functions;
826 if (! quiet_flag)
827 fflush (asm_out_file);
828 current_function_decl = NULL_TREE;
830 if (targetm.have_ctors_dtors)
831 (* targetm.asm_out.constructor) (XEXP (DECL_RTL (ctor), 0),
832 DEFAULT_INIT_PRIORITY);
835 /* Perform file-level initialization. Read in data file, generate name
836 of graph file. */
838 void
839 coverage_init (filename)
840 const char *filename;
842 int len = strlen (filename);
844 /* Name of da file. */
845 da_file_name = (char *) xmalloc (len + strlen (GCOV_DATA_SUFFIX) + 1);
846 strcpy (da_file_name, filename);
847 strcat (da_file_name, GCOV_DATA_SUFFIX);
849 /* Name of bbg file. */
850 bbg_file_name = (char *) xmalloc (len + strlen (GCOV_GRAPH_SUFFIX) + 1);
851 strcpy (bbg_file_name, filename);
852 strcat (bbg_file_name, GCOV_GRAPH_SUFFIX);
854 read_counts_file ();
857 /* Performs file-level cleanup. Close graph file, generate coverage
858 variables and constructor. */
860 void
861 coverage_finish ()
863 create_coverage ();
864 if (bbg_file_opened)
866 int error = gcov_close ();
868 if (error)
869 unlink (bbg_file_name);
870 #if SELF_COVERAGE
871 /* If the compiler is instrumented, we should not
872 unconditionally remove the counts file, because we might be
873 recompiling ourselves. The .da files are all removed during
874 copying the stage1 files. */
875 if (error)
876 #endif
877 unlink (da_file_name);
881 #include "gt-coverage.h"