Skip to content

Commit f8de332

Browse files
committed
[Macros] Create llvm::MemoryBuffer directly from macro expansion result
Saves one memory copy. No need to create a temporary NullTerminatedStringRef.
1 parent 43eabf1 commit f8de332

File tree

2 files changed

+87
-78
lines changed

2 files changed

+87
-78
lines changed

include/swift/Basic/Lazy.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,25 @@ template <typename Arg1> inline T &Lazy<T>::getWithInit(Arg1 &&arg1) {
7575
return unsafeGetAlreadyInitialized();
7676
}
7777

78+
template <typename T>
79+
class LazyValue {
80+
std::function<T()> Init;
81+
llvm::Optional<T> Value;
82+
83+
public:
84+
LazyValue(std::function<T()> Init) : Init(Init){};
85+
86+
T &get() {
87+
if (!Value.hasValue()) {
88+
Value = Init();
89+
}
90+
return *Value;
91+
}
92+
93+
T *operator->() { return &get(); }
94+
T &operator*() { return get(); }
95+
};
96+
7897
} // end namespace swift
7998

8099
#define SWIFT_LAZY_CONSTANT(INITIAL_VALUE) \

lib/Sema/TypeCheckMacros.cpp

Lines changed: 68 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "swift/AST/SourceFile.h"
3131
#include "swift/AST/TypeCheckRequests.h"
3232
#include "swift/Basic/Defer.h"
33+
#include "swift/Basic/Lazy.h"
3334
#include "swift/Basic/SourceManager.h"
3435
#include "swift/Basic/StringExtras.h"
3536
#include "swift/Demangling/Demangler.h"
@@ -441,6 +442,9 @@ ExternalMacroDefinitionRequest::evaluate(Evaluator &evaluator, ASTContext *ctx,
441442
/// Adjust the given mangled name for a macro expansion to produce a valid
442443
/// buffer name.
443444
static std::string adjustMacroExpansionBufferName(StringRef name) {
445+
if (name.empty()) {
446+
return "<macro-expansion>";
447+
}
444448
std::string result;
445449
if (name.startswith(MANGLING_PREFIX_STR)) {
446450
result += MACRO_EXPANSION_BUFFER_MANGLING_PREFIX;
@@ -677,7 +681,7 @@ Expr *swift::expandMacroExpr(
677681
return nullptr;
678682

679683
// Evaluate the macro.
680-
NullTerminatedStringRef evaluatedSource;
684+
std::unique_ptr<llvm::MemoryBuffer> evaluatedSource;
681685

682686
MacroDecl *macro = cast<MacroDecl>(macroRef.getDecl());
683687

@@ -687,20 +691,15 @@ Expr *swift::expandMacroExpr(
687691
}
688692

689693
/// The discriminator used for the macro.
690-
std::string cachedDiscriminator;
691-
auto getDiscriminator = [&]() -> StringRef {
692-
if (!cachedDiscriminator.empty())
693-
return cachedDiscriminator;
694-
694+
LazyValue<std::string> discriminator([&]() -> std::string {
695695
#if SWIFT_SWIFT_PARSER
696696
if (auto expansionExpr = dyn_cast<MacroExpansionExpr>(expr)) {
697697
Mangle::ASTMangler mangler;
698-
cachedDiscriminator = mangler.mangleMacroExpansion(expansionExpr);
698+
return mangler.mangleMacroExpansion(expansionExpr);
699699
}
700700
#endif
701-
702-
return cachedDiscriminator;
703-
};
701+
return "";
702+
});
704703

705704
auto macroDef = macro->getDefinition();
706705
switch (macroDef.kind) {
@@ -722,8 +721,8 @@ Expr *swift::expandMacroExpr(
722721
// Expand the definition with the given arguments.
723722
auto result = expandMacroDefinition(
724723
macroDef.getExpanded(), macro, expr->getArgs());
725-
llvm::MallocAllocator allocator;
726-
evaluatedSource = NullTerminatedStringRef(result, allocator);
724+
evaluatedSource = llvm::MemoryBuffer::getMemBufferCopy(
725+
result, adjustMacroExpansionBufferName(*discriminator));
727726
break;
728727
}
729728

@@ -757,14 +756,16 @@ Expr *swift::expandMacroExpr(
757756
ptrdiff_t evaluatedSourceLength;
758757
swift_ASTGen_expandFreestandingMacro(
759758
&ctx.Diags, externalDef->opaqueHandle,
760-
static_cast<uint32_t>(externalDef->kind), getDiscriminator().data(),
761-
getDiscriminator().size(), astGenSourceFile,
759+
static_cast<uint32_t>(externalDef->kind), discriminator->data(),
760+
discriminator->size(), astGenSourceFile,
762761
expr->getStartLoc().getOpaquePointerValue(), &evaluatedSourceAddress,
763762
&evaluatedSourceLength);
764763
if (!evaluatedSourceAddress)
765764
return nullptr;
766-
evaluatedSource = NullTerminatedStringRef(evaluatedSourceAddress,
767-
(size_t)evaluatedSourceLength);
765+
evaluatedSource = llvm::MemoryBuffer::getMemBufferCopy(
766+
{evaluatedSourceAddress, (size_t)evaluatedSourceLength},
767+
adjustMacroExpansionBufferName(*discriminator));
768+
free((void *)evaluatedSourceAddress);
768769
break;
769770
#else
770771
ctx.Diags.diagnose(expr->getLoc(), diag::macro_unsupported);
@@ -773,26 +774,18 @@ Expr *swift::expandMacroExpr(
773774
}
774775
}
775776

776-
// Figure out a reasonable name for the macro expansion buffer.
777-
std::string bufferName;
778-
if (getDiscriminator().empty())
779-
bufferName = "macro-expansion";
780-
else {
781-
bufferName = adjustMacroExpansionBufferName(getDiscriminator());
782-
}
783-
784777
// Dump macro expansions to standard output, if requested.
785778
if (ctx.LangOpts.DumpMacroExpansions) {
786-
llvm::errs() << bufferName << " as " << expandedType.getString()
779+
llvm::errs() << evaluatedSource->getBufferIdentifier() << " as "
780+
<< expandedType.getString()
787781
<< "\n------------------------------\n"
788-
<< evaluatedSource
782+
<< evaluatedSource->getBuffer()
789783
<< "\n------------------------------\n";
790784
}
791785

792786
// Create a new source buffer with the contents of the expanded macro.
793-
auto macroBuffer =
794-
llvm::MemoryBuffer::getMemBufferCopy(evaluatedSource, bufferName);
795-
unsigned macroBufferID = sourceMgr.addNewSourceBuffer(std::move(macroBuffer));
787+
unsigned macroBufferID =
788+
sourceMgr.addNewSourceBuffer(std::move(evaluatedSource));
796789
auto macroBufferRange = sourceMgr.getRangeForBuffer(macroBufferID);
797790
GeneratedSourceInfo sourceInfo{
798791
GeneratedSourceInfo::ExpressionMacroExpansion,
@@ -803,7 +796,6 @@ Expr *swift::expandMacroExpr(
803796
dc
804797
};
805798
sourceMgr.setGeneratedSourceInfo(macroBufferID, sourceInfo);
806-
free((void*)evaluatedSource.data());
807799

808800
// Create a source file to hold the macro buffer. This is automatically
809801
// registered with the enclosing module.
@@ -866,7 +858,7 @@ swift::expandFreestandingMacro(MacroExpansionDecl *med) {
866858
return None;
867859

868860
// Evaluate the macro.
869-
NullTerminatedStringRef evaluatedSource;
861+
std::unique_ptr<llvm::MemoryBuffer> evaluatedSource;
870862

871863
MacroDecl *macro = cast<MacroDecl>(med->getMacroRef().getDecl());
872864
auto macroRoles = macro->getMacroRoles();
@@ -880,6 +872,16 @@ swift::expandFreestandingMacro(MacroExpansionDecl *med) {
880872
return None;
881873
}
882874

875+
/// The discriminator used for the macro.
876+
LazyValue<std::string> discriminator([&]() -> std::string {
877+
#if SWIFT_SWIFT_PARSER
878+
Mangle::ASTMangler mangler;
879+
return mangler.mangleMacroExpansion(med);
880+
#else
881+
return ""
882+
#endif
883+
});
884+
883885
auto macroDef = macro->getDefinition();
884886
switch (macroDef.kind) {
885887
case MacroDefinition::Kind::Undefined:
@@ -899,8 +901,8 @@ swift::expandFreestandingMacro(MacroExpansionDecl *med) {
899901
// Expand the definition with the given arguments.
900902
auto result = expandMacroDefinition(
901903
macroDef.getExpanded(), macro, med->getArgs());
902-
llvm::MallocAllocator allocator;
903-
evaluatedSource = NullTerminatedStringRef(result, allocator);
904+
evaluatedSource = llvm::MemoryBuffer::getMemBufferCopy(
905+
result, adjustMacroExpansionBufferName(*discriminator));
904906
break;
905907
}
906908

@@ -945,21 +947,20 @@ swift::expandFreestandingMacro(MacroExpansionDecl *med) {
945947
if (!astGenSourceFile)
946948
return None;
947949

948-
Mangle::ASTMangler mangler;
949-
auto discriminator = mangler.mangleMacroExpansion(med);
950-
951950
const char *evaluatedSourceAddress;
952951
ptrdiff_t evaluatedSourceLength;
953952
swift_ASTGen_expandFreestandingMacro(
954953
&ctx.Diags, externalDef->opaqueHandle,
955-
static_cast<uint32_t>(externalDef->kind), discriminator.data(),
956-
discriminator.size(), astGenSourceFile,
954+
static_cast<uint32_t>(externalDef->kind), discriminator->data(),
955+
discriminator->size(), astGenSourceFile,
957956
med->getStartLoc().getOpaquePointerValue(), &evaluatedSourceAddress,
958957
&evaluatedSourceLength);
959958
if (!evaluatedSourceAddress)
960959
return None;
961-
evaluatedSource = NullTerminatedStringRef(evaluatedSourceAddress,
962-
(size_t)evaluatedSourceLength);
960+
evaluatedSource = llvm::MemoryBuffer::getMemBufferCopy(
961+
{evaluatedSourceAddress, (size_t)evaluatedSourceLength},
962+
adjustMacroExpansionBufferName(*discriminator));
963+
free((void *)evaluatedSourceAddress);
963964
break;
964965
#else
965966
med->diagnose(diag::macro_unsupported);
@@ -968,26 +969,17 @@ swift::expandFreestandingMacro(MacroExpansionDecl *med) {
968969
}
969970
}
970971

971-
// Figure out a reasonable name for the macro expansion buffer.
972-
std::string bufferName;
973-
{
974-
Mangle::ASTMangler mangler;
975-
bufferName = adjustMacroExpansionBufferName(
976-
mangler.mangleMacroExpansion(med));
977-
}
978-
979972
// Dump macro expansions to standard output, if requested.
980973
if (ctx.LangOpts.DumpMacroExpansions) {
981-
llvm::errs() << bufferName
974+
llvm::errs() << evaluatedSource->getBufferIdentifier()
982975
<< "\n------------------------------\n"
983-
<< evaluatedSource
976+
<< evaluatedSource->getBuffer()
984977
<< "\n------------------------------\n";
985978
}
986979

987980
// Create a new source buffer with the contents of the expanded macro.
988-
auto macroBuffer =
989-
llvm::MemoryBuffer::getMemBufferCopy(evaluatedSource, bufferName);
990-
unsigned macroBufferID = sourceMgr.addNewSourceBuffer(std::move(macroBuffer));
981+
unsigned macroBufferID =
982+
sourceMgr.addNewSourceBuffer(std::move(evaluatedSource));
991983
auto macroBufferRange = sourceMgr.getRangeForBuffer(macroBufferID);
992984
GeneratedSourceInfo sourceInfo{
993985
GeneratedSourceInfo::FreestandingDeclMacroExpansion,
@@ -998,7 +990,6 @@ swift::expandFreestandingMacro(MacroExpansionDecl *med) {
998990
dc
999991
};
1000992
sourceMgr.setGeneratedSourceInfo(macroBufferID, sourceInfo);
1001-
free((void*)evaluatedSource.data());
1002993

1003994
// Create a source file to hold the macro buffer. This is automatically
1004995
// registered with the enclosing module.
@@ -1092,9 +1083,16 @@ evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo, CustomAttr *attr,
10921083
}
10931084

10941085
// Evaluate the macro.
1095-
NullTerminatedStringRef evaluatedSource;
1086+
std::unique_ptr<llvm::MemoryBuffer> evaluatedSource;
10961087

1097-
std::string discriminator;
1088+
LazyValue<std::string> discriminator([&]() -> std::string {
1089+
#if SWIFT_SWIFT_PARSER
1090+
Mangle::ASTMangler mangler;
1091+
return mangler.mangleAttachedMacroExpansion(attachedTo, attr, role);
1092+
#else
1093+
return "";
1094+
#endif
1095+
});
10981096
auto macroDef = macro->getDefinition();
10991097
switch (macroDef.kind) {
11001098
case MacroDefinition::Kind::Undefined:
@@ -1115,7 +1113,8 @@ evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo, CustomAttr *attr,
11151113
auto result = expandMacroDefinition(
11161114
macroDef.getExpanded(), macro, attr->getArgs());
11171115
llvm::MallocAllocator allocator;
1118-
evaluatedSource = NullTerminatedStringRef(result, allocator);
1116+
evaluatedSource = llvm::MemoryBuffer::getMemBufferCopy(
1117+
result, adjustMacroExpansionBufferName(*discriminator));
11191118
break;
11201119
}
11211120

@@ -1161,26 +1160,22 @@ evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo, CustomAttr *attr,
11611160
if (auto var = dyn_cast<VarDecl>(attachedTo))
11621161
searchDecl = var->getParentPatternBinding();
11631162

1164-
{
1165-
Mangle::ASTMangler mangler;
1166-
discriminator =
1167-
mangler.mangleAttachedMacroExpansion(attachedTo, attr, role);
1168-
}
1169-
11701163
const char *evaluatedSourceAddress;
11711164
ptrdiff_t evaluatedSourceLength;
11721165
swift_ASTGen_expandAttachedMacro(
11731166
&ctx.Diags, externalDef->opaqueHandle,
1174-
static_cast<uint32_t>(externalDef->kind), discriminator.data(),
1175-
discriminator.size(), static_cast<uint32_t>(role), astGenAttrSourceFile,
1176-
attr->AtLoc.getOpaquePointerValue(), astGenDeclSourceFile,
1177-
searchDecl->getStartLoc().getOpaquePointerValue(),
1167+
static_cast<uint32_t>(externalDef->kind), discriminator->data(),
1168+
discriminator->size(), static_cast<uint32_t>(role),
1169+
astGenAttrSourceFile, attr->AtLoc.getOpaquePointerValue(),
1170+
astGenDeclSourceFile, searchDecl->getStartLoc().getOpaquePointerValue(),
11781171
astGenParentDeclSourceFile, parentDeclLoc, &evaluatedSourceAddress,
11791172
&evaluatedSourceLength);
11801173
if (!evaluatedSourceAddress)
11811174
return nullptr;
1182-
evaluatedSource = NullTerminatedStringRef(evaluatedSourceAddress,
1183-
(size_t)evaluatedSourceLength);
1175+
evaluatedSource = llvm::MemoryBuffer::getMemBufferCopy(
1176+
{evaluatedSourceAddress, (size_t)evaluatedSourceLength},
1177+
adjustMacroExpansionBufferName(*discriminator));
1178+
free((void *)evaluatedSourceAddress);
11841179
break;
11851180
#else
11861181
attachedTo->diagnose(diag::macro_unsupported);
@@ -1189,14 +1184,11 @@ evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo, CustomAttr *attr,
11891184
}
11901185
}
11911186

1192-
// Figure out a reasonable name for the macro expansion buffer.
1193-
std::string bufferName = adjustMacroExpansionBufferName(discriminator);
1194-
11951187
// Dump macro expansions to standard output, if requested.
11961188
if (ctx.LangOpts.DumpMacroExpansions) {
1197-
llvm::errs() << bufferName
1189+
llvm::errs() << evaluatedSource->getBufferIdentifier()
11981190
<< "\n------------------------------\n"
1199-
<< evaluatedSource
1191+
<< evaluatedSource->getBuffer()
12001192
<< "\n------------------------------\n";
12011193
}
12021194

@@ -1284,9 +1276,8 @@ evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo, CustomAttr *attr,
12841276
}
12851277

12861278
// Create a new source buffer with the contents of the expanded macro.
1287-
auto macroBuffer =
1288-
llvm::MemoryBuffer::getMemBufferCopy(evaluatedSource, bufferName);
1289-
unsigned macroBufferID = sourceMgr.addNewSourceBuffer(std::move(macroBuffer));
1279+
unsigned macroBufferID =
1280+
sourceMgr.addNewSourceBuffer(std::move(evaluatedSource));
12901281
auto macroBufferRange = sourceMgr.getRangeForBuffer(macroBufferID);
12911282
GeneratedSourceInfo sourceInfo{
12921283
generatedSourceKind,
@@ -1297,7 +1288,6 @@ evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo, CustomAttr *attr,
12971288
attr
12981289
};
12991290
sourceMgr.setGeneratedSourceInfo(macroBufferID, sourceInfo);
1300-
free((void*)evaluatedSource.data());
13011291

13021292
// Create a source file to hold the macro buffer. This is automatically
13031293
// registered with the enclosing module.

0 commit comments

Comments
 (0)