从函数获取文件名和位置

Que*_*ayo 1 llvm llvm-clang clang++ llvm-3.0 llvm-ir

我有一个遍历 LLVM IR 代码的 LLVM 传递,我想为原始代码的函数和基本块获取一个目录和一个文件名。我知道当我有一个指令指针时,我可以使用下面的代码轻松获取信息:感谢@hailinzeng(如何从 LLVM 指令获取文件名和目录?

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();
}
Run Code Online (Sandbox Code Playgroud)

但是,由于类FunctionBasicBlock没有成员函数getDebugLoc(),这不起作用。我在这里看到了另一篇使用元数据的帖子但我不知道如何访问元数据DILocationDIScope从元数据获取。使用

MDNode *n = inst->getMetadata("dbg");
DILocation loc(n);   `
Run Code Online (Sandbox Code Playgroud)

给出以下错误

/usr/lib/llvm-3.9/include/llvm/IR/Metadata.def:83:42: 注意:'llvm::DILocation' 的前向声明 HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DILocation)

我正在使用 llvm 3.9。

更新 :: 感谢斯坦尼斯拉夫·潘克维奇。我没有包含正确的标题,但现在我有一个新问题。DILocation 需要 LLVMContext、StorageType 和 unsigned Line。如何从函数指针获取行号和存储类型? DILocation(LLVMContext &C, StorageType Storage, unsigned Line,

对于那些处理类似问题的人,您可以使用 LLVMContext

llvm::MDNode * testmd = F.getMetadata("dbg");
F.getContext ()
Run Code Online (Sandbox Code Playgroud)

小智 5

如果您查看代码的 .ll 文件,您会发现每个函数都有与之关联的 DINode,例如!<some_number>. 这是具有有关该功能的信息的元数据节点号。该节点的类型是DISubprogram你可以这样访问它:

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();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

您可以使用调试节点中的所有信息。