Skip to main content

llvm_ir/
value.rs

1//! SSA values: constants, instruction results, function arguments, and globals.
2
3use crate::context::{ConstId, GlobalId, TypeId};
4
5/// Constant value stored in the Context constant pool.
6#[derive(Clone, Debug, PartialEq)]
7pub enum ConstantData {
8    /// Small integer (fits in u64).
9    Int { ty: TypeId, val: u64 },
10    /// Wide integer (more than 64 bits), stored as little-endian 64-bit words.
11    IntWide { ty: TypeId, words: Vec<u64> },
12    /// Floating-point value stored as raw bits.
13    Float { ty: TypeId, bits: u64 },
14    /// Null / null pointer / zero pointer.
15    Null(TypeId),
16    /// Undef value.
17    Undef(TypeId),
18    /// Poison value.
19    Poison(TypeId),
20    /// Zero-initializer (aggregate types).
21    ZeroInitializer(TypeId),
22    /// Constant array.
23    Array { ty: TypeId, elements: Vec<ConstId> },
24    /// Constant struct.
25    Struct { ty: TypeId, fields: Vec<ConstId> },
26    /// Constant vector.
27    Vector { ty: TypeId, elements: Vec<ConstId> },
28    /// Reference to a global symbol (global variable or function).
29    /// `name` is the LLVM IR name (without `@`), used for printing.
30    GlobalRef {
31        ty: TypeId,
32        id: GlobalId,
33        name: String,
34    },
35}
36
37/// A function argument (SSA value produced by function entry).
38#[derive(Clone, Debug)]
39pub struct Argument {
40    /// Public API for `name`.
41    pub name: String,
42    /// Public API for `ty`.
43    pub ty: TypeId,
44    /// Public API for `index`.
45    pub index: u32,
46}
47
48/// A global variable definition.
49#[derive(Clone, Debug)]
50pub struct GlobalVariable {
51    /// Public API for `name`.
52    pub name: String,
53    /// Type of the value stored (not the pointer type).
54    pub ty: TypeId,
55    /// Optional constant initializer.
56    pub initializer: Option<ConstId>,
57    /// If true, the global is read-only.
58    pub is_constant: bool,
59    /// Public API for `linkage`.
60    pub linkage: Linkage,
61}
62
63/// Linkage kinds matching LLVM IR semantics.
64#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
65pub enum Linkage {
66    /// `Private` variant.
67    Private,
68    /// `Internal` variant.
69    Internal,
70    /// `External` variant.
71    External,
72    /// `Weak` variant.
73    Weak,
74    /// `WeakOdr` variant.
75    WeakOdr,
76    /// `LinkOnce` variant.
77    LinkOnce,
78    /// `LinkOnceOdr` variant.
79    LinkOnceOdr,
80    /// `Common` variant.
81    Common,
82    /// `AvailableExternally` variant.
83    AvailableExternally,
84}
85
86impl Linkage {
87    /// Public API for `as_str`.
88    pub fn as_str(self) -> &'static str {
89        match self {
90            Linkage::Private => "private",
91            Linkage::Internal => "internal",
92            Linkage::External => "",
93            Linkage::Weak => "weak",
94            Linkage::WeakOdr => "weak_odr",
95            Linkage::LinkOnce => "linkonce",
96            Linkage::LinkOnceOdr => "linkonce_odr",
97            Linkage::Common => "common",
98            Linkage::AvailableExternally => "available_externally",
99        }
100    }
101
102    /// Public API for `is_external`.
103    pub fn is_external(self) -> bool {
104        self == Linkage::External
105    }
106}
107
108impl Default for Linkage {
109    fn default() -> Self {
110        Linkage::External
111    }
112}
113
114#[cfg(test)]
115mod tests {
116    use super::*;
117
118    #[test]
119    fn linkage_str() {
120        assert_eq!(Linkage::Private.as_str(), "private");
121        assert_eq!(Linkage::External.as_str(), "");
122        assert_eq!(Linkage::Internal.as_str(), "internal");
123    }
124}