【发布时间】:2022-01-25 08:54:47
【问题描述】:
我正试图弄清楚 LLVM 中类型的确切规则。据我了解,一般规则是操作符,例如add 必须接受两个 T 类型的操作数,并返回一个 T 类型的结果。但是,整数常量似乎是一个例外。
根据https://llvm.org/docs/LangRef.html#simple-constants
标准整数(如“4”)是整数类型的常量。
“整数”这个词链接到的地方
整数类型是一种非常简单的类型,它只是为所需的整数类型指定任意位宽。可以指定从 1 位到 223(约 800 万)的任意位宽。
所以它没有说明给定常量最终的整数类型宽度。
查看 LLVM 源代码,它包含一个名为 APInt、任意精度整数、https://llvm.org/doxygen/classllvm_1_1APInt.html 的类,这似乎表明整数常量存储为任意精度。
对 clang 的一些实验产生了这个指令:
store i128 -1844674407370955161510, i128* %3, align 16, !tbaa !3
它确实有一个 128 位的整数常量,没有任何 C 表示其类型所需的特殊后缀。
但整数常量也可以是算术运算的操作数。
这是否意味着完整的类型规则类似于'运算符必须采用 T 类型的操作数,并返回 T 类型的结果,除非其中一个操作数是整数常量,在这种情况下它不会需要遵守那个规则吗?
编辑:好的,进一步深入了解解析器的作用......
LLLexer.cpp 在我正在查看的版本的第 1121 行,这似乎是它对整数常量令牌进行词法分析的地方:
// If the next character is a '.', then it is a fp value, otherwise its
// integer.
if (CurPtr[0] != '.') {
if (TokStart[0] == '0' && TokStart[1] == 'x')
return Lex0x();
APSIntVal = APSInt(StringRef(TokStart, CurPtr - TokStart));
return lltok::APSInt;
}
所以它创建了一个没有附加位宽的APSInt(任意精度有符号整数)。
【问题讨论】: