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;
164 if (!gcov_open (da_file_name
, 1))
167 if (gcov_read_unsigned () != GCOV_DATA_MAGIC
)
169 warning ("`%s' is not a gcov data file", da_file_name
);
173 else if ((version
= gcov_read_unsigned ()) != GCOV_VERSION
)
176 gcov_unsigned_t required
= GCOV_VERSION
;
178 for (ix
= 4; ix
--; required
>>= 8, version
>>= 8)
183 warning ("`%s' is version `%.4s', expected version `%.4s'",
189 counts_hash
= htab_create (10,
190 htab_counts_entry_hash
, htab_counts_entry_eq
,
191 htab_counts_entry_del
);
192 while ((tag
= gcov_read_unsigned ()))
194 gcov_unsigned_t length
;
195 gcov_position_t offset
;
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 ()))
292 warning (error
< 0 ? "`%s' has overflowed" : "`%s' is corrupted",
294 htab_delete (counts_hash
);
300 /* Returns the counters for a particular tag. */
303 get_coverage_counts (unsigned counter
, unsigned expected
,
304 const struct gcov_ctr_summary
**summary
)
306 counts_entry_t
*entry
, elt
;
308 /* No hash table, no counts. */
311 static int warned
= 0;
314 warning ("file %s not found, execution counts assumed to be zero",
319 elt
.ident
= current_function_funcdef_no
+ 1;
321 entry
= htab_find (counts_hash
, &elt
);
324 warning ("no coverage for function '%s' found.", IDENTIFIER_POINTER
325 (DECL_ASSEMBLER_NAME (current_function_decl
)));
329 if (expected
!= entry
->summary
.num
330 || compute_checksum () != entry
->checksum
)
332 warning ("coverage mismatch for `%s'", IDENTIFIER_POINTER
333 (DECL_ASSEMBLER_NAME (current_function_decl
)));
338 *summary
= &entry
->summary
;
340 return entry
->counts
;
343 /* Allocate NUM counters of type COUNTER. Returns non-zero if the
344 allocation succeeded. */
347 coverage_counter_alloc (unsigned counter
, unsigned num
)
355 if (!ctr_labels
[counter
])
357 /* Generate and save a copy of this so it can be shared. */
360 ASM_GENERATE_INTERNAL_LABEL (buf
, "LPBX", counter
+ 1);
361 ctr_labels
[counter
] = gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
363 fn_b_ctrs
[counter
] = fn_n_ctrs
[counter
];
364 fn_n_ctrs
[counter
] += num
;
365 fn_ctr_mask
|= 1 << counter
;
369 /* Generate a MEM rtl to access COUNTER NO. */
372 coverage_counter_ref (unsigned counter
, unsigned no
)
374 unsigned gcov_size
= tree_low_cst (TYPE_SIZE (GCOV_TYPE_NODE
), 1);
375 enum machine_mode mode
= mode_for_size (gcov_size
, MODE_INT
, 0);
378 if (no
>= fn_n_ctrs
[counter
] - fn_b_ctrs
[counter
])
380 no
+= prg_n_ctrs
[counter
] + fn_b_ctrs
[counter
];
381 ref
= plus_constant (ctr_labels
[counter
], gcov_size
/ BITS_PER_UNIT
* no
);
382 ref
= gen_rtx_MEM (mode
, ref
);
383 set_mem_alias_set (ref
, new_alias_set ());
388 /* Generate a checksum for a string. CHKSUM is the current
392 checksum_string (unsigned chksum
, const char *string
)
396 unsigned value
= *string
<< 24;
399 for (ix
= 8; ix
--; value
<<= 1)
403 feedback
= (value
^ chksum
) & 0x80000000 ? 0x04c11db7 : 0;
413 /* Compute checksum for the current function. We generate a CRC32. */
418 unsigned chksum
= DECL_SOURCE_LINE (current_function_decl
);
420 chksum
= checksum_string (chksum
, DECL_SOURCE_FILE (current_function_decl
));
421 chksum
= checksum_string
422 (chksum
, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl
)));
427 /* Begin output to the graph file for the current function.
428 Opens the output file, if not already done. Writes the
429 function header, if not already done. Returns non-zero if data
433 coverage_begin_output ()
438 if (!bbg_function_announced
)
440 const char *file
= DECL_SOURCE_FILE (current_function_decl
);
441 unsigned line
= DECL_SOURCE_LINE (current_function_decl
);
442 unsigned long offset
;
444 if (!bbg_file_opened
)
446 if (!gcov_open (bbg_file_name
, -1))
447 error ("cannot open %s", bbg_file_name
);
450 gcov_write_unsigned (GCOV_GRAPH_MAGIC
);
451 gcov_write_unsigned (GCOV_VERSION
);
456 /* Announce function */
457 offset
= gcov_write_tag (GCOV_TAG_FUNCTION
);
458 gcov_write_unsigned (current_function_funcdef_no
+ 1);
459 gcov_write_unsigned (compute_checksum ());
460 gcov_write_string (IDENTIFIER_POINTER
461 (DECL_ASSEMBLER_NAME (current_function_decl
)));
462 gcov_write_string (file
);
463 gcov_write_unsigned (line
);
464 gcov_write_length (offset
);
466 bbg_function_announced
= 1;
468 return !gcov_is_error ();
471 /* Finish coverage data for the current function. Verify no output
472 error has occurred. Save function coverage counts. */
475 coverage_end_function ()
479 if (bbg_file_opened
> 1 && gcov_is_error ())
481 warning ("error writing `%s'", bbg_file_name
);
482 bbg_file_opened
= -1;
487 struct function_list
*item
;
489 item
= xmalloc (sizeof (struct function_list
));
491 *functions_tail
= item
;
492 functions_tail
= &item
->next
;
495 item
->ident
= current_function_funcdef_no
+ 1;
496 item
->checksum
= compute_checksum ();
497 for (i
= 0; i
!= GCOV_COUNTERS
; i
++)
499 item
->n_ctrs
[i
] = fn_n_ctrs
[i
];
500 prg_n_ctrs
[i
] += fn_n_ctrs
[i
];
501 fn_n_ctrs
[i
] = fn_b_ctrs
[i
] = 0;
503 prg_ctr_mask
|= fn_ctr_mask
;
506 bbg_function_announced
= 0;
509 /* Creates the gcov_fn_info RECORD_TYPE. */
512 build_fn_info_type (counters
)
515 tree type
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
520 fields
= build_decl (FIELD_DECL
, NULL_TREE
, unsigned_intSI_type_node
);
523 field
= build_decl (FIELD_DECL
, NULL_TREE
, unsigned_intSI_type_node
);
524 TREE_CHAIN (field
) = fields
;
527 array_type
= build_index_type (build_int_2 (counters
- 1, 0));
528 array_type
= build_array_type (unsigned_type_node
, array_type
);
531 field
= build_decl (FIELD_DECL
, NULL_TREE
, array_type
);
532 TREE_CHAIN (field
) = fields
;
535 finish_builtin_struct (type
, "__gcov_fn_info", fields
, NULL_TREE
);
540 /* Creates a CONSTRUCTOR for a gcov_fn_info. FUNCTION is
541 the function being processed and TYPE is the gcov_fn_info
545 build_fn_info_value (function
, type
)
546 const struct function_list
*function
;
549 tree value
= NULL_TREE
;
550 tree fields
= TYPE_FIELDS (type
);
552 tree array_value
= NULL_TREE
;
555 value
= tree_cons (fields
,
556 convert (unsigned_intSI_type_node
,
557 build_int_2 (function
->ident
, 0)),
559 fields
= TREE_CHAIN (fields
);
562 value
= tree_cons (fields
,
563 convert (unsigned_intSI_type_node
,
564 build_int_2 (function
->checksum
, 0)),
566 fields
= TREE_CHAIN (fields
);
569 for (ix
= 0; ix
!= GCOV_COUNTERS
; ix
++)
570 if (prg_ctr_mask
& (1 << ix
))
572 tree counters
= convert (unsigned_type_node
,
573 build_int_2 (function
->n_ctrs
[ix
], 0));
575 array_value
= tree_cons (NULL_TREE
, counters
, array_value
);
578 array_value
= build_constructor (TREE_TYPE (fields
), nreverse (array_value
));
579 value
= tree_cons (fields
, array_value
, value
);
581 value
= build_constructor (type
, nreverse (value
));
586 /* Creates the gcov_ctr_info RECORD_TYPE. */
589 build_ctr_info_type ()
591 tree type
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
592 tree field
, fields
= NULL_TREE
;
593 tree gcov_ptr_type
= build_pointer_type (GCOV_TYPE_NODE
);
594 tree gcov_merge_fn_type
;
597 field
= build_decl (FIELD_DECL
, NULL_TREE
, unsigned_intSI_type_node
);
598 TREE_CHAIN (field
) = fields
;
602 field
= build_decl (FIELD_DECL
, NULL_TREE
, gcov_ptr_type
);
603 TREE_CHAIN (field
) = fields
;
608 build_function_type_list (void_type_node
,
609 gcov_ptr_type
, unsigned_type_node
,
611 field
= build_decl (FIELD_DECL
, NULL_TREE
,
612 build_pointer_type (gcov_merge_fn_type
));
613 TREE_CHAIN (field
) = fields
;
616 finish_builtin_struct (type
, "__gcov_ctr_info", fields
, NULL_TREE
);
621 /* Creates a CONSTRUCTOR for a gcov_ctr_info. COUNTER is
622 the counter being processed and TYPE is the gcov_ctr_info
626 build_ctr_info_value (counter
, type
)
630 tree value
= NULL_TREE
;
631 tree fields
= TYPE_FIELDS (type
);
635 value
= tree_cons (fields
,
636 convert (unsigned_intSI_type_node
,
637 build_int_2 (prg_n_ctrs
[counter
], 0)),
639 fields
= TREE_CHAIN (fields
);
641 if (prg_n_ctrs
[counter
])
643 tree array_type
, array
;
645 array_type
= build_index_type (build_int_2 (prg_n_ctrs
[counter
] - 1, 0));
646 array_type
= build_array_type (TREE_TYPE (TREE_TYPE (fields
)),
649 array
= build (VAR_DECL
, array_type
, NULL_TREE
, NULL_TREE
);
650 TREE_STATIC (array
) = 1;
651 DECL_NAME (array
) = get_identifier (XSTR (ctr_labels
[counter
], 0));
652 assemble_variable (array
, 0, 0, 0);
654 value
= tree_cons (fields
,
655 build1 (ADDR_EXPR
, TREE_TYPE (fields
), array
),
659 value
= tree_cons (fields
, null_pointer_node
, value
);
660 fields
= TREE_CHAIN (fields
);
662 fn
= build_decl (FUNCTION_DECL
,
663 get_identifier (ctr_merge_functions
[counter
]),
664 TREE_TYPE (TREE_TYPE (fields
)));
665 DECL_EXTERNAL (fn
) = 1;
666 TREE_PUBLIC (fn
) = 1;
667 DECL_ARTIFICIAL (fn
) = 1;
668 TREE_NOTHROW (fn
) = 1;
669 value
= tree_cons (fields
,
670 build1 (ADDR_EXPR
, TREE_TYPE (fields
), fn
),
673 value
= build_constructor (type
, nreverse (value
));
678 /* Creates the gcov_info RECORD_TYPE and initializer for it. Returns a
684 unsigned n_ctr_types
, ix
;
685 tree type
, const_type
;
686 tree fn_info_type
, fn_info_value
= NULL_TREE
;
687 tree fn_info_ptr_type
;
688 tree ctr_info_type
, ctr_info_ary_type
, ctr_info_value
= NULL_TREE
;
689 tree field
, fields
= NULL_TREE
;
690 tree value
= NULL_TREE
;
691 tree filename_string
;
695 const struct function_list
*fn
;
698 /* Count the number of active counters. */
699 for (n_ctr_types
= 0, ix
= 0; ix
!= GCOV_COUNTERS
; ix
++)
700 if (prg_ctr_mask
& (1 << ix
))
703 type
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
704 const_type
= build_qualified_type (type
, TYPE_QUAL_CONST
);
707 field
= build_decl (FIELD_DECL
, NULL_TREE
, unsigned_intSI_type_node
);
708 TREE_CHAIN (field
) = fields
;
710 value
= tree_cons (field
, convert (unsigned_intSI_type_node
,
711 build_int_2 (GCOV_VERSION
, 0)),
715 field
= build_decl (FIELD_DECL
, NULL_TREE
, build_pointer_type (const_type
));
716 TREE_CHAIN (field
) = fields
;
718 value
= tree_cons (field
, null_pointer_node
, value
);
721 string_type
= build_pointer_type (build_qualified_type (char_type_node
,
723 field
= build_decl (FIELD_DECL
, NULL_TREE
, string_type
);
724 TREE_CHAIN (field
) = fields
;
726 filename
= getpwd ();
727 filename
= (filename
&& da_file_name
[0] != '/'
728 ? concat (filename
, "/", da_file_name
, NULL
)
730 filename_len
= strlen (filename
);
731 filename_string
= build_string (filename_len
+ 1, filename
);
732 if (filename
!= da_file_name
)
734 TREE_TYPE (filename_string
) =
735 build_array_type (char_type_node
,
736 build_index_type (build_int_2 (filename_len
, 0)));
737 value
= tree_cons (field
, build1 (ADDR_EXPR
, string_type
, filename_string
),
740 /* Build the fn_info type and initializer. */
741 fn_info_type
= build_fn_info_type (n_ctr_types
);
742 fn_info_ptr_type
= build_pointer_type (build_qualified_type
743 (fn_info_type
, TYPE_QUAL_CONST
));
744 for (fn
= functions_head
, n_fns
= 0; fn
; fn
= fn
->next
, n_fns
++)
745 fn_info_value
= tree_cons (NULL_TREE
,
746 build_fn_info_value (fn
, fn_info_type
),
752 array_type
= build_index_type (build_int_2 (n_fns
- 1, 0));
753 array_type
= build_array_type (fn_info_type
, array_type
);
755 fn_info_value
= build_constructor (array_type
, nreverse (fn_info_value
));
756 fn_info_value
= build1 (ADDR_EXPR
, fn_info_ptr_type
, fn_info_value
);
759 fn_info_value
= null_pointer_node
;
761 /* number of functions */
762 field
= build_decl (FIELD_DECL
, NULL_TREE
, unsigned_type_node
);
763 TREE_CHAIN (field
) = fields
;
765 value
= tree_cons (field
,
766 convert (unsigned_type_node
, build_int_2 (n_fns
, 0)),
770 field
= build_decl (FIELD_DECL
, NULL_TREE
, fn_info_ptr_type
);
771 TREE_CHAIN (field
) = fields
;
773 value
= tree_cons (field
, fn_info_value
, value
);
776 field
= build_decl (FIELD_DECL
, NULL_TREE
, unsigned_type_node
);
777 TREE_CHAIN (field
) = fields
;
779 value
= tree_cons (field
,
780 convert (unsigned_type_node
,
781 build_int_2 (prg_ctr_mask
, 0)),
785 ctr_info_type
= build_ctr_info_type ();
786 ctr_info_ary_type
= build_index_type (build_int_2 (n_ctr_types
, 0));
787 ctr_info_ary_type
= build_array_type (ctr_info_type
, ctr_info_ary_type
);
788 for (ix
= 0; ix
!= GCOV_COUNTERS
; ix
++)
789 if (prg_ctr_mask
& (1 << ix
))
790 ctr_info_value
= tree_cons (NULL_TREE
,
791 build_ctr_info_value (ix
, ctr_info_type
),
793 ctr_info_value
= build_constructor (ctr_info_ary_type
,
794 nreverse (ctr_info_value
));
796 field
= build_decl (FIELD_DECL
, NULL_TREE
, ctr_info_ary_type
);
797 TREE_CHAIN (field
) = fields
;
799 value
= tree_cons (field
, ctr_info_value
, value
);
801 finish_builtin_struct (type
, "__gcov_info", fields
, NULL_TREE
);
803 value
= build_constructor (type
, nreverse (value
));
808 /* Write out the structure which libgcov uses to locate all the
809 counters. The structures used here must match those defined in
810 gcov-io.h. Write out the constructor to call __gcov_init. */
815 tree gcov_info
, gcov_info_value
;
819 rtx gcov_info_address
;
821 no_coverage
= 1; /* Disable any further coverage. */
826 gcov_info_value
= build_gcov_info ();
828 gcov_info
= build (VAR_DECL
, TREE_TYPE (gcov_info_value
),
829 NULL_TREE
, NULL_TREE
);
830 DECL_INITIAL (gcov_info
) = gcov_info_value
;
832 TREE_STATIC (gcov_info
) = 1;
833 ASM_GENERATE_INTERNAL_LABEL (name
, "LPBX", 0);
834 DECL_NAME (gcov_info
) = get_identifier (name
);
836 /* Build structure. */
837 assemble_variable (gcov_info
, 0, 0, 0);
839 /* Build the constructor function to invoke __gcov_init. */
840 ctor_name
= concat (IDENTIFIER_POINTER (get_file_function_name ('I')),
842 ctor
= build_decl (FUNCTION_DECL
, get_identifier (ctor_name
),
843 build_function_type (void_type_node
, NULL_TREE
));
845 DECL_EXTERNAL (ctor
) = 0;
847 /* It can be a static function as long as collect2 does not have
848 to scan the object file to find its ctor/dtor routine. */
849 TREE_PUBLIC (ctor
) = ! targetm
.have_ctors_dtors
;
850 TREE_USED (ctor
) = 1;
851 DECL_RESULT (ctor
) = build_decl (RESULT_DECL
, NULL_TREE
, void_type_node
);
852 DECL_UNINLINABLE (ctor
) = 1;
854 ctor
= (*lang_hooks
.decls
.pushdecl
) (ctor
);
855 rest_of_decl_compilation (ctor
, 0, 1, 0);
856 announce_function (ctor
);
857 current_function_decl
= ctor
;
858 DECL_INITIAL (ctor
) = error_mark_node
;
859 make_decl_rtl (ctor
, NULL
);
860 init_function_start (ctor
, input_filename
, input_line
);
861 (*lang_hooks
.decls
.pushlevel
) (0);
862 expand_function_start (ctor
, 0);
864 /* Actually generate the code to call __gcov_init. */
865 gcov_info_address
= force_reg (Pmode
, XEXP (DECL_RTL (gcov_info
), 0));
866 emit_library_call (gcov_init_libfunc
, LCT_NORMAL
, VOIDmode
, 1,
867 gcov_info_address
, Pmode
);
869 expand_function_end (input_filename
, input_line
, 0);
870 (*lang_hooks
.decls
.poplevel
) (1, 0, 1);
872 rest_of_compilation (ctor
);
875 fflush (asm_out_file
);
876 current_function_decl
= NULL_TREE
;
878 if (targetm
.have_ctors_dtors
)
879 (* targetm
.asm_out
.constructor
) (XEXP (DECL_RTL (ctor
), 0),
880 DEFAULT_INIT_PRIORITY
);
883 /* Perform file-level initialization. Read in data file, generate name
887 coverage_init (filename
)
888 const char *filename
;
890 int len
= strlen (filename
);
892 /* Name of da file. */
893 da_file_name
= (char *) xmalloc (len
+ strlen (GCOV_DATA_SUFFIX
) + 1);
894 strcpy (da_file_name
, filename
);
895 strcat (da_file_name
, GCOV_DATA_SUFFIX
);
897 /* Name of bbg file. */
898 bbg_file_name
= (char *) xmalloc (len
+ strlen (GCOV_GRAPH_SUFFIX
) + 1);
899 strcpy (bbg_file_name
, filename
);
900 strcat (bbg_file_name
, GCOV_GRAPH_SUFFIX
);
905 /* Performs file-level cleanup. Close graph file, generate coverage
906 variables and constructor. */
914 int error
= gcov_close ();
917 unlink (bbg_file_name
);
919 /* If the compiler is instrumented, we should not
920 unconditionally remove the counts file, because we might be
921 recompiling ourselves. The .da files are all removed during
922 copying the stage1 files. */
925 unlink (da_file_name
);
929 #include "gt-coverage.h"