为什么这种类型别名导致编译错误(C ++)?

时间:2017-07-17 09:13:47

标签: c++ c++11 compiler-errors compilation llvm

我正在写一个LLVM传递,它可以重命名函数。我有这段小代码

// Get function arguments
std::vector<Argument*> Arguments;
for (auto Arg = F.arg_begin(); Arg != F.arg_end(); ++Arg)
{
  Type *ArgTy = Arg->getType();

  if (ArgTy->isFloatingPointTy())
  {
    errs() << "Cannot test function: " << F.getName() << " (floating point arguments)\n";
    return false;
  }
  Arguments.push_back(Arg);
}

Arguments.push_back(Arg)导致编译错误:

no known conversion for argument 1 from ‘llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::Argument, false, false, void>, false, false>’ to ‘llvm::Argument* const&’

但是,在标头文件llvm/IR/Function.hsource)中,arg_iterator被声明为类型Argument *的别名,以及函数arg_begin()arg_end()实例调用Function,返回arg_iterator()类型。那么为什么我会收到类型错误?是否与使用auto关键字有关?

3 个答案:

答案 0 :(得分:1)

检查驱动器上使用的文件版本。如果你没有直接从GitHub使用它,但是你的文件可能会以某种方式安装LLVM,请检查你正在构建的实际文件。

&#34;责备&#34;在GitHub上显示,大约4个月前(commitarg_begin / arg_end返回类型从ArgumentListType::iteratorArgument *发生了变化,因此你可能正在构建旧版本,它仍然具有原始的复杂迭代器类型。

答案 1 :(得分:0)

尝试取消引用迭代器:

std::vector<Argument*> Arguments;
for (auto Arg = F.arg_begin(); Arg != F.arg_end(); ++Arg)
{
  auto *ArgTy = Arg->getType();

  if (ArgTy->isFloatingPointTy())
  {
    errs() << "Cannot test function: " << F.getName() << " (floating point arguments)\n";
    return false;
  }
  Arguments.push_back(*Arg);
}

这仅在F存储Argument*

等对象时才有效

答案 2 :(得分:0)

为防止编译错误,可能的解决方案如下

// Get function arguments
std::vector<Argument*> Arguments;
for (auto Arg = F.arg_begin(); Arg != F.arg_end(); ++Arg)
{
  Type *ArgTy = Arg->getType();

  if (ArgTy->isFloatingPointTy())
  {
    errs() << "Cannot test function: " << F.getName() << " (floating point arguments)\n";
    return false;
  }
  // Grab a pointer to the argument reference
  Argument *ArgPtr = &*Arg;
  Arguments.push_back(ArgPtr);
}

我的问题源于我对C ++中指针与引用的误解(详见here)。

我不确定为什么arg_iterator != Argument *在编译时 - 它是 也许是因为某些LLVM特定的功能。在任何情况下,我们都需要取消引用Arg才能获得Argument类型,然后按顺序获取Argument类型的地址(使用&运算符)获取指向此Argument类型的指针。

相关问题