-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathcoverage.adb
333 lines (276 loc) · 10.2 KB
/
coverage.adb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
------------------------------------------------------------------------------
-- --
-- GNATcoverage --
-- --
-- Copyright (C) 2009-2024, AdaCore --
-- --
-- GNATcoverage is free software; you can redistribute it and/or modify it --
-- under terms of the GNU General Public License as published by the Free --
-- Software Foundation; either version 3, or (at your option) any later --
-- version. This software is distributed in the hope that it will be useful --
-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- --
-- TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --
-- License for more details. You should have received a copy of the GNU --
-- General Public License distributed with this software; see file --
-- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy --
-- of the license. --
------------------------------------------------------------------------------
with Ada.Command_Line;
with Ada.Containers;
with Support_Files; use Support_Files;
with Version; use Version;
package body Coverage is
Levels : Levels_Type := (others => False);
-- Global variable that records the coverage operation that has been asked
-- to xcov. Set using Set_Coverage_Levels.
-- Maps from valid --level string values to internal Levels array,
-- such as:
--
-- "stmt" -> (stmt => True, others => False);
-- "stmt+decision" -> (stmt => True, Decision => True, others => False)
-- ...
--
-- One map per family of criteria (source vs object coverage).
Object_Coverage_Enabled_Cached : Boolean;
Source_Coverage_Enabled_Cached : Boolean;
MCDC_Coverage_Enabled_Cached : Boolean;
-- Global variables to hold cached return values for enabled coverage
-- levels query functions. These functions can be called very often, so
-- just returning a boolean removes any overhead. These globals are updated
-- at each call of Set_Coverage_Levels, which is not called very often.
function Any_Coverage_Enabled (L : Levels_Type) return Boolean;
-- True if any level marked True in L is enabled
---------------------------
-- Coverage_Option_Value --
---------------------------
function Coverage_Option_Value return String is
begin
return Coverage_Option_Value (Levels);
end Coverage_Option_Value;
-------------
-- Enabled --
-------------
function Enabled (Level : Coverage_Level) return Boolean is
begin
return Levels (Level);
end Enabled;
--------------------------
-- Any_Coverage_Enabled --
--------------------------
function Any_Coverage_Enabled (L : Levels_Type) return Boolean is
begin
return (L and Levels) /= Levels_Type'(others => False);
end Any_Coverage_Enabled;
-------------------------------
-- Decision_Coverage_Enabled --
-------------------------------
function Decision_Coverage_Enabled return Boolean is
begin
return MCDC_Coverage_Enabled or else Enabled (Decision);
end Decision_Coverage_Enabled;
---------------------------
-- MCDC_Coverage_Enabled --
---------------------------
function MCDC_Coverage_Enabled return Boolean is
begin
return MCDC_Coverage_Enabled_Cached;
end MCDC_Coverage_Enabled;
--------------------------------
-- Assertion_Coverage_Enabled --
--------------------------------
function Assertion_Coverage_Enabled return Boolean is
begin
return Source_Coverage_Enabled
and then (Enabled (ATC) or else Enabled (ATCC));
end Assertion_Coverage_Enabled;
------------------------------------------
-- Assertion_Condition_Coverage_Enabled --
------------------------------------------
function Assertion_Condition_Coverage_Enabled return Boolean is
(Enabled (ATCC));
----------------
-- MCDC_Level --
----------------
function MCDC_Level return MCDC_Coverage_Level is
begin
pragma Assert (MCDC_Coverage_Enabled);
if Enabled (UC_MCDC) then
pragma Assert (not Enabled (MCDC));
return UC_MCDC;
else
pragma Assert (not Enabled (UC_MCDC));
return MCDC;
end if;
end MCDC_Level;
-------------------------------
-- Assertion_Condition_Level --
-------------------------------
function Assertion_Condition_Level return Contract_Condition_Level is
begin
pragma Assert (Assertion_Condition_Coverage_Enabled);
pragma Assert (Enabled (ATCC));
return ATCC;
end Assertion_Condition_Level;
----------------
-- Object_Level --
----------------
function Object_Level return Object_Coverage_Level is
begin
pragma Assert (Object_Coverage_Enabled);
if Enabled (Insn) then
pragma Assert (not Enabled (Branch));
return Insn;
else
pragma Assert (not Enabled (Insn));
return Branch;
end if;
end Object_Level;
-----------------------------
-- Object_Coverage_Enabled --
-----------------------------
function Object_Coverage_Enabled return Boolean is
begin
return Object_Coverage_Enabled_Cached;
end Object_Coverage_Enabled;
-----------------------------
-- Source_Coverage_Enabled --
-----------------------------
function Source_Coverage_Enabled return Boolean is
begin
return Source_Coverage_Enabled_Cached;
end Source_Coverage_Enabled;
-------------------------
-- Set_Coverage_Levels --
-------------------------
procedure Set_Coverage_Levels (Opt : String) is
use Levels_Option_Maps;
Cur : Cursor;
begin
-- Try to match a source level first, more likely
Cur := Source_Levels_Option_Map.Find (Opt'Unrestricted_Access);
if Cur = No_Element then
Cur := Object_Levels_Option_Map.Find (Opt'Unrestricted_Access);
end if;
Levels := Element (Cur);
Object_Coverage_Enabled_Cached := Any_Coverage_Enabled
((Object_Coverage_Level => True, others => False));
Source_Coverage_Enabled_Cached := Any_Coverage_Enabled
((Source_Coverage_Level => True, others => False));
MCDC_Coverage_Enabled_Cached := Any_Coverage_Enabled
((MCDC_Coverage_Level => True, others => False));
end Set_Coverage_Levels;
--------------------
-- Current_Levels --
--------------------
function Current_Levels return Levels_Type is
begin
return Levels;
end Current_Levels;
function Source_Levels_Enabled return Levels_Sets.Set is
Res : Levels_Sets.Set;
begin
if Source_Coverage_Enabled then
Res.Include (Stmt);
if Decision_Coverage_Enabled then
Res.Include (Decision);
if MCDC_Coverage_Enabled then
Res.Include (MCDC_Level);
end if;
end if;
if Assertion_Coverage_Enabled then
Res.Include (ATC);
if Enabled (ATCC) then
Res.Include (ATCC);
end if;
end if;
if Enabled (Fun_Call) then
Res.Include (Fun_Call);
end if;
if Enabled (GExpr) then
Res.Include (GExpr);
end if;
end if;
return Res;
end Source_Levels_Enabled;
-----------------------------
-- Coverage_Levels_Enabled --
-----------------------------
function Coverage_Levels_Enabled return Levels_Sets.Set is
begin
if Source_Coverage_Enabled then
return Source_Levels_Enabled;
else
declare
Res : Levels_Sets.Set;
begin
if Enabled (Insn) then
Res.Include (Insn);
end if;
if Enabled (Branch) then
Res.Include (Branch);
end if;
return Res;
end;
end if;
end Coverage_Levels_Enabled;
---------------------
-- Is_Load_Allowed --
---------------------
function Is_Load_Allowed
(Filename : String; Checkpoint_Levels : Levels_Type) return String is
begin
-- Be defensive with object coverage, which is not supported with
-- checkpoints.
if (for some L in Object_Coverage_Level => Checkpoint_Levels (L)) then
return ("object coverage in checkpoint is not supported. Corrupted"
& " checkpoint file?");
end if;
-- We allow loading iff the current levels are a subset of
-- Checkpoint_Levels.
if (for some L in Source_Coverage_Level =>
not Checkpoint_Levels (L) and then Levels (L))
then
return ("incompatible coverage level: " & Filename
& " was produced with """
& Coverage_Option_Value (Checkpoint_Levels)
& """ but we expect at least """
& Coverage_Option_Value & """");
end if;
return "";
end Is_Load_Allowed;
-----------------
-- Get_Context --
-----------------
function Get_Context return Context is
use Ada.Command_Line;
Command : Unbounded_String := +Support_Files.Gnatcov_Command_Name;
begin
for J in 1 .. Argument_Count loop
Append (Command, ' ' & Argument (J));
end loop;
return Context'
(Timestamp => Clock,
Version => +Xcov_Version,
Command => Command,
Levels => +Coverage_Option_Value);
end Get_Context;
---------------
-- To_String --
---------------
function To_String (C : Context) return String is
S : aliased Unbounded_String;
SS : aliased Unbounded_String_Stream (S'Access);
begin
Context'Output (SS'Access, C);
return +S;
end To_String;
-----------------
-- From_String --
-----------------
function From_String (S : String) return Context is
Str : aliased Unbounded_String := +S;
SS : aliased Unbounded_String_Stream (Str'Access);
begin
return Context'Input (SS'Access);
end From_String;
end Coverage;