// \file Main.cpp // // This file is distributed under the MIT License. See LICENSE.md for details. // #include #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/Error.h" #include "llvm/Support/PluginLoader.h" #include "llvm/Support/raw_os_ostream.h" #include "revng/Model/LoadModelPass.h" #include "revng/Pipeline/AllRegistries.h" #include "revng/Pipeline/ContainerSet.h" #include "revng/Pipeline/CopyPipe.h" #include "revng/Pipeline/GenericLLVMPipe.h" #include "revng/Pipeline/LLVMContainerFactory.h" #include "revng/Pipeline/LLVMKind.h" #include "revng/Pipeline/Loader.h" #include "revng/Pipeline/Target.h" #include "revng/Pipes/ModelGlobal.h" #include "revng/Pipes/PipelineManager.h" #include "revng/Support/InitRevng.h" using std::string; using namespace llvm; using namespace llvm::cl; using namespace pipeline; using namespace ::revng::pipes; using namespace ::revng; static cl::list Arguments(Positional, ZeroOrMore, desc(" ..."), cat(MainCategory)); static llvm::cl::list InputPipeline("P", llvm::cl::desc(""), llvm::cl::cat(MainCategory)); static llvm::cl::list EnablingFlags("f", llvm::cl::desc("list of " "pipeline " "enabling " "flags"), llvm::cl::cat(MainCategory)); static llvm::cl::alias A1("l", llvm::cl::desc("Alias for --load"), llvm::cl::aliasopt(llvm::LoadOpt), llvm::cl::cat(MainCategory)); static ExitOnError AbortOnError; int main(int argc, char *argv[]) { using revng::FilePath; revng::InitRevng X(argc, argv, "", { &MainCategory }); Registry::runAllInitializationRoutines(); auto Manager = AbortOnError(revng::pipes::PipelineManager::create(InputPipeline, EnablingFlags, "")); const pipeline::Loader &Loader = Manager.getLoader(); const llvm::StringMap &PipesMap = Loader.getPipes(); if (Arguments.size() <= 1 or PipesMap.count(Arguments[0]) == 0) { llvm::outs() << "USAGE: revng-pipe [options] ...\n\n"; llvm::outs() << " can be one of:\n\n"; for (auto &Pair : PipesMap) { llvm::outs() << "revng pipe " << Pair.first() << " "; for (size_t I = 0; I < Pair.second.Pipe->getContainerArgumentsCount(); I++) { llvm::outs() << "<" << Pair.second.Pipe->getContainerName(I) << "> "; } llvm::outs() << "\n"; } return EXIT_SUCCESS; } const auto &Name = ModelGlobalName; auto *Model(cantFail(Manager.context().getGlobal(Name))); InputPath = Arguments[1]; AbortOnError(Model->load(FilePath::fromLocalStorage(Arguments[1]))); const auto &Pipe = PipesMap.find(Arguments[0])->second.Pipe; std::vector DefaultNames; pipeline::ContainerSet Set; if (Arguments.size() - 2 != Pipe->getContainerArgumentsCount()) { llvm::errs() << "Pipe " << Arguments[0] << " required " << Pipe->getContainerArgumentsCount() << " arguments\n"; return EXIT_FAILURE; } for (size_t I = 0; I < Pipe->getContainerArgumentsCount(); I++) { DefaultNames.push_back((llvm::Twine("arg") + llvm::Twine(I)).str()); } PipeWrapper ClonedPipe(Pipe, DefaultNames); for (size_t I = 0; I < Pipe->getContainerArgumentsCount(); I++) { llvm::StringRef Name = ClonedPipe.Pipe->getContainerName(I); auto &Factory = Loader.getContainerFactory(Name); Set.add(DefaultNames[I], Factory, Factory(DefaultNames[I])); AbortOnError(Set.at(DefaultNames[I]) .load(FilePath::fromLocalStorage(Arguments[I + 2]))); } auto Enumeration = Set.enumerate(); ExecutionContext ExecutionContext(Manager.context(), &ClonedPipe, Enumeration); AbortOnError(ClonedPipe.Pipe->run(ExecutionContext, Set)); for (size_t I = 0; I < Pipe->getContainerArgumentsCount(); I++) { if (not Pipe->isContainerArgumentConst(I)) AbortOnError(Set.at(DefaultNames[I]) .store(FilePath::fromLocalStorage(Arguments[I + 2]))); } return EXIT_SUCCESS; }