1*a9ac8606Spatrick //===------ Interpreter.cpp - Incremental Compilation and Execution -------===// 2*a9ac8606Spatrick // 3*a9ac8606Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*a9ac8606Spatrick // See https://llvm.org/LICENSE.txt for license information. 5*a9ac8606Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*a9ac8606Spatrick // 7*a9ac8606Spatrick //===----------------------------------------------------------------------===// 8*a9ac8606Spatrick // 9*a9ac8606Spatrick // This file implements the component which performs incremental code 10*a9ac8606Spatrick // compilation and execution. 11*a9ac8606Spatrick // 12*a9ac8606Spatrick //===----------------------------------------------------------------------===// 13*a9ac8606Spatrick 14*a9ac8606Spatrick #include "clang/Interpreter/Interpreter.h" 15*a9ac8606Spatrick 16*a9ac8606Spatrick #include "IncrementalExecutor.h" 17*a9ac8606Spatrick #include "IncrementalParser.h" 18*a9ac8606Spatrick 19*a9ac8606Spatrick #include "clang/AST/ASTContext.h" 20*a9ac8606Spatrick #include "clang/Basic/TargetInfo.h" 21*a9ac8606Spatrick #include "clang/CodeGen/ModuleBuilder.h" 22*a9ac8606Spatrick #include "clang/CodeGen/ObjectFilePCHContainerOperations.h" 23*a9ac8606Spatrick #include "clang/Driver/Compilation.h" 24*a9ac8606Spatrick #include "clang/Driver/Driver.h" 25*a9ac8606Spatrick #include "clang/Driver/Job.h" 26*a9ac8606Spatrick #include "clang/Driver/Options.h" 27*a9ac8606Spatrick #include "clang/Driver/Tool.h" 28*a9ac8606Spatrick #include "clang/Frontend/CompilerInstance.h" 29*a9ac8606Spatrick #include "clang/Frontend/TextDiagnosticBuffer.h" 30*a9ac8606Spatrick #include "clang/Lex/PreprocessorOptions.h" 31*a9ac8606Spatrick 32*a9ac8606Spatrick #include "llvm/IR/Module.h" 33*a9ac8606Spatrick #include "llvm/Support/Host.h" 34*a9ac8606Spatrick 35*a9ac8606Spatrick using namespace clang; 36*a9ac8606Spatrick 37*a9ac8606Spatrick // FIXME: Figure out how to unify with namespace init_convenience from 38*a9ac8606Spatrick // tools/clang-import-test/clang-import-test.cpp and 39*a9ac8606Spatrick // examples/clang-interpreter/main.cpp 40*a9ac8606Spatrick namespace { 41*a9ac8606Spatrick /// Retrieves the clang CC1 specific flags out of the compilation's jobs. 42*a9ac8606Spatrick /// \returns NULL on error. 43*a9ac8606Spatrick static llvm::Expected<const llvm::opt::ArgStringList *> 44*a9ac8606Spatrick GetCC1Arguments(DiagnosticsEngine *Diagnostics, 45*a9ac8606Spatrick driver::Compilation *Compilation) { 46*a9ac8606Spatrick // We expect to get back exactly one Command job, if we didn't something 47*a9ac8606Spatrick // failed. Extract that job from the Compilation. 48*a9ac8606Spatrick const driver::JobList &Jobs = Compilation->getJobs(); 49*a9ac8606Spatrick if (!Jobs.size() || !isa<driver::Command>(*Jobs.begin())) 50*a9ac8606Spatrick return llvm::createStringError(std::errc::state_not_recoverable, 51*a9ac8606Spatrick "Driver initialization failed. " 52*a9ac8606Spatrick "Unable to create a driver job"); 53*a9ac8606Spatrick 54*a9ac8606Spatrick // The one job we find should be to invoke clang again. 55*a9ac8606Spatrick const driver::Command *Cmd = cast<driver::Command>(&(*Jobs.begin())); 56*a9ac8606Spatrick if (llvm::StringRef(Cmd->getCreator().getName()) != "clang") 57*a9ac8606Spatrick return llvm::createStringError(std::errc::state_not_recoverable, 58*a9ac8606Spatrick "Driver initialization failed"); 59*a9ac8606Spatrick 60*a9ac8606Spatrick return &Cmd->getArguments(); 61*a9ac8606Spatrick } 62*a9ac8606Spatrick 63*a9ac8606Spatrick static llvm::Expected<std::unique_ptr<CompilerInstance>> 64*a9ac8606Spatrick CreateCI(const llvm::opt::ArgStringList &Argv) { 65*a9ac8606Spatrick std::unique_ptr<CompilerInstance> Clang(new CompilerInstance()); 66*a9ac8606Spatrick IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 67*a9ac8606Spatrick 68*a9ac8606Spatrick // Register the support for object-file-wrapped Clang modules. 69*a9ac8606Spatrick // FIXME: Clang should register these container operations automatically. 70*a9ac8606Spatrick auto PCHOps = Clang->getPCHContainerOperations(); 71*a9ac8606Spatrick PCHOps->registerWriter(std::make_unique<ObjectFilePCHContainerWriter>()); 72*a9ac8606Spatrick PCHOps->registerReader(std::make_unique<ObjectFilePCHContainerReader>()); 73*a9ac8606Spatrick 74*a9ac8606Spatrick // Buffer diagnostics from argument parsing so that we can output them using 75*a9ac8606Spatrick // a well formed diagnostic object. 76*a9ac8606Spatrick IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); 77*a9ac8606Spatrick TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer; 78*a9ac8606Spatrick DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer); 79*a9ac8606Spatrick bool Success = CompilerInvocation::CreateFromArgs( 80*a9ac8606Spatrick Clang->getInvocation(), llvm::makeArrayRef(Argv.begin(), Argv.size()), 81*a9ac8606Spatrick Diags); 82*a9ac8606Spatrick 83*a9ac8606Spatrick // Infer the builtin include path if unspecified. 84*a9ac8606Spatrick if (Clang->getHeaderSearchOpts().UseBuiltinIncludes && 85*a9ac8606Spatrick Clang->getHeaderSearchOpts().ResourceDir.empty()) 86*a9ac8606Spatrick Clang->getHeaderSearchOpts().ResourceDir = 87*a9ac8606Spatrick CompilerInvocation::GetResourcesPath(Argv[0], nullptr); 88*a9ac8606Spatrick 89*a9ac8606Spatrick // Create the actual diagnostics engine. 90*a9ac8606Spatrick Clang->createDiagnostics(); 91*a9ac8606Spatrick if (!Clang->hasDiagnostics()) 92*a9ac8606Spatrick return llvm::createStringError(std::errc::state_not_recoverable, 93*a9ac8606Spatrick "Initialization failed. " 94*a9ac8606Spatrick "Unable to create diagnostics engine"); 95*a9ac8606Spatrick 96*a9ac8606Spatrick DiagsBuffer->FlushDiagnostics(Clang->getDiagnostics()); 97*a9ac8606Spatrick if (!Success) 98*a9ac8606Spatrick return llvm::createStringError(std::errc::state_not_recoverable, 99*a9ac8606Spatrick "Initialization failed. " 100*a9ac8606Spatrick "Unable to flush diagnostics"); 101*a9ac8606Spatrick 102*a9ac8606Spatrick // FIXME: Merge with CompilerInstance::ExecuteAction. 103*a9ac8606Spatrick llvm::MemoryBuffer *MB = llvm::MemoryBuffer::getMemBuffer("").release(); 104*a9ac8606Spatrick Clang->getPreprocessorOpts().addRemappedFile("<<< inputs >>>", MB); 105*a9ac8606Spatrick 106*a9ac8606Spatrick Clang->setTarget(TargetInfo::CreateTargetInfo( 107*a9ac8606Spatrick Clang->getDiagnostics(), Clang->getInvocation().TargetOpts)); 108*a9ac8606Spatrick if (!Clang->hasTarget()) 109*a9ac8606Spatrick return llvm::createStringError(std::errc::state_not_recoverable, 110*a9ac8606Spatrick "Initialization failed. " 111*a9ac8606Spatrick "Target is missing"); 112*a9ac8606Spatrick 113*a9ac8606Spatrick Clang->getTarget().adjust(Clang->getDiagnostics(), Clang->getLangOpts()); 114*a9ac8606Spatrick 115*a9ac8606Spatrick return std::move(Clang); 116*a9ac8606Spatrick } 117*a9ac8606Spatrick 118*a9ac8606Spatrick } // anonymous namespace 119*a9ac8606Spatrick 120*a9ac8606Spatrick llvm::Expected<std::unique_ptr<CompilerInstance>> 121*a9ac8606Spatrick IncrementalCompilerBuilder::create(std::vector<const char *> &ClangArgv) { 122*a9ac8606Spatrick 123*a9ac8606Spatrick // If we don't know ClangArgv0 or the address of main() at this point, try 124*a9ac8606Spatrick // to guess it anyway (it's possible on some platforms). 125*a9ac8606Spatrick std::string MainExecutableName = 126*a9ac8606Spatrick llvm::sys::fs::getMainExecutable(nullptr, nullptr); 127*a9ac8606Spatrick 128*a9ac8606Spatrick ClangArgv.insert(ClangArgv.begin(), MainExecutableName.c_str()); 129*a9ac8606Spatrick 130*a9ac8606Spatrick // Prepending -c to force the driver to do something if no action was 131*a9ac8606Spatrick // specified. By prepending we allow users to override the default 132*a9ac8606Spatrick // action and use other actions in incremental mode. 133*a9ac8606Spatrick // FIXME: Print proper driver diagnostics if the driver flags are wrong. 134*a9ac8606Spatrick ClangArgv.insert(ClangArgv.begin() + 1, "-c"); 135*a9ac8606Spatrick 136*a9ac8606Spatrick if (!llvm::is_contained(ClangArgv, " -x")) { 137*a9ac8606Spatrick // We do C++ by default; append right after argv[0] if no "-x" given 138*a9ac8606Spatrick ClangArgv.push_back("-x"); 139*a9ac8606Spatrick ClangArgv.push_back("c++"); 140*a9ac8606Spatrick } 141*a9ac8606Spatrick 142*a9ac8606Spatrick // Put a dummy C++ file on to ensure there's at least one compile job for the 143*a9ac8606Spatrick // driver to construct. 144*a9ac8606Spatrick ClangArgv.push_back("<<< inputs >>>"); 145*a9ac8606Spatrick 146*a9ac8606Spatrick CompilerInvocation Invocation; 147*a9ac8606Spatrick // Buffer diagnostics from argument parsing so that we can output them using a 148*a9ac8606Spatrick // well formed diagnostic object. 149*a9ac8606Spatrick IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 150*a9ac8606Spatrick IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); 151*a9ac8606Spatrick TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer; 152*a9ac8606Spatrick DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer); 153*a9ac8606Spatrick unsigned MissingArgIndex, MissingArgCount; 154*a9ac8606Spatrick const llvm::opt::OptTable &Opts = driver::getDriverOptTable(); 155*a9ac8606Spatrick llvm::opt::InputArgList ParsedArgs = 156*a9ac8606Spatrick Opts.ParseArgs(ArrayRef<const char *>(ClangArgv).slice(1), 157*a9ac8606Spatrick MissingArgIndex, MissingArgCount); 158*a9ac8606Spatrick ParseDiagnosticArgs(*DiagOpts, ParsedArgs, &Diags); 159*a9ac8606Spatrick 160*a9ac8606Spatrick driver::Driver Driver(/*MainBinaryName=*/ClangArgv[0], 161*a9ac8606Spatrick llvm::sys::getProcessTriple(), Diags); 162*a9ac8606Spatrick Driver.setCheckInputsExist(false); // the input comes from mem buffers 163*a9ac8606Spatrick llvm::ArrayRef<const char *> RF = llvm::makeArrayRef(ClangArgv); 164*a9ac8606Spatrick std::unique_ptr<driver::Compilation> Compilation(Driver.BuildCompilation(RF)); 165*a9ac8606Spatrick 166*a9ac8606Spatrick if (Compilation->getArgs().hasArg(driver::options::OPT_v)) 167*a9ac8606Spatrick Compilation->getJobs().Print(llvm::errs(), "\n", /*Quote=*/false); 168*a9ac8606Spatrick 169*a9ac8606Spatrick auto ErrOrCC1Args = GetCC1Arguments(&Diags, Compilation.get()); 170*a9ac8606Spatrick if (auto Err = ErrOrCC1Args.takeError()) 171*a9ac8606Spatrick return std::move(Err); 172*a9ac8606Spatrick 173*a9ac8606Spatrick return CreateCI(**ErrOrCC1Args); 174*a9ac8606Spatrick } 175*a9ac8606Spatrick 176*a9ac8606Spatrick Interpreter::Interpreter(std::unique_ptr<CompilerInstance> CI, 177*a9ac8606Spatrick llvm::Error &Err) { 178*a9ac8606Spatrick llvm::ErrorAsOutParameter EAO(&Err); 179*a9ac8606Spatrick auto LLVMCtx = std::make_unique<llvm::LLVMContext>(); 180*a9ac8606Spatrick TSCtx = std::make_unique<llvm::orc::ThreadSafeContext>(std::move(LLVMCtx)); 181*a9ac8606Spatrick IncrParser = std::make_unique<IncrementalParser>(std::move(CI), 182*a9ac8606Spatrick *TSCtx->getContext(), Err); 183*a9ac8606Spatrick } 184*a9ac8606Spatrick 185*a9ac8606Spatrick Interpreter::~Interpreter() {} 186*a9ac8606Spatrick 187*a9ac8606Spatrick llvm::Expected<std::unique_ptr<Interpreter>> 188*a9ac8606Spatrick Interpreter::create(std::unique_ptr<CompilerInstance> CI) { 189*a9ac8606Spatrick llvm::Error Err = llvm::Error::success(); 190*a9ac8606Spatrick auto Interp = 191*a9ac8606Spatrick std::unique_ptr<Interpreter>(new Interpreter(std::move(CI), Err)); 192*a9ac8606Spatrick if (Err) 193*a9ac8606Spatrick return std::move(Err); 194*a9ac8606Spatrick return std::move(Interp); 195*a9ac8606Spatrick } 196*a9ac8606Spatrick 197*a9ac8606Spatrick const CompilerInstance *Interpreter::getCompilerInstance() const { 198*a9ac8606Spatrick return IncrParser->getCI(); 199*a9ac8606Spatrick } 200*a9ac8606Spatrick 201*a9ac8606Spatrick llvm::Expected<PartialTranslationUnit &> 202*a9ac8606Spatrick Interpreter::Parse(llvm::StringRef Code) { 203*a9ac8606Spatrick return IncrParser->Parse(Code); 204*a9ac8606Spatrick } 205*a9ac8606Spatrick 206*a9ac8606Spatrick llvm::Error Interpreter::Execute(PartialTranslationUnit &T) { 207*a9ac8606Spatrick assert(T.TheModule); 208*a9ac8606Spatrick if (!IncrExecutor) { 209*a9ac8606Spatrick const llvm::Triple &Triple = 210*a9ac8606Spatrick getCompilerInstance()->getASTContext().getTargetInfo().getTriple(); 211*a9ac8606Spatrick llvm::Error Err = llvm::Error::success(); 212*a9ac8606Spatrick IncrExecutor = std::make_unique<IncrementalExecutor>(*TSCtx, Err, Triple); 213*a9ac8606Spatrick 214*a9ac8606Spatrick if (Err) 215*a9ac8606Spatrick return Err; 216*a9ac8606Spatrick } 217*a9ac8606Spatrick // FIXME: Add a callback to retain the llvm::Module once the JIT is done. 218*a9ac8606Spatrick if (auto Err = IncrExecutor->addModule(std::move(T.TheModule))) 219*a9ac8606Spatrick return Err; 220*a9ac8606Spatrick 221*a9ac8606Spatrick if (auto Err = IncrExecutor->runCtors()) 222*a9ac8606Spatrick return Err; 223*a9ac8606Spatrick 224*a9ac8606Spatrick return llvm::Error::success(); 225*a9ac8606Spatrick } 226