1*0b57cec5SDimitry Andric //===- ValueList.cpp - Internal BitcodeReader implementation --------------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric 
9*0b57cec5SDimitry Andric #include "ValueList.h"
10*0b57cec5SDimitry Andric #include "llvm/IR/Argument.h"
11*0b57cec5SDimitry Andric #include "llvm/IR/Constant.h"
12*0b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
13*0b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h"
14*0b57cec5SDimitry Andric #include "llvm/IR/Instruction.h"
15*0b57cec5SDimitry Andric #include "llvm/IR/Type.h"
16*0b57cec5SDimitry Andric #include "llvm/IR/User.h"
17*0b57cec5SDimitry Andric #include "llvm/IR/Value.h"
18*0b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
1981ad6265SDimitry Andric #include "llvm/Support/Error.h"
20*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
21*0b57cec5SDimitry Andric #include <cstddef>
22*0b57cec5SDimitry Andric 
23*0b57cec5SDimitry Andric using namespace llvm;
24*0b57cec5SDimitry Andric 
assignValue(unsigned Idx,Value * V,unsigned TypeID)2581ad6265SDimitry Andric Error BitcodeReaderValueList::assignValue(unsigned Idx, Value *V,
2681ad6265SDimitry Andric                                           unsigned TypeID) {
27*0b57cec5SDimitry Andric   if (Idx == size()) {
2881ad6265SDimitry Andric     push_back(V, TypeID);
2981ad6265SDimitry Andric     return Error::success();
30*0b57cec5SDimitry Andric   }
31*0b57cec5SDimitry Andric 
32*0b57cec5SDimitry Andric   if (Idx >= size())
33*0b57cec5SDimitry Andric     resize(Idx + 1);
34*0b57cec5SDimitry Andric 
3581ad6265SDimitry Andric   auto &Old = ValuePtrs[Idx];
3681ad6265SDimitry Andric   if (!Old.first) {
3781ad6265SDimitry Andric     Old.first = V;
3881ad6265SDimitry Andric     Old.second = TypeID;
3981ad6265SDimitry Andric     return Error::success();
40*0b57cec5SDimitry Andric   }
41*0b57cec5SDimitry Andric 
4281ad6265SDimitry Andric   assert(!isa<Constant>(&*Old.first) && "Shouldn't update constant");
43*0b57cec5SDimitry Andric   // If there was a forward reference to this value, replace it.
4481ad6265SDimitry Andric   Value *PrevVal = Old.first;
4581ad6265SDimitry Andric   if (PrevVal->getType() != V->getType())
4681ad6265SDimitry Andric     return createStringError(
4781ad6265SDimitry Andric         std::errc::illegal_byte_sequence,
4881ad6265SDimitry Andric         "Assigned value does not match type of forward declaration");
4981ad6265SDimitry Andric   Old.first->replaceAllUsesWith(V);
50*0b57cec5SDimitry Andric   PrevVal->deleteValue();
5181ad6265SDimitry Andric   return Error::success();
52*0b57cec5SDimitry Andric }
53*0b57cec5SDimitry Andric 
getValueFwdRef(unsigned Idx,Type * Ty,unsigned TyID,BasicBlock * ConstExprInsertBB)5481ad6265SDimitry Andric Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty,
5581ad6265SDimitry Andric                                               unsigned TyID,
5681ad6265SDimitry Andric                                               BasicBlock *ConstExprInsertBB) {
57*0b57cec5SDimitry Andric   // Bail out for a clearly invalid value.
58*0b57cec5SDimitry Andric   if (Idx >= RefsUpperBound)
59*0b57cec5SDimitry Andric     return nullptr;
60*0b57cec5SDimitry Andric 
61*0b57cec5SDimitry Andric   if (Idx >= size())
62*0b57cec5SDimitry Andric     resize(Idx + 1);
63*0b57cec5SDimitry Andric 
6481ad6265SDimitry Andric   if (Value *V = ValuePtrs[Idx].first) {
65*0b57cec5SDimitry Andric     // If the types don't match, it's invalid.
66*0b57cec5SDimitry Andric     if (Ty && Ty != V->getType())
67*0b57cec5SDimitry Andric       return nullptr;
6881ad6265SDimitry Andric 
6981ad6265SDimitry Andric     Expected<Value *> MaybeV = MaterializeValueFn(Idx, ConstExprInsertBB);
7081ad6265SDimitry Andric     if (!MaybeV) {
7181ad6265SDimitry Andric       // TODO: We might want to propagate the precise error message here.
7281ad6265SDimitry Andric       consumeError(MaybeV.takeError());
7381ad6265SDimitry Andric       return nullptr;
7481ad6265SDimitry Andric     }
7581ad6265SDimitry Andric     return MaybeV.get();
76*0b57cec5SDimitry Andric   }
77*0b57cec5SDimitry Andric 
78*0b57cec5SDimitry Andric   // No type specified, must be invalid reference.
79*0b57cec5SDimitry Andric   if (!Ty)
80*0b57cec5SDimitry Andric     return nullptr;
81*0b57cec5SDimitry Andric 
82*0b57cec5SDimitry Andric   // Create and return a placeholder, which will later be RAUW'd.
83*0b57cec5SDimitry Andric   Value *V = new Argument(Ty);
8481ad6265SDimitry Andric   ValuePtrs[Idx] = {V, TyID};
85*0b57cec5SDimitry Andric   return V;
86*0b57cec5SDimitry Andric }
87