'Get name from LLVM debug metadata

I am trying to extract source level function name form llvm debug metadata. So far, I have tried getting the pointer to DISubprogram and printing out the metadata.

// Assuming Function *F;
DISubprogram *ds = F -> getSubprogram();
if(Metadata *mt = dyn_cast<Metadata>(ds)){
    mt -> dump();
}

This prints out the metadata as:

 <0xa988370> = distinct !DISubprogram(name: "main111", linkageName: "_Z7main111v", scope: <0xa983080>, file: <0xa983080>, line: 26, type: <0xa988480>, scopeLine: 27, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: <0xa982468>, retainedNodes: <0xa97f480>)

I want to extract the name information (main111) from the metadata.

Simply doing F -> getName(); returns back the linkageName (_Z7main111v). I was able to get the linkageName by performing:

ds -> getLinkageName();

But wasn't able to get the source level name (main111) by doing the following:

ds -> getDisplayName(); // generated error

What would be the proper way to extract the source level function name from the metadata?



Solution 1:[1]

What you're looking for is the method DISubprogram::getName. getDisplayName is a method of DIGlobalVariable but it's not available for DISubprogram, so that would explain the error you're getting.

Consider the following snippet (based on LLVM 14) executed for each Function F of a Module:

DISubprogram* DI = F.getSubprogram();
if(!DI) {
  errs() << "Function " << F.getName() << " does not have a subprogram\n";
  continue;
}

StringRef IRName = F.getName();
StringRef SourceName = DI->getName();
StringRef LinkageName = DI->getLinkageName();

errs() << "the ir name " << IRName << "\n";
errs() << "the source name is " << SourceName << "\n";
errs() << "the linkage name is " << LinkageName << "\n";
errs() << "\n";

If I use the following code as input (compiled with clang -S -emit-llvm main.cpp -g -o main.ll)

namespace fooworld {
int foo(int a, int b) {
  return a + b;
}
}

double bar(double a, double b) {
  return a + b;
}

class B {
  int n;
  int size() const;
};

int B::size() const {
  return n;
}

I get the following output:

the ir name _ZN8fooworld3fooEii
the source name is foo
the linkage name is _ZN8fooworld3fooEii

Function llvm.dbg.declare does not have a subprogram
the ir name _Z3bardd
the source name is bar
the linkage name is _Z3bardd

the ir name _ZNK1B4sizeEv
the source name is size
the linkage name is _ZNK1B4sizeEv

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 jmmartinez