Skip to content

Commit 4e15a8c

Browse files
[AST] Get it a deterministic traverse order for classMembers
Make sure the traversal order for classMembers in deterministic in the mdoule by sorting them first. Also fix the comparsion function for `DeclName` to make sure there aren't two DeclNames with different OpaquePointer can be evaluated to equal. rdar://147513165
1 parent deb1d96 commit 4e15a8c

File tree

3 files changed

+46
-15
lines changed

3 files changed

+46
-15
lines changed

lib/AST/Identifier.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,14 @@ int Identifier::compare(Identifier other) const {
9898
}
9999

100100
int DeclName::compare(DeclName other) const {
101+
// Fast equality comparsion.
102+
if (getOpaqueValue() == other.getOpaqueValue())
103+
return 0;
104+
105+
// Order based on if it is compound name or not.
106+
if (isSimpleName() != other.isSimpleName())
107+
return isSimpleName() ? -1 : 1;
108+
101109
// Compare base names.
102110
if (int result = getBaseName().compare(other.getBaseName()))
103111
return result;
@@ -111,9 +119,8 @@ int DeclName::compare(DeclName other) const {
111119
return result;
112120
}
113121

114-
if (argNames.size() == otherArgNames.size())
115-
return 0;
116-
122+
assert(argNames.size() != otherArgNames.size() &&
123+
"equality should be covered by opaque value comparsion");
117124
return argNames.size() < otherArgNames.size() ? -1 : 1;
118125
}
119126

lib/AST/Module.cpp

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -694,13 +694,17 @@ void SourceLookupCache::lookupClassMembers(ImportPath::Access accessPath,
694694
VisibleDeclConsumer &consumer) {
695695
assert(accessPath.size() <= 1 && "can only refer to top-level decls");
696696

697-
if (!accessPath.empty()) {
698-
for (auto &member : ClassMembers) {
699-
// Non-simple names are also stored under their simple name, so make
700-
// sure to only report them once.
701-
if (!member.first.isSimpleName())
702-
continue;
697+
std::vector<std::pair<DeclName, TinyPtrVector<ValueDecl *>>> OrderedMembers;
698+
for (auto &member : ClassMembers) {
699+
if (!member.first.isSimpleName())
700+
continue;
701+
OrderedMembers.emplace_back(member.first, member.second);
702+
}
703+
llvm::sort(OrderedMembers,
704+
[](auto &LHS, auto &RHS) { return LHS.first < RHS.first; });
703705

706+
if (!accessPath.empty()) {
707+
for (auto &member : OrderedMembers) {
704708
for (ValueDecl *vd : member.second) {
705709
auto *nominal = vd->getDeclContext()->getSelfNominalTypeDecl();
706710
if (nominal && nominal->getName() == accessPath.front().Item)
@@ -712,12 +716,7 @@ void SourceLookupCache::lookupClassMembers(ImportPath::Access accessPath,
712716
return;
713717
}
714718

715-
for (auto &member : ClassMembers) {
716-
// Non-simple names are also stored under their simple name, so make sure to
717-
// only report them once.
718-
if (!member.first.isSimpleName())
719-
continue;
720-
719+
for (auto &member : OrderedMembers) {
721720
for (ValueDecl *vd : member.second)
722721
if (ABIRoleInfo(vd).matchesOptions(OptionSet<ModuleLookupFlags>())) // FIXME: figure this out
723722
consumer.foundDecl(vd, DeclVisibilityKind::DynamicLookup,

test/Frontend/output_determinism_check.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,28 @@
3838

3939
public var x = 1
4040
public func test() {}
41+
42+
class A {
43+
var a = 0
44+
var b = 0
45+
var c = 0
46+
var d = 0
47+
}
48+
class B {
49+
var a = 0
50+
var b = 0
51+
var c = 0
52+
var d = 0
53+
}
54+
class C {
55+
var a = 0
56+
var b = 0
57+
var c = 0
58+
var d = 0
59+
}
60+
class D {
61+
var a = 0
62+
var b = 0
63+
var c = 0
64+
var d = 0
65+
}

0 commit comments

Comments
 (0)