• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use rustc_middle::mir::coverage::{CounterValueReference, MappedExpressionIndex};
2 
3 /// Must match the layout of `LLVMRustCounterKind`.
4 #[derive(Copy, Clone, Debug)]
5 #[repr(C)]
6 pub enum CounterKind {
7     Zero = 0,
8     CounterValueReference = 1,
9     Expression = 2,
10 }
11 
12 /// A reference to an instance of an abstract "counter" that will yield a value in a coverage
13 /// report. Note that `id` has different interpretations, depending on the `kind`:
14 ///   * For `CounterKind::Zero`, `id` is assumed to be `0`
15 ///   * For `CounterKind::CounterValueReference`,  `id` matches the `counter_id` of the injected
16 ///     instrumentation counter (the `index` argument to the LLVM intrinsic
17 ///     `instrprof.increment()`)
18 ///   * For `CounterKind::Expression`, `id` is the index into the coverage map's array of
19 ///     counter expressions.
20 ///
21 /// Corresponds to struct `llvm::coverage::Counter`.
22 ///
23 /// Must match the layout of `LLVMRustCounter`.
24 #[derive(Copy, Clone, Debug)]
25 #[repr(C)]
26 pub struct Counter {
27     // Important: The layout (order and types of fields) must match its C++ counterpart.
28     pub kind: CounterKind,
29     id: u32,
30 }
31 
32 impl Counter {
33     /// Constructs a new `Counter` of kind `Zero`. For this `CounterKind`, the
34     /// `id` is not used.
zero() -> Self35     pub fn zero() -> Self {
36         Self { kind: CounterKind::Zero, id: 0 }
37     }
38 
39     /// Constructs a new `Counter` of kind `CounterValueReference`, and converts
40     /// the given 1-based counter_id to the required 0-based equivalent for
41     /// the `Counter` encoding.
counter_value_reference(counter_id: CounterValueReference) -> Self42     pub fn counter_value_reference(counter_id: CounterValueReference) -> Self {
43         Self { kind: CounterKind::CounterValueReference, id: counter_id.zero_based_index() }
44     }
45 
46     /// Constructs a new `Counter` of kind `Expression`.
expression(mapped_expression_index: MappedExpressionIndex) -> Self47     pub fn expression(mapped_expression_index: MappedExpressionIndex) -> Self {
48         Self { kind: CounterKind::Expression, id: mapped_expression_index.into() }
49     }
50 
51     /// Returns true if the `Counter` kind is `Zero`.
is_zero(&self) -> bool52     pub fn is_zero(&self) -> bool {
53         matches!(self.kind, CounterKind::Zero)
54     }
55 
56     /// An explicitly-named function to get the ID value, making it more obvious
57     /// that the stored value is now 0-based.
zero_based_id(&self) -> u3258     pub fn zero_based_id(&self) -> u32 {
59         debug_assert!(!self.is_zero(), "`id` is undefined for CounterKind::Zero");
60         self.id
61     }
62 }
63 
64 /// Corresponds to enum `llvm::coverage::CounterExpression::ExprKind`.
65 ///
66 /// Must match the layout of `LLVMRustCounterExprKind`.
67 #[derive(Copy, Clone, Debug)]
68 #[repr(C)]
69 pub enum ExprKind {
70     Subtract = 0,
71     Add = 1,
72 }
73 
74 /// Corresponds to struct `llvm::coverage::CounterExpression`.
75 ///
76 /// Must match the layout of `LLVMRustCounterExpression`.
77 #[derive(Copy, Clone, Debug)]
78 #[repr(C)]
79 pub struct CounterExpression {
80     pub kind: ExprKind,
81     pub lhs: Counter,
82     pub rhs: Counter,
83 }
84 
85 impl CounterExpression {
new(lhs: Counter, kind: ExprKind, rhs: Counter) -> Self86     pub fn new(lhs: Counter, kind: ExprKind, rhs: Counter) -> Self {
87         Self { kind, lhs, rhs }
88     }
89 }
90