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