Skip to content

Commit 0290736

Browse files
authored
Merge pull request swiftlang#34245 from rjmccall/generalize-export-attributes
Generalize SWIFT_RUNTIME_EXPORT to work for other runtime libraries
2 parents 169948f + 4481e3b commit 0290736

File tree

3 files changed

+102
-35
lines changed

3 files changed

+102
-35
lines changed

include/swift/Basic/LLVM.h

+16-8
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@
2626
// without a definition of NoneType.
2727
#include "llvm/ADT/None.h"
2828

29+
// Don't pre-declare certain LLVM types in the runtime, which must
30+
// not put things in namespace llvm for ODR reasons.
31+
#if !defined(swiftCore_EXPORTS)
32+
#define SWIFT_LLVM_ODR_SAFE 1
33+
#else
34+
#define SWIFT_LLVM_ODR_SAFE 0
35+
#endif
36+
2937
// Forward declarations.
3038
namespace llvm {
3139
// Containers.
@@ -34,18 +42,18 @@ namespace llvm {
3442
class Twine;
3543
template <typename T> class SmallPtrSetImpl;
3644
template <typename T, unsigned N> class SmallPtrSet;
37-
#if !defined(swiftCore_EXPORTS)
45+
#if SWIFT_LLVM_ODR_SAFE
3846
template <typename T> class SmallVectorImpl;
3947
template <typename T, unsigned N> class SmallVector;
4048
#endif
4149
template <unsigned N> class SmallString;
4250
template <typename T, unsigned N> class SmallSetVector;
43-
#if !defined(swiftCore_EXPORTS)
51+
#if SWIFT_LLVM_ODR_SAFE
4452
template<typename T> class ArrayRef;
4553
template<typename T> class MutableArrayRef;
4654
#endif
4755
template<typename T> class TinyPtrVector;
48-
#if !defined(swiftCore_EXPORTS)
56+
#if SWIFT_LLVM_ODR_SAFE
4957
template<typename T> class Optional;
5058
#endif
5159
template <typename ...PTs> class PointerUnion;
@@ -56,7 +64,7 @@ namespace llvm {
5664
class raw_ostream;
5765
class APInt;
5866
class APFloat;
59-
#if !defined(swiftCore_EXPORTS)
67+
#if SWIFT_LLVM_ODR_SAFE
6068
template <typename Fn> class function_ref;
6169
#endif
6270
} // end namespace llvm
@@ -71,13 +79,13 @@ namespace swift {
7179
using llvm::cast_or_null;
7280

7381
// Containers.
74-
#if !defined(swiftCore_EXPORTS)
82+
#if SWIFT_LLVM_ODR_SAFE
7583
using llvm::ArrayRef;
7684
using llvm::MutableArrayRef;
7785
#endif
7886
using llvm::iterator_range;
7987
using llvm::None;
80-
#if !defined(swiftCore_EXPORTS)
88+
#if SWIFT_LLVM_ODR_SAFE
8189
using llvm::Optional;
8290
#endif
8391
using llvm::PointerUnion;
@@ -86,7 +94,7 @@ namespace swift {
8694
using llvm::SmallPtrSetImpl;
8795
using llvm::SmallSetVector;
8896
using llvm::SmallString;
89-
#if !defined(swiftCore_EXPORTS)
97+
#if SWIFT_LLVM_ODR_SAFE
9098
using llvm::SmallVector;
9199
using llvm::SmallVectorImpl;
92100
#endif
@@ -98,7 +106,7 @@ namespace swift {
98106
// Other common classes.
99107
using llvm::APFloat;
100108
using llvm::APInt;
101-
#if !defined(swiftCore_EXPORTS)
109+
#if SWIFT_LLVM_ODR_SAFE
102110
using llvm::function_ref;
103111
#endif
104112
using llvm::NoneType;

include/swift/Runtime/Metadata.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,10 @@ const TypeContextDescriptor *swift_getTypeContextDescriptor(const Metadata *type
878878
SWIFT_RUNTIME_EXPORT
879879
const HeapObject *swift_getKeyPath(const void *pattern, const void *arguments);
880880

881+
// For some reason, MSVC doesn't accept these declarations outside of
882+
// swiftCore. TODO: figure out a reasonable way to declare them.
881883
#if defined(swiftCore_EXPORTS)
884+
882885
/// Given a pointer to a borrowed value of type `Root` and a
883886
/// `KeyPath<Root, Value>`, project a pointer to a borrowed value of type
884887
/// `Value`.
@@ -900,7 +903,8 @@ swift_modifyAtWritableKeyPath;
900903
SWIFT_RUNTIME_EXPORT
901904
YieldOnceCoroutine<OpaqueValue* (const OpaqueValue *root, void *keyPath)>::type
902905
swift_modifyAtReferenceWritableKeyPath;
903-
#endif
906+
907+
#endif // swiftCore_EXPORTS
904908

905909
SWIFT_RUNTIME_EXPORT
906910
void swift_enableDynamicReplacementScope(const DynamicReplacementScope *scope);

stdlib/public/SwiftShims/Visibility.h

+81-26
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@
5252
# define SWIFT_END_NULLABILITY_ANNOTATIONS
5353
#endif
5454

55+
#define SWIFT_MACRO_CONCAT(A, B) A ## B
56+
#define SWIFT_MACRO_IF_0(IF_TRUE, IF_FALSE) IF_FALSE
57+
#define SWIFT_MACRO_IF_1(IF_TRUE, IF_FALSE) IF_TRUE
58+
#define SWIFT_MACRO_IF(COND, IF_TRUE, IF_FALSE) \
59+
SWIFT_MACRO_CONCAT(SWIFT_MACRO_IF_, COND)(IF_TRUE, IF_FALSE)
60+
5561
#if __has_attribute(pure)
5662
#define SWIFT_READONLY __attribute__((__pure__))
5763
#else
@@ -94,48 +100,97 @@
94100
#define SWIFT_ATTRIBUTE_UNAVAILABLE
95101
#endif
96102

97-
// TODO: support using shims headers in overlays by parameterizing
98-
// SWIFT_RUNTIME_EXPORT on the library it's exported from.
99-
100-
/// Attribute used to export symbols from the runtime.
103+
// Define the appropriate attributes for sharing symbols across
104+
// image (executable / shared-library) boundaries.
105+
//
106+
// SWIFT_ATTRIBUTE_FOR_EXPORTS will be placed on declarations that
107+
// are known to be exported from the current image. Typically, they
108+
// are placed on header declarations and then inherited by the actual
109+
// definitions.
110+
//
111+
// SWIFT_ATTRIBUTE_FOR_IMPORTS will be placed on declarations that
112+
// are known to be exported from a different image. This never
113+
// includes a definition.
114+
//
115+
// Getting the right attribute on a declaratioon can be pretty awkward,
116+
// but it's necessary under the C translation model. All of this
117+
// ceremony is familiar to Windows programmers; C/C++ programmers
118+
// everywhere else usually don't bother, but since we have to get it
119+
// right for Windows, we have everything set up to get it right on
120+
// other targets as well, and doing so lets the compiler use more
121+
// efficient symbol access patterns.
101122
#if defined(__MACH__) || defined(__wasi__)
102123

103-
# define SWIFT_EXPORT_ATTRIBUTE __attribute__((__visibility__("default")))
124+
// On Mach-O and WebAssembly, we use non-hidden visibility. We just use
125+
// default visibility on both imports and exports, both because these
126+
// targets don't support protected visibility but because they don't
127+
// need it: symbols are not interposable outside the current image
128+
// by default.
129+
# define SWIFT_ATTRIBUTE_FOR_EXPORTS __attribute__((__visibility__("default")))
130+
# define SWIFT_ATTRIBUTE_FOR_IMPORTS __attribute__((__visibility__("default")))
104131

105132
#elif defined(__ELF__)
106133

107-
// We make assumptions that the runtime and standard library can refer to each
108-
// other's symbols as DSO-local, which means we can't allow the dynamic linker
109-
// to relocate these symbols. We must give them protected visibility while
110-
// building the standard library and runtime.
111-
# if defined(swiftCore_EXPORTS)
112-
# define SWIFT_EXPORT_ATTRIBUTE __attribute__((__visibility__("protected")))
113-
# else
114-
# define SWIFT_EXPORT_ATTRIBUTE __attribute__((__visibility__("default")))
115-
# endif
134+
// On ELF, we use non-hidden visibility. For exports, we must use
135+
// protected visibility to tell the compiler and linker that the symbols
136+
// can't be interposed outside the current image. For imports, we must
137+
// use default visibility because protected visibility guarantees that
138+
// the symbol is defined in the current library, which isn't true for
139+
// an import.
140+
//
141+
// The compiler does assume that the runtime and standard library can
142+
// refer to each other's symbols as DSO-local, so it's important that
143+
// we get this right or we can get linker errors.
144+
# define SWIFT_ATTRIBUTE_FOR_EXPORTS __attribute__((__visibility__("protected")))
145+
# define SWIFT_ATTRIBUTE_FOR_IMPORTS __attribute__((__visibility__("default")))
146+
147+
#elif defined(__CYGWIN__)
148+
149+
// For now, we ignore all this on Cygwin.
150+
# define SWIFT_ATTRIBUTE_FOR_EXPORTS
151+
# define SWIFT_ATTRIBUTE_FOR_IMPORTS
116152

117153
// FIXME: this #else should be some sort of #elif Windows
118154
#else // !__MACH__ && !__ELF__
119155

120-
# if defined(__CYGWIN__)
121-
# define SWIFT_EXPORT_ATTRIBUTE
122-
# else
156+
// On PE/COFF, we use dllimport and dllexport.
157+
# define SWIFT_ATTRIBUTE_FOR_EXPORTS __declspec(dllexport)
158+
# define SWIFT_ATTRIBUTE_FOR_IMPORTS __declspec(dllimport)
123159

124-
# if defined(swiftCore_EXPORTS)
125-
# define SWIFT_EXPORT_ATTRIBUTE __declspec(dllexport)
126-
# else
127-
# define SWIFT_EXPORT_ATTRIBUTE __declspec(dllimport)
128-
# endif
129-
130-
# endif
160+
#endif
131161

162+
// CMake conventionally passes -DlibraryName_EXPORTS when building
163+
// code that goes into libraryName. This isn't the best macro name,
164+
// but it's conventional. We do have to pass it explicitly in a few
165+
// places in the build system for a variety of reasons.
166+
//
167+
// Unfortunately, defined(D) is a special function you can use in
168+
// preprocessor conditions, not a macro you can use anywhere, so we
169+
// need to manually check for all the libraries we know about so that
170+
// we can use them in our condition below.s
171+
#if defined(swiftCore_EXPORTS)
172+
#define SWIFT_IMAGE_EXPORTS_swiftCore 1
173+
#else
174+
#define SWIFT_IMAGE_EXPORTS_swiftCore 0
132175
#endif
133176

177+
#define SWIFT_EXPORT_FROM_ATTRIBUTE(LIBRARY) \
178+
SWIFT_MACRO_IF(SWIFT_IMAGE_EXPORTS_##LIBRARY, \
179+
SWIFT_ATTRIBUTE_FOR_EXPORTS, \
180+
SWIFT_ATTRIBUTE_FOR_IMPORTS)
181+
182+
// SWIFT_EXPORT_FROM(LIBRARY) declares something to be a C-linkage
183+
// entity exported by the given library.
184+
//
185+
// SWIFT_RUNTIME_EXPORT is just SWIFT_EXPORT_FROM(swiftCore).
186+
//
187+
// TODO: use this in shims headers in overlays.
134188
#if defined(__cplusplus)
135-
#define SWIFT_RUNTIME_EXPORT extern "C" SWIFT_EXPORT_ATTRIBUTE
189+
#define SWIFT_EXPORT_FROM(LIBRARY) extern "C" SWIFT_EXPORT_FROM_ATTRIBUTE(LIBRARY)
136190
#else
137-
#define SWIFT_RUNTIME_EXPORT SWIFT_EXPORT_ATTRIBUTE
191+
#define SWIFT_EXPORT_FROM(LIBRARY) SWIFT_EXPORT_FROM_ATTRIBUTE(LIBRARY)
138192
#endif
193+
#define SWIFT_RUNTIME_EXPORT SWIFT_EXPORT_FROM(swiftCore)
139194

140195
#if __cplusplus > 201402l && __has_cpp_attribute(fallthrough)
141196
#define SWIFT_FALLTHROUGH [[fallthrough]]

0 commit comments

Comments
 (0)