Skip to content

Commit 7ee1105

Browse files
authored
Merge pull request #9750 from github/alexdenisov/extract-imported-modules
Swift: also extract imported modules
2 parents fbeecd6 + 5233a5e commit 7ee1105

File tree

1 file changed

+39
-1
lines changed

1 file changed

+39
-1
lines changed

swift/extractor/SwiftExtractor.cpp

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <memory>
88
#include <unistd.h>
99
#include <unordered_set>
10+
#include <queue>
1011

1112
#include <swift/AST/SourceFile.h>
1213
#include <swift/Basic/FileTypes.h>
@@ -51,6 +52,18 @@ static void archiveFile(const SwiftExtractorConfiguration& config, swift::Source
5152
}
5253
}
5354

55+
static std::string getTrapFilename(swift::ModuleDecl& module, swift::SourceFile* primaryFile) {
56+
if (primaryFile) {
57+
return primaryFile->getFilename().str();
58+
}
59+
// Several modules with different name might come from .pcm (clang module) files
60+
// In this case we want to differentiate them
61+
std::string filename = module.getModuleFilename().str();
62+
filename += "-";
63+
filename += module.getName().str();
64+
return filename;
65+
}
66+
5467
static void extractDeclarations(const SwiftExtractorConfiguration& config,
5568
llvm::ArrayRef<swift::Decl*> topLevelDecls,
5669
swift::CompilerInstance& compiler,
@@ -60,7 +73,8 @@ static void extractDeclarations(const SwiftExtractorConfiguration& config,
6073
// the same input file(s)
6174
// We are using PID to avoid concurrent access
6275
// TODO: find a more robust approach to avoid collisions?
63-
llvm::StringRef filename = primaryFile ? primaryFile->getFilename() : module.getModuleFilename();
76+
auto name = getTrapFilename(module, primaryFile);
77+
llvm::StringRef filename(name);
6478
std::string tempTrapName = filename.str() + '.' + std::to_string(getpid()) + ".trap";
6579
llvm::SmallString<PATH_MAX> tempTrapPath(config.tempTrapDir);
6680
llvm::sys::path::append(tempTrapPath, tempTrapName);
@@ -144,7 +158,31 @@ void codeql::extractSwiftFiles(const SwiftExtractorConfiguration& config,
144158
}
145159
}
146160

161+
// getASTContext().getLoadedModules() does not provide all the modules available within the
162+
// program.
163+
// We need to iterate over all the imported modules (recursively) to see the whole "universe."
164+
std::unordered_set<swift::ModuleDecl*> allModules;
165+
std::queue<swift::ModuleDecl*> worklist;
147166
for (auto& [_, module] : compiler.getASTContext().getLoadedModules()) {
167+
worklist.push(module);
168+
allModules.insert(module);
169+
}
170+
171+
while (!worklist.empty()) {
172+
auto module = worklist.front();
173+
worklist.pop();
174+
llvm::SmallVector<swift::ImportedModule> importedModules;
175+
// TODO: we may need more than just Exported ones
176+
module->getImportedModules(importedModules, swift::ModuleDecl::ImportFilterKind::Exported);
177+
for (auto& imported : importedModules) {
178+
if (allModules.count(imported.importedModule) == 0) {
179+
worklist.push(imported.importedModule);
180+
allModules.insert(imported.importedModule);
181+
}
182+
}
183+
}
184+
185+
for (auto& module : allModules) {
148186
// We only extract system and builtin modules here as the other "user" modules can be built
149187
// during the build process and then re-used at a later stage. In this case, we extract the
150188
// user code twice: once during the module build in a form of a source file, and then as

0 commit comments

Comments
 (0)