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
19using namespace llvm;
20
21Error 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(N: 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 EC: std::errc::illegal_byte_sequence,
44 Fmt: "Assigned value does not match type of forward declaration");
45 Old.first->replaceAllUsesWith(V);
46 PrevVal->deleteValue();
47 return Error::success();
48}
49
50Value *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(N: 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(Err: 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