I am making a compiler for a subset of PHP using LLVM and OCaml. LLVM string processing tutorials are a bit missing - at least I can't find them.
This is the code I want to compile:
<?php $a = "foo";
This is my typed AST for the code above:
[(Typedast.Stmt Typedast.Expr (Typedast.TUnit, (<opaque>, Typedast.Binop ((Typedast.Eq None), (<opaque>, Typedast.Lvar ((<opaque>, "$a"), Typedast.TString)), (<opaque>, (Typedast.String (<opaque>, "asd"))), Typedast.TUnit))))]
( <opaque> here simply means that pos (position) is not displayed.)
This is my generated LLVM IR:
; ModuleID = 'mymodule' @foo = private unnamed_addr constant [4 x i8] c"foo\00" define i32 @main() { entry: %"$a" = alloca i8 store i8 0, i8* %"$a" store i8* getelementptr inbounds ([4 x i8]* @foo, i32 0, i32 0), i8* %"$a" ret i32 0 }
And my error message:
Stored value type does not match pointer operand type! store i8* getelementptr inbounds ([4 x i8]* @asd, i32 0, i32 0), i8* %"$a" i8LLVM ERROR: Broken module found, compilation aborted!
The problem is that i8* %"$a" should be i8** %"$a" , as shown in LLVM IR for a simple C program:
int main() { char* str = "Hello, world!"; puts(str); return 0; }
which this LLVM IR will generate:
@.str = private unnamed_addr constant [14 x i8] c"Hello, world!\00", align 1 ; Function Attrs: nounwind uwtable define i32 @main() #0 { %1 = alloca i32, align 4 %str = alloca i8*, align 8 store i32 0, i32* %1 store i8* getelementptr inbounds ([14 x i8]* @.str, i32 0, i32 0), i8** %str, align 8 %2 = load i8** %str, align 8 %3 = call i32 @puts(i8* %2) ret i32 0 }
Any help was appreciated.