mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Swift: lock built swiftmodule traps in main
This should cover `-merge-modules` mode. Dumping of the configuration to the target files was moved to a separate pair of header/source files, as now it is also done in `SwiftOutputRewrite.cpp`.
This commit is contained in:
@@ -2,14 +2,10 @@ load("//swift:rules.bzl", "swift_cc_binary")
|
||||
|
||||
swift_cc_binary(
|
||||
name = "extractor",
|
||||
srcs = [
|
||||
"SwiftOutputRewrite.cpp",
|
||||
"SwiftOutputRewrite.h",
|
||||
"SwiftExtractor.cpp",
|
||||
"SwiftExtractor.h",
|
||||
"SwiftExtractorConfiguration.h",
|
||||
"main.cpp",
|
||||
],
|
||||
srcs = glob([
|
||||
"*.h",
|
||||
"*.cpp",
|
||||
]),
|
||||
visibility = ["//swift:__pkg__"],
|
||||
deps = [
|
||||
"//swift/extractor/infra",
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "swift/extractor/trap/generated/TrapClasses.h"
|
||||
#include "swift/extractor/trap/TrapDomain.h"
|
||||
#include "swift/extractor/visitors/SwiftVisitor.h"
|
||||
#include "swift/extractor/infra/TargetFile.h"
|
||||
#include "swift/extractor/TargetTrapFile.h"
|
||||
|
||||
using namespace codeql;
|
||||
using namespace std::string_literals;
|
||||
@@ -80,20 +80,6 @@ static llvm::SmallVector<swift::Decl*> getTopLevelDecls(swift::ModuleDecl& modul
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void dumpArgs(TargetFile& out, const SwiftExtractorConfiguration& config) {
|
||||
out << "/* extractor-args:\n";
|
||||
for (const auto& opt : config.frontendOptions) {
|
||||
out << " " << std::quoted(opt) << " \\\n";
|
||||
}
|
||||
out << "\n*/\n";
|
||||
|
||||
out << "/* swift-frontend-args:\n";
|
||||
for (const auto& opt : config.patchedFrontendOptions) {
|
||||
out << " " << std::quoted(opt) << " \\\n";
|
||||
}
|
||||
out << "\n*/\n";
|
||||
}
|
||||
|
||||
static void extractDeclarations(const SwiftExtractorConfiguration& config,
|
||||
swift::CompilerInstance& compiler,
|
||||
swift::ModuleDecl& module,
|
||||
@@ -103,12 +89,11 @@ static void extractDeclarations(const SwiftExtractorConfiguration& config,
|
||||
// The extractor can be called several times from different processes with
|
||||
// the same input file(s). Using `TargetFile` the first process will win, and the following
|
||||
// will just skip the work
|
||||
auto trapTarget = TargetFile::create(filename + ".trap", config.trapDir, config.getTempTrapDir());
|
||||
auto trapTarget = createTargetTrapFile(config, filename);
|
||||
if (!trapTarget) {
|
||||
// another process arrived first, nothing to do for us
|
||||
return;
|
||||
}
|
||||
dumpArgs(*trapTarget, config);
|
||||
TrapDomain trap{*trapTarget};
|
||||
|
||||
// TODO: remove this and recreate it with IPA when we have that
|
||||
@@ -172,14 +157,6 @@ void codeql::extractSwiftFiles(const SwiftExtractorConfiguration& config,
|
||||
auto inputFiles = collectInputFilenames(compiler);
|
||||
auto modules = collectModules(compiler);
|
||||
|
||||
// we want to make sure any following extractor run will not try to extract things from
|
||||
// the swiftmodule files we are creating in this run, as those things will already have been
|
||||
// extracted from source with more information. We do this by creating empty trap files.
|
||||
// TargetFile semantics will ensure any following run trying to extract that swiftmodule will just
|
||||
// skip doing it
|
||||
for (const auto& output : config.outputSwiftModules) {
|
||||
TargetFile::create(output + ".trap", config.trapDir, config.getTempTrapDir());
|
||||
}
|
||||
for (auto& module : modules) {
|
||||
bool isFromSourceFile = false;
|
||||
for (auto file : module->getFiles()) {
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "swift/extractor/infra/TargetFile.h"
|
||||
|
||||
namespace codeql {
|
||||
struct SwiftExtractorConfiguration {
|
||||
// The location for storing TRAP files to be imported by CodeQL engine.
|
||||
@@ -32,9 +34,6 @@ struct SwiftExtractorConfiguration {
|
||||
// A temporary directory that contains build artifacts generated by the extractor during the
|
||||
// overall extraction process.
|
||||
std::string getTempArtifactDir() const { return scratchDir + "/swift-extraction-artifacts"; }
|
||||
|
||||
// Output swiftmodule files. This also includes possible locations where XCode internally moves
|
||||
// modules
|
||||
std::vector<std::string> outputSwiftModules;
|
||||
};
|
||||
|
||||
} // namespace codeql
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "SwiftOutputRewrite.h"
|
||||
#include "swift/extractor/SwiftExtractorConfiguration.h"
|
||||
#include "swift/extractor/TargetTrapFile.h"
|
||||
|
||||
#include <llvm/ADT/SmallString.h>
|
||||
#include <llvm/Support/FileSystem.h>
|
||||
@@ -323,15 +324,18 @@ std::vector<std::string> collectVFSFiles(const SwiftExtractorConfiguration& conf
|
||||
|
||||
return overlays;
|
||||
}
|
||||
std::vector<std::string> getOutputSwiftModules(
|
||||
const std::unordered_map<std::string, std::string>& remapping) {
|
||||
std::vector<std::string> ret;
|
||||
|
||||
void lockOutputSwiftModuleTraps(const SwiftExtractorConfiguration& config,
|
||||
const std::unordered_map<std::string, std::string>& remapping) {
|
||||
for (const auto& [oldPath, newPath] : remapping) {
|
||||
if (llvm::StringRef(oldPath).endswith(".swiftmodule")) {
|
||||
ret.push_back(oldPath);
|
||||
if (auto target = createTargetTrapFile(config, oldPath)) {
|
||||
*target << "// trap file deliberately empty\n"
|
||||
"// this swiftmodule was created during the build, so its entities must have"
|
||||
" been extracted directly from source files";
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace codeql
|
||||
|
||||
@@ -29,7 +29,7 @@ void storeRemappingForVFS(const SwiftExtractorConfiguration& config,
|
||||
// This is separate from storeRemappingForVFS as we also collect files produced by other processes.
|
||||
std::vector<std::string> collectVFSFiles(const SwiftExtractorConfiguration& config);
|
||||
|
||||
// Returns a list of output remapped swift module files
|
||||
std::vector<std::string> getOutputSwiftModules(
|
||||
const std::unordered_map<std::string, std::string>& remapping);
|
||||
// Creates empty trap files for output swiftmodule files
|
||||
void lockOutputSwiftModuleTraps(const SwiftExtractorConfiguration& config,
|
||||
const std::unordered_map<std::string, std::string>& remapping);
|
||||
} // namespace codeql
|
||||
|
||||
23
swift/extractor/TargetTrapFile.cpp
Normal file
23
swift/extractor/TargetTrapFile.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "swift/extractor/TargetTrapFile.h"
|
||||
#include <iomanip>
|
||||
namespace codeql {
|
||||
std::optional<TargetFile> createTargetTrapFile(const SwiftExtractorConfiguration& configuration,
|
||||
std::string_view target) {
|
||||
std::string trap{target};
|
||||
trap += ".trap";
|
||||
auto ret = TargetFile::create(trap, configuration.trapDir, configuration.getTempTrapDir());
|
||||
if (ret) {
|
||||
*ret << "/* extractor-args:\n";
|
||||
for (const auto& opt : configuration.frontendOptions) {
|
||||
*ret << " " << std::quoted(opt) << " \\\n";
|
||||
}
|
||||
*ret << "\n*/\n"
|
||||
"/* swift-frontend-args:\n";
|
||||
for (const auto& opt : configuration.patchedFrontendOptions) {
|
||||
*ret << " " << std::quoted(opt) << " \\\n";
|
||||
}
|
||||
*ret << "\n*/\n";
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
} // namespace codeql
|
||||
11
swift/extractor/TargetTrapFile.h
Normal file
11
swift/extractor/TargetTrapFile.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "swift/extractor/infra/TargetFile.h"
|
||||
#include "swift/extractor/SwiftExtractorConfiguration.h"
|
||||
|
||||
namespace codeql {
|
||||
|
||||
std::optional<TargetFile> createTargetTrapFile(const SwiftExtractorConfiguration& configuration,
|
||||
std::string_view target);
|
||||
|
||||
} // namespace codeql
|
||||
@@ -68,7 +68,7 @@ int main(int argc, char** argv) {
|
||||
codeql::rewriteOutputsInPlace(configuration, configuration.patchedFrontendOptions);
|
||||
codeql::ensureDirectoriesForNewPathsExist(remapping);
|
||||
codeql::storeRemappingForVFS(configuration, remapping);
|
||||
configuration.outputSwiftModules = codeql::getOutputSwiftModules(remapping);
|
||||
codeql::lockOutputSwiftModuleTraps(configuration, remapping);
|
||||
|
||||
std::vector<const char*> args;
|
||||
for (auto& arg : configuration.patchedFrontendOptions) {
|
||||
|
||||
Reference in New Issue
Block a user