从Function获取文件名和位置

时间:2017-04-27 04:41:13

标签: llvm clang++ llvm-clang llvm-ir llvm-3.0

我有一个LLVM传递,它遍历LLVM IR代码,我想获得原始代码的函数和基本块的目录和文件名。我知道当我有一个指令指针时,我可以使用下面的代码轻松获取信息:感谢@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();
}

但是,由于课程FunctionBasicBlock没有成员函数getDebugLoc(),因此无效。我看到了另一篇使用元数据的帖子here,但我不知道如何从元数据中获取DILocationDIScope。使用

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

给出错误

  

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

我正在使用llvm 3.9。

更新:: 谢谢Stanislav Pankevich。我没有包括正确的标题,但现在我有一个新问题。 DILocation需要LLVMContext,StorageType和unsigned Line。如何从函数指针获取行号和存储类型?   DILocation(LLVMContext &C, StorageType Storage, unsigned Line,

对于处理类似问题的人,可以使用

获取LLVMContext
llvm::MDNode * testmd = F.getMetadata("dbg");
F.getContext ()

2 个答案:

答案 0 :(得分:4)

如果查看代码的.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();
    }
  }
}

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

答案 1 :(得分:0)

如果我们想要列详细信息,这在 DISubprogram 中是不可能的。 我试过这个:

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

sample.ll 文件确实包含以下几行: !10 = !DILocation(line: 1, column: 1, scope: !1) 但是,它会在运行时转储核心。任何建议请如何让它工作。