]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/mir/coverage.rs
Move orphan module-name/mod.rs files into module-name.rs files
[rust.git] / compiler / rustc_middle / src / mir / coverage.rs
1 //! Metadata from source code coverage analysis and instrumentation.
2
3 use rustc_macros::HashStable;
4 use rustc_span::Symbol;
5
6 use std::cmp::Ord;
7 use std::fmt::{self, Debug, Formatter};
8
9 rustc_index::newtype_index! {
10     pub struct ExpressionOperandId {
11         derive [HashStable]
12         DEBUG_FORMAT = "ExpressionOperandId({})",
13         MAX = 0xFFFF_FFFF,
14     }
15 }
16
17 impl ExpressionOperandId {
18     /// An expression operand for a "zero counter", as described in the following references:
19     ///
20     /// * https://github.com/rust-lang/llvm-project/blob/llvmorg-8.0.0/llvm/docs/CoverageMappingFormat.rst#counter
21     /// * https://github.com/rust-lang/llvm-project/blob/llvmorg-8.0.0/llvm/docs/CoverageMappingFormat.rst#tag
22     /// * https://github.com/rust-lang/llvm-project/blob/llvmorg-8.0.0/llvm/docs/CoverageMappingFormat.rst#counter-expressions
23     ///
24     /// This operand can be used to count two or more separate code regions with a single counter,
25     /// if they run sequentially with no branches, by injecting the `Counter` in a `BasicBlock` for
26     /// one of the code regions, and inserting `CounterExpression`s ("add ZERO to the counter") in
27     /// the coverage map for the other code regions.
28     pub const ZERO: Self = Self::from_u32(0);
29 }
30
31 rustc_index::newtype_index! {
32     pub struct CounterValueReference {
33         derive [HashStable]
34         DEBUG_FORMAT = "CounterValueReference({})",
35         MAX = 0xFFFF_FFFF,
36     }
37 }
38
39 impl CounterValueReference {
40     // Counters start at 1 to reserve 0 for ExpressionOperandId::ZERO.
41     pub const START: Self = Self::from_u32(1);
42 }
43
44 rustc_index::newtype_index! {
45     pub struct InjectedExpressionIndex {
46         derive [HashStable]
47         DEBUG_FORMAT = "InjectedExpressionIndex({})",
48         MAX = 0xFFFF_FFFF,
49     }
50 }
51
52 rustc_index::newtype_index! {
53     pub struct MappedExpressionIndex {
54         derive [HashStable]
55         DEBUG_FORMAT = "MappedExpressionIndex({})",
56         MAX = 0xFFFF_FFFF,
57     }
58 }
59
60 impl From<CounterValueReference> for ExpressionOperandId {
61     #[inline]
62     fn from(v: CounterValueReference) -> ExpressionOperandId {
63         ExpressionOperandId::from(v.as_u32())
64     }
65 }
66
67 impl From<InjectedExpressionIndex> for ExpressionOperandId {
68     #[inline]
69     fn from(v: InjectedExpressionIndex) -> ExpressionOperandId {
70         ExpressionOperandId::from(v.as_u32())
71     }
72 }
73
74 #[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
75 pub enum CoverageKind {
76     Counter {
77         function_source_hash: u64,
78         id: CounterValueReference,
79     },
80     Expression {
81         id: InjectedExpressionIndex,
82         lhs: ExpressionOperandId,
83         op: Op,
84         rhs: ExpressionOperandId,
85     },
86     Unreachable,
87 }
88
89 impl CoverageKind {
90     pub fn as_operand_id(&self) -> ExpressionOperandId {
91         match *self {
92             CoverageKind::Counter { id, .. } => ExpressionOperandId::from(id),
93             CoverageKind::Expression { id, .. } => ExpressionOperandId::from(id),
94             CoverageKind::Unreachable => {
95                 bug!("Unreachable coverage cannot be part of an expression")
96             }
97         }
98     }
99 }
100
101 #[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, PartialEq, Eq, PartialOrd, Ord)]
102 pub struct CodeRegion {
103     pub file_name: Symbol,
104     pub start_line: u32,
105     pub start_col: u32,
106     pub end_line: u32,
107     pub end_col: u32,
108 }
109
110 impl Debug for CodeRegion {
111     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
112         write!(
113             fmt,
114             "{}:{}:{} - {}:{}",
115             self.file_name, self.start_line, self.start_col, self.end_line, self.end_col
116         )
117     }
118 }
119
120 #[derive(Copy, Clone, Debug, PartialEq, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
121 pub enum Op {
122     Subtract,
123     Add,
124 }