I'm currently writing a scripting language compiler using LLVM that can compile to executable code and use a JIT too.
The problem I have is to show line numbers in diagnostic messages. Here is some sample code which might be output by my backend (not exactly, but roughly)
; allocate three values. Two for the operands and one for the result.
; all three are of type "myvalue".
%num1 = alloca %myvalue
%num2 = alloca %myvalue
%result = alloca %myvalue
; evaluates 42 + 33. first store the values into the stack
store %myvalue { %mytype* @inttype, i32 42 }, %myvalue* %num1
store %myvalue { %mytype* @inttype, i32 33 }, %myvalue* %num2
; then let the runtime lib calculate it
call void @rtEmitAdd(%myvalue* %num1,
%myvalue* %num2,
%myvalue* %result)
The function rtEmitAdd
is defined in my runtime library, which is written in C++ and does all the handing of implicit conversions, memory cleanup and so on. Now, rtEmitAdd
can detect that it can't add the two values (for instance, an int and a string can be added together by converting the int to a string. But two func values, pointer to functions, cannot be added together). It needs to output a diagnostic message to the user then, and in my compiler I longjmp
back to the entry point of my script that I previously saved using setjmp
). So far it's working nicely.
But now I have all the source line number and even column numbers in my AST for the corresponding AST nodes. However, I have no clue how to get the line number where the addition appears from the point of my runtime library.
I could pass them to my runtime library, as follows
call void @rtEmitAdd(i32 3, % appeared in line 3
%myvalue* %num1,
%myvalue* %num2,
%myvalue* %result)
But I want to avoid this, since I don't want to pay cost for something I hardly ever use (normally, scripts are correct and diagnostics aren't shown).
Any ideas on how I can achieve that?