How does one declare stdin
, stout
, and stderr
(preferably the C versions) in LLVM? I am trying to use some stdio functions in a toy language I am creating. One such function was fgets
:
char * fgets ( char * str, int num, FILE * stream );
In order to use that I needed stdin
. So I wrote some LLVM API code to generate the definition of FILE that I found, and declared stdin
a external global. The code generated this:
%file = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %marker*, %file*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
%marker = type { %marker*, %file*, i32 }
@stdin = external global %file*
However, when I ran the resulting module, it gave me this error:
Undefined symbols for architecture x86_64:
"_stdin", referenced from:
_main in cc9A5m3z.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
Apparently, what I wrote didn't work. So my question is what do I have to write in the LLVM API to declare stdin
, stout
, and stderr
for functions like fgets
in something like a toy language compiler?
If anyone is interested, I found an answer to my question. After some intense searching I found a way to get the stdin
stream without having to make a C extension: fdopen
and making FILE
an opaque struct.
FILE* fdopen (int fildes, const char *mode)
When fdopen is passed 0 for a file descriptor (fildes
) It returns the stdin
stream. Using the LLVM API, I generated the following LLVM assembly:
%FILE = type opaque
declare %FILE* @fdopen(i32, i8*)
@r = constant [2 x i8] c"r\00"
Then I was able to retrieve stdin
with this call statement:
%stdin = call %FILE* @fdopen(i32 0, i8* getelementptr inbounds ([2 x i8]* @r, i32 0, i32 0))
If you use functions like putchar
, printf
, gets
, strtol
, puts
, fflush
you won't need stdin
and stdout
. I wrote a toy compiler and those were enough for I/O with strings and integers. fflush
is called with null and stdout
gets flushed.
%struct._IO_FILE = type opaque
declare i32 @fflush(%struct._IO_FILE*)
...
call i32 @fflush(%struct._IO_FILE* null)
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With