1

I have an LLVM pass that iterates over LLVM IR code and I would like to get a directory and a filename for both the functions and basic blocks for the original code. I know that when I have an Instruction Pointer, I can easily get the information using the code below: Thanks to @hailinzeng (How to get the filename and directory from a LLVM Instruction?)

const llvm::DebugLoc &location = i_iter->getDebugLoc();

if (location && debugLocationInfoOn) {
  std::string dbgInfo;
  llvm::raw_string_ostream rso(dbgInfo);
  location.print(rso);
  std::cout << rso.str();
}

However, since the class Function and BasicBlock do not have a member function getDebugLoc(), this doesn't work. I saw another post here using the metadata but I do not know how to get to the DILocation or DIScope from the metadata. Using

MDNode *n = inst->getMetadata("dbg");
DILocation loc(n);   `

Gives the error below

/usr/lib/llvm-3.9/include/llvm/IR/Metadata.def:83:42: note: forward declaration of 'llvm::DILocation' HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DILocation)

I'm using llvm 3.9.

UPDATE :: Thanks Stanislav Pankevich. I wasn't including the right headers but now I have a new issue. DILocation requires LLVMContext, StorageType, and unsigned Line. How do I get the line number and and storage type from a function pointer? DILocation(LLVMContext &C, StorageType Storage, unsigned Line,

For those working with a similar issue, you can get LLVMContext using

llvm::MDNode * testmd = F.getMetadata("dbg");
F.getContext ()
Community
  • 1
  • 1
Quentin Mayo
  • 390
  • 4
  • 11
  • The `note: forward declaration ...` message indicates you are missing `#include "llvm/IR/DebugInfoMetadata.h"` and maybe `#include "llvm/IR/DebugInfo.h"` imports. See also this: http://stackoverflow.com/a/41715433/598057. – Stanislav Pankevich Apr 27 '17 at 11:59
  • Are you sure the approach from the linked topic is not working for you: `MDNode *metadata = function->getMetadata(0);`, then `DILocation *debugLocation = dyn_cast(metadata);`? – Stanislav Pankevich Apr 27 '17 at 13:39

2 Answers2

5

If you look at the .ll file for your code, you would see that every function has DINode associated with it, something like !<some_number>. That's the metadata node number that is has info about that function. The type of that node is DISubprogram You can access it like this:

SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
F.getAllMetadata(MDs);
for (auto &MD : MDs) {
  if (MDNode *N = MD.second) {
    if (auto *subProgram = dyn_cast<DISubprogram>(N)) {
      errs() << subProgram->getLine();
    }
  }
}

You can use all the information that is there in the debug node.

deLta
  • 561
  • 2
  • 12
0

How about if we want column details, which is not possible with DISubprogram. I tried this:

DILocation *debugLocation = dyn_cast<DILocation>(N);
debugLocation->getLine();

The sample.ll file does contain these lines: !10 = !DILocation(line: 1, column: 1, scope: !1) However, it gives core dumped at run time. Any suggestions please how to get it working.

NewUser
  • 41
  • 5