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
23using namespace llvm;
24
25Error 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
54Value *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