mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[serialization] Sprinkle PrettyStackTrace throughout deserialization code.
Since we don't have soft-failure yet from deserialization, it's helpful to at least know where to start looking when something crashes. There are some rough edges here but it should be much better than nothing. This also pulls the list of record nodes out into a separate file, so that we can avoid repeating it. Example crash: 1. While reading from ./CTypes.swiftmodule 2. While deserializing 'CBool' (StructDecl) 3. While deserializing decl #26 (XREF) 4. Cross-reference to 'LogicValue' in swift (don't worry, this is an example where I'm tweaking things) <rdar://problem/14838332> Swift SVN r11057
This commit is contained in:
160
lib/Serialization/DeclTypeRecordNodes.def
Normal file
160
lib/Serialization/DeclTypeRecordNodes.def
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
//===-- DeclTypeRecordNodes.def - Serialization Metaprogramming -*- 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
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
/// \file
|
||||||
|
/// \brief Defines macros used for metaprogramming with the serialized records
|
||||||
|
/// in the "decls-and-types" block of serialized ASTs.
|
||||||
|
///
|
||||||
|
/// You should define one of the following sets of macros:
|
||||||
|
/// - RECORD(Id)
|
||||||
|
/// - RECORD(Id) and RECORD_VAL(Id)
|
||||||
|
/// - Any of TYPE(Id), DECL(Id), PATTERN(Id)
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef RECORD
|
||||||
|
#define RECORD(Id)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RECORD_VAL
|
||||||
|
#define DECLTYPERECORDNODES_HAS_RECORD_VAL 1
|
||||||
|
#else
|
||||||
|
#define DECLTYPERECORDNODES_HAS_RECORD_VAL 0
|
||||||
|
#define RECORD_VAL(Id, Value) RECORD(Id)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TYPE
|
||||||
|
#define TYPE(Id) RECORD(Id##_TYPE)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FIRST_TYPE
|
||||||
|
# if DECLTYPERECORDNODES_HAS_RECORD_VAL
|
||||||
|
# define FIRST_TYPE(Id, Value) RECORD_VAL(Id##_TYPE, Value)
|
||||||
|
# else
|
||||||
|
# define FIRST_TYPE(Id, Value) TYPE(Id)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DECL
|
||||||
|
#define DECL(Id) RECORD(Id##_DECL)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FIRST_DECL
|
||||||
|
# if DECLTYPERECORDNODES_HAS_RECORD_VAL
|
||||||
|
# define FIRST_DECL(Id, Value) RECORD_VAL(Id##_DECL, Value)
|
||||||
|
# else
|
||||||
|
# define FIRST_DECL(Id, Value) DECL(Id)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PATTERN
|
||||||
|
#define PATTERN(Id) RECORD(Id##_PATTERN)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FIRST_PATTERN
|
||||||
|
# if DECLTYPERECORDNODES_HAS_RECORD_VAL
|
||||||
|
# define FIRST_PATTERN(Id, Value) RECORD_VAL(Id##_PATTERN, Value)
|
||||||
|
# else
|
||||||
|
# define FIRST_PATTERN(Id, Value) PATTERN(Id)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TRAILING_INFO
|
||||||
|
#define TRAILING_INFO(Id) RECORD(Id)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef OTHER
|
||||||
|
#define OTHER(Id, Value) RECORD_VAL(Id, Value)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// These IDs must \em not be renumbered or reordered without incrementing
|
||||||
|
// VERSION_MAJOR in ModuleFormat.h. Names, however, may change.
|
||||||
|
FIRST_TYPE(NAME_ALIAS, 1)
|
||||||
|
TYPE(GENERIC_TYPE_PARAM)
|
||||||
|
TYPE(ASSOCIATED_TYPE) // This is correct! ASSOCIATED_TYPE_TYPE
|
||||||
|
TYPE(DEPENDENT_MEMBER)
|
||||||
|
TYPE(NOMINAL)
|
||||||
|
TYPE(PAREN)
|
||||||
|
TYPE(TUPLE)
|
||||||
|
TRAILING_INFO(TUPLE_TYPE_ELT)
|
||||||
|
TYPE(FUNCTION)
|
||||||
|
TYPE(METATYPE)
|
||||||
|
TYPE(LVALUE)
|
||||||
|
TYPE(ARCHETYPE)
|
||||||
|
TRAILING_INFO(ARCHETYPE_NESTED_TYPE_NAMES)
|
||||||
|
TRAILING_INFO(ARCHETYPE_NESTED_TYPES)
|
||||||
|
TYPE(PROTOCOL_COMPOSITION)
|
||||||
|
TYPE(SUBSTITUTED)
|
||||||
|
TYPE(BOUND_GENERIC)
|
||||||
|
TRAILING_INFO(BOUND_GENERIC_SUBSTITUTION)
|
||||||
|
TYPE(POLYMORPHIC_FUNCTION)
|
||||||
|
TYPE(GENERIC_FUNCTION)
|
||||||
|
TYPE(ARRAY_SLICE)
|
||||||
|
TYPE(ARRAY)
|
||||||
|
TYPE(REFERENCE_STORAGE)
|
||||||
|
TYPE(UNBOUND_GENERIC)
|
||||||
|
TYPE(OPTIONAL)
|
||||||
|
TYPE(SIL_FUNCTION)
|
||||||
|
|
||||||
|
FIRST_DECL(TYPE_ALIAS, 100)
|
||||||
|
DECL(GENERIC_TYPE_PARAM)
|
||||||
|
DECL(ASSOCIATED_TYPE)
|
||||||
|
DECL(STRUCT)
|
||||||
|
DECL(CONSTRUCTOR)
|
||||||
|
DECL(VAR)
|
||||||
|
DECL(FUNC)
|
||||||
|
DECL(PATTERN_BINDING)
|
||||||
|
DECL(PROTOCOL)
|
||||||
|
DECL(PREFIX_OPERATOR)
|
||||||
|
DECL(POSTFIX_OPERATOR)
|
||||||
|
DECL(INFIX_OPERATOR)
|
||||||
|
DECL(CLASS)
|
||||||
|
DECL(ENUM)
|
||||||
|
DECL(ENUM_ELEMENT)
|
||||||
|
DECL(SUBSCRIPT)
|
||||||
|
DECL(EXTENSION)
|
||||||
|
DECL(DESTRUCTOR)
|
||||||
|
|
||||||
|
FIRST_PATTERN(PAREN, 200)
|
||||||
|
PATTERN(TUPLE)
|
||||||
|
TRAILING_INFO(TUPLE_PATTERN_ELT)
|
||||||
|
PATTERN(NAMED)
|
||||||
|
PATTERN(ANY)
|
||||||
|
PATTERN(TYPED)
|
||||||
|
PATTERN(ISA)
|
||||||
|
PATTERN(NOMINAL_TYPE)
|
||||||
|
TRAILING_INFO(NOMINAL_TYPE_PATTERN_ELT)
|
||||||
|
PATTERN(VAR)
|
||||||
|
|
||||||
|
OTHER(GENERIC_PARAM_LIST, 240)
|
||||||
|
TRAILING_INFO(GENERIC_PARAM)
|
||||||
|
TRAILING_INFO(GENERIC_REQUIREMENT)
|
||||||
|
TRAILING_INFO(LAST_GENERIC_REQUIREMENT)
|
||||||
|
|
||||||
|
OTHER(NO_CONFORMANCE, 250)
|
||||||
|
OTHER(NORMAL_PROTOCOL_CONFORMANCE, 251)
|
||||||
|
OTHER(SPECIALIZED_PROTOCOL_CONFORMANCE, 252)
|
||||||
|
OTHER(INHERITED_PROTOCOL_CONFORMANCE, 253)
|
||||||
|
OTHER(DECL_CONTEXT, 254)
|
||||||
|
OTHER(XREF, 255)
|
||||||
|
|
||||||
|
#undef RECORD
|
||||||
|
#undef DECLTYPERECORDNODES_HAS_RECORD_VAL
|
||||||
|
#undef RECORD_VAL
|
||||||
|
#undef TYPE
|
||||||
|
#undef FIRST_TYPE
|
||||||
|
#undef DECL
|
||||||
|
#undef FIRST_DECL
|
||||||
|
#undef PATTERN
|
||||||
|
#undef FIRST_PATTERN
|
||||||
|
#undef TRAILING_INFO
|
||||||
|
#undef OTHER
|
||||||
@@ -13,7 +13,9 @@
|
|||||||
#include "ModuleFile.h"
|
#include "ModuleFile.h"
|
||||||
#include "ModuleFormat.h"
|
#include "ModuleFormat.h"
|
||||||
#include "swift/AST/AST.h"
|
#include "swift/AST/AST.h"
|
||||||
|
#include "swift/AST/PrettyStackTrace.h"
|
||||||
#include "swift/Serialization/BCReadingExtras.h"
|
#include "swift/Serialization/BCReadingExtras.h"
|
||||||
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
|
||||||
using namespace swift;
|
using namespace swift;
|
||||||
using namespace swift::serialization;
|
using namespace swift::serialization;
|
||||||
@@ -21,6 +23,77 @@ using namespace swift::serialization;
|
|||||||
using ConformancePair = std::pair<ProtocolDecl *, ProtocolConformance *>;
|
using ConformancePair = std::pair<ProtocolDecl *, ProtocolConformance *>;
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
class PrettyDeclDeserialization : public llvm::PrettyStackTraceEntry {
|
||||||
|
const ModuleFile::Serialized<Decl*> &DeclOrOffset;
|
||||||
|
DeclID ID;
|
||||||
|
decls_block::RecordKind Kind;
|
||||||
|
public:
|
||||||
|
PrettyDeclDeserialization(const ModuleFile::Serialized<Decl*> &declOrOffset,
|
||||||
|
DeclID DID, decls_block::RecordKind kind)
|
||||||
|
: DeclOrOffset(declOrOffset), ID(DID), Kind(kind) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *getRecordKindString(decls_block::RecordKind Kind) {
|
||||||
|
switch (Kind) {
|
||||||
|
#define RECORD(Id) case decls_block::Id: return #Id;
|
||||||
|
#include "DeclTypeRecordNodes.def"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void print(raw_ostream &os) const override {
|
||||||
|
if (!DeclOrOffset.isComplete()) {
|
||||||
|
os << "While deserializing decl #" << ID << " ("
|
||||||
|
<< getRecordKindString(Kind) << ")\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
os << "While deserializing ";
|
||||||
|
if (auto VD = dyn_cast<ValueDecl>(DeclOrOffset.get())) {
|
||||||
|
os << "'" << VD->getName() << "' ("
|
||||||
|
<< Decl::getKindName(VD->getKind()) << "Decl) \n";
|
||||||
|
} else {
|
||||||
|
os << Decl::getKindName(DeclOrOffset.get()->getKind())
|
||||||
|
<< "Decl #" << ID << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class PrettyXRefDeserialization : public llvm::PrettyStackTraceEntry {
|
||||||
|
ModuleFile &File;
|
||||||
|
XRefKind Kind;
|
||||||
|
Module &ContainingModule;
|
||||||
|
ArrayRef<uint64_t> RawPath;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PrettyXRefDeserialization(ModuleFile &file, XRefKind kind, Module &M,
|
||||||
|
ArrayRef<uint64_t> rawPath)
|
||||||
|
: File(file), Kind(kind), ContainingModule(M), RawPath(rawPath) {}
|
||||||
|
|
||||||
|
virtual void print(raw_ostream &os) const override {
|
||||||
|
auto NamePath = RawPath;
|
||||||
|
|
||||||
|
os << "Cross-reference to ";
|
||||||
|
switch (Kind) {
|
||||||
|
case XRefKind::SwiftValue:
|
||||||
|
case XRefKind::SwiftOperator:
|
||||||
|
break;
|
||||||
|
case XRefKind::SwiftGenericParameter:
|
||||||
|
os << "generic param " << RawPath.back() << " of ";
|
||||||
|
NamePath = RawPath.slice(0, RawPath.size()-1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
os << "'";
|
||||||
|
interleave(NamePath,
|
||||||
|
[&](IdentifierID IID) { os << File.getIdentifier(IID); },
|
||||||
|
[&]() { os << "."; });
|
||||||
|
os << "' in " << ContainingModule.Name << "\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // end anonymous namespace
|
||||||
|
|
||||||
|
|
||||||
/// Translate from the serialization DefaultArgumentKind enumerators, which are
|
/// Translate from the serialization DefaultArgumentKind enumerators, which are
|
||||||
/// guaranteed to be stable, to the AST ones.
|
/// guaranteed to be stable, to the AST ones.
|
||||||
static Optional<swift::DefaultArgumentKind>
|
static Optional<swift::DefaultArgumentKind>
|
||||||
@@ -783,6 +856,9 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext,
|
|||||||
StringRef blobData;
|
StringRef blobData;
|
||||||
unsigned recordID = DeclTypeCursor.readRecord(entry.ID, scratch, &blobData);
|
unsigned recordID = DeclTypeCursor.readRecord(entry.ID, scratch, &blobData);
|
||||||
|
|
||||||
|
PrettyDeclDeserialization stackTraceEntry(
|
||||||
|
declOrOffset, DID, static_cast<decls_block::RecordKind>(recordID));
|
||||||
|
|
||||||
switch (recordID) {
|
switch (recordID) {
|
||||||
case decls_block::TYPE_ALIAS_DECL: {
|
case decls_block::TYPE_ALIAS_DECL: {
|
||||||
IdentifierID nameID;
|
IdentifierID nameID;
|
||||||
@@ -1626,6 +1702,9 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext,
|
|||||||
assert(M && "missing dependency");
|
assert(M && "missing dependency");
|
||||||
rawAccessPath = rawAccessPath.slice(1);
|
rawAccessPath = rawAccessPath.slice(1);
|
||||||
|
|
||||||
|
PrettyXRefDeserialization moreStackInfo(*this, static_cast<XRefKind>(kind),
|
||||||
|
*M, rawAccessPath);
|
||||||
|
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case XRefKind::SwiftValue:
|
case XRefKind::SwiftValue:
|
||||||
case XRefKind::SwiftGenericParameter: {
|
case XRefKind::SwiftGenericParameter: {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "llvm/ADT/StringExtras.h"
|
#include "llvm/ADT/StringExtras.h"
|
||||||
#include "llvm/Support/MemoryBuffer.h"
|
#include "llvm/Support/MemoryBuffer.h"
|
||||||
|
#include "llvm/Support/PrettyStackTrace.h"
|
||||||
|
|
||||||
using namespace swift;
|
using namespace swift;
|
||||||
using namespace swift::serialization;
|
using namespace swift::serialization;
|
||||||
@@ -72,6 +73,19 @@ validateControlBlock(llvm::BitstreamCursor &cursor,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
class PrettyModuleFileDeserialization : public llvm::PrettyStackTraceEntry {
|
||||||
|
const ModuleFile &File;
|
||||||
|
public:
|
||||||
|
explicit PrettyModuleFileDeserialization(const ModuleFile &file)
|
||||||
|
: File(file) {}
|
||||||
|
|
||||||
|
virtual void print(raw_ostream &os) const override {
|
||||||
|
os << "While reading from " << File.getModuleFilename() << "\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // end anonymous namespace
|
||||||
|
|
||||||
/// Used to deserialize entries in the on-disk decl hash table.
|
/// Used to deserialize entries in the on-disk decl hash table.
|
||||||
class ModuleFile::DeclTableInfo {
|
class ModuleFile::DeclTableInfo {
|
||||||
public:
|
public:
|
||||||
@@ -274,6 +288,8 @@ ModuleFile::ModuleFile(std::unique_ptr<llvm::MemoryBuffer> input)
|
|||||||
InputReader(reinterpret_cast<const uint8_t *>(InputFile->getBufferStart()),
|
InputReader(reinterpret_cast<const uint8_t *>(InputFile->getBufferStart()),
|
||||||
reinterpret_cast<const uint8_t *>(InputFile->getBufferEnd())),
|
reinterpret_cast<const uint8_t *>(InputFile->getBufferEnd())),
|
||||||
Status(ModuleStatus::Valid) {
|
Status(ModuleStatus::Valid) {
|
||||||
|
PrettyModuleFileDeserialization stackEntry(*this);
|
||||||
|
|
||||||
llvm::BitstreamCursor cursor{InputReader};
|
llvm::BitstreamCursor cursor{InputReader};
|
||||||
|
|
||||||
for (unsigned char byte : SIGNATURE) {
|
for (unsigned char byte : SIGNATURE) {
|
||||||
@@ -452,6 +468,8 @@ static NominalTypeDecl *getAnyNominal(Decl *D) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ModuleFile::associateWithFileContext(FileUnit *file) {
|
bool ModuleFile::associateWithFileContext(FileUnit *file) {
|
||||||
|
PrettyModuleFileDeserialization stackEntry(*this);
|
||||||
|
|
||||||
assert(Status == ModuleStatus::Valid && "invalid module file");
|
assert(Status == ModuleStatus::Valid && "invalid module file");
|
||||||
assert(!FileContext && "already associated with an AST module");
|
assert(!FileContext && "already associated with an AST module");
|
||||||
FileContext = file;
|
FileContext = file;
|
||||||
@@ -503,6 +521,8 @@ ModuleFile::~ModuleFile() = default;
|
|||||||
|
|
||||||
void ModuleFile::lookupValue(Identifier name,
|
void ModuleFile::lookupValue(Identifier name,
|
||||||
SmallVectorImpl<ValueDecl*> &results) {
|
SmallVectorImpl<ValueDecl*> &results) {
|
||||||
|
PrettyModuleFileDeserialization stackEntry(*this);
|
||||||
|
|
||||||
if (!TopLevelDecls)
|
if (!TopLevelDecls)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -521,6 +541,8 @@ void ModuleFile::lookupValue(Identifier name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
OperatorDecl *ModuleFile::lookupOperator(Identifier name, DeclKind fixity) {
|
OperatorDecl *ModuleFile::lookupOperator(Identifier name, DeclKind fixity) {
|
||||||
|
PrettyModuleFileDeserialization stackEntry(*this);
|
||||||
|
|
||||||
if (!OperatorDecls)
|
if (!OperatorDecls)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
@@ -541,6 +563,8 @@ OperatorDecl *ModuleFile::lookupOperator(Identifier name, DeclKind fixity) {
|
|||||||
void ModuleFile::getImportedModules(
|
void ModuleFile::getImportedModules(
|
||||||
SmallVectorImpl<Module::ImportedModule> &results,
|
SmallVectorImpl<Module::ImportedModule> &results,
|
||||||
bool includePrivate) {
|
bool includePrivate) {
|
||||||
|
PrettyModuleFileDeserialization stackEntry(*this);
|
||||||
|
|
||||||
for (auto &dep : Dependencies) {
|
for (auto &dep : Dependencies) {
|
||||||
if (!includePrivate && !dep.IsExported)
|
if (!includePrivate && !dep.IsExported)
|
||||||
continue;
|
continue;
|
||||||
@@ -552,6 +576,7 @@ void ModuleFile::getImportedModules(
|
|||||||
void ModuleFile::lookupVisibleDecls(Module::AccessPathTy accessPath,
|
void ModuleFile::lookupVisibleDecls(Module::AccessPathTy accessPath,
|
||||||
VisibleDeclConsumer &consumer,
|
VisibleDeclConsumer &consumer,
|
||||||
NLKind lookupKind) {
|
NLKind lookupKind) {
|
||||||
|
PrettyModuleFileDeserialization stackEntry(*this);
|
||||||
assert(accessPath.size() <= 1 && "can only refer to top-level decls");
|
assert(accessPath.size() <= 1 && "can only refer to top-level decls");
|
||||||
|
|
||||||
if (!TopLevelDecls)
|
if (!TopLevelDecls)
|
||||||
@@ -576,6 +601,7 @@ void ModuleFile::lookupVisibleDecls(Module::AccessPathTy accessPath,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ModuleFile::loadExtensions(NominalTypeDecl *nominal) {
|
void ModuleFile::loadExtensions(NominalTypeDecl *nominal) {
|
||||||
|
PrettyModuleFileDeserialization stackEntry(*this);
|
||||||
if (!ExtensionDecls)
|
if (!ExtensionDecls)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -590,6 +616,8 @@ void ModuleFile::loadExtensions(NominalTypeDecl *nominal) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ModuleFile::loadDeclsConformingTo(KnownProtocolKind kind) {
|
void ModuleFile::loadDeclsConformingTo(KnownProtocolKind kind) {
|
||||||
|
PrettyModuleFileDeserialization stackEntry(*this);
|
||||||
|
|
||||||
auto index = static_cast<unsigned>(kind);
|
auto index = static_cast<unsigned>(kind);
|
||||||
for (DeclID DID : KnownProtocolAdopters[index]) {
|
for (DeclID DID : KnownProtocolAdopters[index]) {
|
||||||
Decl *D = getDecl(DID);
|
Decl *D = getDecl(DID);
|
||||||
@@ -602,6 +630,7 @@ void ModuleFile::loadDeclsConformingTo(KnownProtocolKind kind) {
|
|||||||
void ModuleFile::lookupClassMember(Module::AccessPathTy accessPath,
|
void ModuleFile::lookupClassMember(Module::AccessPathTy accessPath,
|
||||||
Identifier name,
|
Identifier name,
|
||||||
SmallVectorImpl<ValueDecl*> &results) {
|
SmallVectorImpl<ValueDecl*> &results) {
|
||||||
|
PrettyModuleFileDeserialization stackEntry(*this);
|
||||||
assert(accessPath.size() <= 1 && "can only refer to top-level decls");
|
assert(accessPath.size() <= 1 && "can only refer to top-level decls");
|
||||||
|
|
||||||
if (!ClassMembersByName)
|
if (!ClassMembersByName)
|
||||||
@@ -632,6 +661,7 @@ void ModuleFile::lookupClassMember(Module::AccessPathTy accessPath,
|
|||||||
|
|
||||||
void ModuleFile::lookupClassMembers(Module::AccessPathTy accessPath,
|
void ModuleFile::lookupClassMembers(Module::AccessPathTy accessPath,
|
||||||
VisibleDeclConsumer &consumer) {
|
VisibleDeclConsumer &consumer) {
|
||||||
|
PrettyModuleFileDeserialization stackEntry(*this);
|
||||||
assert(accessPath.size() <= 1 && "can only refer to top-level decls");
|
assert(accessPath.size() <= 1 && "can only refer to top-level decls");
|
||||||
|
|
||||||
if (!ClassMembersByName)
|
if (!ClassMembersByName)
|
||||||
@@ -668,6 +698,7 @@ ModuleFile::collectLinkLibraries(Module::LinkLibraryCallback callback) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ModuleFile::getTopLevelDecls(SmallVectorImpl<Decl *> &results) {
|
void ModuleFile::getTopLevelDecls(SmallVectorImpl<Decl *> &results) {
|
||||||
|
PrettyModuleFileDeserialization stackEntry(*this);
|
||||||
if (OperatorDecls) {
|
if (OperatorDecls) {
|
||||||
for (auto entry : make_range(OperatorDecls->data_begin(),
|
for (auto entry : make_range(OperatorDecls->data_begin(),
|
||||||
OperatorDecls->data_end())) {
|
OperatorDecls->data_end())) {
|
||||||
@@ -697,5 +728,6 @@ void ModuleFile::getDisplayDecls(SmallVectorImpl<Decl *> &results) {
|
|||||||
if (ShadowedModule)
|
if (ShadowedModule)
|
||||||
ShadowedModule->getDisplayDecls(results);
|
ShadowedModule->getDisplayDecls(results);
|
||||||
|
|
||||||
|
PrettyModuleFileDeserialization stackEntry(*this);
|
||||||
getTopLevelDecls(results);
|
getTopLevelDecls(results);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -180,6 +180,8 @@ private:
|
|||||||
/// Convenience function for module loading.
|
/// Convenience function for module loading.
|
||||||
void error(ModuleStatus issue = ModuleStatus::Malformed) {
|
void error(ModuleStatus issue = ModuleStatus::Malformed) {
|
||||||
assert(issue != ModuleStatus::Valid);
|
assert(issue != ModuleStatus::Valid);
|
||||||
|
assert((!FileContext || issue != ModuleStatus::Malformed) &&
|
||||||
|
"error deserializing an individual record");
|
||||||
Status = issue;
|
Status = issue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,8 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
///
|
///
|
||||||
/// \file Contains various constants and helper types to deal with serialized
|
/// \file
|
||||||
|
/// \brief Contains various constants and helper types to deal with serialized
|
||||||
/// modules.
|
/// modules.
|
||||||
///
|
///
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@@ -303,75 +304,9 @@ namespace decls_block {
|
|||||||
// These IDs must \em not be renumbered or reordered without incrementing
|
// These IDs must \em not be renumbered or reordered without incrementing
|
||||||
// VERSION_MAJOR.
|
// VERSION_MAJOR.
|
||||||
enum RecordKind : uint8_t {
|
enum RecordKind : uint8_t {
|
||||||
NAME_ALIAS_TYPE = 1,
|
#define RECORD(Id) Id,
|
||||||
GENERIC_TYPE_PARAM_TYPE,
|
#define RECORD_VAL(Id, Value) Id = Value,
|
||||||
ASSOCIATED_TYPE_TYPE,
|
#include "DeclTypeRecordNodes.def"
|
||||||
DEPENDENT_MEMBER_TYPE,
|
|
||||||
NOMINAL_TYPE,
|
|
||||||
PAREN_TYPE,
|
|
||||||
TUPLE_TYPE,
|
|
||||||
TUPLE_TYPE_ELT,
|
|
||||||
FUNCTION_TYPE,
|
|
||||||
METATYPE_TYPE,
|
|
||||||
LVALUE_TYPE,
|
|
||||||
ARCHETYPE_TYPE,
|
|
||||||
ARCHETYPE_NESTED_TYPE_NAMES,
|
|
||||||
ARCHETYPE_NESTED_TYPES,
|
|
||||||
PROTOCOL_COMPOSITION_TYPE,
|
|
||||||
SUBSTITUTED_TYPE,
|
|
||||||
BOUND_GENERIC_TYPE,
|
|
||||||
BOUND_GENERIC_SUBSTITUTION,
|
|
||||||
POLYMORPHIC_FUNCTION_TYPE,
|
|
||||||
GENERIC_FUNCTION_TYPE,
|
|
||||||
ARRAY_SLICE_TYPE,
|
|
||||||
ARRAY_TYPE,
|
|
||||||
REFERENCE_STORAGE_TYPE,
|
|
||||||
UNBOUND_GENERIC_TYPE,
|
|
||||||
OPTIONAL_TYPE,
|
|
||||||
SIL_FUNCTION_TYPE,
|
|
||||||
|
|
||||||
TYPE_ALIAS_DECL = 100,
|
|
||||||
GENERIC_TYPE_PARAM_DECL,
|
|
||||||
ASSOCIATED_TYPE_DECL,
|
|
||||||
STRUCT_DECL,
|
|
||||||
CONSTRUCTOR_DECL,
|
|
||||||
VAR_DECL,
|
|
||||||
FUNC_DECL,
|
|
||||||
PATTERN_BINDING_DECL,
|
|
||||||
PROTOCOL_DECL,
|
|
||||||
PREFIX_OPERATOR_DECL,
|
|
||||||
POSTFIX_OPERATOR_DECL,
|
|
||||||
INFIX_OPERATOR_DECL,
|
|
||||||
CLASS_DECL,
|
|
||||||
ENUM_DECL,
|
|
||||||
ENUM_ELEMENT_DECL,
|
|
||||||
SUBSCRIPT_DECL,
|
|
||||||
EXTENSION_DECL,
|
|
||||||
DESTRUCTOR_DECL,
|
|
||||||
KNOWN_PROTOCOL,
|
|
||||||
|
|
||||||
PAREN_PATTERN = 200,
|
|
||||||
TUPLE_PATTERN,
|
|
||||||
TUPLE_PATTERN_ELT,
|
|
||||||
NAMED_PATTERN,
|
|
||||||
ANY_PATTERN,
|
|
||||||
TYPED_PATTERN,
|
|
||||||
ISA_PATTERN,
|
|
||||||
NOMINAL_TYPE_PATTERN,
|
|
||||||
NOMINAL_TYPE_PATTERN_ELT,
|
|
||||||
VAR_PATTERN,
|
|
||||||
|
|
||||||
GENERIC_PARAM_LIST = 240,
|
|
||||||
GENERIC_PARAM,
|
|
||||||
GENERIC_REQUIREMENT,
|
|
||||||
LAST_GENERIC_REQUIREMENT,
|
|
||||||
|
|
||||||
NO_CONFORMANCE = 250,
|
|
||||||
NORMAL_PROTOCOL_CONFORMANCE = 251,
|
|
||||||
SPECIALIZED_PROTOCOL_CONFORMANCE = 252,
|
|
||||||
INHERITED_PROTOCOL_CONFORMANCE = 253,
|
|
||||||
DECL_CONTEXT = 254,
|
|
||||||
XREF = 255
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using NameAliasTypeLayout = BCRecordLayout<
|
using NameAliasTypeLayout = BCRecordLayout<
|
||||||
|
|||||||
@@ -230,124 +230,62 @@ void Serializer::writeBlockInfoBlock() {
|
|||||||
|
|
||||||
SmallVector<unsigned char, 64> nameBuffer;
|
SmallVector<unsigned char, 64> nameBuffer;
|
||||||
#define BLOCK(X) emitBlockID(Out, X ## _ID, #X, nameBuffer)
|
#define BLOCK(X) emitBlockID(Out, X ## _ID, #X, nameBuffer)
|
||||||
#define RECORD(K, X) emitRecordID(Out, K::X, #X, nameBuffer)
|
#define BLOCK_RECORD(K, X) emitRecordID(Out, K::X, #X, nameBuffer)
|
||||||
|
|
||||||
BLOCK(CONTROL_BLOCK);
|
BLOCK(CONTROL_BLOCK);
|
||||||
RECORD(control_block, METADATA);
|
BLOCK_RECORD(control_block, METADATA);
|
||||||
|
|
||||||
BLOCK(INPUT_BLOCK);
|
BLOCK(INPUT_BLOCK);
|
||||||
RECORD(input_block, SOURCE_FILE);
|
BLOCK_RECORD(input_block, SOURCE_FILE);
|
||||||
RECORD(input_block, IMPORTED_MODULE);
|
BLOCK_RECORD(input_block, IMPORTED_MODULE);
|
||||||
RECORD(input_block, LINK_LIBRARY);
|
BLOCK_RECORD(input_block, LINK_LIBRARY);
|
||||||
|
|
||||||
BLOCK(DECLS_AND_TYPES_BLOCK);
|
BLOCK(DECLS_AND_TYPES_BLOCK);
|
||||||
RECORD(decls_block, NAME_ALIAS_TYPE);
|
#define RECORD(X) BLOCK_RECORD(decls_block, X);
|
||||||
RECORD(decls_block, GENERIC_TYPE_PARAM_TYPE);
|
#include "DeclTypeRecordNodes.def"
|
||||||
RECORD(decls_block, ASSOCIATED_TYPE_TYPE);
|
|
||||||
RECORD(decls_block, DEPENDENT_MEMBER_TYPE);
|
|
||||||
RECORD(decls_block, NOMINAL_TYPE);
|
|
||||||
RECORD(decls_block, PAREN_TYPE);
|
|
||||||
RECORD(decls_block, TUPLE_TYPE);
|
|
||||||
RECORD(decls_block, TUPLE_TYPE_ELT);
|
|
||||||
RECORD(decls_block, FUNCTION_TYPE);
|
|
||||||
RECORD(decls_block, METATYPE_TYPE);
|
|
||||||
RECORD(decls_block, LVALUE_TYPE);
|
|
||||||
RECORD(decls_block, ARCHETYPE_TYPE);
|
|
||||||
RECORD(decls_block, ARCHETYPE_NESTED_TYPE_NAMES);
|
|
||||||
RECORD(decls_block, ARCHETYPE_NESTED_TYPES);
|
|
||||||
RECORD(decls_block, PROTOCOL_COMPOSITION_TYPE);
|
|
||||||
RECORD(decls_block, SUBSTITUTED_TYPE);
|
|
||||||
RECORD(decls_block, BOUND_GENERIC_TYPE);
|
|
||||||
RECORD(decls_block, BOUND_GENERIC_SUBSTITUTION);
|
|
||||||
RECORD(decls_block, POLYMORPHIC_FUNCTION_TYPE);
|
|
||||||
RECORD(decls_block, GENERIC_FUNCTION_TYPE);
|
|
||||||
RECORD(decls_block, ARRAY_SLICE_TYPE);
|
|
||||||
RECORD(decls_block, ARRAY_TYPE);
|
|
||||||
RECORD(decls_block, REFERENCE_STORAGE_TYPE);
|
|
||||||
RECORD(decls_block, UNBOUND_GENERIC_TYPE);
|
|
||||||
RECORD(decls_block, OPTIONAL_TYPE);
|
|
||||||
RECORD(decls_block, SIL_FUNCTION_TYPE);
|
|
||||||
|
|
||||||
RECORD(decls_block, TYPE_ALIAS_DECL);
|
|
||||||
RECORD(decls_block, GENERIC_TYPE_PARAM_DECL);
|
|
||||||
RECORD(decls_block, ASSOCIATED_TYPE_DECL);
|
|
||||||
RECORD(decls_block, STRUCT_DECL);
|
|
||||||
RECORD(decls_block, CONSTRUCTOR_DECL);
|
|
||||||
RECORD(decls_block, VAR_DECL);
|
|
||||||
RECORD(decls_block, FUNC_DECL);
|
|
||||||
RECORD(decls_block, PATTERN_BINDING_DECL);
|
|
||||||
RECORD(decls_block, PROTOCOL_DECL);
|
|
||||||
RECORD(decls_block, PREFIX_OPERATOR_DECL);
|
|
||||||
RECORD(decls_block, POSTFIX_OPERATOR_DECL);
|
|
||||||
RECORD(decls_block, INFIX_OPERATOR_DECL);
|
|
||||||
RECORD(decls_block, CLASS_DECL);
|
|
||||||
RECORD(decls_block, ENUM_DECL);
|
|
||||||
RECORD(decls_block, ENUM_ELEMENT_DECL);
|
|
||||||
RECORD(decls_block, SUBSCRIPT_DECL);
|
|
||||||
RECORD(decls_block, EXTENSION_DECL);
|
|
||||||
RECORD(decls_block, DESTRUCTOR_DECL);
|
|
||||||
|
|
||||||
RECORD(decls_block, PAREN_PATTERN);
|
|
||||||
RECORD(decls_block, TUPLE_PATTERN);
|
|
||||||
RECORD(decls_block, TUPLE_PATTERN_ELT);
|
|
||||||
RECORD(decls_block, NAMED_PATTERN);
|
|
||||||
RECORD(decls_block, ANY_PATTERN);
|
|
||||||
RECORD(decls_block, TYPED_PATTERN);
|
|
||||||
|
|
||||||
RECORD(decls_block, GENERIC_PARAM_LIST);
|
|
||||||
RECORD(decls_block, GENERIC_PARAM);
|
|
||||||
RECORD(decls_block, GENERIC_REQUIREMENT);
|
|
||||||
RECORD(decls_block, LAST_GENERIC_REQUIREMENT);
|
|
||||||
|
|
||||||
RECORD(decls_block, NO_CONFORMANCE);
|
|
||||||
RECORD(decls_block, NORMAL_PROTOCOL_CONFORMANCE);
|
|
||||||
RECORD(decls_block, SPECIALIZED_PROTOCOL_CONFORMANCE);
|
|
||||||
RECORD(decls_block, INHERITED_PROTOCOL_CONFORMANCE);
|
|
||||||
RECORD(decls_block, DECL_CONTEXT);
|
|
||||||
RECORD(decls_block, XREF);
|
|
||||||
|
|
||||||
BLOCK(IDENTIFIER_DATA_BLOCK);
|
BLOCK(IDENTIFIER_DATA_BLOCK);
|
||||||
RECORD(identifier_block, IDENTIFIER_DATA);
|
BLOCK_RECORD(identifier_block, IDENTIFIER_DATA);
|
||||||
|
|
||||||
BLOCK(INDEX_BLOCK);
|
BLOCK(INDEX_BLOCK);
|
||||||
RECORD(index_block, TYPE_OFFSETS);
|
BLOCK_RECORD(index_block, TYPE_OFFSETS);
|
||||||
RECORD(index_block, DECL_OFFSETS);
|
BLOCK_RECORD(index_block, DECL_OFFSETS);
|
||||||
RECORD(index_block, IDENTIFIER_OFFSETS);
|
BLOCK_RECORD(index_block, IDENTIFIER_OFFSETS);
|
||||||
RECORD(index_block, TOP_LEVEL_DECLS);
|
BLOCK_RECORD(index_block, TOP_LEVEL_DECLS);
|
||||||
RECORD(index_block, OPERATORS);
|
BLOCK_RECORD(index_block, OPERATORS);
|
||||||
RECORD(index_block, EXTENSIONS);
|
BLOCK_RECORD(index_block, EXTENSIONS);
|
||||||
RECORD(index_block, CLASS_MEMBERS);
|
BLOCK_RECORD(index_block, CLASS_MEMBERS);
|
||||||
|
|
||||||
BLOCK(SIL_BLOCK);
|
BLOCK(SIL_BLOCK);
|
||||||
RECORD(sil_block, SIL_FUNCTION);
|
BLOCK_RECORD(sil_block, SIL_FUNCTION);
|
||||||
RECORD(sil_block, SIL_BASIC_BLOCK);
|
BLOCK_RECORD(sil_block, SIL_BASIC_BLOCK);
|
||||||
RECORD(sil_block, SIL_ONE_VALUE_ONE_OPERAND);
|
BLOCK_RECORD(sil_block, SIL_ONE_VALUE_ONE_OPERAND);
|
||||||
RECORD(sil_block, SIL_ONE_TYPE);
|
BLOCK_RECORD(sil_block, SIL_ONE_TYPE);
|
||||||
RECORD(sil_block, SIL_ONE_OPERAND);
|
BLOCK_RECORD(sil_block, SIL_ONE_OPERAND);
|
||||||
RECORD(sil_block, SIL_ONE_TYPE_ONE_OPERAND);
|
BLOCK_RECORD(sil_block, SIL_ONE_TYPE_ONE_OPERAND);
|
||||||
RECORD(sil_block, SIL_ONE_TYPE_VALUES);
|
BLOCK_RECORD(sil_block, SIL_ONE_TYPE_VALUES);
|
||||||
RECORD(sil_block, SIL_TWO_OPERANDS);
|
BLOCK_RECORD(sil_block, SIL_TWO_OPERANDS);
|
||||||
RECORD(sil_block, SIL_INST_APPLY);
|
BLOCK_RECORD(sil_block, SIL_INST_APPLY);
|
||||||
RECORD(sil_block, SIL_INST_NO_OPERAND);
|
BLOCK_RECORD(sil_block, SIL_INST_NO_OPERAND);
|
||||||
RECORD(sil_block, SIL_VTABLE);
|
BLOCK_RECORD(sil_block, SIL_VTABLE);
|
||||||
RECORD(sil_block, SIL_VTABLE_ENTRY);
|
BLOCK_RECORD(sil_block, SIL_VTABLE_ENTRY);
|
||||||
RECORD(sil_block, SIL_GLOBALVAR);
|
BLOCK_RECORD(sil_block, SIL_GLOBALVAR);
|
||||||
|
|
||||||
BLOCK(SIL_INDEX_BLOCK);
|
BLOCK(SIL_INDEX_BLOCK);
|
||||||
RECORD(sil_index_block, SIL_FUNC_NAMES);
|
BLOCK_RECORD(sil_index_block, SIL_FUNC_NAMES);
|
||||||
RECORD(sil_index_block, SIL_FUNC_OFFSETS);
|
BLOCK_RECORD(sil_index_block, SIL_FUNC_OFFSETS);
|
||||||
RECORD(sil_index_block, SIL_VTABLE_NAMES);
|
BLOCK_RECORD(sil_index_block, SIL_VTABLE_NAMES);
|
||||||
RECORD(sil_index_block, SIL_VTABLE_OFFSETS);
|
BLOCK_RECORD(sil_index_block, SIL_VTABLE_OFFSETS);
|
||||||
RECORD(sil_index_block, SIL_GLOBALVAR_NAMES);
|
BLOCK_RECORD(sil_index_block, SIL_GLOBALVAR_NAMES);
|
||||||
RECORD(sil_index_block, SIL_GLOBALVAR_OFFSETS);
|
BLOCK_RECORD(sil_index_block, SIL_GLOBALVAR_OFFSETS);
|
||||||
|
|
||||||
BLOCK(KNOWN_PROTOCOL_BLOCK);
|
BLOCK(KNOWN_PROTOCOL_BLOCK);
|
||||||
#define PROTOCOL(Id) RECORD(index_block, Id);
|
#define PROTOCOL(Id) BLOCK_RECORD(index_block, Id);
|
||||||
#include "swift/AST/KnownProtocols.def"
|
#include "swift/AST/KnownProtocols.def"
|
||||||
RECORD(index_block, FORCE_DESERIALIZATION);
|
BLOCK_RECORD(index_block, FORCE_DESERIALIZATION);
|
||||||
|
|
||||||
#undef BLOCK
|
#undef BLOCK
|
||||||
#undef RECORD
|
#undef BLOCK_RECORD
|
||||||
}
|
}
|
||||||
|
|
||||||
void Serializer::writeHeader() {
|
void Serializer::writeHeader() {
|
||||||
|
|||||||
Reference in New Issue
Block a user