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();
}
Другие вопросы по тегам