LLVM stdin/stdout/stderr

top*_*hat 11 llvm

如何在LLVM中声明stdin,stoutstderr(最好是C版本)?我试图在我正在创建的玩具语言中使用一些stdio函数.一个这样的功能是fgets:

char * fgets ( char * str, int num, FILE * stream );
Run Code Online (Sandbox Code Playgroud)

为了使用我需要的stdin.所以我写了一些LLVM API代码来生成我找到的FILE的定义,并声明stdin了一个外部全局.代码生成了这个:

%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*
Run Code Online (Sandbox Code Playgroud)

但是,当我运行生成的模块时,它给了我这个错误:

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
Run Code Online (Sandbox Code Playgroud)

显然,我写的东西不起作用.所以我的问题是什么我有LLVM API中写的申报stdin,stout以及stderr对功能,如fgets在像玩具语言编译器?

top*_*hat 6

如果有人有兴趣,我找到了我的问题的答案.经过一番激烈的搜索后,我找到了一种获取stdin流的方法,而不必进行C扩展:fdopen并制作FILE一个不透明的结构.

FILE* fdopen (int fildes, const char *mode)
Run Code Online (Sandbox Code Playgroud)

当fdopen为文件描述符(fildes)传递0时返回stdin流.使用LLVM API,我生成了以下LLVM程序集:

%FILE = type opaque
declare %FILE* @fdopen(i32, i8*)
@r = constant [2 x i8] c"r\00"
Run Code Online (Sandbox Code Playgroud)

然后我能够stdin使用此调用语句检索:

%stdin = call %FILE* @fdopen(i32 0, i8* getelementptr inbounds ([2 x i8]* @r, i32 0, i32 0))
Run Code Online (Sandbox Code Playgroud)


小智 5

如果您使用的功能,如putchar,printf,gets,strtol,puts,fflush你不需要stdinstdout.我写了一个玩具编译器,这对于带有字符串和整数的I/O来说已经足够了.fflush使用null调用并stdout刷新.

%struct._IO_FILE = type opaque
declare i32 @fflush(%struct._IO_FILE*)
...
call i32 @fflush(%struct._IO_FILE* null)
...
Run Code Online (Sandbox Code Playgroud)