Modern equivalent of LLVM AnnotationManager?
Now that LLVM's AnnotationManager is gone (it disappeared in the 2.6 release, I think?), how can I get the annotations for specific fu开发者_运维百科nctions, globals, and instructions?
(For example, I have bitcode compiled from C void myFunction(__attribute__((annotate("foo"))) int var)
--- given an Argument *
reference to this int var
argument, how might I determine which annotate
attributes are attached to it?)
To get annotations for a specific function, traverse the entry BasicBlock of the function to find its calls to the @llvm.var.annotation
intrinsic, as follows:
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";
}
}
AnnotationManager was deleted because it was useless (and it won't solve your problem). All the annotations are handled via the global named 'llvm.global.annotations' and annotation intrinsics, which you can surely parse and obtain the information you needed.
Look into IR to have an idea, how your C code was transformed into IR and what annotation attribute was turned into.
精彩评论