Skip to content

Commit

Permalink
[Serialization] Distinguish between static and non-static vars. (#7176)…
Browse files Browse the repository at this point in the history
… (#7187)

Every other declaration kind gets this for free in its interface type,
but properties don't. Just add a bit, it's simple enough.

rdar://problem/30289803
  • Loading branch information
jrose-apple authored and tkremenek committed Feb 1, 2017
1 parent 6b19f27 commit 36e166c
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 17 deletions.
5 changes: 3 additions & 2 deletions include/swift/Serialization/ModuleFormat.h
Expand Up @@ -54,7 +54,7 @@ const uint16_t VERSION_MAJOR = 0;
/// in source control, you should also update the comment to briefly
/// describe what change you made. The content of this comment isn't important;
/// it just ensures a conflict if two people change the module format.
const uint16_t VERSION_MINOR = 308; // Last change: nested type table
const uint16_t VERSION_MINOR = 309; // Last change: static/non-static values

using DeclID = PointerEmbeddedInt<unsigned, 31>;
using DeclIDField = BCFixed<31>;
Expand Down Expand Up @@ -1179,7 +1179,8 @@ namespace decls_block {
XREF_VALUE_PATH_PIECE,
TypeIDField, // type
IdentifierIDField, // name
BCFixed<1> // restrict to protocol extension
BCFixed<1>, // restrict to protocol extension
BCFixed<1> // static?
>;

using XRefInitializerPathPieceLayout = BCRecordLayout<
Expand Down
20 changes: 13 additions & 7 deletions lib/Serialization/Deserialization.cpp
Expand Up @@ -1223,7 +1223,7 @@ getActualCtorInitializerKind(uint8_t raw) {
/// from Clang can also appear in any module.
static void filterValues(Type expectedTy, ModuleDecl *expectedModule,
CanGenericSignature expectedGenericSig, bool isType,
bool inProtocolExt,
bool inProtocolExt, bool isStatic,
Optional<swift::CtorInitializerKind> ctorInit,
SmallVectorImpl<ValueDecl *> &values) {
CanType canTy;
Expand All @@ -1238,6 +1238,8 @@ static void filterValues(Type expectedTy, ModuleDecl *expectedModule,
return true;
if (canTy && value->getInterfaceType()->getCanonicalType() != canTy)
return true;
if (value->isStatic() != isStatic)
return true;
// FIXME: Should be able to move a value from an extension in a derived
// module to the original definition in a base module.
if (expectedModule && !value->hasClangNode() &&
Expand Down Expand Up @@ -1309,10 +1311,12 @@ Decl *ModuleFile::resolveCrossReference(ModuleDecl *M, uint32_t pathLen) {
bool isType = (recordID == XREF_TYPE_PATH_PIECE);
bool onlyInNominal = false;
bool inProtocolExt = false;
bool isStatic = false;
if (isType)
XRefTypePathPieceLayout::readRecord(scratch, IID, onlyInNominal);
else
XRefValuePathPieceLayout::readRecord(scratch, TID, IID, inProtocolExt);
XRefValuePathPieceLayout::readRecord(scratch, TID, IID, inProtocolExt,
isStatic);

Identifier name = getIdentifier(IID);
pathTrace.addValue(name);
Expand All @@ -1327,8 +1331,8 @@ Decl *ModuleFile::resolveCrossReference(ModuleDecl *M, uint32_t pathLen) {
M->lookupQualified(ModuleType::get(M), name,
NL_QualifiedDefault | NL_KnownNoDependency,
/*typeResolver=*/nullptr, values);
filterValues(filterTy, nullptr, nullptr, isType, inProtocolExt, None,
values);
filterValues(filterTy, nullptr, nullptr, isType, inProtocolExt, isStatic,
None, values);

// HACK HACK HACK: Omit-needless-words hack to try to cope with
// the "NS" prefix being added/removed. No "real" compiler mode
Expand Down Expand Up @@ -1484,6 +1488,7 @@ Decl *ModuleFile::resolveCrossReference(ModuleDecl *M, uint32_t pathLen) {
bool isType = false;
bool onlyInNominal = false;
bool inProtocolExt = false;
bool isStatic = false;
switch (recordID) {
case XREF_TYPE_PATH_PIECE: {
IdentifierID IID;
Expand All @@ -1495,7 +1500,8 @@ Decl *ModuleFile::resolveCrossReference(ModuleDecl *M, uint32_t pathLen) {

case XREF_VALUE_PATH_PIECE: {
IdentifierID IID;
XRefValuePathPieceLayout::readRecord(scratch, TID, IID, inProtocolExt);
XRefValuePathPieceLayout::readRecord(scratch, TID, IID, inProtocolExt,
isStatic);
memberName = getIdentifier(IID);
break;
}
Expand Down Expand Up @@ -1534,8 +1540,8 @@ Decl *ModuleFile::resolveCrossReference(ModuleDecl *M, uint32_t pathLen) {

auto members = nominal->lookupDirect(memberName, onlyInNominal);
values.append(members.begin(), members.end());
filterValues(filterTy, M, genericSig, isType, inProtocolExt, ctorInit,
values);
filterValues(filterTy, M, genericSig, isType, inProtocolExt, isStatic,
ctorInit, values);
break;
}

Expand Down
12 changes: 8 additions & 4 deletions lib/Serialization/Serialization.cpp
Expand Up @@ -1622,7 +1622,8 @@ void Serializer::writeCrossReference(const DeclContext *DC, uint32_t pathLen) {
XRefValuePathPieceLayout::emitRecord(Out, ScratchRecord, abbrCode,
addTypeRef(ty),
addIdentifierRef(SD->getName()),
isProtocolExt);
isProtocolExt,
SD->isStatic());
break;
}

Expand All @@ -1637,7 +1638,8 @@ void Serializer::writeCrossReference(const DeclContext *DC, uint32_t pathLen) {
abbrCode = DeclTypeAbbrCodes[XRefValuePathPieceLayout::Code];
XRefValuePathPieceLayout::emitRecord(Out, ScratchRecord, abbrCode,
addTypeRef(ty), nameID,
isProtocolExt);
isProtocolExt,
storage->isStatic());

abbrCode =
DeclTypeAbbrCodes[XRefOperatorOrAccessorPathPieceLayout::Code];
Expand Down Expand Up @@ -1671,7 +1673,8 @@ void Serializer::writeCrossReference(const DeclContext *DC, uint32_t pathLen) {
XRefValuePathPieceLayout::emitRecord(Out, ScratchRecord, abbrCode,
addTypeRef(ty),
addIdentifierRef(fn->getName()),
isProtocolExt);
isProtocolExt,
fn->isStatic());

if (fn->isOperator()) {
// Encode the fixity as a filter on the func decls, to distinguish prefix
Expand Down Expand Up @@ -1752,7 +1755,8 @@ void Serializer::writeCrossReference(const Decl *D) {
XRefValuePathPieceLayout::emitRecord(Out, ScratchRecord, abbrCode,
addTypeRef(ty),
addIdentifierRef(val->getName()),
isProtocolExt);
isProtocolExt,
val->isStatic());
}

/// Translate from the AST associativity enum to the Serialization enum
Expand Down
9 changes: 7 additions & 2 deletions test/Serialization/Inputs/multi-file-2.swift
@@ -1,5 +1,5 @@
// Do not put any classes in this file. It's part of the test that no classes
// get serialized here.
// Do not put any protocols in this file. It's part of the test that no
// protocols get serialized here.

enum TheEnum {
case A, B, C(MyClass)
Expand Down Expand Up @@ -28,3 +28,8 @@ public func hasLocal() {
useEquatable(LocalEnum.A)
useEquatable(Wrapper.LocalEnum.A)
}

class Base {
class var conflict: Int { return 0 }
var conflict: Int { return 1 }
}
9 changes: 7 additions & 2 deletions test/Serialization/multi-file.swift
Expand Up @@ -24,8 +24,8 @@ func bar() {
foo(EquatableEnum.A)
}

// THIS-FILE-DAG: CLASS_DECL
// OTHER-FILE-NEG-NOT: CLASS_DECL
// THIS-FILE-DAG: PROTOCOL_DECL
// OTHER-FILE-NEG-NOT: PROTOCOL_DECL
// OTHER-FILE-DAG: ENUM_DECL
// THIS-FILE-NEG-NOT: ENUM_DECL

Expand Down Expand Up @@ -54,3 +54,8 @@ private protocol SomeProto {
private struct Generic<T> {
// THIS-FILE-DAG: GENERIC_TYPE_PARAM_DECL
}

class Sub: Base {
override class var conflict: Int { return 100 }
override var conflict: Int { return 200 }
}

0 comments on commit 36e166c

Please sign in to comment.