我使用Clang 3.3编译MUSL C库,并转储生成的LLVM IR文件。我发现,该文件结构为什么LLVM IR结构中的函数指针字段被{} *替换?
struct __FILE_s {
unsigned flags;
unsigned char *rpos, *rend;
int (*close)(FILE *);
unsigned char *wend, *wpos;
unsigned char *mustbezero_1;
unsigned char *wbase;
size_t (*read)(FILE *, unsigned char *, size_t);
size_t (*write)(FILE *, const unsigned char *, size_t);
off_t (*seek)(FILE *, off_t, int);
unsigned char *buf;
size_t buf_size;
FILE *prev, *next;
int fd;
int pipe_pid;
long lockcount;
short dummy3;
signed char mode;
signed char lbf;
int lock;
int waiters;
void *cookie;
off_t off;
char *getln_buf;
void *mustbezero_2;
unsigned char *shend;
off_t shlim, shcnt;
};
被编译为
%struct.__FILE_s = type { i32, i8*, i8*,
i32 (%struct.__FILE_s*)*, i8*, i8*, i8*, i8*,
i64 (%struct.__FILE_s*, i8*, i64)*,
i64 (%struct.__FILE_s*, i8*, i64)*,
i64 (%struct.__FILE_s*, i64, i32)*,
i8*, i64, %struct.__FILE_s*, %struct.__FILE_s*,
i32, i32, i64, i16, i8, i8, i32, i32, i8*,
i64, i8*, i8*, i8*, i64, i64 }
在一些IR文件
,但在其他的源文件编译为
%struct.__FILE_s = type { i32, i8*, i8*,
i32 (%struct.__FILE_s*)*, i8*, i8*, i8*, i8*,
i64 (%struct.__FILE_s*, i8*, i64)*,
{}*,
i64 (%struct.__FILE_s*, i64, i32)*,
i8*, i64, %struct.__FILE_s*, %struct.__FILE_s*,
i32, i32, i64, i16, i8, i8, i32, i32, i8*,
i64, i8*, i8*, i8*, i64, i64 }
。这两个IR结构之间的唯一区别是第一个表单中的函数指针类型字段被替换为{} *而不是其完整类型。谁能告诉我为什么会发生这种情况,以及如何禁用{} *替换?
谢谢你的回应。我认为这个问题更多的是LLVM的具体实现,因为即使包含完整的类型定义,一些结构字段仍然缺失(由*替换)。 – user2744932
我不遵循最后一段。但我也不相信这个答案是有道理的。为什么只有一个函数指针会被影响,而不是所有其他使用'FILE *'的文件都会受到影响? –
你能解释一下你最后一段的意思吗?我不清楚你是否说每个文件*都应该包含完整的定义,或者*不应该*。 –