我正在写一个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.h
(source)中,arg_iterator
被声明为类型Argument *
的别名,以及函数arg_begin()
和arg_end()
实例调用Function
,返回arg_iterator()
类型。那么为什么我会收到类型错误?是否与使用auto
关键字有关?
答案 0 :(得分:1)
检查驱动器上使用的文件版本。如果你没有直接从GitHub使用它,但是你的文件可能会以某种方式安装LLVM,请检查你正在构建的实际文件。
&#34;责备&#34;在GitHub上显示,大约4个月前(commit)arg_begin
/ arg_end
返回类型从ArgumentListType::iterator
到Argument *
发生了变化,因此你可能正在构建旧版本,它仍然具有原始的复杂迭代器类型。
答案 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
类型的指针。