Lift nested type lookup fast-pathing up to FileUnit.

We use this to avoid circularity issues in serialization; we'd like to
extend that to the Clang importer. This is only necessary because we
can't look up a single member at a time, but it can still fix issues
in the short term.

This commit should have no effect on functionality.
This commit is contained in:
Jordan Rose
2017-07-13 14:07:00 -07:00
parent 88aa00e7de
commit 03e1e3b6e0
6 changed files with 33 additions and 19 deletions

View File

@@ -555,6 +555,18 @@ public:
return nullptr;
}
/// Directly look for a nested type declared within this module inside the
/// given nominal type (including any extensions).
///
/// This is a fast-path hack to avoid circular dependencies in deserialization
/// and the Clang importer.
///
/// Private and fileprivate types should not be returned by this lookup.
virtual TypeDecl *lookupNestedType(Identifier name,
const NominalTypeDecl *parent) const {
return nullptr;
}
/// Find ValueDecls in the module and pass them to the given consumer object.
///
/// This does a simple local lookup, not recursively looking through imports.

View File

@@ -603,7 +603,7 @@ public:
/// Searches the module's nested type decls table for the given member of
/// the given type.
TypeDecl *lookupNestedType(Identifier name, const ValueDecl *parent);
TypeDecl *lookupNestedType(Identifier name, const NominalTypeDecl *parent);
/// Searches the module's operators for one with the given name and fixity.
///

View File

@@ -132,6 +132,10 @@ public:
virtual TypeDecl *lookupLocalType(StringRef MangledName) const override;
virtual TypeDecl *
lookupNestedType(Identifier name,
const NominalTypeDecl *parent) const override;
virtual OperatorDecl *lookupOperator(Identifier name,
DeclKind fixity) const override;

View File

@@ -1319,9 +1319,7 @@ ModuleFile::resolveCrossReference(ModuleDecl *baseModule, uint32_t pathLen) {
&blobData);
switch (recordID) {
case XREF_TYPE_PATH_PIECE: {
if (values.size() == 1) {
ModuleDecl *module = values.front()->getModuleContext();
if (values.size() == 1 && isa<NominalTypeDecl>(values.front())) {
// Fast path for nested types that avoids deserializing all
// members of the parent type.
IdentifierID IID;
@@ -1334,29 +1332,23 @@ ModuleFile::resolveCrossReference(ModuleDecl *baseModule, uint32_t pathLen) {
"If you're seeing a crash here, try passing "
"-Xfrontend -disable-serialization-nested-type-lookup-table"};
auto *baseType = cast<NominalTypeDecl>(values.front());
TypeDecl *nestedType = nullptr;
if (onlyInNominal) {
// Only look in the file containing the type itself.
const DeclContext *dc = values.front()->getDeclContext();
auto *serializedFile =
dyn_cast<SerializedASTFile>(dc->getModuleScopeContext());
if (serializedFile) {
nestedType =
serializedFile->File.lookupNestedType(memberName,
values.front());
auto *containingFile =
dyn_cast<FileUnit>(dc->getModuleScopeContext());
if (containingFile) {
nestedType = containingFile->lookupNestedType(memberName, baseType);
}
} else {
// Fault in extensions, then ask every serialized AST in the module.
(void)cast<NominalTypeDecl>(values.front())->getExtensions();
for (FileUnit *file : module->getFiles()) {
(void)baseType->getExtensions();
for (FileUnit *file : baseType->getModuleContext()->getFiles()) {
if (file == getFile())
continue;
auto *serializedFile = dyn_cast<SerializedASTFile>(file);
if (!serializedFile)
continue;
nestedType =
serializedFile->File.lookupNestedType(memberName,
values.front());
nestedType = file->lookupNestedType(memberName, baseType);
if (nestedType)
break;
}

View File

@@ -1363,7 +1363,7 @@ TypeDecl *ModuleFile::lookupLocalType(StringRef MangledName) {
}
TypeDecl *ModuleFile::lookupNestedType(Identifier name,
const ValueDecl *parent) {
const NominalTypeDecl *parent) {
PrettyStackTraceModuleFile stackEntry(*this);
if (!NestedTypeDecls)

View File

@@ -525,6 +525,12 @@ TypeDecl *SerializedASTFile::lookupLocalType(llvm::StringRef MangledName) const{
return File.lookupLocalType(MangledName);
}
TypeDecl *
SerializedASTFile::lookupNestedType(Identifier name,
const NominalTypeDecl *parent) const {
return File.lookupNestedType(name, parent);
}
OperatorDecl *SerializedASTFile::lookupOperator(Identifier name,
DeclKind fixity) const {
return File.lookupOperator(name, fixity);