Skip to content

Commit f98842b

Browse files
committed
[Macros] Unify the creation of the macro evaluation context.
We had two implementations of the code that forms the macro evaluation context buffer, one in ASTGen and one in Sema. Unify them into a single place, and unify the creation of macros so we localize this arcane knowledge.
1 parent 16f81fb commit f98842b

File tree

3 files changed

+111
-70
lines changed

3 files changed

+111
-70
lines changed

include/swift/AST/Macro.h

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,6 @@ namespace swift {
5959
/// The type signature of the macro.
6060
const Type signature;
6161

62-
/// Documentation for the macro.
63-
const StringRef documentation;
64-
6562
/// The module with which this macro is associated.
6663
ModuleDecl * const owningModule;
6764

@@ -75,18 +72,14 @@ namespace swift {
7572
Macro(
7673
Kind kind, ImplementationKind implementationKind, Identifier name,
7774
GenericSignature genericSignature, Type signature,
78-
StringRef documentation, ModuleDecl *owningModule,
75+
ModuleDecl *owningModule,
7976
ArrayRef<ModuleDecl *> supplementalSignatureModules,
8077
void *opaqueHandle
8178
) : kind(kind), implementationKind(implementationKind), name(name),
8279
genericSignature(genericSignature), signature(signature),
83-
documentation(documentation), owningModule(owningModule),
80+
owningModule(owningModule),
8481
supplementalSignatureModules(supplementalSignatureModules),
8582
opaqueHandle(opaqueHandle) { }
86-
87-
/// Whether this is a "function-like" macro, meaning that it's expected
88-
/// to have function call arguments.
89-
bool isFunctionLike() const;
9083
};
9184
}
9285

lib/ASTGen/Sources/ASTGen/Macros.swift

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -82,26 +82,33 @@ private func allocateUTF8String(
8282
}
8383
}
8484

