@@ -9,9 +9,28 @@ public final class Module: ModuleRef {
9
9
/// Retrieves the underlying LLVM value object.
10
10
public var moduleRef : LLVMModuleRef { llvm }
11
11
12
+ /// Inline Asm Dialect
12
13
public enum InlineAsmDialect {
13
14
case att
14
15
case intel
16
+
17
+ /// Init inline asm dialect from LLVM
18
+ public init ( llvm: LLVMInlineAsmDialect ) {
19
+ switch llvm {
20
+ case LLVMInlineAsmDialectATT: self = . att
21
+ case LLVMInlineAsmDialectIntel: self = . intel
22
+ default :
23
+ fatalError ( " Unknown behavior kind " )
24
+ }
25
+ }
26
+
27
+ /// Get LLVM representation
28
+ public var llvm : LLVMInlineAsmDialect {
29
+ switch self {
30
+ case . att: LLVMInlineAsmDialectATT
31
+ case . intel: LLVMInlineAsmDialectIntel
32
+ }
33
+ }
15
34
}
16
35
17
36
/// Named Metadata Node
@@ -105,53 +124,97 @@ public final class Module: ModuleRef {
105
124
fatalError ( " Unknown behavior kind " )
106
125
}
107
126
}
127
+
128
+ /// Converts ModuleFlagBehavior to LLVMModuleFlagBehavior
129
+ public var moduleFlagBehavior : LLVMModuleFlagBehavior {
130
+ switch self {
131
+ case . error:
132
+ LLVMModuleFlagBehaviorError
133
+ case . warning:
134
+ LLVMModuleFlagBehaviorWarning
135
+ case . require:
136
+ LLVMModuleFlagBehaviorRequire
137
+ case . override:
138
+ LLVMModuleFlagBehaviorOverride
139
+ case . append:
140
+ LLVMModuleFlagBehaviorAppend
141
+ case . appendUnique:
142
+ LLVMModuleFlagBehaviorAppendUnique
143
+ }
144
+ }
108
145
}
109
146
110
147
class Metadata : MetadataRef {
111
- private let llvm : LLVMMetadataRef
112
- public var metadataRef : LLVMMetadataRef {
113
- llvm }
114
- public init ( llvm: LLVMMetadataRef ) {
148
+ private let llvm : LLVMMetadataRef
149
+ public var metadataRef : LLVMMetadataRef {
150
+ llvm
151
+ }
152
+
153
+ public init ( llvm: LLVMMetadataRef ) {
115
154
self . llvm = llvm
116
155
}
117
156
}
118
157
158
+ /// Represents the possible errors that can be thrown while interacting with a
159
+ /// `Module` object.
160
+ public enum ModuleError : Error , CustomStringConvertible {
161
+ /// Thrown when a module does not pass the module verification process.
162
+ /// Includes the reason the module did not pass verification.
163
+ case didNotPassVerification( String )
164
+ /// Thrown when a module cannot be printed at a given path. Provides the
165
+ /// erroneous path and a deeper reason why printing to that path failed.
166
+ case couldNotPrint( path: String , error: String )
167
+ /// Thrown when a module cannot emit bitcode because it contains erroneous
168
+ /// declarations.
169
+ case couldNotEmitBitCode( path: String )
170
+
171
+ public var description : String {
172
+ switch self {
173
+ case let . didNotPassVerification( message) :
174
+ " module did not pass verification: \( message) "
175
+ case let . couldNotPrint( path, error) :
176
+ " could not print to file \( path) : \( error) "
177
+ case let . couldNotEmitBitCode( path) :
178
+ " could not emit bitcode to file \( path) for an unknown reason "
179
+ }
180
+ }
181
+ }
182
+
119
183
public class ModuleFlagEntry {
120
184
private let llvm : OpaquePointer ?
121
185
private let bounds : Int
122
186
123
- public init ( llvm: OpaquePointer ? , bounds: Int ) {
187
+ public init ( llvm: OpaquePointer ? , bounds: Int ) {
124
188
self . llvm = llvm
125
189
self . bounds = bounds
126
190
}
127
191
128
192
/// Get Metadata flags etries count
129
- public var count : Int { self . bounds }
193
+ public var count : Int { bounds }
130
194
131
- /// Returns the flag behavior for a module flag entry at a specific index.
195
+ /// Returns the flag behavior for a module flag entry at a specific index.
132
196
public func getFlagBehavior( at index: UInt32 ) -> ModuleFlagBehavior {
133
197
let bh = LLVMModuleFlagEntriesGetFlagBehavior ( llvm, index)
134
198
return ModuleFlagBehavior ( raw: bh)
135
199
}
136
200
137
- /// Returns the key for a module flag entry at a specific index.
201
+ /// Returns the key for a module flag entry at a specific index.
138
202
public func getKey( at index: UInt32 ) -> String {
139
- var length : Int = 0
203
+ var length = 0
140
204
let keyPointer = LLVMModuleFlagEntriesGetKey ( llvm, index, & length)
141
205
return String ( cString: keyPointer!)
142
-
143
206
}
144
207
145
- /// Returns the metadata for a module flag entry at a specific index.
208
+ /// Returns the metadata for a module flag entry at a specific index.
146
209
public func getMetadata( at index: UInt32 ) -> MetadataRef {
147
210
let metadata = LLVMModuleFlagEntriesGetMetadata ( llvm, index) !
148
211
return Metadata ( llvm: metadata)
149
212
}
150
213
151
214
/// Deinitialize this value and dispose of its resources.
152
215
deinit {
153
- guard let ptr = llvm else { return }
154
- LLVMDisposeModuleFlagsMetadata ( ptr)
216
+ guard let ptr = llvm else { return }
217
+ LLVMDisposeModuleFlagsMetadata ( ptr)
155
218
}
156
219
}
157
220
@@ -190,10 +253,10 @@ public final class Module: ModuleRef {
190
253
/// Get and Set the identifier of a module.
191
254
public var moduleIdentifier : String {
192
255
get {
193
- self . getModuleIdentifier
256
+ getModuleIdentifier
194
257
}
195
258
set {
196
- self . setModuleIdentifier ( identifier: newValue)
259
+ setModuleIdentifier ( identifier: newValue)
197
260
}
198
261
}
199
262
@@ -214,14 +277,14 @@ public final class Module: ModuleRef {
214
277
/// Get and Set the original source file name of a module to a string Name
215
278
public var sourceFileName : String {
216
279
get {
217
- self . getSourceFileName!
280
+ getSourceFileName!
218
281
}
219
282
set {
220
- self . setSourceFileName ( fileName: newValue)
283
+ setSourceFileName ( fileName: newValue)
221
284
}
222
285
}
223
286
224
- ///Set the original source file name of a module to a string Name
287
+ /// Set the original source file name of a module to a string Name
225
288
public func setSourceFileName( fileName: String ) {
226
289
fileName. withCString { cString in
227
290
LLVMSetSourceFileName ( llvm, cString, fileName. utf8. count)
@@ -230,7 +293,7 @@ public final class Module: ModuleRef {
230
293
231
294
/// Obtain the module's original source file name.
232
295
public var getSourceFileName : String ? {
233
- var length : Int = 0
296
+ var length = 0
234
297
guard let cString = LLVMGetSourceFileName ( llvm, & length) else {
235
298
return nil
236
299
}
@@ -252,8 +315,7 @@ public final class Module: ModuleRef {
252
315
return String ( cString: cString)
253
316
}
254
317
255
-
256
- /// Obtain the target triple for a module.
318
+ /// Obtain the target triple for a module.
257
319
func getTargetTriple( ) -> String {
258
320
guard let targetTriplePointer = LLVMGetTarget ( llvm) else {
259
321
return " "
@@ -268,14 +330,153 @@ public final class Module: ModuleRef {
268
330
}
269
331
}
270
332
271
- /// Returns the module flags as an array of flag-key-value triples. The caller
272
- /// is responsible for freeing this array by calling
273
- /// `LLVMDisposeModuleFlagsMetadata`.
333
+ /// Returns the module flags as an array of flag-key-value triples. The caller
334
+ /// is responsible for freeing this array by calling
335
+ /// `LLVMDisposeModuleFlagsMetadata`.
274
336
public func copyModuleFlagsMetadata( ) -> ModuleFlagEntry ? {
275
- var length : Int = 0
276
- guard let flagsPointer = LLVMCopyModuleFlagsMetadata ( llvm, & length) else { return nil }
337
+ var length = 0
338
+ guard let flagsPointer = LLVMCopyModuleFlagsMetadata ( llvm, & length) else { return nil }
339
+
340
+ return ModuleFlagEntry ( llvm: flagsPointer, bounds: length)
341
+ }
342
+
343
+ /// Add a module-level flag to the module-level flags metadata if it doesn't
344
+ /// already exist.
345
+ func getModuleFlag( key: String ) -> MetadataRef {
346
+ let keyLen = key. utf8. count
347
+ let metadata = key. withCString { keyPtr in
348
+ LLVMGetModuleFlag ( llvm, keyPtr, keyLen) !
349
+ }
350
+ return Metadata ( llvm: metadata)
351
+ }
352
+
353
+ /// Add a module-level flag to the module-level flags metadata if it doesn't
354
+ /// already exist.
355
+ func addModuleFlag( behavior: ModuleFlagBehavior , key: String , value: MetadataRef ) {
356
+ let keyLen = key. utf8. count
357
+ key. withCString { keyPtr in
358
+ LLVMAddModuleFlag ( llvm, behavior. moduleFlagBehavior, keyPtr, keyLen, value. metadataRef)
359
+ }
360
+ }
361
+
362
+ /// Dump a representation of a module to stderr.
363
+ func dump_module( ) {
364
+ LLVMDumpModule ( llvm)
365
+ }
366
+
367
+ /// Print a representation of a module to a file. The ErrorMessage needs to be
368
+ /// disposed with `LLVMDisposeMessage`. Returns 0 on success, 1 otherwise.
369
+ func printToFile( filename: String ) throws {
370
+ var errorMessage : UnsafeMutablePointer < CChar > ?
371
+
372
+ let result = filename. withCString { filenamePtr in
373
+ LLVMPrintModuleToFile ( llvm, filenamePtr, & errorMessage)
374
+ }
375
+
376
+ if result != 0 , let errorMessage {
377
+ defer { LLVMDisposeMessage ( errorMessage) }
378
+ let errorString = String ( cString: errorMessage)
379
+ throw ModuleError . couldNotPrint ( path: filename, error: errorString)
380
+ }
381
+ }
382
+
383
+ /// Return a string representation of the module. Use
384
+ /// `LLVMDisposeMessage` to free the string.
385
+ func printToString( ) -> String {
386
+ guard let moduleString = LLVMPrintModuleToString ( llvm) else {
387
+ return " "
388
+ }
389
+ defer { LLVMDisposeMessage ( moduleString) }
390
+ return String ( cString: moduleString)
391
+ }
392
+
393
+ /// ==========================
394
+ /// Get inline assembly for a module.
395
+ public func getModuleInlineAsm( module _: LLVMModuleRef ) -> String {
396
+ var length = 0
397
+ let cString = LLVMGetModuleInlineAsm ( llvm, & length)
398
+ return String ( cString: cString!)
399
+ }
400
+
401
+ /// Set inline assembly for a module.
402
+ public func setModuleInlineAsm( asm: String ) {
403
+ asm. withCString { cString in
404
+ LLVMSetModuleInlineAsm2 ( llvm, cString, asm. utf8. count)
405
+ }
406
+ }
407
+
408
+ /// Append inline assembly to a module.
409
+ public func appendModuleInlineAsm( asm: String ) {
410
+ asm. withCString { cString in
411
+ LLVMAppendModuleInlineAsm ( llvm, cString, asm. utf8. count)
412
+ }
413
+ }
414
+
415
+ /// Create the specified uniqued inline asm string.
416
+ public func getInlineAsm( type: TypeRef , asmString: String , constraints: String ,
417
+ hasSideEffects: Bool , isAlignStack: Bool ,
418
+ dialect: InlineAsmDialect , canThrow: Bool ) -> ValueRef
419
+ {
420
+ let inlineAsm = asmString. withCString { asmCString in
421
+ constraints. withCString { constraintsCString in
422
+ LLVMGetInlineAsm ( type. typeRef, asmCString, asmString. utf8. count, constraintsCString, constraints. utf8. count, hasSideEffects. llvm, isAlignStack. llvm, dialect. llvm, canThrow. llvm)
423
+ }
424
+ }
425
+ return Value ( llvm: inlineAsm!)
426
+ }
427
+
428
+ /// Get the template string used for an inline assembly snippet
429
+ public func getInlineAsmAsmString( inlineAsmVal: ValueRef ) -> String {
430
+ var length = 0
431
+ let cString = LLVMGetInlineAsmAsmString ( inlineAsmVal. valueRef, & length)
432
+ return String ( cString: cString!)
433
+ }
434
+
435
+ /// Get the raw constraint string for an inline assembly snippet
436
+ public func getInlineAsmConstraintString( inlineAsmVal: ValueRef ) -> String {
437
+ var length = 0
438
+ let cString = LLVMGetInlineAsmConstraintString ( inlineAsmVal. valueRef, & length)
439
+ return String ( cString: cString!)
440
+ }
441
+
442
+ /// Get the dialect used by the inline asm snippet
443
+ public func getInlineAsmDialect( inlineAsmVal: ValueRef ) -> InlineAsmDialect {
444
+ let dialect = LLVMGetInlineAsmDialect ( inlineAsmVal. valueRef)
445
+ return InlineAsmDialect ( llvm: dialect)
446
+ }
447
+
448
+ /// Get the function type of the inline assembly snippet. The same type that
449
+ /// was passed into LLVMGetInlineAsm originally
450
+ public func getInlineAsmFunctionType( inlineAsmVal: ValueRef ) -> TypeRef {
451
+ let typeRef = LLVMGetInlineAsmFunctionType ( inlineAsmVal. valueRef)
452
+ return Types ( llvm: typeRef!)
453
+ }
454
+
455
+ /// Get if the inline asm snippet has side effects
456
+ public func inlineAsmHasSideEffects( inlineAsmVal: ValueRef ) -> Bool {
457
+ LLVMGetInlineAsmHasSideEffects ( inlineAsmVal. valueRef) != 0
458
+ }
459
+
460
+ /// Get if the inline asm snippet needs an aligned stack
461
+ public func inlineAsmNeedsAlignedStack( inlineAsmVal: ValueRef ) -> Bool {
462
+ LLVMGetInlineAsmNeedsAlignedStack ( inlineAsmVal. valueRef) != 0
463
+ }
464
+
465
+ /// Get if the inline asm snippet may unwind the stack
466
+ public func inlineAsmCanUnwind( inlineAsmVal: ValueRef ) -> Bool {
467
+ LLVMGetInlineAsmCanUnwind ( inlineAsmVal. valueRef) != 0
468
+ }
469
+
470
+ /// Obtain the context to which this module is associated.
471
+ func getModuleContext( ) -> ContextRef {
472
+ let context = LLVMGetModuleContext ( llvm)
473
+ return Context ( llvm: context!)
474
+ }
277
475
278
- return ModuleFlagEntry ( llvm: flagsPointer, bounds: length)
476
+ /// Obtain an iterator to the first NamedMDNode in a Module.
477
+ func getFirstNamedMetadata( ) -> NamedMetadataNodeRef {
478
+ let namedMD = LLVMGetFirstNamedMetadata ( llvm)
479
+ return NamedMetadataNode ( llvm: namedMD!)
279
480
}
280
481
281
482
/// Destroy a module instance.
0 commit comments