LLVM возвращает постоянное целое число из значения *
Я создаю llvm::Value* из целочисленной константы следующим образом:
llvm::Value* constValue = llvm::ConstantInt::get( llvmContext , llvm::APInt( node->someInt() ));
теперь я хочу получить значение константы во время компиляции обратно;
int constIntValue = constValue->???
Примеры, показанные в руководстве по программированию LLVM, предполагают, что cast<> будет принимать указатель при использовании параметра шаблона типа (а не указателя типа плюс), однако я почти уверен, что это не с версии 2.8:
llvm::Value* foo = 0;
llvm::ConstantInt* intValue = & llvm::cast< llvm::ConstantInt , llvm::Value >(foo );
//build error:
//error: no matching function for call to ‘cast(llvm::Value*&)’
Каков будет правильный подход здесь?
3 ответа
Дано llvm::Value* foo
И ты знаешь это foo
на самом деле ConstantInt
, Я считаю, что идиоматический подход кода LLVM заключается в использовании dyn_cast
следующее:
if (llvm::ConstantInt* CI = dyn_cast<llvm::ConstantInt>(foo)) {
// foo indeed is a ConstantInt, we can use CI here
}
else {
// foo was not actually a ConstantInt
}
Если вы абсолютно уверены, что foo
это ConstantInt
и готовы получить сбой утверждения, если это не так, вы можете использовать cast
вместо dyn_cast
,
PS Обратите внимание, что cast
а также dyn_cast
являются частью собственной реализации RTTI в LLVM. dyn_cast
действует несколько аналогично стандартному C++ dynamic_cast
Хотя есть различия в реализации и производительности (как можно прочитать здесь).
Ответ Эли великолепен, но в нем отсутствует последняя часть, которая возвращает целое число. Полная картина должна выглядеть так:
if (ConstantInt* CI = dyn_cast<ConstantInt>(Val)) {
if (CI->getBitWidth() <= 32) {
constIntValue = CI->getSExtValue();
}
}
Конечно, вы также можете изменить его на <= 64
если constIntValue
64-разрядное целое число и т. д.
И как писал Илай, если вы уверены, что значение действительно имеет тип ConstInt
, ты можешь использовать cast<ConstantInt>
вместо dyn_cast
,
Другие ответы работают, если константа является переменной в текущем файле.
Однако, если константная переменная является глобальной переменной, определенной в другом файле, на который ссылается текущий файл через extern. В этом случае переменная в текущем файле является
Constant *c;
if (isa<GlobalValue>(c)) {
GlobalValue *gvalue = dyn_cast<GlobalValue>(c);
GlobalVariable *gv = dyn_cast<GlobalVariable>(gvalue);
ConstantInt *ci = dyn_cast<ConstantInt>(gv->getInitializer());
errs() << ci->getValue();
}