"Function" file name

Folks,

I am newbie to llvm!

I am writing a simple pass that inherits from ModulePass. I override the runOnModule method. In the method, i am attempting to print all the function in the module and the source-file they appear in. I could print the name of the function using the Module::iterator. I am, however, not able to figure-out the way to identify the source-file for a given “Function”. Any help in this regards is appreciated.

Thanks and with best regards,
Nizam

Hi Nizam,

I am writing a simple pass that inherits from ModulePass. I override the
runOnModule method. In the method, i am attempting to print all the function
in the module and the source-file they appear in. I could print the name of
the function using the Module::iterator. I am, however, not able to
figure-out the way to identify the source-file for a given "Function".

That information is generally only present if the file was compiled
with debug info ("clang -g"), and even then I believe it's only
attached to the instructions in a function rather than the function
itself. Inlining can complicate things further, so you need to pick
the *right* instruction (some may come from a different file
entirely).

Some grubbing around the class hierarchy suggests this procedure:
1. Find a "ret" instruction in the function (actually, a function can
rarely exist with "unreachable" instead of "ret" so be careful).
2. Call Instruction::getDebugLoc on it
3. Call DebugLoc::getAsMDNode to convert it into an MDNode
4. Create a DILocation from that MDNode and query it for your info.

There may be a simpler way, but hopefully that will do the job.

Cheers.

Tim.

This should work, but I think a more standard approach (though arguably slower) is to use DebugInfoFinder (from DebugInfo.h).

So create a DebugInfoFinder, process the module with it, and then iterate over all the subprograms to find the one matching your function. Roughly something like:

DebugInfoFinder Finder;
Finder.processModule(F->getParent());
for (DebugInfoFinder::iterator Iter = Finder.subprogram_begin(),
    End = Finder.subprogram_end(); Iter != End; ++Iter) {
  const MDNode* node = *Iter;
  DISubprogram SP(node);
  if (SP.describes(F)) return SP.getFilename();
}

Nice! Didn't know about that class.

Cheers.

Tim.