mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
(De-)serialization for foreign error conventions.
Currently untestable (due to SILGen's inability to handle throwing @objc methods), but testing will become trivial once that's in place. Swift SVN r27294
This commit is contained in:
@@ -148,6 +148,7 @@ PATTERN(NOMINAL_TYPE)
|
||||
TRAILING_INFO(NOMINAL_TYPE_PATTERN_ELT)
|
||||
PATTERN(VAR)
|
||||
|
||||
OTHER(FOREIGN_ERROR_CONVENTION, 228)
|
||||
OTHER(DECL_CONTEXT, 229)
|
||||
OTHER(XREF_TYPE_PATH_PIECE, 230)
|
||||
OTHER(XREF_VALUE_PATH_PIECE, 231)
|
||||
|
||||
@@ -660,6 +660,9 @@ public:
|
||||
GenericParamList *maybeReadGenericParams(DeclContext *DC,
|
||||
llvm::BitstreamCursor &Cursor,
|
||||
GenericParamList *outerParams = nullptr);
|
||||
|
||||
/// Reads a foreign error conformance from \c DeclTypeCursor, if present.
|
||||
Optional<ForeignErrorConvention> maybeReadForeignErrorConvention();
|
||||
};
|
||||
|
||||
} // end namespace swift
|
||||
|
||||
@@ -51,7 +51,7 @@ const uint16_t VERSION_MAJOR = 0;
|
||||
/// To ensure that two separate changes don't silently get merged into one
|
||||
/// in source control, you should also update the comment to briefly
|
||||
/// describe what change you made.
|
||||
const uint16_t VERSION_MINOR = 191; // Last change: consolidate function type representations
|
||||
const uint16_t VERSION_MINOR = 192; // Last change: foreign error convention
|
||||
|
||||
using DeclID = Fixnum<31>;
|
||||
using DeclIDField = BCFixed<31>;
|
||||
@@ -115,6 +115,15 @@ enum class FunctionTypeRepresentation : uint8_t {
|
||||
};
|
||||
using FunctionTypeRepresentationField = BCFixed<4>;
|
||||
|
||||
enum class ForeignErrorConventionKind : uint8_t {
|
||||
ZeroResult,
|
||||
NonZeroResult,
|
||||
NilResult,
|
||||
NonNilError,
|
||||
};
|
||||
|
||||
using ForeignErrorConventionKindField = BCFixed<2>;
|
||||
|
||||
// These IDs must \em not be renumbered or reordered without incrementing
|
||||
// VERSION_MAJOR.
|
||||
enum class SILFunctionTypeRepresentation : uint8_t {
|
||||
@@ -1200,6 +1209,15 @@ namespace decls_block {
|
||||
BCFixed<1> // is a decl
|
||||
>;
|
||||
|
||||
using ForeignErrorConventionLayout = BCRecordLayout<
|
||||
FOREIGN_ERROR_CONVENTION,
|
||||
ForeignErrorConventionKindField, // kind
|
||||
BCFixed<1>, // owned
|
||||
BCVBR<4>, // error parameter index
|
||||
TypeIDField, // error parameter type
|
||||
TypeIDField // result type
|
||||
>;
|
||||
|
||||
using AbstractClosureExprLayout = BCRecordLayout<
|
||||
ABSTRACT_CLOSURE_EXPR_CONTEXT,
|
||||
TypeIDField, // type
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "swift/Serialization/ModuleFormat.h"
|
||||
#include "swift/AST/AST.h"
|
||||
#include "swift/AST/ASTContext.h"
|
||||
#include "swift/AST/ForeignErrorConvention.h"
|
||||
#include "swift/AST/PrettyStackTrace.h"
|
||||
#include "swift/ClangImporter/ClangImporter.h"
|
||||
#include "swift/Serialization/BCReadingExtras.h"
|
||||
@@ -2140,6 +2141,9 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
assert(bodyParams0&&bodyParams1 && "missing body patterns for constructor");
|
||||
ctor->setBodyParams(bodyParams0, bodyParams1);
|
||||
|
||||
if (auto errorConvention = maybeReadForeignErrorConvention())
|
||||
ctor->setForeignErrorConvention(*errorConvention);
|
||||
|
||||
// This must be set after recording the constructor in the map.
|
||||
// A polymorphic constructor type needs to refer to the constructor to get
|
||||
// its generic parameters.
|
||||
@@ -2398,6 +2402,9 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
fn->setDeserializedSignature(patterns,
|
||||
TypeLoc::withoutLoc(signature->getResult()));
|
||||
|
||||
if (auto errorConvention = maybeReadForeignErrorConvention())
|
||||
fn->setForeignErrorConvention(*errorConvention);
|
||||
|
||||
if (auto overridden = cast_or_null<FuncDecl>(getDecl(overriddenID))) {
|
||||
fn->setOverriddenDecl(overridden);
|
||||
AddAttribute(new (ctx) OverrideAttr(SourceLoc()));
|
||||
@@ -2408,6 +2415,7 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
fn->setImplicit();
|
||||
fn->setMutating(isMutating);
|
||||
fn->setDynamicSelf(hasDynamicSelf);
|
||||
|
||||
// If we are an accessor on a var or subscript, make sure it is deserialized
|
||||
// too.
|
||||
getDecl(accessorStorageDeclID);
|
||||
@@ -3827,3 +3835,92 @@ ModuleFile::loadAssociatedTypeDefault(const swift::AssociatedTypeDecl *ATD,
|
||||
uint64_t contextData) {
|
||||
return TypeLoc::withoutLoc(getType(contextData));
|
||||
}
|
||||
|
||||
static Optional<ForeignErrorConvention::Kind>
|
||||
decodeRawStableForeignErrorConventionKind(uint8_t kind) {
|
||||
switch (kind) {
|
||||
case static_cast<uint8_t>(ForeignErrorConventionKind::ZeroResult):
|
||||
return ForeignErrorConvention::ZeroResult;
|
||||
case static_cast<uint8_t>(ForeignErrorConventionKind::NonZeroResult):
|
||||
return ForeignErrorConvention::NonZeroResult;
|
||||
case static_cast<uint8_t>(ForeignErrorConventionKind::NilResult):
|
||||
return ForeignErrorConvention::NilResult;
|
||||
case static_cast<uint8_t>(ForeignErrorConventionKind::NonNilError):
|
||||
return ForeignErrorConvention::NonNilError;
|
||||
default:
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
Optional<ForeignErrorConvention> ModuleFile::maybeReadForeignErrorConvention() {
|
||||
using namespace decls_block;
|
||||
|
||||
SmallVector<uint64_t, 8> scratch;
|
||||
|
||||
auto next = DeclTypeCursor.advance(AF_DontPopBlockAtEnd);
|
||||
if (next.Kind != llvm::BitstreamEntry::Record)
|
||||
return None;
|
||||
|
||||
unsigned recKind = DeclTypeCursor.readRecord(next.ID, scratch);
|
||||
switch (recKind) {
|
||||
case FOREIGN_ERROR_CONVENTION:
|
||||
break;
|
||||
|
||||
default:
|
||||
return None;
|
||||
}
|
||||
|
||||
uint8_t rawKind;
|
||||
bool isOwned;
|
||||
unsigned errorParameterIndex;
|
||||
TypeID errorParameterTypeID;
|
||||
TypeID resultTypeID;
|
||||
ForeignErrorConventionLayout::readRecord(scratch, rawKind, isOwned,
|
||||
errorParameterIndex,
|
||||
errorParameterTypeID,
|
||||
resultTypeID);
|
||||
|
||||
ForeignErrorConvention::Kind kind;
|
||||
if (auto optKind = decodeRawStableForeignErrorConventionKind(rawKind))
|
||||
kind = *optKind;
|
||||
else {
|
||||
error();
|
||||
return None;
|
||||
}
|
||||
|
||||
Type errorParameterType = getType(errorParameterTypeID);
|
||||
CanType canErrorParameterType;
|
||||
if (errorParameterType)
|
||||
canErrorParameterType = errorParameterType->getCanonicalType();
|
||||
|
||||
Type resultType = getType(resultTypeID);
|
||||
CanType canResultType;
|
||||
if (resultType)
|
||||
canResultType = resultType->getCanonicalType();
|
||||
|
||||
auto owned = isOwned ? ForeignErrorConvention::IsOwned
|
||||
: ForeignErrorConvention::IsNotOwned;
|
||||
switch (kind) {
|
||||
case ForeignErrorConvention::ZeroResult:
|
||||
return ForeignErrorConvention::getZeroResult(errorParameterIndex,
|
||||
owned,
|
||||
canErrorParameterType,
|
||||
canResultType);
|
||||
|
||||
case ForeignErrorConvention::NonZeroResult:
|
||||
return ForeignErrorConvention::getNonZeroResult(errorParameterIndex,
|
||||
owned,
|
||||
canErrorParameterType,
|
||||
canResultType);
|
||||
|
||||
case ForeignErrorConvention::NilResult:
|
||||
return ForeignErrorConvention::getNilResult(errorParameterIndex,
|
||||
owned,
|
||||
canErrorParameterType);
|
||||
|
||||
case ForeignErrorConvention::NonNilError:
|
||||
return ForeignErrorConvention::getNonNilError(errorParameterIndex,
|
||||
owned,
|
||||
canErrorParameterType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "swift/AST/AST.h"
|
||||
#include "swift/AST/ASTWalker.h"
|
||||
#include "swift/AST/DiagnosticsCommon.h"
|
||||
#include "swift/AST/ForeignErrorConvention.h"
|
||||
#include "swift/AST/LinkLibrary.h"
|
||||
#include "swift/AST/Mangle.h"
|
||||
#include "swift/AST/RawComment.h"
|
||||
@@ -1772,6 +1773,48 @@ void Serializer::writeLocalDeclContext(const DeclContext *DC) {
|
||||
}
|
||||
}
|
||||
|
||||
static ForeignErrorConventionKind getRawStableForeignErrorConventionKind(
|
||||
ForeignErrorConvention::Kind kind) {
|
||||
switch (kind) {
|
||||
case ForeignErrorConvention::ZeroResult:
|
||||
return ForeignErrorConventionKind::ZeroResult;
|
||||
case ForeignErrorConvention::NonZeroResult:
|
||||
return ForeignErrorConventionKind::NonZeroResult;
|
||||
case ForeignErrorConvention::NilResult:
|
||||
return ForeignErrorConventionKind::NilResult;
|
||||
case ForeignErrorConvention::NonNilError:
|
||||
return ForeignErrorConventionKind::NonNilError;
|
||||
}
|
||||
}
|
||||
|
||||
void Serializer::writeForeignErrorConvention(const ForeignErrorConvention &fec){
|
||||
using namespace decls_block;
|
||||
|
||||
auto kind = getRawStableForeignErrorConventionKind(fec.getKind());
|
||||
uint8_t isOwned = fec.isErrorOwned() == ForeignErrorConvention::IsOwned;
|
||||
TypeID errorParameterTypeID = addTypeRef(fec.getErrorParameterType());
|
||||
TypeID resultTypeID;
|
||||
switch (fec.getKind()) {
|
||||
case ForeignErrorConvention::ZeroResult:
|
||||
case ForeignErrorConvention::NonZeroResult:
|
||||
resultTypeID = addTypeRef(fec.getResultType());
|
||||
break;
|
||||
|
||||
case ForeignErrorConvention::NilResult:
|
||||
case ForeignErrorConvention::NonNilError:
|
||||
resultTypeID = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
auto abbrCode = DeclTypeAbbrCodes[ForeignErrorConventionLayout::Code];
|
||||
ForeignErrorConventionLayout::emitRecord(Out, ScratchRecord, abbrCode,
|
||||
static_cast<uint8_t>(kind),
|
||||
isOwned,
|
||||
fec.getErrorParameterIndex(),
|
||||
errorParameterTypeID,
|
||||
resultTypeID);
|
||||
}
|
||||
|
||||
void Serializer::writeDecl(const Decl *D) {
|
||||
using namespace decls_block;
|
||||
|
||||
@@ -2244,6 +2287,9 @@ void Serializer::writeDecl(const Decl *D) {
|
||||
for (auto pattern : fn->getBodyParamPatterns())
|
||||
writePattern(pattern);
|
||||
|
||||
if (auto errorConvention = fn->getForeignErrorConvention())
|
||||
writeForeignErrorConvention(*errorConvention);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2355,6 +2401,8 @@ void Serializer::writeDecl(const Decl *D) {
|
||||
assert(ctor->getBodyParamPatterns().size() == 2);
|
||||
for (auto pattern : ctor->getBodyParamPatterns())
|
||||
writePattern(pattern);
|
||||
if (auto errorConvention = ctor->getForeignErrorConvention())
|
||||
writeForeignErrorConvention(*errorConvention);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3046,6 +3094,7 @@ void Serializer::writeAllDeclsAndTypes() {
|
||||
registerDeclTypeAbbr<GenericRequirementLayout>();
|
||||
registerDeclTypeAbbr<LastGenericRequirementLayout>();
|
||||
|
||||
registerDeclTypeAbbr<ForeignErrorConventionLayout>();
|
||||
registerDeclTypeAbbr<DeclContextLayout>();
|
||||
registerDeclTypeAbbr<AbstractClosureExprLayout>();
|
||||
registerDeclTypeAbbr<PatternBindingInitializerLayout>();
|
||||
|
||||
@@ -263,6 +263,9 @@ private:
|
||||
/// Writes out a declaration attribute.
|
||||
void writeDeclAttribute(const DeclAttribute *DA);
|
||||
|
||||
/// Writes out a foreign error convention.
|
||||
void writeForeignErrorConvention(const ForeignErrorConvention &fec);
|
||||
|
||||
/// Writes the given decl.
|
||||
void writeDecl(const Decl *D);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user