Skip to content

Commit 3612a35

Browse files
committed
[Macros] Add (de-)serialization for expanded macro definitions
(cherry picked from commit 38230b7)
1 parent f3e3a72 commit 3612a35

File tree

7 files changed

+113
-2
lines changed

7 files changed

+113
-2
lines changed

lib/AST/ASTVerifier.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,7 @@ class Verifier : public ASTWalker {
769769
FUNCTION_LIKE(FuncDecl)
770770
FUNCTION_LIKE(EnumElementDecl)
771771
FUNCTION_LIKE(SubscriptDecl)
772+
FUNCTION_LIKE(MacroDecl)
772773
TYPE_LIKE(NominalTypeDecl)
773774
TYPE_LIKE(ExtensionDecl)
774775

lib/Serialization/DeclTypeRecordNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ OTHER(PRIVATE_DISCRIMINATOR, 128)
184184
OTHER(FILENAME_FOR_PRIVATE, 129)
185185

186186
OTHER(DESERIALIZATION_SAFETY, 130)
187+
OTHER(EXPANDED_MACRO_DEFINITION, 131)
188+
OTHER(EXPANDED_MACRO_REPLACEMENTS, 132)
187189

188190
// 140 is unused; was ABSTRACT_PROTOCOL_CONFORMANCE
189191
OTHER(NORMAL_PROTOCOL_CONFORMANCE, 141)

lib/Serialization/Deserialization.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4676,6 +4676,7 @@ class DeclDeserializer {
46764676
uint8_t rawAccessLevel;
46774677
unsigned numArgNames;
46784678
unsigned builtinID;
4679+
uint8_t hasExpandedMacroDefinition;
46794680
IdentifierID externalModuleNameID;
46804681
IdentifierID externalMacroTypeNameID;
46814682

@@ -4689,6 +4690,7 @@ class DeclDeserializer {
46894690
rawAccessLevel,
46904691
numArgNames,
46914692
builtinID,
4693+
hasExpandedMacroDefinition,
46924694
externalModuleNameID,
46934695
externalMacroTypeNameID,
46944696
argNameAndDependencyIDs);
@@ -4782,6 +4784,58 @@ class DeclDeserializer {
47824784
MF.getIdentifier(externalMacroTypeNameID)
47834785
)
47844786
);
4787+
} else if (hasExpandedMacroDefinition) {
4788+
// Macro expansion definition block.
4789+
llvm::BitstreamEntry entry =
4790+
MF.fatalIfUnexpected(MF.DeclTypeCursor.advance(AF_DontPopBlockAtEnd));
4791+
if (entry.Kind != llvm::BitstreamEntry::Record)
4792+
return macro;
4793+
4794+
SmallVector<uint64_t, 16> scratch;
4795+
scratch.clear();
4796+
StringRef expansionText;
4797+
unsigned recordID = MF.fatalIfUnexpected(
4798+
MF.DeclTypeCursor.readRecord(entry.ID, scratch, &expansionText));
4799+
if (recordID != decls_block::EXPANDED_MACRO_DEFINITION)
4800+
return macro;
4801+
4802+
uint8_t hasReplacements;
4803+
decls_block::ExpandedMacroDefinitionLayout::readRecord(
4804+
scratch, hasReplacements);
4805+
4806+
// Macro replacements block.
4807+
SmallVector<ExpandedMacroReplacement, 2> replacements;
4808+
if (hasReplacements) {
4809+
llvm::BitstreamEntry entry =
4810+
MF.fatalIfUnexpected(
4811+
MF.DeclTypeCursor.advance(AF_DontPopBlockAtEnd));
4812+
if (entry.Kind == llvm::BitstreamEntry::Record) {
4813+
scratch.clear();
4814+
unsigned recordID = MF.fatalIfUnexpected(
4815+
MF.DeclTypeCursor.readRecord(entry.ID, scratch, &blobData));
4816+
if (recordID != decls_block::EXPANDED_MACRO_REPLACEMENTS)
4817+
return macro;
4818+
4819+
ArrayRef<uint64_t> serializedReplacements;
4820+
decls_block::ExpandedMacroReplacementsLayout::readRecord(
4821+
scratch, serializedReplacements);
4822+
if (serializedReplacements.size() % 3 == 0) {
4823+
for (unsigned i : range(0, serializedReplacements.size() / 3)) {
4824+
ExpandedMacroReplacement replacement{
4825+
static_cast<unsigned>(serializedReplacements[3*i]),
4826+
static_cast<unsigned>(serializedReplacements[3*i + 1]),
4827+
static_cast<unsigned>(serializedReplacements[3*i + 2])
4828+
};
4829+
replacements.push_back(replacement);
4830+
}
4831+
}
4832+
}
4833+
}
4834+
4835+
ctx.evaluator.cacheOutput(
4836+
MacroDefinitionRequest{macro},
4837+
MacroDefinition::forExpanded(ctx, expansionText, replacements)
4838+
);
47854839
}
47864840

47874841
return macro;

lib/Serialization/ModuleFormat.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5858
/// describe what change you made. The content of this comment isn't important;
5959
/// it just ensures a conflict if two people change the module format.
6060
/// Don't worry about adhering to the 80-column limit for this line.
61-
const uint16_t SWIFTMODULE_VERSION_MINOR = 756; // build complexEquality executor builtin
61+
const uint16_t SWIFTMODULE_VERSION_MINOR = 757; // expanded macro definitions
6262

