Skip to content

Commit faa06bf

Browse files
authored
Merge pull request #32581 from slavapestov/cached-emitted-members-request
Deterministically order class members for emission
2 parents 4b2fecf + 89b2f27 commit faa06bf

14 files changed

+130
-130
lines changed

include/swift/AST/ASTMangler.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ class ASTMangler : public Mangler {
101101
SymbolKind SKind = SymbolKind::Default);
102102

103103
std::string mangleDestructorEntity(const DestructorDecl *decl,
104-
bool isDeallocating, SymbolKind SKind);
104+
bool isDeallocating,
105+
SymbolKind SKind = SymbolKind::Default);
105106

106107
std::string mangleConstructorEntity(const ConstructorDecl *ctor,
107108
bool isAllocating,
@@ -120,11 +121,11 @@ class ASTMangler : public Mangler {
120121

121122
std::string mangleDefaultArgumentEntity(const DeclContext *func,
122123
unsigned index,
123-
SymbolKind SKind);
124+
SymbolKind SKind = SymbolKind::Default);
124125

125126
std::string mangleInitializerEntity(const VarDecl *var, SymbolKind SKind);
126127
std::string mangleBackingInitializerEntity(const VarDecl *var,
127-
SymbolKind SKind);
128+
SymbolKind SKind = SymbolKind::Default);
128129

129130
std::string mangleNominalType(const NominalTypeDecl *decl);
130131

include/swift/AST/Decl.h

+2-13
Original file line numberDiff line numberDiff line change
@@ -535,17 +535,14 @@ class alignas(1 << DeclAlignInBits) Decl {
535535
NumRequirementsInSignature : 16
536536
);
537537

