annotate gcc/gcov.c @ 128:fe568345ddd5

fix CbC-example
author mir3636
date Wed, 11 Apr 2018 19:32:28 +0900
parents 04ced10e8804
children 84e7813d76e9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 /* Gcov.c: prepend line execution counts and branch probabilities to a
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2 source file.
111
kono
parents: 67
diff changeset
3 Copyright (C) 1990-2017 Free Software Foundation, Inc.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 Contributed by James E. Wilson of Cygnus Support.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 Mangled by Bob Manson of Cygnus Support.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 Mangled further by Nathan Sidwell <nathan@codesourcery.com>
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 Gcov is free software; you can redistribute it and/or modify
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 it under the terms of the GNU General Public License as published by
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 the Free Software Foundation; either version 3, or (at your option)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 any later version.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 Gcov is distributed in the hope that it will be useful,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 GNU General Public License for more details.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 You should have received a copy of the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 along with Gcov; see the file COPYING3. If not see
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 <http://www.gnu.org/licenses/>. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 /* ??? Print a list of the ten blocks with the highest execution counts,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 and list the line numbers corresponding to those blocks. Also, perhaps
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 list the line numbers with the highest execution counts, only printing
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 the first if there are several which are all listed in the same block. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 /* ??? Should have an option to print the number of basic blocks, and the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 percent of them that are covered. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
29
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 /* Need an option to show individual block counts, and show
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 probabilities of fall through arcs. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
32
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
33 #include "config.h"
111
kono
parents: 67
diff changeset
34 #define INCLUDE_ALGORITHM
kono
parents: 67
diff changeset
35 #define INCLUDE_VECTOR
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 #include "system.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
37 #include "coretypes.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 #include "tm.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 #include "intl.h"
111
kono
parents: 67
diff changeset
40 #include "diagnostic.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 #include "version.h"
111
kono
parents: 67
diff changeset
42 #include "demangle.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
43
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 #include <getopt.h>
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45
111
kono
parents: 67
diff changeset
46 #include "md5.h"
kono
parents: 67
diff changeset
47
kono
parents: 67
diff changeset
48 using namespace std;
kono
parents: 67
diff changeset
49
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 #define IN_GCOV 1
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
51 #include "gcov-io.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 #include "gcov-io.c"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
53
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 /* The gcno file is generated by -ftest-coverage option. The gcda file is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 generated by a program compiled with -fprofile-arcs. Their formats
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 are documented in gcov-io.h. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 /* The functions in this file for creating and solution program flow graphs
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 are very similar to functions in the gcc source file profile.c. In
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
60 some places we make use of the knowledge of how profile.c works to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 select particular algorithms here. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
62
111
kono
parents: 67
diff changeset
63 /* The code validates that the profile information read in corresponds
kono
parents: 67
diff changeset
64 to the code currently being compiled. Rather than checking for
kono
parents: 67
diff changeset
65 identical files, the code below compares a checksum on the CFG
kono
parents: 67
diff changeset
66 (based on the order of basic blocks and the arcs in the CFG). If
kono
parents: 67
diff changeset
67 the CFG checksum in the gcda file match the CFG checksum in the
kono
parents: 67
diff changeset
68 gcno file, the profile data will be used. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
69
111
kono
parents: 67
diff changeset
70 /* This is the size of the buffer used to read in source file lines. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
71
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
72 struct function_info;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 struct block_info;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 struct source_info;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
75
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 /* Describes an arc between two basic blocks. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
77
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 typedef struct arc_info
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
79 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 /* source and destination blocks. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
81 struct block_info *src;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 struct block_info *dst;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
83
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 /* transition counts. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
85 gcov_type count;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 /* used in cycle search, so that we do not clobber original counts. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 gcov_type cs_count;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
88
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 unsigned int count_valid : 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
90 unsigned int on_tree : 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
91 unsigned int fake : 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
92 unsigned int fall_through : 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
93
111
kono
parents: 67
diff changeset
94 /* Arc to a catch handler. */
kono
parents: 67
diff changeset
95 unsigned int is_throw : 1;
kono
parents: 67
diff changeset
96
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 /* Arc is for a function that abnormally returns. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 unsigned int is_call_non_return : 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
99
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
100 /* Arc is for catch/setjmp. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 unsigned int is_nonlocal_return : 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
102
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 /* Is an unconditional branch. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
104 unsigned int is_unconditional : 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
105
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 /* Loop making arc. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 unsigned int cycle : 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
108
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
109 /* Next branch on line. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 struct arc_info *line_next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
111
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 /* Links to next arc on src and dst lists. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 struct arc_info *succ_next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
114 struct arc_info *pred_next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 } arc_t;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
116
111
kono
parents: 67
diff changeset
117 /* Describes which locations (lines and files) are associated with
kono
parents: 67
diff changeset
118 a basic block. */
kono
parents: 67
diff changeset
119
kono
parents: 67
diff changeset
120 struct block_location_info
kono
parents: 67
diff changeset
121 {
kono
parents: 67
diff changeset
122 block_location_info (unsigned _source_file_idx):
kono
parents: 67
diff changeset
123 source_file_idx (_source_file_idx)
kono
parents: 67
diff changeset
124 {}
kono
parents: 67
diff changeset
125
kono
parents: 67
diff changeset
126 unsigned source_file_idx;
kono
parents: 67
diff changeset
127 vector<unsigned> lines;
kono
parents: 67
diff changeset
128 };
kono
parents: 67
diff changeset
129
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
130 /* Describes a basic block. Contains lists of arcs to successor and
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 predecessor blocks. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
132
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 typedef struct block_info
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 {
111
kono
parents: 67
diff changeset
135 /* Constructor. */
kono
parents: 67
diff changeset
136 block_info ();
kono
parents: 67
diff changeset
137
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
138 /* Chain of exit and entry arcs. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 arc_t *succ;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
140 arc_t *pred;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
141
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
142 /* Number of unprocessed exit and entry arcs. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
143 gcov_type num_succ;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
144 gcov_type num_pred;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
145
111
kono
parents: 67
diff changeset
146 unsigned id;
kono
parents: 67
diff changeset
147
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
148 /* Block execution count. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
149 gcov_type count;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
150 unsigned count_valid : 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
151 unsigned valid_chain : 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
152 unsigned invalid_chain : 1;
111
kono
parents: 67
diff changeset
153 unsigned exceptional : 1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
154
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
155 /* Block is a call instrumenting site. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
156 unsigned is_call_site : 1; /* Does the call. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
157 unsigned is_call_return : 1; /* Is the return. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
158
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
159 /* Block is a landing pad for longjmp or throw. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
160 unsigned is_nonlocal_return : 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
161
111
kono
parents: 67
diff changeset
162 vector<block_location_info> locations;
kono
parents: 67
diff changeset
163
kono
parents: 67
diff changeset
164 struct
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
165 {
111
kono
parents: 67
diff changeset
166 /* Single line graph cycle workspace. Used for all-blocks
kono
parents: 67
diff changeset
167 mode. */
kono
parents: 67
diff changeset
168 arc_t *arc;
kono
parents: 67
diff changeset
169 unsigned ident;
kono
parents: 67
diff changeset
170 } cycle; /* Used in all-blocks mode, after blocks are linked onto
kono
parents: 67
diff changeset
171 lines. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
172
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
173 /* Temporary chain for solving graph, and for chaining blocks on one
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
174 line. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
175 struct block_info *chain;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
176
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
177 } block_t;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
178
111
kono
parents: 67
diff changeset
179 block_info::block_info (): succ (NULL), pred (NULL), num_succ (0), num_pred (0),
kono
parents: 67
diff changeset
180 id (0), count (0), count_valid (0), valid_chain (0), invalid_chain (0),
kono
parents: 67
diff changeset
181 exceptional (0), is_call_site (0), is_call_return (0), is_nonlocal_return (0),
kono
parents: 67
diff changeset
182 locations (), chain (NULL)
kono
parents: 67
diff changeset
183 {
kono
parents: 67
diff changeset
184 cycle.arc = NULL;
kono
parents: 67
diff changeset
185 }
kono
parents: 67
diff changeset
186
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
187 /* Describes a single function. Contains an array of basic blocks. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
188
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
189 typedef struct function_info
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
190 {
111
kono
parents: 67
diff changeset
191 function_info ();
kono
parents: 67
diff changeset
192 ~function_info ();
kono
parents: 67
diff changeset
193
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
194 /* Name of function. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
195 char *name;
111
kono
parents: 67
diff changeset
196 char *demangled_name;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
197 unsigned ident;
111
kono
parents: 67
diff changeset
198 unsigned lineno_checksum;
kono
parents: 67
diff changeset
199 unsigned cfg_checksum;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
200
111
kono
parents: 67
diff changeset
201 /* The graph contains at least one fake incoming edge. */
kono
parents: 67
diff changeset
202 unsigned has_catch : 1;
kono
parents: 67
diff changeset
203
kono
parents: 67
diff changeset
204 /* Array of basic blocks. Like in GCC, the entry block is
kono
parents: 67
diff changeset
205 at blocks[0] and the exit block is at blocks[1]. */
kono
parents: 67
diff changeset
206 #define ENTRY_BLOCK (0)
kono
parents: 67
diff changeset
207 #define EXIT_BLOCK (1)
kono
parents: 67
diff changeset
208 vector<block_t> blocks;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
209 unsigned blocks_executed;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
210
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
211 /* Raw arc coverage counts. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
212 gcov_type *counts;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
213 unsigned num_counts;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
214
111
kono
parents: 67
diff changeset
215 /* First line number & file. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
216 unsigned line;
111
kono
parents: 67
diff changeset
217 unsigned src;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
218
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
219 /* Next function in same source file. */
111
kono
parents: 67
diff changeset
220 struct function_info *next_file_fn;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
221
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
222 /* Next function. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
223 struct function_info *next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
224 } function_t;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
225
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
226 /* Describes coverage of a file or function. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
227
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
228 typedef struct coverage_info
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
229 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
230 int lines;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
231 int lines_executed;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
232
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
233 int branches;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
234 int branches_executed;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
235 int branches_taken;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
236
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
237 int calls;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
238 int calls_executed;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
239
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
240 char *name;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
241 } coverage_t;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
242
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
243 /* Describes a single line of source. Contains a chain of basic blocks
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
244 with code on it. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
245
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
246 typedef struct line_info
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
247 {
111
kono
parents: 67
diff changeset
248 /* Return true when NEEDLE is one of basic blocks the line belongs to. */
kono
parents: 67
diff changeset
249 bool has_block (block_t *needle);
kono
parents: 67
diff changeset
250
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
251 gcov_type count; /* execution count */
111
kono
parents: 67
diff changeset
252 arc_t *branches; /* branches from blocks that end on this line. */
kono
parents: 67
diff changeset
253 block_t *blocks; /* blocks which start on this line.
kono
parents: 67
diff changeset
254 Used in all-blocks mode. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
255 unsigned exists : 1;
111
kono
parents: 67
diff changeset
256 unsigned unexceptional : 1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
257 } line_t;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
258
111
kono
parents: 67
diff changeset
259 bool
kono
parents: 67
diff changeset
260 line_t::has_block (block_t *needle)
kono
parents: 67
diff changeset
261 {
kono
parents: 67
diff changeset
262 for (block_t *n = blocks; n; n = n->chain)
kono
parents: 67
diff changeset
263 if (n == needle)
kono
parents: 67
diff changeset
264 return true;
kono
parents: 67
diff changeset
265
kono
parents: 67
diff changeset
266 return false;
kono
parents: 67
diff changeset
267 }
kono
parents: 67
diff changeset
268
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
269 /* Describes a file mentioned in the block graph. Contains an array
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
270 of line info. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
271
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
272 typedef struct source_info
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
273 {
111
kono
parents: 67
diff changeset
274 /* Canonical name of source file. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
275 char *name;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
276 time_t file_time;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
277
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
278 /* Array of line information. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
279 line_t *lines;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
280 unsigned num_lines;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
281
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
282 coverage_t coverage;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
283
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
284 /* Functions in this source file. These are in ascending line
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
285 number order. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
286 function_t *functions;
111
kono
parents: 67
diff changeset
287 } source_t;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
288
111
kono
parents: 67
diff changeset
289 typedef struct name_map
kono
parents: 67
diff changeset
290 {
kono
parents: 67
diff changeset
291 char *name; /* Source file name */
kono
parents: 67
diff changeset
292 unsigned src; /* Source file */
kono
parents: 67
diff changeset
293 } name_map_t;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
294
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
295 /* Holds a list of function basic block graphs. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
296
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
297 static function_t *functions;
111
kono
parents: 67
diff changeset
298 static function_t **fn_end = &functions;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
299
111
kono
parents: 67
diff changeset
300 static source_t *sources; /* Array of source files */
kono
parents: 67
diff changeset
301 static unsigned n_sources; /* Number of sources */
kono
parents: 67
diff changeset
302 static unsigned a_sources; /* Allocated sources */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
303
111
kono
parents: 67
diff changeset
304 static name_map_t *names; /* Mapping of file names to sources */
kono
parents: 67
diff changeset
305 static unsigned n_names; /* Number of names */
kono
parents: 67
diff changeset
306 static unsigned a_names; /* Allocated names */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
307
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
308 /* This holds data summary information. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
309
111
kono
parents: 67
diff changeset
310 static unsigned object_runs;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
311 static unsigned program_count;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
312
111
kono
parents: 67
diff changeset
313 static unsigned total_lines;
kono
parents: 67
diff changeset
314 static unsigned total_executed;
kono
parents: 67
diff changeset
315
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
316 /* Modification time of graph file. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
317
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
318 static time_t bbg_file_time;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
319
111
kono
parents: 67
diff changeset
320 /* Name of the notes (gcno) output file. The "bbg" prefix is for
kono
parents: 67
diff changeset
321 historical reasons, when the notes file contained only the
kono
parents: 67
diff changeset
322 basic block graph notes. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
323
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
324 static char *bbg_file_name;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
325
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
326 /* Stamp of the bbg file */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
327 static unsigned bbg_stamp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
328
111
kono
parents: 67
diff changeset
329 /* Name and file pointer of the input file for the count data (gcda). */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
330
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
331 static char *da_file_name;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
332
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
333 /* Data file is missing. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
334
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
335 static int no_data_file;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
336
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
337 /* If there is several input files, compute and display results after
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
338 reading all data files. This way if two or more gcda file refer to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
339 the same source file (eg inline subprograms in a .h file), the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
340 counts are added. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
341
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
342 static int multiple_files = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
343
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
344 /* Output branch probabilities. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
345
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
346 static int flag_branches = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
347
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
348 /* Show unconditional branches too. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
349 static int flag_unconditional = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
350
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
351 /* Output a gcov file if this is true. This is on by default, and can
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
352 be turned off by the -n option. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
353
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
354 static int flag_gcov_file = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
355
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
356 /* Output progress indication if this is true. This is off by default
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
357 and can be turned on by the -d option. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
358
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
359 static int flag_display_progress = 0;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
360
111
kono
parents: 67
diff changeset
361 /* Output *.gcov file in intermediate format used by 'lcov'. */
kono
parents: 67
diff changeset
362
kono
parents: 67
diff changeset
363 static int flag_intermediate_format = 0;
kono
parents: 67
diff changeset
364
kono
parents: 67
diff changeset
365 /* Output demangled function names. */
kono
parents: 67
diff changeset
366
kono
parents: 67
diff changeset
367 static int flag_demangled_names = 0;
kono
parents: 67
diff changeset
368
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
369 /* For included files, make the gcov output file name include the name
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
370 of the input source file. For example, if x.h is included in a.c,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
371 then the output file name is a.c##x.h.gcov instead of x.h.gcov. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
372
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
373 static int flag_long_names = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
374
111
kono
parents: 67
diff changeset
375 /* For situations when a long name can potentially hit filesystem path limit,
kono
parents: 67
diff changeset
376 let's calculate md5sum of the path and append it to a file name. */
kono
parents: 67
diff changeset
377
kono
parents: 67
diff changeset
378 static int flag_hash_filenames = 0;
kono
parents: 67
diff changeset
379
kono
parents: 67
diff changeset
380 /* Print verbose informations. */
kono
parents: 67
diff changeset
381
kono
parents: 67
diff changeset
382 static int flag_verbose = 0;
kono
parents: 67
diff changeset
383
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
384 /* Output count information for every basic block, not merely those
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
385 that contain line number information. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
386
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
387 static int flag_all_blocks = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
388
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
389 /* Output summary info for each function. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
390
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
391 static int flag_function_summary = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
392
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
393 /* Object directory file prefix. This is the directory/file where the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
394 graph and data files are looked for, if nonzero. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
395
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
396 static char *object_directory = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
397
111
kono
parents: 67
diff changeset
398 /* Source directory prefix. This is removed from source pathnames
kono
parents: 67
diff changeset
399 that match, when generating the output file name. */
kono
parents: 67
diff changeset
400
kono
parents: 67
diff changeset
401 static char *source_prefix = 0;
kono
parents: 67
diff changeset
402 static size_t source_length = 0;
kono
parents: 67
diff changeset
403
kono
parents: 67
diff changeset
404 /* Only show data for sources with relative pathnames. Absolute ones
kono
parents: 67
diff changeset
405 usually indicate a system header file, which although it may
kono
parents: 67
diff changeset
406 contain inline functions, is usually uninteresting. */
kono
parents: 67
diff changeset
407 static int flag_relative_only = 0;
kono
parents: 67
diff changeset
408
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
409 /* Preserve all pathname components. Needed when object files and
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
410 source files are in subdirectories. '/' is mangled as '#', '.' is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
411 elided and '..' mangled to '^'. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
412
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
413 static int flag_preserve_paths = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
414
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
415 /* Output the number of times a branch was taken as opposed to the percentage
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
416 of times it was taken. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
417
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
418 static int flag_counts = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
419
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
420 /* Forward declarations. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
421 static int process_args (int, char **);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
422 static void print_usage (int) ATTRIBUTE_NORETURN;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
423 static void print_version (void) ATTRIBUTE_NORETURN;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
424 static void process_file (const char *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
425 static void generate_results (const char *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
426 static void create_file_names (const char *);
111
kono
parents: 67
diff changeset
427 static int name_search (const void *, const void *);
kono
parents: 67
diff changeset
428 static int name_sort (const void *, const void *);
kono
parents: 67
diff changeset
429 static char *canonicalize_name (const char *);
kono
parents: 67
diff changeset
430 static unsigned find_source (const char *);
kono
parents: 67
diff changeset
431 static function_t *read_graph_file (void);
kono
parents: 67
diff changeset
432 static int read_count_file (function_t *);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
433 static void solve_flow_graph (function_t *);
111
kono
parents: 67
diff changeset
434 static void find_exception_blocks (function_t *);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
435 static void add_branch_counts (coverage_t *, const arc_t *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
436 static void add_line_counts (coverage_t *, function_t *);
111
kono
parents: 67
diff changeset
437 static void executed_summary (unsigned, unsigned);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
438 static void function_summary (const coverage_t *, const char *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
439 static const char *format_gcov (gcov_type, gcov_type, int);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
440 static void accumulate_line_counts (source_t *);
111
kono
parents: 67
diff changeset
441 static void output_gcov_file (const char *, source_t *);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
442 static int output_branch_count (FILE *, int, const arc_t *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
443 static void output_lines (FILE *, const source_t *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
444 static char *make_gcov_file_name (const char *, const char *);
111
kono
parents: 67
diff changeset
445 static char *mangle_name (const char *, char *);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
446 static void release_structures (void);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
447 extern int main (int, char **);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
448
111
kono
parents: 67
diff changeset
449 function_info::function_info (): name (NULL), demangled_name (NULL),
kono
parents: 67
diff changeset
450 ident (0), lineno_checksum (0), cfg_checksum (0), has_catch (0),
kono
parents: 67
diff changeset
451 blocks (), blocks_executed (0), counts (NULL), num_counts (0),
kono
parents: 67
diff changeset
452 line (0), src (0), next_file_fn (NULL), next (NULL)
kono
parents: 67
diff changeset
453 {
kono
parents: 67
diff changeset
454 }
kono
parents: 67
diff changeset
455
kono
parents: 67
diff changeset
456 function_info::~function_info ()
kono
parents: 67
diff changeset
457 {
kono
parents: 67
diff changeset
458 for (int i = blocks.size () - 1; i >= 0; i--)
kono
parents: 67
diff changeset
459 {
kono
parents: 67
diff changeset
460 arc_t *arc, *arc_n;
kono
parents: 67
diff changeset
461
kono
parents: 67
diff changeset
462 for (arc = blocks[i].succ; arc; arc = arc_n)
kono
parents: 67
diff changeset
463 {
kono
parents: 67
diff changeset
464 arc_n = arc->succ_next;
kono
parents: 67
diff changeset
465 free (arc);
kono
parents: 67
diff changeset
466 }
kono
parents: 67
diff changeset
467 }
kono
parents: 67
diff changeset
468 free (counts);
kono
parents: 67
diff changeset
469 if (flag_demangled_names && demangled_name != name)
kono
parents: 67
diff changeset
470 free (demangled_name);
kono
parents: 67
diff changeset
471 free (name);
kono
parents: 67
diff changeset
472 }
kono
parents: 67
diff changeset
473
kono
parents: 67
diff changeset
474 /* Cycle detection!
kono
parents: 67
diff changeset
475 There are a bajillion algorithms that do this. Boost's function is named
kono
parents: 67
diff changeset
476 hawick_cycles, so I used the algorithm by K. A. Hawick and H. A. James in
kono
parents: 67
diff changeset
477 "Enumerating Circuits and Loops in Graphs with Self-Arcs and Multiple-Arcs"
kono
parents: 67
diff changeset
478 (url at <http://complexity.massey.ac.nz/cstn/013/cstn-013.pdf>).
kono
parents: 67
diff changeset
479
kono
parents: 67
diff changeset
480 The basic algorithm is simple: effectively, we're finding all simple paths
kono
parents: 67
diff changeset
481 in a subgraph (that shrinks every iteration). Duplicates are filtered by
kono
parents: 67
diff changeset
482 "blocking" a path when a node is added to the path (this also prevents non-
kono
parents: 67
diff changeset
483 simple paths)--the node is unblocked only when it participates in a cycle.
kono
parents: 67
diff changeset
484 */
kono
parents: 67
diff changeset
485
kono
parents: 67
diff changeset
486 typedef vector<arc_t *> arc_vector_t;
kono
parents: 67
diff changeset
487 typedef vector<const block_t *> block_vector_t;
kono
parents: 67
diff changeset
488
kono
parents: 67
diff changeset
489 /* Enum with types of loop in CFG. */
kono
parents: 67
diff changeset
490
kono
parents: 67
diff changeset
491 enum loop_type
kono
parents: 67
diff changeset
492 {
kono
parents: 67
diff changeset
493 NO_LOOP = 0,
kono
parents: 67
diff changeset
494 LOOP = 1,
kono
parents: 67
diff changeset
495 NEGATIVE_LOOP = 3
kono
parents: 67
diff changeset
496 };
kono
parents: 67
diff changeset
497
kono
parents: 67
diff changeset
498 /* Loop_type operator that merges two values: A and B. */
kono
parents: 67
diff changeset
499
kono
parents: 67
diff changeset
500 inline loop_type& operator |= (loop_type& a, loop_type b)
kono
parents: 67
diff changeset
501 {
kono
parents: 67
diff changeset
502 return a = static_cast<loop_type> (a | b);
kono
parents: 67
diff changeset
503 }
kono
parents: 67
diff changeset
504
kono
parents: 67
diff changeset
505 /* Handle cycle identified by EDGES, where the function finds minimum cs_count
kono
parents: 67
diff changeset
506 and subtract the value from all counts. The subtracted value is added
kono
parents: 67
diff changeset
507 to COUNT. Returns type of loop. */
kono
parents: 67
diff changeset
508
kono
parents: 67
diff changeset
509 static loop_type
kono
parents: 67
diff changeset
510 handle_cycle (const arc_vector_t &edges, int64_t &count)
kono
parents: 67
diff changeset
511 {
kono
parents: 67
diff changeset
512 /* Find the minimum edge of the cycle, and reduce all nodes in the cycle by
kono
parents: 67
diff changeset
513 that amount. */
kono
parents: 67
diff changeset
514 int64_t cycle_count = INTTYPE_MAXIMUM (int64_t);
kono
parents: 67
diff changeset
515 for (unsigned i = 0; i < edges.size (); i++)
kono
parents: 67
diff changeset
516 {
kono
parents: 67
diff changeset
517 int64_t ecount = edges[i]->cs_count;
kono
parents: 67
diff changeset
518 if (cycle_count > ecount)
kono
parents: 67
diff changeset
519 cycle_count = ecount;
kono
parents: 67
diff changeset
520 }
kono
parents: 67
diff changeset
521 count += cycle_count;
kono
parents: 67
diff changeset
522 for (unsigned i = 0; i < edges.size (); i++)
kono
parents: 67
diff changeset
523 edges[i]->cs_count -= cycle_count;
kono
parents: 67
diff changeset
524
kono
parents: 67
diff changeset
525 return cycle_count < 0 ? NEGATIVE_LOOP : LOOP;
kono
parents: 67
diff changeset
526 }
kono
parents: 67
diff changeset
527
kono
parents: 67
diff changeset
528 /* Unblock a block U from BLOCKED. Apart from that, iterate all blocks
kono
parents: 67
diff changeset
529 blocked by U in BLOCK_LISTS. */
kono
parents: 67
diff changeset
530
kono
parents: 67
diff changeset
531 static void
kono
parents: 67
diff changeset
532 unblock (const block_t *u, block_vector_t &blocked,
kono
parents: 67
diff changeset
533 vector<block_vector_t > &block_lists)
kono
parents: 67
diff changeset
534 {
kono
parents: 67
diff changeset
535 block_vector_t::iterator it = find (blocked.begin (), blocked.end (), u);
kono
parents: 67
diff changeset
536 if (it == blocked.end ())
kono
parents: 67
diff changeset
537 return;
kono
parents: 67
diff changeset
538
kono
parents: 67
diff changeset
539 unsigned index = it - blocked.begin ();
kono
parents: 67
diff changeset
540 blocked.erase (it);
kono
parents: 67
diff changeset
541
kono
parents: 67
diff changeset
542 block_vector_t to_unblock (block_lists[index]);
kono
parents: 67
diff changeset
543
kono
parents: 67
diff changeset
544 block_lists.erase (block_lists.begin () + index);
kono
parents: 67
diff changeset
545
kono
parents: 67
diff changeset
546 for (block_vector_t::iterator it = to_unblock.begin ();
kono
parents: 67
diff changeset
547 it != to_unblock.end (); it++)
kono
parents: 67
diff changeset
548 unblock (*it, blocked, block_lists);
kono
parents: 67
diff changeset
549 }
kono
parents: 67
diff changeset
550
kono
parents: 67
diff changeset
551 /* Find circuit going to block V, PATH is provisional seen cycle.
kono
parents: 67
diff changeset
552 BLOCKED is vector of blocked vertices, BLOCK_LISTS contains vertices
kono
parents: 67
diff changeset
553 blocked by a block. COUNT is accumulated count of the current LINE.
kono
parents: 67
diff changeset
554 Returns what type of loop it contains. */
kono
parents: 67
diff changeset
555
kono
parents: 67
diff changeset
556 static loop_type
kono
parents: 67
diff changeset
557 circuit (block_t *v, arc_vector_t &path, block_t *start,
kono
parents: 67
diff changeset
558 block_vector_t &blocked, vector<block_vector_t> &block_lists,
kono
parents: 67
diff changeset
559 line_t &linfo, int64_t &count)
kono
parents: 67
diff changeset
560 {
kono
parents: 67
diff changeset
561 loop_type result = NO_LOOP;
kono
parents: 67
diff changeset
562
kono
parents: 67
diff changeset
563 /* Add v to the block list. */
kono
parents: 67
diff changeset
564 gcc_assert (find (blocked.begin (), blocked.end (), v) == blocked.end ());
kono
parents: 67
diff changeset
565 blocked.push_back (v);
kono
parents: 67
diff changeset
566 block_lists.push_back (block_vector_t ());
kono
parents: 67
diff changeset
567
kono
parents: 67
diff changeset
568 for (arc_t *arc = v->succ; arc; arc = arc->succ_next)
kono
parents: 67
diff changeset
569 {
kono
parents: 67
diff changeset
570 block_t *w = arc->dst;
kono
parents: 67
diff changeset
571 if (w < start || !linfo.has_block (w))
kono
parents: 67
diff changeset
572 continue;
kono
parents: 67
diff changeset
573
kono
parents: 67
diff changeset
574 path.push_back (arc);
kono
parents: 67
diff changeset
575 if (w == start)
kono
parents: 67
diff changeset
576 /* Cycle has been found. */
kono
parents: 67
diff changeset
577 result |= handle_cycle (path, count);
kono
parents: 67
diff changeset
578 else if (find (blocked.begin (), blocked.end (), w) == blocked.end ())
kono
parents: 67
diff changeset
579 result |= circuit (w, path, start, blocked, block_lists, linfo, count);
kono
parents: 67
diff changeset
580
kono
parents: 67
diff changeset
581 path.pop_back ();
kono
parents: 67
diff changeset
582 }
kono
parents: 67
diff changeset
583
kono
parents: 67
diff changeset
584 if (result != NO_LOOP)
kono
parents: 67
diff changeset
585 unblock (v, blocked, block_lists);
kono
parents: 67
diff changeset
586 else
kono
parents: 67
diff changeset
587 for (arc_t *arc = v->succ; arc; arc = arc->succ_next)
kono
parents: 67
diff changeset
588 {
kono
parents: 67
diff changeset
589 block_t *w = arc->dst;
kono
parents: 67
diff changeset
590 if (w < start || !linfo.has_block (w))
kono
parents: 67
diff changeset
591 continue;
kono
parents: 67
diff changeset
592
kono
parents: 67
diff changeset
593 size_t index
kono
parents: 67
diff changeset
594 = find (blocked.begin (), blocked.end (), w) - blocked.begin ();
kono
parents: 67
diff changeset
595 gcc_assert (index < blocked.size ());
kono
parents: 67
diff changeset
596 block_vector_t &list = block_lists[index];
kono
parents: 67
diff changeset
597 if (find (list.begin (), list.end (), v) == list.end ())
kono
parents: 67
diff changeset
598 list.push_back (v);
kono
parents: 67
diff changeset
599 }
kono
parents: 67
diff changeset
600
kono
parents: 67
diff changeset
601 return result;
kono
parents: 67
diff changeset
602 }
kono
parents: 67
diff changeset
603
kono
parents: 67
diff changeset
604 /* Find cycles for a LINFO. If HANDLE_NEGATIVE_CYCLES is set and the line
kono
parents: 67
diff changeset
605 contains a negative loop, then perform the same function once again. */
kono
parents: 67
diff changeset
606
kono
parents: 67
diff changeset
607 static gcov_type
kono
parents: 67
diff changeset
608 get_cycles_count (line_t &linfo, bool handle_negative_cycles = true)
kono
parents: 67
diff changeset
609 {
kono
parents: 67
diff changeset
610 /* Note that this algorithm works even if blocks aren't in sorted order.
kono
parents: 67
diff changeset
611 Each iteration of the circuit detection is completely independent
kono
parents: 67
diff changeset
612 (except for reducing counts, but that shouldn't matter anyways).
kono
parents: 67
diff changeset
613 Therefore, operating on a permuted order (i.e., non-sorted) only
kono
parents: 67
diff changeset
614 has the effect of permuting the output cycles. */
kono
parents: 67
diff changeset
615
kono
parents: 67
diff changeset
616 loop_type result = NO_LOOP;
kono
parents: 67
diff changeset
617 gcov_type count = 0;
kono
parents: 67
diff changeset
618 for (block_t *block = linfo.blocks; block; block = block->chain)
kono
parents: 67
diff changeset
619 {
kono
parents: 67
diff changeset
620 arc_vector_t path;
kono
parents: 67
diff changeset
621 block_vector_t blocked;
kono
parents: 67
diff changeset
622 vector<block_vector_t > block_lists;
kono
parents: 67
diff changeset
623 result |= circuit (block, path, block, blocked, block_lists, linfo,
kono
parents: 67
diff changeset
624 count);
kono
parents: 67
diff changeset
625 }
kono
parents: 67
diff changeset
626
kono
parents: 67
diff changeset
627 /* If we have a negative cycle, repeat the find_cycles routine. */
kono
parents: 67
diff changeset
628 if (result == NEGATIVE_LOOP && handle_negative_cycles)
kono
parents: 67
diff changeset
629 count += get_cycles_count (linfo, false);
kono
parents: 67
diff changeset
630
kono
parents: 67
diff changeset
631 return count;
kono
parents: 67
diff changeset
632 }
kono
parents: 67
diff changeset
633
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
634 int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
635 main (int argc, char **argv)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
636 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
637 int argno;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
638 int first_arg;
111
kono
parents: 67
diff changeset
639 const char *p;
kono
parents: 67
diff changeset
640
kono
parents: 67
diff changeset
641 p = argv[0] + strlen (argv[0]);
kono
parents: 67
diff changeset
642 while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
kono
parents: 67
diff changeset
643 --p;
kono
parents: 67
diff changeset
644 progname = p;
kono
parents: 67
diff changeset
645
kono
parents: 67
diff changeset
646 xmalloc_set_program_name (progname);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
647
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
648 /* Unlock the stdio streams. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
649 unlock_std_streams ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
650
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
651 gcc_init_libintl ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
652
111
kono
parents: 67
diff changeset
653 diagnostic_initialize (global_dc, 0);
kono
parents: 67
diff changeset
654
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
655 /* Handle response files. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
656 expandargv (&argc, &argv);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
657
111
kono
parents: 67
diff changeset
658 a_names = 10;
kono
parents: 67
diff changeset
659 names = XNEWVEC (name_map_t, a_names);
kono
parents: 67
diff changeset
660 a_sources = 10;
kono
parents: 67
diff changeset
661 sources = XNEWVEC (source_t, a_sources);
kono
parents: 67
diff changeset
662
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
663 argno = process_args (argc, argv);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
664 if (optind == argc)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
665 print_usage (true);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
666
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
667 if (argc - argno > 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
668 multiple_files = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
669
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
670 first_arg = argno;
111
kono
parents: 67
diff changeset
671
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
672 for (; argno != argc; argno++)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
673 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
674 if (flag_display_progress)
111
kono
parents: 67
diff changeset
675 printf ("Processing file %d out of %d\n", argno - first_arg + 1,
kono
parents: 67
diff changeset
676 argc - first_arg);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
677 process_file (argv[argno]);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
678 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
679
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
680 generate_results (multiple_files ? NULL : argv[argc - 1]);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
681
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
682 release_structures ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
683
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
684 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
685 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
686
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
687 /* Print a usage message and exit. If ERROR_P is nonzero, this is an error,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
688 otherwise the output of --help. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
689
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
690 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
691 print_usage (int error_p)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
692 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
693 FILE *file = error_p ? stderr : stdout;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
694 int status = error_p ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
695
111
kono
parents: 67
diff changeset
696 fnotice (file, "Usage: gcov [OPTION...] SOURCE|OBJ...\n\n");
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
697 fnotice (file, "Print code coverage information.\n\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
698 fnotice (file, " -a, --all-blocks Show information for every basic block\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
699 fnotice (file, " -b, --branch-probabilities Include branch probabilities in output\n");
111
kono
parents: 67
diff changeset
700 fnotice (file, " -c, --branch-counts Output counts of branches taken\n\
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
701 rather than percentages\n");
111
kono
parents: 67
diff changeset
702 fnotice (file, " -d, --display-progress Display progress information\n");
kono
parents: 67
diff changeset
703 fnotice (file, " -f, --function-summaries Output summaries for each function\n");
kono
parents: 67
diff changeset
704 fnotice (file, " -h, --help Print this help, then exit\n");
kono
parents: 67
diff changeset
705 fnotice (file, " -i, --intermediate-format Output .gcov file in intermediate text format\n");
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
706 fnotice (file, " -l, --long-file-names Use long output file names for included\n\
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
707 source files\n");
111
kono
parents: 67
diff changeset
708 fnotice (file, " -m, --demangled-names Output demangled function names\n");
kono
parents: 67
diff changeset
709 fnotice (file, " -n, --no-output Do not create an output file\n");
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
710 fnotice (file, " -o, --object-directory DIR|FILE Search for object files in DIR or called FILE\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
711 fnotice (file, " -p, --preserve-paths Preserve all pathname components\n");
111
kono
parents: 67
diff changeset
712 fnotice (file, " -r, --relative-only Only show data for relative sources\n");
kono
parents: 67
diff changeset
713 fnotice (file, " -s, --source-prefix DIR Source prefix to elide\n");
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
714 fnotice (file, " -u, --unconditional-branches Show unconditional branch counts too\n");
111
kono
parents: 67
diff changeset
715 fnotice (file, " -v, --version Print version number, then exit\n");
kono
parents: 67
diff changeset
716 fnotice (file, " -w, --verbose Print verbose informations\n");
kono
parents: 67
diff changeset
717 fnotice (file, " -x, --hash-filenames Hash long pathnames\n");
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
718 fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
719 bug_report_url);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
720 exit (status);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
721 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
722
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
723 /* Print version information and exit. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
724
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
725 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
726 print_version (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
727 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
728 fnotice (stdout, "gcov %s%s\n", pkgversion_string, version_string);
111
kono
parents: 67
diff changeset
729 fprintf (stdout, "Copyright %s 2017 Free Software Foundation, Inc.\n",
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
730 _("(C)"));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
731 fnotice (stdout,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
732 _("This is free software; see the source for copying conditions.\n"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
733 "There is NO warranty; not even for MERCHANTABILITY or \n"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
734 "FITNESS FOR A PARTICULAR PURPOSE.\n\n"));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
735 exit (SUCCESS_EXIT_CODE);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
736 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
737
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
738 static const struct option options[] =
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
739 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
740 { "help", no_argument, NULL, 'h' },
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
741 { "version", no_argument, NULL, 'v' },
111
kono
parents: 67
diff changeset
742 { "verbose", no_argument, NULL, 'w' },
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
743 { "all-blocks", no_argument, NULL, 'a' },
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
744 { "branch-probabilities", no_argument, NULL, 'b' },
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
745 { "branch-counts", no_argument, NULL, 'c' },
111
kono
parents: 67
diff changeset
746 { "intermediate-format", no_argument, NULL, 'i' },
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
747 { "no-output", no_argument, NULL, 'n' },
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
748 { "long-file-names", no_argument, NULL, 'l' },
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
749 { "function-summaries", no_argument, NULL, 'f' },
111
kono
parents: 67
diff changeset
750 { "demangled-names", no_argument, NULL, 'm' },
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
751 { "preserve-paths", no_argument, NULL, 'p' },
111
kono
parents: 67
diff changeset
752 { "relative-only", no_argument, NULL, 'r' },
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
753 { "object-directory", required_argument, NULL, 'o' },
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
754 { "object-file", required_argument, NULL, 'o' },
111
kono
parents: 67
diff changeset
755 { "source-prefix", required_argument, NULL, 's' },
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
756 { "unconditional-branches", no_argument, NULL, 'u' },
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
757 { "display-progress", no_argument, NULL, 'd' },
111
kono
parents: 67
diff changeset
758 { "hash-filenames", no_argument, NULL, 'x' },
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
759 { 0, 0, 0, 0 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
760 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
761
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
762 /* Process args, return index to first non-arg. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
763
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
764 static int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
765 process_args (int argc, char **argv)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
766 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
767 int opt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
768
111
kono
parents: 67
diff changeset
769 const char *opts = "abcdfhilmno:prs:uvwx";
kono
parents: 67
diff changeset
770 while ((opt = getopt_long (argc, argv, opts, options, NULL)) != -1)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
771 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
772 switch (opt)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
773 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
774 case 'a':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
775 flag_all_blocks = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
776 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
777 case 'b':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
778 flag_branches = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
779 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
780 case 'c':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
781 flag_counts = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
782 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
783 case 'f':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
784 flag_function_summary = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
785 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
786 case 'h':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
787 print_usage (false);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
788 /* print_usage will exit. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
789 case 'l':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
790 flag_long_names = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
791 break;
111
kono
parents: 67
diff changeset
792 case 'm':
kono
parents: 67
diff changeset
793 flag_demangled_names = 1;
kono
parents: 67
diff changeset
794 break;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
795 case 'n':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
796 flag_gcov_file = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
797 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
798 case 'o':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
799 object_directory = optarg;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
800 break;
111
kono
parents: 67
diff changeset
801 case 's':
kono
parents: 67
diff changeset
802 source_prefix = optarg;
kono
parents: 67
diff changeset
803 source_length = strlen (source_prefix);
kono
parents: 67
diff changeset
804 break;
kono
parents: 67
diff changeset
805 case 'r':
kono
parents: 67
diff changeset
806 flag_relative_only = 1;
kono
parents: 67
diff changeset
807 break;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
808 case 'p':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
809 flag_preserve_paths = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
810 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
811 case 'u':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
812 flag_unconditional = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
813 break;
111
kono
parents: 67
diff changeset
814 case 'i':
kono
parents: 67
diff changeset
815 flag_intermediate_format = 1;
kono
parents: 67
diff changeset
816 flag_gcov_file = 1;
kono
parents: 67
diff changeset
817 break;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
818 case 'd':
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
819 flag_display_progress = 1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
820 break;
111
kono
parents: 67
diff changeset
821 case 'x':
kono
parents: 67
diff changeset
822 flag_hash_filenames = 1;
kono
parents: 67
diff changeset
823 break;
kono
parents: 67
diff changeset
824 case 'w':
kono
parents: 67
diff changeset
825 flag_verbose = 1;
kono
parents: 67
diff changeset
826 break;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
827 case 'v':
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
828 print_version ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
829 /* print_version will exit. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
830 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
831 print_usage (true);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
832 /* print_usage will exit. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
833 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
834 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
835
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
836 return optind;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
837 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
838
111
kono
parents: 67
diff changeset
839 /* Output the result in intermediate format used by 'lcov'.
kono
parents: 67
diff changeset
840
kono
parents: 67
diff changeset
841 The intermediate format contains a single file named 'foo.cc.gcov',
kono
parents: 67
diff changeset
842 with no source code included. A sample output is
kono
parents: 67
diff changeset
843
kono
parents: 67
diff changeset
844 file:foo.cc
kono
parents: 67
diff changeset
845 function:5,1,_Z3foov
kono
parents: 67
diff changeset
846 function:13,1,main
kono
parents: 67
diff changeset
847 function:19,1,_GLOBAL__sub_I__Z3foov
kono
parents: 67
diff changeset
848 function:19,1,_Z41__static_initialization_and_destruction_0ii
kono
parents: 67
diff changeset
849 lcount:5,1
kono
parents: 67
diff changeset
850 lcount:7,9
kono
parents: 67
diff changeset
851 lcount:9,8
kono
parents: 67
diff changeset
852 lcount:11,1
kono
parents: 67
diff changeset
853 file:/.../iostream
kono
parents: 67
diff changeset
854 lcount:74,1
kono
parents: 67
diff changeset
855 file:/.../basic_ios.h
kono
parents: 67
diff changeset
856 file:/.../ostream
kono
parents: 67
diff changeset
857 file:/.../ios_base.h
kono
parents: 67
diff changeset
858 function:157,0,_ZStorSt12_Ios_IostateS_
kono
parents: 67
diff changeset
859 lcount:157,0
kono
parents: 67
diff changeset
860 file:/.../char_traits.h
kono
parents: 67
diff changeset
861 function:258,0,_ZNSt11char_traitsIcE6lengthEPKc
kono
parents: 67
diff changeset
862 lcount:258,0
kono
parents: 67
diff changeset
863 ...
kono
parents: 67
diff changeset
864
kono
parents: 67
diff changeset
865 The default gcov outputs multiple files: 'foo.cc.gcov',
kono
parents: 67
diff changeset
866 'iostream.gcov', 'ios_base.h.gcov', etc. with source code
kono
parents: 67
diff changeset
867 included. Instead the intermediate format here outputs only a single
kono
parents: 67
diff changeset
868 file 'foo.cc.gcov' similar to the above example. */
kono
parents: 67
diff changeset
869
kono
parents: 67
diff changeset
870 static void
kono
parents: 67
diff changeset
871 output_intermediate_file (FILE *gcov_file, source_t *src)
kono
parents: 67
diff changeset
872 {
kono
parents: 67
diff changeset
873 unsigned line_num; /* current line number. */
kono
parents: 67
diff changeset
874 const line_t *line; /* current line info ptr. */
kono
parents: 67
diff changeset
875 function_t *fn; /* current function info ptr. */
kono
parents: 67
diff changeset
876
kono
parents: 67
diff changeset
877 fprintf (gcov_file, "file:%s\n", src->name); /* source file name */
kono
parents: 67
diff changeset
878
kono
parents: 67
diff changeset
879 for (fn = src->functions; fn; fn = fn->next_file_fn)
kono
parents: 67
diff changeset
880 {
kono
parents: 67
diff changeset
881 /* function:<name>,<line_number>,<execution_count> */
kono
parents: 67
diff changeset
882 fprintf (gcov_file, "function:%d,%s,%s\n", fn->line,
kono
parents: 67
diff changeset
883 format_gcov (fn->blocks[0].count, 0, -1),
kono
parents: 67
diff changeset
884 flag_demangled_names ? fn->demangled_name : fn->name);
kono
parents: 67
diff changeset
885 }
kono
parents: 67
diff changeset
886
kono
parents: 67
diff changeset
887 for (line_num = 1, line = &src->lines[line_num];
kono
parents: 67
diff changeset
888 line_num < src->num_lines;
kono
parents: 67
diff changeset
889 line_num++, line++)
kono
parents: 67
diff changeset
890 {
kono
parents: 67
diff changeset
891 arc_t *arc;
kono
parents: 67
diff changeset
892 if (line->exists)
kono
parents: 67
diff changeset
893 fprintf (gcov_file, "lcount:%u,%s\n", line_num,
kono
parents: 67
diff changeset
894 format_gcov (line->count, 0, -1));
kono
parents: 67
diff changeset
895 if (flag_branches)
kono
parents: 67
diff changeset
896 for (arc = line->branches; arc; arc = arc->line_next)
kono
parents: 67
diff changeset
897 {
kono
parents: 67
diff changeset
898 if (!arc->is_unconditional && !arc->is_call_non_return)
kono
parents: 67
diff changeset
899 {
kono
parents: 67
diff changeset
900 const char *branch_type;
kono
parents: 67
diff changeset
901 /* branch:<line_num>,<branch_coverage_type>
kono
parents: 67
diff changeset
902 branch_coverage_type
kono
parents: 67
diff changeset
903 : notexec (Branch not executed)
kono
parents: 67
diff changeset
904 : taken (Branch executed and taken)
kono
parents: 67
diff changeset
905 : nottaken (Branch executed, but not taken)
kono
parents: 67
diff changeset
906 */
kono
parents: 67
diff changeset
907 if (arc->src->count)
kono
parents: 67
diff changeset
908 branch_type = (arc->count > 0) ? "taken" : "nottaken";
kono
parents: 67
diff changeset
909 else
kono
parents: 67
diff changeset
910 branch_type = "notexec";
kono
parents: 67
diff changeset
911 fprintf (gcov_file, "branch:%d,%s\n", line_num, branch_type);
kono
parents: 67
diff changeset
912 }
kono
parents: 67
diff changeset
913 }
kono
parents: 67
diff changeset
914 }
kono
parents: 67
diff changeset
915 }
kono
parents: 67
diff changeset
916
kono
parents: 67
diff changeset
917 /* Process a single input file. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
918
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
919 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
920 process_file (const char *file_name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
921 {
111
kono
parents: 67
diff changeset
922 function_t *fns;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
923
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
924 create_file_names (file_name);
111
kono
parents: 67
diff changeset
925 fns = read_graph_file ();
kono
parents: 67
diff changeset
926 if (!fns)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
927 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
928
111
kono
parents: 67
diff changeset
929 read_count_file (fns);
kono
parents: 67
diff changeset
930 while (fns)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
931 {
111
kono
parents: 67
diff changeset
932 function_t *fn = fns;
kono
parents: 67
diff changeset
933
kono
parents: 67
diff changeset
934 fns = fn->next;
kono
parents: 67
diff changeset
935 fn->next = NULL;
kono
parents: 67
diff changeset
936 if (fn->counts || no_data_file)
kono
parents: 67
diff changeset
937 {
kono
parents: 67
diff changeset
938 unsigned src = fn->src;
kono
parents: 67
diff changeset
939 unsigned line = fn->line;
kono
parents: 67
diff changeset
940 unsigned block_no;
kono
parents: 67
diff changeset
941 function_t *probe, **prev;
kono
parents: 67
diff changeset
942
kono
parents: 67
diff changeset
943 /* Now insert it into the source file's list of
kono
parents: 67
diff changeset
944 functions. Normally functions will be encountered in
kono
parents: 67
diff changeset
945 ascending order, so a simple scan is quick. Note we're
kono
parents: 67
diff changeset
946 building this list in reverse order. */
kono
parents: 67
diff changeset
947 for (prev = &sources[src].functions;
kono
parents: 67
diff changeset
948 (probe = *prev); prev = &probe->next_file_fn)
kono
parents: 67
diff changeset
949 if (probe->line <= line)
kono
parents: 67
diff changeset
950 break;
kono
parents: 67
diff changeset
951 fn->next_file_fn = probe;
kono
parents: 67
diff changeset
952 *prev = fn;
kono
parents: 67
diff changeset
953
kono
parents: 67
diff changeset
954 /* Mark last line in files touched by function. */
kono
parents: 67
diff changeset
955 for (block_no = 0; block_no != fn->blocks.size (); block_no++)
kono
parents: 67
diff changeset
956 {
kono
parents: 67
diff changeset
957 block_t *block = &fn->blocks[block_no];
kono
parents: 67
diff changeset
958 for (unsigned i = 0; i < block->locations.size (); i++)
kono
parents: 67
diff changeset
959 {
kono
parents: 67
diff changeset
960 unsigned s = block->locations[i].source_file_idx;
kono
parents: 67
diff changeset
961
kono
parents: 67
diff changeset
962 /* Sort lines of locations. */
kono
parents: 67
diff changeset
963 sort (block->locations[i].lines.begin (),
kono
parents: 67
diff changeset
964 block->locations[i].lines.end ());
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
965
111
kono
parents: 67
diff changeset
966 if (!block->locations[i].lines.empty ())
kono
parents: 67
diff changeset
967 {
kono
parents: 67
diff changeset
968 unsigned last_line
kono
parents: 67
diff changeset
969 = block->locations[i].lines.back () + 1;
kono
parents: 67
diff changeset
970 if (last_line > sources[s].num_lines)
kono
parents: 67
diff changeset
971 sources[s].num_lines = last_line;
kono
parents: 67
diff changeset
972 }
kono
parents: 67
diff changeset
973 }
kono
parents: 67
diff changeset
974 }
kono
parents: 67
diff changeset
975
kono
parents: 67
diff changeset
976 solve_flow_graph (fn);
kono
parents: 67
diff changeset
977 if (fn->has_catch)
kono
parents: 67
diff changeset
978 find_exception_blocks (fn);
kono
parents: 67
diff changeset
979 *fn_end = fn;
kono
parents: 67
diff changeset
980 fn_end = &fn->next;
kono
parents: 67
diff changeset
981 }
kono
parents: 67
diff changeset
982 else
kono
parents: 67
diff changeset
983 /* The function was not in the executable -- some other
kono
parents: 67
diff changeset
984 instance must have been selected. */
kono
parents: 67
diff changeset
985 delete fn;
kono
parents: 67
diff changeset
986 }
kono
parents: 67
diff changeset
987 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
988
111
kono
parents: 67
diff changeset
989 static void
kono
parents: 67
diff changeset
990 output_gcov_file (const char *file_name, source_t *src)
kono
parents: 67
diff changeset
991 {
kono
parents: 67
diff changeset
992 char *gcov_file_name = make_gcov_file_name (file_name, src->coverage.name);
kono
parents: 67
diff changeset
993
kono
parents: 67
diff changeset
994 if (src->coverage.lines)
kono
parents: 67
diff changeset
995 {
kono
parents: 67
diff changeset
996 FILE *gcov_file = fopen (gcov_file_name, "w");
kono
parents: 67
diff changeset
997 if (gcov_file)
kono
parents: 67
diff changeset
998 {
kono
parents: 67
diff changeset
999 fnotice (stdout, "Creating '%s'\n", gcov_file_name);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1000
111
kono
parents: 67
diff changeset
1001 if (flag_intermediate_format)
kono
parents: 67
diff changeset
1002 output_intermediate_file (gcov_file, src);
kono
parents: 67
diff changeset
1003 else
kono
parents: 67
diff changeset
1004 output_lines (gcov_file, src);
kono
parents: 67
diff changeset
1005 if (ferror (gcov_file))
kono
parents: 67
diff changeset
1006 fnotice (stderr, "Error writing output file '%s'\n", gcov_file_name);
kono
parents: 67
diff changeset
1007 fclose (gcov_file);
kono
parents: 67
diff changeset
1008 }
kono
parents: 67
diff changeset
1009 else
kono
parents: 67
diff changeset
1010 fnotice (stderr, "Could not open output file '%s'\n", gcov_file_name);
kono
parents: 67
diff changeset
1011 }
kono
parents: 67
diff changeset
1012 else
kono
parents: 67
diff changeset
1013 {
kono
parents: 67
diff changeset
1014 unlink (gcov_file_name);
kono
parents: 67
diff changeset
1015 fnotice (stdout, "Removing '%s'\n", gcov_file_name);
kono
parents: 67
diff changeset
1016 }
kono
parents: 67
diff changeset
1017 free (gcov_file_name);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1018 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1019
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1020 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1021 generate_results (const char *file_name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1022 {
111
kono
parents: 67
diff changeset
1023 unsigned ix;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1024 source_t *src;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1025 function_t *fn;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1026
111
kono
parents: 67
diff changeset
1027 for (ix = n_sources, src = sources; ix--; src++)
kono
parents: 67
diff changeset
1028 if (src->num_lines)
kono
parents: 67
diff changeset
1029 src->lines = XCNEWVEC (line_t, src->num_lines);
kono
parents: 67
diff changeset
1030
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1031 for (fn = functions; fn; fn = fn->next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1032 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1033 coverage_t coverage;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1034
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1035 memset (&coverage, 0, sizeof (coverage));
111
kono
parents: 67
diff changeset
1036 coverage.name = flag_demangled_names ? fn->demangled_name : fn->name;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1037 add_line_counts (flag_function_summary ? &coverage : NULL, fn);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1038 if (flag_function_summary)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1039 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1040 function_summary (&coverage, "Function");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1041 fnotice (stdout, "\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1042 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1043 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1044
111
kono
parents: 67
diff changeset
1045 if (file_name)
kono
parents: 67
diff changeset
1046 {
kono
parents: 67
diff changeset
1047 name_map_t *name_map = (name_map_t *)bsearch
kono
parents: 67
diff changeset
1048 (file_name, names, n_names, sizeof (*names), name_search);
kono
parents: 67
diff changeset
1049 if (name_map)
kono
parents: 67
diff changeset
1050 file_name = sources[name_map->src].coverage.name;
kono
parents: 67
diff changeset
1051 else
kono
parents: 67
diff changeset
1052 file_name = canonicalize_name (file_name);
kono
parents: 67
diff changeset
1053 }
kono
parents: 67
diff changeset
1054
kono
parents: 67
diff changeset
1055 for (ix = n_sources, src = sources; ix--; src++)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1056 {
111
kono
parents: 67
diff changeset
1057 if (flag_relative_only)
kono
parents: 67
diff changeset
1058 {
kono
parents: 67
diff changeset
1059 /* Ignore this source, if it is an absolute path (after
kono
parents: 67
diff changeset
1060 source prefix removal). */
kono
parents: 67
diff changeset
1061 char first = src->coverage.name[0];
kono
parents: 67
diff changeset
1062
kono
parents: 67
diff changeset
1063 #if HAVE_DOS_BASED_FILE_SYSTEM
kono
parents: 67
diff changeset
1064 if (first && src->coverage.name[1] == ':')
kono
parents: 67
diff changeset
1065 first = src->coverage.name[2];
kono
parents: 67
diff changeset
1066 #endif
kono
parents: 67
diff changeset
1067 if (IS_DIR_SEPARATOR (first))
kono
parents: 67
diff changeset
1068 continue;
kono
parents: 67
diff changeset
1069 }
kono
parents: 67
diff changeset
1070
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1071 accumulate_line_counts (src);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1072 function_summary (&src->coverage, "File");
111
kono
parents: 67
diff changeset
1073 total_lines += src->coverage.lines;
kono
parents: 67
diff changeset
1074 total_executed += src->coverage.lines_executed;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1075 if (flag_gcov_file)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1076 {
111
kono
parents: 67
diff changeset
1077 output_gcov_file (file_name, src);
kono
parents: 67
diff changeset
1078 fnotice (stdout, "\n");
kono
parents: 67
diff changeset
1079 }
kono
parents: 67
diff changeset
1080 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1081
111
kono
parents: 67
diff changeset
1082 if (!file_name)
kono
parents: 67
diff changeset
1083 executed_summary (total_lines, total_executed);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1084 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1085
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1086 /* Release all memory used. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1087
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1088 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1089 release_structures (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1090 {
111
kono
parents: 67
diff changeset
1091 unsigned ix;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1092 function_t *fn;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1093
111
kono
parents: 67
diff changeset
1094 for (ix = n_sources; ix--;)
kono
parents: 67
diff changeset
1095 free (sources[ix].lines);
kono
parents: 67
diff changeset
1096 free (sources);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1097
111
kono
parents: 67
diff changeset
1098 for (ix = n_names; ix--;)
kono
parents: 67
diff changeset
1099 free (names[ix].name);
kono
parents: 67
diff changeset
1100 free (names);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1101
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1102 while ((fn = functions))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1103 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1104 functions = fn->next;
111
kono
parents: 67
diff changeset
1105 delete fn;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1106 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1107 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1108
111
kono
parents: 67
diff changeset
1109 /* Generate the names of the graph and data files. If OBJECT_DIRECTORY
kono
parents: 67
diff changeset
1110 is not specified, these are named from FILE_NAME sans extension. If
kono
parents: 67
diff changeset
1111 OBJECT_DIRECTORY is specified and is a directory, the files are in that
kono
parents: 67
diff changeset
1112 directory, but named from the basename of the FILE_NAME, sans extension.
kono
parents: 67
diff changeset
1113 Otherwise OBJECT_DIRECTORY is taken to be the name of the object *file*
kono
parents: 67
diff changeset
1114 and the data files are named from that. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1115
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1116 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1117 create_file_names (const char *file_name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1118 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1119 char *cptr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1120 char *name;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1121 int length = strlen (file_name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1122 int base;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1123
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1124 /* Free previous file names. */
111
kono
parents: 67
diff changeset
1125 free (bbg_file_name);
kono
parents: 67
diff changeset
1126 free (da_file_name);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1127 da_file_name = bbg_file_name = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1128 bbg_file_time = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1129 bbg_stamp = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1130
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1131 if (object_directory && object_directory[0])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1132 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1133 struct stat status;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1134
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1135 length += strlen (object_directory) + 2;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1136 name = XNEWVEC (char, length);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1137 name[0] = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1138
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1139 base = !stat (object_directory, &status) && S_ISDIR (status.st_mode);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1140 strcat (name, object_directory);
111
kono
parents: 67
diff changeset
1141 if (base && (!IS_DIR_SEPARATOR (name[strlen (name) - 1])))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1142 strcat (name, "/");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1143 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1144 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1145 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1146 name = XNEWVEC (char, length + 1);
111
kono
parents: 67
diff changeset
1147 strcpy (name, file_name);
kono
parents: 67
diff changeset
1148 base = 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1149 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1150
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1151 if (base)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1152 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1153 /* Append source file name. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1154 const char *cptr = lbasename (file_name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1155 strcat (name, cptr ? cptr : file_name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1156 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1157
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1158 /* Remove the extension. */
111
kono
parents: 67
diff changeset
1159 cptr = strrchr (CONST_CAST (char *, lbasename (name)), '.');
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1160 if (cptr)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1161 *cptr = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1162
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1163 length = strlen (name);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1164
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1165 bbg_file_name = XNEWVEC (char, length + strlen (GCOV_NOTE_SUFFIX) + 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1166 strcpy (bbg_file_name, name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1167 strcpy (bbg_file_name + length, GCOV_NOTE_SUFFIX);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1168
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1169 da_file_name = XNEWVEC (char, length + strlen (GCOV_DATA_SUFFIX) + 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1170 strcpy (da_file_name, name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1171 strcpy (da_file_name + length, GCOV_DATA_SUFFIX);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1172
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1173 free (name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1174 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1175 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1176
111
kono
parents: 67
diff changeset
1177 /* A is a string and B is a pointer to name_map_t. Compare for file
kono
parents: 67
diff changeset
1178 name orderability. */
kono
parents: 67
diff changeset
1179
kono
parents: 67
diff changeset
1180 static int
kono
parents: 67
diff changeset
1181 name_search (const void *a_, const void *b_)
kono
parents: 67
diff changeset
1182 {
kono
parents: 67
diff changeset
1183 const char *a = (const char *)a_;
kono
parents: 67
diff changeset
1184 const name_map_t *b = (const name_map_t *)b_;
kono
parents: 67
diff changeset
1185
kono
parents: 67
diff changeset
1186 #if HAVE_DOS_BASED_FILE_SYSTEM
kono
parents: 67
diff changeset
1187 return strcasecmp (a, b->name);
kono
parents: 67
diff changeset
1188 #else
kono
parents: 67
diff changeset
1189 return strcmp (a, b->name);
kono
parents: 67
diff changeset
1190 #endif
kono
parents: 67
diff changeset
1191 }
kono
parents: 67
diff changeset
1192
kono
parents: 67
diff changeset
1193 /* A and B are a pointer to name_map_t. Compare for file name
kono
parents: 67
diff changeset
1194 orderability. */
kono
parents: 67
diff changeset
1195
kono
parents: 67
diff changeset
1196 static int
kono
parents: 67
diff changeset
1197 name_sort (const void *a_, const void *b_)
kono
parents: 67
diff changeset
1198 {
kono
parents: 67
diff changeset
1199 const name_map_t *a = (const name_map_t *)a_;
kono
parents: 67
diff changeset
1200 return name_search (a->name, b_);
kono
parents: 67
diff changeset
1201 }
kono
parents: 67
diff changeset
1202
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1203 /* Find or create a source file structure for FILE_NAME. Copies
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1204 FILE_NAME on creation */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1205
111
kono
parents: 67
diff changeset
1206 static unsigned
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1207 find_source (const char *file_name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1208 {
111
kono
parents: 67
diff changeset
1209 name_map_t *name_map;
kono
parents: 67
diff changeset
1210 char *canon;
kono
parents: 67
diff changeset
1211 unsigned idx;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1212 struct stat status;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1213
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1214 if (!file_name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1215 file_name = "<unknown>";
111
kono
parents: 67
diff changeset
1216 name_map = (name_map_t *)bsearch
kono
parents: 67
diff changeset
1217 (file_name, names, n_names, sizeof (*names), name_search);
kono
parents: 67
diff changeset
1218 if (name_map)
kono
parents: 67
diff changeset
1219 {
kono
parents: 67
diff changeset
1220 idx = name_map->src;
kono
parents: 67
diff changeset
1221 goto check_date;
kono
parents: 67
diff changeset
1222 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1223
111
kono
parents: 67
diff changeset
1224 if (n_names + 2 > a_names)
kono
parents: 67
diff changeset
1225 {
kono
parents: 67
diff changeset
1226 /* Extend the name map array -- we'll be inserting one or two
kono
parents: 67
diff changeset
1227 entries. */
kono
parents: 67
diff changeset
1228 a_names *= 2;
kono
parents: 67
diff changeset
1229 name_map = XNEWVEC (name_map_t, a_names);
kono
parents: 67
diff changeset
1230 memcpy (name_map, names, n_names * sizeof (*names));
kono
parents: 67
diff changeset
1231 free (names);
kono
parents: 67
diff changeset
1232 names = name_map;
kono
parents: 67
diff changeset
1233 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1234
111
kono
parents: 67
diff changeset
1235 /* Not found, try the canonical name. */
kono
parents: 67
diff changeset
1236 canon = canonicalize_name (file_name);
kono
parents: 67
diff changeset
1237 name_map = (name_map_t *) bsearch (canon, names, n_names, sizeof (*names),
kono
parents: 67
diff changeset
1238 name_search);
kono
parents: 67
diff changeset
1239 if (!name_map)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1240 {
111
kono
parents: 67
diff changeset
1241 /* Not found with canonical name, create a new source. */
kono
parents: 67
diff changeset
1242 source_t *src;
kono
parents: 67
diff changeset
1243
kono
parents: 67
diff changeset
1244 if (n_sources == a_sources)
kono
parents: 67
diff changeset
1245 {
kono
parents: 67
diff changeset
1246 a_sources *= 2;
kono
parents: 67
diff changeset
1247 src = XNEWVEC (source_t, a_sources);
kono
parents: 67
diff changeset
1248 memcpy (src, sources, n_sources * sizeof (*sources));
kono
parents: 67
diff changeset
1249 free (sources);
kono
parents: 67
diff changeset
1250 sources = src;
kono
parents: 67
diff changeset
1251 }
kono
parents: 67
diff changeset
1252
kono
parents: 67
diff changeset
1253 idx = n_sources;
kono
parents: 67
diff changeset
1254
kono
parents: 67
diff changeset
1255 name_map = &names[n_names++];
kono
parents: 67
diff changeset
1256 name_map->name = canon;
kono
parents: 67
diff changeset
1257 name_map->src = idx;
kono
parents: 67
diff changeset
1258
kono
parents: 67
diff changeset
1259 src = &sources[n_sources++];
kono
parents: 67
diff changeset
1260 memset (src, 0, sizeof (*src));
kono
parents: 67
diff changeset
1261 src->name = canon;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1262 src->coverage.name = src->name;
111
kono
parents: 67
diff changeset
1263 if (source_length
kono
parents: 67
diff changeset
1264 #if HAVE_DOS_BASED_FILE_SYSTEM
kono
parents: 67
diff changeset
1265 /* You lose if separators don't match exactly in the
kono
parents: 67
diff changeset
1266 prefix. */
kono
parents: 67
diff changeset
1267 && !strncasecmp (source_prefix, src->coverage.name, source_length)
kono
parents: 67
diff changeset
1268 #else
kono
parents: 67
diff changeset
1269 && !strncmp (source_prefix, src->coverage.name, source_length)
kono
parents: 67
diff changeset
1270 #endif
kono
parents: 67
diff changeset
1271 && IS_DIR_SEPARATOR (src->coverage.name[source_length]))
kono
parents: 67
diff changeset
1272 src->coverage.name += source_length + 1;
kono
parents: 67
diff changeset
1273 if (!stat (src->name, &status))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1274 src->file_time = status.st_mtime;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1275 }
111
kono
parents: 67
diff changeset
1276 else
kono
parents: 67
diff changeset
1277 idx = name_map->src;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1278
111
kono
parents: 67
diff changeset
1279 if (name_search (file_name, name_map))
kono
parents: 67
diff changeset
1280 {
kono
parents: 67
diff changeset
1281 /* Append the non-canonical name. */
kono
parents: 67
diff changeset
1282 name_map = &names[n_names++];
kono
parents: 67
diff changeset
1283 name_map->name = xstrdup (file_name);
kono
parents: 67
diff changeset
1284 name_map->src = idx;
kono
parents: 67
diff changeset
1285 }
kono
parents: 67
diff changeset
1286
kono
parents: 67
diff changeset
1287 /* Resort the name map. */
kono
parents: 67
diff changeset
1288 qsort (names, n_names, sizeof (*names), name_sort);
kono
parents: 67
diff changeset
1289
kono
parents: 67
diff changeset
1290 check_date:
kono
parents: 67
diff changeset
1291 if (sources[idx].file_time > bbg_file_time)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1292 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1293 static int info_emitted;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1294
111
kono
parents: 67
diff changeset
1295 fnotice (stderr, "%s:source file is newer than notes file '%s'\n",
kono
parents: 67
diff changeset
1296 file_name, bbg_file_name);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1297 if (!info_emitted)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1298 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1299 fnotice (stderr,
111
kono
parents: 67
diff changeset
1300 "(the message is displayed only once per source file)\n");
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1301 info_emitted = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1302 }
111
kono
parents: 67
diff changeset
1303 sources[idx].file_time = 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1304 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1305
111
kono
parents: 67
diff changeset
1306 return idx;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1307 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1308
111
kono
parents: 67
diff changeset
1309 /* Read the notes file. Return list of functions read -- in reverse order. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1310
111
kono
parents: 67
diff changeset
1311 static function_t *
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1312 read_graph_file (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1313 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1314 unsigned version;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1315 unsigned current_tag = 0;
111
kono
parents: 67
diff changeset
1316 function_t *fn = NULL;
kono
parents: 67
diff changeset
1317 function_t *fns = NULL;
kono
parents: 67
diff changeset
1318 function_t **fns_end = &fns;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1319 unsigned tag;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1320
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1321 if (!gcov_open (bbg_file_name, 1))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1322 {
111
kono
parents: 67
diff changeset
1323 fnotice (stderr, "%s:cannot open notes file\n", bbg_file_name);
kono
parents: 67
diff changeset
1324 return fns;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1325 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1326 bbg_file_time = gcov_time ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1327 if (!gcov_magic (gcov_read_unsigned (), GCOV_NOTE_MAGIC))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1328 {
111
kono
parents: 67
diff changeset
1329 fnotice (stderr, "%s:not a gcov notes file\n", bbg_file_name);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1330 gcov_close ();
111
kono
parents: 67
diff changeset
1331 return fns;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1332 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1333
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1334 version = gcov_read_unsigned ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1335 if (version != GCOV_VERSION)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1336 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1337 char v[4], e[4];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1338
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1339 GCOV_UNSIGNED2STRING (v, version);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1340 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1341
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1342 fnotice (stderr, "%s:version '%.4s', prefer '%.4s'\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1343 bbg_file_name, v, e);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1344 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1345 bbg_stamp = gcov_read_unsigned ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1346
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1347 while ((tag = gcov_read_unsigned ()))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1348 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1349 unsigned length = gcov_read_unsigned ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1350 gcov_position_t base = gcov_position ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1351
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1352 if (tag == GCOV_TAG_FUNCTION)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1353 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1354 char *function_name;
111
kono
parents: 67
diff changeset
1355 unsigned ident, lineno;
kono
parents: 67
diff changeset
1356 unsigned lineno_checksum, cfg_checksum;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1357
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1358 ident = gcov_read_unsigned ();
111
kono
parents: 67
diff changeset
1359 lineno_checksum = gcov_read_unsigned ();
kono
parents: 67
diff changeset
1360 cfg_checksum = gcov_read_unsigned ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1361 function_name = xstrdup (gcov_read_string ());
111
kono
parents: 67
diff changeset
1362 unsigned src_idx = find_source (gcov_read_string ());
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1363 lineno = gcov_read_unsigned ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1364
111
kono
parents: 67
diff changeset
1365 fn = new function_t;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1366 fn->name = function_name;
111
kono
parents: 67
diff changeset
1367 if (flag_demangled_names)
kono
parents: 67
diff changeset
1368 {
kono
parents: 67
diff changeset
1369 fn->demangled_name = cplus_demangle (fn->name, DMGL_PARAMS);
kono
parents: 67
diff changeset
1370 if (!fn->demangled_name)
kono
parents: 67
diff changeset
1371 fn->demangled_name = fn->name;
kono
parents: 67
diff changeset
1372 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1373 fn->ident = ident;
111
kono
parents: 67
diff changeset
1374 fn->lineno_checksum = lineno_checksum;
kono
parents: 67
diff changeset
1375 fn->cfg_checksum = cfg_checksum;
kono
parents: 67
diff changeset
1376 fn->src = src_idx;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1377 fn->line = lineno;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1378
111
kono
parents: 67
diff changeset
1379 fn->next_file_fn = NULL;
kono
parents: 67
diff changeset
1380 fn->next = NULL;
kono
parents: 67
diff changeset
1381 *fns_end = fn;
kono
parents: 67
diff changeset
1382 fns_end = &fn->next;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1383 current_tag = tag;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1384 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1385 else if (fn && tag == GCOV_TAG_BLOCKS)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1386 {
111
kono
parents: 67
diff changeset
1387 if (!fn->blocks.empty ())
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1388 fnotice (stderr, "%s:already seen blocks for '%s'\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1389 bbg_file_name, fn->name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1390 else
111
kono
parents: 67
diff changeset
1391 fn->blocks.resize (gcov_read_unsigned ());
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1392 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1393 else if (fn && tag == GCOV_TAG_ARCS)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1394 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1395 unsigned src = gcov_read_unsigned ();
111
kono
parents: 67
diff changeset
1396 fn->blocks[src].id = src;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1397 unsigned num_dests = GCOV_TAG_ARCS_NUM (length);
111
kono
parents: 67
diff changeset
1398 block_t *src_blk = &fn->blocks[src];
kono
parents: 67
diff changeset
1399 unsigned mark_catches = 0;
kono
parents: 67
diff changeset
1400 struct arc_info *arc;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1401
111
kono
parents: 67
diff changeset
1402 if (src >= fn->blocks.size () || fn->blocks[src].succ)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1403 goto corrupt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1404
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1405 while (num_dests--)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1406 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1407 unsigned dest = gcov_read_unsigned ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1408 unsigned flags = gcov_read_unsigned ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1409
111
kono
parents: 67
diff changeset
1410 if (dest >= fn->blocks.size ())
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1411 goto corrupt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1412 arc = XCNEW (arc_t);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1413
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1414 arc->dst = &fn->blocks[dest];
111
kono
parents: 67
diff changeset
1415 arc->src = src_blk;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1416
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1417 arc->count = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1418 arc->count_valid = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1419 arc->on_tree = !!(flags & GCOV_ARC_ON_TREE);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1420 arc->fake = !!(flags & GCOV_ARC_FAKE);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1421 arc->fall_through = !!(flags & GCOV_ARC_FALLTHROUGH);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1422
111
kono
parents: 67
diff changeset
1423 arc->succ_next = src_blk->succ;
kono
parents: 67
diff changeset
1424 src_blk->succ = arc;
kono
parents: 67
diff changeset
1425 src_blk->num_succ++;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1426
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1427 arc->pred_next = fn->blocks[dest].pred;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1428 fn->blocks[dest].pred = arc;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1429 fn->blocks[dest].num_pred++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1430
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1431 if (arc->fake)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1432 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1433 if (src)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1434 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1435 /* Exceptional exit from this function, the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1436 source block must be a call. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1437 fn->blocks[src].is_call_site = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1438 arc->is_call_non_return = 1;
111
kono
parents: 67
diff changeset
1439 mark_catches = 1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1440 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1441 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1442 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1443 /* Non-local return from a callee of this
111
kono
parents: 67
diff changeset
1444 function. The destination block is a setjmp. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1445 arc->is_nonlocal_return = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1446 fn->blocks[dest].is_nonlocal_return = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1447 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1448 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1449
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1450 if (!arc->on_tree)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1451 fn->num_counts++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1452 }
111
kono
parents: 67
diff changeset
1453
kono
parents: 67
diff changeset
1454 if (mark_catches)
kono
parents: 67
diff changeset
1455 {
kono
parents: 67
diff changeset
1456 /* We have a fake exit from this block. The other
kono
parents: 67
diff changeset
1457 non-fall through exits must be to catch handlers.
kono
parents: 67
diff changeset
1458 Mark them as catch arcs. */
kono
parents: 67
diff changeset
1459
kono
parents: 67
diff changeset
1460 for (arc = src_blk->succ; arc; arc = arc->succ_next)
kono
parents: 67
diff changeset
1461 if (!arc->fake && !arc->fall_through)
kono
parents: 67
diff changeset
1462 {
kono
parents: 67
diff changeset
1463 arc->is_throw = 1;
kono
parents: 67
diff changeset
1464 fn->has_catch = 1;
kono
parents: 67
diff changeset
1465 }
kono
parents: 67
diff changeset
1466 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1467 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1468 else if (fn && tag == GCOV_TAG_LINES)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1469 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1470 unsigned blockno = gcov_read_unsigned ();
111
kono
parents: 67
diff changeset
1471 block_t *block = &fn->blocks[blockno];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1472
111
kono
parents: 67
diff changeset
1473 if (blockno >= fn->blocks.size ())
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1474 goto corrupt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1475
111
kono
parents: 67
diff changeset
1476 while (true)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1477 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1478 unsigned lineno = gcov_read_unsigned ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1479
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1480 if (lineno)
111
kono
parents: 67
diff changeset
1481 block->locations.back ().lines.push_back (lineno);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1482 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1483 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1484 const char *file_name = gcov_read_string ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1485
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1486 if (!file_name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1487 break;
111
kono
parents: 67
diff changeset
1488 block->locations.push_back (block_location_info
kono
parents: 67
diff changeset
1489 (find_source (file_name)));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1490 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1491 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1492 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1493 else if (current_tag && !GCOV_TAG_IS_SUBTAG (current_tag, tag))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1494 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1495 fn = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1496 current_tag = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1497 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1498 gcov_sync (base, length);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1499 if (gcov_is_error ())
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1500 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1501 corrupt:;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1502 fnotice (stderr, "%s:corrupted\n", bbg_file_name);
111
kono
parents: 67
diff changeset
1503 break;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1504 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1505 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1506 gcov_close ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1507
111
kono
parents: 67
diff changeset
1508 if (!fns)
kono
parents: 67
diff changeset
1509 fnotice (stderr, "%s:no functions found\n", bbg_file_name);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1510
111
kono
parents: 67
diff changeset
1511 return fns;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1512 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1513
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1514 /* Reads profiles from the count file and attach to each
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1515 function. Return nonzero if fatal error. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1516
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1517 static int
111
kono
parents: 67
diff changeset
1518 read_count_file (function_t *fns)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1519 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1520 unsigned ix;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1521 unsigned version;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1522 unsigned tag;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1523 function_t *fn = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1524 int error = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1525
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1526 if (!gcov_open (da_file_name, 1))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1527 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1528 fnotice (stderr, "%s:cannot open data file, assuming not executed\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1529 da_file_name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1530 no_data_file = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1531 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1532 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1533 if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1534 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1535 fnotice (stderr, "%s:not a gcov data file\n", da_file_name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1536 cleanup:;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1537 gcov_close ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1538 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1539 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1540 version = gcov_read_unsigned ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1541 if (version != GCOV_VERSION)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1542 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1543 char v[4], e[4];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1544
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1545 GCOV_UNSIGNED2STRING (v, version);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1546 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
1547
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1548 fnotice (stderr, "%s:version '%.4s', prefer version '%.4s'\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1549 da_file_name, v, e);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1550 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1551 tag = gcov_read_unsigned ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1552 if (tag != bbg_stamp)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1553 {
111
kono
parents: 67
diff changeset
1554 fnotice (stderr, "%s:stamp mismatch with notes file\n", da_file_name);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1555 goto cleanup;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1556 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1557
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1558 while ((tag = gcov_read_unsigned ()))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1559 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1560 unsigned length = gcov_read_unsigned ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1561 unsigned long base = gcov_position ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1562
111
kono
parents: 67
diff changeset
1563 if (tag == GCOV_TAG_PROGRAM_SUMMARY)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1564 {
111
kono
parents: 67
diff changeset
1565 struct gcov_summary summary;
kono
parents: 67
diff changeset
1566 gcov_read_summary (&summary);
kono
parents: 67
diff changeset
1567 object_runs += summary.ctrs[GCOV_COUNTER_ARCS].runs;
kono
parents: 67
diff changeset
1568 program_count++;
kono
parents: 67
diff changeset
1569 }
kono
parents: 67
diff changeset
1570 else if (tag == GCOV_TAG_FUNCTION && !length)
kono
parents: 67
diff changeset
1571 ; /* placeholder */
kono
parents: 67
diff changeset
1572 else if (tag == GCOV_TAG_FUNCTION && length == GCOV_TAG_FUNCTION_LENGTH)
kono
parents: 67
diff changeset
1573 {
kono
parents: 67
diff changeset
1574 unsigned ident;
kono
parents: 67
diff changeset
1575 struct function_info *fn_n;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1576
111
kono
parents: 67
diff changeset
1577 /* Try to find the function in the list. To speed up the
kono
parents: 67
diff changeset
1578 search, first start from the last function found. */
kono
parents: 67
diff changeset
1579 ident = gcov_read_unsigned ();
kono
parents: 67
diff changeset
1580 fn_n = fns;
kono
parents: 67
diff changeset
1581 for (fn = fn ? fn->next : NULL; ; fn = fn->next)
kono
parents: 67
diff changeset
1582 {
kono
parents: 67
diff changeset
1583 if (fn)
kono
parents: 67
diff changeset
1584 ;
kono
parents: 67
diff changeset
1585 else if ((fn = fn_n))
kono
parents: 67
diff changeset
1586 fn_n = NULL;
kono
parents: 67
diff changeset
1587 else
kono
parents: 67
diff changeset
1588 {
kono
parents: 67
diff changeset
1589 fnotice (stderr, "%s:unknown function '%u'\n",
kono
parents: 67
diff changeset
1590 da_file_name, ident);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1591 break;
111
kono
parents: 67
diff changeset
1592 }
kono
parents: 67
diff changeset
1593 if (fn->ident == ident)
kono
parents: 67
diff changeset
1594 break;
kono
parents: 67
diff changeset
1595 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1596
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1597 if (!fn)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1598 ;
111
kono
parents: 67
diff changeset
1599 else if (gcov_read_unsigned () != fn->lineno_checksum
kono
parents: 67
diff changeset
1600 || gcov_read_unsigned () != fn->cfg_checksum)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1601 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1602 mismatch:;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1603 fnotice (stderr, "%s:profile mismatch for '%s'\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1604 da_file_name, fn->name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1605 goto cleanup;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1606 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1607 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1608 else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_ARCS) && fn)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1609 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1610 if (length != GCOV_TAG_COUNTER_LENGTH (fn->num_counts))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1611 goto mismatch;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1612
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1613 if (!fn->counts)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1614 fn->counts = XCNEWVEC (gcov_type, fn->num_counts);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1615
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1616 for (ix = 0; ix != fn->num_counts; ix++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1617 fn->counts[ix] += gcov_read_counter ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1618 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1619 gcov_sync (base, length);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1620 if ((error = gcov_is_error ()))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1621 {
111
kono
parents: 67
diff changeset
1622 fnotice (stderr,
kono
parents: 67
diff changeset
1623 error < 0
kono
parents: 67
diff changeset
1624 ? N_("%s:overflowed\n")
kono
parents: 67
diff changeset
1625 : N_("%s:corrupted\n"),
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1626 da_file_name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1627 goto cleanup;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1628 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1629 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1630
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1631 gcov_close ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1632 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1633 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1634
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1635 /* Solve the flow graph. Propagate counts from the instrumented arcs
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1636 to the blocks and the uninstrumented arcs. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1637
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1638 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1639 solve_flow_graph (function_t *fn)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1640 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1641 unsigned ix;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1642 arc_t *arc;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1643 gcov_type *count_ptr = fn->counts;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1644 block_t *blk;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1645 block_t *valid_blocks = NULL; /* valid, but unpropagated blocks. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1646 block_t *invalid_blocks = NULL; /* invalid, but inferable blocks. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1647
111
kono
parents: 67
diff changeset
1648 /* The arcs were built in reverse order. Fix that now. */
kono
parents: 67
diff changeset
1649 for (ix = fn->blocks.size (); ix--;)
kono
parents: 67
diff changeset
1650 {
kono
parents: 67
diff changeset
1651 arc_t *arc_p, *arc_n;
kono
parents: 67
diff changeset
1652
kono
parents: 67
diff changeset
1653 for (arc_p = NULL, arc = fn->blocks[ix].succ; arc;
kono
parents: 67
diff changeset
1654 arc_p = arc, arc = arc_n)
kono
parents: 67
diff changeset
1655 {
kono
parents: 67
diff changeset
1656 arc_n = arc->succ_next;
kono
parents: 67
diff changeset
1657 arc->succ_next = arc_p;
kono
parents: 67
diff changeset
1658 }
kono
parents: 67
diff changeset
1659 fn->blocks[ix].succ = arc_p;
kono
parents: 67
diff changeset
1660
kono
parents: 67
diff changeset
1661 for (arc_p = NULL, arc = fn->blocks[ix].pred; arc;
kono
parents: 67
diff changeset
1662 arc_p = arc, arc = arc_n)
kono
parents: 67
diff changeset
1663 {
kono
parents: 67
diff changeset
1664 arc_n = arc->pred_next;
kono
parents: 67
diff changeset
1665 arc->pred_next = arc_p;
kono
parents: 67
diff changeset
1666 }
kono
parents: 67
diff changeset
1667 fn->blocks[ix].pred = arc_p;
kono
parents: 67
diff changeset
1668 }
kono
parents: 67
diff changeset
1669
kono
parents: 67
diff changeset
1670 if (fn->blocks.size () < 2)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1671 fnotice (stderr, "%s:'%s' lacks entry and/or exit blocks\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1672 bbg_file_name, fn->name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1673 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1674 {
111
kono
parents: 67
diff changeset
1675 if (fn->blocks[ENTRY_BLOCK].num_pred)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1676 fnotice (stderr, "%s:'%s' has arcs to entry block\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1677 bbg_file_name, fn->name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1678 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1679 /* We can't deduce the entry block counts from the lack of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1680 predecessors. */
111
kono
parents: 67
diff changeset
1681 fn->blocks[ENTRY_BLOCK].num_pred = ~(unsigned)0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1682
111
kono
parents: 67
diff changeset
1683 if (fn->blocks[EXIT_BLOCK].num_succ)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1684 fnotice (stderr, "%s:'%s' has arcs from exit block\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1685 bbg_file_name, fn->name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1686 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1687 /* Likewise, we can't deduce exit block counts from the lack
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1688 of its successors. */
111
kono
parents: 67
diff changeset
1689 fn->blocks[EXIT_BLOCK].num_succ = ~(unsigned)0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1690 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1691
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1692 /* Propagate the measured counts, this must be done in the same
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1693 order as the code in profile.c */
111
kono
parents: 67
diff changeset
1694 for (unsigned i = 0; i < fn->blocks.size (); i++)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1695 {
111
kono
parents: 67
diff changeset
1696 blk = &fn->blocks[i];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1697 block_t const *prev_dst = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1698 int out_of_order = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1699 int non_fake_succ = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1700
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1701 for (arc = blk->succ; arc; arc = arc->succ_next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1702 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1703 if (!arc->fake)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1704 non_fake_succ++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1705
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1706 if (!arc->on_tree)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1707 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1708 if (count_ptr)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1709 arc->count = *count_ptr++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1710 arc->count_valid = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1711 blk->num_succ--;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1712 arc->dst->num_pred--;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1713 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1714 if (prev_dst && prev_dst > arc->dst)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1715 out_of_order = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1716 prev_dst = arc->dst;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1717 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1718 if (non_fake_succ == 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1719 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1720 /* If there is only one non-fake exit, it is an
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1721 unconditional branch. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1722 for (arc = blk->succ; arc; arc = arc->succ_next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1723 if (!arc->fake)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1724 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1725 arc->is_unconditional = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1726 /* If this block is instrumenting a call, it might be
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1727 an artificial block. It is not artificial if it has
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1728 a non-fallthrough exit, or the destination of this
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1729 arc has more than one entry. Mark the destination
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1730 block as a return site, if none of those conditions
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1731 hold. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1732 if (blk->is_call_site && arc->fall_through
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1733 && arc->dst->pred == arc && !arc->pred_next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1734 arc->dst->is_call_return = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1735 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1736 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1737
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1738 /* Sort the successor arcs into ascending dst order. profile.c
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1739 normally produces arcs in the right order, but sometimes with
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1740 one or two out of order. We're not using a particularly
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1741 smart sort. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1742 if (out_of_order)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1743 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1744 arc_t *start = blk->succ;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1745 unsigned changes = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1746
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1747 while (changes)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1748 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1749 arc_t *arc, *arc_p, *arc_n;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1750
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1751 changes = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1752 for (arc_p = NULL, arc = start; (arc_n = arc->succ_next);)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1753 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1754 if (arc->dst > arc_n->dst)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1755 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1756 changes = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1757 if (arc_p)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1758 arc_p->succ_next = arc_n;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1759 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1760 start = arc_n;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1761 arc->succ_next = arc_n->succ_next;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1762 arc_n->succ_next = arc;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1763 arc_p = arc_n;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1764 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1765 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1766 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1767 arc_p = arc;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1768 arc = arc_n;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1769 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1770 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1771 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1772 blk->succ = start;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1773 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1774
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1775 /* Place it on the invalid chain, it will be ignored if that's
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1776 wrong. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1777 blk->invalid_chain = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1778 blk->chain = invalid_blocks;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1779 invalid_blocks = blk;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1780 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1781
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1782 while (invalid_blocks || valid_blocks)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1783 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1784 while ((blk = invalid_blocks))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1785 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1786 gcov_type total = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1787 const arc_t *arc;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1788
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1789 invalid_blocks = blk->chain;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1790 blk->invalid_chain = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1791 if (!blk->num_succ)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1792 for (arc = blk->succ; arc; arc = arc->succ_next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1793 total += arc->count;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1794 else if (!blk->num_pred)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1795 for (arc = blk->pred; arc; arc = arc->pred_next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1796 total += arc->count;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1797 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1798 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1799
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1800 blk->count = total;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1801 blk->count_valid = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1802 blk->chain = valid_blocks;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1803 blk->valid_chain = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1804 valid_blocks = blk;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1805 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1806 while ((blk = valid_blocks))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1807 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1808 gcov_type total;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1809 arc_t *arc, *inv_arc;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1810
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1811 valid_blocks = blk->chain;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1812 blk->valid_chain = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1813 if (blk->num_succ == 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1814 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1815 block_t *dst;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1816
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1817 total = blk->count;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1818 inv_arc = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1819 for (arc = blk->succ; arc; arc = arc->succ_next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1820 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1821 total -= arc->count;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1822 if (!arc->count_valid)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1823 inv_arc = arc;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1824 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1825 dst = inv_arc->dst;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1826 inv_arc->count_valid = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1827 inv_arc->count = total;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1828 blk->num_succ--;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1829 dst->num_pred--;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1830 if (dst->count_valid)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1831 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1832 if (dst->num_pred == 1 && !dst->valid_chain)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1833 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1834 dst->chain = valid_blocks;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1835 dst->valid_chain = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1836 valid_blocks = dst;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1837 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1838 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1839 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1840 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1841 if (!dst->num_pred && !dst->invalid_chain)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1842 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1843 dst->chain = invalid_blocks;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1844 dst->invalid_chain = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1845 invalid_blocks = dst;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1846 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1847 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1848 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1849 if (blk->num_pred == 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1850 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1851 block_t *src;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1852
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1853 total = blk->count;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1854 inv_arc = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1855 for (arc = blk->pred; arc; arc = arc->pred_next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1856 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1857 total -= arc->count;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1858 if (!arc->count_valid)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1859 inv_arc = arc;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1860 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1861 src = inv_arc->src;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1862 inv_arc->count_valid = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1863 inv_arc->count = total;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1864 blk->num_pred--;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1865 src->num_succ--;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1866 if (src->count_valid)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1867 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1868 if (src->num_succ == 1 && !src->valid_chain)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1869 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1870 src->chain = valid_blocks;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1871 src->valid_chain = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1872 valid_blocks = src;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1873 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1874 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1875 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1876 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1877 if (!src->num_succ && !src->invalid_chain)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1878 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1879 src->chain = invalid_blocks;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1880 src->invalid_chain = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1881 invalid_blocks = src;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1882 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1883 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1884 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1885 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1886 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1887
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1888 /* If the graph has been correctly solved, every block will have a
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1889 valid count. */
111
kono
parents: 67
diff changeset
1890 for (unsigned i = 0; ix < fn->blocks.size (); i++)
kono
parents: 67
diff changeset
1891 if (!fn->blocks[i].count_valid)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1892 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1893 fnotice (stderr, "%s:graph is unsolvable for '%s'\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1894 bbg_file_name, fn->name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1895 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1896 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1897 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1898
111
kono
parents: 67
diff changeset
1899 /* Mark all the blocks only reachable via an incoming catch. */
kono
parents: 67
diff changeset
1900
kono
parents: 67
diff changeset
1901 static void
kono
parents: 67
diff changeset
1902 find_exception_blocks (function_t *fn)
kono
parents: 67
diff changeset
1903 {
kono
parents: 67
diff changeset
1904 unsigned ix;
kono
parents: 67
diff changeset
1905 block_t **queue = XALLOCAVEC (block_t *, fn->blocks.size ());
kono
parents: 67
diff changeset
1906
kono
parents: 67
diff changeset
1907 /* First mark all blocks as exceptional. */
kono
parents: 67
diff changeset
1908 for (ix = fn->blocks.size (); ix--;)
kono
parents: 67
diff changeset
1909 fn->blocks[ix].exceptional = 1;
kono
parents: 67
diff changeset
1910
kono
parents: 67
diff changeset
1911 /* Now mark all the blocks reachable via non-fake edges */
kono
parents: 67
diff changeset
1912 queue[0] = &fn->blocks[0];
kono
parents: 67
diff changeset
1913 queue[0]->exceptional = 0;
kono
parents: 67
diff changeset
1914 for (ix = 1; ix;)
kono
parents: 67
diff changeset
1915 {
kono
parents: 67
diff changeset
1916 block_t *block = queue[--ix];
kono
parents: 67
diff changeset
1917 const arc_t *arc;
kono
parents: 67
diff changeset
1918
kono
parents: 67
diff changeset
1919 for (arc = block->succ; arc; arc = arc->succ_next)
kono
parents: 67
diff changeset
1920 if (!arc->fake && !arc->is_throw && arc->dst->exceptional)
kono
parents: 67
diff changeset
1921 {
kono
parents: 67
diff changeset
1922 arc->dst->exceptional = 0;
kono
parents: 67
diff changeset
1923 queue[ix++] = arc->dst;
kono
parents: 67
diff changeset
1924 }
kono
parents: 67
diff changeset
1925 }
kono
parents: 67
diff changeset
1926 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1927
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1928
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1929 /* Increment totals in COVERAGE according to arc ARC. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1930
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1931 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1932 add_branch_counts (coverage_t *coverage, const arc_t *arc)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1933 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1934 if (arc->is_call_non_return)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1935 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1936 coverage->calls++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1937 if (arc->src->count)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1938 coverage->calls_executed++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1939 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1940 else if (!arc->is_unconditional)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1941 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1942 coverage->branches++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1943 if (arc->src->count)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1944 coverage->branches_executed++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1945 if (arc->count)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1946 coverage->branches_taken++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1947 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1948 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1949
111
kono
parents: 67
diff changeset
1950 /* Format a GCOV_TYPE integer as either a percent ratio, or absolute
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1951 count. If dp >= 0, format TOP/BOTTOM * 100 to DP decimal places.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1952 If DP is zero, no decimal point is printed. Only print 100% when
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1953 TOP==BOTTOM and only print 0% when TOP=0. If dp < 0, then simply
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1954 format TOP. Return pointer to a static string. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1955
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1956 static char const *
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1957 format_gcov (gcov_type top, gcov_type bottom, int dp)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1958 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1959 static char buffer[20];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1960
111
kono
parents: 67
diff changeset
1961 /* Handle invalid values that would result in a misleading value. */
kono
parents: 67
diff changeset
1962 if (bottom != 0 && top > bottom && dp >= 0)
kono
parents: 67
diff changeset
1963 {
kono
parents: 67
diff changeset
1964 sprintf (buffer, "NAN %%");
kono
parents: 67
diff changeset
1965 return buffer;
kono
parents: 67
diff changeset
1966 }
kono
parents: 67
diff changeset
1967
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1968 if (dp >= 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1969 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1970 float ratio = bottom ? (float)top / bottom : 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1971 int ix;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1972 unsigned limit = 100;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1973 unsigned percent;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1974
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1975 for (ix = dp; ix--; )
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1976 limit *= 10;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1977
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1978 percent = (unsigned) (ratio * limit + (float)0.5);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1979 if (percent <= 0 && top)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1980 percent = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1981 else if (percent >= limit && top != bottom)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1982 percent = limit - 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1983 ix = sprintf (buffer, "%.*u%%", dp + 1, percent);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1984 if (dp)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1985 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1986 dp++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1987 do
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1988 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1989 buffer[ix+1] = buffer[ix];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1990 ix--;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1991 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1992 while (dp--);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1993 buffer[ix + 1] = '.';
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1994 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1995 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1996 else
111
kono
parents: 67
diff changeset
1997 sprintf (buffer, "%" PRId64, (int64_t)top);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1998
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1999 return buffer;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2000 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2001
111
kono
parents: 67
diff changeset
2002 /* Summary of execution */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2003
111
kono
parents: 67
diff changeset
2004 static void
kono
parents: 67
diff changeset
2005 executed_summary (unsigned lines, unsigned executed)
kono
parents: 67
diff changeset
2006 {
kono
parents: 67
diff changeset
2007 if (lines)
kono
parents: 67
diff changeset
2008 fnotice (stdout, "Lines executed:%s of %d\n",
kono
parents: 67
diff changeset
2009 format_gcov (executed, lines, 2), lines);
kono
parents: 67
diff changeset
2010 else
kono
parents: 67
diff changeset
2011 fnotice (stdout, "No executable lines\n");
kono
parents: 67
diff changeset
2012 }
kono
parents: 67
diff changeset
2013
kono
parents: 67
diff changeset
2014 /* Output summary info for a function or file. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2015
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2016 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2017 function_summary (const coverage_t *coverage, const char *title)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2018 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2019 fnotice (stdout, "%s '%s'\n", title, coverage->name);
111
kono
parents: 67
diff changeset
2020 executed_summary (coverage->lines, coverage->lines_executed);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2021
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2022 if (flag_branches)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2023 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2024 if (coverage->branches)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2025 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2026 fnotice (stdout, "Branches executed:%s of %d\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2027 format_gcov (coverage->branches_executed,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2028 coverage->branches, 2),
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2029 coverage->branches);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2030 fnotice (stdout, "Taken at least once:%s of %d\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2031 format_gcov (coverage->branches_taken,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2032 coverage->branches, 2),
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2033 coverage->branches);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2034 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2035 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2036 fnotice (stdout, "No branches\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2037 if (coverage->calls)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2038 fnotice (stdout, "Calls executed:%s of %d\n",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2039 format_gcov (coverage->calls_executed, coverage->calls, 2),
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2040 coverage->calls);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2041 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2042 fnotice (stdout, "No calls\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2043 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2044 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2045
111
kono
parents: 67
diff changeset
2046 /* Canonicalize the filename NAME by canonicalizing directory
kono
parents: 67
diff changeset
2047 separators, eliding . components and resolving .. components
kono
parents: 67
diff changeset
2048 appropriately. Always returns a unique string. */
kono
parents: 67
diff changeset
2049
kono
parents: 67
diff changeset
2050 static char *
kono
parents: 67
diff changeset
2051 canonicalize_name (const char *name)
kono
parents: 67
diff changeset
2052 {
kono
parents: 67
diff changeset
2053 /* The canonical name cannot be longer than the incoming name. */
kono
parents: 67
diff changeset
2054 char *result = XNEWVEC (char, strlen (name) + 1);
kono
parents: 67
diff changeset
2055 const char *base = name, *probe;
kono
parents: 67
diff changeset
2056 char *ptr = result;
kono
parents: 67
diff changeset
2057 char *dd_base;
kono
parents: 67
diff changeset
2058 int slash = 0;
kono
parents: 67
diff changeset
2059
kono
parents: 67
diff changeset
2060 #if HAVE_DOS_BASED_FILE_SYSTEM
kono
parents: 67
diff changeset
2061 if (base[0] && base[1] == ':')
kono
parents: 67
diff changeset
2062 {
kono
parents: 67
diff changeset
2063 result[0] = base[0];
kono
parents: 67
diff changeset
2064 result[1] = ':';
kono
parents: 67
diff changeset
2065 base += 2;
kono
parents: 67
diff changeset
2066 ptr += 2;
kono
parents: 67
diff changeset
2067 }
kono
parents: 67
diff changeset
2068 #endif
kono
parents: 67
diff changeset
2069 for (dd_base = ptr; *base; base = probe)
kono
parents: 67
diff changeset
2070 {
kono
parents: 67
diff changeset
2071 size_t len;
kono
parents: 67
diff changeset
2072
kono
parents: 67
diff changeset
2073 for (probe = base; *probe; probe++)
kono
parents: 67
diff changeset
2074 if (IS_DIR_SEPARATOR (*probe))
kono
parents: 67
diff changeset
2075 break;
kono
parents: 67
diff changeset
2076
kono
parents: 67
diff changeset
2077 len = probe - base;
kono
parents: 67
diff changeset
2078 if (len == 1 && base[0] == '.')
kono
parents: 67
diff changeset
2079 /* Elide a '.' directory */
kono
parents: 67
diff changeset
2080 ;
kono
parents: 67
diff changeset
2081 else if (len == 2 && base[0] == '.' && base[1] == '.')
kono
parents: 67
diff changeset
2082 {
kono
parents: 67
diff changeset
2083 /* '..', we can only elide it and the previous directory, if
kono
parents: 67
diff changeset
2084 we're not a symlink. */
kono
parents: 67
diff changeset
2085 struct stat ATTRIBUTE_UNUSED buf;
kono
parents: 67
diff changeset
2086
kono
parents: 67
diff changeset
2087 *ptr = 0;
kono
parents: 67
diff changeset
2088 if (dd_base == ptr
kono
parents: 67
diff changeset
2089 #if defined (S_ISLNK)
kono
parents: 67
diff changeset
2090 /* S_ISLNK is not POSIX.1-1996. */
kono
parents: 67
diff changeset
2091 || stat (result, &buf) || S_ISLNK (buf.st_mode)
kono
parents: 67
diff changeset
2092 #endif
kono
parents: 67
diff changeset
2093 )
kono
parents: 67
diff changeset
2094 {
kono
parents: 67
diff changeset
2095 /* Cannot elide, or unreadable or a symlink. */
kono
parents: 67
diff changeset
2096 dd_base = ptr + 2 + slash;
kono
parents: 67
diff changeset
2097 goto regular;
kono
parents: 67
diff changeset
2098 }
kono
parents: 67
diff changeset
2099 while (ptr != dd_base && *ptr != '/')
kono
parents: 67
diff changeset
2100 ptr--;
kono
parents: 67
diff changeset
2101 slash = ptr != result;
kono
parents: 67
diff changeset
2102 }
kono
parents: 67
diff changeset
2103 else
kono
parents: 67
diff changeset
2104 {
kono
parents: 67
diff changeset
2105 regular:
kono
parents: 67
diff changeset
2106 /* Regular pathname component. */
kono
parents: 67
diff changeset
2107 if (slash)
kono
parents: 67
diff changeset
2108 *ptr++ = '/';
kono
parents: 67
diff changeset
2109 memcpy (ptr, base, len);
kono
parents: 67
diff changeset
2110 ptr += len;
kono
parents: 67
diff changeset
2111 slash = 1;
kono
parents: 67
diff changeset
2112 }
kono
parents: 67
diff changeset
2113
kono
parents: 67
diff changeset
2114 for (; IS_DIR_SEPARATOR (*probe); probe++)
kono
parents: 67
diff changeset
2115 continue;
kono
parents: 67
diff changeset
2116 }
kono
parents: 67
diff changeset
2117 *ptr = 0;
kono
parents: 67
diff changeset
2118
kono
parents: 67
diff changeset
2119 return result;
kono
parents: 67
diff changeset
2120 }
kono
parents: 67
diff changeset
2121
kono
parents: 67
diff changeset
2122 /* Print hex representation of 16 bytes from SUM and write it to BUFFER. */
kono
parents: 67
diff changeset
2123
kono
parents: 67
diff changeset
2124 static void
kono
parents: 67
diff changeset
2125 md5sum_to_hex (const char *sum, char *buffer)
kono
parents: 67
diff changeset
2126 {
kono
parents: 67
diff changeset
2127 for (unsigned i = 0; i < 16; i++)
kono
parents: 67
diff changeset
2128 sprintf (buffer + (2 * i), "%02x", (unsigned char)sum[i]);
kono
parents: 67
diff changeset
2129 }
kono
parents: 67
diff changeset
2130
kono
parents: 67
diff changeset
2131 /* Generate an output file name. INPUT_NAME is the canonicalized main
kono
parents: 67
diff changeset
2132 input file and SRC_NAME is the canonicalized file name.
kono
parents: 67
diff changeset
2133 LONG_OUTPUT_NAMES and PRESERVE_PATHS affect name generation. With
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2134 long_output_names we prepend the processed name of the input file
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2135 to each output name (except when the current source file is the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2136 input file, so you don't get a double concatenation). The two
111
kono
parents: 67
diff changeset
2137 components are separated by '##'. With preserve_paths we create a
kono
parents: 67
diff changeset
2138 filename from all path components of the source file, replacing '/'
kono
parents: 67
diff changeset
2139 with '#', and .. with '^', without it we simply take the basename
kono
parents: 67
diff changeset
2140 component. (Remember, the canonicalized name will already have
kono
parents: 67
diff changeset
2141 elided '.' components and converted \\ separators.) */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2142
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2143 static char *
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2144 make_gcov_file_name (const char *input_name, const char *src_name)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2145 {
111
kono
parents: 67
diff changeset
2146 char *ptr;
kono
parents: 67
diff changeset
2147 char *result;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2148
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2149 if (flag_long_names && input_name && strcmp (src_name, input_name))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2150 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2151 /* Generate the input filename part. */
111
kono
parents: 67
diff changeset
2152 result = XNEWVEC (char, strlen (input_name) + strlen (src_name) + 10);
kono
parents: 67
diff changeset
2153
kono
parents: 67
diff changeset
2154 ptr = result;
kono
parents: 67
diff changeset
2155 ptr = mangle_name (input_name, ptr);
kono
parents: 67
diff changeset
2156 ptr[0] = ptr[1] = '#';
kono
parents: 67
diff changeset
2157 ptr += 2;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2158 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2159 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2160 {
111
kono
parents: 67
diff changeset
2161 result = XNEWVEC (char, strlen (src_name) + 10);
kono
parents: 67
diff changeset
2162 ptr = result;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2163 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2164
111
kono
parents: 67
diff changeset
2165 ptr = mangle_name (src_name, ptr);
kono
parents: 67
diff changeset
2166 strcpy (ptr, ".gcov");
kono
parents: 67
diff changeset
2167
kono
parents: 67
diff changeset
2168 /* When hashing filenames, we shorten them by only using the filename
kono
parents: 67
diff changeset
2169 component and appending a hash of the full (mangled) pathname. */
kono
parents: 67
diff changeset
2170 if (flag_hash_filenames)
kono
parents: 67
diff changeset
2171 {
kono
parents: 67
diff changeset
2172 md5_ctx ctx;
kono
parents: 67
diff changeset
2173 char md5sum[16];
kono
parents: 67
diff changeset
2174 char md5sum_hex[33];
kono
parents: 67
diff changeset
2175
kono
parents: 67
diff changeset
2176 md5_init_ctx (&ctx);
kono
parents: 67
diff changeset
2177 md5_process_bytes (src_name, strlen (src_name), &ctx);
kono
parents: 67
diff changeset
2178 md5_finish_ctx (&ctx, md5sum);
kono
parents: 67
diff changeset
2179 md5sum_to_hex (md5sum, md5sum_hex);
kono
parents: 67
diff changeset
2180 free (result);
kono
parents: 67
diff changeset
2181
kono
parents: 67
diff changeset
2182 result = XNEWVEC (char, strlen (src_name) + 50);
kono
parents: 67
diff changeset
2183 ptr = result;
kono
parents: 67
diff changeset
2184 ptr = mangle_name (src_name, ptr);
kono
parents: 67
diff changeset
2185 ptr[0] = ptr[1] = '#';
kono
parents: 67
diff changeset
2186 ptr += 2;
kono
parents: 67
diff changeset
2187 memcpy (ptr, md5sum_hex, 32);
kono
parents: 67
diff changeset
2188 ptr += 32;
kono
parents: 67
diff changeset
2189 strcpy (ptr, ".gcov");
kono
parents: 67
diff changeset
2190 }
kono
parents: 67
diff changeset
2191
kono
parents: 67
diff changeset
2192 return result;
kono
parents: 67
diff changeset
2193 }
kono
parents: 67
diff changeset
2194
kono
parents: 67
diff changeset
2195 static char *
kono
parents: 67
diff changeset
2196 mangle_name (char const *base, char *ptr)
kono
parents: 67
diff changeset
2197 {
kono
parents: 67
diff changeset
2198 size_t len;
kono
parents: 67
diff changeset
2199
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2200 /* Generate the source filename part. */
111
kono
parents: 67
diff changeset
2201 if (!flag_preserve_paths)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2202 {
111
kono
parents: 67
diff changeset
2203 base = lbasename (base);
kono
parents: 67
diff changeset
2204 len = strlen (base);
kono
parents: 67
diff changeset
2205 memcpy (ptr, base, len);
kono
parents: 67
diff changeset
2206 ptr += len;
kono
parents: 67
diff changeset
2207 }
kono
parents: 67
diff changeset
2208 else
kono
parents: 67
diff changeset
2209 {
kono
parents: 67
diff changeset
2210 /* Convert '/' to '#', convert '..' to '^',
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2211 convert ':' to '~' on DOS based file system. */
111
kono
parents: 67
diff changeset
2212 const char *probe;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2213
111
kono
parents: 67
diff changeset
2214 #if HAVE_DOS_BASED_FILE_SYSTEM
kono
parents: 67
diff changeset
2215 if (base[0] && base[1] == ':')
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2216 {
111
kono
parents: 67
diff changeset
2217 ptr[0] = base[0];
kono
parents: 67
diff changeset
2218 ptr[1] = '~';
kono
parents: 67
diff changeset
2219 ptr += 2;
kono
parents: 67
diff changeset
2220 base += 2;
kono
parents: 67
diff changeset
2221 }
kono
parents: 67
diff changeset
2222 #endif
kono
parents: 67
diff changeset
2223 for (; *base; base = probe)
kono
parents: 67
diff changeset
2224 {
kono
parents: 67
diff changeset
2225 size_t len;
kono
parents: 67
diff changeset
2226
kono
parents: 67
diff changeset
2227 for (probe = base; *probe; probe++)
kono
parents: 67
diff changeset
2228 if (*probe == '/')
kono
parents: 67
diff changeset
2229 break;
kono
parents: 67
diff changeset
2230 len = probe - base;
kono
parents: 67
diff changeset
2231 if (len == 2 && base[0] == '.' && base[1] == '.')
kono
parents: 67
diff changeset
2232 *ptr++ = '^';
kono
parents: 67
diff changeset
2233 else
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2234 {
111
kono
parents: 67
diff changeset
2235 memcpy (ptr, base, len);
kono
parents: 67
diff changeset
2236 ptr += len;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2237 }
111
kono
parents: 67
diff changeset
2238 if (*probe)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2239 {
111
kono
parents: 67
diff changeset
2240 *ptr++ = '#';
kono
parents: 67
diff changeset
2241 probe++;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2242 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2243 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2244 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2245
111
kono
parents: 67
diff changeset
2246 return ptr;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2247 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2248
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2249 /* Scan through the bb_data for each line in the block, increment
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2250 the line number execution count indicated by the execution count of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2251 the appropriate basic block. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2252
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2253 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2254 add_line_counts (coverage_t *coverage, function_t *fn)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2255 {
111
kono
parents: 67
diff changeset
2256 bool has_any_line = false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2257 /* Scan each basic block. */
111
kono
parents: 67
diff changeset
2258 for (unsigned ix = 0; ix != fn->blocks.size (); ix++)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2259 {
111
kono
parents: 67
diff changeset
2260 line_t *line = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2261 block_t *block = &fn->blocks[ix];
111
kono
parents: 67
diff changeset
2262 if (block->count && ix && ix + 1 != fn->blocks.size ())
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2263 fn->blocks_executed++;
111
kono
parents: 67
diff changeset
2264 for (unsigned i = 0; i < block->locations.size (); i++)
kono
parents: 67
diff changeset
2265 {
kono
parents: 67
diff changeset
2266 const source_t *src = &sources[block->locations[i].source_file_idx];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2267
111
kono
parents: 67
diff changeset
2268 vector<unsigned> &lines = block->locations[i].lines;
kono
parents: 67
diff changeset
2269 for (unsigned j = 0; j < lines.size (); j++)
kono
parents: 67
diff changeset
2270 {
kono
parents: 67
diff changeset
2271 line = &src->lines[lines[j]];
kono
parents: 67
diff changeset
2272 if (coverage)
kono
parents: 67
diff changeset
2273 {
kono
parents: 67
diff changeset
2274 if (!line->exists)
kono
parents: 67
diff changeset
2275 coverage->lines++;
kono
parents: 67
diff changeset
2276 if (!line->count && block->count)
kono
parents: 67
diff changeset
2277 coverage->lines_executed++;
kono
parents: 67
diff changeset
2278 }
kono
parents: 67
diff changeset
2279 line->exists = 1;
kono
parents: 67
diff changeset
2280 if (!block->exceptional)
kono
parents: 67
diff changeset
2281 line->unexceptional = 1;
kono
parents: 67
diff changeset
2282 line->count += block->count;
kono
parents: 67
diff changeset
2283 }
kono
parents: 67
diff changeset
2284 }
kono
parents: 67
diff changeset
2285 block->cycle.arc = NULL;
kono
parents: 67
diff changeset
2286 block->cycle.ident = ~0U;
kono
parents: 67
diff changeset
2287 has_any_line = true;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2288
111
kono
parents: 67
diff changeset
2289 if (!ix || ix + 1 == fn->blocks.size ())
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2290 /* Entry or exit block */;
111
kono
parents: 67
diff changeset
2291 else if (line != NULL)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2292 {
111
kono
parents: 67
diff changeset
2293 block->chain = line->blocks;
kono
parents: 67
diff changeset
2294 line->blocks = block;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2295
111
kono
parents: 67
diff changeset
2296 if (flag_branches)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2297 {
111
kono
parents: 67
diff changeset
2298 arc_t *arc;
kono
parents: 67
diff changeset
2299
kono
parents: 67
diff changeset
2300 for (arc = block->succ; arc; arc = arc->succ_next)
kono
parents: 67
diff changeset
2301 {
kono
parents: 67
diff changeset
2302 arc->line_next = line->branches;
kono
parents: 67
diff changeset
2303 line->branches = arc;
kono
parents: 67
diff changeset
2304 if (coverage && !arc->is_unconditional)
kono
parents: 67
diff changeset
2305 add_branch_counts (coverage, arc);
kono
parents: 67
diff changeset
2306 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2307 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2308 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2309 }
111
kono
parents: 67
diff changeset
2310
kono
parents: 67
diff changeset
2311 if (!has_any_line)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2312 fnotice (stderr, "%s:no lines for '%s'\n", bbg_file_name, fn->name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2313 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2314
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2315 /* Accumulate the line counts of a file. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2316
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2317 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2318 accumulate_line_counts (source_t *src)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2319 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2320 line_t *line;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2321 function_t *fn, *fn_p, *fn_n;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2322 unsigned ix;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2323
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2324 /* Reverse the function order. */
111
kono
parents: 67
diff changeset
2325 for (fn = src->functions, fn_p = NULL; fn; fn_p = fn, fn = fn_n)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2326 {
111
kono
parents: 67
diff changeset
2327 fn_n = fn->next_file_fn;
kono
parents: 67
diff changeset
2328 fn->next_file_fn = fn_p;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2329 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2330 src->functions = fn_p;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2331
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2332 for (ix = src->num_lines, line = src->lines; ix--; line++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2333 {
111
kono
parents: 67
diff changeset
2334 if (line->blocks)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2335 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2336 /* The user expects the line count to be the number of times
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2337 a line has been executed. Simply summing the block count
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2338 will give an artificially high number. The Right Thing
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2339 is to sum the entry counts to the graph of blocks on this
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2340 line, then find the elementary cycles of the local graph
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2341 and add the transition counts of those cycles. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2342 block_t *block, *block_p, *block_n;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2343 gcov_type count = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2344
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2345 /* Reverse the block information. */
111
kono
parents: 67
diff changeset
2346 for (block = line->blocks, block_p = NULL; block;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2347 block_p = block, block = block_n)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2348 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2349 block_n = block->chain;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2350 block->chain = block_p;
111
kono
parents: 67
diff changeset
2351 block->cycle.ident = ix;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2352 }
111
kono
parents: 67
diff changeset
2353 line->blocks = block_p;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2354
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2355 /* Sum the entry arcs. */
111
kono
parents: 67
diff changeset
2356 for (block = line->blocks; block; block = block->chain)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2357 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2358 arc_t *arc;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2359
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2360 for (arc = block->pred; arc; arc = arc->pred_next)
111
kono
parents: 67
diff changeset
2361 if (flag_branches)
kono
parents: 67
diff changeset
2362 add_branch_counts (&src->coverage, arc);
kono
parents: 67
diff changeset
2363 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2364
111
kono
parents: 67
diff changeset
2365 /* Cycle detection. */
kono
parents: 67
diff changeset
2366 for (block = line->blocks; block; block = block->chain)
kono
parents: 67
diff changeset
2367 {
kono
parents: 67
diff changeset
2368 for (arc_t *arc = block->pred; arc; arc = arc->pred_next)
kono
parents: 67
diff changeset
2369 if (!line->has_block (arc->src))
kono
parents: 67
diff changeset
2370 count += arc->count;
kono
parents: 67
diff changeset
2371 for (arc_t *arc = block->succ; arc; arc = arc->succ_next)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2372 arc->cs_count = arc->count;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2373 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2374
111
kono
parents: 67
diff changeset
2375 /* Now, add the count of loops entirely on this line. */
kono
parents: 67
diff changeset
2376 count += get_cycles_count (*line);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2377 line->count = count;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2378 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2379
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2380 if (line->exists)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2381 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2382 src->coverage.lines++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2383 if (line->count)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2384 src->coverage.lines_executed++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2385 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2386 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2387 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2388
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2389 /* Output information about ARC number IX. Returns nonzero if
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2390 anything is output. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2391
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2392 static int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2393 output_branch_count (FILE *gcov_file, int ix, const arc_t *arc)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2394 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2395 if (arc->is_call_non_return)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2396 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2397 if (arc->src->count)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2398 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2399 fnotice (gcov_file, "call %2d returned %s\n", ix,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2400 format_gcov (arc->src->count - arc->count,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2401 arc->src->count, -flag_counts));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2402 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2403 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2404 fnotice (gcov_file, "call %2d never executed\n", ix);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2405 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2406 else if (!arc->is_unconditional)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2407 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2408 if (arc->src->count)
111
kono
parents: 67
diff changeset
2409 fnotice (gcov_file, "branch %2d taken %s%s", ix,
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2410 format_gcov (arc->count, arc->src->count, -flag_counts),
111
kono
parents: 67
diff changeset
2411 arc->fall_through ? " (fallthrough)"
kono
parents: 67
diff changeset
2412 : arc->is_throw ? " (throw)" : "");
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2413 else
111
kono
parents: 67
diff changeset
2414 fnotice (gcov_file, "branch %2d never executed", ix);
kono
parents: 67
diff changeset
2415
kono
parents: 67
diff changeset
2416 if (flag_verbose)
kono
parents: 67
diff changeset
2417 fnotice (gcov_file, " (BB %d)", arc->dst->id);
kono
parents: 67
diff changeset
2418
kono
parents: 67
diff changeset
2419 fnotice (gcov_file, "\n");
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2420 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2421 else if (flag_unconditional && !arc->dst->is_call_return)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2422 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2423 if (arc->src->count)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2424 fnotice (gcov_file, "unconditional %2d taken %s\n", ix,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2425 format_gcov (arc->count, arc->src->count, -flag_counts));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2426 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2427 fnotice (gcov_file, "unconditional %2d never executed\n", ix);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2428 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2429 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2430 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2431 return 1;
111
kono
parents: 67
diff changeset
2432 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2433
111
kono
parents: 67
diff changeset
2434 static const char *
kono
parents: 67
diff changeset
2435 read_line (FILE *file)
kono
parents: 67
diff changeset
2436 {
kono
parents: 67
diff changeset
2437 static char *string;
kono
parents: 67
diff changeset
2438 static size_t string_len;
kono
parents: 67
diff changeset
2439 size_t pos = 0;
kono
parents: 67
diff changeset
2440 char *ptr;
kono
parents: 67
diff changeset
2441
kono
parents: 67
diff changeset
2442 if (!string_len)
kono
parents: 67
diff changeset
2443 {
kono
parents: 67
diff changeset
2444 string_len = 200;
kono
parents: 67
diff changeset
2445 string = XNEWVEC (char, string_len);
kono
parents: 67
diff changeset
2446 }
kono
parents: 67
diff changeset
2447
kono
parents: 67
diff changeset
2448 while ((ptr = fgets (string + pos, string_len - pos, file)))
kono
parents: 67
diff changeset
2449 {
kono
parents: 67
diff changeset
2450 size_t len = strlen (string + pos);
kono
parents: 67
diff changeset
2451
kono
parents: 67
diff changeset
2452 if (len && string[pos + len - 1] == '\n')
kono
parents: 67
diff changeset
2453 {
kono
parents: 67
diff changeset
2454 string[pos + len - 1] = 0;
kono
parents: 67
diff changeset
2455 return string;
kono
parents: 67
diff changeset
2456 }
kono
parents: 67
diff changeset
2457 pos += len;
kono
parents: 67
diff changeset
2458 /* If the file contains NUL characters or an incomplete
kono
parents: 67
diff changeset
2459 last line, which can happen more than once in one run,
kono
parents: 67
diff changeset
2460 we have to avoid doubling the STRING_LEN unnecessarily. */
kono
parents: 67
diff changeset
2461 if (pos > string_len / 2)
kono
parents: 67
diff changeset
2462 {
kono
parents: 67
diff changeset
2463 string_len *= 2;
kono
parents: 67
diff changeset
2464 string = XRESIZEVEC (char, string, string_len);
kono
parents: 67
diff changeset
2465 }
kono
parents: 67
diff changeset
2466 }
kono
parents: 67
diff changeset
2467
kono
parents: 67
diff changeset
2468 return pos ? string : NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2469 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2470
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2471 /* Read in the source file one line at a time, and output that line to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2472 the gcov file preceded by its execution count and other
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2473 information. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2474
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2475 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2476 output_lines (FILE *gcov_file, const source_t *src)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2477 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2478 FILE *source_file;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2479 unsigned line_num; /* current line number. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2480 const line_t *line; /* current line info ptr. */
111
kono
parents: 67
diff changeset
2481 const char *retval = ""; /* status of source file reading. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2482 function_t *fn = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2483
111
kono
parents: 67
diff changeset
2484 fprintf (gcov_file, "%9s:%5d:Source:%s\n", "-", 0, src->coverage.name);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2485 if (!multiple_files)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2486 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2487 fprintf (gcov_file, "%9s:%5d:Graph:%s\n", "-", 0, bbg_file_name);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2488 fprintf (gcov_file, "%9s:%5d:Data:%s\n", "-", 0,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2489 no_data_file ? "-" : da_file_name);
111
kono
parents: 67
diff changeset
2490 fprintf (gcov_file, "%9s:%5d:Runs:%u\n", "-", 0, object_runs);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2491 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2492 fprintf (gcov_file, "%9s:%5d:Programs:%u\n", "-", 0, program_count);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2493
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2494 source_file = fopen (src->name, "r");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2495 if (!source_file)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2496 {
111
kono
parents: 67
diff changeset
2497 fnotice (stderr, "Cannot open source file %s\n", src->name);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2498 retval = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2499 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2500 else if (src->file_time == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2501 fprintf (gcov_file, "%9s:%5d:Source is newer than graph\n", "-", 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2502
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2503 if (flag_branches)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2504 fn = src->functions;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2505
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2506 for (line_num = 1, line = &src->lines[line_num];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2507 line_num < src->num_lines; line_num++, line++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2508 {
111
kono
parents: 67
diff changeset
2509 for (; fn && fn->line == line_num; fn = fn->next_file_fn)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2510 {
111
kono
parents: 67
diff changeset
2511 arc_t *arc = fn->blocks[EXIT_BLOCK].pred;
kono
parents: 67
diff changeset
2512 gcov_type return_count = fn->blocks[EXIT_BLOCK].count;
kono
parents: 67
diff changeset
2513 gcov_type called_count = fn->blocks[ENTRY_BLOCK].count;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2514
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2515 for (; arc; arc = arc->pred_next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2516 if (arc->fake)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2517 return_count -= arc->count;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 47
diff changeset
2518
111
kono
parents: 67
diff changeset
2519 fprintf (gcov_file, "function %s", flag_demangled_names ?
kono
parents: 67
diff changeset
2520 fn->demangled_name : fn->name);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2521 fprintf (gcov_file, " called %s",
111
kono
parents: 67
diff changeset
2522 format_gcov (called_count, 0, -1));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2523 fprintf (gcov_file, " returned %s",
111
kono
parents: 67
diff changeset
2524 format_gcov (return_count, called_count, 0));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2525 fprintf (gcov_file, " blocks executed %s",
111
kono
parents: 67
diff changeset
2526 format_gcov (fn->blocks_executed, fn->blocks.size () - 2,
kono
parents: 67
diff changeset
2527 0));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2528 fprintf (gcov_file, "\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2529 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2530
111
kono
parents: 67
diff changeset
2531 if (retval)
kono
parents: 67
diff changeset
2532 retval = read_line (source_file);
kono
parents: 67
diff changeset
2533
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2534 /* For lines which don't exist in the .bb file, print '-' before
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2535 the source line. For lines which exist but were never
111
kono
parents: 67
diff changeset
2536 executed, print '#####' or '=====' before the source line.
kono
parents: 67
diff changeset
2537 Otherwise, print the execution count before the source line.
kono
parents: 67
diff changeset
2538 There are 16 spaces of indentation added before the source
kono
parents: 67
diff changeset
2539 line so that tabs won't be messed up. */
kono
parents: 67
diff changeset
2540 fprintf (gcov_file, "%9s:%5u:%s\n",
kono
parents: 67
diff changeset
2541 !line->exists ? "-" : line->count
kono
parents: 67
diff changeset
2542 ? format_gcov (line->count, 0, -1)
kono
parents: 67
diff changeset
2543 : line->unexceptional ? "#####" : "=====", line_num,
kono
parents: 67
diff changeset
2544 retval ? retval : "/*EOF*/");
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2545
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2546 if (flag_all_blocks)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2547 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2548 block_t *block;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2549 arc_t *arc;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2550 int ix, jx;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2551
111
kono
parents: 67
diff changeset
2552 for (ix = jx = 0, block = line->blocks; block;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2553 block = block->chain)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2554 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2555 if (!block->is_call_return)
111
kono
parents: 67
diff changeset
2556 {
kono
parents: 67
diff changeset
2557 fprintf (gcov_file, "%9s:%5u-block %2d",
kono
parents: 67
diff changeset
2558 !line->exists ? "-" : block->count
kono
parents: 67
diff changeset
2559 ? format_gcov (block->count, 0, -1)
kono
parents: 67
diff changeset
2560 : block->exceptional ? "%%%%%" : "$$$$$",
kono
parents: 67
diff changeset
2561 line_num, ix++);
kono
parents: 67
diff changeset
2562 if (flag_verbose)
kono
parents: 67
diff changeset
2563 fprintf (gcov_file, " (BB %u)", block->id);
kono
parents: 67
diff changeset
2564 fprintf (gcov_file, "\n");
kono
parents: 67
diff changeset
2565 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2566 if (flag_branches)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2567 for (arc = block->succ; arc; arc = arc->succ_next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2568 jx += output_branch_count (gcov_file, jx, arc);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2569 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2570 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2571 else if (flag_branches)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2572 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2573 int ix;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2574 arc_t *arc;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2575
111
kono
parents: 67
diff changeset
2576 for (ix = 0, arc = line->branches; arc; arc = arc->line_next)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2577 ix += output_branch_count (gcov_file, ix, arc);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2578 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2579 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2580
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2581 /* Handle all remaining source lines. There may be lines after the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2582 last line of code. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2583 if (retval)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2584 {
111
kono
parents: 67
diff changeset
2585 for (; (retval = read_line (source_file)); line_num++)
kono
parents: 67
diff changeset
2586 fprintf (gcov_file, "%9s:%5u:%s\n", "-", line_num, retval);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2587 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2588
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2589 if (source_file)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2590 fclose (source_file);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2591 }