Skip to content

Commit bdd4c00

Browse files
committed
[Macros] Diagnose how ExternalMacroDefinition request was failed
Return the failure reason as the result.
1 parent d4adba2 commit bdd4c00

12 files changed

+122
-55
lines changed

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+
llvm::StringRef getErrorMessage() const {
47+
return llvm::StringRef(static_cast<const char *>(opaqueHandle));
48+
}
3749
};
3850

3951
/// A reference to an external macro.

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: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4296,19 +4296,18 @@ class ExpandPeerMacroRequest
42964296
/// Resolve an external macro given its module and type name.
42974297
class ExternalMacroDefinitionRequest
42984298
: public SimpleRequest<ExternalMacroDefinitionRequest,
4299-
llvm::Optional<ExternalMacroDefinition>(
4300-
ASTContext *, Identifier, Identifier),
4299+
ExternalMacroDefinition(ASTContext *, Identifier,
4300+
Identifier),
43014301
RequestFlags::Cached> {
43024302
public:
43034303
using SimpleRequest::SimpleRequest;
43044304

43054305
private:
43064306
friend SimpleRequest;
43074307

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

43134312
public:
43144313
// Source location

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ SWIFT_REQUEST(TypeChecker, CompilerPluginLoadRequest,
461461
LoadedCompilerPlugin(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: 11 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,17 @@ 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+
llvm::SmallString<0> stash;
501+
auto _ref = Str.toStringRef(stash);
498502

499-
size_t size = Str.size();
500-
char *memory = A.template Allocate<char>(size + 1);
501-
memcpy(memory, Str.data(), size);
503+
size_t size = _ref.size();
504+
if (size == 0)
505+
return;
506+
char *memory = static_cast<char *>(A.Allocate(size + 1, alignof(char)));
507+
memcpy(memory, _ref.data(), size);
502508
memory[size] = '\0';
503509
Ref = {memory, size};
504510
}

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

lib/Basic/Sandbox.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ static StringRef sandboxProfile(llvm::BumpPtrAllocator &Alloc) {
3030
// This is required to launch any processes (execve(2)).
3131
contents += "(allow process-exec*)\n";
3232

33-
return NullTerminatedStringRef(contents, Alloc);
33+
return NullTerminatedStringRef(StringRef(contents), Alloc);
3434
}
3535
#endif
3636

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2073,14 +2073,14 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
20732073
ExternalMacroDefinitionRequest request{
20742074
&Ctx, external.moduleName, external.macroTypeName
20752075
};
2076-
auto externalDef = evaluateOrDefault(Ctx.evaluator, request, llvm::None);
2077-
if (!externalDef) {
2078-
MD->diagnose(
2079-
diag::external_macro_not_found,
2080-
external.moduleName.str(),
2081-
external.macroTypeName.str(),
2082-
MD->getName()
2083-
).limitBehavior(DiagnosticBehavior::Warning);
2076+
auto externalDef =
2077+
evaluateOrDefault(Ctx.evaluator, request,
2078+
ExternalMacroDefinition::error("failed request"));
2079+
if (externalDef.isError()) {
2080+
MD->diagnose(diag::external_macro_not_found, external.moduleName.str(),
2081+
external.macroTypeName.str(), MD->getName(),
2082+
externalDef.getErrorMessage())
2083+
.limitBehavior(DiagnosticBehavior::Warning);
20842084
}
20852085

20862086
break;

lib/Sema/TypeCheckMacros.cpp

Lines changed: 52 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,12 @@ extern "C" void swift_ASTGen_freeExpansionReplacements(
6565
ptrdiff_t numReplacements);
6666

6767
extern "C" ptrdiff_t swift_ASTGen_expandFreestandingMacro(
68-
void *diagEngine, void *macro, uint8_t externalKind,
68+
void *diagEngine, const void *macro, uint8_t externalKind,
6969
const char *discriminator, uint8_t rawMacroRole, void *sourceFile,
7070
const void *sourceLocation, BridgedString *evaluatedSourceOut);
7171

7272
extern "C" ptrdiff_t swift_ASTGen_expandAttachedMacro(
73-
void *diagEngine, void *macro, uint8_t externalKind,
73+
void *diagEngine, const void *macro, uint8_t externalKind,
7474
const char *discriminator, const char *qualifiedType,
7575
const char *conformances, uint8_t rawMacroRole, void *customAttrSourceFile,
7676
const void *customAttrSourceLocation, void *declarationSourceFile,
@@ -381,7 +381,7 @@ CompilerPluginLoadRequest::evaluate(Evaluator &evaluator, ASTContext *ctx,
381381
return nullptr;
382382
}
383383

384-
static llvm::Optional<ExternalMacroDefinition>
384+
static ExternalMacroDefinition
385385
resolveInProcessMacro(ASTContext &ctx, Identifier moduleName,
386386
Identifier typeName, LoadedLibraryPlugin *plugin) {
387387
#if SWIFT_BUILD_SWIFT_SYNTAX
@@ -398,13 +398,27 @@ resolveInProcessMacro(ASTContext &ctx, Identifier moduleName,
398398

399399
return ExternalMacroDefinition{
400400
ExternalMacroDefinition::PluginKind::InProcess, inProcess};
401+
} else {
402+
NullTerminatedStringRef err(
403+
"type '" + moduleName.str() + "." + typeName.str() +
404+
"' is not a valid macro implementation type in library plugin '" +
405+
StringRef(plugin->getLibraryPath()) + "'",
406+
ctx);
407+
408+
return ExternalMacroDefinition::error(err);
401409
}
402410
}
411+
NullTerminatedStringRef err("macro implementation type '" + moduleName.str() +
412+
"." + typeName.str() +
413+
"' could not be found in library plugin '" +
414+
StringRef(plugin->getLibraryPath()) + "'",
415+
ctx);
416+
return ExternalMacroDefinition::error(err);
403417
#endif
404-
return llvm::None;
418+
return ExternalMacroDefinition::error("macro is not supported");
405419
}
406420

407-
static llvm::Optional<ExternalMacroDefinition>
421+
static ExternalMacroDefinition
408422
resolveExecutableMacro(ASTContext &ctx,
409423
LoadedExecutablePlugin *executablePlugin,
410424
Identifier moduleName, Identifier typeName) {
@@ -417,11 +431,17 @@ resolveExecutableMacro(ASTContext &ctx,
417431
return ExternalMacroDefinition{
418432
ExternalMacroDefinition::PluginKind::Executable, execMacro};
419433
}
434+
NullTerminatedStringRef err(
435+
"macro implementation type '" + moduleName.str() + "." + typeName.str() +
436+
"' could not be found in executable plugin" +
437+
StringRef(executablePlugin->getExecutablePath()),
438+
ctx);
439+
return ExternalMacroDefinition::error(err);
420440
#endif
421-
return llvm::None;
441+
return ExternalMacroDefinition::error("macro is not supported");
422442
}
423443

424-
llvm::Optional<ExternalMacroDefinition>
444+
ExternalMacroDefinition
425445
ExternalMacroDefinitionRequest::evaluate(Evaluator &evaluator, ASTContext *ctx,
426446
Identifier moduleName,
427447
Identifier typeName) const {
@@ -432,19 +452,17 @@ ExternalMacroDefinitionRequest::evaluate(Evaluator &evaluator, ASTContext *ctx,
432452
evaluateOrDefault(evaluator, loadRequest, nullptr);
433453

434454
if (auto loadedLibrary = loaded.getAsLibraryPlugin()) {
435-
if (auto inProcess = resolveInProcessMacro(
436-
*ctx, moduleName, typeName, loadedLibrary))
437-
return *inProcess;
455+
return resolveInProcessMacro(*ctx, moduleName, typeName, loadedLibrary);
438456
}
439457

440458
if (auto *executablePlugin = loaded.getAsExecutablePlugin()) {
441-
if (auto executableMacro = resolveExecutableMacro(*ctx, executablePlugin,
442-
moduleName, typeName)) {
443-
return executableMacro;
444-
}
459+
return resolveExecutableMacro(*ctx, executablePlugin, moduleName, typeName);
445460
}
446461

447-
return llvm::None;
462+
NullTerminatedStringRef err("plugin that can handle module '" +
463+
moduleName.str() + "' not found",
464+
*ctx);
465+
return ExternalMacroDefinition::error(err);
448466
}
449467

450468
/// Adjust the given mangled name for a macro expansion to produce a valid
@@ -1028,11 +1046,14 @@ evaluateFreestandingMacro(FreestandingMacroExpansion *expansion,
10281046
auto external = macroDef.getExternalMacro();
10291047
ExternalMacroDefinitionRequest request{&ctx, external.moduleName,
10301048
external.macroTypeName};
1031-
auto externalDef = evaluateOrDefault(ctx.evaluator, request, llvm::None);
1032-
if (!externalDef) {
1049+
auto externalDef =
1050+
evaluateOrDefault(ctx.evaluator, request,
1051+
ExternalMacroDefinition::error("request error"));
1052+
if (externalDef.isError()) {
10331053
ctx.Diags.diagnose(loc, diag::external_macro_not_found,
10341054
external.moduleName.str(),
1035-
external.macroTypeName.str(), macro->getName());
1055+
external.macroTypeName.str(), macro->getName(),
1056+
externalDef.getErrorMessage());
10361057
macro->diagnose(diag::decl_declared_here, macro);
10371058
return nullptr;
10381059
}
@@ -1062,9 +1083,10 @@ evaluateFreestandingMacro(FreestandingMacroExpansion *expansion,
10621083
return nullptr;
10631084

10641085
BridgedString evaluatedSourceOut{nullptr, 0};
1086+
assert(!externalDef.isError());
10651087
swift_ASTGen_expandFreestandingMacro(
1066-
&ctx.Diags, externalDef->opaqueHandle,
1067-
static_cast<uint32_t>(externalDef->kind), discriminator->c_str(),
1088+
&ctx.Diags, externalDef.opaqueHandle,
1089+
static_cast<uint32_t>(externalDef.kind), discriminator->c_str(),
10681090
getRawMacroRole(macroRole), astGenSourceFile,
10691091
expansion->getSourceRange().Start.getOpaquePointerValue(),
10701092
&evaluatedSourceOut);
@@ -1301,13 +1323,14 @@ static SourceFile *evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo,
13011323
ExternalMacroDefinitionRequest request{
13021324
&ctx, external.moduleName, external.macroTypeName
13031325
};
1304-
auto externalDef = evaluateOrDefault(ctx.evaluator, request, llvm::None);
1305-
if (!externalDef) {
1326+
auto externalDef =
1327+
evaluateOrDefault(ctx.evaluator, request,
1328+
ExternalMacroDefinition::error("failed request"));
1329+
if (externalDef.isError()) {
13061330
attachedTo->diagnose(diag::external_macro_not_found,
1307-
external.moduleName.str(),
1308-
external.macroTypeName.str(),
1309-
macro->getName()
1310-
);
1331+
external.moduleName.str(),
1332+
external.macroTypeName.str(), macro->getName(),
1333+
externalDef.getErrorMessage());
13111334
macro->diagnose(diag::decl_declared_here, macro);
13121335
return nullptr;
13131336
}
@@ -1339,9 +1362,10 @@ static SourceFile *evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo,
13391362
searchDecl = var->getParentPatternBinding();
13401363

13411364
BridgedString evaluatedSourceOut{nullptr, 0};
1365+
assert(!externalDef.isError());
13421366
swift_ASTGen_expandAttachedMacro(
1343-
&ctx.Diags, externalDef->opaqueHandle,
1344-
static_cast<uint32_t>(externalDef->kind), discriminator->c_str(),
1367+
&ctx.Diags, externalDef.opaqueHandle,
1368+
static_cast<uint32_t>(externalDef.kind), discriminator->c_str(),
13451369
extendedType.c_str(), conformanceList.c_str(), getRawMacroRole(role),
13461370
astGenAttrSourceFile, attr->AtLoc.getOpaquePointerValue(),
13471371
astGenDeclSourceFile, searchDecl->getStartLoc().getOpaquePointerValue(),

0 commit comments

Comments
 (0)