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