如何引用 LLVM 迭代器?

How do LLVM iterators get referenced?

我正在努力将一个旧项目从 LLVM 3.0 升级到 7.0.0。我在 LLVM 4.0.0 Relesae Notes 中读到:

iterator now stores an ilist_node_base* instead of a T*. The implicit conversions between ilist<T>::iterator and T* have been removed. Clients may use N->getIterator() (if not nullptr) or &*I (if not end())

我现在 运行 遇到了一些编译器允许通过 &*i 取消引用迭代器的实例,但我完全被 how/why 难住了。根据我对指针的理解,不应该 &*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);
    }
}

我环顾四周,但没有找到对这一变化的恰当解释。谁能提供一些见解?

当你写 *i 时,你实际上调用了特殊的 operator*() 重载,那个 returns 一个 Instruction 给你,然后你得到一个指向它的指针 &。因此,&*i.