Skip to content

Commit 58fa6ca

Browse files
committed
[Macros] Diagnose how ExternalMacroDefinition request was failed
Return the failure reason as the result.
1 parent 27cd7ca commit 58fa6ca

12 files changed

+132
-69
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7298,7 +7298,7 @@ ERROR(macro_undefined,PointsToFirstBadToken,
72987298
"no macro named %0", (Identifier))
72997299
ERROR(external_macro_not_found,none,
73007300
"external macro implementation type '%0.%1' could not be found for "
7301-
"macro %2", (StringRef, StringRef, DeclName))
7301+
"macro %2; %3", (StringRef, StringRef, DeclName, StringRef))
73027302
ERROR(macro_must_be_defined,none,
73037303
"macro %0 requires a definition", (DeclName))
73047304
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
@@ -4272,19 +4272,18 @@ class ExpandPeerMacroRequest
42724272
/// Resolve an external macro given its module and type name.
42734273
class ExternalMacroDefinitionRequest
42744274
: public SimpleRequest<ExternalMacroDefinitionRequest,
4275-
llvm::Optional<ExternalMacroDefinition>(
4276-
ASTContext *, Identifier, Identifier),
4275+
ExternalMacroDefinition(ASTContext *, Identifier,
4276+
Identifier),
42774277
RequestFlags::Cached> {
42784278
public:
42794279
using SimpleRequest::SimpleRequest;
42804280

42814281
private:
42824282
friend SimpleRequest;
42834283

4284-
llvm::Optional<ExternalMacroDefinition> evaluate(
4285-
Evaluator &evaluator, ASTContext *ctx,
4286-
Identifier moduleName, Identifier typeName
4287-
) const;
4284+
ExternalMacroDefinition evaluate(Evaluator &evaluator, ASTContext *ctx,
4285+
Identifier moduleName,
4286+
Identifier typeName) const;
42884287

42894288
public:
42904289
// Source location

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ SWIFT_REQUEST(TypeChecker, CompilerPluginLoadRequest,
457457
LoadedCompilerPlugin(ASTContext *, Identifier),
458458
Cached, NoLocationInfo)
459459
SWIFT_REQUEST(TypeChecker, ExternalMacroDefinitionRequest,
460-
Optional<ExternalMacroDefinition>(ASTContext *, Identifier, Identifier),
460+
ExternalMacroDefinition(ASTContext *, Identifier, Identifier),
461461
Cached, NoLocationInfo)
462462
SWIFT_REQUEST(TypeChecker, ExpandMacroExpansionDeclRequest,
463463
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: 62 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -71,22 +71,21 @@ extern "C" void swift_ASTGen_freeExpansionReplacements(
7171
ptrdiff_t numReplacements);
7272

7373
extern "C" ptrdiff_t swift_ASTGen_expandFreestandingMacro(
74-
void *diagEngine, void *macro, uint8_t externalKind,
74+
void *diagEngine, const void *macro, uint8_t externalKind,
7575
const char *discriminator, ptrdiff_t discriminatorLength,
76-
uint8_t rawMacroRole, void *sourceFile,
77-
const void *sourceLocation, const char **evaluatedSource,
78-
ptrdiff_t *evaluatedSourceLength);
76+
uint8_t rawMacroRole, void *sourceFile, const void *sourceLocation,
77+
const char **evaluatedSource, ptrdiff_t *evaluatedSourceLength);
7978

8079
extern "C" ptrdiff_t swift_ASTGen_expandAttachedMacro(
81-
void *diagEngine, void *macro, uint8_t externalKind,
80+
void *diagEngine, const void *macro, uint8_t externalKind,
8281
const char *discriminator, ptrdiff_t discriminatorLength,
8382
const char *qualifiedType, ptrdiff_t qualifiedTypeLength,
8483
const char *conformances, ptrdiff_t conformancesLength,
85-
uint8_t rawMacroRole,
86-
void *customAttrSourceFile, const void *customAttrSourceLocation,
87-
void *declarationSourceFile, const void *declarationSourceLocation,
88-
void *parentDeclSourceFile, const void *parentDeclSourceLocation,
89-
const char **evaluatedSource, ptrdiff_t *evaluatedSourceLength);
84+
uint8_t rawMacroRole, void *customAttrSourceFile,
85+
const void *customAttrSourceLocation, void *declarationSourceFile,
86+
const void *declarationSourceLocation, void *parentDeclSourceFile,
87+
const void *parentDeclSourceLocation, const char **evaluatedSource,
88+
ptrdiff_t *evaluatedSourceLength);
9089

