1+ use std:: assert_matches:: assert_matches;
12use std:: sync:: Arc ;
23
34use itertools:: Itertools ;
45use rustc_abi:: Align ;
56use rustc_codegen_ssa:: traits:: { BaseTypeCodegenMethods , ConstCodegenMethods } ;
67use rustc_data_structures:: fx:: FxIndexMap ;
78use rustc_index:: IndexVec ;
9+ use rustc_macros:: TryFromU32 ;
810use rustc_middle:: ty:: TyCtxt ;
911use rustc_session:: RemapFileNameExt ;
1012use rustc_session:: config:: RemapPathScopeComponents ;
@@ -20,6 +22,23 @@ mod covfun;
2022mod spans;
2123mod unused;
2224
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+
2342/// Generates and exports the coverage map, which is embedded in special
2443/// linker sections in the final binary.
2544///
@@ -29,19 +48,13 @@ pub(crate) fn finalize(cx: &mut CodegenCx<'_, '_>) {
2948 let tcx = cx. tcx ;
3049
3150 // 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 ) ;
4558
4659 debug ! ( "Generating coverage map for CodegenUnit: `{}`" , cx. codegen_unit. name( ) ) ;
4760
@@ -201,7 +214,11 @@ impl VirtualFileMapping {
201214/// Generates the contents of the covmap record for this CGU, which mostly
202215/// consists of a header and a list of filenames. The record is then stored
203216/// 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+ ) {
205222 // A covmap record consists of four target-endian u32 values, followed by
206223 // the encoded filenames table. Two of the header fields are unused in
207224 // 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
212229 cx. const_u32 ( 0 ) , // (unused)
213230 cx. const_u32 ( filenames_buffer. len ( ) as u32 ) ,
214231 cx. const_u32 ( 0 ) , // (unused)
215- cx. const_u32 ( version) ,
232+ cx. const_u32 ( version. to_u32 ( ) ) ,
216233 ] ,
217234 /* packed */ false ,
218235 ) ;
0 commit comments