Skip to content

Commit 26d3c4a

Browse files
committed
Swift: extract system and builtin modules separately
1 parent ff55eff commit 26d3c4a

File tree

2 files changed

+47
-21
lines changed

2 files changed

+47
-21
lines changed

swift/extractor/SwiftExtractor.cpp

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,15 @@ static void archiveFile(const SwiftExtractorConfiguration& config, swift::Source
4949
}
5050
}
5151

52-
static void extractFile(const SwiftExtractorConfiguration& config,
53-
swift::CompilerInstance& compiler,
54-
swift::SourceFile& file) {
52+
static void extractDeclarations(const SwiftExtractorConfiguration& config,
53+
swift::CompilerInstance& compiler,
54+
llvm::StringRef filename,
55+
llvm::ArrayRef<swift::Decl*> topLevelDecls) {
5556
// The extractor can be called several times from different processes with
5657
// the same input file(s)
5758
// We are using PID to avoid concurrent access
5859
// TODO: find a more robust approach to avoid collisions?
59-
std::string tempTrapName = file.getFilename().str() + '.' + std::to_string(getpid()) + ".trap";
60+
std::string tempTrapName = filename.str() + '.' + std::to_string(getpid()) + ".trap";
6061
llvm::SmallString<PATH_MAX> tempTrapPath(config.trapDir);
6162
llvm::sys::path::append(tempTrapPath, tempTrapName);
6263

@@ -84,7 +85,7 @@ static void extractFile(const SwiftExtractorConfiguration& config,
8485
TrapOutput trap{trapStream};
8586
TrapArena arena{};
8687

87-
// TODO move default location emission elsewhere, possibly in a separate global trap file
88+
// TODO: move default location emission elsewhere, possibly in a separate global trap file
8889
auto unknownFileLabel = arena.allocateLabel<FileTag>();
8990
// the following cannot conflict with actual files as those have an absolute path starting with /
9091
trap.assignKey(unknownFileLabel, "unknown");
@@ -93,22 +94,23 @@ static void extractFile(const SwiftExtractorConfiguration& config,
9394
trap.assignKey(unknownLocationLabel, "unknown");
9495
trap.emit(LocationsTrap{unknownLocationLabel, unknownFileLabel});
9596

96-
// In the case of emtpy files, the dispatcher is not called, but we still want to 'record' the
97-
// fact that the file was extracted
98-
// TODO: to be moved elsewhere
99-
llvm::SmallString<PATH_MAX> srcFilePath(file.getFilename());
100-
llvm::sys::fs::make_absolute(srcFilePath);
101-
auto fileLabel = arena.allocateLabel<FileTag>();
102-
trap.assignKey(fileLabel, srcFilePath.str().str());
103-
trap.emit(FilesTrap{fileLabel, srcFilePath.str().str()});
104-
10597
SwiftVisitor visitor(compiler.getSourceMgr(), arena, trap);
106-
for (swift::Decl* decl : file.getTopLevelDecls()) {
98+
for (swift::Decl* decl : topLevelDecls) {
10799
visitor.extract(decl);
108100
}
101+
if (topLevelDecls.empty()) {
102+
// In the case of emtpy files, the dispatcher is not called, but we still want to 'record' the
103+
// fact that the file was extracted
104+
// TODO: to be moved elsewhere
105+
llvm::SmallString<PATH_MAX> srcFilePath(filename);
106+
llvm::sys::fs::make_absolute(srcFilePath);
107+
auto fileLabel = arena.allocateLabel<FileTag>();
108+
trap.assignKey(fileLabel, srcFilePath.str().str());
109+
trap.emit(FilesTrap{fileLabel, srcFilePath.str().str()});
110+
}
109111

110112
// TODO: Pick a better name to avoid collisions
111-
std::string trapName = file.getFilename().str() + ".trap";
113+
std::string trapName = filename.str() + ".trap";
112114
llvm::SmallString<PATH_MAX> trapPath(config.trapDir);
113115
llvm::sys::path::append(trapPath, trapName);
114116

@@ -121,10 +123,24 @@ static void extractFile(const SwiftExtractorConfiguration& config,
121123

122124
void codeql::extractSwiftFiles(const SwiftExtractorConfiguration& config,
123125
swift::CompilerInstance& compiler) {
124-
// The extraction will only work if one (or more) `-primary-file` CLI option is provided, which
125-
// is what always happen in case of `swift build` and `xcodebuild`
126-
for (auto s : compiler.getPrimarySourceFiles()) {
127-
archiveFile(config, *s);
128-
extractFile(config, compiler, *s);
126+
for (auto& [_, module] : compiler.getASTContext().getLoadedModules()) {
127+
// We only extract system and builtin modules here as the other "user" modules can be built
128+
// during the build process and then re-used at a later stage. In this case, we extract the
129+
// user code twice: once during the module build in a form of a source file, and then as
130+
// a pre-built module during building of the dependent source files.
131+
if (module->isSystemModule() || module->isBuiltinModule()) {
132+
llvm::SmallVector<swift::Decl*> decls;
133+
module->getTopLevelDecls(decls);
134+
// TODO: pass ModuleDecl directly when we have module extraction in place?
135+
extractDeclarations(config, compiler, module->getModuleFilename(), decls);
136+
} else {
137+
// The extraction will only work if one (or more) `-primary-file` CLI option is provided,
138+
// which is what always happens in case of `swift build` and `xcodebuild`
139+
for (auto primaryFile : module->getPrimarySourceFiles()) {
140+
archiveFile(config, *primaryFile);
141+
extractDeclarations(config, compiler, primaryFile->getFilename(),
142+
primaryFile->getTopLevelDecls());
143+
}
144+
}
129145
}
130146
}

swift/ql/test/library-tests/controlflow/graph/Cfg.expected

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4811,6 +4811,10 @@ cfg.swift:
48114811
#-----| -> exit init
48124812

48134813
# 378| init
4814+
<<<<<<< HEAD
4815+
=======
4816+
#-----| -> TBD (OtherConstructorDeclRefExpr)
4817+
>>>>>>> d532f3b4d5 (Swift: extract system and builtin modules separately)
48144818
#-----| -> call to ...
48154819

48164820
# 379| super
@@ -4825,9 +4829,15 @@ cfg.swift:
48254829
# 379| self = ...
48264830
#-----| -> return
48274831

4832+
# 379| TBD (OtherConstructorDeclRefExpr)
4833+
#-----| -> super
4834+
4835+
<<<<<<< HEAD
4836+
=======
48284837
# 379| call to ...
48294838
#-----| -> super
48304839

4840+
>>>>>>> d532f3b4d5 (Swift: extract system and builtin modules separately)
48314841
# 379| 0
48324842
#-----| -> call to ...
48334843

0 commit comments

Comments
 (0)