Skip to content

Commit 8185db4

Browse files
committed
[Serialization] Add a "unavailable" bit to conditional substitution record
A step towards supporting different opaque result type produced by a `if #unavailable` block.
1 parent 0fdba62 commit 8185db4

File tree

4 files changed

+62
-22
lines changed

4 files changed

+62
-22
lines changed

lib/Serialization/DeclTypeRecordNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ OTHER(DERIVATIVE_FUNCTION_CONFIGURATION, 154)
199199
OTHER(ERROR_FLAG, 155)
200200

201201
TRAILING_INFO(CONDITIONAL_SUBSTITUTION)
202+
TRAILING_INFO(CONDITIONAL_SUBSTITUTION_COND)
202203

203204
#ifndef DECL_ATTR
204205
#define DECL_ATTR(NAME, CLASS, OPTIONS, CODE) RECORD_VAL(CLASS##_DECL_ATTR, 180+CODE)

lib/Serialization/Deserialization.cpp

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3548,6 +3548,39 @@ class DeclDeserializer {
35483548
return deserializeAnyFunc(scratch, blobData, /*isAccessor*/true);
35493549
}
35503550

3551+
void deserializeConditionalSubstitutionConditions(
3552+
SmallVectorImpl<VersionRange> &conditions) {
3553+
using namespace decls_block;
3554+
3555+
SmallVector<uint64_t, 4> scratch;
3556+
StringRef blobData;
3557+
3558+
while (true) {
3559+
llvm::BitstreamEntry entry =
3560+
MF.fatalIfUnexpected(MF.DeclTypeCursor.advance(AF_DontPopBlockAtEnd));
3561+
if (entry.Kind != llvm::BitstreamEntry::Record)
3562+
break;
3563+
3564+
scratch.clear();
3565+
3566+
unsigned recordID = MF.fatalIfUnexpected(
3567+
MF.DeclTypeCursor.readRecord(entry.ID, scratch, &blobData));
3568+
if (recordID != decls_block::CONDITIONAL_SUBSTITUTION_COND)
3569+
break;
3570+
3571+
bool isUnavailability;
3572+
DEF_VER_TUPLE_PIECES(condition);
3573+
3574+
ConditionalSubstitutionConditionLayout::readRecord(
3575+
scratch, isUnavailability, LIST_VER_TUPLE_PIECES(condition));
3576+
3577+
llvm::VersionTuple condition;
3578+
DECODE_VER_TUPLE(condition);
3579+
3580+
conditions.push_back(VersionRange::allGTE(condition));
3581+
}
3582+
}
3583+
35513584
void deserializeConditionalSubstitutions(
35523585
SmallVectorImpl<OpaqueTypeDecl::ConditionallyAvailableSubstitutions *>
35533586
&limitedAvailability) {
@@ -3566,20 +3599,16 @@ class DeclDeserializer {
35663599
if (recordID != decls_block::CONDITIONAL_SUBSTITUTION)
35673600
break;
35683601

3569-
ArrayRef<uint64_t> rawConditions;
35703602
SubstitutionMapID substitutionMapRef;
35713603

35723604
decls_block::ConditionalSubstitutionLayout::readRecord(
3573-
scratch, substitutionMapRef, rawConditions);
3574-
3575-
SmallVector<VersionRange, 4> conditions;
3576-
llvm::transform(rawConditions, std::back_inserter(conditions),
3577-
[&](uint64_t id) {
3578-
llvm::VersionTuple lowerEndpoint;
3579-
if (lowerEndpoint.tryParse(MF.getIdentifier(id).str()))
3580-
MF.fatal();
3581-
return VersionRange::allGTE(lowerEndpoint);
3582-
});
3605+
scratch, substitutionMapRef);
3606+
3607+
SmallVector<VersionRange, 2> conditions;
3608+
deserializeConditionalSubstitutionConditions(conditions);
3609+
3610+
if (conditions.empty())
3611+
MF.fatal();
35833612

35843613
auto subMapOrError = MF.getSubstitutionMapChecked(substitutionMapRef);
35853614
if (!subMapOrError)

lib/Serialization/ModuleFormat.h

Lines changed: 10 additions & 3 deletions
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 = 697; // change local type mangling
61+
const uint16_t SWIFTMODULE_VERSION_MINOR = 698; // opaque decl with unavailability conditions
6262

6363
/// A standard hash seed used for all string hashes in a serialized module.
6464
///
@@ -1462,10 +1462,17 @@ namespace decls_block {
14621462
// - inlinable body text, if any
14631463
>;
14641464

1465+
using ConditionalSubstitutionConditionLayout = BCRecordLayout<
1466+
CONDITIONAL_SUBSTITUTION_COND,
1467+
BCFixed<1>, // is unavailable?
1468+
BC_AVAIL_TUPLE // the OS version triple.
1469+
>;
1470+
14651471
using ConditionalSubstitutionLayout = BCRecordLayout<
14661472
CONDITIONAL_SUBSTITUTION,
1467-
SubstitutionMapIDField,
1468-
BCArray<IdentifierIDField> // N conditions where each is <major>.<minor>.<patch>
1473+
SubstitutionMapIDField
1474+
// Trailed by N conditions that include a version and
1475+
// unavailability indicator.
14691476
>;
14701477

14711478
using OpaqueTypeLayout = BCRecordLayout<

lib/Serialization/Serialization.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3945,17 +3945,19 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
39453945
S.DeclTypeAbbrCodes[ConditionalSubstitutionLayout::Code];
39463946
for (const auto *subs :
39473947
opaqueDecl->getConditionallyAvailableSubstitutions().drop_back()) {
3948-
SmallVector<IdentifierID, 4> conditions;
3948+
ConditionalSubstitutionLayout::emitRecord(
3949+
S.Out, S.ScratchRecord, abbrCode,
3950+
S.addSubstitutionMapRef(subs->getSubstitutions()));
39493951

3952+
unsigned condAbbrCode =
3953+
S.DeclTypeAbbrCodes[ConditionalSubstitutionConditionLayout::Code];
39503954
for (const auto &condition : subs->getAvailability()) {
3951-
auto lowerEndpoint = condition.getLowerEndpoint();
3952-
conditions.push_back(
3953-
S.addUniquedStringRef(lowerEndpoint.getAsString()));
3955+
ENCODE_VER_TUPLE(osVersion, llvm::Optional<llvm::VersionTuple>(
3956+
condition.getLowerEndpoint()));
3957+
ConditionalSubstitutionConditionLayout::emitRecord(
3958+
S.Out, S.ScratchRecord, condAbbrCode, /*isUnavailable=*/false,
3959+
LIST_VER_TUPLE_PIECES(osVersion));
39543960
}
3955-
3956-
ConditionalSubstitutionLayout::emitRecord(
3957-
S.Out, S.ScratchRecord, abbrCode,
3958-
S.addSubstitutionMapRef(subs->getSubstitutions()), conditions);
39593961
}
39603962
}
39613963
}
@@ -5134,6 +5136,7 @@ void Serializer::writeAllDeclsAndTypes() {
51345136
registerDeclTypeAbbr<XRefLayout>();
51355137

51365138
registerDeclTypeAbbr<ConditionalSubstitutionLayout>();
5139+
registerDeclTypeAbbr<ConditionalSubstitutionConditionLayout>();
51375140

51385141
#define DECL_ATTR(X, NAME, ...) \
51395142
registerDeclTypeAbbr<NAME##DeclAttrLayout>();

0 commit comments

Comments
 (0)