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*&)’
Каким будет правильный подход?
Ответы
Ответ 1
Учитывая 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
.
P.S. Обратите внимание, что cast
и dyn_cast
являются частью собственной реализации RTL для LLVM. dyn_cast
действует несколько аналогично стандарту С++ dynamic_cast
, хотя существуют различия в реализации и производительности (как может быть здесь).
Ответ 2
Ответ Eli велик, но ему не хватает финальной части, которая возвращает целое число. Полная картина должна выглядеть так:
if (ConstantInt* CI = dyn_cast<ConstantInt>(Val)) {
if (CI->getBitWidth() <= 32) {
constIntValue = CI->getSExtValue();
}
}
Конечно, вы также можете изменить его на <= 64
, если constIntValue
- это 64-разрядное целое число и т.д.
И как писал Эли, если вы уверены, что значение действительно имеет тип ConstInt
, вы можете использовать cast<ConstantInt>
вместо dyn_cast
.