@@ -230,6 +230,29 @@ public final class Module: CustomStringConvertible {
230
230
}
231
231
}
232
232
233
+ /// Retrieves the sequence of aliases that make up this module.
234
+ public var aliases : AnySequence < Alias > {
235
+ var current = firstAlias
236
+ return AnySequence< Alias> {
237
+ return AnyIterator< Alias> {
238
+ defer { current = current? . next ( ) }
239
+ return current
240
+ }
241
+ }
242
+ }
243
+
244
+ /// Retrieves the first alias in this module, if there are any aliases.
245
+ public var firstAlias : Alias ? {
246
+ guard let fn = LLVMGetFirstGlobalAlias ( llvm) else { return nil }
247
+ return Alias ( llvm: fn)
248
+ }
249
+
250
+ /// Retrieves the last alias in this module, if there are any aliases.
251
+ public var lastAlias : Alias ? {
252
+ guard let fn = LLVMGetLastGlobalAlias ( llvm) else { return nil }
253
+ return Alias ( llvm: fn)
254
+ }
255
+
233
256
/// The current debug metadata version number.
234
257
public static var debugMetadataVersion : UInt32 {
235
258
return LLVMDebugMetadataVersion ( ) ;
@@ -301,12 +324,24 @@ extension Module {
301
324
/// - parameter name: The name of the function to create.
302
325
///
303
326
/// - returns: A representation of the newly created function with the given
304
- /// name or nil if such a representation could not be created.
327
+ /// name or nil if such a representation could not be created.
305
328
public func function( named name: String ) -> Function ? {
306
329
guard let fn = LLVMGetNamedFunction ( llvm, name) else { return nil }
307
330
return Function ( llvm: fn)
308
331
}
309
332
333
+ /// Searches for and retrieves an alias with the given name in this module
334
+ /// if that name references an existing alias.
335
+ ///
336
+ /// - parameter name: The name of the alias to search for.
337
+ ///
338
+ /// - returns: A representation of an alias with the given
339
+ /// name or nil if no such named alias exists.
340
+ public func alias( named name: String ) -> Alias ? {
341
+ guard let alias = LLVMGetNamedGlobalAlias ( llvm, name, name. count) else { return nil }
342
+ return Alias ( llvm: alias)
343
+ }
344
+
310
345
/// Searches for and retrieves a comdat section with the given name in this
311
346
/// module. If none is found, one with that name is created and returned.
312
347
///
@@ -397,6 +432,159 @@ extension Module {
397
432
}
398
433
}
399
434
435
+ // MARK: Module Flags
436
+
437
+ extension Module {
438
+ /// Represents flags that describe information about the module for use by
439
+ /// an external entity e.g. the dynamic linker.
440
+ ///
441
+ /// - Warning: Module flags are not a general runtime metadata infrastructure,
442
+ /// and may be stripped by LLVM. As of the current release, LLVM hardcodes
443
+ /// support for object-file emission of module flags related to
444
+ /// Objective-C.
445
+ public class Flags {
446
+ /// Enumerates the supported behaviors for resolving collisions when two
447
+ /// module flags share the same key. These collisions can occur when the
448
+ /// different flags are inserted under the same key, or when modules
449
+ /// containing flags under the same key are merged.
450
+ public enum Behavior {
451
+ /// Emits an error if two values disagree, otherwise the resulting value
452
+ /// is that of the operands.
453
+ case error
454
+ /// Emits a warning if two values disagree. The result value will be the
455
+ /// operand for the flag from the first module being linked.
456
+ case warning
457
+ /// Adds a requirement that another module flag be present and have a
458
+ /// specified value after linking is performed. The value must be a
459
+ /// metadata pair, where the first element of the pair is the ID of the
460
+ /// module flag to be restricted, and the second element of the pair is
461
+ /// the value the module flag should be restricted to. This behavior can
462
+ /// be used to restrict the allowable results (via triggering of an error)
463
+ /// of linking IDs with the **Override** behavior.
464
+ case require
465
+ /// Uses the specified value, regardless of the behavior or value of the
466
+ /// other module. If both modules specify **Override**, but the values
467
+ /// differ, an error will be emitted.
468
+ case override
469
+ /// Appends the two values, which are required to be metadata nodes.
470
+ case append
471
+ /// Appends the two values, which are required to be metadata
472
+ /// nodes. However, duplicate entries in the second list are dropped
473
+ /// during the append operation.
474
+ case appendUnique
475
+
476
+ fileprivate init ( raw: LLVMModuleFlagBehavior ) {
477
+ switch raw {
478
+ case LLVMModuleFlagBehaviorError:
479
+ self = . error
480
+ case LLVMModuleFlagBehaviorWarning:
481
+ self = . warning
482
+ case LLVMModuleFlagBehaviorRequire:
483
+ self = . require
484
+ case LLVMModuleFlagBehaviorOverride:
485
+ self = . override
486
+ case LLVMModuleFlagBehaviorAppend:
487
+ self = . append
488
+ case LLVMModuleFlagBehaviorAppendUnique:
489
+ self = . appendUnique
490
+ default :
491
+ fatalError ( " Unknown behavior kind " )
492
+ }
493
+ }
494
+
495
+ fileprivate static let behaviorMapping : [ Behavior : LLVMModuleFlagBehavior ] = [
496
+ . error: LLVMModuleFlagBehaviorError,
497
+ . warning: LLVMModuleFlagBehaviorWarning,
498
+ . require: LLVMModuleFlagBehaviorRequire,
499
+ . override: LLVMModuleFlagBehaviorOverride,
500
+ . append: LLVMModuleFlagBehaviorAppend,
501
+ . appendUnique: LLVMModuleFlagBehaviorAppendUnique,
502
+ ]
503
+ }
504
+
505
+ /// Represents an entry in the module flags structure.
506
+ public struct Entry {
507
+ fileprivate let base : Flags
508
+ fileprivate let index : UInt32
509
+
510
+ /// The conflict behavior of this flag.
511
+ public var behavior : Behavior {
512
+ let raw = LLVMModuleFlagEntriesGetFlagBehavior ( self . base. llvm, self . index)
513
+ return Behavior ( raw: raw)
514
+ }
515
+
516
+ /// The key this flag was inserted with.
517
+ public var key : String {
518
+ var count = 0
519
+ guard let key = LLVMModuleFlagEntriesGetKey ( self . base. llvm, self . index, & count) else { return " " }
520
+ return String ( cString: key)
521
+ }
522
+
523
+ /// The metadata value associated with this flag.
524
+ public var metadata : IRMetadata {
525
+ return AnyMetadata ( llvm: LLVMModuleFlagEntriesGetMetadata ( self . base. llvm, self . index) )
526
+ }
527
+ }
528
+
529
+ private let llvm : OpaquePointer ?
530
+ private let bounds : Int
531
+ fileprivate init ( llvm: OpaquePointer ? , bounds: Int ) {
532
+ self . llvm = llvm
533
+ self . bounds = bounds
534
+ }
535
+
536
+ deinit {
537
+ guard let ptr = llvm else { return }
538
+ LLVMDisposeModuleFlagsMetadata ( ptr)
539
+ }
540
+
541
+ /// Retrieves a flag at the given index.
542
+ ///
543
+ /// - Parameter index: The index to retrieve.
544
+ ///
545
+ /// - Returns: An entry describing the flag at the given index.
546
+ public subscript( _ index: Int ) -> Entry {
547
+ precondition ( index >= 0 && index < self . bounds, " Index out of bounds " )
548
+ return Entry ( base: self , index: UInt32 ( index) )
549
+ }
550
+
551
+ public var count : Int {
552
+ return self . bounds
553
+ }
554
+ }
555
+
556
+ /// Add a module-level flag to the module-level flags metadata.
557
+ ///
558
+ /// - Parameters:
559
+ /// - name: The key for this flag.
560
+ /// - value: The metadata node to insert as the value for this flag.
561
+ /// - behavior: The resolution strategy to apply should the key for this
562
+ /// flag conflict with an existing flag.
563
+ public func addFlag( named name: String , value: IRMetadata , behavior: Flags . Behavior ) {
564
+ let raw = Flags . Behavior. behaviorMapping [ behavior] !
565
+ LLVMAddModuleFlag ( llvm, raw, name, name. count, value. asMetadata ( ) )
566
+ }
567
+
568
+ /// A convenience for inserting constant values as module-level flags.
569
+ ///
570
+ /// - Parameters:
571
+ /// - name: The key for this flag.
572
+ /// - value: The constant value to insert as the metadata for this flag.
573
+ /// - behavior: The resolution strategy to apply should the key for this
574
+ /// flag conflict with an existing flag.
575
+ public func addFlag( named name: String , constant: IRConstant , behavior: Flags . Behavior ) {
576
+ let raw = Flags . Behavior. behaviorMapping [ behavior] !
577
+ LLVMAddModuleFlag ( llvm, raw, name, name. count, LLVMValueAsMetadata ( constant. asLLVM ( ) ) )
578
+ }
579
+
580
+ /// Retrieves the module-level flags, if they exist.
581
+ public var flags : Flags ? {
582
+ var len = 0
583
+ guard let raw = LLVMCopyModuleFlagsMetadata ( llvm, & len) else { return nil }
584
+ return Flags ( llvm: raw, bounds: len)
585
+ }
586
+ }
587
+
400
588
extension Bool {
401
589
internal var llvm : LLVMBool {
402
590
return self ? 1 : 0
0 commit comments