github.com/llir/llvm@v0.3.6/ir/metadata/metadata.go (about) 1 // Package metadata provides access to LLVM IR metadata. 2 package metadata 3 4 import ( 5 "fmt" 6 "strconv" 7 "strings" 8 9 "github.com/llir/llvm/internal/enc" 10 "github.com/llir/llvm/ir/types" 11 "github.com/llir/llvm/ir/value" 12 ) 13 14 // TODO: remove Null if possible. 15 16 // Convenience literals. 17 var ( 18 // Null metadata literal. 19 Null = &NullLit{} 20 ) 21 22 // ~~~ [ Named metadata definition ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 23 24 // NamedDef is a named metadata definition. 25 type NamedDef struct { 26 // Metadata definition name (without '!' prefix). 27 Name string 28 // Metadata definition nodes. 29 Nodes []Node 30 } 31 32 // Ident returns the identifier associated with the named metadata definition. 33 func (md *NamedDef) Ident() string { 34 return enc.MetadataName(md.Name) 35 } 36 37 // LLString returns the LLVM syntax representation of the named metadata 38 // definition. 39 // 40 // Name=MetadataName '=' '!' '{' MDNodes=(MetadataNode separator ',')* '}' 41 func (md *NamedDef) LLString() string { 42 buf := &strings.Builder{} 43 buf.WriteString("!{") 44 for i, node := range md.Nodes { 45 if i != 0 { 46 buf.WriteString(", ") 47 } 48 buf.WriteString(node.Ident()) 49 } 50 buf.WriteString("}") 51 return buf.String() 52 } 53 54 // === [ Metadata nodes and metadata strings ] ================================= 55 56 // --- [ Metadata tuple ] ------------------------------------------------------ 57 58 // Tuple is a metadata node tuple. 59 type Tuple struct { 60 // Metadata ID associated with the metadata tuple; -1 if not present. 61 MetadataID 62 // (optional) Distinct. 63 Distinct bool 64 65 // Metadata tuple fields. 66 Fields []Field 67 } 68 69 // String returns the LLVM syntax representation of the metadata tuple. 70 func (md *Tuple) String() string { 71 return md.Ident() 72 } 73 74 // Ident returns the identifier associated with the metadata tuple. 75 func (md *Tuple) Ident() string { 76 if md == nil { 77 return "null" 78 } 79 if md.MetadataID != -1 { 80 return md.MetadataID.Ident() 81 } 82 return md.LLString() 83 } 84 85 // LLString returns the LLVM syntax representation of the metadata tuple. 86 // 87 // '!' MDFields 88 func (md *Tuple) LLString() string { 89 buf := &strings.Builder{} 90 if md.Distinct { 91 buf.WriteString("distinct ") 92 } 93 buf.WriteString("!{") 94 for i, field := range md.Fields { 95 if i != 0 { 96 buf.WriteString(", ") 97 } 98 buf.WriteString(field.String()) 99 } 100 buf.WriteString("}") 101 return buf.String() 102 } 103 104 // SetDistinct specifies whether the metadata definition is dinstict. 105 func (md *Tuple) SetDistinct(distinct bool) { 106 md.Distinct = distinct 107 } 108 109 // --- [ Metadata value ] ------------------------------------------------------ 110 111 // A Value is a metadata value. 112 type Value struct { 113 // Metadata value. 114 Value Metadata 115 } 116 117 // String returns the LLVM syntax representation of the metadata value as a 118 // type-value pair. 119 func (md *Value) String() string { 120 return fmt.Sprintf("%s %s", md.Type(), md.Ident()) 121 } 122 123 // Type returns the type of the metadata value. 124 func (md *Value) Type() types.Type { 125 return types.Metadata 126 } 127 128 // Ident returns the identifier associated with the metadata value. 129 func (md *Value) Ident() string { 130 return md.Value.String() 131 } 132 133 // --- [ Metadata string ] ----------------------------------------------------- 134 135 // String is a metadata string. 136 type String struct { 137 // Metadata string value. 138 Value string 139 } 140 141 // String returns the LLVM syntax representation of the metadata string. 142 func (md *String) String() string { 143 // '!' Val=StringLit 144 return fmt.Sprintf("!%s", quote(md.Value)) 145 } 146 147 // --- [ Metadata attachment ] ------------------------------------------------- 148 149 // Attachment is a metadata attachment. 150 type Attachment struct { 151 // Metadata attachment name (without '!' prefix); e.g. !dbg. 152 Name string 153 // Metadata attachment node. 154 Node MDNode 155 } 156 157 // String returns the string representation of the metadata attachment. 158 func (m *Attachment) String() string { 159 // Name=MetadataName MDNode 160 return fmt.Sprintf("%s %s", enc.MetadataName(m.Name), m.Node.Ident()) 161 } 162 163 // --- [ Integer literals ] ----------------------------------------------------- 164 165 // IntLit is an integer literal. 166 type IntLit int64 167 168 // String returns the LLVM syntax representation of the integer literal. 169 func (i IntLit) String() string { 170 return strconv.FormatInt(int64(i), 10) 171 } 172 173 // UintLit is an unsigned integer literal. 174 type UintLit uint64 175 176 // String returns the LLVM syntax representation of the unsigned integer literal. 177 func (i UintLit) String() string { 178 return strconv.FormatUint(uint64(i), 10) 179 } 180 181 // --- [ Null literal ] -------------------------------------------------------- 182 183 // TODO: remove NullLit if possible. 184 185 // NullLit is a metadata null literal. 186 type NullLit struct{} 187 188 // String returns the LLVM syntax representation of the null literal. 189 func (i *NullLit) String() string { 190 return "null" 191 } 192 193 // --- [ Metadata identifiers ] ------------------------------------------------ 194 195 // ~~~ [ Metadata ID ] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 196 197 // MetadataID is a metadata ID, as used by metadata definitions. 198 type MetadataID int64 199 200 // Ident returns the identifier associated with the metadata ID. 201 func (i MetadataID) Ident() string { 202 return enc.MetadataID(int64(i)) 203 } 204 205 // ID returns the ID of the metadata ID. 206 func (i MetadataID) ID() int64 { 207 return int64(i) 208 } 209 210 // SetID sets the ID of the metadata ID. 211 func (i *MetadataID) SetID(id int64) { 212 *i = MetadataID(id) 213 } 214 215 // --- [ DIArgList ] ----------------------------------------------------------- 216 217 // DIArgList is a metadata node containing a list of function local values. 218 type DIArgList struct { 219 Fields []value.Value 220 } 221 222 // String returns the LLVM syntax representation of the DIArgList metadata 223 // node. 224 func (md *DIArgList) String() string { 225 return md.LLString() 226 } 227 228 // LLString returns the LLVM syntax representation of the DIArgList metadata 229 // node. 230 // 231 // '!DIArgList' '(' Fields=(DIArgListField separator ',')* ')' 232 func (md *DIArgList) LLString() string { 233 buf := &strings.Builder{} 234 buf.WriteString("!DIArgList(") 235 for i, field := range md.Fields { 236 if i != 0 { 237 buf.WriteString(", ") 238 } 239 buf.WriteString(field.String()) 240 } 241 buf.WriteString(")") 242 return buf.String() 243 }