summaryrefslogtreecommitdiff
path: root/gcc/coverage.c
diff options
context:
space:
mode:
authorrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2003-05-04 15:20:26 +0000
committerrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2003-05-04 15:20:26 +0000
commit35cb45c4eaeb15d82c29d4555824c4fe2f7d1678 (patch)
tree05de4edb80cb0ae6e59ff9b0f5b6509cae6fde04 /gcc/coverage.c
parent65ff8f7314508add07c15d6c9d77e2724318bdeb (diff)
downloadgcc-35cb45c4eaeb15d82c29d4555824c4fe2f7d1678.tar.gz
* Makefile.in (LIBGCOV): Add _gcov_merge_add.
* gcov-io.h: Make GCOV_LINKAGE extern in libgcov and prevent resulting namespace clash. (GCOV_MERGE_FUNCTIONS): New. (gcov_merge_fn): Declare. (struct gcov_ctr_info): New field "merge". (__gcov_merge_add): Declare. * coverage.c (ctr_merge_functions): New. (build_ctr_info_type, build_ctr_info_value): Initialize merge field of gcov_ctr_info type. * libgcov.c (__gcov_merge_add): New. (gcov_exit): Call a hook to merge values of counters. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@66457 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/coverage.c')
-rw-r--r--gcc/coverage.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/gcc/coverage.c b/gcc/coverage.c
index 6d8ae9a55fb..36400f32e9c 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -98,6 +98,9 @@ static htab_t counts_hash = NULL;
/* The names of the counter tables. */
static GTY(()) rtx ctr_labels[GCOV_COUNTERS];
+/* The names of merge functions for counters. */
+static const char *ctr_merge_functions[GCOV_COUNTERS] = GCOV_MERGE_FUNCTIONS;
+
/* Forward declarations. */
static hashval_t htab_counts_entry_hash PARAMS ((const void *));
static int htab_counts_entry_eq PARAMS ((const void *, const void *));
@@ -559,6 +562,7 @@ build_ctr_info_type ()
{
tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
tree field, fields = NULL_TREE;
+ tree gcov_merge_fn_type;
/* counters */
field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
@@ -571,6 +575,18 @@ build_ctr_info_type ()
TREE_CHAIN (field) = fields;
fields = field;
+ /* merge */
+ gcov_merge_fn_type =
+ build_function_type_list (
+ void_type_node,
+ build_pointer_type (make_signed_type (GCOV_TYPE_SIZE)),
+ unsigned_type_node,
+ NULL_TREE);
+ field = build_decl (FIELD_DECL, NULL_TREE,
+ build_pointer_type (gcov_merge_fn_type));
+ TREE_CHAIN (field) = fields;
+ fields = field;
+
finish_builtin_struct (type, "__gcov_ctr_info", fields, NULL_TREE);
return type;
@@ -587,6 +603,7 @@ build_ctr_info_value (counter, type)
{
tree value = NULL_TREE;
tree fields = TYPE_FIELDS (type);
+ tree fn;
/* counters */
value = tree_cons (fields,
@@ -614,6 +631,20 @@ build_ctr_info_value (counter, type)
}
else
value = tree_cons (fields, null_pointer_node, value);
+ fields = TREE_CHAIN (fields);
+
+ fn = build_decl (FUNCTION_DECL,
+ get_identifier (ctr_merge_functions[counter]),
+ TREE_TYPE (TREE_TYPE (fields)));
+ DECL_EXTERNAL (fn) = 1;
+ TREE_PUBLIC (fn) = 1;
+ DECL_ARTIFICIAL (fn) = 1;
+ TREE_NOTHROW (fn) = 1;
+ value = tree_cons (fields,
+ build1 (ADDR_EXPR,
+ TREE_TYPE (fields),
+ fn),
+ value);
value = build_constructor (type, nreverse (value));