Files
codeql/swift/extractor/main.cpp
Paolo Tranquilli 521e6235b5 Swift: use std::filesystem and picoSHA2
This replaces usages of `llvm::fs` and string manipulation with
`std::filesystem`, also replacing `std::string` with
`std::filesystem::path` where it made sense.

Moreover MD5 hashing used in macOS file remapping was replaced by
SHA256 hashing using a small header-only SHA256 C++ library with an
MIT license, https://github.com/okdshin/PicoSHA2.

File contents hashing was relocated to the newly created `file` library
for later planned reuse.
2022-10-26 13:23:44 +02:00

94 lines
3.0 KiB
C++

#include <fstream>
#include <iomanip>
#include <stdlib.h>
#include <unordered_set>
#include <vector>
#include <string>
#include <iostream>
#include <swift/Basic/LLVMInitialize.h>
#include <swift/FrontendTool/FrontendTool.h>
#include "swift/extractor/SwiftExtractor.h"
#include "swift/extractor/TargetTrapFile.h"
#include "swift/extractor/remapping/SwiftOutputRewrite.h"
#include "swift/extractor/remapping/SwiftOpenInterception.h"
using namespace std::string_literals;
// This is part of the swiftFrontendTool interface, we hook into the
// compilation pipeline and extract files after the Swift frontend performed
// semantic analysis
class Observer : public swift::FrontendObserver {
public:
explicit Observer(const codeql::SwiftExtractorConfiguration& config) : config{config} {}
void performedSemanticAnalysis(swift::CompilerInstance& compiler) override {
codeql::extractSwiftFiles(config, compiler);
}
private:
const codeql::SwiftExtractorConfiguration& config;
};
static std::string getenv_or(const char* envvar, const std::string& def) {
if (const char* var = getenv(envvar)) {
return var;
}
return def;
}
static void lockOutputSwiftModuleTraps(const codeql::SwiftExtractorConfiguration& config,
const codeql::PathRemapping& remapping) {
for (const auto& [oldPath, newPath] : remapping) {
if (oldPath.extension() == ".swiftmodule") {
if (auto target = codeql::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";
}
}
}
}
int main(int argc, char** argv) {
if (argc == 1) {
// TODO: print usage
return 1;
}
// Required by Swift/LLVM
PROGRAM_START(argc, argv);
INITIALIZE_LLVM();
codeql::SwiftExtractorConfiguration configuration{};
configuration.trapDir = getenv_or("CODEQL_EXTRACTOR_SWIFT_TRAP_DIR", ".");
configuration.sourceArchiveDir = getenv_or("CODEQL_EXTRACTOR_SWIFT_SOURCE_ARCHIVE_DIR", ".");
configuration.scratchDir = getenv_or("CODEQL_EXTRACTOR_SWIFT_SCRATCH_DIR", ".");
codeql::initRemapping(configuration.getTempArtifactDir());
configuration.frontendOptions.reserve(argc - 1);
for (int i = 1; i < argc; i++) {
configuration.frontendOptions.push_back(argv[i]);
}
configuration.patchedFrontendOptions = configuration.frontendOptions;
auto remapping = codeql::rewriteOutputsInPlace(configuration.getTempArtifactDir(),
configuration.patchedFrontendOptions);
codeql::ensureDirectoriesForNewPathsExist(remapping);
lockOutputSwiftModuleTraps(configuration, remapping);
std::vector<const char*> args;
for (auto& arg : configuration.patchedFrontendOptions) {
args.push_back(arg.c_str());
}
Observer observer(configuration);
int frontend_rc = swift::performFrontend(args, "swift-extractor", (void*)main, &observer);
codeql::finalizeRemapping(remapping);
return frontend_rc;
}