为什么这种类型的别名会导致编译错误(C++)?

问题描述:

我正在写一个LLVM传递函数,以重新命名函数。我有这样一小段代码为什么这种类型的别名会导致编译错误(C++)?

// 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.hsource),arg_iterator被声明为类型Argument *的别名,由Function实例调用的函数arg_begin()arg_end(),返回arg_iterator()类型。那么,为什么我会得到类型错误?它是否与使用关键字auto有关?

+0

你*知道如何使用迭代器?当你(例如)*解引用*迭代器时得到什么? –

+2

@Someprogrammerdude当迭代器的类型为'Argument *'时,你得到指向的'Argument'作为左值。但问题是为什么'auto Arg = F.arg_begin()'的类型不是在头部声明的'arg_iterator'(=='Argument *'),而是别的。 UnchartedWaters:创建一个[mcve]。你的例子不完整。 – user2079303

尝试取消引用您的迭代器:

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*

选中你正在使用您的驱动器上的文件的版本这只会工作。如果您没有直接从GitHub使用它,但是可能您的文件以LLVM安装方式进行了某种操作,请检查您正在构建的实际文件。

在GitHub上显示“怪”,即有一个在arg_begin/arg_end返回类型从ArgumentListType::iteratorArgument *大约4个月前的变化(commit),所以你可能会建立针对旧版本,仍然有最初的复杂迭代器类型。

为了防止编译错误,尽可能解决方案如下

// 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); 
} 

我的问题从我的指针误解VS出现在C++(见here了解更多细节)引用。

我不确定为什么arg_iterator != Argument *在编译时 - 它是 也许是因为某些LLVM的特定功能。在任何情况下,我们需要取消Arg以获得Argument类型,然后取Argument类型的地址(使用&运算符),以便获得指向此类型的指针Argument

+0

我认为你的困惑是在迭代器和指针之间,而不是引用和指针 – Useless

+0

代码也应该在原始版本中工作,但只有当'arg_begin'返回类型实际上是'Argument *'时,也就是说,如果您使用的是最近版本从GitHub版本 - 有一个变化,看到我的答案。 – axalis