Files
codeql/swift/extractor/main.cpp
Alex Denisov 488befb577 Swift: store TRAP files in a temporary folder until the extraction is complete
Currently, we have a number of assertions in the codebase and certain
assumptions about the AST. These don't always hold, sometimes leading to
a crash in the extractor.
The crashes leave incomplete TRAP files that cannot be imported into the
database.

With this change, we still get those incomplete TRAP files, but we also
get a database in the end (even thoough it is also incomplete as we
cannot import everything).
2022-06-29 07:17:06 +02:00

67 lines
2.2 KiB
C++

#include <fstream>
#include <iomanip>
#include <stdlib.h>
#include <swift/Basic/LLVMInitialize.h>
#include <swift/FrontendTool/FrontendTool.h>
#include "SwiftExtractor.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 analysys
class Observer : public swift::FrontendObserver {
public:
explicit Observer(const codeql::SwiftExtractorConfiguration& config) : config{config} {}
void parsedArgs(swift::CompilerInvocation& invocation) override {
// Original compiler and the extractor-compiler get into conflicts when
// both produce the same output files.
// TODO: change the final artifact destinations instead of disabling
// the artifact generation completely?
invocation.getFrontendOptions().RequestedAction = swift::FrontendOptions::ActionType::Typecheck;
}
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;
}
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", ".");
configuration.tempTrapDir = configuration.scratchDir + "/swift-trap-temp";
std::vector<const char*> args;
for (int i = 1; i < argc; i++) {
args.push_back(argv[i]);
}
std::copy(std::begin(args), std::end(args), std::back_inserter(configuration.frontendOptions));
Observer observer(configuration);
int frontend_rc = swift::performFrontend(args, "swift-extractor", (void*)main, &observer);
return frontend_rc;
}