Skip to content

Commit 37a6374

Browse files
authored
Merge pull request #69027 from rintaro/macro-resolveerror-rdar115571427
[Macros] Improve macro plugin loading macro definition resolution diagnostics
2 parents 366514b + 444fcfa commit 37a6374

21 files changed

+344
-141
lines changed

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -536,9 +536,6 @@ REMARK(warning_in_access_notes_file,none,
536536
"ignored invalid content in access notes file: %0",
537537
(StringRef))
538538

539-
WARNING(compiler_plugin_not_loaded,none,
540-
"compiler plugin not loaded: %0; loader error: %1", (StringRef, StringRef))
541-
542539
ERROR(dont_enable_interop_and_compat,none,
543540
"do not pass both '-enable-experimental-cxx-interop' and "
544541
"'-cxx-interoperability-mode'; remove '-enable-experimental-cxx-interop'", ())

include/swift/AST/DiagnosticsSema.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7312,7 +7312,7 @@ ERROR(macro_undefined,PointsToFirstBadToken,
73127312
"no macro named %0", (Identifier))
73137313
ERROR(external_macro_not_found,none,
73147314
"external macro implementation type '%0.%1' could not be found for "
7315-
"macro %2", (StringRef, StringRef, DeclName))
7315+
"macro %2; %3", (StringRef, StringRef, DeclName, StringRef))
73167316
ERROR(macro_must_be_defined,none,
73177317
"macro %0 requires a definition", (DeclName))
73187318
ERROR(external_macro_outside_macro_definition,none,

include/swift/AST/MacroDefinition.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#ifndef SWIFT_AST_MACRO_DEFINITION_H
1919
#define SWIFT_AST_MACRO_DEFINITION_H
2020

21+
#include "swift/Basic/StringExtras.h"
2122
#include "llvm/ADT/PointerUnion.h"
2223

2324
namespace swift {
@@ -26,14 +27,25 @@ class ASTContext;
2627

2728
/// A reference to an external macro definition that is understood by ASTGen.
2829
struct ExternalMacroDefinition {
29-
enum class PluginKind {
30+
enum class PluginKind : int8_t {
3031
InProcess = 0,
3132
Executable = 1,
33+
Error = -1,
3234
};
3335
PluginKind kind;
3436
/// ASTGen's notion of an macro definition, which is opaque to the C++ part
35-
/// of the compiler.
36-
void *opaqueHandle = nullptr;
37+
/// of the compiler. If 'kind' is 'PluginKind::Error', this is a C-string to
38+
/// the error message
39+
const void *opaqueHandle = nullptr;
40+
41+
static ExternalMacroDefinition error(NullTerminatedStringRef message) {
42+
return ExternalMacroDefinition{PluginKind::Error,
43+
static_cast<const void *>(message.data())};
44+
}
45+
bool isError() const { return kind == PluginKind::Error; }
46+
NullTerminatedStringRef getErrorMessage() const {
47+
return static_cast<const char *>(opaqueHandle);
48+
}
3749
};
3850

3951
/// A reference to an external macro.

include/swift/AST/PluginLoader.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,15 @@ class PluginLoader {
7676
/// returns a nullptr.
7777
/// NOTE: This method is idempotent. If the plugin is already loaded, the same
7878
/// instance is simply returned.
79-
LoadedLibraryPlugin *loadLibraryPlugin(llvm::StringRef path);
79+
llvm::Expected<LoadedLibraryPlugin *> loadLibraryPlugin(llvm::StringRef path);
8080

8181
/// Launch the specified executable plugin path resolving the path with the
8282
/// current VFS. If it fails to load the plugin, a diagnostic is emitted, and
8383
/// returns a nullptr.
8484
/// NOTE: This method is idempotent. If the plugin is already loaded, the same
8585
/// instance is simply returned.
86-
LoadedExecutablePlugin *loadExecutablePlugin(llvm::StringRef path);
86+
llvm::Expected<LoadedExecutablePlugin *>
87+
loadExecutablePlugin(llvm::StringRef path);
8788
};
8889

8990
} // namespace swift

include/swift/AST/PluginRegistry.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,19 @@ class LoadedLibraryPlugin {
3333
/// Cache of loaded symbols.
3434
llvm::StringMap<void *> resolvedSymbols;
3535

36+
/// Path to the plugin library.
37+
const std::string LibraryPath;
38+
3639
public:
37-
LoadedLibraryPlugin(void *handle) : handle(handle) {}
40+
LoadedLibraryPlugin(void *handle, StringRef path)
41+
: handle(handle), LibraryPath(path) {}
3842

3943
/// Finds the address of the given symbol within the library.
4044
void *getAddressOfSymbol(const char *symbolName);
45+
46+
NullTerminatedStringRef getLibraryPath() {
47+
return {LibraryPath.c_str(), LibraryPath.size()};
48+
}
4149
};
4250

4351
/// Represent a "resolved" executable plugin.

include/swift/AST/TypeCheckRequests.h

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4238,34 +4238,57 @@ class ExpandSynthesizedMemberMacroRequest
42384238
};
42394239

42404240
/// Represent a loaded plugin either an in-process library or an executable.
4241-
class LoadedCompilerPlugin {
4242-
llvm::PointerUnion<LoadedLibraryPlugin *, LoadedExecutablePlugin *> ptr;
4241+
class CompilerPluginLoadResult {
4242+
enum class PluginKind : uint8_t {
4243+
Error = 0,
4244+
Library,
4245+
Executable,
4246+
};
4247+
PluginKind Kind;
4248+
void *opaqueHandle;
4249+
4250+
CompilerPluginLoadResult(PluginKind K, void *opaque)
4251+
: Kind(K), opaqueHandle(opaque) {}
42434252

42444253
public:
4245-
LoadedCompilerPlugin(std::nullptr_t) : ptr(nullptr) {}
4246-
LoadedCompilerPlugin(LoadedLibraryPlugin *ptr) : ptr(ptr){};
4247-
LoadedCompilerPlugin(LoadedExecutablePlugin *ptr) : ptr(ptr){};
4254+
CompilerPluginLoadResult(LoadedLibraryPlugin *ptr)
4255+
: CompilerPluginLoadResult(PluginKind::Library, ptr){};
4256+
CompilerPluginLoadResult(LoadedExecutablePlugin *ptr)
4257+
: CompilerPluginLoadResult(PluginKind::Executable, ptr){};
4258+
static CompilerPluginLoadResult error(NullTerminatedStringRef message) {
4259+
return CompilerPluginLoadResult(PluginKind::Error,
4260+
const_cast<char *>(message.data()));
4261+
}
42484262

42494263
LoadedLibraryPlugin *getAsLibraryPlugin() const {
4250-
return ptr.dyn_cast<LoadedLibraryPlugin *>();
4264+
if (Kind != PluginKind::Library)
4265+
return nullptr;
4266+
return static_cast<LoadedLibraryPlugin *>(opaqueHandle);
42514267
}
42524268
LoadedExecutablePlugin *getAsExecutablePlugin() const {
4253-
return ptr.dyn_cast<LoadedExecutablePlugin *>();
4269+
if (Kind != PluginKind::Executable)
4270+
return nullptr;
4271+
return static_cast<LoadedExecutablePlugin *>(opaqueHandle);
4272+
}
4273+
bool isError() const { return Kind == PluginKind::Error; }
4274+
NullTerminatedStringRef getErrorMessage() const {
4275+
assert(isError());
4276+
return static_cast<const char *>(opaqueHandle);
42544277
}
42554278
};
42564279

42574280
class CompilerPluginLoadRequest
42584281
: public SimpleRequest<CompilerPluginLoadRequest,
4259-
LoadedCompilerPlugin(ASTContext *, Identifier),
4282+
CompilerPluginLoadResult(ASTContext *, Identifier),
42604283
RequestFlags::Cached> {
42614284
public:
42624285
using SimpleRequest::SimpleRequest;
42634286

42644287
private:
42654288
friend SimpleRequest;
42664289

4267-
LoadedCompilerPlugin evaluate(Evaluator &evaluator, ASTContext *ctx,
4268-
Identifier moduleName) const;
4290+
CompilerPluginLoadResult evaluate(Evaluator &evaluator, ASTContext *ctx,
4291+
Identifier moduleName) const;
42694292

42704293
public:
42714294
// Source location
@@ -4296,19 +4319,18 @@ class ExpandPeerMacroRequest
42964319
/// Resolve an external macro given its module and type name.
42974320
class ExternalMacroDefinitionRequest
42984321
: public SimpleRequest<ExternalMacroDefinitionRequest,
4299-
llvm::Optional<ExternalMacroDefinition>(
4300-
ASTContext *, Identifier, Identifier),
4322+
ExternalMacroDefinition(ASTContext *, Identifier,
4323+
Identifier),
43014324
RequestFlags::Cached> {
43024325
public:
43034326
using SimpleRequest::SimpleRequest;
43044327

43054328
private:
43064329
friend SimpleRequest;
43074330

4308-
llvm::Optional<ExternalMacroDefinition> evaluate(
4309-
Evaluator &evaluator, ASTContext *ctx,
4310-
Identifier moduleName, Identifier typeName
4311-
) const;
4331+
ExternalMacroDefinition evaluate(Evaluator &evaluator, ASTContext *ctx,
4332+
Identifier moduleName,
4333+
Identifier typeName) const;
43124334

43134335
public:
43144336
// Source location

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -458,10 +458,10 @@ SWIFT_REQUEST(TypeChecker, MacroDefinitionRequest,
458458
MacroDefinition(MacroDecl *),
459459
Cached, NoLocationInfo)
460460
SWIFT_REQUEST(TypeChecker, CompilerPluginLoadRequest,
461-
LoadedCompilerPlugin(ASTContext *, Identifier),
461+
CompilerPluginLoadResult(ASTContext *, Identifier),
462462
Cached, NoLocationInfo)
463463
SWIFT_REQUEST(TypeChecker, ExternalMacroDefinitionRequest,
464-
Optional<ExternalMacroDefinition>(ASTContext *, Identifier, Identifier),
464+
ExternalMacroDefinition(ASTContext *, Identifier, Identifier),
465465
Cached, NoLocationInfo)
466466
SWIFT_REQUEST(TypeChecker, ExpandMacroExpansionDeclRequest,
467467
ArrayRef<Decl *>(MacroExpansionDecl *),

include/swift/Basic/StringExtras.h

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@
2121
#include "swift/Basic/LLVM.h"
2222
#include "swift/Basic/OptionSet.h"
2323
#include "llvm/ADT/Optional.h"
24+
#include "llvm/ADT/SmallString.h"
2425
#include "llvm/ADT/SmallVector.h"
2526
#include "llvm/ADT/StringRef.h"
2627
#include "llvm/ADT/StringSet.h"
28+
#include "llvm/ADT/Twine.h"
2729
#include "llvm/Support/Allocator.h"
2830
#include <iterator>
2931
#include <string>
@@ -492,13 +494,21 @@ class NullTerminatedStringRef {
492494

493495
/// Create a null-terminated string, copying \p Str into \p A .
494496
template <typename Allocator>
495-
NullTerminatedStringRef(StringRef Str, Allocator &A) : Ref("") {
496-
if (Str.empty())
497+
NullTerminatedStringRef(llvm::Twine Str, Allocator &A) : Ref("") {
498+
if (Str.isTriviallyEmpty())
497499
return;
500+
if (Str.isSingleStringLiteral()) {
501+
Ref = Str.getSingleStringRef();
502+
return;
503+
}
504+
llvm::SmallString<0> stash;
505+
auto _ref = Str.toStringRef(stash);
498506

499-
size_t size = Str.size();
500-
char *memory = A.template Allocate<char>(size + 1);
501-
memcpy(memory, Str.data(), size);
507+
size_t size = _ref.size();
508+
if (size == 0)
509+
return;
510+
char *memory = static_cast<char *>(A.Allocate(size + 1, alignof(char)));
511+
memcpy(memory, _ref.data(), size);
502512
memory[size] = '\0';
503513
Ref = {memory, size};
504514
}

lib/AST/PluginLoader.cpp

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,12 @@ PluginLoader::lookupPluginByModuleName(Identifier moduleName) {
158158
}
159159
}
160160

161-
LoadedLibraryPlugin *PluginLoader::loadLibraryPlugin(StringRef path) {
161+
llvm::Expected<LoadedLibraryPlugin *>
162+
PluginLoader::loadLibraryPlugin(StringRef path) {
162163
auto fs = Ctx.SourceMgr.getFileSystem();
163164
SmallString<128> resolvedPath;
164165
if (auto err = fs->getRealPath(path, resolvedPath)) {
165-
Ctx.Diags.diagnose(SourceLoc(), diag::compiler_plugin_not_loaded, path,
166-
err.message());
167-
return nullptr;
166+
return llvm::createStringError(err, err.message());
168167
}
169168

170169
// Track the dependency.
@@ -174,21 +173,25 @@ LoadedLibraryPlugin *PluginLoader::loadLibraryPlugin(StringRef path) {
174173
// Load the plugin.
175174
auto plugin = getRegistry()->loadLibraryPlugin(resolvedPath);
176175
if (!plugin) {
177-
Ctx.Diags.diagnose(SourceLoc(), diag::compiler_plugin_not_loaded, path,
178-
llvm::toString(plugin.takeError()));
179-
return nullptr;
176+
resolvedPath.push_back(0);
177+
return llvm::handleErrors(
178+
plugin.takeError(), [&](const llvm::ErrorInfoBase &err) {
179+
return llvm::createStringError(
180+
err.convertToErrorCode(),
181+
"compiler plugin '%s' could not be loaded; %s",
182+
resolvedPath.data(), err.message().data());
183+
});
180184
}
181185

182-
return plugin.get();
186+
return plugin;
183187
}
184188

185-
LoadedExecutablePlugin *PluginLoader::loadExecutablePlugin(StringRef path) {
189+
llvm::Expected<LoadedExecutablePlugin *>
190+
PluginLoader::loadExecutablePlugin(StringRef path) {
186191
auto fs = Ctx.SourceMgr.getFileSystem();
187192
SmallString<128> resolvedPath;
188193
if (auto err = fs->getRealPath(path, resolvedPath)) {
189-
Ctx.Diags.diagnose(SourceLoc(), diag::compiler_plugin_not_loaded, path,
190-
err.message());
191-
return nullptr;
194+
return llvm::createStringError(err, err.message());
192195
}
193196

194197
// Track the dependency.
@@ -198,10 +201,15 @@ LoadedExecutablePlugin *PluginLoader::loadExecutablePlugin(StringRef path) {
198201
// Load the plugin.
199202
auto plugin = getRegistry()->loadExecutablePlugin(resolvedPath);
200203
if (!plugin) {
201-
Ctx.Diags.diagnose(SourceLoc(), diag::compiler_plugin_not_loaded, path,
202-
llvm::toString(plugin.takeError()));
203-
return nullptr;
204+
resolvedPath.push_back(0);
205+
return llvm::handleErrors(
206+
plugin.takeError(), [&](const llvm::ErrorInfoBase &err) {
207+
return llvm::createStringError(
208+
err.convertToErrorCode(),
209+
"compiler plugin '%s' could not be loaded: %s",
210+
resolvedPath.data(), err.message().data());
211+
});
204212
}
205213

206-
return plugin.get();
214+
return plugin;
207215
}

lib/AST/PluginRegistry.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ PluginRegistry::loadLibraryPlugin(StringRef path) {
6767
}
6868
#endif
6969

70-
storage = std::make_unique<LoadedLibraryPlugin>(lib);
70+
storage = std::make_unique<LoadedLibraryPlugin>(lib, path);
7171
return storage.get();
7272
}
7373

0 commit comments

Comments
 (0)