mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Deserializing a witness record in a conformance may fail if either of the requirement or witness changed name or type, most likely due to SDK modernization changes across Swift versions. When this happens, leave an opaque placeholder in the conformance to indicate that the witness exists but we don't get to see it. For expedience, right now this just witnesses the requirement to itself, so that code in the type checker or elsewhere that tries to ad-hoc devirtualize references to the requirement just gets the requirement back. Arguably, we shouldn't include the witness at all in imported conformances, since they should be an implementation detail, but that's a bigger, riskier change. This patch as is should be enough to address rdar://problem/31185053.
150 lines
4.6 KiB
C++
150 lines
4.6 KiB
C++
//===--- Validation.h - Validation / errors for serialization ---*- C++ -*-===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef SWIFT_SERIALIZATION_VALIDATION_H
|
|
#define SWIFT_SERIALIZATION_VALIDATION_H
|
|
|
|
#include "swift/Basic/LLVM.h"
|
|
#include "llvm/ADT/ArrayRef.h"
|
|
#include "llvm/ADT/SmallVector.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
|
|
namespace swift {
|
|
|
|
enum class ResilienceStrategy : unsigned;
|
|
|
|
namespace serialization {
|
|
|
|
/// Describes whether a serialized module can be used by this compiler.
|
|
enum class Status {
|
|
/// The module is valid.
|
|
Valid,
|
|
|
|
/// The module file format is too old to be used by this version of the
|
|
/// compiler.
|
|
FormatTooOld,
|
|
|
|
/// The module file format is too new to be used by this version of the
|
|
/// compiler.
|
|
FormatTooNew,
|
|
|
|
/// The module file depends on another module that can't be loaded.
|
|
MissingDependency,
|
|
|
|
/// The module file is an overlay for a Clang module, which can't be found.
|
|
MissingShadowedModule,
|
|
|
|
/// The module file depends on a bridging header that can't be loaded.
|
|
FailedToLoadBridgingHeader,
|
|
|
|
/// The module file is malformed in some way.
|
|
Malformed,
|
|
|
|
/// The module documentation file is malformed in some way.
|
|
MalformedDocumentation,
|
|
|
|
/// The module file's name does not match the module it is being loaded
|
|
/// into.
|
|
NameMismatch,
|
|
|
|
/// The module file was built for a different target platform.
|
|
TargetIncompatible,
|
|
|
|
/// The module file was built for a target newer than the current target.
|
|
TargetTooNew
|
|
};
|
|
|
|
/// Returns true if the data looks like it contains a serialized AST.
|
|
bool isSerializedAST(StringRef data);
|
|
|
|
/// \see validateSerializedAST()
|
|
struct ValidationInfo {
|
|
StringRef name = {};
|
|
StringRef targetTriple = {};
|
|
StringRef shortVersion = {};
|
|
version::Version compatibilityVersion = {};
|
|
size_t bytes = 0;
|
|
Status status = Status::Malformed;
|
|
};
|
|
|
|
/// A collection of options that can be used to set up a new AST context
|
|
/// before it has been created.
|
|
///
|
|
/// Note that this is intended to be a transient data structure; as such,
|
|
/// <strong>none of the string values added to it are copied</strong>.
|
|
///
|
|
/// \sa validateSerializedAST()
|
|
class ExtendedValidationInfo {
|
|
SmallVector<StringRef, 4> ExtraClangImporterOpts;
|
|
StringRef SDKPath;
|
|
struct {
|
|
unsigned IsSIB : 1;
|
|
unsigned IsTestable : 1;
|
|
unsigned ResilienceStrategy : 2;
|
|
} Bits;
|
|
public:
|
|
ExtendedValidationInfo() : Bits() {}
|
|
|
|
StringRef getSDKPath() const { return SDKPath; }
|
|
void setSDKPath(StringRef path) {
|
|
assert(SDKPath.empty());
|
|
SDKPath = path;
|
|
}
|
|
|
|
ArrayRef<StringRef> getExtraClangImporterOptions() const {
|
|
return ExtraClangImporterOpts;
|
|
}
|
|
void addExtraClangImporterOption(StringRef option) {
|
|
ExtraClangImporterOpts.push_back(option);
|
|
}
|
|
|
|
bool isSIB() const { return Bits.IsSIB; }
|
|
void setIsSIB(bool val) {
|
|
Bits.IsSIB = val;
|
|
}
|
|
bool isTestable() const { return Bits.IsTestable; }
|
|
void setIsTestable(bool val) {
|
|
Bits.IsTestable = val;
|
|
}
|
|
ResilienceStrategy getResilienceStrategy() const {
|
|
return ResilienceStrategy(Bits.ResilienceStrategy);
|
|
}
|
|
void setResilienceStrategy(ResilienceStrategy resilience) {
|
|
Bits.ResilienceStrategy = unsigned(resilience);
|
|
}
|
|
};
|
|
|
|
/// Returns info about the serialized AST in the given data.
|
|
///
|
|
/// If the returned status is anything but Status::Valid, the serialized data
|
|
/// cannot be loaded by this version of the compiler. If the returned size is
|
|
/// non-zero, it's possible to skip over this module's data, in case there is
|
|
/// more data in the buffer. The returned name, which may be empty, directly
|
|
/// points into the given data buffer.
|
|
///
|
|
/// Note that this does not actually try to load the module or validate any
|
|
/// of its dependencies; it only checks that it /can/ be loaded.
|
|
///
|
|
/// \param data A buffer containing the serialized AST. Result information
|
|
/// refers directly into this buffer.
|
|
/// \param[out] extendedInfo If present, will be populated with additional
|
|
/// compilation options serialized into the AST at build time that may be
|
|
/// necessary to load it properly.
|
|
ValidationInfo
|
|
validateSerializedAST(StringRef data,
|
|
ExtendedValidationInfo *extendedInfo = nullptr);
|
|
|
|
} // end namespace serialization
|
|
} // end namespace swift
|
|
|
|
#endif
|