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
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
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
31 #include "coretypes.h"
45 #include "langhooks.h"
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
68 struct gcov_ctr_summary summary
;
71 struct counts_entry
*chain
;
75 static struct function_list
*functions_head
= 0;
76 static struct function_list
**functions_tail
= &functions_head
;
77 static unsigned no_coverage
= 0;
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
]; /* Total counters allocated. */
83 /* Counter information for current function. */
84 static unsigned fn_ctr_mask
; /* Mask of counters used. */
85 static unsigned fn_n_ctrs
[GCOV_COUNTERS
]; /* Counters allocated. */
86 static unsigned fn_b_ctrs
[GCOV_COUNTERS
]; /* Allocation base. */
88 /* Name of the output file for coverage output file. */
89 static char *bbg_file_name
;
90 static unsigned bbg_file_opened
;
91 static int bbg_function_announced
;
93 /* Name of the count data file. */
94 static char *da_file_name
;
96 /* Hash table of count data. */
97 static htab_t counts_hash
= NULL
;
99 /* The names of the counter tables. */
100 static GTY(()) rtx ctr_labels
[GCOV_COUNTERS
];
102 /* The names of merge functions for counters. */
103 static const char *const ctr_merge_functions
[GCOV_COUNTERS
] = GCOV_MERGE_FUNCTIONS
;
104 static const char *const ctr_names
[GCOV_COUNTERS
] = GCOV_COUNTER_NAMES
;
106 /* Forward declarations. */
107 static hashval_t htab_counts_entry_hash
PARAMS ((const void *));
108 static int htab_counts_entry_eq
PARAMS ((const void *, const void *));
109 static void htab_counts_entry_del
PARAMS ((void *));
110 static void read_counts_file
PARAMS ((void));
111 static unsigned compute_checksum
PARAMS ((void));
112 static unsigned checksum_string
PARAMS ((unsigned, const char *));
113 static tree build_fn_info_type
PARAMS ((unsigned));
114 static tree build_fn_info_value
PARAMS ((const struct function_list
*, tree
));
115 static tree build_ctr_info_type
PARAMS ((void));
116 static tree build_ctr_info_value
PARAMS ((unsigned, tree
));
117 static tree build_gcov_info
PARAMS ((void));
118 static void create_coverage
PARAMS ((void));
122 htab_counts_entry_hash (of
)
125 const counts_entry_t
*entry
= of
;
127 return entry
->ident
* GCOV_COUNTERS
+ entry
->ctr
;
131 htab_counts_entry_eq (of1
, of2
)
135 const counts_entry_t
*entry1
= of1
;
136 const counts_entry_t
*entry2
= of2
;
138 return entry1
->ident
== entry2
->ident
&& entry1
->ctr
== entry2
->ctr
;
142 htab_counts_entry_del (of
)
145 counts_entry_t
*entry
= of
;
147 free (entry
->counts
);
151 /* Read in the counts file, if available. */
156 gcov_unsigned_t fn_ident
= 0;
157 gcov_unsigned_t version
, checksum
= -1;
159 counts_entry_t
*summaried
= NULL
;
160 unsigned seen_summary
= 0;
162 if (!gcov_open (da_file_name
, 1))
165 if (gcov_read_unsigned () != GCOV_DATA_MAGIC
)
167 warning ("`%s' is not a gcov data file", da_file_name
);
171 else if ((version
= gcov_read_unsigned ()) != GCOV_VERSION
)
174 gcov_unsigned_t required
= GCOV_VERSION
;
176 for (ix
= 4; ix
--; required
>>= 8, version
>>= 8)
181 warning ("`%s' is version `%.4s', expected version `%.4s'",
187 counts_hash
= htab_create (10,
188 htab_counts_entry_hash
, htab_counts_entry_eq
,
189 htab_counts_entry_del
);
190 while (!gcov_is_eof ())
192 gcov_unsigned_t tag
, length
;
193 gcov_position_t offset
;
196 tag
= gcov_read_unsigned ();
197 length
= gcov_read_unsigned ();
198 offset
= gcov_position ();
199 if (tag
== GCOV_TAG_FUNCTION
)
201 fn_ident
= gcov_read_unsigned ();
202 checksum
= gcov_read_unsigned ();
205 /* We have already seen a summary, this means that this
206 new function begins a new set of program runs. We
207 must unlink the summaried chain. */
208 counts_entry_t
*entry
, *chain
;
210 for (entry
= summaried
; entry
; entry
= chain
)
212 chain
= entry
->chain
;
219 else if (tag
== GCOV_TAG_PROGRAM_SUMMARY
)
221 counts_entry_t
*entry
;
222 struct gcov_summary summary
;
224 gcov_read_summary (&summary
);
226 for (entry
= summaried
; entry
; entry
= entry
->chain
)
228 struct gcov_ctr_summary
*csum
= &summary
.ctrs
[entry
->ctr
];
230 entry
->summary
.runs
+= csum
->runs
;
231 entry
->summary
.sum_all
+= csum
->sum_all
;
232 if (entry
->summary
.run_max
< csum
->run_max
)
233 entry
->summary
.run_max
= csum
->run_max
;
234 entry
->summary
.sum_max
+= csum
->sum_max
;
237 else if (GCOV_TAG_IS_COUNTER (tag
) && fn_ident
)
239 counts_entry_t
**slot
, *entry
, elt
;
240 unsigned n_counts
= length
/ 8;
243 elt
.ident
= fn_ident
;
244 elt
.ctr
= GCOV_COUNTER_FOR_TAG (tag
);
246 slot
= (counts_entry_t
**) htab_find_slot
247 (counts_hash
, &elt
, INSERT
);
251 *slot
= entry
= xcalloc (1, sizeof (counts_entry_t
));
252 entry
->ident
= elt
.ident
;
253 entry
->ctr
= elt
.ctr
;
254 entry
->checksum
= checksum
;
255 entry
->summary
.num
= n_counts
;
256 entry
->counts
= xcalloc (n_counts
, sizeof (gcov_type
));
258 else if (entry
->checksum
!= checksum
259 || entry
->summary
.num
!= n_counts
)
261 warning ("coverage mismatch for function %u", fn_ident
);
262 htab_delete (counts_hash
);
265 else if (elt
.ctr
>= GCOV_COUNTERS_SUMMABLE
)
267 warning ("cannot merge separate %s counters for function %u",
268 ctr_names
[elt
.ctr
], fn_ident
);
272 if (elt
.ctr
< GCOV_COUNTERS_SUMMABLE
273 /* This should always be true for a just allocated entry,
274 and always false for an existing one. Check this way, in
275 case the gcov file is corrupt. */
276 && (!entry
->chain
|| summaried
!= entry
))
278 entry
->chain
= summaried
;
281 for (ix
= 0; ix
!= n_counts
; ix
++)
282 entry
->counts
[ix
] += gcov_read_counter ();
285 gcov_sync (offset
, length
);
286 if ((error
= gcov_is_error ()))
288 warning (error
< 0 ? "`%s' has overflowed" : "`%s' is corrupted",
290 htab_delete (counts_hash
);
298 /* Returns the counters for a particular tag. */
301 get_coverage_counts (unsigned counter
, unsigned expected
,
302 const struct gcov_ctr_summary
**summary
)
304 counts_entry_t
*entry
, elt
;
306 /* No hash table, no counts. */
309 static int warned
= 0;
312 warning ("file %s not found, execution counts assumed to be zero",
317 elt
.ident
= current_function_funcdef_no
+ 1;
319 entry
= htab_find (counts_hash
, &elt
);
322 warning ("no coverage for function '%s' found.", IDENTIFIER_POINTER
323 (DECL_ASSEMBLER_NAME (current_function_decl
)));
327 if (expected
!= entry
->summary
.num
328 || compute_checksum () != entry
->checksum
)
330 warning ("coverage mismatch for `%s'", IDENTIFIER_POINTER
331 (DECL_ASSEMBLER_NAME (current_function_decl
)));
336 *summary
= &entry
->summary
;
338 return entry
->counts
;
341 /* Allocate NUM counters of type COUNTER. Returns non-zero if the
342 allocation succeeded. */
345 coverage_counter_alloc (unsigned counter
, unsigned num
)
353 if (!ctr_labels
[counter
])
355 /* Generate and save a copy of this so it can be shared. */
358 ASM_GENERATE_INTERNAL_LABEL (buf
, "LPBX", counter
+ 1);
359 ctr_labels
[counter
] = gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
361 fn_b_ctrs
[counter
] = fn_n_ctrs
[counter
];
362 fn_n_ctrs
[counter
] += num
;
363 fn_ctr_mask
|= 1 << counter
;
367 /* Generate a MEM rtl to access COUNTER NO. */
370 coverage_counter_ref (unsigned counter
, unsigned no
)
372 unsigned gcov_size
= tree_low_cst (TYPE_SIZE (GCOV_TYPE_NODE
), 1);
373 enum machine_mode mode
= mode_for_size (gcov_size
, MODE_INT
, 0);
376 if (no
>= fn_n_ctrs
[counter
] - fn_b_ctrs
[counter
])
378 no
+= prg_n_ctrs
[counter
] + fn_b_ctrs
[counter
];
379 ref
= plus_constant (ctr_labels
[counter
], gcov_size
/ BITS_PER_UNIT
* no
);
380 ref
= gen_rtx_MEM (mode
, ref
);
381 set_mem_alias_set (ref
, new_alias_set ());
386 /* Generate a checksum for a string. CHKSUM is the current
390 checksum_string (unsigned chksum
, const char *string
)
394 unsigned value
= *string
<< 24;
397 for (ix
= 8; ix
--; value
<<= 1)
401 feedback
= (value
^ chksum
) & 0x80000000 ? 0x04c11db7 : 0;
411 /* Compute checksum for the current function. We generate a CRC32. */
416 unsigned chksum
= DECL_SOURCE_LINE (current_function_decl
);
418 chksum
= checksum_string (chksum
, DECL_SOURCE_FILE (current_function_decl
));
419 chksum
= checksum_string
420 (chksum
, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl
)));
425 /* Begin output to the graph file for the current function.
426 Opens the output file, if not already done. Writes the
427 function header, if not already done. Returns non-zero if data
431 coverage_begin_output ()
436 if (!bbg_function_announced
)
438 const char *file
= DECL_SOURCE_FILE (current_function_decl
);
439 unsigned line
= DECL_SOURCE_LINE (current_function_decl
);
440 unsigned long offset
;
442 if (!bbg_file_opened
)
444 if (!gcov_open (bbg_file_name
, -1))
445 error ("cannot open %s", bbg_file_name
);
448 gcov_write_unsigned (GCOV_GRAPH_MAGIC
);
449 gcov_write_unsigned (GCOV_VERSION
);
454 /* Announce function */
455 offset
= gcov_write_tag (GCOV_TAG_FUNCTION
);
456 gcov_write_unsigned (current_function_funcdef_no
+ 1);
457 gcov_write_unsigned (compute_checksum ());
458 gcov_write_string (IDENTIFIER_POINTER
459 (DECL_ASSEMBLER_NAME (current_function_decl
)));
460 gcov_write_string (file
);
461 gcov_write_unsigned (line
);
462 gcov_write_length (offset
);
464 bbg_function_announced
= 1;
466 return !gcov_is_error ();
469 /* Finish coverage data for the current function. Verify no output
470 error has occurred. Save function coverage counts. */
473 coverage_end_function ()
477 if (bbg_file_opened
> 1 && gcov_is_error ())
479 warning ("error writing `%s'", bbg_file_name
);
480 bbg_file_opened
= -1;
485 struct function_list
*item
;
487 item
= xmalloc (sizeof (struct function_list
));
489 *functions_tail
= item
;
490 functions_tail
= &item
->next
;
493 item
->ident
= current_function_funcdef_no
+ 1;
494 item
->checksum
= compute_checksum ();
495 for (i
= 0; i
!= GCOV_COUNTERS
; i
++)
497 item
->n_ctrs
[i
] = fn_n_ctrs
[i
];
498 prg_n_ctrs
[i
] += fn_n_ctrs
[i
];
499 fn_n_ctrs
[i
] = fn_b_ctrs
[i
] = 0;
501 prg_ctr_mask
|= fn_ctr_mask
;
504 bbg_function_announced
= 0;
507 /* Creates the gcov_fn_info RECORD_TYPE. */
510 build_fn_info_type (counters
)
513 tree type
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
518 fields
= build_decl (FIELD_DECL
, NULL_TREE
, unsigned_intSI_type_node
);
521 field
= build_decl (FIELD_DECL
, NULL_TREE
, unsigned_intSI_type_node
);
522 TREE_CHAIN (field
) = fields
;
525 array_type
= build_index_type (build_int_2 (counters
- 1, 0));
526 array_type
= build_array_type (unsigned_type_node
, array_type
);
529 field
= build_decl (FIELD_DECL
, NULL_TREE
, array_type
);
530 TREE_CHAIN (field
) = fields
;
533 finish_builtin_struct (type
, "__gcov_fn_info", fields
, NULL_TREE
);
538 /* Creates a CONSTRUCTOR for a gcov_fn_info. FUNCTION is
539 the function being processed and TYPE is the gcov_fn_info
543 build_fn_info_value (function
, type
)
544 const struct function_list
*function
;
547 tree value
= NULL_TREE
;
548 tree fields
= TYPE_FIELDS (type
);
550 tree array_value
= NULL_TREE
;
553 value
= tree_cons (fields
,
554 convert (unsigned_intSI_type_node
,
555 build_int_2 (function
->ident
, 0)),
557 fields
= TREE_CHAIN (fields
);
560 value
= tree_cons (fields
,
561 convert (unsigned_intSI_type_node
,
562 build_int_2 (function
->checksum
, 0)),
564 fields
= TREE_CHAIN (fields
);
567 for (ix
= 0; ix
!= GCOV_COUNTERS
; ix
++)
568 if (prg_ctr_mask
& (1 << ix
))
570 tree counters
= convert (unsigned_type_node
,
571 build_int_2 (function
->n_ctrs
[ix
], 0));
573 array_value
= tree_cons (NULL_TREE
, counters
, array_value
);
576 array_value
= build_constructor (TREE_TYPE (fields
), nreverse (array_value
));
577 value
= tree_cons (fields
, array_value
, value
);
579 value
= build_constructor (type
, nreverse (value
));
584 /* Creates the gcov_ctr_info RECORD_TYPE. */
587 build_ctr_info_type ()
589 tree type
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
590 tree field
, fields
= NULL_TREE
;
591 tree gcov_ptr_type
= build_pointer_type (GCOV_TYPE_NODE
);
592 tree gcov_merge_fn_type
;
595 field
= build_decl (FIELD_DECL
, NULL_TREE
, unsigned_intSI_type_node
);
596 TREE_CHAIN (field
) = fields
;
600 field
= build_decl (FIELD_DECL
, NULL_TREE
, gcov_ptr_type
);
601 TREE_CHAIN (field
) = fields
;
606 build_function_type_list (void_type_node
,
607 gcov_ptr_type
, unsigned_type_node
,
609 field
= build_decl (FIELD_DECL
, NULL_TREE
,
610 build_pointer_type (gcov_merge_fn_type
));
611 TREE_CHAIN (field
) = fields
;
614 finish_builtin_struct (type
, "__gcov_ctr_info", fields
, NULL_TREE
);
619 /* Creates a CONSTRUCTOR for a gcov_ctr_info. COUNTER is
620 the counter being processed and TYPE is the gcov_ctr_info
624 build_ctr_info_value (counter
, type
)
628 tree value
= NULL_TREE
;
629 tree fields
= TYPE_FIELDS (type
);
633 value
= tree_cons (fields
,
634 convert (unsigned_intSI_type_node
,
635 build_int_2 (prg_n_ctrs
[counter
], 0)),
637 fields
= TREE_CHAIN (fields
);
639 if (prg_n_ctrs
[counter
])
641 tree array_type
, array
;
643 array_type
= build_index_type (build_int_2 (prg_n_ctrs
[counter
] - 1, 0));
644 array_type
= build_array_type (TREE_TYPE (TREE_TYPE (fields
)),
647 array
= build (VAR_DECL
, array_type
, NULL_TREE
, NULL_TREE
);
648 TREE_STATIC (array
) = 1;
649 DECL_NAME (array
) = get_identifier (XSTR (ctr_labels
[counter
], 0));
650 assemble_variable (array
, 0, 0, 0);
652 value
= tree_cons (fields
,
653 build1 (ADDR_EXPR
, TREE_TYPE (fields
), array
),
657 value
= tree_cons (fields
, null_pointer_node
, value
);
658 fields
= TREE_CHAIN (fields
);
660 fn
= build_decl (FUNCTION_DECL
,
661 get_identifier (ctr_merge_functions
[counter
]),
662 TREE_TYPE (TREE_TYPE (fields
)));
663 DECL_EXTERNAL (fn
) = 1;
664 TREE_PUBLIC (fn
) = 1;
665 DECL_ARTIFICIAL (fn
) = 1;
666 TREE_NOTHROW (fn
) = 1;
667 value
= tree_cons (fields
,
668 build1 (ADDR_EXPR
, TREE_TYPE (fields
), fn
),
671 value
= build_constructor (type
, nreverse (value
));
676 /* Creates the gcov_info RECORD_TYPE and initializer for it. Returns a
682 unsigned n_ctr_types
, ix
;
683 tree type
, const_type
;
684 tree fn_info_type
, fn_info_value
= NULL_TREE
;
685 tree fn_info_ptr_type
;
686 tree ctr_info_type
, ctr_info_ary_type
, ctr_info_value
= NULL_TREE
;
687 tree field
, fields
= NULL_TREE
;
688 tree value
= NULL_TREE
;
689 tree filename_string
;
693 const struct function_list
*fn
;
696 /* Count the number of active counters. */
697 for (n_ctr_types
= 0, ix
= 0; ix
!= GCOV_COUNTERS
; ix
++)
698 if (prg_ctr_mask
& (1 << ix
))
701 type
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
702 const_type
= build_qualified_type (type
, TYPE_QUAL_CONST
);
705 field
= build_decl (FIELD_DECL
, NULL_TREE
, unsigned_intSI_type_node
);
706 TREE_CHAIN (field
) = fields
;
708 value
= tree_cons (field
, convert (unsigned_intSI_type_node
,
709 build_int_2 (GCOV_VERSION
, 0)),
713 field
= build_decl (FIELD_DECL
, NULL_TREE
, build_pointer_type (const_type
));
714 TREE_CHAIN (field
) = fields
;
716 value
= tree_cons (field
, null_pointer_node
, value
);
719 string_type
= build_pointer_type (build_qualified_type (char_type_node
,
721 field
= build_decl (FIELD_DECL
, NULL_TREE
, string_type
);
722 TREE_CHAIN (field
) = fields
;
724 filename
= getpwd ();
725 filename
= (filename
&& da_file_name
[0] != '/'
726 ? concat (filename
, "/", da_file_name
, NULL
)
728 filename_len
= strlen (filename
);
729 filename_string
= build_string (filename_len
+ 1, filename
);
730 if (filename
!= da_file_name
)
732 TREE_TYPE (filename_string
) =
733 build_array_type (char_type_node
,
734 build_index_type (build_int_2 (filename_len
, 0)));
735 value
= tree_cons (field
, build1 (ADDR_EXPR
, string_type
, filename_string
),
738 /* Build the fn_info type and initializer. */
739 fn_info_type
= build_fn_info_type (n_ctr_types
);
740 fn_info_ptr_type
= build_pointer_type (build_qualified_type
741 (fn_info_type
, TYPE_QUAL_CONST
));
742 for (fn
= functions_head
, n_fns
= 0; fn
; fn
= fn
->next
, n_fns
++)
743 fn_info_value
= tree_cons (NULL_TREE
,
744 build_fn_info_value (fn
, fn_info_type
),
750 array_type
= build_index_type (build_int_2 (n_fns
- 1, 0));
751 array_type
= build_array_type (fn_info_type
, array_type
);
753 fn_info_value
= build_constructor (array_type
, nreverse (fn_info_value
));
754 fn_info_value
= build1 (ADDR_EXPR
, fn_info_ptr_type
, fn_info_value
);
757 fn_info_value
= null_pointer_node
;
759 /* number of functions */
760 field
= build_decl (FIELD_DECL
, NULL_TREE
, unsigned_type_node
);
761 TREE_CHAIN (field
) = fields
;
763 value
= tree_cons (field
,
764 convert (unsigned_type_node
, build_int_2 (n_fns
, 0)),
768 field
= build_decl (FIELD_DECL
, NULL_TREE
, fn_info_ptr_type
);
769 TREE_CHAIN (field
) = fields
;
771 value
= tree_cons (field
, fn_info_value
, value
);
774 field
= build_decl (FIELD_DECL
, NULL_TREE
, unsigned_type_node
);
775 TREE_CHAIN (field
) = fields
;
777 value
= tree_cons (field
,
778 convert (unsigned_type_node
,
779 build_int_2 (prg_ctr_mask
, 0)),
783 ctr_info_type
= build_ctr_info_type ();
784 ctr_info_ary_type
= build_index_type (build_int_2 (n_ctr_types
, 0));
785 ctr_info_ary_type
= build_array_type (ctr_info_type
, ctr_info_ary_type
);
786 for (ix
= 0; ix
!= GCOV_COUNTERS
; ix
++)
787 if (prg_ctr_mask
& (1 << ix
))
788 ctr_info_value
= tree_cons (NULL_TREE
,
789 build_ctr_info_value (ix
, ctr_info_type
),
791 ctr_info_value
= build_constructor (ctr_info_ary_type
,
792 nreverse (ctr_info_value
));
794 field
= build_decl (FIELD_DECL
, NULL_TREE
, ctr_info_ary_type
);
795 TREE_CHAIN (field
) = fields
;
797 value
= tree_cons (field
, ctr_info_value
, value
);
799 finish_builtin_struct (type
, "__gcov_info", fields
, NULL_TREE
);
801 value
= build_constructor (type
, nreverse (value
));
806 /* Write out the structure which libgcov uses to locate all the
807 counters. The structures used here must match those defined in
808 gcov-io.h. Write out the constructor to call __gcov_init. */
813 tree gcov_info
, gcov_info_value
;
817 rtx gcov_info_address
;
819 no_coverage
= 1; /* Disable any further coverage. */
824 gcov_info_value
= build_gcov_info ();
826 gcov_info
= build (VAR_DECL
, TREE_TYPE (gcov_info_value
),
827 NULL_TREE
, NULL_TREE
);
828 DECL_INITIAL (gcov_info
) = gcov_info_value
;
830 TREE_STATIC (gcov_info
) = 1;
831 ASM_GENERATE_INTERNAL_LABEL (name
, "LPBX", 0);
832 DECL_NAME (gcov_info
) = get_identifier (name
);
834 /* Build structure. */
835 assemble_variable (gcov_info
, 0, 0, 0);
837 /* Build the constructor function to invoke __gcov_init. */
838 ctor_name
= concat (IDENTIFIER_POINTER (get_file_function_name ('I')),
840 ctor
= build_decl (FUNCTION_DECL
, get_identifier (ctor_name
),
841 build_function_type (void_type_node
, NULL_TREE
));
843 DECL_EXTERNAL (ctor
) = 0;
845 /* It can be a static function as long as collect2 does not have
846 to scan the object file to find its ctor/dtor routine. */
847 TREE_PUBLIC (ctor
) = ! targetm
.have_ctors_dtors
;
848 TREE_USED (ctor
) = 1;
849 DECL_RESULT (ctor
) = build_decl (RESULT_DECL
, NULL_TREE
, void_type_node
);
850 DECL_UNINLINABLE (ctor
) = 1;
852 ctor
= (*lang_hooks
.decls
.pushdecl
) (ctor
);
853 rest_of_decl_compilation (ctor
, 0, 1, 0);
854 announce_function (ctor
);
855 current_function_decl
= ctor
;
856 DECL_INITIAL (ctor
) = error_mark_node
;
857 make_decl_rtl (ctor
, NULL
);
858 init_function_start (ctor
, input_filename
, input_line
);
859 (*lang_hooks
.decls
.pushlevel
) (0);
860 expand_function_start (ctor
, 0);
862 /* Actually generate the code to call __gcov_init. */
863 gcov_info_address
= force_reg (Pmode
, XEXP (DECL_RTL (gcov_info
), 0));
864 emit_library_call (gcov_init_libfunc
, LCT_NORMAL
, VOIDmode
, 1,
865 gcov_info_address
, Pmode
);
867 expand_function_end (input_filename
, input_line
, 0);
868 (*lang_hooks
.decls
.poplevel
) (1, 0, 1);
870 rest_of_compilation (ctor
);
873 fflush (asm_out_file
);
874 current_function_decl
= NULL_TREE
;
876 if (targetm
.have_ctors_dtors
)
877 (* targetm
.asm_out
.constructor
) (XEXP (DECL_RTL (ctor
), 0),
878 DEFAULT_INIT_PRIORITY
);
881 /* Perform file-level initialization. Read in data file, generate name
885 coverage_init (filename
)
886 const char *filename
;
888 int len
= strlen (filename
);
890 /* Name of da file. */
891 da_file_name
= (char *) xmalloc (len
+ strlen (GCOV_DATA_SUFFIX
) + 1);
892 strcpy (da_file_name
, filename
);
893 strcat (da_file_name
, GCOV_DATA_SUFFIX
);
895 /* Name of bbg file. */
896 bbg_file_name
= (char *) xmalloc (len
+ strlen (GCOV_GRAPH_SUFFIX
) + 1);
897 strcpy (bbg_file_name
, filename
);
898 strcat (bbg_file_name
, GCOV_GRAPH_SUFFIX
);
903 /* Performs file-level cleanup. Close graph file, generate coverage
904 variables and constructor. */
912 int error
= gcov_close ();
915 unlink (bbg_file_name
);
917 /* If the compiler is instrumented, we should not
918 unconditionally remove the counts file, because we might be
919 recompiling ourselves. The .da files are all removed during
920 copying the stage1 files. */
923 unlink (da_file_name
);
927 #include "gt-coverage.h"