LLVM 迭代器如何被引用?

3
我正在升级一个旧项目,从LLVM 3.0到7.0.0。我在LLVM 4.0.0版本说明中读到:

iterator现在存储ilist_node_base*而不是T*。在ilist<T>的迭代器ilist<T>::iteratorT*之间的隐式转换已被删除。客户端可以使用N->getIterator()(如果不为空)或&*I(如果不是end())

现在我遇到了一些情况,在这些情况下,通过&*i解引用迭代器是被编译器允许的,但我完全不知道为什么/如何工作。根据我的指针理解,&*i == i,这应该成立,对吗?

以下是一个具体的例子(在LLVM 3.0中,此代码是有效的):

for (Function::iterator b = function.begin(), be = function.end(); b != be; b++)
{
    for (BasicBlock::iterator i = b->begin(), ie=b->end(); i != ie; i++)
    {
        ...
        CallInst::Create(module.getFunction("foo"), args, "", i);
    }
}

当使用LLVM 7.0.0运行时,会出现错误:

error: no matching function for call 'Create'

/root/llvm-7.0.0/include/llvm/IR/Instructions.h:1941.20: note: candidate function not viable: no known 
      conversion from 'BasicBlock::iterator'(aka 'ilist_iterator<node_options<llvm::Instruction,
      extract_sentinel_tracking<>::value, extract_sentinel_tracking<>::is_explicit, void>, false,
      false>') to 'llvm::Instruction *' for 4th argument

但是下面的代码可以编译并且理解&*i是一个instruction*:
for (Function::iterator b = function.begin(), be = function.end(); b != be; b++)
{
    for (BasicBlock::iterator i = b->begin(), ie=b->end(); i != ie; i++)
    {
        ...
        CallInst::Create(module.getFunction("foo"), args, "", &*i);
    }
}

我已经找了一圈,但没有找到一个好的解释这个变化的文章。是否有人能够提供一些见解呢?


“&*b” 是推荐的做法吗?我猜不是,那么其他方法是什么? - Dmitry Mikushin
1个回答

8
当你写*i时,实际上调用了特殊的operator*()重载函数,该函数会返回一个Instruction对象的指针,然后通过&获取该指针。因此,&*i的意思是取得i指向的Instruction对象的地址。

这看起来非常简单,谢谢!你有operator*()重载的源代码吗? - Aroic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接