[AST] check modules before recursing for display decls

This commit is contained in:
Victoria Mitchell
2022-01-14 16:28:04 -07:00
parent ec6c3fb3d7
commit aeaf6b22db
5 changed files with 27 additions and 4 deletions

View File

@@ -189,6 +189,8 @@ public:
virtual Identifier
getDiscriminatorForPrivateValue(const ValueDecl *D) const = 0;
virtual bool shouldCollectDisplayDecls() const { return true; }
/// Finds all top-level decls in this file.
///
/// This does a simple local lookup, not recursively looking through imports.

View File

@@ -760,6 +760,15 @@ public:
/// The order of the results is not guaranteed to be meaningful.
void getPrecedenceGroups(SmallVectorImpl<PrecedenceGroupDecl*> &Results) const;
/// Determines whether this module should be recursed into when calling
/// \c getDisplayDecls.
///
/// Some modules should not call \c getDisplayDecls, due to assertions
/// in their implementation. These are usually implicit imports that would be
/// recursed into for parsed modules. This function provides a guard against
/// recusing into modules that should not have decls collected.
bool shouldCollectDisplayDecls() const;
/// Finds all top-level decls that should be displayed to a client of this
/// module.
///

View File

@@ -87,6 +87,8 @@ public:
ObjCSelector selector,
SmallVectorImpl<AbstractFunctionDecl *> &results) const override;
virtual bool shouldCollectDisplayDecls() const override;
virtual void getTopLevelDecls(SmallVectorImpl<Decl*> &results) const override;
virtual void getDisplayDecls(SmallVectorImpl<Decl*> &results) const override;

View File

@@ -780,13 +780,22 @@ void SourceFile::lookupObjCMethods(
results.append(known->second.begin(), known->second.end());
}
bool ModuleDecl::shouldCollectDisplayDecls() const {
for (const FileUnit *file : Files) {
if (!file->shouldCollectDisplayDecls())
return false;
}
return true;
}
static void collectParsedExportedImports(const ModuleDecl *M, SmallPtrSetImpl<ModuleDecl *> &Imports) {
for (const FileUnit *file : M->getFiles()) {
if (const SourceFile *source = dyn_cast<SourceFile>(file)) {
if (source->hasImports()) {
for (auto import : source->getImports()) {
if (import.options.contains(ImportFlags::Exported)) {
if (!Imports.contains(import.module.importedModule)) {
if (import.options.contains(ImportFlags::Exported) &&
!Imports.contains(import.module.importedModule) &&
import.module.importedModule->shouldCollectDisplayDecls()) {
Imports.insert(import.module.importedModule);
}
}
@@ -794,7 +803,6 @@ static void collectParsedExportedImports(const ModuleDecl *M, SmallPtrSetImpl<Mo
}
}
}
}
void ModuleDecl::getLocalTypeDecls(SmallVectorImpl<TypeDecl*> &Results) const {
FORWARD(getLocalTypeDecls, (Results));

View File

@@ -3120,6 +3120,8 @@ public:
};
} // unnamed namespace
bool ClangModuleUnit::shouldCollectDisplayDecls() const { return isTopLevel(); }
void ClangModuleUnit::getTopLevelDecls(SmallVectorImpl<Decl*> &results) const {
VectorDeclPtrConsumer consumer(results);
FilteringDeclaredDeclConsumer filterConsumer(consumer, this);