LLVM 是否在其整数常量的类型规则中做出了例外?
Does LLVM make an exception in its type rules for integer constants?
我正在尝试弄清楚 LLVM 中类型的确切规则。据我了解,一般规则是运营商,例如add
必须接受两个 T 类型的操作数,并且 return 也是 T 类型的结果。但是,整数常量似乎是一个例外。
根据https://llvm.org/docs/LangRef.html#simple-constants
Standard integers (such as ‘4’) are constants of the integer type.
单词 'integer' 链接到
The integer type is a very simple type that simply specifies an arbitrary bit width for the integer type desired. Any bit width from 1 bit to 223(about 8 million) can be specified.
所以它没有说明给定常量最终的整数类型的宽度。
查看 LLVM 源代码,它包含一个名为 APInt 的 class,任意精度整数,https://llvm.org/doxygen/classllvm_1_1APInt.html 这似乎表明整数常量存储为任意精度。
用 clang 进行的一些实验生成了这条指令:
store i128 -1844674407370955161510, i128* %3, align 16, !tbaa !3
它确实有一个 128 位整数常量,没有 C 需要的任何特殊后缀来指示其类型。
但是整数常量也可以是算术运算的操作数。
这是否意味着完整类型规则类似于“运算符必须采用 T 类型的操作数,并且 return 结果也是 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
(任意精度带符号整数)。
不,它没有例外。
获得常量整数的唯一方法是调用 get()
/getTrue()
/... 中的一个函数 ConstantInt,您会注意到它们都采用具有显式位宽的类型,或具有隐式类型(IIRC bool 是唯一的例子,但我可能忘记了一些东西)。
根据 IRC 上的 jrtc27,所有操作数都必须具有为操作指定的类型,因此常量操作数被认为具有该类型。
我正在尝试弄清楚 LLVM 中类型的确切规则。据我了解,一般规则是运营商,例如add
必须接受两个 T 类型的操作数,并且 return 也是 T 类型的结果。但是,整数常量似乎是一个例外。
根据https://llvm.org/docs/LangRef.html#simple-constants
Standard integers (such as ‘4’) are constants of the integer type.
单词 'integer' 链接到
The integer type is a very simple type that simply specifies an arbitrary bit width for the integer type desired. Any bit width from 1 bit to 223(about 8 million) can be specified.
所以它没有说明给定常量最终的整数类型的宽度。
查看 LLVM 源代码,它包含一个名为 APInt 的 class,任意精度整数,https://llvm.org/doxygen/classllvm_1_1APInt.html 这似乎表明整数常量存储为任意精度。
用 clang 进行的一些实验生成了这条指令:
store i128 -1844674407370955161510, i128* %3, align 16, !tbaa !3
它确实有一个 128 位整数常量,没有 C 需要的任何特殊后缀来指示其类型。
但是整数常量也可以是算术运算的操作数。
这是否意味着完整类型规则类似于“运算符必须采用 T 类型的操作数,并且 return 结果也是 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
(任意精度带符号整数)。
不,它没有例外。
获得常量整数的唯一方法是调用 get()
/getTrue()
/... 中的一个函数 ConstantInt,您会注意到它们都采用具有显式位宽的类型,或具有隐式类型(IIRC bool 是唯一的例子,但我可能忘记了一些东西)。
根据 IRC 上的 jrtc27,所有操作数都必须具有为操作指定的类型,因此常量操作数被认为具有该类型。