Skip to content

Commit af83069

Browse files
committed
Add bindings to metadata attached to globals
1 parent d71db97 commit af83069

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed

Sources/LLVM/IRGlobal.swift

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,140 @@ extension IRGlobal {
7979
LLVMDeleteGlobal(self.asLLVM())
8080
}
8181
}
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

Comments
 (0)