Hi,
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(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
Prakash
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);
OK, try writing out the LLVM IR you expect to get for that final store
in full (assume num is named "%num" and alloc is named "%alloc").
Check each detail of it against the lines above; do you see any
discrepancies?
Cheers.
Tim.
As you may have noticed, although the assertions from the debug+assert LLVM build are factually correct, for the purposes of debugging code linked against it, it’s not all that useful.
I have found it useful to build a wrapper layer around LLVM in my project. The primary purpose of the wrapper was to isolate my application from changes in the LLVM API, as it seems to be a moving target. However, for places where I trigger LLVM’s assertions frequently, I have “copied” those assertions into my wrapper to do the same checks prior to calling into LLVM, and to produce useful diagnostics in the case of failure.
For example, I often get argument mismatches between a function call and its definition. So, in my callFunction wrapper, I do the type checks, and in the event of failure, I print out:
-
the name of the function being called
-
the position of the argument whose type mismatches
-
the formal and actual types in question.
You can consider doing the same - create a wrapper around your calls into LLVM, and add better diagnostics where required.
If there is sufficient interest, I might document better what I did.
Thanks a lot Tim and David.
I really found it useful to compare the instructions in the IR with the C++ Classes.
The error in the above code is
Value *num = ConstantInt:: get(Type::getInt64Ty(context), aTable.value, true);
I should use a 32 bit int as my AllocaInst instrcution uses 32 bit int
Thanks
Prakash