Я работаю над обновлением старого проекта с LLVM 3.0 до 7.0.0. Я прочитал в LLVM 4.0.0 Relesae Notes :
iterator
теперь хранит ilist_node_base*
вместо T*
. Неявные преобразования между ilist<T>::iterator
и T*
были удалены. Клиенты могут использовать N->getIterator()
(если не nullptr) или &*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);
}
}
Я посмотрел вокруг, но не нашел хорошегообъяснение этого изменения. Может ли кто-нибудь дать некоторое представление?