9190
extern "C" bool swift_ASTGen_initializePlugin(void *handle, void *diagEngine);
9291
extern "C" void swift_ASTGen_deinitializePlugin(void *handle);
@@ -389,7 +388,7 @@ CompilerPluginLoadRequest::evaluate(Evaluator &evaluator, ASTContext *ctx,
389388
return nullptr;
390389
}
391390

392-
static llvm::Optional<ExternalMacroDefinition>
391+
static ExternalMacroDefinition
393392
resolveInProcessMacro(ASTContext &ctx, Identifier moduleName,
394393
Identifier typeName, LoadedLibraryPlugin *plugin) {
395394
#if SWIFT_BUILD_SWIFT_SYNTAX
@@ -406,13 +405,27 @@ resolveInProcessMacro(ASTContext &ctx, Identifier moduleName,
406405

407406
return ExternalMacroDefinition{
408407
ExternalMacroDefinition::PluginKind::InProcess, inProcess};
408+
} else {
409+
NullTerminatedStringRef err(
410+
"type '" + moduleName.str() + "." + typeName.str() +
411+
"' is not a valid macro implementation type in library plugin '" +
412+
StringRef(plugin->getLibraryPath()) + "'",
413+
ctx);
414+
415+
return ExternalMacroDefinition::error(err);
409416
}
410417
}
418+
NullTerminatedStringRef err("macro implementation type '" + moduleName.str() +
419+
"." + typeName.str() +
420+
"' could not be found in library plugin '" +
421+
StringRef(plugin->getLibraryPath()) + "'",
422+
ctx);
423+
return ExternalMacroDefinition::error(err);
411424
#endif
412-
return llvm::None;
425+
return ExternalMacroDefinition::error("macro is not supported");
413426
}
414427

415-
static llvm::Optional<ExternalMacroDefinition>
428+
static ExternalMacroDefinition
416429
resolveExecutableMacro(ASTContext &ctx,
417430
LoadedExecutablePlugin *executablePlugin,
418431
Identifier moduleName, Identifier typeName) {
@@ -426,11 +439,17 @@ resolveExecutableMacro(ASTContext &ctx,
426439
return ExternalMacroDefinition{
427440
ExternalMacroDefinition::PluginKind::Executable, execMacro};
428441
}
442+
NullTerminatedStringRef err(
443+
"macro implementation type '" + moduleName.str() + "." + typeName.str() +
444+
"' could not be found in executable plugin" +
445+
StringRef(executablePlugin->getExecutablePath()),
446+
ctx);
447+
return ExternalMacroDefinition::error(err);
429448
#endif
430-
return llvm::None;
449+
return ExternalMacroDefinition::error("macro is not supported");
431450
}
432451

