24
24
#include "swift/Parse/Lexer.h"
25
25
#include "swift/Subsystems.h"
26
26
#include "llvm/Config/config.h"
27
- #include "llvm/Support/DynamicLibrary.h"
28
27
#include <cstdlib>
29
28
29
+ #if !defined(_WIN32)
30
+ #include <dlfcn.h>
31
+ #endif
32
+
30
33
using namespace swift;
31
34
32
35
#define ALLMACROS_PROPERTY_NAME "allMacros"
@@ -56,8 +59,7 @@ void swift_ASTGen_getMacroTypes(const void *getter,
56
59
#endif
57
60
58
61
static const void *
59
- getMacroRegistrationPropertyGetter(llvm::sys::DynamicLibrary library,
60
- StringRef moduleName,
62
+ getMacroRegistrationPropertyGetter(void *library, StringRef moduleName,
61
63
ASTContext &ctx) {
62
64
assert(!moduleName.empty());
63
65
// TODO: Consider using runtime lookup to get all types that conform to the
@@ -147,23 +149,28 @@ getMacroRegistrationPropertyGetter(llvm::sys::DynamicLibrary library,
147
149
assert(mangleResult.isSuccess());
148
150
name = mangleResult.result();
149
151
}
150
- return ctx.getAddressOfSymbol(name, & library);
152
+ return ctx.getAddressOfSymbol(name.c_str(), library);
151
153
}
152
154
153
155
void ASTContext::loadCompilerPlugins() {
154
- for (StringRef path : SearchPathOpts.getCompilerPluginLibraryPaths()) {
155
- std::string errorMsg;
156
- auto lib = llvm::sys::DynamicLibrary::getPermanentLibrary(
157
- path.data(), &errorMsg);
158
- if (!lib.isValid()) {
156
+ for (auto &path : SearchPathOpts.getCompilerPluginLibraryPaths()) {
157
+ void *lib = nullptr;
158
+ #if !defined(_WIN32)
159
+ lib = dlopen(path.c_str(), RTLD_LAZY|RTLD_LOCAL);
160
+ #endif
161
+ if (!lib) {
162
+ const char *errorMsg = "Unsupported platform";
163
+ #if !defined(_WIN32)
164
+ errorMsg = dlerror();
165
+ #endif
159
166
Diags.diagnose(SourceLoc(), diag::compiler_plugin_not_loaded, path,
160
167
errorMsg);
161
168
continue;
162
169
}
163
170
auto moduleName = llvm::sys::path::filename(path);
164
- #if !defined(_WIN32)
171
+ #if !defined(_WIN32)
165
172
moduleName.consume_front("lib");
166
- #endif
173
+ #endif
167
174
moduleName.consume_back(LTDL_SHLIB_EXT);
168
175
auto *getter = getMacroRegistrationPropertyGetter(lib, moduleName, *this);
169
176
if (!getter) {
@@ -175,7 +182,7 @@ void ASTContext::loadCompilerPlugins() {
175
182
// Note: We don't currently have a way to poke at the contents of a Swift
176
183
// array `[Any.Type]` from C++. But this should not be an issue for release
177
184
// toolchains where user-defined macros will be used.
178
- #if SWIFT_SWIFT_PARSER
185
+ #if SWIFT_SWIFT_PARSER
179
186
const void *const *metatypesAddress;
180
187
ptrdiff_t metatypeCount;
181
188
swift_ASTGen_getMacroTypes(getter, &metatypesAddress, &metatypeCount);
@@ -186,7 +193,7 @@ void ASTContext::loadCompilerPlugins() {
186
193
LoadedPlugins.try_emplace(name, std::move(plugin));
187
194
}
188
195
free(const_cast<void *>((const void *)metatypes.data()));
189
- #endif
196
+ #endif // SWIFT_SWIFT_PARSER
190
197
}
191
198
}
192
199
@@ -197,8 +204,7 @@ using WitnessTableLookupFn = const void *(const void *type,
197
204
extern "C" WitnessTableLookupFn swift_conformsToProtocol;
198
205
#endif
199
206
200
- CompilerPlugin::CompilerPlugin(const void *metadata,
201
- llvm::sys::DynamicLibrary parentLibrary,
207
+ CompilerPlugin::CompilerPlugin(const void *metadata, void *parentLibrary,
202
208
ASTContext &ctx)
203
209
: metadata(metadata), parentLibrary(parentLibrary)
204
210
{
@@ -208,6 +214,8 @@ CompilerPlugin::CompilerPlugin(const void *metadata,
208
214
#endif
209
215
void *protocolDescriptor =
210
216
ctx.getAddressOfSymbol(COMPILER_PLUGIN_PROTOCOL_DESCRIPTOR);
217
+ assert(swift_conformsToProtocol);
218
+ assert(protocolDescriptor);
211
219
witnessTable = swift_conformsToProtocol(metadata, protocolDescriptor);
212
220
assert(witnessTable && "Type does not conform to _CompilerPlugin");
213
221
auto returnedName = invokeName();
@@ -216,6 +224,12 @@ CompilerPlugin::CompilerPlugin(const void *metadata,
216
224
kind = invokeKind();
217
225
}
218
226
227
+ CompilerPlugin::~CompilerPlugin() {
228
+ #if !defined(_WIN32)
229
+ dlclose(parentLibrary);
230
+ #endif
231
+ }
232
+
219
233
namespace {
220
234
struct CharBuffer {
221
235
const char *data;
@@ -280,3 +294,28 @@ CompilerPlugin::invokeRewrite(StringRef targetModuleName,
280
294
llvm_unreachable("Incompatible host compiler");
281
295
#endif
282
296
}
297
+
298
+ Optional<StringRef>
299
+ CompilerPlugin::invokeGenericSignature() const {
300
+ #if __clang__
301
+ using Method = SWIFT_CC CharBuffer(
302
+ SWIFT_CONTEXT const void *, const void *, const void *);
303
+ auto method = getWitnessMethodUnsafe<Method>(
304
+ WitnessTableEntry::GenericSignature);
305
+ return method(metadata, metadata, witnessTable).str();
306
+ #else
307
+ llvm_unreachable("Incompatible host compiler");
308
+ #endif
309
+ }
310
+
311
+ StringRef CompilerPlugin::invokeTypeSignature() const {
312
+ #if __clang__
313
+ using Method = SWIFT_CC CharBuffer(
314
+ SWIFT_CONTEXT const void *, const void *, const void *);
315
+ auto method = getWitnessMethodUnsafe<Method>(
316
+ WitnessTableEntry::TypeSignature);
317
+ return method(metadata, metadata, witnessTable).str();
318
+ #else
319
+ llvm_unreachable("Incompatible host compiler");
320
+ #endif
321
+ }
0 commit comments