6363
/// A standard hash seed used for all string hashes in a serialized module.
6464
///
@@ -1726,13 +1726,30 @@ namespace decls_block {
17261726
AccessLevelField, // access level
17271727
BCVBR<5>, // number of parameter name components
17281728
BCVBR<3>, // builtin macro definition ID
1729+
BCFixed<1>, // whether it has an expanded macro definition
17291730
IdentifierIDField, // external module name, for external macros
17301731
IdentifierIDField, // external type name, for external macros
17311732
BCArray<IdentifierIDField> // name components,
17321733
// followed by TypeID dependencies
17331734
// The record is trailed by:
17341735
// - its generic parameters, if any
17351736
// - parameter list, if present
1737+
// - expanded macro definition, if needed.
1738+
>;
1739+
1740+
/// The expanded macro definition text.
1741+
using ExpandedMacroDefinitionLayout = BCRecordLayout<
1742+
EXPANDED_MACRO_DEFINITION,
1743+
BCFixed<1>, // whether it has replacements
1744+
BCBlob // expansion text
1745+
// potentially trailed by the expanded macro replacements
1746+
>;
1747+
1748+
/// The replacements to be performed for an expanded macro definition.
1749+
using ExpandedMacroReplacementsLayout = BCRecordLayout<
1750+
EXPANDED_MACRO_REPLACEMENTS,
1751+
BCArray<BCVBR<6>> // a set of replacement triples (start offset,
1752+
// end offset, parameter index)
17361753
>;
17371754

17381755
using InlinableBodyTextLayout = BCRecordLayout<

lib/Serialization/Serialization.cpp

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4590,8 +4590,10 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
45904590
Type resultType = macro->getResultInterfaceType();
45914591

45924592
uint8_t builtinID = 0;
4593+
uint8_t hasExpandedDefinition = 0;
45934594
IdentifierID externalModuleNameID = 0;
45944595
IdentifierID externalMacroTypeNameID = 0;
4596+
Optional<ExpandedMacroDefinition> expandedDef;
45954597
auto def = macro->getDefinition();
45964598
switch (def.kind) {
45974599
case MacroDefinition::Kind::Invalid:
@@ -4615,7 +4617,9 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
46154617
}
46164618

46174619
case MacroDefinition::Kind::Expanded: {
4618-
llvm_unreachable("No serialization support yet");
4620+
expandedDef = def.getExpanded();
4621+
hasExpandedDefinition = 1;
4622+
break;
46194623
}
46204624
}
46214625

@@ -4630,13 +4634,40 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
46304634
rawAccessLevel,
46314635
macro->getName().getArgumentNames().size(),
46324636
builtinID,
4637+
hasExpandedDefinition,
46334638
externalModuleNameID,
46344639
externalMacroTypeNameID,
46354640
nameComponentsAndDependencies);
46364641

46374642
writeGenericParams(macro->getGenericParams());
46384643
if (macro->parameterList)
46394644
writeParameterList(macro->parameterList);
4645+
4646+
if (expandedDef) {
4647+
// Source text for the expanded macro definition layout.
4648+
uint8_t hasReplacements = !expandedDef->getReplacements().empty();
4649+
unsigned abbrCode =
4650+
S.DeclTypeAbbrCodes[ExpandedMacroDefinitionLayout::Code];
4651+
ExpandedMacroDefinitionLayout::emitRecord(
4652+
S.Out, S.ScratchRecord, abbrCode,
4653+
hasReplacements,
4654+
expandedDef->getExpansionText());
4655+
4656+
// If there are any replacements, emit a replacements record.
4657+
if (!hasReplacements) {
4658+
SmallVector<uint64_t, 3> replacements;
4659+
for (const auto &replacement : expandedDef->getReplacements()) {
4660+
replacements.push_back(replacement.startOffset);
4661+
replacements.push_back(replacement.endOffset);
4662+
replacements.push_back(replacement.parameterIndex);
4663+
}
4664+
4665+
unsigned abbrCode =
4666+
S.DeclTypeAbbrCodes[ExpandedMacroReplacementsLayout::Code];
4667+
ExpandedMacroReplacementsLayout::emitRecord(
4668+
S.Out, S.ScratchRecord, abbrCode, replacements);
4669+
}
4670+
}
46404671
}
46414672

46424673
void visitTopLevelCodeDecl(const TopLevelCodeDecl *) {
@@ -5615,6 +5646,8 @@ void Serializer::writeAllDeclsAndTypes() {
56155646
registerDeclTypeAbbr<PrivateDiscriminatorLayout>();
56165647
registerDeclTypeAbbr<FilenameForPrivateLayout>();
56175648
registerDeclTypeAbbr<DeserializationSafetyLayout>();
5649+
registerDeclTypeAbbr<ExpandedMacroDefinitionLayout>();
5650+
registerDeclTypeAbbr<ExpandedMacroReplacementsLayout>();
56185651
registerDeclTypeAbbr<MembersLayout>();
56195652
registerDeclTypeAbbr<XRefLayout>();
56205653

test/Serialization/Inputs/def_macros.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
@freestanding(expression) public macro publicStringify<T>(_ value: T, label: String? = nil) -> (T, String) = #externalMacro(module: "MacroDefinition", type: "StringifyMacro")
22

3+
@freestanding(expression) public macro unlabeledStringify<T>(_ value: T) -> (T, String) = #publicStringify(value, label: "default label")
4+
5+
36
@freestanding(expression) macro internalStringify<T>(_ value: T) -> (T, String) = #externalMacro(module: "MacroDefinition", type: "StringifyMacro")
47

58
@attached(accessor) public macro myWrapper() = #externalMacro(module: "MacroDefinition", type: "MyWrapperMacro")

test/Serialization/macros.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import def_macros
1414
func test(a: Int, b: Int) {
1515
_ = #publicStringify(a + b)
1616
_ = #publicStringify(a + b, label: "hello")
17+
_ = #unlabeledStringify(a + b)
1718

1819
_ = #internalStringify(a + b)
1920
// expected-error@-1{{no macro named 'internalStringify'}}

0 commit comments

Comments
 (0)