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