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