1 //===- ValueList.cpp - Internal BitcodeReader implementation --------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "ValueList.h"
10 #include "llvm/IR/Argument.h"
11 #include "llvm/IR/Constant.h"
12 #include "llvm/IR/Constants.h"
13 #include "llvm/IR/GlobalValue.h"
14 #include "llvm/IR/Instruction.h"
15 #include "llvm/IR/Type.h"
16 #include "llvm/IR/User.h"
17 #include "llvm/IR/Value.h"
18 #include "llvm/Support/Casting.h"
19 #include "llvm/Support/Error.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include <cstddef>
22 
23 using namespace llvm;
24 
assignValue(unsigned Idx,Value * V,unsigned TypeID)25 Error BitcodeReaderValueList::assignValue(unsigned Idx, Value *V,
26                                           unsigned TypeID) {
27   if (Idx == size()) {
28     push_back(V, TypeID);
29     return Error::success();
30   }
31 
32   if (Idx >= size())
33     resize(Idx + 1);
34 
35   auto &Old = ValuePtrs[Idx];
36   if (!Old.first) {
37     Old.first = V;
38     Old.second = TypeID;
39     return Error::success();
40   }
41 
42   assert(!isa<Constant>(&*Old.first) && "Shouldn't update constant");
43   // If there was a forward reference to this value, replace it.
44   Value *PrevVal = Old.first;
45   if (PrevVal->getType() != V->getType())
46     return createStringError(
47         std::errc::illegal_byte_sequence,
48         "Assigned value does not match type of forward declaration");
49   Old.first->replaceAllUsesWith(V);
50   PrevVal->deleteValue();
51   return Error::success();
52 }
53 
getValueFwdRef(unsigned Idx,Type * Ty,unsigned TyID,BasicBlock * ConstExprInsertBB)54 Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty,
55                                               unsigned TyID,
56                                               BasicBlock *ConstExprInsertBB) {
57   // Bail out for a clearly invalid value.
58   if (Idx >= RefsUpperBound)
59     return nullptr;
60 
61   if (Idx >= size())
62     resize(Idx + 1);
63 
64   if (Value *V = ValuePtrs[Idx].first) {
65     // If the types don't match, it's invalid.
66     if (Ty && Ty != V->getType())
67       return nullptr;
68 
69     Expected<Value *> MaybeV = MaterializeValueFn(Idx, ConstExprInsertBB);
70     if (!MaybeV) {
71       // TODO: We might want to propagate the precise error message here.
72       consumeError(MaybeV.takeError());
73       return nullptr;
74     }
75     return MaybeV.get();
76   }
77 
78   // No type specified, must be invalid reference.
79   if (!Ty)
80     return nullptr;
81 
82   // Create and return a placeholder, which will later be RAUW'd.
83   Value *V = new Argument(Ty);
84   ValuePtrs[Idx] = {V, TyID};
85   return V;
86 }
87