coverage: Add LLVM plumbing for expansion regions
This is currently unused, but paves the way for future work on expansion regions without having to worry about the FFI parts.
This commit is contained in:
parent
2947be7af8
commit
d07ef5b0e1
5 changed files with 57 additions and 7 deletions
|
@ -146,6 +146,7 @@ pub(crate) struct CoverageSpan {
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub(crate) struct Regions {
|
pub(crate) struct Regions {
|
||||||
pub(crate) code_regions: Vec<CodeRegion>,
|
pub(crate) code_regions: Vec<CodeRegion>,
|
||||||
|
pub(crate) expansion_regions: Vec<ExpansionRegion>,
|
||||||
pub(crate) branch_regions: Vec<BranchRegion>,
|
pub(crate) branch_regions: Vec<BranchRegion>,
|
||||||
pub(crate) mcdc_branch_regions: Vec<MCDCBranchRegion>,
|
pub(crate) mcdc_branch_regions: Vec<MCDCBranchRegion>,
|
||||||
pub(crate) mcdc_decision_regions: Vec<MCDCDecisionRegion>,
|
pub(crate) mcdc_decision_regions: Vec<MCDCDecisionRegion>,
|
||||||
|
@ -154,10 +155,16 @@ pub(crate) struct Regions {
|
||||||
impl Regions {
|
impl Regions {
|
||||||
/// Returns true if none of this structure's tables contain any regions.
|
/// Returns true if none of this structure's tables contain any regions.
|
||||||
pub(crate) fn has_no_regions(&self) -> bool {
|
pub(crate) fn has_no_regions(&self) -> bool {
|
||||||
let Self { code_regions, branch_regions, mcdc_branch_regions, mcdc_decision_regions } =
|
let Self {
|
||||||
self;
|
code_regions,
|
||||||
|
expansion_regions,
|
||||||
|
branch_regions,
|
||||||
|
mcdc_branch_regions,
|
||||||
|
mcdc_decision_regions,
|
||||||
|
} = self;
|
||||||
|
|
||||||
code_regions.is_empty()
|
code_regions.is_empty()
|
||||||
|
&& expansion_regions.is_empty()
|
||||||
&& branch_regions.is_empty()
|
&& branch_regions.is_empty()
|
||||||
&& mcdc_branch_regions.is_empty()
|
&& mcdc_branch_regions.is_empty()
|
||||||
&& mcdc_decision_regions.is_empty()
|
&& mcdc_decision_regions.is_empty()
|
||||||
|
@ -172,6 +179,14 @@ pub(crate) struct CodeRegion {
|
||||||
pub(crate) counter: Counter,
|
pub(crate) counter: Counter,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Must match the layout of `LLVMRustCoverageExpansionRegion`.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub(crate) struct ExpansionRegion {
|
||||||
|
pub(crate) cov_span: CoverageSpan,
|
||||||
|
pub(crate) expanded_file_id: u32,
|
||||||
|
}
|
||||||
|
|
||||||
/// Must match the layout of `LLVMRustCoverageBranchRegion`.
|
/// Must match the layout of `LLVMRustCoverageBranchRegion`.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
|
|
@ -63,8 +63,18 @@ pub(crate) fn write_function_mappings_to_buffer(
|
||||||
expressions: &[ffi::CounterExpression],
|
expressions: &[ffi::CounterExpression],
|
||||||
regions: &ffi::Regions,
|
regions: &ffi::Regions,
|
||||||
) -> Vec<u8> {
|
) -> Vec<u8> {
|
||||||
let ffi::Regions { code_regions, branch_regions, mcdc_branch_regions, mcdc_decision_regions } =
|
let ffi::Regions {
|
||||||
regions;
|
code_regions,
|
||||||
|
expansion_regions,
|
||||||
|
branch_regions,
|
||||||
|
mcdc_branch_regions,
|
||||||
|
mcdc_decision_regions,
|
||||||
|
} = regions;
|
||||||
|
|
||||||
|
// SAFETY:
|
||||||
|
// - All types are FFI-compatible and have matching representations in Rust/C++.
|
||||||
|
// - For pointer/length pairs, the pointer and length come from the same vector or slice.
|
||||||
|
// - C++ code does not retain any pointers after the call returns.
|
||||||
llvm::build_byte_buffer(|buffer| unsafe {
|
llvm::build_byte_buffer(|buffer| unsafe {
|
||||||
llvm::LLVMRustCoverageWriteFunctionMappingsToBuffer(
|
llvm::LLVMRustCoverageWriteFunctionMappingsToBuffer(
|
||||||
virtual_file_mapping.as_ptr(),
|
virtual_file_mapping.as_ptr(),
|
||||||
|
@ -73,6 +83,8 @@ pub(crate) fn write_function_mappings_to_buffer(
|
||||||
expressions.len(),
|
expressions.len(),
|
||||||
code_regions.as_ptr(),
|
code_regions.as_ptr(),
|
||||||
code_regions.len(),
|
code_regions.len(),
|
||||||
|
expansion_regions.as_ptr(),
|
||||||
|
expansion_regions.len(),
|
||||||
branch_regions.as_ptr(),
|
branch_regions.as_ptr(),
|
||||||
branch_regions.len(),
|
branch_regions.len(),
|
||||||
mcdc_branch_regions.as_ptr(),
|
mcdc_branch_regions.as_ptr(),
|
||||||
|
|
|
@ -120,13 +120,18 @@ fn fill_region_tables<'tcx>(
|
||||||
// Associate that global file ID with a local file ID for this function.
|
// Associate that global file ID with a local file ID for this function.
|
||||||
let local_file_id = covfun.virtual_file_mapping.local_id_for_global(global_file_id);
|
let local_file_id = covfun.virtual_file_mapping.local_id_for_global(global_file_id);
|
||||||
|
|
||||||
let ffi::Regions { code_regions, branch_regions, mcdc_branch_regions, mcdc_decision_regions } =
|
|
||||||
&mut covfun.regions;
|
|
||||||
|
|
||||||
let make_cov_span =
|
let make_cov_span =
|
||||||
|span: Span| spans::make_coverage_span(local_file_id, source_map, &source_file, span);
|
|span: Span| spans::make_coverage_span(local_file_id, source_map, &source_file, span);
|
||||||
let discard_all = tcx.sess.coverage_discard_all_spans_in_codegen();
|
let discard_all = tcx.sess.coverage_discard_all_spans_in_codegen();
|
||||||
|
|
||||||
|
let ffi::Regions {
|
||||||
|
code_regions,
|
||||||
|
expansion_regions: _, // FIXME(Zalathar): Fill out support for expansion regions
|
||||||
|
branch_regions,
|
||||||
|
mcdc_branch_regions,
|
||||||
|
mcdc_decision_regions,
|
||||||
|
} = &mut covfun.regions;
|
||||||
|
|
||||||
// For each counter/region pair in this function+file, convert it to a
|
// For each counter/region pair in this function+file, convert it to a
|
||||||
// form suitable for FFI.
|
// form suitable for FFI.
|
||||||
for &Mapping { ref kind, span } in &fn_cov_info.mappings {
|
for &Mapping { ref kind, span } in &fn_cov_info.mappings {
|
||||||
|
|
|
@ -2019,6 +2019,8 @@ unsafe extern "C" {
|
||||||
NumExpressions: size_t,
|
NumExpressions: size_t,
|
||||||
CodeRegions: *const crate::coverageinfo::ffi::CodeRegion,
|
CodeRegions: *const crate::coverageinfo::ffi::CodeRegion,
|
||||||
NumCodeRegions: size_t,
|
NumCodeRegions: size_t,
|
||||||
|
ExpansionRegions: *const crate::coverageinfo::ffi::ExpansionRegion,
|
||||||
|
NumExpansionRegions: size_t,
|
||||||
BranchRegions: *const crate::coverageinfo::ffi::BranchRegion,
|
BranchRegions: *const crate::coverageinfo::ffi::BranchRegion,
|
||||||
NumBranchRegions: size_t,
|
NumBranchRegions: size_t,
|
||||||
MCDCBranchRegions: *const crate::coverageinfo::ffi::MCDCBranchRegion,
|
MCDCBranchRegions: *const crate::coverageinfo::ffi::MCDCBranchRegion,
|
||||||
|
|
|
@ -77,6 +77,13 @@ struct LLVMRustCoverageCodeRegion {
|
||||||
LLVMRustCounter Count;
|
LLVMRustCounter Count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Must match the layout of
|
||||||
|
// `rustc_codegen_llvm::coverageinfo::ffi::ExpansionRegion`.
|
||||||
|
struct LLVMRustCoverageExpansionRegion {
|
||||||
|
LLVMRustCoverageSpan Span;
|
||||||
|
uint32_t ExpandedFileID;
|
||||||
|
};
|
||||||
|
|
||||||
// Must match the layout of
|
// Must match the layout of
|
||||||
// `rustc_codegen_llvm::coverageinfo::ffi::BranchRegion`.
|
// `rustc_codegen_llvm::coverageinfo::ffi::BranchRegion`.
|
||||||
struct LLVMRustCoverageBranchRegion {
|
struct LLVMRustCoverageBranchRegion {
|
||||||
|
@ -151,6 +158,8 @@ extern "C" void LLVMRustCoverageWriteFunctionMappingsToBuffer(
|
||||||
const unsigned *VirtualFileMappingIDs, size_t NumVirtualFileMappingIDs,
|
const unsigned *VirtualFileMappingIDs, size_t NumVirtualFileMappingIDs,
|
||||||
const LLVMRustCounterExpression *RustExpressions, size_t NumExpressions,
|
const LLVMRustCounterExpression *RustExpressions, size_t NumExpressions,
|
||||||
const LLVMRustCoverageCodeRegion *CodeRegions, size_t NumCodeRegions,
|
const LLVMRustCoverageCodeRegion *CodeRegions, size_t NumCodeRegions,
|
||||||
|
const LLVMRustCoverageExpansionRegion *ExpansionRegions,
|
||||||
|
size_t NumExpansionRegions,
|
||||||
const LLVMRustCoverageBranchRegion *BranchRegions, size_t NumBranchRegions,
|
const LLVMRustCoverageBranchRegion *BranchRegions, size_t NumBranchRegions,
|
||||||
const LLVMRustCoverageMCDCBranchRegion *MCDCBranchRegions,
|
const LLVMRustCoverageMCDCBranchRegion *MCDCBranchRegions,
|
||||||
size_t NumMCDCBranchRegions,
|
size_t NumMCDCBranchRegions,
|
||||||
|
@ -179,6 +188,13 @@ extern "C" void LLVMRustCoverageWriteFunctionMappingsToBuffer(
|
||||||
Region.Span.ColumnStart, Region.Span.LineEnd, Region.Span.ColumnEnd));
|
Region.Span.ColumnStart, Region.Span.LineEnd, Region.Span.ColumnEnd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Expansion regions:
|
||||||
|
for (const auto &Region : ArrayRef(ExpansionRegions, NumExpansionRegions)) {
|
||||||
|
MappingRegions.push_back(coverage::CounterMappingRegion::makeExpansion(
|
||||||
|
Region.Span.FileID, Region.ExpandedFileID, Region.Span.LineStart,
|
||||||
|
Region.Span.ColumnStart, Region.Span.LineEnd, Region.Span.ColumnEnd));
|
||||||
|
}
|
||||||
|
|
||||||
// Branch regions:
|
// Branch regions:
|
||||||
for (const auto &Region : ArrayRef(BranchRegions, NumBranchRegions)) {
|
for (const auto &Region : ArrayRef(BranchRegions, NumBranchRegions)) {
|
||||||
MappingRegions.push_back(coverage::CounterMappingRegion::makeBranchRegion(
|
MappingRegions.push_back(coverage::CounterMappingRegion::makeBranchRegion(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue