xref: /freebsd/contrib/llvm-project/llvm/lib/Bitcode/Reader/ValueList.cpp (revision 770cf0a5f02dc8983a89c6568d741fbc25baa999)
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/GlobalValue.h"
13 #include "llvm/IR/Instruction.h"
14 #include "llvm/IR/Type.h"
15 #include "llvm/IR/Value.h"
16 #include "llvm/Support/Casting.h"
17 #include "llvm/Support/Error.h"
18 
19 using namespace llvm;
20 
21 Error BitcodeReaderValueList::assignValue(unsigned Idx, Value *V,
22                                           unsigned TypeID) {
23   if (Idx == size()) {
24     push_back(V, TypeID);
25     return Error::success();
26   }
27 
28   if (Idx >= size())
29     resize(Idx + 1);
30 
31   auto &Old = ValuePtrs[Idx];
32   if (!Old.first) {
33     Old.first = V;
34     Old.second = TypeID;
35     return Error::success();
36   }
37 
38   assert(!isa<Constant>(&*Old.first) && "Shouldn't update constant");
39   // If there was a forward reference to this value, replace it.
40   Value *PrevVal = Old.first;
41   if (PrevVal->getType() != V->getType())
42     return createStringError(
43         std::errc::illegal_byte_sequence,
44         "Assigned value does not match type of forward declaration");
45   Old.first->replaceAllUsesWith(V);
46   PrevVal->deleteValue();
47   return Error::success();
48 }
49 
50 Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty,
51                                               unsigned TyID,
52                                               BasicBlock *ConstExprInsertBB) {
53   // Bail out for a clearly invalid value.
54   if (Idx >= RefsUpperBound)
55     return nullptr;
56 
57   if (Idx >= size())
58     resize(Idx + 1);
59 
60   if (Value *V = ValuePtrs[Idx].first) {
61     // If the types don't match, it's invalid.
62     if (Ty && Ty != V->getType())
63       return nullptr;
64 
65     Expected<Value *> MaybeV = MaterializeValueFn(Idx, ConstExprInsertBB);
66     if (!MaybeV) {
67       // TODO: We might want to propagate the precise error message here.
68       consumeError(MaybeV.takeError());
69       return nullptr;
70     }
71     return MaybeV.get();
72   }
73 
74   // No type specified, must be invalid reference.
75   if (!Ty)
76     return nullptr;
77 
78   // Create and return a placeholder, which will later be RAUW'd.
79   Value *V = new Argument(Ty);
80   ValuePtrs[Idx] = {V, TyID};
81   return V;
82 }
83