538-
SWIFT_INLINE_BITFIELD(ClassDecl, NominalTypeDecl, 1+1+2+1+1+1+1+1+1,
538+
SWIFT_INLINE_BITFIELD(ClassDecl, NominalTypeDecl, 1+1+2+1+1+1+1+1,
539539
/// Whether this class inherits its superclass's convenience initializers.
540540
InheritsSuperclassInits : 1,
541541
ComputedInheritsSuperclassInits : 1,
542542

543543
/// \see ClassDecl::ForeignKind
544544
RawForeignKind : 2,
545545

546-
/// \see ClassDecl::getEmittedMembers()
547-
HasForcedEmittedMembers : 1,
548-
549546
HasMissingDesignatedInitializers : 1,
550547
ComputedHasMissingDesignatedInitializers : 1,
551548

@@ -3856,14 +3853,6 @@ class ClassDecl final : public NominalTypeDecl {
38563853
llvm::PointerIntPair<Type, 1, bool> SuperclassType;
38573854
} LazySemanticInfo;
38583855

3859-
bool hasForcedEmittedMembers() const {
3860-
return Bits.ClassDecl.HasForcedEmittedMembers;
3861-
}
3862-
3863-
void setHasForcedEmittedMembers() {
3864-
Bits.ClassDecl.HasForcedEmittedMembers = true;
3865-
}
3866-
38673856
Optional<bool> getCachedInheritsSuperclassInitializers() const {
38683857
if (Bits.ClassDecl.ComputedInheritsSuperclassInits)
38693858
return Bits.ClassDecl.InheritsSuperclassInits;
@@ -4089,7 +4078,7 @@ class ClassDecl final : public NominalTypeDecl {
40894078

40904079
/// Get all the members of this class, synthesizing any implicit members
40914080
/// that appear in the vtable if needed.
4092-
DeclRange getEmittedMembers() const;
4081+
ArrayRef<Decl *> getEmittedMembers() const;
40934082

40944083
// Implement isa/cast/dyncast/etc.
40954084
static bool classof(const Decl *D) {

include/swift/AST/TypeCheckRequests.h

+3-6
Original file line numberDiff line numberDiff line change
@@ -1064,23 +1064,20 @@ class SynthesizeAccessorRequest :
10641064

10651065
class EmittedMembersRequest :
10661066
public SimpleRequest<EmittedMembersRequest,
1067-
DeclRange(ClassDecl *),
1068-
RequestFlags::SeparatelyCached> {
1067+
ArrayRef<Decl *>(ClassDecl *),
1068+
RequestFlags::Cached> {
10691069
public:
10701070
using SimpleRequest::SimpleRequest;
10711071

10721072
private:
10731073
friend SimpleRequest;
10741074

10751075
// Evaluation.
1076-
DeclRange
1076+
ArrayRef<Decl *>
10771077
evaluate(Evaluator &evaluator, ClassDecl *classDecl) const;
10781078

10791079
public:
1080-
// Separate caching.
10811080
bool isCached() const { return true; }
1082-
Optional<DeclRange> getCachedResult() const;
1083-
void cacheResult(DeclRange value) const;
10841081
};
10851082

10861083
class IsImplicitlyUnwrappedOptionalRequest :

include/swift/AST/TypeCheckerTypeIDZone.def

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ SWIFT_REQUEST(TypeChecker, TypeEraserHasViableInitRequest,
6565
SWIFT_REQUEST(TypeChecker, DynamicallyReplacedDeclRequest,
6666
ValueDecl *(ValueDecl *),
6767
Cached, NoLocationInfo)
68-
SWIFT_REQUEST(TypeChecker, EmittedMembersRequest, DeclRange(ClassDecl *),
69-
SeparatelyCached, NoLocationInfo)
68+
SWIFT_REQUEST(TypeChecker, EmittedMembersRequest, ArrayRef<Decl *>(ClassDecl *),
69+
Cached, NoLocationInfo)
7070
SWIFT_REQUEST(TypeChecker, EnumRawValuesRequest,
7171
evaluator::SideEffect (EnumDecl *, TypeResolutionStage),
7272
SeparatelyCached, NoLocationInfo)

include/swift/Demangling/ManglingUtils.h

+9-3
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,8 @@ void mangleIdentifier(Mangler &M, StringRef ident) {
192192
// Mangle the sub-string up to the next word substitution (or to the end
193193
// of the identifier - that's why we added the dummy-word).
194194
// The first thing: we add the encoded sub-string length.
195+
bool first = true;
195196
M.Buffer << (Repl.StringPos - Pos);
196-
assert(!isDigit(ident[Pos]) &&
197-
"first char of sub-string may not be a digit");
198197
do {
199198
// Update the start position of new added words, so that they refer to
200199
// the begin of the whole mangled Buffer.
@@ -203,9 +202,16 @@ void mangleIdentifier(Mangler &M, StringRef ident) {
203202
M.Words[WordsInBuffer].start = M.getBufferStr().size();
204203
WordsInBuffer++;
205204
}
205+
// Error recovery. We sometimes need to mangle identifiers coming
206+
// from invalid code.
207+
if (first && isDigit(ident[Pos]))
208+
M.Buffer << 'X';
206209
// Add a literal character of the sub-string.
207-
M.Buffer << ident[Pos];
210+
else
211+
M.Buffer << ident[Pos];
212+
208213
Pos++;
214+
first = false;
209215
} while (Pos < Repl.StringPos);
210216
}
211217
// Is it a "real" word substitution (and not the dummy-word)?

include/swift/SIL/SILVTableVisitor.h

+1-70
Original file line numberDiff line numberDiff line change
@@ -18,55 +18,11 @@
1818
#ifndef SWIFT_SIL_SILVTABLEVISITOR_H
1919
#define SWIFT_SIL_SILVTABLEVISITOR_H
2020

21-
#include <string>
22-
2321
#include "swift/AST/Decl.h"
2422
#include "swift/AST/Types.h"
25-
#include "swift/AST/ASTMangler.h"
2623

2724
namespace swift {
2825

29-
// Utility class for deterministically ordering vtable entries for
30-
// synthesized methods.
31-
struct SortedFuncList {
32-
using Entry = std::pair<std::string, AbstractFunctionDecl *>;
33-
SmallVector<Entry, 2> elts;
34-
bool sorted = false;
35-
36-
void add(AbstractFunctionDecl *afd) {
37-
Mangle::ASTMangler mangler;
38-
std::string mangledName;
39-
if (auto *cd = dyn_cast<ConstructorDecl>(afd))
40-
mangledName = mangler.mangleConstructorEntity(cd, 0);
41-
else
42-
mangledName = mangler.mangleEntity(afd);
43-
44-
elts.push_back(std::make_pair(mangledName, afd));
45-
}
46-
47-
bool empty() { return elts.empty(); }
48-
49-
void sort() {
50-
assert(!sorted);
51-
sorted = true;
52-
std::sort(elts.begin(),
53-
elts.end(),
54-
[](const Entry &lhs, const Entry &rhs) -> bool {
55-
return lhs.first < rhs.first;
56-
});
57-
}
58-
59-
decltype(elts)::const_iterator begin() const {
60-
assert(sorted);
61-
return elts.begin();
62-
}
63-
64-
decltype(elts)::const_iterator end() const {
65-
assert(sorted);
66-
return elts.end();
67-
}
68-
};
69-
7026
/// A CRTP class for visiting virtually-dispatched methods of a class.
7127
///
7228
/// You must override these two methods in your subclass:
@@ -192,33 +148,8 @@ template <class T> class SILVTableVisitor {
192148
if (!theClass->hasKnownSwiftImplementation())
193149
return;
194150

195-
// Note that while vtable order is not ABI, we still want it to be
196-
// consistent between translation units.
197-
//
198-
// So, sort synthesized members by their mangled name, since they
199-
// are added lazily during type checking, with the remaining ones
200-
// forced at the end.
201-
SortedFuncList synthesizedMembers;
202-
203-
for (auto member : theClass->getEmittedMembers()) {
204-
if (auto *afd = dyn_cast<AbstractFunctionDecl>(member)) {
205-
if (afd->isSynthesized()) {
206-
synthesizedMembers.add(afd);
207-
continue;
208-
}
209-
}
210-
151+
for (auto member : theClass->getEmittedMembers())
211152
maybeAddMember(member);
212-
}
213-
214-
if (synthesizedMembers.empty())
215-
return;
216-
217-
synthesizedMembers.sort();
218-
219-
for (const auto &pair : synthesizedMembers) {
220-
maybeAddMember(pair.second);
221-
}
222153
}
223154
};
224155

lib/AST/ASTMangler.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2741,7 +2741,7 @@ void ASTMangler::appendConstructorEntity(const ConstructorDecl *ctor,
27412741
}
27422742

27432743
void ASTMangler::appendDestructorEntity(const DestructorDecl *dtor,
2744-
bool isDeallocating) {
2744+
bool isDeallocating) {
27452745
appendContextOf(dtor);
27462746
appendOperator(isDeallocating ? "fD" : "fd");
27472747
}

lib/AST/Decl.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -4277,11 +4277,11 @@ DestructorDecl *ClassDecl::getDestructor() const {
42774277
nullptr);
42784278
}
42794279

4280-
DeclRange ClassDecl::getEmittedMembers() const {
4280+
ArrayRef<Decl *> ClassDecl::getEmittedMembers() const {
42814281
ASTContext &ctx = getASTContext();
42824282
return evaluateOrDefault(ctx.evaluator,
42834283
EmittedMembersRequest{const_cast<ClassDecl *>(this)},
4284-
getMembers());
4284+
ArrayRef<Decl *>());
42854285
}
42864286

42874287
/// Synthesizer callback for an empty implicit function body.
@@ -4310,6 +4310,10 @@ GetDestructorRequest::evaluate(Evaluator &evaluator, ClassDecl *CD) const {
43104310
if (ctx.LangOpts.EnableObjCInterop)
43114311
CD->recordObjCMethod(DD, DD->getObjCSelector());
43124312

4313+
// Mark it as synthesized to make its location in getEmittedMembers()
4314+
// deterministic.
4315+
DD->setSynthesized(true);
4316+
43134317
return DD;
43144318
}
43154319

lib/AST/TypeCheckRequests.cpp

-17
Original file line numberDiff line numberDiff line change
@@ -783,23 +783,6 @@ void SynthesizeAccessorRequest::cacheResult(AccessorDecl *accessor) const {
783783
storage->setSynthesizedAccessor(kind, accessor);
784784
}
785785

786-
//----------------------------------------------------------------------------//
787-
// EmittedMembersRequest computation.
788-
//----------------------------------------------------------------------------//
789-
790-
Optional<DeclRange>
791-
EmittedMembersRequest::getCachedResult() const {
792-
auto *classDecl = std::get<0>(getStorage());
793-
if (classDecl->hasForcedEmittedMembers())
794-
return classDecl->getMembers();
795-
return None;
796-
}
797-
798-
void EmittedMembersRequest::cacheResult(DeclRange result) const {
799-
auto *classDecl = std::get<0>(getStorage());
800-
classDecl->setHasForcedEmittedMembers();
801-
}
802-
803786
//----------------------------------------------------------------------------//
804787
// IsImplicitlyUnwrappedOptionalRequest computation.
805788
//----------------------------------------------------------------------------//

0 commit comments

Comments
 (0)