433-
llvm::Optional<ExternalMacroDefinition>
452+
ExternalMacroDefinition
434453
ExternalMacroDefinitionRequest::evaluate(Evaluator &evaluator, ASTContext *ctx,
435454
Identifier moduleName,
436455
Identifier typeName) const {
@@ -441,19 +460,17 @@ ExternalMacroDefinitionRequest::evaluate(Evaluator &evaluator, ASTContext *ctx,
441460
evaluateOrDefault(evaluator, loadRequest, nullptr);
442461

443462
if (auto loadedLibrary = loaded.getAsLibraryPlugin()) {
444-
if (auto inProcess = resolveInProcessMacro(
445-
*ctx, moduleName, typeName, loadedLibrary))
446-
return *inProcess;
463+
return resolveInProcessMacro(*ctx, moduleName, typeName, loadedLibrary);
447464
}
448465

449466
if (auto *executablePlugin = loaded.getAsExecutablePlugin()) {
450-
if (auto executableMacro = resolveExecutableMacro(*ctx, executablePlugin,
451-
moduleName, typeName)) {
452-
return executableMacro;
453-
}
467+
return resolveExecutableMacro(*ctx, executablePlugin, moduleName, typeName);
454468
}
455469

456-
return llvm::None;
470+
NullTerminatedStringRef err("plugin that can handle module '" +
471+
moduleName.str() + "' not found",
472+
*ctx);
473+
return ExternalMacroDefinition::error(err);
457474
}
458475

459476
/// Adjust the given mangled name for a macro expansion to produce a valid
@@ -1037,11 +1054,14 @@ evaluateFreestandingMacro(FreestandingMacroExpansion *expansion,
10371054
auto external = macroDef.getExternalMacro();
10381055
ExternalMacroDefinitionRequest request{&ctx, external.moduleName,
10391056
external.macroTypeName};
1040-
auto externalDef = evaluateOrDefault(ctx.evaluator, request, llvm::None);
1041-
if (!externalDef) {
1057+
auto externalDef =
1058+
evaluateOrDefault(ctx.evaluator, request,
1059+
ExternalMacroDefinition::error("request error"));
1060+
if (externalDef.isError()) {
10421061
ctx.Diags.diagnose(loc, diag::external_macro_not_found,
10431062
external.moduleName.str(),
1044-
external.macroTypeName.str(), macro->getName());
1063+
external.macroTypeName.str(), macro->getName(),
1064+
externalDef.getErrorMessage());
10451065
macro->diagnose(diag::decl_declared_here, macro);
10461066
return nullptr;
10471067
}
@@ -1072,11 +1092,11 @@ evaluateFreestandingMacro(FreestandingMacroExpansion *expansion,
10721092

10731093
const char *evaluatedSourceAddress;
10741094
ptrdiff_t evaluatedSourceLength;
1095+
assert(!externalDef.isError());
10751096
swift_ASTGen_expandFreestandingMacro(
1076-
&ctx.Diags, externalDef->opaqueHandle,
1077-
static_cast<uint32_t>(externalDef->kind), discriminator->data(),
1078-
discriminator->size(),
1079-
getRawMacroRole(macroRole), astGenSourceFile,
1097+
&ctx.Diags, externalDef.opaqueHandle,
1098+
static_cast<uint32_t>(externalDef.kind), discriminator->data(),
1099+
discriminator->size(), getRawMacroRole(macroRole), astGenSourceFile,
10801100
expansion->getSourceRange().Start.getOpaquePointerValue(),
10811101
&evaluatedSourceAddress, &evaluatedSourceLength);
10821102
if (!evaluatedSourceAddress)
@@ -1312,13 +1332,14 @@ static SourceFile *evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo,
13121332
ExternalMacroDefinitionRequest request{
13131333
&ctx, external.moduleName, external.macroTypeName
13141334
};
1315-
auto externalDef = evaluateOrDefault(ctx.evaluator, request, llvm::None);
1316-
if (!externalDef) {
1335+
auto externalDef =
1336+
evaluateOrDefault(ctx.evaluator, request,
1337+
ExternalMacroDefinition::error("failed request"));
1338+
if (externalDef.isError()) {
13171339
attachedTo->diagnose(diag::external_macro_not_found,
1318-
external.moduleName.str(),
1319-
external.macroTypeName.str(),
1320-
macro->getName()
1321-
);
1340+
external.moduleName.str(),
1341+
external.macroTypeName.str(), macro->getName(),
1342+
externalDef.getErrorMessage());
13221343
macro->diagnose(diag::decl_declared_here, macro);
13231344
return nullptr;
13241345
}
@@ -1351,13 +1372,12 @@ static SourceFile *evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo,
13511372

13521373
const char *evaluatedSourceAddress;
13531374
ptrdiff_t evaluatedSourceLength;
1375+
assert(!externalDef.isError());
13541376
swift_ASTGen_expandAttachedMacro(
1355-
&ctx.Diags, externalDef->opaqueHandle,
1356-
static_cast<uint32_t>(externalDef->kind),
1357-
discriminator->data(), discriminator->size(),
1358-
extendedType.data(), extendedType.size(),
1359-
conformanceList.data(), conformanceList.size(),
1360-
getRawMacroRole(role),
1377+
&ctx.Diags, externalDef.opaqueHandle,
1378+
static_cast<uint32_t>(externalDef.kind), discriminator->data(),
1379+
discriminator->size(), extendedType.data(), extendedType.size(),
1380+
conformanceList.data(), conformanceList.size(), getRawMacroRole(role),
13611381
astGenAttrSourceFile, attr->AtLoc.getOpaquePointerValue(),
13621382
astGenDeclSourceFile, searchDecl->getStartLoc().getOpaquePointerValue(),
13631383
astGenParentDeclSourceFile, parentDeclLoc, &evaluatedSourceAddress,

0 commit comments

Comments
 (0)