xref: /freebsd-src/contrib/llvm-project/llvm/lib/Bitcode/Reader/ValueList.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
10b57cec5SDimitry Andric //===- ValueList.cpp - Internal BitcodeReader implementation --------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "ValueList.h"
100b57cec5SDimitry Andric #include "llvm/IR/Argument.h"
110b57cec5SDimitry Andric #include "llvm/IR/Constant.h"
120b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
130b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h"
140b57cec5SDimitry Andric #include "llvm/IR/Instruction.h"
150b57cec5SDimitry Andric #include "llvm/IR/Type.h"
160b57cec5SDimitry Andric #include "llvm/IR/User.h"
170b57cec5SDimitry Andric #include "llvm/IR/Value.h"
180b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
19*81ad6265SDimitry Andric #include "llvm/Support/Error.h"
200b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
210b57cec5SDimitry Andric #include <cstddef>
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric using namespace llvm;
240b57cec5SDimitry Andric 
assignValue(unsigned Idx,Value * V,unsigned TypeID)25*81ad6265SDimitry Andric Error BitcodeReaderValueList::assignValue(unsigned Idx, Value *V,
26*81ad6265SDimitry Andric                                           unsigned TypeID) {
270b57cec5SDimitry Andric   if (Idx == size()) {
28*81ad6265SDimitry Andric     push_back(V, TypeID);
29*81ad6265SDimitry Andric     return Error::success();
300b57cec5SDimitry Andric   }
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric   if (Idx >= size())
330b57cec5SDimitry Andric     resize(Idx + 1);
340b57cec5SDimitry Andric 
35*81ad6265SDimitry Andric   auto &Old = ValuePtrs[Idx];
36*81ad6265SDimitry Andric   if (!Old.first) {
37*81ad6265SDimitry Andric     Old.first = V;
38*81ad6265SDimitry Andric     Old.second = TypeID;
39*81ad6265SDimitry Andric     return Error::success();
400b57cec5SDimitry Andric   }
410b57cec5SDimitry Andric 
42*81ad6265SDimitry Andric   assert(!isa<Constant>(&*Old.first) && "Shouldn't update constant");
430b57cec5SDimitry Andric   // If there was a forward reference to this value, replace it.
44*81ad6265SDimitry Andric   Value *PrevVal = Old.first;
45*81ad6265SDimitry Andric   if (PrevVal->getType() != V->getType())
46*81ad6265SDimitry Andric     return createStringError(
47*81ad6265SDimitry Andric         std::errc::illegal_byte_sequence,
48*81ad6265SDimitry Andric         "Assigned value does not match type of forward declaration");
49*81ad6265SDimitry Andric   Old.first->replaceAllUsesWith(V);
500b57cec5SDimitry Andric   PrevVal->deleteValue();
51*81ad6265SDimitry Andric   return Error::success();
520b57cec5SDimitry Andric }
530b57cec5SDimitry Andric 
getValueFwdRef(unsigned Idx,Type * Ty,unsigned TyID,BasicBlock * ConstExprInsertBB)54*81ad6265SDimitry Andric Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty,
55*81ad6265SDimitry Andric                                               unsigned TyID,
56*81ad6265SDimitry Andric                                               BasicBlock *ConstExprInsertBB) {
570b57cec5SDimitry Andric   // Bail out for a clearly invalid value.
580b57cec5SDimitry Andric   if (Idx >= RefsUpperBound)
590b57cec5SDimitry Andric     return nullptr;
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric   if (Idx >= size())
620b57cec5SDimitry Andric     resize(Idx + 1);
630b57cec5SDimitry Andric 
64*81ad6265SDimitry Andric   if (Value *V = ValuePtrs[Idx].first) {
650b57cec5SDimitry Andric     // If the types don't match, it's invalid.
660b57cec5SDimitry Andric     if (Ty && Ty != V->getType())
670b57cec5SDimitry Andric       return nullptr;
68*81ad6265SDimitry Andric 
69*81ad6265SDimitry Andric     Expected<Value *> MaybeV = MaterializeValueFn(Idx, ConstExprInsertBB);
70*81ad6265SDimitry Andric     if (!MaybeV) {
71*81ad6265SDimitry Andric       // TODO: We might want to propagate the precise error message here.
72*81ad6265SDimitry Andric       consumeError(MaybeV.takeError());
73*81ad6265SDimitry Andric       return nullptr;
74*81ad6265SDimitry Andric     }
75*81ad6265SDimitry Andric     return MaybeV.get();
760b57cec5SDimitry Andric   }
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric   // No type specified, must be invalid reference.
790b57cec5SDimitry Andric   if (!Ty)
800b57cec5SDimitry Andric     return nullptr;
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   // Create and return a placeholder, which will later be RAUW'd.
830b57cec5SDimitry Andric   Value *V = new Argument(Ty);
84*81ad6265SDimitry Andric   ValuePtrs[Idx] = {V, TyID};
850b57cec5SDimitry Andric   return V;
860b57cec5SDimitry Andric }
87