Вы, похоже, следуете этому учебнику .В вашем вопросе отсутствует какой-то ценный контекст, который я воспроизвожу ниже:
Например, следующий код использует API LLVM для создания инструкции alloca для хранения целых чисел (тип LLVM i32) в стеке.Это пространство хранения используется для хранения значений и для загрузки значений из областей памяти в стеке.
llvm::AllocaInst *Alloca;
// unlike CreateEntryBlockAlloca the following will
// create the alloca instr at the current insertion point
// rather than at the start of the block
Alloca = llvm::Builder.CreateAlloca(llvm::IntegerType::get(getGlobalContext(), 32), nullptr, "variable_name");
Затем следует сохранить этот указатель в таблице символов для идентификатора NAME.Вы можете получить доступ к указателю на тип TYPE, используя Alloca->getType()
, когда хотите присвоить значение этому местоположению.
Так что Alloca->getType()
предоставляет вам объект PointerType, представляющий "указатель на i32
, "в частности указатель на место в стеке, которое было выделено для i32
.Но rvalue
- это i32
, а не указатель на i32
.Тем не менее, мы все равно можем использовать Alloca->getType()
для сравнения типа lvalue
(i32
) с чем-то, а именно с типом rvalue
:
Чтобы присвоить значение вОператор без кофеина типа lvalue = rvalue
, вы должны получить местоположение lvalue
из таблицы символов.Вы можете проверить тип rvalue
, используя следующий вызов API:
const llvm::PointerType *ptrTy = rvalue->getType()->getPointerTo();
Сначала мы получим тип rvalue
.Мы не можем сравнивать его напрямую с типом lvalue
, потому что у нас есть только тип «указатель на тип lvalue
».Поэтому нам нужно преобразовать объект типа, полученный из rvalue
, в «указатель на тип rvalue
», то есть преобразовать его из i32
в *i32
.
InДругими словами, как мы можем проверить, что rvalue
имеет тип i32
, если все, с чем мы должны сравнивать его, это тип *i32
?Ответ таков: мы просто переводим тип rvalue
в тип указателя, то есть берем его i32
и делаем его указателем *i32
.
В этот момент ptrTy
содержит указатель типа "указатель"для типа rvalue
", в то время как мы также знаем, что Alloca->getType()
дает нам тип" указатель на тип lvalue
. "Чтобы назначить rvalue
для lvalue
, мы проверяем, что эти два типа совпадают:
И проверяем, что тип расположения Alloca для lvalue имеет тот же тип:
ptrTy == Alloca->getType()
Вышеприведенное выражение является условным;это верно, если типы одинаковы, и ложь в противном случае.Предполагая, что это правда, вы присваиваете значения следующим образом:
llvm::Value *val = Builder.CreateStore(rvalue, Alloca)