[serialization] Fix a recursive-dependency bug caught by previous commit.

Constructors have their "implicit this" VarDecl specified at creation, but
the context for said VarDecl is the constructor itself. Add a new flag to
allow the deserialization of a VarDecl without setting a DeclContext.

Swift SVN r5747
This commit is contained in:
Jordan Rose
2013-06-21 17:52:08 +00:00
parent 5e0d3f15fc
commit d6801fe0fd
2 changed files with 16 additions and 8 deletions

View File

@@ -203,7 +203,7 @@ DeclContext *ModuleFile::getDeclContext(DeclID DID) {
llvm_unreachable("unknown DeclContext kind");
}
Decl *ModuleFile::getDecl(DeclID DID) {
Decl *ModuleFile::getDecl(DeclID DID, DeclDeserializationOptions opts) {
if (DID == 0)
return nullptr;
@@ -346,7 +346,7 @@ Decl *ModuleFile::getDecl(DeclID DID) {
NominalTypeDecl *parent;
{
BCOffsetRAII restoreOffset(DeclTypeCursor);
thisDecl = cast<VarDecl>(getDecl(implicitThisID));
thisDecl = cast<VarDecl>(getDecl(implicitThisID, SkipContext));
parent = cast<NominalTypeDecl>(getDeclContext(parentID));
}
@@ -355,6 +355,7 @@ Decl *ModuleFile::getDecl(DeclID DID) {
thisDecl, /*generic params=*/nullptr,
parent);
declOrOffset = ctor;
thisDecl->setDeclContext(ctor);
Pattern *args = maybeReadPattern();
assert(args && "missing arguments for constructor");
@@ -379,8 +380,9 @@ Decl *ModuleFile::getDecl(DeclID DID) {
isNeverLValue, typeID, getterID,
setterID, overriddenID);
auto DC = (opts & SkipContext) ? nullptr : getDeclContext(contextID);
auto var = new (ctx) VarDecl(SourceLoc(), getIdentifier(nameID),
getType(typeID), nullptr);
getType(typeID), DC);
// Explicitly set the getter and setter info /before/ recording the VarDecl
// in the map. The functions will check this to know if they are getters or
@@ -394,10 +396,6 @@ Decl *ModuleFile::getDecl(DeclID DID) {
declOrOffset = var;
// Explicitly set the DeclContext /after/ recording the VarDecl in the map.
// Sometimes the context has to reference this decl.
var->setDeclContext(getDeclContext(contextID));
var->setNeverUsedAsLValue(isNeverLValue);
if (isImplicit)
var->setImplicit();