Getting a pointer to function in llvm - llvm

I'm trying to get a pointer to a function that returns a void and has a string as arguement. The code compiles successfully, but when running the pass, it fails with the following error:
Assertion `(i >= FTy->getNumParams() || FTy->getParamType(i) == Args[i]->getType()) && "Calling a function with a bad signature!"' failed.
Can someone please help. How do I create the signature for such a function correctly?
StructType *StructTy_class_std__basic_string = mod->getTypeByName("class.std::basic_string");
if (!StructTy_class_std__basic_string)
{
StructTy_class_std__basic_string = StructType::create(mod->getContext(), "class.std::basic_string");
}
LLVMContext &Context = mod->getContext();
Constant *c = mod->getOrInsertFunction("_Z5countSs",
Type::getVoidTy(Context),
StructTy_class_std__basic_string, NULL);
Function *funtPtr = cast<Function>(c);
And this is how I make a call to CreateCall:
Constant *a = ConstantDataArray::getString(mod->getContext(), instruction->getOpcodeName(), true);
builder.SetInsertPoint(instruction);
builder.CreateCall(count,a);

Related

a value of type "void *" cannot be assigned to an entity of type "RANDOMSTRUCT *"

So I was working on malloc in void. And I have a code:
int iInitRandomPhaseArrays(WS_ELEMENT *Aufbau, RANDOMSTRUCT **random)
{
WS_ELEMENT *Act;
int iCounter = 0, i;
RANDOMSTRUCT *dummy;
Act = Aufbau;
if (*random != NULL)
return -1;
while (Act != NULL)
{
if (Act->operation == Linsenarray)
iCounter++;
Act = Act->pNext;
}
if (iCounter)
{
dummy = malloc(iCounter * sizeof(random));
ran1_3ARG(&ran1_idum, &ran1_iy, ran1_iv);
dummy[0].idum = ran1_idum;
dummy[0].iy = ran1_iy;
memcpy(dummy[0].iv, ran1_iv, sizeof(ran1_iv));
for (i = 0; i < iCounter; i++)
ran1_3ARG(&dummy[i].idum, &dummy[i].iy, dummy[i].iv);
dummy[0].Anzahl = iCounter;
*random = dummy;
}
return iCounter;
}
here error:
a value of type "void *" cannot be assigned to an entity of type "RANDOMSTRUCT *"
Can anyone help me solve it?
Change the line:
dummy = malloc(iCounter * sizeof(random));
to say:
dummy = (RANDOMSTRUCT *)malloc(iCounter * sizeof(RANDOMSTRUCT));
dummy = malloc(iCounter * sizeof(random));
this allocates the wrong amount of memory (a multiple of a pointer size, not the pointed-to) and returns a void*. In c++ void* doesn't implicitly convert to other pointer types. In c it does.
Assuming you actually mean to use C-isms in C++ code, write this:
template<class T>
T* typed_malloc( std::size_t count = 1 ) {
return static_cast<T*>(malloc( sizeof(T)*count ));
}
this function is a type-safe version of malloc that handles 9999/10000 uses, and prevents an annoying class of bugs.
Then change the line of code to:
dummy = typed_malloc<RANDOMSTRUCT>(iCounter);
Sometimes using malloc in c++ isn't easy to remove, because your code interacts with c code. This kind of change can eliminate bugs before they happen as you modify c code to c++ relatively transparently.

LLVM: Creating a CallInst with a null pointer operand

I'm trying to use the LLVM C++ bindings to write a pass which generates the following IR
%1 = call i64 #time(i64* null) #3
#time here is the C standard library time() function.
Here's the code I've written
void Pass::Insert(BasicBlock *bb, Type *timety, Module *m) {
Type *timetype[1];
timetype[0] = timety;
ArrayRef<Type *> timeTypeAref(timetype, 1);
Value *args[1];
args[0] = ConstantInt::get(timety, 0, false);
ArrayRef<Value *> argsRef(args, 1);
FunctionType *signature = FunctionType::get(timety, false);
Function *timeFunc =
Function::Create(signature, Function::ExternalLinkage, "time", m);
IRBuilder<> Builder(&*(bb->getFirstInsertionPt()));
AllocaInst *a1 = Builder.CreateAlloca(timety, nullptr, Twine("a1"));
CallInst *c1 = Builder.CreateCall(timeFunc, args, Twine("time"));
}
This compiles, but results in the following error when run
Incorrect number of arguments passed to called function!
%time = call i64 #time(i64 0)
As I understand this, I need to pass an int64 pointer which deferences to nullptr, but I'm unable to figure out how to do that.
LLVM provides a ConstantPointerNull class which does exactly what I want - it returns a null pointer of the required type.
All that needs to be changed is the line beginning with args[0] = ... to
args[0] = ConstantPointerNull::get(PointerType::get(timety, 0));.

c++ find command no longer works

This is some old code not written by me. It compiles with GCC 3.4.6, but now we are checking the build with GCC 4.4.7 and the build fails.
I hope this code is enough to go on:
list<Chapter*> * tocP; //Chapter is a class
tocP = NULL;
if (_searchChapter)
{
_chapter = _manager->GetCurrentChapter(); // _chapter is a Chapter*
}
else
{
tocP = _manager->GetTableOfContents();
if (tocP != NULL && tocP->size() > 0)
_chapter = tocP->front();
}
...
list<Chapter*>::iterator chp;
if (tocP != NULL && tocP->size() > 0)
for (chp=find(tocP->begin(),tocP->end(),_chapter); chp != tocP->end(); ++chp) // this code fails
{
//code to process chapter
}
error message is:
../src/HelpSearchC.C: In member function 'int HelpSearchC_i::DoSearch()':
../src/HelpSearchC.C:685: error: no matching function for call to 'find(std::_List_iterator<Chapter*>,
std::_List_iterator<Chapter*>, Chapter*&)'
You have to add #include <algorithm> on top of the file. The function find is defined within this header.

LLVM insert pass into PassManager

I'm writing a module level pass and inside the runOnModule function I have the following bit of code:
for (Module::iterator F = M.begin(), FEND = M.end(); F != FEND; ++F){
if (!(*F).isDeclaration()){
LoopInfo* LI = new LoopInfo();
LI->runOnFunction(*F);
lis.push_back(LI);
for(LoopInfo::iterator L = LI->begin(), LEND = LI->end(); L != LEND; ++L){
// add all functions
loops.push_back(*L);
}
}
}
This all compiles but when I run it I get the following error:
opt: /include/llvm/PassAnalysisSupport.h:200: AnalysisType
&llvm::Pass::getAnalysis() const [AnalysisType = llvm::DominatorTreeWrapperPass]:
Assertion `Resolver && "Pass has not been inserted into a PassManager object!"' failed.
I tried putting the below code in ``lib/Transforms/IPO/PassManagerBuilder.cppin thepopulateModulePassManager` method but nothing happened.
if (EnableMergeFunctions) {
MPM.add(createMergeFunctionsPass());
MPM.add(createJumpThreadingPass()); // Merge consecutive conditionals
MPM.add(createInstructionCombiningPass());
MPM.add(createCFGSimplificationPass());
}
Any help would be great thanks.

LLVM StoreInst and AllocaInst

I am trying to write a simple interpreter.
I am trying to generate LLVM IR for assignment operation. The code for the generation part looks like this
llvm::Value* codeGenSymTab(llvm::LLVMContext& context) {
printf("\n CodeGen SymTab \n");
Value *num = ConstantInt::get(Type::getInt64Ty(context), aTable.value, true);
Value *alloc = new AllocaInst(IntegerType::get(context, 32), aTable.variableName,entry);
StoreInst *ptr = new StoreInst(num,alloc,false,entry);
}
Here goes the SymTab definition:
struct SymTab {
char* variableName;
int value;
llvm::Value* (*codeGen)(llvm::LLVMContext& context);
};
When I try to execute the output file,I get the following error:
Assertion failed: (getOperand(0)->getType() == cast<PointerType>(getOperand(1)->getType())->getElementType() && "Ptr must be a pointer to Val type!"), function AssertOK, file Instructions.cpp, line 1084.
Abort trap: 6
Can you help me resolve it ?
Thanks
You try to store a value of type i64 into an address of type i32*, and these don't match.
You can fix this by using the same type - or preferably, the actual same object:
IntegerType *int_type = Type::getInt64Ty(context);
Value *num = ConstantInt::get(int_type, aTable.value, true);
Value *alloc = new AllocaInst(int_type, aTable.variableName, entry);
StoreInst *ptr = new StoreInst(num,alloc,false,entry);