[Serialization] Move (Module)Status and validateSerializedAST into a namespace.

Also into a separate file.

Before (swift/Serialization/SerializedModuleLoader.h):
  ModuleStatus
  SerializedModuleLoader::ValidationInfo
  SerializedModuleLoader::ExtendedValidationInfo
  SerializedModuleLoader::isSerializedAST
  SerializedModuleLoader::validateSerializedAST

After (swift/Serialization/Validation.h):
  serialization::Status
  serialization::ValidationInfo
  serialization::ExtendedValidationInfo
  serialization::isSerializedAST
  serialization::validateSerializedAST

No functionality change, just a lot of renaming and a bit of reorganizing.

Swift SVN r25226
This commit is contained in:
Jordan Rose
2015-02-12 05:32:25 +00:00
parent 65b432a495
commit dbd3b60f6b
13 changed files with 204 additions and 174 deletions

View File

@@ -20,8 +20,8 @@
#include "swift/AST/Module.h" #include "swift/AST/Module.h"
#include "swift/AST/RawComment.h" #include "swift/AST/RawComment.h"
#include "swift/AST/TypeLoc.h" #include "swift/AST/TypeLoc.h"
#include "swift/Serialization/SerializedModuleLoader.h"
#include "swift/Serialization/ModuleFormat.h" #include "swift/Serialization/ModuleFormat.h"
#include "swift/Serialization/Validation.h"
#include "swift/Basic/LLVM.h" #include "swift/Basic/LLVM.h"
#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
@@ -43,6 +43,7 @@ class ProtocolConformance;
/// A serialized module, along with the tools to access it. /// A serialized module, along with the tools to access it.
class ModuleFile : public LazyMemberLoader { class ModuleFile : public LazyMemberLoader {
friend class SerializedASTFile; friend class SerializedASTFile;
using Status = serialization::Status;
/// A reference back to the AST representation of the file. /// A reference back to the AST representation of the file.
FileUnit *FileContext = nullptr; FileUnit *FileContext = nullptr;
@@ -317,7 +318,7 @@ private:
} Bits = {}; } Bits = {};
static_assert(sizeof(Bits) <= 8, "The bit set should be small"); static_assert(sizeof(Bits) <= 8, "The bit set should be small");
void setStatus(ModuleStatus status) { void setStatus(Status status) {
Bits.Status = static_cast<unsigned>(status); Bits.Status = static_cast<unsigned>(status);
assert(status == getStatus() && "not enough bits for status"); assert(status == getStatus() && "not enough bits for status");
} }
@@ -340,9 +341,9 @@ private:
public: public:
/// Change the status of the current module. Default argument marks the module /// Change the status of the current module. Default argument marks the module
/// as being malformed. /// as being malformed.
ModuleStatus error(ModuleStatus issue = ModuleStatus::Malformed) { Status error(Status issue = Status::Malformed) {
assert(issue != ModuleStatus::Valid); assert(issue != Status::Valid);
assert((!FileContext || issue != ModuleStatus::Malformed) && assert((!FileContext || issue != Status::Malformed) &&
"error deserializing an individual record"); "error deserializing an individual record");
setStatus(issue); setStatus(issue);
return getStatus(); return getStatus();
@@ -444,7 +445,7 @@ public:
/// \param[out] theModule The loaded module. /// \param[out] theModule The loaded module.
/// \returns Whether the module was successfully loaded, or what went wrong /// \returns Whether the module was successfully loaded, or what went wrong
/// if it was not. /// if it was not.
static ModuleStatus static Status
load(std::unique_ptr<llvm::MemoryBuffer> moduleInputBuffer, load(std::unique_ptr<llvm::MemoryBuffer> moduleInputBuffer,
std::unique_ptr<llvm::MemoryBuffer> moduleDocInputBuffer, std::unique_ptr<llvm::MemoryBuffer> moduleDocInputBuffer,
bool isFramework, std::unique_ptr<ModuleFile> &theModule) { bool isFramework, std::unique_ptr<ModuleFile> &theModule) {
@@ -461,11 +462,11 @@ public:
/// ///
/// Returns any error that occurred during association, including validation /// Returns any error that occurred during association, including validation
/// that the module file is compatible with the module it's being loaded as. /// that the module file is compatible with the module it's being loaded as.
ModuleStatus associateWithFileContext(FileUnit *file, SourceLoc diagLoc); Status associateWithFileContext(FileUnit *file, SourceLoc diagLoc);
/// Checks whether this module can be used. /// Checks whether this module can be used.
ModuleStatus getStatus() const { Status getStatus() const {
return static_cast<ModuleStatus>(Bits.Status); return static_cast<Status>(Bits.Status);
} }
/// Returns the list of modules this module depends on. /// Returns the list of modules this module depends on.

View File

@@ -16,46 +16,10 @@
#include "swift/AST/Module.h" #include "swift/AST/Module.h"
#include "swift/AST/ModuleLoader.h" #include "swift/AST/ModuleLoader.h"
#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MemoryBuffer.h"
#include <map>
namespace swift { namespace swift {
class ModuleFile; class ModuleFile;
/// Describes whether a loaded module can be used.
enum class ModuleStatus {
/// 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 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
};
/// \brief Imports serialized Swift modules into an ASTContext. /// \brief Imports serialized Swift modules into an ASTContext.
class SerializedModuleLoader : public ModuleLoader { class SerializedModuleLoader : public ModuleLoader {
private: private:
@@ -126,64 +90,6 @@ public:
unsigned previousGeneration, unsigned previousGeneration,
llvm::TinyPtrVector<AbstractFunctionDecl *> &methods); llvm::TinyPtrVector<AbstractFunctionDecl *> &methods);
/// Returns true if the data looks like it contains a serialized AST.
static bool isSerializedAST(StringRef data);
/// \see validateSerializedAST()
struct ValidationInfo {
StringRef name = {};
StringRef targetTriple = {};
size_t bytes = 0;
ModuleStatus status = ModuleStatus::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> ClangImporterOpts;
StringRef SDKPath;
public:
ExtendedValidationInfo() = default;
StringRef getSDKPath() const { return SDKPath; }
void setSDKPath(StringRef path) {
assert(SDKPath.empty());
SDKPath = path;
}
ArrayRef<StringRef> getClangImporterOptions() const {
return ClangImporterOpts;
}
void addClangImporterOption(StringRef option) {
ClangImporterOpts.push_back(option);
}
};
/// Returns info about the serialized AST in the given data.
///
/// If the returned status is anything but ModuleStatus::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.
static ValidationInfo
validateSerializedAST(StringRef data,
ExtendedValidationInfo *extendedInfo = nullptr);
virtual void verifyAllModules() override; virtual void verifyAllModules() override;
}; };

View File

@@ -13,6 +13,11 @@
#ifndef SWIFT_SERIALIZATION_SILLOADER_H #ifndef SWIFT_SERIALIZATION_SILLOADER_H
#define SWIFT_SERIALIZATION_SILLOADER_H #define SWIFT_SERIALIZATION_SILLOADER_H
#include "swift/AST/Decl.h"
#include "swift/AST/Identifier.h"
#include <memory>
#include <vector>
namespace swift { namespace swift {
class ASTContext; class ASTContext;
class Module; class Module;

View File

@@ -0,0 +1,121 @@
//===--- Validation.h - Validation / errors for serialization ---*- c++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://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 {
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 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 = {};
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;
public:
ExtendedValidationInfo() = default;
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);
}
};
/// 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

View File

@@ -18,6 +18,7 @@
#include "swift/ASTSectionImporter/ASTSectionImporter.h" #include "swift/ASTSectionImporter/ASTSectionImporter.h"
#include "swift/Basic/Dwarf.h" #include "swift/Basic/Dwarf.h"
#include "swift/Serialization/SerializedModuleLoader.h" #include "swift/Serialization/SerializedModuleLoader.h"
#include "swift/Serialization/Validation.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
@@ -25,17 +26,17 @@ using namespace swift;
bool swift::parseASTSection(SerializedModuleLoader *SML, StringRef buf, bool swift::parseASTSection(SerializedModuleLoader *SML, StringRef buf,
SmallVectorImpl<std::string> &foundModules) { SmallVectorImpl<std::string> &foundModules) {
if (!SerializedModuleLoader::isSerializedAST(buf)) if (!serialization::isSerializedAST(buf))
return false; return false;
// An AST section consists of one or more AST modules, optionally with // An AST section consists of one or more AST modules, optionally with
// headers. Iterate over all AST modules. // headers. Iterate over all AST modules.
while (!buf.empty()) { while (!buf.empty()) {
auto info = SerializedModuleLoader::validateSerializedAST(buf); auto info = serialization::validateSerializedAST(buf);
assert(info.name.size() < (2 << 10) && "name failed sanity check"); assert(info.name.size() < (2 << 10) && "name failed sanity check");
if (info.status == ModuleStatus::Valid) { if (info.status == serialization::Status::Valid) {
assert(info.bytes != 0); assert(info.bytes != 0);
if (!info.name.empty()) { if (!info.name.empty()) {
StringRef moduleData = buf.substr(0, info.bytes); StringRef moduleData = buf.substr(0, info.bytes);

View File

@@ -130,7 +130,7 @@ bool CompilerInstance::setup(const CompilerInvocation &Invok) {
auto Copy = std::unique_ptr<llvm::MemoryBuffer>( auto Copy = std::unique_ptr<llvm::MemoryBuffer>(
llvm::MemoryBuffer::getMemBufferCopy( llvm::MemoryBuffer::getMemBufferCopy(
InputBuffer->getBuffer(), InputBuffer->getBufferIdentifier())); InputBuffer->getBuffer(), InputBuffer->getBufferIdentifier()));
if (SerializedModuleLoader::isSerializedAST(Copy->getBuffer())) { if (serialization::isSerializedAST(Copy->getBuffer())) {
PartialModules.push_back({ std::move(Copy), nullptr }); PartialModules.push_back({ std::move(Copy), nullptr });
} else { } else {
unsigned BufferID = SourceMgr.addNewSourceBuffer(std::move(Copy)); unsigned BufferID = SourceMgr.addNewSourceBuffer(std::move(Copy));
@@ -171,8 +171,7 @@ bool CompilerInstance::setup(const CompilerInvocation &Invok) {
return true; return true;
} }
if (SerializedModuleLoader::isSerializedAST( if (serialization::isSerializedAST(InputFileOrErr.get()->getBuffer())) {
InputFileOrErr.get()->getBuffer())) {
llvm::SmallString<128> ModuleDocFilePath(File); llvm::SmallString<128> ModuleDocFilePath(File);
llvm::sys::path::replace_extension(ModuleDocFilePath, llvm::sys::path::replace_extension(ModuleDocFilePath,
SERIALIZED_MODULE_DOC_EXTENSION); SERIALIZED_MODULE_DOC_EXTENSION);

View File

@@ -14,8 +14,6 @@
#include "swift/Basic/SourceManager.h" #include "swift/Basic/SourceManager.h"
#include "swift/ClangImporter/ClangModule.h" #include "swift/ClangImporter/ClangModule.h"
#include "swift/Parse/Parser.h" #include "swift/Parse/Parser.h"
#include "swift/Serialization/SerializedModuleLoader.h"
#include "swift/Serialization/ModuleFile.h"
#include "swift/Subsystems.h" #include "swift/Subsystems.h"
#include "clang/AST/ASTContext.h" #include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h" #include "clang/AST/DeclObjC.h"

View File

@@ -20,6 +20,7 @@
#include "swift/Basic/Range.h" #include "swift/Basic/Range.h"
#include "swift/ClangImporter/ClangImporter.h" #include "swift/ClangImporter/ClangImporter.h"
#include "swift/Serialization/BCReadingExtras.h" #include "swift/Serialization/BCReadingExtras.h"
#include "swift/Serialization/SerializedModuleLoader.h"
#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringExtras.h"
#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MemoryBuffer.h"
@@ -30,9 +31,6 @@ using namespace swift;
using namespace swift::serialization; using namespace swift::serialization;
using namespace llvm::support; using namespace llvm::support;
using ValidationInfo = SerializedModuleLoader::ValidationInfo;
using ExtendedValidationInfo = SerializedModuleLoader::ExtendedValidationInfo;
static bool checkModuleSignature(llvm::BitstreamCursor &cursor) { static bool checkModuleSignature(llvm::BitstreamCursor &cursor) {
for (unsigned char byte : MODULE_SIGNATURE) for (unsigned char byte : MODULE_SIGNATURE)
if (cursor.AtEndOfStream() || cursor.Read(8) != byte) if (cursor.AtEndOfStream() || cursor.Read(8) != byte)
@@ -101,7 +99,7 @@ static bool readOptionsBlock(llvm::BitstreamCursor &cursor,
extendedInfo.setSDKPath(blobData); extendedInfo.setSDKPath(blobData);
break; break;
case options_block::XCC: case options_block::XCC:
extendedInfo.addClangImporterOption(blobData); extendedInfo.addExtraClangImporterOption(blobData);
break; break;
default: default:
// Unknown options record, possibly for use by a future version of the // Unknown options record, possibly for use by a future version of the
@@ -127,7 +125,7 @@ validateControlBlock(llvm::BitstreamCursor &cursor,
auto next = cursor.advance(); auto next = cursor.advance();
while (next.Kind != llvm::BitstreamEntry::EndBlock) { while (next.Kind != llvm::BitstreamEntry::EndBlock) {
if (next.Kind == llvm::BitstreamEntry::Error) { if (next.Kind == llvm::BitstreamEntry::Error) {
result.status = ModuleStatus::Malformed; result.status = Status::Malformed;
return result; return result;
} }
@@ -135,14 +133,14 @@ validateControlBlock(llvm::BitstreamCursor &cursor,
if (next.ID == OPTIONS_BLOCK_ID && extendedInfo) { if (next.ID == OPTIONS_BLOCK_ID && extendedInfo) {
cursor.EnterSubBlock(OPTIONS_BLOCK_ID); cursor.EnterSubBlock(OPTIONS_BLOCK_ID);
if (!readOptionsBlock(cursor, scratch, *extendedInfo)) { if (!readOptionsBlock(cursor, scratch, *extendedInfo)) {
result.status = ModuleStatus::Malformed; result.status = Status::Malformed;
return result; return result;
} }
} else { } else {
// Unknown metadata sub-block, possibly for use by a future version of // Unknown metadata sub-block, possibly for use by a future version of
// the module format. // the module format.
if (cursor.SkipBlock()) { if (cursor.SkipBlock()) {
result.status = ModuleStatus::Malformed; result.status = Status::Malformed;
return result; return result;
} }
} }
@@ -156,26 +154,26 @@ validateControlBlock(llvm::BitstreamCursor &cursor,
switch (kind) { switch (kind) {
case control_block::METADATA: { case control_block::METADATA: {
if (versionSeen) { if (versionSeen) {
result.status = ModuleStatus::Malformed; result.status = Status::Malformed;
break; break;
} }
uint16_t versionMajor = scratch[0]; uint16_t versionMajor = scratch[0];
if (versionMajor > VERSION_MAJOR) if (versionMajor > VERSION_MAJOR)
result.status = ModuleStatus::FormatTooNew; result.status = Status::FormatTooNew;
else if (versionMajor < VERSION_MAJOR) else if (versionMajor < VERSION_MAJOR)
result.status = ModuleStatus::FormatTooOld; result.status = Status::FormatTooOld;
else else
result.status = ModuleStatus::Valid; result.status = Status::Valid;
// Major version 0 does not have stable minor versions. // Major version 0 does not have stable minor versions.
if (versionMajor == 0) { if (versionMajor == 0) {
uint16_t versionMinor = scratch[1]; uint16_t versionMinor = scratch[1];
if (versionMinor != VERSION_MINOR) { if (versionMinor != VERSION_MINOR) {
if (versionMinor < VERSION_MINOR) if (versionMinor < VERSION_MINOR)
result.status = ModuleStatus::FormatTooOld; result.status = Status::FormatTooOld;
else else
result.status = ModuleStatus::FormatTooNew; result.status = Status::FormatTooNew;
} }
} }
@@ -200,7 +198,13 @@ validateControlBlock(llvm::BitstreamCursor &cursor,
return result; return result;
} }
ValidationInfo SerializedModuleLoader::validateSerializedAST( bool serialization::isSerializedAST(StringRef data) {
StringRef signatureStr(reinterpret_cast<const char *>(MODULE_SIGNATURE),
llvm::array_lengthof(MODULE_SIGNATURE));
return data.startswith(signatureStr);
}
ValidationInfo serialization::validateSerializedAST(
StringRef data, StringRef data,
ExtendedValidationInfo *extendedInfo) { ExtendedValidationInfo *extendedInfo) {
ValidationInfo result; ValidationInfo result;
@@ -224,12 +228,12 @@ ValidationInfo SerializedModuleLoader::validateSerializedAST(
if (topLevelEntry.ID == CONTROL_BLOCK_ID) { if (topLevelEntry.ID == CONTROL_BLOCK_ID) {
cursor.EnterSubBlock(CONTROL_BLOCK_ID); cursor.EnterSubBlock(CONTROL_BLOCK_ID);
result = validateControlBlock(cursor, scratch, extendedInfo); result = validateControlBlock(cursor, scratch, extendedInfo);
if (result.status == ModuleStatus::Malformed) if (result.status == Status::Malformed)
return result; return result;
} else { } else {
if (cursor.SkipBlock()) { if (cursor.SkipBlock()) {
result.status = ModuleStatus::Malformed; result.status = Status::Malformed;
return result; return result;
} }
} }
@@ -242,7 +246,7 @@ ValidationInfo SerializedModuleLoader::validateSerializedAST(
assert(cursor.GetCurrentBitNo() % CHAR_BIT == 0); assert(cursor.GetCurrentBitNo() % CHAR_BIT == 0);
result.bytes = cursor.GetCurrentBitNo() / CHAR_BIT; result.bytes = cursor.GetCurrentBitNo() / CHAR_BIT;
} else { } else {
result.status = ModuleStatus::Malformed; result.status = Status::Malformed;
} }
return result; return result;
@@ -708,7 +712,7 @@ ModuleFile::ModuleFile(
getEndBytePtr(this->ModuleInputBuffer.get())), getEndBytePtr(this->ModuleInputBuffer.get())),
ModuleDocInputReader(getStartBytePtr(this->ModuleDocInputBuffer.get()), ModuleDocInputReader(getStartBytePtr(this->ModuleDocInputBuffer.get()),
getEndBytePtr(this->ModuleDocInputBuffer.get())) { getEndBytePtr(this->ModuleDocInputBuffer.get())) {
assert(getStatus() == ModuleStatus::Valid); assert(getStatus() == Status::Valid);
Bits.IsFramework = isFramework; Bits.IsFramework = isFramework;
PrettyModuleFileDeserialization stackEntry(*this); PrettyModuleFileDeserialization stackEntry(*this);
@@ -733,7 +737,7 @@ ModuleFile::ModuleFile(
cursor.EnterSubBlock(CONTROL_BLOCK_ID); cursor.EnterSubBlock(CONTROL_BLOCK_ID);
auto info = validateControlBlock(cursor, scratch, nullptr); auto info = validateControlBlock(cursor, scratch, nullptr);
if (info.status != ModuleStatus::Valid) { if (info.status != Status::Valid) {
error(info.status); error(info.status);
return; return;
} }
@@ -938,7 +942,7 @@ ModuleFile::ModuleFile(
llvm::BitstreamCursor docCursor{ModuleDocInputReader}; llvm::BitstreamCursor docCursor{ModuleDocInputReader};
if (!checkModuleDocSignature(docCursor) || if (!checkModuleDocSignature(docCursor) ||
!enterTopLevelModuleBlock(docCursor, MODULE_DOC_BLOCK_ID)) { !enterTopLevelModuleBlock(docCursor, MODULE_DOC_BLOCK_ID)) {
error(ModuleStatus::MalformedDocumentation); error(Status::MalformedDocumentation);
return; return;
} }
@@ -947,7 +951,7 @@ ModuleFile::ModuleFile(
switch (topLevelEntry.ID) { switch (topLevelEntry.ID) {
case COMMENT_BLOCK_ID: { case COMMENT_BLOCK_ID: {
if (!hasValidControlBlock || !readCommentBlock(docCursor)) { if (!hasValidControlBlock || !readCommentBlock(docCursor)) {
error(ModuleStatus::MalformedDocumentation); error(Status::MalformedDocumentation);
return; return;
} }
break; break;
@@ -957,7 +961,7 @@ ModuleFile::ModuleFile(
// Unknown top-level block, possibly for use by a future version of the // Unknown top-level block, possibly for use by a future version of the
// module format. // module format.
if (docCursor.SkipBlock()) { if (docCursor.SkipBlock()) {
error(ModuleStatus::MalformedDocumentation); error(Status::MalformedDocumentation);
return; return;
} }
break; break;
@@ -967,30 +971,30 @@ ModuleFile::ModuleFile(
} }
if (topLevelEntry.Kind != llvm::BitstreamEntry::EndBlock) { if (topLevelEntry.Kind != llvm::BitstreamEntry::EndBlock) {
error(ModuleStatus::MalformedDocumentation); error(Status::MalformedDocumentation);
return; return;
} }
} }
ModuleStatus ModuleFile::associateWithFileContext(FileUnit *file, Status ModuleFile::associateWithFileContext(FileUnit *file,
SourceLoc diagLoc) { SourceLoc diagLoc) {
PrettyModuleFileDeserialization stackEntry(*this); PrettyModuleFileDeserialization stackEntry(*this);
assert(getStatus() == ModuleStatus::Valid && "invalid module file"); assert(getStatus() == Status::Valid && "invalid module file");
assert(!FileContext && "already associated with an AST module"); assert(!FileContext && "already associated with an AST module");
FileContext = file; FileContext = file;
if (file->getParentModule()->Name.str() != Name) if (file->getParentModule()->Name.str() != Name)
return error(ModuleStatus::NameMismatch); return error(Status::NameMismatch);
ASTContext &ctx = getContext(); ASTContext &ctx = getContext();
llvm::Triple moduleTarget(llvm::Triple::normalize(TargetTriple)); llvm::Triple moduleTarget(llvm::Triple::normalize(TargetTriple));
if (!areCompatibleArchitectures(moduleTarget, ctx.LangOpts.Target) || if (!areCompatibleArchitectures(moduleTarget, ctx.LangOpts.Target) ||
!areCompatibleOSs(moduleTarget, ctx.LangOpts.Target)) { !areCompatibleOSs(moduleTarget, ctx.LangOpts.Target)) {
return error(ModuleStatus::TargetIncompatible); return error(Status::TargetIncompatible);
} else if (isTargetTooNew(moduleTarget, ctx.LangOpts.Target)) { } else if (isTargetTooNew(moduleTarget, ctx.LangOpts.Target)) {
return error(ModuleStatus::TargetTooNew); return error(Status::TargetTooNew);
} }
auto clangImporter = static_cast<ClangImporter *>(ctx.getClangModuleLoader()); auto clangImporter = static_cast<ClangImporter *>(ctx.getClangModuleLoader());
@@ -1044,7 +1048,7 @@ ModuleStatus ModuleFile::associateWithFileContext(FileUnit *file,
// If we're missing the module we're shadowing, treat that specially. // If we're missing the module we're shadowing, treat that specially.
if (modulePath.size() == 1 && if (modulePath.size() == 1 &&
modulePath.front() == file->getParentModule()->Name) { modulePath.front() == file->getParentModule()->Name) {
return error(ModuleStatus::MissingShadowedModule); return error(Status::MissingShadowedModule);
} }
// Otherwise, continue trying to load dependencies, so that we can list // Otherwise, continue trying to load dependencies, so that we can list
@@ -1065,7 +1069,7 @@ ModuleStatus ModuleFile::associateWithFileContext(FileUnit *file,
} }
if (missingDependency) { if (missingDependency) {
return error(ModuleStatus::MissingDependency); return error(Status::MissingDependency);
} }
if (Bits.HasUnderlyingModule) if (Bits.HasUnderlyingModule)

View File

@@ -161,10 +161,10 @@ FileUnit *SerializedModuleLoader::loadAST(
} }
std::unique_ptr<ModuleFile> loadedModuleFile; std::unique_ptr<ModuleFile> loadedModuleFile;
ModuleStatus err = ModuleFile::load(std::move(moduleInputBuffer), serialization::Status err = ModuleFile::load(std::move(moduleInputBuffer),
std::move(moduleDocInputBuffer), std::move(moduleDocInputBuffer),
isFramework, loadedModuleFile); isFramework, loadedModuleFile);
if (err == ModuleStatus::Valid) { if (err == serialization::Status::Valid) {
Ctx.bumpGeneration(); Ctx.bumpGeneration();
// We've loaded the file. Now try to bring it into the AST. // We've loaded the file. Now try to bring it into the AST.
@@ -174,7 +174,7 @@ FileUnit *SerializedModuleLoader::loadAST(
auto diagLocOrInvalid = diagLoc.getValueOr(SourceLoc()); auto diagLocOrInvalid = diagLoc.getValueOr(SourceLoc());
err = loadedModuleFile->associateWithFileContext(fileUnit, err = loadedModuleFile->associateWithFileContext(fileUnit,
diagLocOrInvalid); diagLocOrInvalid);
if (err == ModuleStatus::Valid) { if (err == serialization::Status::Valid) {
LoadedModuleFiles.emplace_back(std::move(loadedModuleFile), LoadedModuleFiles.emplace_back(std::move(loadedModuleFile),
Ctx.getCurrentGeneration()); Ctx.getCurrentGeneration());
return fileUnit; return fileUnit;
@@ -188,29 +188,29 @@ FileUnit *SerializedModuleLoader::loadAST(
return nullptr; return nullptr;
switch (loadedModuleFile->getStatus()) { switch (loadedModuleFile->getStatus()) {
case ModuleStatus::Valid: case serialization::Status::Valid:
llvm_unreachable("At this point we know loading has failed"); llvm_unreachable("At this point we know loading has failed");
case ModuleStatus::FormatTooNew: case serialization::Status::FormatTooNew:
Ctx.Diags.diagnose(*diagLoc, diag::serialization_module_too_new, Ctx.Diags.diagnose(*diagLoc, diag::serialization_module_too_new,
moduleBufferID); moduleBufferID);
break; break;
case ModuleStatus::FormatTooOld: case serialization::Status::FormatTooOld:
Ctx.Diags.diagnose(*diagLoc, diag::serialization_module_too_old, Ctx.Diags.diagnose(*diagLoc, diag::serialization_module_too_old,
moduleBufferID); moduleBufferID);
break; break;
case ModuleStatus::Malformed: case serialization::Status::Malformed:
Ctx.Diags.diagnose(*diagLoc, diag::serialization_malformed_module, Ctx.Diags.diagnose(*diagLoc, diag::serialization_malformed_module,
moduleBufferID); moduleBufferID);
break; break;
case ModuleStatus::MalformedDocumentation: case serialization::Status::MalformedDocumentation:
assert(moduleDocBufferID); assert(moduleDocBufferID);
Ctx.Diags.diagnose(*diagLoc, diag::serialization_malformed_module, Ctx.Diags.diagnose(*diagLoc, diag::serialization_malformed_module,
moduleDocBufferID ? moduleDocBufferID : ""); moduleDocBufferID ? moduleDocBufferID : "");
break; break;
case ModuleStatus::MissingDependency: { case serialization::Status::MissingDependency: {
// Figure out /which/ dependencies are missing. // Figure out /which/ dependencies are missing.
// FIXME: Dependencies should be de-duplicated at serialization time, // FIXME: Dependencies should be de-duplicated at serialization time,
// not now. // not now.
@@ -255,7 +255,7 @@ FileUnit *SerializedModuleLoader::loadAST(
break; break;
} }
case ModuleStatus::MissingShadowedModule: { case serialization::Status::MissingShadowedModule: {
Ctx.Diags.diagnose(*diagLoc, diag::serialization_missing_shadowed_module, Ctx.Diags.diagnose(*diagLoc, diag::serialization_missing_shadowed_module,
M.Name); M.Name);
if (Ctx.SearchPathOpts.SDKPath.empty()) { if (Ctx.SearchPathOpts.SDKPath.empty()) {
@@ -265,7 +265,7 @@ FileUnit *SerializedModuleLoader::loadAST(
break; break;
} }
case ModuleStatus::NameMismatch: { case serialization::Status::NameMismatch: {
// FIXME: This doesn't handle a non-debugger REPL, which should also treat // FIXME: This doesn't handle a non-debugger REPL, which should also treat
// this as a non-fatal error. // this as a non-fatal error.
auto diagKind = diag::serialization_name_mismatch; auto diagKind = diag::serialization_name_mismatch;
@@ -276,7 +276,7 @@ FileUnit *SerializedModuleLoader::loadAST(
break; break;
} }
case ModuleStatus::TargetIncompatible: { case serialization::Status::TargetIncompatible: {
// FIXME: This doesn't handle a non-debugger REPL, which should also treat // FIXME: This doesn't handle a non-debugger REPL, which should also treat
// this as a non-fatal error. // this as a non-fatal error.
auto diagKind = diag::serialization_target_incompatible; auto diagKind = diag::serialization_target_incompatible;
@@ -287,7 +287,7 @@ FileUnit *SerializedModuleLoader::loadAST(
break; break;
} }
case ModuleStatus::TargetTooNew: { case serialization::Status::TargetTooNew: {
StringRef moduleTargetTriple = loadedModuleFile->getTargetTriple(); StringRef moduleTargetTriple = loadedModuleFile->getTargetTriple();
llvm::Triple moduleTarget(llvm::Triple::normalize(moduleTargetTriple)); llvm::Triple moduleTarget(llvm::Triple::normalize(moduleTargetTriple));
@@ -387,13 +387,6 @@ void SerializedModuleLoader::loadObjCMethods(
} }
} }
bool SerializedModuleLoader::isSerializedAST(StringRef data) {
using serialization::MODULE_SIGNATURE;
StringRef signatureStr(reinterpret_cast<const char *>(MODULE_SIGNATURE),
llvm::array_lengthof(MODULE_SIGNATURE));
return data.startswith(signatureStr);
}
void SerializedModuleLoader::verifyAllModules() { void SerializedModuleLoader::verifyAllModules() {
#ifndef NDEBUG #ifndef NDEBUG
for (const LoadedModulePair &loaded : LoadedModuleFiles) for (const LoadedModulePair &loaded : LoadedModuleFiles)

View File

@@ -11,9 +11,10 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#define DEBUG_TYPE "serialized-sil-loader" #define DEBUG_TYPE "serialized-sil-loader"
#include "swift/Serialization/SerializedSILLoader.h"
#include "DeserializeSIL.h" #include "DeserializeSIL.h"
#include "swift/Serialization/ModuleFile.h" #include "swift/Serialization/ModuleFile.h"
#include "swift/Serialization/SerializedSILLoader.h" #include "swift/Serialization/SerializedModuleLoader.h"
#include "swift/SIL/SILModule.h" #include "swift/SIL/SILModule.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
@@ -24,6 +25,7 @@ SerializedSILLoader::SerializedSILLoader(ASTContext &Ctx,
Callback *callback) { Callback *callback) {
// Get a list of SerializedModules from ASTContext. // Get a list of SerializedModules from ASTContext.
// FIXME: Iterating over LoadedModules is not a good way to do this.
for (auto &Entry : Ctx.LoadedModules) { for (auto &Entry : Ctx.LoadedModules) {
for (auto File : Entry.second->getFiles()) { for (auto File : Entry.second->getFiles()) {
if (auto LoadedAST = dyn_cast<SerializedASTFile>(File)) { if (auto LoadedAST = dyn_cast<SerializedASTFile>(File)) {

View File

@@ -19,6 +19,7 @@
#include "swift/ASTSectionImporter/ASTSectionImporter.h" #include "swift/ASTSectionImporter/ASTSectionImporter.h"
#include "swift/Frontend/Frontend.h" #include "swift/Frontend/Frontend.h"
#include "swift/Serialization/SerializedModuleLoader.h" #include "swift/Serialization/SerializedModuleLoader.h"
#include "swift/Serialization/Validation.h"
#include "swift/Basic/Dwarf.h" #include "swift/Basic/Dwarf.h"
#include "llvm/Object/MachO.h" #include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h" #include "llvm/Object/ObjectFile.h"
@@ -59,19 +60,18 @@ void anchorForGetMainExecutable() {}
using namespace llvm::MachO; using namespace llvm::MachO;
static void printValidationInfo(llvm::StringRef data) { static void printValidationInfo(llvm::StringRef data) {
swift::SerializedModuleLoader::ExtendedValidationInfo extendedInfo; swift::serialization::ExtendedValidationInfo extendedInfo;
swift::SerializedModuleLoader::ValidationInfo info = swift::serialization::ValidationInfo info =
swift::SerializedModuleLoader::validateSerializedAST(data, swift::serialization::validateSerializedAST(data, &extendedInfo);
&extendedInfo); if (info.status != swift::serialization::Status::Valid)
if (info.status != swift::ModuleStatus::Valid)
return; return;
llvm::outs() << "- Target: " << info.targetTriple << "\n"; llvm::outs() << "- Target: " << info.targetTriple << "\n";
if (!extendedInfo.getSDKPath().empty()) if (!extendedInfo.getSDKPath().empty())
llvm::outs() << "- SDK path: " << extendedInfo.getSDKPath() << "\n"; llvm::outs() << "- SDK path: " << extendedInfo.getSDKPath() << "\n";
if (!extendedInfo.getClangImporterOptions().empty()) { if (!extendedInfo.getExtraClangImporterOptions().empty()) {
llvm::outs() << "- -Xcc options:"; llvm::outs() << "- -Xcc options:";
for (llvm::StringRef option : extendedInfo.getClangImporterOptions()) for (llvm::StringRef option : extendedInfo.getExtraClangImporterOptions())
llvm::outs() << " " << option; llvm::outs() << " " << option;
llvm::outs() << "\n"; llvm::outs() << "\n";
} }

View File

@@ -162,7 +162,7 @@ int main(int argc, char **argv) {
// name of the module to the file's name. // name of the module to the file's name.
Invocation.addInputBuffer(FileBufOrErr.get().get()); Invocation.addInputBuffer(FileBufOrErr.get().get());
bool IsModule = false; bool IsModule = false;
if (SerializedModuleLoader::isSerializedAST(FileBufOrErr.get()->getBuffer())){ if (serialization::isSerializedAST(FileBufOrErr.get()->getBuffer())) {
IsModule = true; IsModule = true;
const StringRef Stem = ModuleName.size() ? const StringRef Stem = ModuleName.size() ?
StringRef(ModuleName) : StringRef(ModuleName) :

View File

@@ -372,7 +372,7 @@ int main(int argc, char **argv) {
// name of the module to the file's name. // name of the module to the file's name.
Invocation.addInputBuffer(FileBufOrErr.get().get()); Invocation.addInputBuffer(FileBufOrErr.get().get());
bool IsModule = false; bool IsModule = false;
if (SerializedModuleLoader::isSerializedAST(FileBufOrErr.get()->getBuffer())){ if (serialization::isSerializedAST(FileBufOrErr.get()->getBuffer())) {
IsModule = true; IsModule = true;
const StringRef Stem = ModuleName.size() ? const StringRef Stem = ModuleName.size() ?
StringRef(ModuleName) : StringRef(ModuleName) :