blankboy2011
blankboy2011

Reputation: 369

How to get the field name from llvm's metadata

I have a question:

Given the getelementptr instruction, how can I get the field name using metadata?

e.g.

%b = getelementptr inbounds %struct.T* %7, i32 0, i32 1, !dbg !31

I want get its field name "b".

Please post the code! Thank you in advance!

Upvotes: 3

Views: 1712

Answers (2)

blankboy2011
blankboy2011

Reputation: 369

1) If there is a pointer points to a structure, whose metadata is meta,we can use the following function getFieldName to get the field name for an offset offset.

std::string getFieldName(MDNode* meta,int offset){
    if(!meta){
        errs()<<"The meta is NULL\n";
        return ""; 
    }   
    DIVariable div(meta);
    DIType dit=div.getType(); 
    DIDerivedType didt=static_cast<DIDerivedType>(dit);
    DICompositeType dict=static_cast<DICompositeType>(didt.getTypeDerivedFrom());
    DIArray dia=dict.getTypeArray(); 
    assert(offset<dia.getNumElements());
    DIType field=static_cast<DIType>(dia.getElement(offset));
    //errs()<<"Field'name is "<<field.getName()<<"\n";
    return field.getName();
}   

2) If I is an GetElementPtr instruction, we can use the following code to get it's offset.

int offset=0;
ConstantInt* CI=dyn_cast<ConstantInt>(I->getOperand(2));
offset=CI->getSExtValue();

Upvotes: 1

Oak
Oak

Reputation: 26878

If you mean you just want to get the string b from that instruction, you can do that by calling getName() on it. But that's not a reliable way to find the actual field name the gep is referring to. Finding this takes a lot more effort: basically you need to find out the type the gep's first parameter is pointing to (%struct.T), then from the gep's offsets understand which field in the struct the gep is referring to.

It's too complicated for me to write the full code for doing this here, but generally you'd want to use DI classes from DebugInfo.h - read the documentation in that file to learn how to use those classes. Specifically, to match the offsets to a type, I think you'll need to use a DICompositeType and go over all the types contained in it (getTypeArray() will probaby do that).

To get the type to start with you'll need to find the @llvm.dbg.value for the gep's first parameter (the one where the 1st argument is the metadata referring to that struct pointer) - the 3rd argument should be the metadata from the arg, and using DIVariable::getType() should help you here.

It's possible that there are simpler solutions for your question than the above, but I don't know any...

Upvotes: 2

Related Questions