Reputation: 61
I want to implement a string type in LLVM-IR, and my plan is as follows:
When a string variable is declared, allocate memory for a i8*.
When the variable is initialized, store the string somewhere, store the pointer to the first element at the formerly allocated address, and save the length of the string in a member variable.
The problem is, that I can't get the pointer to the first element. Using the IRBuilder (C++ API), I have yet created the following code:
%str2 = alloca i8*
%1 = alloca [4 x i8]
store [4 x i8] c"foo\00", [4 x i8]* %1
%2 = getelementptr [4 x i8], [4 x i8]* %1, i32 0
store [4 x i8]* %2, i8** %str2
But calling llc on this gives the following error:
error: stored value and pointer type do not match
store [4 x i8]* %2, i8** %str2
^
When using clang to emit llvm-ir on the same (char* instead of string) code, it emits the following:
%str2 = alloca i8*, align 8
store i8* %str, i8** %1, align 8
store i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8** %str2, align 8
Which looks very similar imho, but is not the same.
Clang makes the string a global constant (which is hopefully not necessary), uses the offset parameter of getelementptr and gives the type i8* to the store instruction.
Unfortunately I wasn't able to find any API Methods to explicitly give a type to the store instruction, or use the offset parameter (which wouldn't even help, I guess).
So finally my question is: How can I properly get a pointer to the first array element and store it?
Thanks in advance
Upvotes: 4
Views: 4363
Reputation: 61
As in the link in the comment, the solution is to bitcast the [n x i8]* to an i8*
%str2 = alloca i8*
%1 = alloca [4 x i8]
store [4 x i8] c"foo\00", [4 x i8]* %1
%2 = bitcast [4 x i8]* %1 to i8*
store i8* %2, i8** %str2
Upvotes: 2