Serialization: Remove an old hack

SILFunctions no longer have a GenericParamList, so all of these
circularity and ordering problems are gone.

We *do* deserialize the generic parameters before creating decls
that have them though, so serialize generic parameters as if
their DeclContext was the DeclContext of the owner decl.

This is what we do when we parse generic parameters too; in
both cases, the constructor for the owner decl gives the
generic parameters the right DeclContext.
This commit is contained in:
Slava Pestov
2018-08-10 14:13:19 -07:00
parent 038a55757d
commit 6812fd63b8
4 changed files with 18 additions and 50 deletions

View File

@@ -506,8 +506,7 @@ private:
/// Main logic of getDeclChecked.
llvm::Expected<Decl *>
getDeclCheckedImpl(serialization::DeclID DID,
Optional<DeclContext *> ForcedContext = None);
getDeclCheckedImpl(serialization::DeclID DID);
/// Reads the index block, which contains global tables.
///
@@ -796,23 +795,15 @@ public:
/// Returns the decl with the given ID, deserializing it if needed.
///
/// \param DID The ID for the decl within this module.
/// \param ForcedContext Optional override for the decl context of certain
/// kinds of decls, used to avoid re-entrant
/// deserialization.
///
/// \sa getDeclChecked
Decl *getDecl(serialization::DeclID DID,
Optional<DeclContext *> ForcedContext = None);
Decl *getDecl(serialization::DeclID DID);
/// Returns the decl with the given ID, deserializing it if needed.
///
/// \param DID The ID for the decl within this module.
/// \param ForcedContext Optional override for the decl context of certain
/// kinds of decls, used to avoid re-entrant
/// deserialization.
llvm::Expected<Decl *>
getDeclChecked(serialization::DeclID DID,
Optional<DeclContext *> ForcedContext = None);
getDeclChecked(serialization::DeclID DID);
/// Returns the decl context with the given ID, deserializing it if needed.
DeclContext *getDeclContext(serialization::DeclContextID DID);

View File

