|
| 1 | +//===--- Linkage.swift ----------------------------------------------------===// |
| 2 | +// |
| 3 | +// This source file is part of the Swift.org open source project |
| 4 | +// |
| 5 | +// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors |
| 6 | +// Licensed under Apache License v2.0 with Runtime Library Exception |
| 7 | +// |
| 8 | +// See https://swift.org/LICENSE.txt for license information |
| 9 | +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
| 10 | +// |
| 11 | +//===----------------------------------------------------------------------===// |
| 12 | + |
| 13 | +import SILBridging |
| 14 | + |
| 15 | +public enum Linkage: CustomStringConvertible { |
| 16 | + /// This object definition is visible to multiple Swift modules (and |
| 17 | + /// thus potentially across linkage-unit boundaries). There are no |
| 18 | + /// other object definitions with this name in the program. |
| 19 | + /// |
| 20 | + /// Public functions must be definitions, i.e. must have a body, except the |
| 21 | + /// body is emitted by clang. |
| 22 | + case `public` |
| 23 | + |
| 24 | + /// This is a special linkage used for symbols which are treated |
| 25 | + /// as public for the purposes of SIL serialization and optimization, |
| 26 | + /// but do not have public entry points in the generated binary. |
| 27 | + /// |
| 28 | + /// This linkage is used for @_alwaysEmitIntoClient functions. |
| 29 | + /// |
| 30 | + /// There is no external variant of this linkage, because from other |
| 31 | + /// translation units in the same module, this behaves identically |
| 32 | + /// to the HiddenExternal linkage. |
| 33 | + /// |
| 34 | + /// When deserialized, such declarations receive Shared linkage. |
| 35 | + /// |
| 36 | + /// PublicNonABI functions must be definitions. |
| 37 | + case publicNonABI |
| 38 | + |
| 39 | + /// Same as \c Public, except the definition is visible within a package |
| 40 | + /// of modules. |
| 41 | + case package |
| 42 | + |
| 43 | + /// Similar to \c PublicNonABI, this definition is used for symbols treated |
| 44 | + /// as package but do not have package entry points in the generated binary. |
| 45 | + /// It's used for default argument expressions and `@_alwaysEmitIntoClient`. |
| 46 | + /// When deserialized, this will become \c Shared linkage. |
| 47 | + case packageNonABI |
| 48 | + |
| 49 | + /// This object definition is visible only to the current Swift |
| 50 | + /// module (and thus should not be visible across linkage-unit |
| 51 | + /// boundaries). There are no other object definitions with this |
| 52 | + /// name in the module. |
| 53 | + /// |
| 54 | + /// Hidden functions must be definitions, i.e. must have a body, except the |
| 55 | + /// body is emitted by clang. |
| 56 | + case hidden |
| 57 | + |
| 58 | + /// This object definition is visible only within a single Swift |
| 59 | + /// module. There may be other object definitions with this name in |
| 60 | + /// the module; those definitions are all guaranteed to be |
| 61 | + /// semantically equivalent to this one. |
| 62 | + /// |
| 63 | + /// This linkage is used e.g. for thunks and for specialized functions. |
| 64 | + /// |
| 65 | + /// Shared functions must be definitions, i.e. must have a body, except the |
| 66 | + /// body is emitted by clang. |
| 67 | + case shared |
| 68 | + |
| 69 | + /// This object definition is visible only within a single Swift |
| 70 | + /// file. |
| 71 | + /// |
| 72 | + /// Private functions must be definitions, i.e. must have a body, except the |
| 73 | + /// body is emitted by clang. |
| 74 | + case `private` |
| 75 | + |
| 76 | + /// A Public definition with the same name as this object will be |
| 77 | + /// available to the current Swift module at runtime. If this |
| 78 | + /// object is a definition, it is semantically equivalent to that |
| 79 | + /// definition. |
| 80 | + case publicExternal |
| 81 | + |
| 82 | + /// Similar to \c PublicExternal. |
| 83 | + /// Used to reference a \c Package definition in a different module |
| 84 | + /// within a package. |
| 85 | + case packageExternal |
| 86 | + |
| 87 | + /// A Public or Hidden definition with the same name as this object |
| 88 | + /// will be defined by the current Swift module at runtime. |
| 89 | + /// |
| 90 | + /// This linkage is only used for non-whole-module compilations to refer to |
| 91 | + /// functions in other files of the same module. |
| 92 | + case hiddenExternal |
| 93 | + |
| 94 | + public var isExternal: Bool { |
| 95 | + switch self { |
| 96 | + case .public, |
| 97 | + .publicNonABI, |
| 98 | + .package, |
| 99 | + .packageNonABI, |
| 100 | + .hidden, |
| 101 | + .shared, |
| 102 | + .private: |
| 103 | + return false |
| 104 | + case .packageExternal, |
| 105 | + .publicExternal, |
| 106 | + .hiddenExternal: |
| 107 | + return true |
| 108 | + } |
| 109 | + |
| 110 | + } |
| 111 | + |
| 112 | + public var description: String { |
| 113 | + switch self { |
| 114 | + case .public: return "public" |
| 115 | + case .publicNonABI: return "publicNonABI" |
| 116 | + case .package: return "package" |
| 117 | + case .packageNonABI: return "packageNonABI" |
| 118 | + case .hidden: return "hidden" |
| 119 | + case .shared: return "shared" |
| 120 | + case .private: return "private" |
| 121 | + case .packageExternal: return "packageExternal" |
| 122 | + case .publicExternal: return "publicExternal" |
| 123 | + case .hiddenExternal: return "hiddenExternal" |
| 124 | + } |
| 125 | + } |
| 126 | +} |
| 127 | + |
| 128 | +// Bridging utilities |
| 129 | + |
| 130 | +extension BridgedLinkage { |
| 131 | + var linkage: Linkage { |
| 132 | + switch self { |
| 133 | + case .Public: return .public |
| 134 | + case .PublicNonABI: return .publicNonABI |
| 135 | + case .Package: return .package |
| 136 | + case .PackageNonABI: return .packageNonABI |
| 137 | + case .Hidden: return .hidden |
| 138 | + case .Shared: return .shared |
| 139 | + case .Private: return .private |
| 140 | + case .PublicExternal: return .publicExternal |
| 141 | + case .PackageExternal: return .packageExternal |
| 142 | + case .HiddenExternal: return .hiddenExternal |
| 143 | + default: |
| 144 | + fatalError("unsupported argument convention") |
| 145 | + } |
| 146 | + } |
| 147 | +} |
| 148 | + |
| 149 | +extension Linkage { |
| 150 | + public var bridged: BridgedLinkage { |
| 151 | + switch self { |
| 152 | + case .public: return .Public |
| 153 | + case .publicNonABI: return .PublicNonABI |
| 154 | + case .package: return .Package |
| 155 | + case .packageNonABI: return .PackageNonABI |
| 156 | + case .hidden: return .Hidden |
| 157 | + case .shared: return .Shared |
| 158 | + case .private: return .Private |
| 159 | + case .publicExternal: return .PublicExternal |
| 160 | + case .packageExternal: return .PackageExternal |
| 161 | + case .hiddenExternal: return .HiddenExternal |
| 162 | + } |
| 163 | + } |
| 164 | +} |
0 commit comments