26 #include "clang_compiler.hpp"
27 #include "casadi/core/casadi_os.hpp"
28 #include "casadi/core/casadi_misc.hpp"
29 #include "casadi/core/casadi_meta.hpp"
30 #include "casadi/core/filesystem_impl.hpp"
45 int CASADI_IMPORTER_CLANG_EXPORT
48 plugin->name =
"clang";
50 plugin->version = CASADI_VERSION;
80 "Include paths for the JIT compiler. "
81 "The include directory shipped with CasADi will be automatically appended."}},
84 "Compile flags for the JIT compiler. Default: None"}}
93 for (
auto&& op : opts) {
94 if (op.first==
"include_path") {
96 }
else if (op.first==
"flags") {
102 std::vector<const char *> args(1,
name_.c_str());
104 args.push_back(f.c_str());
108 clang::CompilerInstance compInst;
114 std::string jit_include;
116 char buffer[MAX_PATH];
118 if (!GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
119 GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
120 (LPCSTR)addr, &hm)) {
121 casadi_error(
"GetModuleHandle failed");
123 GetModuleFileNameA(hm, buffer,
sizeof(buffer));
124 PathRemoveFileSpecA(buffer);
125 jit_include = buffer;
128 if (!dladdr(addr, &dl_info)) {
129 casadi_error(
"dladdr failed");
131 jit_include = dl_info.dli_fname;
132 jit_include = jit_include.substr(0, jit_include.find_last_of(
'/'));
138 auto targetoptions = std::make_shared<clang::Taroptions>();
139 targetoptions->Triple = llvm::sys::getDefaultTargetTriple();
140 clang::TargetInfo *targetInfo =
141 clang::TargetInfo::CreateTargetInfo(compInst.get_diagnostics(), targetoptions);
142 compInst.setTarget(targetInfo);
146 clang::DiagnosticOptions* diagOpts =
new clang::DiagnosticOptions();
148 clang::TextDiagnosticPrinter *diagClient =
new clang::TextDiagnosticPrinter(*
myerr_, diagOpts);
150 clang::DiagnosticIDs* diagID =
new clang::DiagnosticIDs();
152 clang::DiagnosticsEngine diags(diagID, diagOpts, diagClient);
155 #if LLVM_VERSION_MAJOR >= 4
156 std::shared_ptr<clang::CompilerInvocation> compInv(
new clang::CompilerInvocation());
158 clang::CompilerInvocation* compInv =
new clang::CompilerInvocation();
160 #if LLVM_VERSION_MAJOR >= 5
161 clang::CompilerInvocation::CreateFromArgs(*compInv, args, diags);
163 clang::CompilerInvocation::CreateFromArgs(*compInv, &args[0],
164 &args[0] + args.size(), diags);
166 compInst.setInvocation(compInv);
169 compInst.createDiagnostics();
170 if (!compInst.hasDiagnostics())
171 casadi_error(
"Cannot create diagnostics");
174 std::string resourcedir = jit_include +
filesep() +
"clang" +
filesep() + CLANG_VERSION_STRING;
175 compInst.getHeaderSearchOpts().ResourceDir = resourcedir;
178 std::vector<std::pair<std::string, bool> >
179 system_include =
getIncludes(
"system_includes.txt", jit_include);
180 for (
auto i=system_include.begin(); i!=system_include.end(); ++i) {
181 compInst.getHeaderSearchOpts().AddPath(i->first,
182 clang::frontend::System, i->second,
false);
186 system_include =
getIncludes(
"csystem_includes.txt", jit_include);
187 for (
auto i=system_include.begin(); i!=system_include.end(); ++i) {
188 compInst.getHeaderSearchOpts().AddPath(i->first,
189 clang::frontend::CSystem, i->second,
false);
193 system_include =
getIncludes(
"cxxsystem_includes.txt", jit_include);
194 for (
auto i=system_include.begin(); i!=system_include.end(); ++i) {
195 compInst.getHeaderSearchOpts().AddPath(i->first,
196 clang::frontend::CXXSystem, i->second,
false);
200 std::stringstream paths;
204 compInst.getHeaderSearchOpts().AddPath(
path, clang::frontend::System,
false,
false);
212 if (!compInst.ExecuteAction(*
act_))
213 casadi_error(
"Cannot execute action");
216 #if LLVM_VERSION_MAJOR>=4 || (LLVM_VERSION_MAJOR==3 && LLVM_VERSION_MINOR>=5)
217 std::unique_ptr<llvm::Module> module =
act_->takeModule();
220 llvm::Module* module =
act_->takeModule();
224 llvm::InitializeNativeTarget();
225 llvm::InitializeNativeTargetAsmPrinter();
230 llvm::EngineBuilder(std::move(module)).setEngineKind(llvm::EngineKind::JIT)
231 .setErrorStr(&ErrStr).create();
233 casadi_error(
"Could not create ExecutionEngine: " + ErrStr);
240 llvm::Function* f =
module_->getFunction(symname);
252 const char sep =
'\\';
254 const char sep =
'/';
258 std::vector<std::pair<std::string, bool> > ret;
262 std::istream& setup_file = *setup_file_ptr;
265 while (std::getline(setup_file, line)) {
267 if (line.empty())
continue;
270 size_t loc = line.find(
" (framework directory)");
271 bool isframework = loc != std::string::npos;
274 line = line.substr(0, loc);
279 bool relative = PathIsRelative(TEXT(line.c_str()));
281 bool relative = line.at(0)!=sep;
286 ret.push_back(std::make_pair(
path + sep + line, isframework));
289 ret.push_back(std::make_pair(line, isframework));
static std::vector< std::pair< std::string, bool > > getIncludes(const std::string &file, const std::string &path)
ClangCompiler(const std::string &name)
Constructor.
void init(const Dict &opts) override
Initialize.
std::string include_path_
clang::EmitLLVMOnlyAction * act_
~ClangCompiler() override
Destructor.
static const Options options_
Options.
static const std::string meta_doc
A documentation string.
llvm::raw_ostream * myerr_
llvm::LLVMContext * context_
std::vector< std::string > flags_
static ImporterInternal * creator(const std::string &name)
Create a new JIT function.
signal_t get_function(const std::string &symname) override
Get a function pointer for numerical evaluation.
llvm::ExecutionEngine * executionEngine_
static std::unique_ptr< std::istream > ifstream_ptr(const std::string &path, std::ios_base::openmode mode=std::ios_base::in, bool fail=true)
virtual void init(const Dict &opts)
Initialize.
static const Options options_
Options.
std::string name_
C filename.
static void registerPlugin(const Plugin &plugin, bool needs_lock=true)
Register an integrator in the factory.
int CASADI_IMPORTER_CLANG_EXPORT casadi_register_importer_clang(ImporterInternal::Plugin *plugin)
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
void CASADI_IMPORTER_CLANG_EXPORT casadi_load_importer_clang()
void(* signal_t)(void)
Function pointer types for the C API.
std::vector< casadi_int > path(const std::vector< casadi_int > &map, casadi_int i_start)
Options metadata for a class.