@@ -55,7 +55,7 @@ const uint16_t VERSION_MAJOR = 0;
/// describe what change you made. The content of this comment isn't important;
/// it just ensures a conflict if two people change the module format.
/// Don't worry about adhering to the 80-column limit for this line.
const uint16_t VERSION_MINOR = 432; // Last change: default argument text
const uint16_t VERSION_MINOR = 433; // Last change: GenericTypeParamDecl doesn't need a DC
using DeclIDField = BCFixed<31>;
@@ -871,7 +871,6 @@ namespace decls_block {
using GenericTypeParamDeclLayout = BCRecordLayout<
GENERIC_TYPE_PARAM_DECL,
IdentifierIDField, // name
DeclContextIDField, // context decl
BCFixed<1>, // implicit flag
BCVBR<4>, // depth
BCVBR<4> // index

View File

@@ -669,22 +669,7 @@ GenericParamList *ModuleFile::maybeReadGenericParams(DeclContext *DC,
case GENERIC_PARAM: {
DeclID paramDeclID;
GenericParamLayout::readRecord(scratch, paramDeclID);
auto genericParam = cast<GenericTypeParamDecl>(getDecl(paramDeclID, DC));
// FIXME: There are unfortunate inconsistencies in the treatment of
// generic param decls. Currently the first request for context wins
// because we don't want to change context on-the-fly.
// Here are typical scenarios:
// (1) AST reads decl, get's scope.
// Later, readSILFunction tries to force module scope.
// (2) readSILFunction forces module scope.
// Later, readVTable requests an enclosing scope.
// ...other combinations are possible, but as long as AST lookups
// precede SIL linkage, we should be ok.
assert((genericParam->getDeclContext()->isModuleScopeContext() ||
DC->isModuleScopeContext() ||
genericParam->getDeclContext() == DC ||
genericParam->getDeclContext()->isChildContextOf(DC)) &&
"Mismatched decl context for generic types.");
auto genericParam = cast<GenericTypeParamDecl>(getDecl(paramDeclID));
params.push_back(genericParam);
break;
}
@@ -2194,8 +2179,8 @@ static uint64_t encodeLazyConformanceContextData(uint64_t numProtocols,
return (numProtocols << 48) | bitPosition;
}
Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
Expected<Decl *> deserialized = getDeclChecked(DID, ForcedContext);
Decl *ModuleFile::getDecl(DeclID DID) {
Expected<Decl *> deserialized = getDeclChecked(DID);
if (!deserialized) {
fatal(deserialized.takeError());
}
@@ -2203,9 +2188,9 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
}
Expected<Decl *>
ModuleFile::getDeclChecked(DeclID DID, Optional<DeclContext *> ForcedContext) {
ModuleFile::getDeclChecked(DeclID DID) {
// Tag every deserialized ValueDecl coming out of getDeclChecked with its ID.
Expected<Decl *> deserialized = getDeclCheckedImpl(DID, ForcedContext);
Expected<Decl *> deserialized = getDeclCheckedImpl(DID);
if (deserialized && deserialized.get()) {
if (auto *IDC = dyn_cast<IterableDeclContext>(deserialized.get())) {
// Only set the DeclID on the returned Decl if it's one that was loaded
@@ -2220,7 +2205,7 @@ ModuleFile::getDeclChecked(DeclID DID, Optional<DeclContext *> ForcedContext) {
}
Expected<Decl *>
ModuleFile::getDeclCheckedImpl(DeclID DID, Optional<DeclContext *> ForcedContext) {
ModuleFile::getDeclCheckedImpl(DeclID DID) {
if (DID == 0)
return nullptr;
@@ -2572,7 +2557,7 @@ ModuleFile::getDeclCheckedImpl(DeclID DID, Optional<DeclContext *> ForcedContext
}
}
auto DC = ForcedContext ? *ForcedContext : getDeclContext(contextID);
auto DC = getDeclContext(contextID);
auto genericParams = maybeReadGenericParams(DC);
if (declOrOffset.isComplete())
@@ -2601,22 +2586,18 @@ ModuleFile::getDeclCheckedImpl(DeclID DID, Optional<DeclContext *> ForcedContext
case decls_block::GENERIC_TYPE_PARAM_DECL: {
IdentifierID nameID;
DeclContextID contextID;
bool isImplicit;
unsigned depth;
unsigned index;
decls_block::GenericTypeParamDeclLayout::readRecord(scratch, nameID,
contextID,
isImplicit,
depth,
index);
auto DC = ForcedContext ? *ForcedContext : getDeclContext(contextID);
if (declOrOffset.isComplete())
return declOrOffset;
// Always create GenericTypeParamDecls in the associated module;
// maybeReadGenericParams() will reparent them.
auto DC = getAssociatedModule();
auto genericParam = createDecl<GenericTypeParamDecl>(DC,
getIdentifier(nameID),
SourceLoc(),
@@ -2643,7 +2624,7 @@ ModuleFile::getDeclCheckedImpl(DeclID DID, Optional<DeclContext *> ForcedContext
isImplicit,
rawOverriddenIDs);
auto DC = ForcedContext ? *ForcedContext : getDeclContext(contextID);
auto DC = getDeclContext(contextID);
if (declOrOffset.isComplete())
return declOrOffset;
@@ -2939,7 +2920,7 @@ ModuleFile::getDeclCheckedImpl(DeclID DID, Optional<DeclContext *> ForcedContext
}
}
auto DC = ForcedContext ? *ForcedContext : getDeclContext(contextID);
auto DC = getDeclContext(contextID);
if (declOrOffset.isComplete())
return declOrOffset;
@@ -3008,7 +2989,7 @@ ModuleFile::getDeclCheckedImpl(DeclID DID, Optional<DeclContext *> ForcedContext
interfaceTypeID, isVariadic,
rawDefaultArg);
auto DC = ForcedContext ? *ForcedContext : getDeclContext(contextID);
auto DC = getDeclContext(contextID);
if (declOrOffset.isComplete())
return declOrOffset;

View File

@@ -2918,12 +2918,9 @@ void Serializer::writeDecl(const Decl *D) {
auto genericParam = cast<GenericTypeParamDecl>(D);
verifyAttrSerializable(genericParam);
auto contextID = addDeclContextRef(genericParam->getDeclContext());
unsigned abbrCode = DeclTypeAbbrCodes[GenericTypeParamDeclLayout::Code];
GenericTypeParamDeclLayout::emitRecord(Out, ScratchRecord, abbrCode,
addDeclBaseNameRef(genericParam->getName()),
contextID,
genericParam->isImplicit(),
genericParam->getDepth(),
genericParam->getIndex());