xref: /src/contrib/llvm-project/llvm/lib/Bitcode/Reader/ValueList.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad) !
1044eb2f6SDimitry Andric //===- ValueList.cpp - Internal BitcodeReader implementation --------------===//
2b915e9e0SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6b915e9e0SDimitry Andric //
7b915e9e0SDimitry Andric //===----------------------------------------------------------------------===//
8b915e9e0SDimitry Andric 
9b915e9e0SDimitry Andric #include "ValueList.h"
10044eb2f6SDimitry Andric #include "llvm/IR/Argument.h"
11044eb2f6SDimitry Andric #include "llvm/IR/Constant.h"
12b915e9e0SDimitry Andric #include "llvm/IR/Constants.h"
13044eb2f6SDimitry Andric #include "llvm/IR/GlobalValue.h"
14044eb2f6SDimitry Andric #include "llvm/IR/Instruction.h"
15044eb2f6SDimitry Andric #include "llvm/IR/Type.h"
16044eb2f6SDimitry Andric #include "llvm/IR/User.h"
17044eb2f6SDimitry Andric #include "llvm/IR/Value.h"
18044eb2f6SDimitry Andric #include "llvm/Support/Casting.h"
19145449b1SDimitry Andric #include "llvm/Support/Error.h"
20044eb2f6SDimitry Andric #include "llvm/Support/ErrorHandling.h"
21044eb2f6SDimitry Andric #include <cstddef>
22b915e9e0SDimitry Andric 
23b915e9e0SDimitry Andric using namespace llvm;
24b915e9e0SDimitry Andric 
assignValue(unsigned Idx,Value * V,unsigned TypeID)25145449b1SDimitry Andric Error BitcodeReaderValueList::assignValue(unsigned Idx, Value *V,
26145449b1SDimitry Andric                                           unsigned TypeID) {
27b915e9e0SDimitry Andric   if (Idx == size()) {
28145449b1SDimitry Andric     push_back(V, TypeID);
29145449b1SDimitry Andric     return Error::success();
30b915e9e0SDimitry Andric   }
31b915e9e0SDimitry Andric 
32b915e9e0SDimitry Andric   if (Idx >= size())
33b915e9e0SDimitry Andric     resize(Idx + 1);
34b915e9e0SDimitry Andric 
35145449b1SDimitry Andric   auto &Old = ValuePtrs[Idx];
36145449b1SDimitry Andric   if (!Old.first) {
37145449b1SDimitry Andric     Old.first = V;
38145449b1SDimitry Andric     Old.second = TypeID;
39145449b1SDimitry Andric     return Error::success();
40b915e9e0SDimitry Andric   }
41b915e9e0SDimitry Andric 
42145449b1SDimitry Andric   assert(!isa<Constant>(&*Old.first) && "Shouldn't update constant");
43b915e9e0SDimitry Andric   // If there was a forward reference to this value, replace it.
44145449b1SDimitry Andric   Value *PrevVal = Old.first;
45145449b1SDimitry Andric   if (PrevVal->getType() != V->getType())
46145449b1SDimitry Andric     return createStringError(
47145449b1SDimitry Andric         std::errc::illegal_byte_sequence,
48145449b1SDimitry Andric         "Assigned value does not match type of forward declaration");
49145449b1SDimitry Andric   Old.first->replaceAllUsesWith(V);
50b5630dbaSDimitry Andric   PrevVal->deleteValue();
51145449b1SDimitry Andric   return Error::success();
52b915e9e0SDimitry Andric }
53b915e9e0SDimitry Andric 
getValueFwdRef(unsigned Idx,Type * Ty,unsigned TyID,BasicBlock * ConstExprInsertBB)54145449b1SDimitry Andric Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty,
55145449b1SDimitry Andric                                               unsigned TyID,
56145449b1SDimitry Andric                                               BasicBlock *ConstExprInsertBB) {
57e6d15924SDimitry Andric   // Bail out for a clearly invalid value.
58e6d15924SDimitry Andric   if (Idx >= RefsUpperBound)
59e6d15924SDimitry Andric     return nullptr;
60e6d15924SDimitry Andric 
61b915e9e0SDimitry Andric   if (Idx >= size())
62b915e9e0SDimitry Andric     resize(Idx + 1);
63b915e9e0SDimitry Andric 
64145449b1SDimitry Andric   if (Value *V = ValuePtrs[Idx].first) {
65b915e9e0SDimitry Andric     // If the types don't match, it's invalid.
66b915e9e0SDimitry Andric     if (Ty && Ty != V->getType())
67b915e9e0SDimitry Andric       return nullptr;
68145449b1SDimitry Andric 
69145449b1SDimitry Andric     Expected<Value *> MaybeV = MaterializeValueFn(Idx, ConstExprInsertBB);
70145449b1SDimitry Andric     if (!MaybeV) {
71145449b1SDimitry Andric       // TODO: We might want to propagate the precise error message here.
72145449b1SDimitry Andric       consumeError(MaybeV.takeError());
73145449b1SDimitry Andric       return nullptr;
74145449b1SDimitry Andric     }
75145449b1SDimitry Andric     return MaybeV.get();
76b915e9e0SDimitry Andric   }
77b915e9e0SDimitry Andric 
78b915e9e0SDimitry Andric   // No type specified, must be invalid reference.
79b915e9e0SDimitry Andric   if (!Ty)
80b915e9e0SDimitry Andric     return nullptr;
81b915e9e0SDimitry Andric 
82b915e9e0SDimitry Andric   // Create and return a placeholder, which will later be RAUW'd.
83b915e9e0SDimitry Andric   Value *V = new Argument(Ty);
84145449b1SDimitry Andric   ValuePtrs[Idx] = {V, TyID};
85b915e9e0SDimitry Andric   return V;
86b915e9e0SDimitry Andric }
87