@@ -79,3 +79,140 @@ extension IRGlobal {
79
79
LLVMDeleteGlobal ( self . asLLVM ( ) )
80
80
}
81
81
}
82
+
83
+ // MARK: Global Metadata
84
+
85
+ extension IRGlobal {
86
+ /// Retrieves all metadata entries attached to this global value.
87
+ public var metadata : AttachedMetadata {
88
+ var count = 0
89
+ let ptr = LLVMGlobalCopyAllMetadata ( self . asLLVM ( ) , & count)
90
+ return AttachedMetadata ( llvm: ptr, bounds: count)
91
+ }
92
+
93
+ /// Sets a metadata attachment, erasing the existing metadata attachment if
94
+ /// it already exists for the given kind.
95
+ ///
96
+ /// - Parameters:
97
+ /// - metadata: The metadata to attach to this global value.
98
+ /// - kind: The kind of metadata to attach.
99
+ public func addMetadata( _ metadata: IRMetadata , kind: UInt32 ) {
100
+ LLVMGlobalSetMetadata ( self . asLLVM ( ) , kind, metadata. asMetadata ( ) )
101
+ }
102
+
103
+ /// Removes all metadata attachments from this value.
104
+ public func removeAllMetadata( ) {
105
+ LLVMGlobalClearMetadata ( self . asLLVM ( ) )
106
+ }
107
+
108
+ /// Erases a metadata attachment of the given kind if it exists.
109
+ ///
110
+ /// - Parameter kind: The kind of the metadata to remove.
111
+ public func eraseAllMetadata( of kind: UInt32 ) {
112
+ LLVMGlobalEraseMetadata ( self . asLLVM ( ) , kind)
113
+ }
114
+ }
115
+
116
+ /// Represents a sequence of metadata entries attached to a global value that
117
+ /// are uniqued by kind.
118
+ public class AttachedMetadata {
119
+ /// Metadata kinds that are known to LLVM.
120
+ public enum PinnedMetadataKind : UInt32 {
121
+ /// "dbg"
122
+ case dbg = 0
123
+ /// "tbaa"
124
+ case tbaa = 1
125
+ /// "prof"
126
+ case prof = 2
127
+ /// "fpmath"
128
+ case fpmath = 3
129
+ /// "range"
130
+ case range = 4
131
+ /// "tbaa.struct"
132
+ case tbaaStruct = 5
133
+ /// "invariant.load"
134
+ case invariantLoad = 6
135
+ /// "alias.scope"
136
+ case alias_scope = 7
137
+ /// "noalias",
138
+ case noalias = 8
139
+ /// "nontemporal"
140
+ case nontemporal = 9
141
+ /// "llvm.mem.parallel_loop_access"
142
+ case memParallelLoopAccess = 10
143
+ /// "nonnull"
144
+ case nonnull = 11
145
+ /// "dereferenceable"
146
+ case dereferenceable = 12
147
+ /// "dereferenceable_or_null"
148
+ case dereferenceable_or_null = 13
149
+ /// "make.implicit"
150
+ case makeImplicit = 14
151
+ /// "unpredictable"
152
+ case unpredictable = 15
153
+ /// "invariant.group"
154
+ case invariantGroup = 16
155
+ /// "align"
156
+ case align = 17
157
+ /// "llvm.loop"
158
+ case loop = 18
159
+ /// "type"
160
+ case type = 19
161
+ /// "section_prefix"
162
+ case sectionPrefix = 20
163
+ /// "absolute_symbol"
164
+ case absoluteSymbol = 21
165
+ /// "associated"
166
+ case associated = 22
167
+ /// "callees"
168
+ case callees = 23
169
+ /// "irr_loop"
170
+ case irrLoop = 24
171
+ /// "llvm.access.group"
172
+ case accessGroup = 25
173
+ // "callback"
174
+ case callback = 26
175
+ }
176
+
177
+ /// Represents an entry in the module flags structure.
178
+ public struct Entry {
179
+ fileprivate let base : AttachedMetadata
180
+ fileprivate let index : UInt32
181
+
182
+ /// The metadata kind associated with this global metadata.
183
+ public var kind : UInt32 {
184
+ return LLVMValueMetadataEntriesGetKind ( self . base. llvm, self . index)
185
+ }
186
+
187
+ /// The metadata value associated with this entry.
188
+ public var metadata : IRMetadata {
189
+ return AnyMetadata ( llvm: LLVMValueMetadataEntriesGetMetadata ( self . base. llvm, self . index) )
190
+ }
191
+ }
192
+
193
+ private let llvm : OpaquePointer ?
194
+ private let bounds : Int
195
+ fileprivate init ( llvm: OpaquePointer ? , bounds: Int ) {
196
+ self . llvm = llvm
197
+ self . bounds = bounds
198
+ }
199
+
200
+ deinit {
201
+ guard let ptr = llvm else { return }
202
+ LLVMDisposeValueMetadataEntries ( ptr)
203
+ }
204
+
205
+ /// Retrieves a flag at the given index.
206
+ ///
207
+ /// - Parameter index: The index to retrieve.
208
+ ///
209
+ /// - Returns: An entry describing the flag at the given index.
210
+ public subscript( _ index: Int ) -> Entry {
211
+ precondition ( index >= 0 && index < self . bounds, " Index out of bounds " )
212
+ return Entry ( base: self , index: UInt32 ( index) )
213
+ }
214
+
215
+ public var count : Int {
216
+ return self . bounds
217
+ }
218
+ }
0 commit comments