coverage. Generate Mappings of decisions and conditions for MC/DC
This commit is contained in:
parent
68f86381ee
commit
cf6b6cb2b4
10 changed files with 779 additions and 41 deletions
|
@ -1,4 +1,6 @@
|
|||
use rustc_middle::mir::coverage::{CodeRegion, CounterId, CovTerm, ExpressionId, MappingKind};
|
||||
use rustc_middle::mir::coverage::{
|
||||
CodeRegion, ConditionInfo, CounterId, CovTerm, DecisionInfo, ExpressionId, MappingKind,
|
||||
};
|
||||
|
||||
/// Must match the layout of `LLVMRustCounterKind`.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
|
@ -99,6 +101,86 @@ pub enum RegionKind {
|
|||
/// associated with two counters, each representing the number of times the
|
||||
/// expression evaluates to true or false.
|
||||
BranchRegion = 4,
|
||||
|
||||
/// A DecisionRegion represents a top-level boolean expression and is
|
||||
/// associated with a variable length bitmap index and condition number.
|
||||
MCDCDecisionRegion = 5,
|
||||
|
||||
/// A Branch Region can be extended to include IDs to facilitate MC/DC.
|
||||
MCDCBranchRegion = 6,
|
||||
}
|
||||
|
||||
pub mod mcdc {
|
||||
use rustc_middle::mir::coverage::{ConditionInfo, DecisionInfo};
|
||||
|
||||
/// Must match the layout of `LLVMRustMCDCDecisionParameters`.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
pub struct DecisionParameters {
|
||||
bitmap_idx: u32,
|
||||
conditions_num: u16,
|
||||
}
|
||||
|
||||
// ConditionId in llvm is `unsigned int` at 18 while `int16_t` at [19](https://github.com/llvm/llvm-project/pull/81257)
|
||||
type LLVMConditionId = i16;
|
||||
|
||||
/// Must match the layout of `LLVMRustMCDCBranchParameters`.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
pub struct BranchParameters {
|
||||
condition_id: LLVMConditionId,
|
||||
condition_ids: [LLVMConditionId; 2],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum ParameterTag {
|
||||
None = 0,
|
||||
Decision = 1,
|
||||
Branch = 2,
|
||||
}
|
||||
/// Same layout with `LLVMRustMCDCParameters`
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct Parameters {
|
||||
tag: ParameterTag,
|
||||
decision_params: DecisionParameters,
|
||||
branch_params: BranchParameters,
|
||||
}
|
||||
|
||||
impl Parameters {
|
||||
pub fn none() -> Self {
|
||||
Self {
|
||||
tag: ParameterTag::None,
|
||||
decision_params: Default::default(),
|
||||
branch_params: Default::default(),
|
||||
}
|
||||
}
|
||||
pub fn decision(decision_params: DecisionParameters) -> Self {
|
||||
Self { tag: ParameterTag::Decision, decision_params, branch_params: Default::default() }
|
||||
}
|
||||
pub fn branch(branch_params: BranchParameters) -> Self {
|
||||
Self { tag: ParameterTag::Branch, decision_params: Default::default(), branch_params }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ConditionInfo> for BranchParameters {
|
||||
fn from(value: ConditionInfo) -> Self {
|
||||
Self {
|
||||
condition_id: value.condition_id.as_u32() as LLVMConditionId,
|
||||
condition_ids: [
|
||||
value.false_next_id.as_u32() as LLVMConditionId,
|
||||
value.true_next_id.as_u32() as LLVMConditionId,
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DecisionInfo> for DecisionParameters {
|
||||
fn from(value: DecisionInfo) -> Self {
|
||||
Self { bitmap_idx: value.bitmap_idx, conditions_num: value.conditions_num }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This struct provides LLVM's representation of a "CoverageMappingRegion", encoded into the
|
||||
|
@ -122,6 +204,7 @@ pub struct CounterMappingRegion {
|
|||
/// for the false branch of the region.
|
||||
false_counter: Counter,
|
||||
|
||||
mcdc_params: mcdc::Parameters,
|
||||
/// An indirect reference to the source filename. In the LLVM Coverage Mapping Format, the
|
||||
/// file_id is an index into a function-specific `virtual_file_mapping` array of indexes
|
||||
/// that, in turn, are used to look up the filename for this region.
|
||||
|
@ -173,6 +256,26 @@ impl CounterMappingRegion {
|
|||
end_line,
|
||||
end_col,
|
||||
),
|
||||
MappingKind::MCDCBranch { true_term, false_term, mcdc_params } => {
|
||||
Self::mcdc_branch_region(
|
||||
Counter::from_term(true_term),
|
||||
Counter::from_term(false_term),
|
||||
mcdc_params,
|
||||
local_file_id,
|
||||
start_line,
|
||||
start_col,
|
||||
end_line,
|
||||
end_col,
|
||||
)
|
||||
}
|
||||
MappingKind::MCDCDecision(decision_info) => Self::decision_region(
|
||||
decision_info,
|
||||
local_file_id,
|
||||
start_line,
|
||||
start_col,
|
||||
end_line,
|
||||
end_col,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,6 +290,7 @@ impl CounterMappingRegion {
|
|||
Self {
|
||||
counter,
|
||||
false_counter: Counter::ZERO,
|
||||
mcdc_params: mcdc::Parameters::none(),
|
||||
file_id,
|
||||
expanded_file_id: 0,
|
||||
start_line,
|
||||
|
@ -209,6 +313,7 @@ impl CounterMappingRegion {
|
|||
Self {
|
||||
counter,
|
||||
false_counter,
|
||||
mcdc_params: mcdc::Parameters::none(),
|
||||
file_id,
|
||||
expanded_file_id: 0,
|
||||
start_line,
|
||||
|
@ -219,6 +324,54 @@ impl CounterMappingRegion {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn mcdc_branch_region(
|
||||
counter: Counter,
|
||||
false_counter: Counter,
|
||||
condition_info: ConditionInfo,
|
||||
file_id: u32,
|
||||
start_line: u32,
|
||||
start_col: u32,
|
||||
end_line: u32,
|
||||
end_col: u32,
|
||||
) -> Self {
|
||||
Self {
|
||||
counter,
|
||||
false_counter,
|
||||
mcdc_params: mcdc::Parameters::branch(condition_info.into()),
|
||||
file_id,
|
||||
expanded_file_id: 0,
|
||||
start_line,
|
||||
start_col,
|
||||
end_line,
|
||||
end_col,
|
||||
kind: RegionKind::MCDCBranchRegion,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn decision_region(
|
||||
decision_info: DecisionInfo,
|
||||
file_id: u32,
|
||||
start_line: u32,
|
||||
start_col: u32,
|
||||
end_line: u32,
|
||||
end_col: u32,
|
||||
) -> Self {
|
||||
let mcdc_params = mcdc::Parameters::decision(decision_info.into());
|
||||
|
||||
Self {
|
||||
counter: Counter::ZERO,
|
||||
false_counter: Counter::ZERO,
|
||||
mcdc_params,
|
||||
file_id,
|
||||
expanded_file_id: 0,
|
||||
start_line,
|
||||
start_col,
|
||||
end_line,
|
||||
end_col,
|
||||
kind: RegionKind::MCDCDecisionRegion,
|
||||
}
|
||||
}
|
||||
|
||||
// This function might be used in the future; the LLVM API is still evolving, as is coverage
|
||||
// support.
|
||||
#[allow(dead_code)]
|
||||
|
@ -233,6 +386,7 @@ impl CounterMappingRegion {
|
|||
Self {
|
||||
counter: Counter::ZERO,
|
||||
false_counter: Counter::ZERO,
|
||||
mcdc_params: mcdc::Parameters::none(),
|
||||
file_id,
|
||||
expanded_file_id,
|
||||
start_line,
|
||||
|
@ -256,6 +410,7 @@ impl CounterMappingRegion {
|
|||
Self {
|
||||
counter: Counter::ZERO,
|
||||
false_counter: Counter::ZERO,
|
||||
mcdc_params: mcdc::Parameters::none(),
|
||||
file_id,
|
||||
expanded_file_id: 0,
|
||||
start_line,
|
||||
|
@ -280,6 +435,7 @@ impl CounterMappingRegion {
|
|||
Self {
|
||||
counter,
|
||||
false_counter: Counter::ZERO,
|
||||
mcdc_params: mcdc::Parameters::none(),
|
||||
file_id,
|
||||
expanded_file_id: 0,
|
||||
start_line,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue