从FloatingLiteral / APFloat获取原始解析的数字

时间:2015-12-01 14:38:26

标签: c++ clang llvm llvm-clang llvm-ir

我开始使用clang作为我目前正在处理的有界模型检查器的前端,我需要一些从AST获得的浮点数的帮助。

例如,对于这个程序:

int main()
{
  float a = 1.0f;
  long double b = 5567.765434376l;
}

生成的AST是:

FunctionDecl 0x1dea160 </home/mramalho/main.c:3:1, line:7:1> line:3:5 main 'int ()'
`-CompoundStmt 0x1dea368 <line:4:1, line:7:1>
  |-DeclStmt 0x1dea298 <line:5:3, col:17>
  | `-VarDecl 0x1dea218 <col:3, col:13> col:9 a 'float' cinit
  |   `-FloatingLiteral 0x1dea278 <col:13> 'float' 1.000000e+00
  `-DeclStmt 0x1dea350 <line:6:3, col:34>
    `-VarDecl 0x1dea2c0 <col:3, col:19> col:15 b 'long double' cinit
      `-FloatingLiteral 0x1dea320 <col:19> 'long double' 5.567765e+03

我从.getValue()得到的APFLoat号码并没有多大帮助,因为它存储为已转换的号码。

特别是,我想知道是否可以获得原始号码(在上面的例子中,1.0f和5567.765434376l)。如果可能的话,在适用的情况下使用(+/-)Inf和/或NaN的字符串会很棒但不是必需的。

我尝试了几种方法,但我总是以原始数字的修剪版本结束。

我最好的选择是使用方法convertFromString和结构DecimalInfo(都在APFloat上),但我无法找到一种方法来访问它们,因为在我获得FloatingLiteral时已经创建了该数字。

谢谢。

1 个答案:

答案 0 :(得分:4)

不知道回答你自己的问题是否可以,但这是我解决问题的方法:

llvm::SmallVector<char, 32> string;
val.toString(string, 32, 0);

其中val是APFloat。来自文档:

/// Converts this value into a decimal string.
///
/// \param FormatPrecision The maximum number of digits of
///   precision to output.  If there are fewer digits available,
///   zero padding will not be used unless the value is
///   integral and small enough to be expressed in
///   FormatPrecision digits.  0 means to use the natural
///   precision of the number.
/// \param FormatMaxPadding The maximum number of zeros to
///   consider inserting before falling back to scientific
///   notation.  0 means to always use scientific notation.
///
/// Number       Precision    MaxPadding      Result
/// ------       ---------    ----------      ------
/// 1.01E+4              5             2       10100
/// 1.01E+4              4             2       1.01E+4
/// 1.01E+4              5             1       1.01E+4
/// 1.01E-2              5             2       0.0101
/// 1.01E-2              4             2       0.0101
/// 1.01E-2              4             1       1.01E-2

然后,它是一个简单的迭代来获取值。

它还提供了&#34; Inf&#34;无穷大值的字符串。