1e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar//===-- examples/clang-interpreter/main.cpp - Clang C Interpreter Example -===// 2e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar// 3e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar// The LLVM Compiler Infrastructure 4e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar// 5e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar// This file is distributed under the University of Illinois Open Source 6e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar// License. See LICENSE.TXT for details. 7e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar// 8e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar//===----------------------------------------------------------------------===// 9e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 109b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar#include "clang/CodeGen/CodeGenAction.h" 11e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar#include "clang/Driver/Compilation.h" 12e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar#include "clang/Driver/Driver.h" 13e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar#include "clang/Driver/Tool.h" 14e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar#include "clang/Frontend/CompilerInvocation.h" 15e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar#include "clang/Frontend/CompilerInstance.h" 16e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar#include "clang/Frontend/DiagnosticOptions.h" 17e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar#include "clang/Frontend/FrontendDiagnostic.h" 18e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar#include "clang/Frontend/TextDiagnosticPrinter.h" 19e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 20e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar#include "llvm/Module.h" 21e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar#include "llvm/ADT/OwningPtr.h" 22e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar#include "llvm/ADT/SmallString.h" 2317e279405ed20e71369e9c8ee4d8d720d5ead716Eli Friedman#include "llvm/ExecutionEngine/JIT.h" 24e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar#include "llvm/ExecutionEngine/ExecutionEngine.h" 25e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar#include "llvm/Support/ManagedStatic.h" 26e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar#include "llvm/Support/raw_ostream.h" 2703013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Host.h" 2803013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Path.h" 29a6b4045dc462c03cd1e7cb9c3ec9dbfdb9c6ad62Evan Cheng#include "llvm/Support/TargetSelect.h" 30e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbarusing namespace clang; 31e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbarusing namespace clang::driver; 32e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 33ea1924e62162b299d797d23992a466142b3c6c68Dan Gohman// This function isn't referenced outside its translation unit, but it 34ea1924e62162b299d797d23992a466142b3c6c68Dan Gohman// can't use the "static" keyword because its address is used for 35ea1924e62162b299d797d23992a466142b3c6c68Dan Gohman// GetMainExecutable (since some platforms don't support taking the 36ea1924e62162b299d797d23992a466142b3c6c68Dan Gohman// address of main, and some platforms can't implement GetMainExecutable 37ea1924e62162b299d797d23992a466142b3c6c68Dan Gohman// without being given the address of a function in the main executable). 38aeed3da83c112d0649c30493c059314d85d99080Benjamin Kramerllvm::sys::Path GetExecutablePath(const char *Argv0) { 39e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar // This just needs to be some symbol in the binary; C++ doesn't 40e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar // allow taking the address of ::main however. 41e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar void *MainAddr = (void*) (intptr_t) GetExecutablePath; 42e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar return llvm::sys::Path::GetMainExecutable(Argv0, MainAddr); 43e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar} 44e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 45f129562b4397be749148f5fe543c81f90fdfb6fcDan Gohmanstatic int Execute(llvm::Module *Mod, char * const *envp) { 46e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar llvm::InitializeNativeTarget(); 47e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 48e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar std::string Error; 491e4c01b79273b9cd4e9e9ecfd3422df3900b8356Dylan Noblesmith OwningPtr<llvm::ExecutionEngine> EE( 50e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar llvm::ExecutionEngine::createJIT(Mod, &Error)); 51e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar if (!EE) { 52e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar llvm::errs() << "unable to make execution engine: " << Error << "\n"; 53e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar return 255; 54e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar } 55e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 56e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar llvm::Function *EntryFn = Mod->getFunction("main"); 57e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar if (!EntryFn) { 58e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar llvm::errs() << "'main' function not found in module.\n"; 59e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar return 255; 60e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar } 61e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 62e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar // FIXME: Support passing arguments. 63e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar std::vector<std::string> Args; 64e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar Args.push_back(Mod->getModuleIdentifier()); 65e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 66e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar return EE->runFunctionAsMain(EntryFn, Args, envp); 67e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar} 68e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 69e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbarint main(int argc, const char **argv, char * const *envp) { 70e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar void *MainAddr = (void*) (intptr_t) GetExecutablePath; 71e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar llvm::sys::Path Path = GetExecutablePath(argv[0]); 7206b901be05f92417af25de10c55b9e850e5e5c16Benjamin Kramer TextDiagnosticPrinter *DiagClient = 7306b901be05f92417af25de10c55b9e850e5e5c16Benjamin Kramer new TextDiagnosticPrinter(llvm::errs(), DiagnosticOptions()); 74e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 75c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 76d3c1661593e246f9cd25dc9da27e54b0a61ffe0dEli Friedman DiagnosticsEngine Diags(DiagID, DiagClient); 775d8b9548420e67f1bf45b7bbc1cf9fb86e9e4505Sebastian Pop Driver TheDriver(Path.str(), llvm::sys::getDefaultTargetTriple(), 7810a82cde7c317c5dd41dc3faf17f503c52ce2a3dBob Wilson "a.out", /*IsProduction=*/false, Diags); 79e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar TheDriver.setTitle("clang interpreter"); 80e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 81e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar // FIXME: This is a hack to try to force the driver to do something we can 82e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar // recognize. We need to extend the driver library to support this use model 83e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar // (basically, exactly one input, and the operation mode is hard wired). 84e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar llvm::SmallVector<const char *, 16> Args(argv, argv + argc); 85e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar Args.push_back("-fsyntax-only"); 861e4c01b79273b9cd4e9e9ecfd3422df3900b8356Dylan Noblesmith OwningPtr<Compilation> C(TheDriver.BuildCompilation(Args)); 87e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar if (!C) 88e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar return 0; 89e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 90e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar // FIXME: This is copied from ASTUnit.cpp; simplify and eliminate. 91e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 92e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar // We expect to get back exactly one command job, if we didn't something 93e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar // failed. Extract that job from the compilation. 94e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar const driver::JobList &Jobs = C->getJobs(); 95c8b3e6302f75c4fd44866ecfca9a7063d176c30cManuel Klimek if (Jobs.size() != 1 || !isa<driver::Command>(*Jobs.begin())) { 9636d592718ff342f762e32cbde73d1113f88cb275Dylan Noblesmith SmallString<256> Msg; 97e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar llvm::raw_svector_ostream OS(Msg); 98e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar C->PrintJob(OS, C->getJobs(), "; ", true); 99e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar Diags.Report(diag::err_fe_expected_compiler_job) << OS.str(); 100e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar return 1; 101e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar } 102e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 103e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar const driver::Command *Cmd = cast<driver::Command>(*Jobs.begin()); 104e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar if (llvm::StringRef(Cmd->getCreator().getName()) != "clang") { 105e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar Diags.Report(diag::err_fe_expected_clang_command); 106e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar return 1; 107e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar } 108e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 109e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar // Initialize a compiler invocation object from the clang (-cc1) arguments. 110e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar const driver::ArgStringList &CCArgs = Cmd->getArguments(); 1111e4c01b79273b9cd4e9e9ecfd3422df3900b8356Dylan Noblesmith OwningPtr<CompilerInvocation> CI(new CompilerInvocation); 1129e8635a86db25415ed0b6b64b10984943b3bad65Benjamin Kramer CompilerInvocation::CreateFromArgs(*CI, 1139e8635a86db25415ed0b6b64b10984943b3bad65Benjamin Kramer const_cast<const char **>(CCArgs.data()), 1149e8635a86db25415ed0b6b64b10984943b3bad65Benjamin Kramer const_cast<const char **>(CCArgs.data()) + 1159e8635a86db25415ed0b6b64b10984943b3bad65Benjamin Kramer CCArgs.size(), 116a4f0a80e7367bad218ffe1f8ab1b380f690276ceBenjamin Kramer Diags); 117e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 118e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar // Show the invocation, with -v. 119e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar if (CI->getHeaderSearchOpts().Verbose) { 120e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar llvm::errs() << "clang invocation:\n"; 121e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar C->PrintJob(llvm::errs(), C->getJobs(), "\n", true); 122e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar llvm::errs() << "\n"; 123e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar } 124e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 125e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar // FIXME: This is copied from cc1_main.cpp; simplify and eliminate. 126e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 127e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar // Create a compiler instance to handle the actual work. 128e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar CompilerInstance Clang; 129e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar Clang.setInvocation(CI.take()); 130e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 131e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar // Create the compilers actual diagnostics engine. 132a4f0a80e7367bad218ffe1f8ab1b380f690276ceBenjamin Kramer Clang.createDiagnostics(int(CCArgs.size()),const_cast<char**>(CCArgs.data())); 133e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar if (!Clang.hasDiagnostics()) 134e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar return 1; 135e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 136e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar // Infer the builtin include path if unspecified. 137e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar if (Clang.getHeaderSearchOpts().UseBuiltinIncludes && 138e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar Clang.getHeaderSearchOpts().ResourceDir.empty()) 139e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar Clang.getHeaderSearchOpts().ResourceDir = 140e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar CompilerInvocation::GetResourcesPath(argv[0], MainAddr); 141e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 142e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar // Create and execute the frontend to generate an LLVM bitcode module. 1431e4c01b79273b9cd4e9e9ecfd3422df3900b8356Dylan Noblesmith OwningPtr<CodeGenAction> Act(new EmitLLVMOnlyAction()); 144e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar if (!Clang.ExecuteAction(*Act)) 145e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar return 1; 146e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 147e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar int Res = 255; 148e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar if (llvm::Module *Module = Act->takeModule()) 149e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar Res = Execute(Module, envp); 150e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 151e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar // Shutdown. 152e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 153e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar llvm::llvm_shutdown(); 154e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar 155e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar return Res; 156e22462867ca63e41eabe92b12d6182a62bd829a6Daniel Dunbar} 157