1
+ use std:: assert_matches:: assert_matches;
1
2
use std:: sync:: Arc ;
2
3
3
4
use itertools:: Itertools ;
4
5
use rustc_abi:: Align ;
5
6
use rustc_codegen_ssa:: traits:: { BaseTypeCodegenMethods , ConstCodegenMethods } ;
6
7
use rustc_data_structures:: fx:: FxIndexMap ;
7
8
use rustc_index:: IndexVec ;
9
+ use rustc_macros:: TryFromU32 ;
8
10
use rustc_middle:: ty:: TyCtxt ;
9
11
use rustc_session:: RemapFileNameExt ;
10
12
use rustc_session:: config:: RemapPathScopeComponents ;
@@ -20,6 +22,23 @@ mod covfun;
20
22
mod spans;
21
23
mod unused;
22
24
25
+ /// Version number that will be included the `__llvm_covmap` section header.
26
+ /// Corresponds to LLVM's `llvm::coverage::CovMapVersion` (in `CoverageMapping.h`),
27
+ /// or at least the subset that we know and care about.
28
+ ///
29
+ /// Note that version `n` is encoded as `(n-1)`.
30
+ #[ derive( Clone , Copy , Debug , PartialEq , Eq , PartialOrd , Ord , TryFromU32 ) ]
31
+ enum CovmapVersion {
32
+ /// Used by LLVM 18 onwards.
33
+ Version7 = 6 ,
34
+ }
35
+
36
+ impl CovmapVersion {
37
+ fn to_u32 ( self ) -> u32 {
38
+ self as u32
39
+ }
40
+ }
41
+
23
42
/// Generates and exports the coverage map, which is embedded in special
24
43
/// linker sections in the final binary.
25
44
///
@@ -29,19 +48,13 @@ pub(crate) fn finalize(cx: &mut CodegenCx<'_, '_>) {
29
48
let tcx = cx. tcx ;
30
49
31
50
// Ensure that LLVM is using a version of the coverage mapping format that
32
- // agrees with our Rust-side code. Expected versions (encoded as n-1) are:
33
- // - `CovMapVersion::Version7` (6) used by LLVM 18-19
34
- let covmap_version = {
35
- let llvm_covmap_version = llvm_cov:: mapping_version ( ) ;
36
- let expected_versions = 6 ..=6 ;
37
- assert ! (
38
- expected_versions. contains( & llvm_covmap_version) ,
39
- "Coverage mapping version exposed by `llvm-wrapper` is out of sync; \
40
- expected {expected_versions:?} but was {llvm_covmap_version}"
41
- ) ;
42
- // This is the version number that we will embed in the covmap section:
43
- llvm_covmap_version
44
- } ;
51
+ // agrees with our Rust-side code. Expected versions are:
52
+ // - `Version7` (6) used by LLVM 18 onwards.
53
+ let covmap_version =
54
+ CovmapVersion :: try_from ( llvm_cov:: mapping_version ( ) ) . unwrap_or_else ( |raw_version : u32 | {
55
+ panic ! ( "unknown coverage mapping version reported by `llvm-wrapper`: {raw_version}" )
56
+ } ) ;
57
+ assert_matches ! ( covmap_version, CovmapVersion :: Version7 ) ;
45
58
46
59
debug ! ( "Generating coverage map for CodegenUnit: `{}`" , cx. codegen_unit. name( ) ) ;
47
60
@@ -201,7 +214,11 @@ impl VirtualFileMapping {
201
214
/// Generates the contents of the covmap record for this CGU, which mostly
202
215
/// consists of a header and a list of filenames. The record is then stored
203
216
/// as a global variable in the `__llvm_covmap` section.
204
- fn generate_covmap_record < ' ll > ( cx : & mut CodegenCx < ' ll , ' _ > , version : u32 , filenames_buffer : & [ u8 ] ) {
217
+ fn generate_covmap_record < ' ll > (
218
+ cx : & mut CodegenCx < ' ll , ' _ > ,
219
+ version : CovmapVersion ,
220
+ filenames_buffer : & [ u8 ] ,
221
+ ) {
205
222
// A covmap record consists of four target-endian u32 values, followed by
206
223
// the encoded filenames table. Two of the header fields are unused in
207
224
// modern versions of the LLVM coverage mapping format, and are always 0.
@@ -212,7 +229,7 @@ fn generate_covmap_record<'ll>(cx: &mut CodegenCx<'ll, '_>, version: u32, filena
212
229
cx. const_u32 ( 0 ) , // (unused)
213
230
cx. const_u32 ( filenames_buffer. len ( ) as u32 ) ,
214
231
cx. const_u32 ( 0 ) , // (unused)
215
- cx. const_u32 ( version) ,
232
+ cx. const_u32 ( version. to_u32 ( ) ) ,
216
233
] ,
217
234
/* packed */ false ,
218
235
) ;
0 commit comments