Подтвердить что ты не робот

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*&)’

Каким будет правильный подход?

4b9b3361

Ответ 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.