CompileLayerT::addModule crashed for no reason - llvm

I'm trying to create a llvm JIT in my code:
#include <iostream>
#include <vector>
#include <memory>
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Verifier.h"
#include "KaleidoscopeJIT.h"
#include "llvm/Support/TargetSelect.h"
int main() {
llvm::InitializeNativeTarget();
llvm::InitializeNativeTargetAsmPrinter();
llvm::InitializeNativeTargetAsmParser();
llvm::LLVMContext context;
llvm::orc::KaleidoscopeJIT jit;
auto module = std::make_unique<llvm::Module>("top", context);
llvm::IRBuilder<> builder(context);
module->setDataLayout(jit.getTargetMachine().createDataLayout());
llvm::FunctionType *funcType = llvm::FunctionType::get(builder.getVoidTy(), false);
llvm::Function *mainFunc =
llvm::Function::Create(funcType, llvm::Function::ExternalLinkage, "main", module.get());
llvm::BasicBlock *entry = llvm::BasicBlock::Create(context, "", mainFunc);
builder.SetInsertPoint(entry);
module->print(llvm::errs(), nullptr);
auto H = jit.addModule(std::move(module));
...
...
}
when comes to the addModule, the program crashed(interrupted by signal 11: SIGSEGV), I debugged the stack:
llvm::Instruction::getNumSuccessors() const 0x0000565102dbd7e0
llvm::BranchProbabilityInfo::updatePostDominatedByUnreachable(llvm::BasicBlock const*) 0x000056510361d797
llvm::BranchProbabilityInfo::calculate(llvm::Function const&, llvm::LoopInfo const&, llvm::TargetLibraryInfo const*) 0x00005651036220ef
llvm::BranchProbabilityInfoWrapperPass::runOnFunction(llvm::Function&) 0x00005651036225bd
llvm::FPPassManager::runOnFunction(llvm::Function&) 0x0000565102ddc640
llvm::FPPassManager::runOnModule(llvm::Module&) 0x0000565102ddc8b3
llvm::legacy::PassManagerImpl::run(llvm::Module&) 0x0000565102ddcc7e
llvm::orc::SimpleCompiler::operator() CompileUtils.h:68
llvm::orc::LegacyIRCompileLayer<llvm::orc::LegacyRTDyldObjectLinkingLayer, llvm::orc::SimpleCompiler>::addModule IRCompileLayer.h:84
llvm::orc::KaleidoscopeJIT::addModule KaleidoscopeJIT.h:66
main main.cpp:34
__libc_start_main 0x00007f8d8ee38b97
_start 0x0000565102cdc1ca
The KaleidoscopeJIT.h:
//===- KaleidoscopeJIT.h - A simple JIT for Kaleidoscope --------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Contains a simple JIT definition for use in the kaleidoscope tutorials.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
#define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Mangler.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include <algorithm>
#include <map>
#include <memory>
#include <string>
#include <vector>
namespace llvm {
namespace orc {
class KaleidoscopeJIT {
public:
using ObjLayerT = LegacyRTDyldObjectLinkingLayer;
using CompileLayerT = LegacyIRCompileLayer<ObjLayerT, SimpleCompiler>;
KaleidoscopeJIT()
: Resolver(createLegacyLookupResolver(
ES,
[this](const std::string &Name) {
return ObjectLayer.findSymbol(Name, true);
},
[](Error Err) { cantFail(std::move(Err), "lookupFlags failed"); })),
TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
ObjectLayer(ES,
[this](VModuleKey) {
return ObjLayerT::Resources{
std::make_shared<SectionMemoryManager>(), Resolver};
}),
CompileLayer(ObjectLayer, SimpleCompiler(*TM)) {
llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
}
TargetMachine &getTargetMachine() { return *TM; }
VModuleKey addModule(std::unique_ptr<Module> M) {
auto K = ES.allocateVModule();
cantFail(CompileLayer.addModule(K, std::move(M)));
ModuleKeys.push_back(K);
return K;
}
void removeModule(VModuleKey K) {
ModuleKeys.erase(find(ModuleKeys, K));
cantFail(CompileLayer.removeModule(K));
}
JITSymbol findSymbol(const std::string Name) {
return findMangledSymbol(mangle(Name));
}
private:
std::string mangle(const std::string &Name) {
std::string MangledName;
{
raw_string_ostream MangledNameStream(MangledName);
Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
}
return MangledName;
}
JITSymbol findMangledSymbol(const std::string &Name) {
#ifdef _WIN32
// The symbol lookup of ObjectLinkingLayer uses the SymbolRef::SF_Exported
// flag to decide whether a symbol will be visible or not, when we call
// IRCompileLayer::findSymbolIn with ExportedSymbolsOnly set to true.
//
// But for Windows COFF objects, this flag is currently never set.
// For a potential solution see: https://reviews.llvm.org/rL258665
// For now, we allow non-exported symbols on Windows as a workaround.
const bool ExportedSymbolsOnly = false;
#else
const bool ExportedSymbolsOnly = true;
#endif
// Search modules in reverse order: from last added to first added.
// This is the opposite of the usual search order for dlsym, but makes more
// sense in a REPL where we want to bind to the newest available definition.
for (auto H : make_range(ModuleKeys.rbegin(), ModuleKeys.rend()))
if (auto Sym = CompileLayer.findSymbolIn(H, Name, ExportedSymbolsOnly))
return Sym;
// If we can't find the symbol in the JIT, try looking in the host process.
if (auto SymAddr = RTDyldMemoryManager::getSymbolAddressInProcess(Name))
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
#ifdef _WIN32
// For Windows retry without "_" at beginning, as RTDyldMemoryManager uses
// GetProcAddress and standard libraries like msvcrt.dll use names
// with and without "_" (for example "_itoa" but "sin").
if (Name.length() > 2 && Name[0] == '_')
if (auto SymAddr =
RTDyldMemoryManager::getSymbolAddressInProcess(Name.substr(1)))
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
#endif
return nullptr;
}
ExecutionSession ES;
std::shared_ptr<SymbolResolver> Resolver;
std::unique_ptr<TargetMachine> TM;
const DataLayout DL;
ObjLayerT ObjectLayer;
CompileLayerT CompileLayer;
std::vector<VModuleKey> ModuleKeys;
};
} // end namespace orc
} // end namespace llvm
#endif // LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
But if I run codes in https://llvm.org/docs/tutorial/MyFirstLanguageFrontend/LangImpl04.html, it works well, so I guess the environment is right.
Any idea why it crashed?

