From cab1669e09a27145d219adbcb913fe3a25a8a6e7 Mon Sep 17 00:00:00 2001 From: Victoria Mitchell Date: Thu, 3 Feb 2022 12:19:37 -0700 Subject: [PATCH] only recurse getDisplayDecls in SymbolGraphGen --- include/swift/AST/FileUnit.h | 2 +- include/swift/AST/Module.h | 2 +- include/swift/ClangImporter/ClangModule.h | 2 +- include/swift/Sema/IDETypeChecking.h | 2 +- .../Serialization/SerializedModuleLoader.h | 2 +- lib/AST/Module.cpp | 30 ++++++++++--------- lib/ClangImporter/ClangImporter.cpp | 2 +- lib/ClangImporter/DWARFImporter.cpp | 2 +- lib/IDE/IDETypeChecking.cpp | 7 +++-- lib/Serialization/ModuleFile.cpp | 4 +-- lib/Serialization/ModuleFile.h | 2 +- lib/Serialization/SerializedModuleLoader.cpp | 4 +-- lib/SymbolGraphGen/SymbolGraphGen.cpp | 2 +- test/ModuleInterface/exported-import.swift | 12 ++++++++ 14 files changed, 45 insertions(+), 30 deletions(-) create mode 100644 test/ModuleInterface/exported-import.swift diff --git a/include/swift/AST/FileUnit.h b/include/swift/AST/FileUnit.h index a736e10bbbd27..b71996e890a64 100644 --- a/include/swift/AST/FileUnit.h +++ b/include/swift/AST/FileUnit.h @@ -246,7 +246,7 @@ class FileUnit : public DeclContext, public ASTAllocated { /// /// This can differ from \c getTopLevelDecls, e.g. it returns decls from a /// shadowed clang module. - virtual void getDisplayDecls(SmallVectorImpl &results) const { + virtual void getDisplayDecls(SmallVectorImpl &results, bool recursive = false) const { getTopLevelDecls(results); } diff --git a/include/swift/AST/Module.h b/include/swift/AST/Module.h index 31e7c6391ec88..4056e12fe4418 100644 --- a/include/swift/AST/Module.h +++ b/include/swift/AST/Module.h @@ -780,7 +780,7 @@ class ModuleDecl /// shadowed clang module. It does not force synthesized top-level decls that /// should be printed to be added; use \c swift::getTopLevelDeclsForDisplay() /// for that. - void getDisplayDecls(SmallVectorImpl &results) const; + void getDisplayDecls(SmallVectorImpl &results, bool recursive = false) const; using LinkLibraryCallback = llvm::function_ref; diff --git a/include/swift/ClangImporter/ClangModule.h b/include/swift/ClangImporter/ClangModule.h index 21e93ba159f57..79a1ded84cfd3 100644 --- a/include/swift/ClangImporter/ClangModule.h +++ b/include/swift/ClangImporter/ClangModule.h @@ -91,7 +91,7 @@ class ClangModuleUnit final : public LoadedFile { virtual void getTopLevelDecls(SmallVectorImpl &results) const override; - virtual void getDisplayDecls(SmallVectorImpl &results) const override; + virtual void getDisplayDecls(SmallVectorImpl &results, bool recursive = false) const override; virtual void getImportedModules(SmallVectorImpl &imports, diff --git a/include/swift/Sema/IDETypeChecking.h b/include/swift/Sema/IDETypeChecking.h index 28118f05b4b61..05c4f68857135 100644 --- a/include/swift/Sema/IDETypeChecking.h +++ b/include/swift/Sema/IDETypeChecking.h @@ -145,7 +145,7 @@ namespace swift { /// \c ModuleDecl::getDisplayDecls() would only return if previous /// work happened to have synthesized them. void - getTopLevelDeclsForDisplay(ModuleDecl *M, SmallVectorImpl &Results); + getTopLevelDeclsForDisplay(ModuleDecl *M, SmallVectorImpl &Results, bool Recursive = false); struct ExtensionInfo { // The extension with the declarations to apply. diff --git a/include/swift/Serialization/SerializedModuleLoader.h b/include/swift/Serialization/SerializedModuleLoader.h index 7fb7ba04d7065..db12876f00012 100644 --- a/include/swift/Serialization/SerializedModuleLoader.h +++ b/include/swift/Serialization/SerializedModuleLoader.h @@ -433,7 +433,7 @@ class SerializedASTFile final : public LoadedFile { virtual void getOpaqueReturnTypeDecls(SmallVectorImpl &results) const override; - virtual void getDisplayDecls(SmallVectorImpl &results) const override; + virtual void getDisplayDecls(SmallVectorImpl &results, bool recursive = false) const override; virtual void getImportedModules(SmallVectorImpl &imports, diff --git a/lib/AST/Module.cpp b/lib/AST/Module.cpp index ab1ad0d9a53e1..fcea0c306e66d 100644 --- a/lib/AST/Module.cpp +++ b/lib/AST/Module.cpp @@ -949,30 +949,32 @@ SourceFile::getExternalRawLocsForDecl(const Decl *D) const { return Result; } -void ModuleDecl::getDisplayDecls(SmallVectorImpl &Results) const { - if (isParsedModule(this)) { +void ModuleDecl::getDisplayDecls(SmallVectorImpl &Results, bool Recursive) const { + if (Recursive && isParsedModule(this)) { SmallPtrSet Modules; collectParsedExportedImports(this, Modules); for (const ModuleDecl *import : Modules) { - import->getDisplayDecls(Results); + import->getDisplayDecls(Results, Recursive); } } // FIXME: Should this do extra access control filtering? FORWARD(getDisplayDecls, (Results)); #ifndef NDEBUG - llvm::DenseSet visited; - for (auto *D : Results) { - // decls synthesized from implicit clang decls may appear multiple times; - // e.g. if multiple modules with underlying clang modules are re-exported. - // including duplicates of these is harmless, so skip them when counting - // this assertion - if (const auto *CD = D->getClangDecl()) { - if (CD->isImplicit()) continue; - } + if (Recursive) { + llvm::DenseSet visited; + for (auto *D : Results) { + // decls synthesized from implicit clang decls may appear multiple times; + // e.g. if multiple modules with underlying clang modules are re-exported. + // including duplicates of these is harmless, so skip them when counting + // this assertion + if (const auto *CD = D->getClangDecl()) { + if (CD->isImplicit()) continue; + } - auto inserted = visited.insert(D).second; - assert(inserted && "there should be no duplicate decls"); + auto inserted = visited.insert(D).second; + assert(inserted && "there should be no duplicate decls"); + } } #endif } diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index 0bf438df62607..bb8bf6b754100 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -3249,7 +3249,7 @@ static void getImportDecls(ClangModuleUnit *ClangUnit, const clang::Module *M, } } -void ClangModuleUnit::getDisplayDecls(SmallVectorImpl &results) const { +void ClangModuleUnit::getDisplayDecls(SmallVectorImpl &results, bool recursive) const { if (clangModule) getImportDecls(const_cast(this), clangModule, results); getTopLevelDecls(results); diff --git a/lib/ClangImporter/DWARFImporter.cpp b/lib/ClangImporter/DWARFImporter.cpp index 8b635d1ce5ed6..59eae0416df33 100644 --- a/lib/ClangImporter/DWARFImporter.cpp +++ b/lib/ClangImporter/DWARFImporter.cpp @@ -64,7 +64,7 @@ class DWARFModuleUnit final : public LoadedFile { getTopLevelDecls(SmallVectorImpl &results) const override {} virtual void - getDisplayDecls(SmallVectorImpl &results) const override {} + getDisplayDecls(SmallVectorImpl &results, bool recursive = false) const override {} virtual void getImportedModules(SmallVectorImpl &imports, diff --git a/lib/IDE/IDETypeChecking.cpp b/lib/IDE/IDETypeChecking.cpp index 1b6ce382cb33a..3831626710c56 100644 --- a/lib/IDE/IDETypeChecking.cpp +++ b/lib/IDE/IDETypeChecking.cpp @@ -35,9 +35,10 @@ using namespace swift; void swift::getTopLevelDeclsForDisplay(ModuleDecl *M, - SmallVectorImpl &Results) { + SmallVectorImpl &Results, + bool Recursive) { auto startingSize = Results.size(); - M->getDisplayDecls(Results); + M->getDisplayDecls(Results, Recursive); // Force Sendable on all types, which might synthesize some extensions. // FIXME: We can remove this if @_nonSendable stops creating extensions. @@ -49,7 +50,7 @@ swift::getTopLevelDeclsForDisplay(ModuleDecl *M, // Remove what we fetched and fetch again, possibly now with additional // extensions. Results.resize(startingSize); - M->getDisplayDecls(Results); + M->getDisplayDecls(Results, Recursive); } static bool shouldPrintAsFavorable(const Decl *D, const PrintOptions &Options) { diff --git a/lib/Serialization/ModuleFile.cpp b/lib/Serialization/ModuleFile.cpp index ffc9a82f39bdf..ab0ccf6b0c254 100644 --- a/lib/Serialization/ModuleFile.cpp +++ b/lib/Serialization/ModuleFile.cpp @@ -973,9 +973,9 @@ ModuleFile::getOpaqueReturnTypeDecls(SmallVectorImpl &results) } } -void ModuleFile::getDisplayDecls(SmallVectorImpl &results) { +void ModuleFile::getDisplayDecls(SmallVectorImpl &results, bool recursive) { if (UnderlyingModule) - UnderlyingModule->getDisplayDecls(results); + UnderlyingModule->getDisplayDecls(results, recursive); PrettyStackTraceModuleFile stackEntry(*this); getImportDecls(results); diff --git a/lib/Serialization/ModuleFile.h b/lib/Serialization/ModuleFile.h index f28854ad2cbcd..8f302c09fbd04 100644 --- a/lib/Serialization/ModuleFile.h +++ b/lib/Serialization/ModuleFile.h @@ -684,7 +684,7 @@ class ModuleFile /// This includes all decls that should be displayed to clients of the module. /// This can differ from \c getTopLevelDecls, e.g. it returns decls from a /// shadowed clang module. - void getDisplayDecls(SmallVectorImpl &results); + void getDisplayDecls(SmallVectorImpl &results, bool recursive = false); StringRef getModuleFilename() const { if (!Core->ModuleInterfacePath.empty()) diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp index b4d2ec0683376..6a924a8947b7d 100644 --- a/lib/Serialization/SerializedModuleLoader.cpp +++ b/lib/Serialization/SerializedModuleLoader.cpp @@ -1561,8 +1561,8 @@ SerializedASTFile::getOpaqueReturnTypeDecls( } void -SerializedASTFile::getDisplayDecls(SmallVectorImpl &results) const { - File.getDisplayDecls(results); +SerializedASTFile::getDisplayDecls(SmallVectorImpl &results, bool recursive) const { + File.getDisplayDecls(results, recursive); } StringRef SerializedASTFile::getFilename() const { diff --git a/lib/SymbolGraphGen/SymbolGraphGen.cpp b/lib/SymbolGraphGen/SymbolGraphGen.cpp index 7eef98d4d5e9d..8d56c1f5c5b2e 100644 --- a/lib/SymbolGraphGen/SymbolGraphGen.cpp +++ b/lib/SymbolGraphGen/SymbolGraphGen.cpp @@ -57,7 +57,7 @@ symbolgraphgen::emitSymbolGraphForModule(ModuleDecl *M, const SymbolGraphOptions &Options) { SymbolGraphASTWalker Walker(*M, Options); SmallVector ModuleDecls; - swift::getTopLevelDeclsForDisplay(M, ModuleDecls); + swift::getTopLevelDeclsForDisplay(M, ModuleDecls, /*recursive*/true); if (Options.PrintMessages) llvm::errs() << ModuleDecls.size() diff --git a/test/ModuleInterface/exported-import.swift b/test/ModuleInterface/exported-import.swift new file mode 100644 index 0000000000000..aa539a24c49e3 --- /dev/null +++ b/test/ModuleInterface/exported-import.swift @@ -0,0 +1,12 @@ +// RUN: %empty-directory(%t) +// RUN: %target-swift-frontend -swift-version 5 -enable-library-evolution -emit-module-path %t/Other.swiftmodule -module-name Other %S/Inputs/other.swift +// RUN: %target-swift-frontend -swift-version 5 -enable-library-evolution -emit-module-path /dev/null -emit-module-interface-path %t/ExportedImport.swiftmodule -module-name ExportedImport %s -I %t + +// RUN: %FileCheck --input-file %t/ExportedImport.swiftmodule %s + +// CHECK-NOT: otherFileFunction + +@_exported import Other + +// CHECK: public struct SomeStruct +public struct SomeStruct {}