Skip to content

Commit 126058c

Browse files
authored
Merge pull request #8062 from slavapestov/serialization-cleanup
Serialization cleanup
2 parents 8c0e9d5 + 18fbfd4 commit 126058c

File tree

8 files changed

+94
-51
lines changed

8 files changed

+94
-51
lines changed

include/swift/Serialization/ModuleFile.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -490,9 +490,6 @@ class ModuleFile : public LazyMemberLoader {
490490

491491
ParameterList *readParameterList();
492492

493-
GenericParamList *maybeGetOrReadGenericParams(serialization::DeclID contextID,
494-
DeclContext *DC);
495-
496493
/// Reads a generic param list from \c DeclTypeCursor.
497494
///
498495
/// If the record at the cursor is not a generic param list, returns null

lib/Serialization/Deserialization.cpp

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -783,25 +783,6 @@ ModuleFile::maybeReadSubstitution(llvm::BitstreamCursor &cursor,
783783
getContext().AllocateCopy(conformanceBuf)};
784784
}
785785

786-
GenericParamList *
787-
ModuleFile::maybeGetOrReadGenericParams(serialization::DeclID genericContextID,
788-
DeclContext *DC) {
789-
if (genericContextID) {
790-
Decl *genericContext = getDecl(genericContextID);
791-
assert(genericContext && "loading PolymorphicFunctionType before its decl");
792-
793-
if (auto fn = dyn_cast<AbstractFunctionDecl>(genericContext))
794-
return fn->getGenericParams();
795-
if (auto nominal = dyn_cast<NominalTypeDecl>(genericContext))
796-
return nominal->getGenericParams();
797-
if (auto ext = dyn_cast<ExtensionDecl>(genericContext))
798-
return ext->getGenericParams();
799-
llvm_unreachable("only functions and nominals can provide generic params");
800-
} else {
801-
return maybeReadGenericParams(DC);
802-
}
803-
}
804-
805786
GenericParamList *ModuleFile::maybeReadGenericParams(DeclContext *DC,
806787
GenericParamList *outerParams) {
807788
using namespace decls_block;
@@ -821,7 +802,6 @@ GenericParamList *ModuleFile::maybeReadGenericParams(DeclContext *DC,
821802
return nullptr;
822803

823804
SmallVector<GenericTypeParamDecl *, 8> params;
824-
SmallVector<RequirementRepr, 8> requirements;
825805

826806
while (true) {
827807
lastRecordOffset.reset();
@@ -3448,9 +3428,12 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
34483428
extension->setEarlyAttrValidation();
34493429
declOrOffset = extension;
34503430

3451-
// Generic parameters.
3452-
GenericParamList *genericParams = maybeReadGenericParams(DC);
3453-
extension->setGenericParams(genericParams);
3431+
// Generic parameter lists are written from outermost to innermost.
3432+
// Keep reading until we run out of generic parameter lists.
3433+
GenericParamList *outerParams = nullptr;
3434+
while (auto *genericParams = maybeReadGenericParams(DC, outerParams))
3435+
outerParams = genericParams;
3436+
extension->setGenericParams(outerParams);
34543437

34553438
configureGenericEnvironment(extension, genericEnvID);
34563439

@@ -3478,6 +3461,19 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
34783461

34793462
nominal->addExtension(extension);
34803463

3464+
#ifndef NDEBUG
3465+
if (outerParams) {
3466+
unsigned paramCount = 0;
3467+
for (auto *paramList = outerParams;
3468+
paramList != nullptr;
3469+
paramList = paramList->getOuterParameters()) {
3470+
paramCount += paramList->size();
3471+
}
3472+
assert(paramCount ==
3473+
extension->getGenericSignature()->getGenericParams().size());
3474+
}
3475+
#endif
3476+
34813477
break;
34823478
}
34833479

lib/Serialization/Serialization.cpp

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -447,18 +447,6 @@ DeclID Serializer::addDeclRef(const Decl *D, bool forceSerialization) {
447447
isa<PrecedenceGroupDecl>(D)) &&
448448
"cannot cross-reference this decl");
449449

450-
// Record any generic parameters that come from this decl, so that we can use
451-
// the decl to refer to the parameters later.
452-
const GenericParamList *paramList = nullptr;
453-
if (auto fn = dyn_cast<AbstractFunctionDecl>(D))
454-
paramList = fn->getGenericParams();
455-
else if (auto nominal = dyn_cast<NominalTypeDecl>(D))
456-
paramList = nominal->getGenericParams();
457-
else if (auto ext = dyn_cast<ExtensionDecl>(D))
458-
paramList = ext->getGenericParams();
459-
if (paramList)
460-
GenericContexts[paramList] = D;
461-
462450
id = { ++LastDeclID, forceSerialization };
463451
DeclsAndTypesToWrite.push(D);
464452
return id.first;
@@ -535,11 +523,6 @@ NormalConformanceID Serializer::addConformanceRef(
535523
return conformanceID;
536524
}
537525

538-
const Decl *Serializer::getGenericContext(const GenericParamList *paramList) {
539-
auto contextDecl = GenericContexts.lookup(paramList);
540-
return contextDecl;
541-
}
542-
543526
/// Record the name of a block.
544527
static void emitBlockID(llvm::BitstreamWriter &out, unsigned ID,
545528
StringRef name,
@@ -2402,7 +2385,21 @@ void Serializer::writeDecl(const Decl *D) {
24022385
isa<ProtocolDecl>(baseNominal);
24032386
}
24042387

2405-
writeGenericParams(extension->getGenericParams());
2388+
// Extensions of nested generic types have multiple generic parameter
2389+
// lists. Collect them all, from the innermost to outermost.
2390+
SmallVector<GenericParamList *, 2> allGenericParams;
2391+
for (auto *genericParams = extension->getGenericParams();
2392+
genericParams != nullptr;
2393+
genericParams = genericParams->getOuterParameters()) {
2394+
allGenericParams.push_back(genericParams);
2395+
}
2396+
2397+
// Reverse the list, and write the parameter lists, from outermost
2398+
// to innermost.
2399+
std::reverse(allGenericParams.begin(), allGenericParams.end());
2400+
for (auto *genericParams : allGenericParams)
2401+
writeGenericParams(genericParams);
2402+
24062403
writeMembers(extension->getMembers(), isClassExtension);
24072404
writeConformances(conformances, DeclTypeAbbrCodes);
24082405
break;

lib/Serialization/Serialization.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,6 @@ class Serializer {
100100
/// A map from local DeclContexts to their serialized IDs.
101101
llvm::DenseMap<const DeclContext*, DeclContextID> LocalDeclContextIDs;
102102

103-
/// A map from generic parameter lists to the decls they come from.
104-
llvm::DenseMap<const GenericParamList *, const Decl *> GenericContexts;
105-
106103
/// A map from generic environments to their serialized IDs.
107104
llvm::DenseMap<const GenericEnvironment *, GenericEnvironmentID>
108105
GenericEnvironmentIDs;
@@ -120,10 +117,6 @@ class Serializer {
120117
/// table.
121118
using DeclTable = llvm::MapVector<Identifier, DeclTableData>;
122119

123-
/// Returns the declaration the given generic parameter list is associated
124-
/// with.
125-
const Decl *getGenericContext(const GenericParamList *paramList);
126-
127120
using ObjCMethodTableData = SmallVector<std::tuple<TypeID, bool, DeclID>, 4>;
128121

129122
// In-memory representation of what will eventually be an on-disk
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
public struct GenericSubscript {
2+
public init() { }
3+
4+
public subscript<K, V>(k: K) -> V {
5+
get {
6+
while true { }
7+
}
8+
set { }
9+
}
10+
}
11+
12+
public struct Outer<T> {
13+
public struct Inner<U> {
14+
public init() {}
15+
}
16+
}
17+
18+
extension Outer.Inner {
19+
public subscript<K, V>(k: K) -> V {
20+
get {
21+
while true { }
22+
}
23+
set { }
24+
}
25+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
public struct Outer<T> {
2+
public struct Inner<U> {
3+
public init() {}
4+
}
5+
}
6+
7+
extension Outer.Inner {
8+
public func extensionMethod(t: T) -> U {
9+
while true {}
10+
}
11+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: rm -rf %t
2+
// RUN: mkdir -p %t
3+
// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/has_generic_subscript.swift
4+
// RUN: llvm-bcanalyzer %t/has_generic_subscript.swiftmodule | %FileCheck %s
5+
// RUN: %target-swift-frontend -emit-ir -I %t %s -o /dev/null
6+
7+
// CHECK-NOT: UnknownCode
8+
9+
import has_generic_subscript
10+
11+
var sillyDict = GenericSubscript()
12+
var value: Int = sillyDict["beer"]
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: rm -rf %t
2+
// RUN: mkdir -p %t
3+
// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/has_nested_generic_extension.swift
4+
// RUN: llvm-bcanalyzer %t/has_nested_generic_extension.swiftmodule | %FileCheck %s
5+
// RUN: %target-swift-frontend -emit-ir -I %t %s -o /dev/null
6+
7+
// CHECK-NOT: UnknownCode
8+
9+
import has_nested_generic_extension
10+
11+
var sillyGeneric = Outer<String>.Inner<Float>()
12+
let result: Float = sillyGeneric.extensionMethod(t: "square root of two")

0 commit comments

Comments
 (0)