AlexDenisov's comment is right: BasicBlocks should end with terminator instructions. Try adding
builder.CreateRetVoid();
to your code between the call to builder.setInsertPoint and module->print.

Related

LLVM: simple example of a just-in-time compilation

I'm learning LLVM and trying to compile a simple function:
int sum(int a, int b) {
return a+b;
};
on the fly.
So here's the code I have so far:
#include <string>
#include <vector>
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Verifier.h"
using namespace llvm;
static LLVMContext &Context = getGlobalContext();
static std::unique_ptr<Module> MyModule = make_unique<Module>("my compiler", Context);
Function *createFunc(IRBuilder<> &Builder, std::string Name) {
std::vector<Type*> Integers(2, Builder.getInt32Ty());
auto *funcType = FunctionType::get(Builder.getInt32Ty(), Integers, false);
auto *fooFunc = Function::Create(funcType, Function::ExternalLinkage, Name, MyModule.get());
return fooFunc;
};
int main(int argc, char* argv[]) {
static IRBuilder<> Builder(Context);
auto *fooFunc = createFunc(Builder, "sum");
auto *entry = BasicBlock::Create(Context, "entry", fooFunc);
Builder.SetInsertPoint(entry);
// Fill the function body
auto args = fooFunc->arg_begin();
Value *arg1 = &(*args);
args = std::next(args);
Value *arg2 = &(*args);
auto *sum = Builder.CreateAdd(arg1, arg2, "tmp");
Builder.CreateRet(sum);
verifyFunction(*fooFunc);
// TODO: compile and run it
MyModule->dump();
return 0;
}
This compiles and when I run it I get the expected output:
; ModuleID = 'my compiler'
define i32 #sum(i32, i32) {
entry:
%tmp = add i32 %0, %1
ret i32 %tmp
}
just like in the tutorial.
But now I want to compile this function and run it from C++. I'm looking for the easiest way to do something like that:
auto compiledStuff = ...;
auto compiledFn = (int (*)(int, int))compiledStuff;
auto result = compiledFn(3, 8);
I've been digging through the official Kaleidoscope tutorial but the JIT tutorial is really complicated and seems to focus on optimizations and laziness while I still can't figure out how to easily compile a module and call a function from it.
Any help?
So, I've digged through the KaleidoscopeJIT and retrieved the most important pieces. First of all note that I'm using llvm-4.0. I've had lots of issues by not realizing how really incompatible 4.0 and lower versions are.
The code works with C++11. I'm using clang++-4.0 with following compilation flags:
llvm-config-4.0 --cxxflags --ldflags --system-libs --libs core engine
And now the entire code:
#include <string>
#include <vector>
#include <iostream>
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Verifier.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Mangler.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/TargetSelect.h"
using namespace llvm;
typedef orc::ObjectLinkingLayer<> ObjLayerT;
typedef orc::IRCompileLayer<ObjLayerT> CompileLayerT;
static LLVMContext Context;
static auto MyModule = make_unique<Module>("my compiler", Context);
Function *createFunc(IRBuilder<> &Builder, std::string Name) {
std::vector<Type*> Integers(2, Builder.getInt32Ty());
auto *funcType = FunctionType::get(Builder.getInt32Ty(), Integers, false);
auto *fooFunc = Function::Create(funcType, Function::ExternalLinkage, Name, MyModule.get());
return fooFunc;
};
void updateBody(Function *fooFunc, IRBuilder<> &Builder) {
auto *entry = BasicBlock::Create(Context, "entry", fooFunc);
Builder.SetInsertPoint(entry);
auto args = fooFunc->arg_begin();
Value *arg1 = &(*args);
args = std::next(args);
Value *arg2 = &(*args);
auto *sum = Builder.CreateAdd(arg1, arg2, "tmp");
Builder.CreateRet(sum);
};
int main(int argc, char* argv[]) {
// Prepare the module
static IRBuilder<> Builder(Context);
auto *fooFunc = createFunc(Builder, "sum");
updateBody(fooFunc, Builder);
verifyFunction(*fooFunc);
// Initilaze native target
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
InitializeNativeTargetAsmParser();
// Prepare jit layer
ObjLayerT ObjectLayer;
std::unique_ptr<TargetMachine> TM(EngineBuilder().selectTarget());
DataLayout DL(TM->createDataLayout());
CompileLayerT CompileLayer(ObjectLayer, orc::SimpleCompiler(*TM));
auto Resolver = orc::createLambdaResolver(
[&](const std::string &Name) {
if (auto Sym = CompileLayer.findSymbol(Name, false))
return Sym;
return JITSymbol(nullptr);
},
[](const std::string &S) { return nullptr; }
);
// Add MyModule to the jit layer
std::vector<std::unique_ptr<Module>> Modules;
Modules.push_back(std::move(MyModule));
CompileLayer.addModuleSet(
std::move(Modules),
make_unique<SectionMemoryManager>(),
std::move(Resolver)
);
// Retrieve the foo symbol
std::string MangledName;
raw_string_ostream MangledNameStream(MangledName);
Mangler::getNameWithPrefix(MangledNameStream, "sum", DL);
auto Sym = CompileLayer.findSymbol(MangledNameStream.str(), true);
// Cast to function
auto func = (int(*)(int, int))Sym.getAddress();
// Try it
std::cout << func(5, 7) << std::endl;
return 0;
}
I'm not sure if all includes are needed but anyway it works like a charm. Although I'm looking forward for any comment on how to improve it. :)
Using the provided KaleidoscopeJIT.h this is pretty straightforward (I'm using LLVM 4.0.0 in this example):
// Your existing includes here.
#include "llvm/Support/TargetSelect.h" // For InitializeNativeTarget() etc.
#include "KaleidoscopeJIT.h"
int main() {
// Your existing main body here.
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
InitializeNativeTargetAsmParser();
orc::KaleidoscopeJIT jit;
MyModule->setDataLayout(jit.getTargetMachine().createDataLayout());
auto moduleHandle = jit.addModule(std::move(MyModule)); // JIT-compile MyModule.
auto symbol = jit.findSymbol("sum"); // Get the compiled sum function.
auto sumFunc = (int(*)(int, int)) symbol.getAddress(); // Cast it.
auto result = sumFunc(42, 42); // Call it.
assert(result == 84); // VoilĂ .
}

in c++, luabridge::LuaRef:no appropriate default constructor available

I write a lua script and want to parse the script by c++ codes. In this script I have functions, and I want to get the function and save it for usage in the future. The main.cpp is like
#include <string>
#include <iostream>
#include "luaParser.h"
#include "LuaBridge.h"
extern "C" {
# include "lua.h"
# include "lauxlib.h"
# include "lualib.h"
}
using namespace luabridge;
void main (void)
{
lua_State* L = luaL_newstate();
if (luaL_dofile(L, "P3626_PORT.lua"))
{
printf("%s\n", lua_tostring(L, -1));
}
luaL_openlibs(L);
lua_pcall(L, 0, 0, 0);
LuaParser parser;
parser.luaParse(L); // get some values from the luaParser::luaParse function
lua_close(L);
parser.run(); // call the run function defined in LuaParser class
parser.stop(); // call the stop function defined in LuaParser class
}
The P3626_PORT.lua is like:
lua_name = "P3626_PORT.lua"
run = function()
print (" this is my input!!!!!!!")
end
stop = function()
print (" this is my output!!!!!!!")
end
The luaParser.h is like:
#pragma once
#include <string>
#include "LuaBridge.h"
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
using namespace luabridge;
class LuaParser
{
public:
LuaParser();
virtual ~LuaParser();
void luaParse(lua_State* L); // in this function, run (pcall) the script and retrieve functions
void run();
void stop();
private:
LuaRef mRun;
LuaRef mStop;
};
And at last, luaParser.cpp is like this:
#ifdef _WIN32
#pragma warning(disable: 4786)
#endif
#include <stdlib.h>
#include <assert.h>
#include "LuaParser.h"
#include <iostream>
#include <string>
LuaParser::LuaParser(){}
LuaParser::~LuaParser(){}
void LuaParser::luaParse(lua_State* L)
{
using namespace luabridge;
LuaRef serviceName = getGlobal(L, "service_name");
std::string LuaServiceName = serviceName.cast<std::string>();
std::cout << LuaServiceName << std::endl;
// now Let's read the function
mRun = getGlobal(L, "run");
mStop = getGlobal(L, "stop");
}
void LuaParser::run()
{
mRun();
}
void LuaParser::stop()
{
mStop();
}
When compiling the project, I get the error
error c2512: 'luabridge::LuaRef':no appropriate default constructor available
I have tried to solve this problem by such as initializing list but it doesn't work. Any idea how to solve this problem?

failing to parse C++ using llvm and clang

I'm writing a little tool with llvm to parse C and C++ code, but I can't seem to get it to successfully parse C++ at all. I'm probably missing something obvious.
This is what I have so far:
#include <iostream>
#include "llvm/Support/Host.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/raw_ostream.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/FrontendOptions.h"
#include "clang/Frontend/LangStandard.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/DirectoryLookup.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/Parse/ParseAST.h"
class MyASTConsumer : public clang::ASTConsumer {
public:
bool HandleTopLevelDecl(clang::DeclGroupRef d);
virtual ~MyASTConsumer() { }
};
bool MyASTConsumer::HandleTopLevelDecl(clang::DeclGroupRef d)
{
for(auto ii = d.begin(); ii != d.end(); ii++)
{
printf("decl type: %s\n", (*ii)->getDeclKindName());
auto namedDecl = llvm::dyn_cast<clang::NamedDecl>(*ii);
if(namedDecl)
{
printf("name: %s\n", namedDecl->getName().data());
}
}
return true;
}
int main(int, char **argv)
{
using clang::CompilerInstance;
using clang::TargetOptions;
using clang::TargetInfo;
using clang::FileEntry;
using clang::DiagnosticOptions;
using clang::TextDiagnosticPrinter;
using clang::SrcMgr::CharacteristicKind;
using clang::StringRef;
using clang::DirectoryLookup;
using llvm::MemoryBuffer;
using clang::LangOptions;
using clang::FrontendOptions;
using clang::LangStandard;
using clang::CompilerInvocation;
using clang::InitializePreprocessor;
using clang::Preprocessor;
using clang::PreprocessorOptions;
using clang::HeaderSearch;
using clang::HeaderSearchOptions;
CompilerInstance ci;
DiagnosticOptions diagnosticOptions;
ci.createDiagnostics();
CompilerInvocation *invocation = new CompilerInvocation;
LangOptions &langOpts = ci.getLangOpts();
langOpts.RTTI = 1;
langOpts.Bool = 1;
langOpts.CPlusPlus11 = 1;
langOpts.GNUKeywords = 1;
langOpts.CXXExceptions = 1;
langOpts.POSIXThreads = 1;
langOpts.SpellChecking = 1;
invocation->setLangDefaults(langOpts, clang::IK_CXX, LangStandard::lang_gnucxx11);
ci.setInvocation(invocation);
llvm::IntrusiveRefCntPtr<TargetOptions> pto( new TargetOptions() );
pto->Triple = llvm::sys::getDefaultTargetTriple();
llvm::IntrusiveRefCntPtr<TargetInfo> pti(TargetInfo::CreateTargetInfo(ci.getDiagnostics(), pto.getPtr()));
ci.setTarget(pti.getPtr());
ci.createFileManager();
auto &fileManager = ci.getFileManager();
ci.createSourceManager(fileManager);
llvm::IntrusiveRefCntPtr<HeaderSearchOptions> headerSearchOpts( new HeaderSearchOptions() );
ci.createPreprocessor();
auto &pp = ci.getPreprocessor();
pp.setPredefines(builtinMacros);
HeaderSearch &headerSearch = pp.getHeaderSearchInfo();
for(auto &inc: builtinIncludePaths)
{
auto dirEntry = fileManager.getDirectory(StringRef(inc), true);
DirectoryLookup dirLookup(dirEntry, CharacteristicKind::C_System, false);
headerSearch.AddSearchPath (dirLookup, true);
}
MyASTConsumer *astConsumer = new MyASTConsumer();
ci.setASTConsumer(astConsumer);
ci.createASTContext();
const FileEntry *pFile = fileManager.getFile(argv[1]);
auto &sourceManager = ci.getSourceManager();
sourceManager.createMainFileID(pFile);
ci.getDiagnosticClient().BeginSourceFile(
ci.getLangOpts(),
&pp
);
clang::ParseAST(pp, astConsumer, ci.getASTContext());
ci.getDiagnosticClient().EndSourceFile();
return 0;
}
It does parse C just fine, but it errors out on the namespace keyword and extern "C" { blocks. So far I'm stumped. If anyone has a clue, something I'm missing, please share.
I believe I figured out the problem. You should always call setInvocation on the compiler instance before calling a lot of the methods on the compiler instance, as it actually just proxies to the invocation.
I moved the setInvocation call to right after the CompilerInvocation object is created, and things now work.

segfault at the end of the main()

I am compiling a program agains LLVM-CLANG. This is the main
#include <iostream>
#include "CompilerFactory.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Basic/Diagnostic.h"
int main(int argc, char const *argv[])
{
using clang::CompilerInstance;
using clang::TargetOptions;
using clang::TargetInfo;
using clang::FileEntry;
using clang::Token;
using clang::DiagnosticOptions;
using clang::TextDiagnosticPrinter;
CompilerInstance ci;
CSFV::CompilerFactory::GetCompilerInstance(ci);
const FileEntry *pFile = ci.getFileManager().getFile("test.c");
ci.getSourceManager().createMainFileID(pFile);
ci.getPreprocessor().EnterMainSourceFile();
ci.getDiagnosticClient().BeginSourceFile(ci.getLangOpts(),
&ci.getPreprocessor());
Token tok;
do
{
ci.getPreprocessor().Lex(tok);
if (ci.getDiagnostics().hasErrorOccurred())
break;
ci.getPreprocessor().DumpToken(tok);
std::cerr << std::endl;
} while (tok.isNot(clang::tok::eof));
ci.getDiagnosticClient().EndSourceFile();
return 0;
}
and this is the included class
//If they are not defined we have an error at compile time
#define __STDC_LIMIT_MACROS
#define __STDC_CONSTANT_MACROS
#include "llvm/Support/Host.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Basic/TargetInfo.h"
using namespace clang;
namespace CSFV{
class CompilerFactory
{
public:
CompilerFactory();
~CompilerFactory();
/// \brief Generate and returns a compiler instance object
static void GetCompilerInstance(CompilerInstance &ci){
DiagnosticOptions diagOpts;
TextDiagnosticPrinter* diagPrinter =
new TextDiagnosticPrinter(llvm::outs(), &diagOpts, true);
ci.createDiagnostics(diagPrinter);
llvm::IntrusiveRefCntPtr<TargetOptions> pto (new TargetOptions());
pto->Triple = llvm::sys::getDefaultTargetTriple();
TargetInfo *pti =
TargetInfo::CreateTargetInfo(ci.getDiagnostics(), pto.getPtr());
ci.setTarget(pti);
ci.createFileManager();
ci.createSourceManager(ci.getFileManager());
ci.createPreprocessor();
return;
}
};
} //end of namespace CSFV
For some reason I get a segfault at the end of the execution of the main. What am I missing?
I don't know if this is the same problem I had, but what I did was declare the targetoptions as a new pointer.
eg:
clang::TargetOptions *targetOpts=new clang::TargetOptions;
I have a feeling targetinfo cleans it up when itself is destroyed.

OpenKinect c++ - Freenect::Freenect freenect

I have a problem with the code OpenKinect provides. I'm trying to use the Kinect with c++, but I get this error. On the web this question was already asked, but I have not find a decent answer. The code is this:
#include <cstdlib>
#include "libfreenect.h"
#include "libfreenect.hpp"
#include <pthread.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <cmath>
#include <vector>
#if defined(__APPLE__)
#include <GLUT/glut.h>
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#endif
using namespace std;
class Mutex {
...
};
class MyFreenectDevice : public Freenect::FreenectDevice {
public:
MyFreenectDevice(freenect_context *_ctx, int _index)
: Freenect::FreenectDevice(_ctx, _index),
m_buffer_depth(freenect_find_video_mode(FREENECT_RESOLUTION_MEDIUM, FREENECT_VIDEO_RGB).bytes),
m_buffer_video(freenect_find_video_mode(FREENECT_RESOLUTION_MEDIUM, FREENECT_VIDEO_RGB).bytes),
m_gamma(2048),
m_new_rgb_frame(false),
m_new_depth_frame(false)
{
for (unsigned int i = 0; i < 2048; i++) {
float v = i / 2048.0;
v = std::pow(v, 3) * 6;
m_gamma[i] = v * 6 * 256;
}
}
...
private:
std::vector<uint8_t> m_buffer_depth;
std::vector<uint8_t> m_buffer_video;
std::vector<uint16_t> m_gamma;
Mutex m_rgb_mutex;
Mutex m_depth_mutex;
bool m_new_rgb_frame;
bool m_new_depth_frame;
};
Freenect::Freenect freenect;
MyFreenectDevice* device;
freenect_video_format requested_format(FREENECT_VIDEO_RGB);
...
I get the error Unable to resolve identifier identifier freenect for the instruction Freenect::Freenect freenect;.
The code of this template is in the libfreenect.hpp code:
class Freenect : Noncopyable {
private:
typedef std::map<int, FreenectDevice*> DeviceMap;
public:
...
template <typename ConcreteDevice>
ConcreteDevice& createDevice(int _index) {
DeviceMap::iterator it = m_devices.find(_index);
if (it != m_devices.end()) delete it->second;
ConcreteDevice * device = new ConcreteDevice(m_ctx, _index);
m_devices.insert(std::make_pair<int, FreenectDevice*>(_index, device));
return *device;
}
...
}
I have no idea of what is the problem, this is the official code and it should work.. any suggestions? thanks in advance