Получить имя файла и местоположение из функции
У меня есть проход 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) Однако во время выполнения он создает дамп ядра. Любые предложения, пожалуйста, как заставить его работать.