mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[serialization] Add support for oneofs.
Since SILGen support is so poor, the test just uses -parse. Swift SVN r6136
This commit is contained in:
@@ -896,6 +896,71 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
break;
|
||||
}
|
||||
|
||||
case decls_block::ONEOF_DECL: {
|
||||
IdentifierID nameID;
|
||||
DeclID contextID;
|
||||
bool isImplicit;
|
||||
ArrayRef<uint64_t> inheritedIDs;
|
||||
|
||||
decls_block::OneOfLayout::readRecord(scratch, nameID, contextID,
|
||||
isImplicit, inheritedIDs);
|
||||
|
||||
MutableArrayRef<TypeLoc> inherited;
|
||||
DeclContext *DC;
|
||||
{
|
||||
BCOffsetRAII restoreOffset(DeclTypeCursor);
|
||||
inherited = getTypes(inheritedIDs);
|
||||
DC = getDeclContext(contextID);
|
||||
}
|
||||
|
||||
auto genericParams = maybeReadGenericParams(DC);
|
||||
|
||||
auto oneOf = new (ctx) OneOfDecl(SourceLoc(), getIdentifier(nameID),
|
||||
SourceLoc(), inherited,
|
||||
genericParams, DC);
|
||||
declOrOffset = oneOf;
|
||||
|
||||
if (isImplicit)
|
||||
oneOf->setImplicit();
|
||||
if (genericParams)
|
||||
for (auto &genericParam : *oneOf->getGenericParams())
|
||||
genericParam.getAsTypeParam()->setDeclContext(oneOf);
|
||||
|
||||
SmallVector<ProtocolConformance *, 16> conformanceBuf;
|
||||
while (ProtocolConformance *conformance = maybeReadConformance())
|
||||
conformanceBuf.push_back(conformance);
|
||||
oneOf->setConformances(ctx.AllocateCopy(conformanceBuf));
|
||||
|
||||
auto members = readMembers();
|
||||
assert(members.hasValue() && "could not read oneof members");
|
||||
oneOf->setMembers(members.getValue(), SourceRange());
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case decls_block::ONEOF_ELEMENT_DECL: {
|
||||
IdentifierID nameID;
|
||||
DeclID contextID;
|
||||
TypeID argTypeID, ctorTypeID;
|
||||
bool isImplicit;
|
||||
|
||||
decls_block::OneOfElementLayout::readRecord(scratch, nameID, contextID,
|
||||
argTypeID, ctorTypeID,
|
||||
isImplicit);
|
||||
|
||||
auto argTy = getType(argTypeID);
|
||||
auto elem = new (ctx) OneOfElementDecl(SourceLoc(), getIdentifier(nameID),
|
||||
TypeLoc::withoutLoc(argTy),
|
||||
getDeclContext(contextID));
|
||||
declOrOffset = elem;
|
||||
|
||||
elem->setType(getType(ctorTypeID));
|
||||
if (isImplicit)
|
||||
elem->setImplicit();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case decls_block::XREF: {
|
||||
uint8_t kind;
|
||||
TypeID expectedTypeID;
|
||||
|
||||
@@ -237,6 +237,8 @@ namespace decls_block {
|
||||
POSTFIX_OPERATOR_DECL,
|
||||
INFIX_OPERATOR_DECL,
|
||||
CLASS_DECL,
|
||||
ONEOF_DECL,
|
||||
ONEOF_ELEMENT_DECL,
|
||||
|
||||
PAREN_PATTERN = 200,
|
||||
TUPLE_PATTERN,
|
||||
@@ -406,6 +408,7 @@ namespace decls_block {
|
||||
using StructLayout = NominalLayout<STRUCT_DECL>;
|
||||
using ProtocolLayout = NominalLayout<PROTOCOL_DECL>;
|
||||
using ClassLayout = NominalLayout<CLASS_DECL>;
|
||||
using OneOfLayout = NominalLayout<ONEOF_DECL>;
|
||||
|
||||
using ConstructorLayout = BCRecordLayout<
|
||||
CONSTRUCTOR_DECL,
|
||||
@@ -466,6 +469,15 @@ namespace decls_block {
|
||||
BCFixed<8> // precedence
|
||||
>;
|
||||
|
||||
using OneOfElementLayout = BCRecordLayout<
|
||||
ONEOF_ELEMENT_DECL,
|
||||
IdentifierIDField, // name
|
||||
DeclIDField, // context decl
|
||||
TypeIDField, // argument type
|
||||
TypeIDField, // constructor type
|
||||
BCFixed<1> // implicit?
|
||||
>;
|
||||
|
||||
|
||||
using ParenPatternLayout = BCRecordLayout<
|
||||
PAREN_PATTERN
|
||||
|
||||
@@ -424,6 +424,8 @@ void Serializer::writeBlockInfoBlock() {
|
||||
RECORD(decls_block, POSTFIX_OPERATOR_DECL);
|
||||
RECORD(decls_block, INFIX_OPERATOR_DECL);
|
||||
RECORD(decls_block, CLASS_DECL);
|
||||
RECORD(decls_block, ONEOF_DECL);
|
||||
RECORD(decls_block, ONEOF_ELEMENT_DECL);
|
||||
|
||||
RECORD(decls_block, PAREN_PATTERN);
|
||||
RECORD(decls_block, TUPLE_PATTERN);
|
||||
@@ -888,8 +890,31 @@ bool Serializer::writeDecl(const Decl *D) {
|
||||
return true;
|
||||
}
|
||||
|
||||
case DeclKind::OneOf:
|
||||
return false;
|
||||
case DeclKind::OneOf: {
|
||||
auto oneOf = cast<OneOfDecl>(D);
|
||||
|
||||
// FIXME: Handle attributes.
|
||||
if (!oneOf->getAttrs().empty())
|
||||
return false;
|
||||
|
||||
const Decl *DC = getDeclForContext(oneOf->getDeclContext());
|
||||
|
||||
SmallVector<TypeID, 4> inherited;
|
||||
for (auto parent : oneOf->getInherited())
|
||||
inherited.push_back(addTypeRef(parent.getType()));
|
||||
|
||||
unsigned abbrCode = DeclTypeAbbrCodes[OneOfLayout::Code];
|
||||
OneOfLayout::emitRecord(Out, ScratchRecord, abbrCode,
|
||||
addIdentifierRef(oneOf->getName()),
|
||||
addDeclRef(DC),
|
||||
oneOf->isImplicit(),
|
||||
inherited);
|
||||
|
||||
writeGenericParams(oneOf->getGenericParams());
|
||||
writeConformances(oneOf->getConformances());
|
||||
writeMembers(oneOf);
|
||||
return true;
|
||||
}
|
||||
|
||||
case DeclKind::Class: {
|
||||
auto theClass = cast<ClassDecl>(D);
|
||||
@@ -1006,7 +1031,25 @@ bool Serializer::writeDecl(const Decl *D) {
|
||||
return true;
|
||||
}
|
||||
|
||||
case DeclKind::OneOfElement:
|
||||
case DeclKind::OneOfElement: {
|
||||
auto elem = cast<OneOfElementDecl>(D);
|
||||
|
||||
// FIXME: Handle attributes.
|
||||
if (!elem->getAttrs().empty())
|
||||
return false;
|
||||
|
||||
const Decl *DC = getDeclForContext(elem->getDeclContext());
|
||||
|
||||
unsigned abbrCode = DeclTypeAbbrCodes[OneOfElementLayout::Code];
|
||||
OneOfElementLayout::emitRecord(Out, ScratchRecord, abbrCode,
|
||||
addIdentifierRef(elem->getName()),
|
||||
addDeclRef(DC),
|
||||
addTypeRef(elem->getArgumentType()),
|
||||
addTypeRef(elem->getType()),
|
||||
elem->isImplicit());
|
||||
return true;
|
||||
}
|
||||
|
||||
case DeclKind::Subscript:
|
||||
return false;
|
||||
|
||||
@@ -1370,6 +1413,8 @@ void Serializer::writeAllDeclsAndTypes() {
|
||||
registerDeclTypeAbbr<PostfixOperatorLayout>();
|
||||
registerDeclTypeAbbr<InfixOperatorLayout>();
|
||||
registerDeclTypeAbbr<ClassLayout>();
|
||||
registerDeclTypeAbbr<OneOfLayout>();
|
||||
registerDeclTypeAbbr<OneOfElementLayout>();
|
||||
|
||||
registerDeclTypeAbbr<ParenPatternLayout>();
|
||||
registerDeclTypeAbbr<TuplePatternLayout>();
|
||||
|
||||
30
test/Serialization/Inputs/def_oneof.swift
Normal file
30
test/Serialization/Inputs/def_oneof.swift
Normal file
@@ -0,0 +1,30 @@
|
||||
oneof Basic {
|
||||
Untyped,
|
||||
HasType : Int
|
||||
|
||||
constructor() {
|
||||
this = .Untyped
|
||||
}
|
||||
func doSomething() {}
|
||||
}
|
||||
|
||||
oneof Generic<A> {
|
||||
Left : A,
|
||||
Right : A
|
||||
}
|
||||
|
||||
|
||||
protocol Computable {
|
||||
func compute()
|
||||
}
|
||||
|
||||
oneof Lazy<T> : Computable {
|
||||
Thunk : () -> T,
|
||||
Value : T
|
||||
|
||||
func compute() {
|
||||
// if (this ~= .Thunk(var fn)) {
|
||||
// this = .Value(fn())
|
||||
// }
|
||||
}
|
||||
}
|
||||
23
test/Serialization/oneof.swift
Normal file
23
test/Serialization/oneof.swift
Normal file
@@ -0,0 +1,23 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: mkdir %t
|
||||
// RUN: %swift -emit-module -o %t/def_oneof.swiftmodule %S/Inputs/def_oneof.swift
|
||||
// RUN: llvm-bcanalyzer %t/def_oneof.swiftmodule | FileCheck %s
|
||||
// RUN: %swift -parse -I=%t %s -o /dev/null
|
||||
|
||||
// CHECK-NOT: FALL_BACK_TO_TRANSLATION_UNIT
|
||||
|
||||
import def_oneof
|
||||
|
||||
var a : Basic
|
||||
a = .Untyped
|
||||
a.doSomething()
|
||||
a = .HasType(4)
|
||||
a.doSomething()
|
||||
|
||||
var g = Generic.Left(false)
|
||||
g = .Right(true)
|
||||
|
||||
var lazy = Lazy.Thunk({ 42 })
|
||||
var comp : Computable = lazy
|
||||
comp.compute()
|
||||
lazy.compute()
|
||||
Reference in New Issue
Block a user