如何将'llvm :: BasicBlock'转换为'pred_iterator'?

时间:2017-04-08 12:26:53

标签: c++11 llvm

我试图在传递过程中从IR文件中获取所有前任基本块。我可以使用

遍历所有基本块
for (auto iter1 = m->getFunctionList().begin();
     iter1 != m->getFunctionList().end();
     iter1++)
{
  for (auto iter2 = f.getBasicBlockList().begin();
       iter2 != f.getBasicBlockList().end();
       iter2++)
  {
    BasicBlock &bb = *iter2;

    std::cout << "    BasicBlock: " << bb.getName().str() << std::endl;
  }
}

但是,当我从this link添加for (BasicBlock *Pred : pred_iterator(bb)) {}时,出现错误

for (auto iter1 = m->getFunctionList().begin();
     iter1 != m->getFunctionList().end();
     iter1++)
{
  for (auto iter2 = f.getBasicBlockList().begin();
       iter2 != f.getBasicBlockList().end();
       iter2++)
  {
    BasicBlock &bb = *iter2;

    std::cout << "    BasicBlock: " << bb.getName().str() << std::endl;
    for (BasicBlock *Pred : pred_iterator(bb)) {}
  }
}

错误如下所示

test2.cpp:63:37: error: no matching conversion for functional-style cast from 'llvm::BasicBlock' to 'pred_iterator' (aka 'PredIterator<llvm::BasicBlock, user_iterator_impl<llvm::User> >')
        for (BasicBlock *Pred : pred_iterator(bb)) {
                                ^~~~~~~~~~~~~~~~

以下是一些其他信息:

/usr/local/include/llvm/IR/CFG.h:48:19: note: candidate constructor not viable: no known conversion from 'llvm::BasicBlock' to 'llvm::BasicBlock *' for 1st argument; take the address of the
      argument with &
  explicit inline PredIterator(Ptr *bb) : It(bb->user_begin()) {
                  ^
Additional Informatino is below. 
/usr/local/include/llvm/IR/CFG.h:30:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'llvm::BasicBlock' to 'const
      llvm::PredIterator<llvm::BasicBlock, llvm::Value::user_iterator_impl<llvm::User> >' for 1st argument
class PredIterator : public std::iterator<std::forward_iterator_tag,
      ^
/usr/local/include/llvm/IR/CFG.h:30:7: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'llvm::BasicBlock' to
      'llvm::PredIterator<llvm::BasicBlock, llvm::Value::user_iterator_impl<llvm::User> >' for 1st argument
/usr/local/include/llvm/IR/CFG.h:47:3: note: candidate constructor not viable: requires 0 arguments, but 1 was provided
  PredIterator() {}
  ^
/usr/local/include/llvm/IR/CFG.h:51:10: note: candidate constructor not viable: requires 2 arguments, but 1 was provided
  inline PredIterator(Ptr *bb, bool) : It(bb->user_end()) {}

如何从'llvm :: BasicBlock'转换为'pred_iterator'?

1 个答案:

答案 0 :(得分:1)

如您发布的错误消息所示,pred_iterator构造函数需要BasicBlock*,而不是BasicBlock&

您的示例的另一个问题是,为了使用基于范围的循环进行迭代,您需要一个范围,而不是迭代器。您应该使用名为llvm::predecessors的帮助程序。

修正这些错误,我们得出以下结论:

for (BasicBlock *Pred : predecessors(&bb)) {}