1 //! Source locations.
2 //!
3 //! Cranelift tracks the original source location of each instruction, and preserves the source
4 //! location when instructions are transformed.
5 
6 use core::fmt;
7 #[cfg(feature = "enable-serde")]
8 use serde::{Deserialize, Serialize};
9 
10 /// A source location.
11 ///
12 /// This is an opaque 32-bit number attached to each Cranelift IR instruction. Cranelift does not
13 /// interpret source locations in any way, they are simply preserved from the input to the output.
14 ///
15 /// The default source location uses the all-ones bit pattern `!0`. It is used for instructions
16 /// that can't be given a real source location.
17 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
18 #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
19 pub struct SourceLoc(u32);
20 
21 impl SourceLoc {
22     /// Create a new source location with the given bits.
23     pub fn new(bits: u32) -> Self {
24         Self(bits)
25     }
26 
27     /// Is this the default source location?
28     pub fn is_default(self) -> bool {
29         self == Default::default()
30     }
31 
32     /// Read the bits of this source location.
33     pub fn bits(self) -> u32 {
34         self.0
35     }
36 }
37 
38 impl Default for SourceLoc {
39     fn default() -> Self {
40         Self(!0)
41     }
42 }
43 
44 impl fmt::Display for SourceLoc {
45     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
46         if self.is_default() {
47             write!(f, "@-")
48         } else {
49             write!(f, "@{:04x}", self.0)
50         }
51     }
52 }
53 
54 #[cfg(test)]
55 mod tests {
56     use crate::ir::SourceLoc;
57     use alloc::string::ToString;
58 
59     #[test]
60     fn display() {
61         assert_eq!(SourceLoc::default().to_string(), "@-");
62         assert_eq!(SourceLoc::new(0).to_string(), "@0000");
63         assert_eq!(SourceLoc::new(16).to_string(), "@0010");
64         assert_eq!(SourceLoc::new(0xabcdef).to_string(), "@abcdef");
65     }
66 }
67