Получить имя файла и местоположение из функции

У меня есть проход LLVM, который перебирает ИК-код 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();
}

Тем не менее, так как класс Function а также BasicBlock не имеют функции-члена getDebugLoc()это не работает Я видел еще один пост здесь с использованием метаданных, но я не знаю, как добраться до DILocation или же DIScope из метаданных. С помощью

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

Выдает ошибку ниже

/usr/lib/llvm-3.9/include/llvm/IR/Metadata.def:83:42: note: предварительное объявление 'llvm::DILocation' HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DILocation)

Я использую llvm 3.9.

ОБНОВЛЕНИЕ:: Спасибо Станиславу Панкевичу. Я не включил правильные заголовки, но теперь у меня есть новая проблема. DILocation требует LLVMContext, StorageType и неподписанной строки. Как получить номер строки и тип хранилища из указателя функции? DILocation(LLVMContext &C, StorageType Storage, unsigned Line,

Для тех, кто работает с подобной проблемой, вы можете получить LLVMContext, используя

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

2 ответа

Решение

Если вы посмотрите на файл.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();
    }
  }
}

Вы можете использовать всю информацию, которая есть в отладочном узле.

Как насчет того, если нам нужны детали столбца, что невозможно с DISubprogram. Я пробовал это:

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

Файл sample.ll содержит следующие строки: !10 = !DILocation(строка: 1, столбец: 1, область: !1) Однако во время выполнения он создает дамп ядра. Любые предложения, пожалуйста, как заставить его работать.

Другие вопросы по тегам