既然LLVM的AnnotationManager已经消失了(我认为它在2.6版本中消失了吗?),我怎样才能获得特定函数,全局变量和指令的注释?
(例如,我有从C void myFunction(__attribute__((annotate("foo"))) int var)
编译的bitcode ---给Argument *
这个int var
参数的annotate
引用,我如何确定哪个{{1}}属性是附在上面吗?)
答案 0 :(得分:4)
要获取特定函数的注释,遍历函数的BasicBlock条目以查找其对@llvm.var.annotation
内在函数的调用,如下所示:
Module *module;
[...]
std::string getGlobalVariableString(std::string name)
{
// assumption: the zeroth operand of a Value::GlobalVariableVal is the actual Value
Value *v = module->getNamedValue(name)->getOperand(0);
if(v->getValueID() == Value::ConstantArrayVal)
{
ConstantArray *ca = (ConstantArray *)v;
return ca->getAsString();
}
return "";
}
void dumpFunctionArgAnnotations(std::string funcName)
{
std::map<Value *,Argument*> mapValueToArgument;
Function *func = module->getFunction(funcName);
if(!func)
{
std::cout << "no function by that name.\n";
return;
}
std::cout << funcName << "() ====================\n";
// assumption: @llvm.var.annotation calls are always in the function's entry block.
BasicBlock *b = &func->getEntryBlock();
// run through entry block first to build map of pointers to arguments
for(BasicBlock::iterator it = b->begin();it!=b->end();++it)
{
Instruction *inst = it;
if(inst->getOpcode()!=Instruction::Store)
continue;
// `store` operands: http://llvm.org/docs/LangRef.html#i_store
mapValueToArgument[inst->getOperand(1)] = (Argument *)inst->getOperand(0);
}
// run through entry block a second time, to associate annotations with arguments
for(BasicBlock::iterator it = b->begin();it!=b->end();++it)
{
Instruction *inst = it;
if(inst->getOpcode()!=Instruction::Call)
continue;
// assumption: Instruction::Call's operands are the function arguments, followed by the function name
Value *calledFunction = inst->getOperand(inst->getNumOperands()-1);
if(calledFunction->getName().str() != "llvm.var.annotation")
continue;
// `llvm.var.annotation` operands: http://llvm.org/docs/LangRef.html#int_var_annotation
Value *annotatedValue = inst->getOperand(0);
if(annotatedValue->getValueID() != Value::InstructionVal + Instruction::BitCast)
continue;
Argument *a = mapValueToArgument[annotatedValue->getUnderlyingObject()];
if(!a)
continue;
Value *annotation = inst->getOperand(1);
if(annotation->getValueID() != Value::ConstantExprVal)
continue;
ConstantExpr *ce = (ConstantExpr *)annotation;
if(ce->getOpcode() != Instruction::GetElementPtr)
continue;
// `ConstantExpr` operands: http://llvm.org/docs/LangRef.html#constantexprs
Value *gv = ce->getOperand(0);
if(gv->getValueID() != Value::GlobalVariableVal)
continue;
std::cout << " argument " << a->getType()->getDescription() << " " << a->getName().str()
<< " has annotation \"" << getGlobalVariableString(gv->getName().str()) << "\"\n";
}
}
答案 1 :(得分:2)
AnnotationManager已被删除,因为它没用(并且它不会解决您的问题)。所有注释都通过全局命名的'llvm.global.annotations'和注释内在函数来处理,您可以确定地解析并获取所需的信息。
查看IR以了解您的C代码如何转换为IR以及注释属性的转换。