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