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