85-
/// Query the type signature of the given macro.
86-
@_cdecl("swift_ASTGen_getMacroTypeSignature")
87-
public func getMacroTypeSignature(
85+
@_cdecl("swift_ASTGen_getMacroGenericSignature")
86+
public func getMacroGenericSignature(
8887
macroPtr: UnsafeMutablePointer<UInt8>,
89-
evaluationContextPtr: UnsafeMutablePointer<UnsafePointer<UInt8>?>,
90-
evaluationContextLengthPtr: UnsafeMutablePointer<Int>
88+
genericSignaturePtr: UnsafeMutablePointer<UnsafePointer<UInt8>?>,
89+
genericSignatureLengthPtr: UnsafeMutablePointer<Int>
9190
) {
9291
macroPtr.withMemoryRebound(to: ExportedMacro.self, capacity: 1) { macro in
93-
(evaluationContextPtr.pointee, evaluationContextLengthPtr.pointee) =
94-
allocateUTF8String(macro.pointee.evaluationContext, nullTerminated: true)
92+
guard let genericSig = macro.pointee.macro.genericSignature else {
93+
(genericSignaturePtr.pointee, genericSignatureLengthPtr.pointee) = (nil, 0)
94+
return
95+
}
96+
97+
(genericSignaturePtr.pointee, genericSignatureLengthPtr.pointee) =
98+
allocateUTF8String(genericSig.description)
9599
}
96100
}
97101

98-
extension ExportedMacro {
99-
var evaluationContext: String {
100-
"""
101-
struct __MacroEvaluationContext\(self.macro.genericSignature?.description ?? "") {
102-
typealias SignatureType = \(self.macro.signature)
103-
}
104-
"""
102+
/// Query the type signature of the given macro.
103+
@_cdecl("swift_ASTGen_getMacroTypeSignature")
104+
public func getMacroTypeSignature(
105+
macroPtr: UnsafeMutablePointer<UInt8>,
106+
signaturePtr: UnsafeMutablePointer<UnsafePointer<UInt8>?>,
107+
signatureLengthPtr: UnsafeMutablePointer<Int>
108+
) {
109+
macroPtr.withMemoryRebound(to: ExportedMacro.self, capacity: 1) { macro in
110+
(signaturePtr.pointee, signatureLengthPtr.pointee) =
111+
allocateUTF8String(macro.pointee.macro.signature.description)
105112
}
106113
}
107114

lib/Sema/TypeCheckMacros.cpp

Lines changed: 88 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "swift/AST/Macro.h"
2323
#include "swift/AST/SourceFile.h"
2424
#include "swift/AST/TypeCheckRequests.h"
25+
#include "swift/Basic/Defer.h"
2526
#include "swift/Basic/SourceManager.h"
2627
#include "swift/Basic/StringExtras.h"
2728
#include "swift/Parse/Lexer.h"
@@ -43,13 +44,17 @@ extern "C" ptrdiff_t swift_ASTGen_evaluateMacro(
4344
void *sourceFile, const void *sourceLocation,
4445
const char **evaluatedSource, ptrdiff_t *evaluatedSourceLength);
4546

47+
extern "C" void
48+
swift_ASTGen_getMacroGenericSignature(void *macro,
49+
const char **genericSignaturePtr,
50+
ptrdiff_t *genericSignatureLengthPtr);
51+
4652
extern "C" void
4753
swift_ASTGen_getMacroTypeSignature(void *macro,
48-
const char **evaluationContextPtr,
49-
ptrdiff_t *evaluationContextLengthPtr);
54+
const char **signaturePtr,
55+
ptrdiff_t *signatureLengthPtr);
5056

51-
/// Compute the macro signature given the the source containing macro signature
52-
/// source.
57+
/// Create a new macro signature context buffer describing the macro signature.
5358
///
5459
/// The macro signature is a user-defined generic signature and return
5560
/// type that serves as the "interface type" of references to the macro. The
@@ -66,14 +71,38 @@ swift_ASTGen_getMacroTypeSignature(void *macro,
6671
/// facilities to map the parsed signature type back into a semantic
6772
/// \c GenericSignature and \c Type ASTs. The macro signature source above is
6873
/// provided via \c signatureSource.
74+
static NullTerminatedStringRef
75+
getMacroSignatureContextBuffer(
76+
ASTContext &ctx, Optional<StringRef> genericSignature,
77+
StringRef typeSignature
78+
) {
79+
std::string source;
80+
llvm::raw_string_ostream out(source);
81+
out << "struct __MacroEvaluationContext"
82+
<< (genericSignature ? *genericSignature : "") << " {\n"
83+
<< " typealias SignatureType = " << typeSignature << "\n"
84+
<< "}";
85+
auto len = source.length();
86+
auto *buffer = (char *)malloc(len + 1);
87+
memcpy(buffer, source.data(), len + 1);
88+
return {buffer, len};
89+
}
90+
91+
/// Compute the macro signature for a macro given the source code for its
92+
/// generic signature and type signature.
6993
static Optional<std::pair<GenericSignature, Type>>
7094
getMacroSignature(
7195
ModuleDecl *mod, Identifier macroName,
72-
NullTerminatedStringRef signatureSource
96+
Optional<StringRef> genericSignature,
97+
StringRef typeSignature
7398
) {
99+
// Form a buffer containing the macro signature context.
100+
ASTContext &ctx = mod->getASTContext();
101+
StringRef signatureSource = getMacroSignatureContextBuffer(
102+
ctx, genericSignature, typeSignature);
103+
74104
// Create a new source buffer with the contents of the macro's
75105
// signature.
76-
ASTContext &ctx = mod->getASTContext();
77106
SourceManager &sourceMgr = ctx.SourceMgr;
78107
std::string bufferName;
79108
{
@@ -115,20 +144,16 @@ getMacroSignature(
115144
signature->getGenericSignature(), signature->getUnderlyingType());
116145
}
117146

118-
/// Create a builtin macro.
119-
static Macro *createBuiltinMacro(
120-
ModuleDecl *mod, Identifier macroName, void *opaqueHandle) {
121-
// Form the macro type signature.
122-
const char *evaluatedSourcePtr;
123-
ptrdiff_t evaluatedSourceLength;
124-
swift_ASTGen_getMacroTypeSignature(opaqueHandle, &evaluatedSourcePtr,
125-
&evaluatedSourceLength);
126-
147+
/// Create a macro.
148+
static Macro *createMacro(
149+
ModuleDecl *mod, Identifier macroName,
150+
Macro::ImplementationKind implKind,
151+
Optional<StringRef> genericSignature, StringRef typeSignature,
152+
void* opaqueHandle
153+
) {
127154
// Get the type signature of the macro.
128155
auto signature = getMacroSignature(
129-
mod, macroName,
130-
NullTerminatedStringRef(
131-
evaluatedSourcePtr,(size_t)evaluatedSourceLength));
156+
mod, macroName, genericSignature, typeSignature);
132157
if (!signature) {
133158
// FIXME: Swap in ErrorTypes, perhaps?
134159
return nullptr;
@@ -137,45 +162,61 @@ static Macro *createBuiltinMacro(
137162
// FIXME: All macros are expression macros right now
138163
ASTContext &ctx = mod->getASTContext();
139164
return new (ctx) Macro(
140-
Macro::Expression, Macro::ImplementationKind::Builtin, macroName,
141-
signature->first, signature->second, /*FIXME:Documentation*/StringRef(),
165+
Macro::Expression, implKind, macroName,
166+
signature->first, signature->second,
142167
/*FIXME:owningModule*/mod, /*FIXME:supplementalImportModules*/{},
143168
opaqueHandle);
144169
}
145170

146-
static NullTerminatedStringRef
147-
getPluginMacroTypeSignature(CompilerPlugin *plugin, ASTContext &ctx) {
148-
auto genSig = plugin->invokeGenericSignature();
149-
auto typeSig = plugin->invokeTypeSignature();
150-
std::string source;
151-
llvm::raw_string_ostream out(source);
152-
out << "struct __MacroEvaluationContext" << (genSig ? *genSig : "") << " {\n"
153-
<< " typealias SignatureType = " << typeSig << "\n"
154-
<< "}";
155-
auto len = source.length();
156-
auto *buffer = (char *)malloc(len + 1);
157-
memcpy(buffer, source.data(), len + 1);
158-
return {buffer, len};
171+
/// Create a builtin macro.
172+
static Macro *createBuiltinMacro(
173+
ModuleDecl *mod, Identifier macroName, void *opaqueHandle) {
174+
// Form the macro generic signature.
175+
const char *genericSignaturePtr;
176+
ptrdiff_t genericSignatureLength;
177+
swift_ASTGen_getMacroGenericSignature(opaqueHandle, &genericSignaturePtr,
178+
&genericSignatureLength);
179+
SWIFT_DEFER {
180+
free((void*)genericSignaturePtr);
181+
};
182+
183+
Optional<StringRef> genericSignature;
184+
if (genericSignaturePtr && genericSignatureLength)
185+
genericSignature = StringRef(genericSignaturePtr, genericSignatureLength);
186+
187+
// Form the macro type signature.
188+
const char *typeSignaturePtr;
189+
ptrdiff_t typeSignatureLength;
190+
swift_ASTGen_getMacroTypeSignature(opaqueHandle, &typeSignaturePtr,
191+
&typeSignatureLength);
192+
SWIFT_DEFER {
193+
free((void*)typeSignaturePtr);
194+
};
195+
StringRef typeSignature = StringRef(typeSignaturePtr, typeSignatureLength);
196+
197+
return createMacro(
198+
mod, macroName, Macro::ImplementationKind::Builtin,
199+
genericSignature, typeSignature,
200+
opaqueHandle);
159201
}
160202

161203
/// Create a plugin-based macro.
162204
static Macro *createPluginMacro(
163205
ModuleDecl *mod, Identifier macroName, CompilerPlugin *plugin) {
164-
// Get the type signature of the macro.
165-
ASTContext &ctx = mod->getASTContext();
166-
auto signature = getMacroSignature(
167-
mod, macroName, getPluginMacroTypeSignature(plugin, ctx));
168-
if (!signature) {
169-
// FIXME: Swap in ErrorTypes, perhaps?
170-
return nullptr;
171-
}
206+
auto genSignature = plugin->invokeGenericSignature();
207+
SWIFT_DEFER {
208+
if (genSignature)
209+
free((void*)genSignature->data());
210+
};
172211

173-
// FIXME: All macros are expression macros right now
174-
return new (ctx) Macro(
175-
Macro::Expression, Macro::ImplementationKind::Plugin, macroName,
176-
signature->first, signature->second, /*FIXME:Documentation*/StringRef(),
177-
/*FIXME:owningModule*/mod, /*FIXME:supplementalImportModules*/{},
178-
plugin);
212+
auto typeSignature = plugin->invokeTypeSignature();
213+
SWIFT_DEFER {
214+
free((void*)typeSignature.data());
215+
};
216+
217+
return createMacro(
218+
mod, macroName, Macro::ImplementationKind::Plugin, genSignature,
219+
typeSignature, plugin);
179220
}
180221

181222
ArrayRef<Macro *> MacroLookupRequest::evaluate(

0 commit comments

Comments
 (0)