aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp78
1 files changed, 58 insertions, 20 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 26eee99..624533b 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -483,7 +483,10 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
std::vector<std::string> SectionTable;
std::vector<std::string> GCTable;
- std::vector<Type*> TypeList;
+ std::vector<Type *> TypeList;
+ /// Stores pointer element type for a given type ID. This is used during
+ /// upgrades of typed pointer IR in opaque pointer mode.
+ std::vector<Type *> ElementTypeList;
DenseMap<Function *, FunctionType *> FunctionTypes;
BitcodeReaderValueList ValueList;
Optional<MetadataLoader> MDLoader;
@@ -591,6 +594,7 @@ private:
StructType *createIdentifiedStructType(LLVMContext &Context);
Type *getTypeByID(unsigned ID);
+ Type *getElementTypeByID(unsigned ID);
Value *getFnValueByID(unsigned ID, Type *Ty) {
if (Ty && Ty->isMetadataTy())
@@ -1176,6 +1180,23 @@ Type *BitcodeReader::getTypeByID(unsigned ID) {
return TypeList[ID] = createIdentifiedStructType(Context);
}
+Type *BitcodeReader::getElementTypeByID(unsigned ID) {
+ if (ID >= TypeList.size())
+ return nullptr;
+
+ Type *Ty = TypeList[ID];
+ if (!Ty->isPointerTy())
+ return nullptr;
+
+ Type *ElemTy = ElementTypeList[ID];
+ if (!ElemTy)
+ return nullptr;
+
+ assert(cast<PointerType>(Ty)->isOpaqueOrPointeeTypeMatches(ElemTy) &&
+ "Incorrect element type");
+ return ElemTy;
+}
+
StructType *BitcodeReader::createIdentifiedStructType(LLVMContext &Context,
StringRef Name) {
auto *Ret = StructType::create(Context, Name);
@@ -1708,6 +1729,7 @@ Error BitcodeReader::parseTypeTableBody() {
// Read a record.
Record.clear();
Type *ResultTy = nullptr;
+ Type *ElemTy = nullptr;
Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record);
if (!MaybeRecord)
return MaybeRecord.takeError();
@@ -1720,6 +1742,7 @@ Error BitcodeReader::parseTypeTableBody() {
if (Record.empty())
return error("Invalid record");
TypeList.resize(Record[0]);
+ ElementTypeList.resize(Record[0]);
continue;
case bitc::TYPE_CODE_VOID: // VOID
ResultTy = Type::getVoidTy(Context);
@@ -1782,6 +1805,7 @@ Error BitcodeReader::parseTypeTableBody() {
if (!ResultTy ||
!PointerType::isValidElementType(ResultTy))
return error("Invalid type");
+ ElemTy = ResultTy;
ResultTy = PointerType::get(ResultTy, AddressSpace);
break;
}
@@ -1932,7 +1956,9 @@ Error BitcodeReader::parseTypeTableBody() {
return error(
"Invalid TYPE table: Only named structs can be forward referenced");
assert(ResultTy && "Didn't read a type?");
- TypeList[NumRecords++] = ResultTy;
+ TypeList[NumRecords] = ResultTy;
+ ElementTypeList[NumRecords] = ElemTy;
+ ++NumRecords;
}
}
@@ -2348,6 +2374,7 @@ Error BitcodeReader::parseConstants() {
// Read all the records for this value table.
Type *CurTy = Type::getInt32Ty(Context);
+ Type *CurElemTy = nullptr;
unsigned NextCstNo = ValueList.size();
struct DelayedShufTy {
@@ -2459,6 +2486,7 @@ Error BitcodeReader::parseConstants() {
if (TypeList[Record[0]] == VoidType)
return error("Invalid constant type");
CurTy = TypeList[Record[0]];
+ CurElemTy = getElementTypeByID(Record[0]);
continue; // Skip the ValueList manipulation.
case bitc::CST_CODE_NULL: // NULL
if (CurTy->isVoidTy() || CurTy->isFunctionTy() || CurTy->isLabelTy())
@@ -2831,9 +2859,10 @@ Error BitcodeReader::parseConstants() {
for (unsigned i = 0; i != ConstStrSize; ++i)
ConstrStr += (char)Record[3+AsmStrSize+i];
UpgradeInlineAsmString(&AsmStr);
- // FIXME: support upgrading in opaque pointers mode.
- V = InlineAsm::get(cast<FunctionType>(CurTy->getPointerElementType()),
- AsmStr, ConstrStr, HasSideEffects, IsAlignStack);
+ if (!CurElemTy)
+ return error("Missing element type for old-style inlineasm");
+ V = InlineAsm::get(cast<FunctionType>(CurElemTy), AsmStr, ConstrStr,
+ HasSideEffects, IsAlignStack);
break;
}
// This version adds support for the asm dialect keywords (e.g.,
@@ -2857,9 +2886,10 @@ Error BitcodeReader::parseConstants() {
for (unsigned i = 0; i != ConstStrSize; ++i)
ConstrStr += (char)Record[3+AsmStrSize+i];
UpgradeInlineAsmString(&AsmStr);
- // FIXME: support upgrading in opaque pointers mode.
- V = InlineAsm::get(cast<FunctionType>(CurTy->getPointerElementType()),
- AsmStr, ConstrStr, HasSideEffects, IsAlignStack,
+ if (!CurElemTy)
+ return error("Missing element type for old-style inlineasm");
+ V = InlineAsm::get(cast<FunctionType>(CurElemTy), AsmStr, ConstrStr,
+ HasSideEffects, IsAlignStack,
InlineAsm::AsmDialect(AsmDialect));
break;
}
@@ -2888,9 +2918,10 @@ Error BitcodeReader::parseConstants() {
for (unsigned i = 0; i != ConstStrSize; ++i)
ConstrStr += (char)Record[OpNum + AsmStrSize + i];
UpgradeInlineAsmString(&AsmStr);
- // FIXME: support upgrading in opaque pointers mode.
- V = InlineAsm::get(cast<FunctionType>(CurTy->getPointerElementType()),
- AsmStr, ConstrStr, HasSideEffects, IsAlignStack,
+ if (!CurElemTy)
+ return error("Missing element type for old-style inlineasm");
+ V = InlineAsm::get(cast<FunctionType>(CurElemTy), AsmStr, ConstrStr,
+ HasSideEffects, IsAlignStack,
InlineAsm::AsmDialect(AsmDialect), CanThrow);
break;
}
@@ -3288,7 +3319,9 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) {
if (!Ty->isPointerTy())
return error("Invalid type for value");
AddressSpace = cast<PointerType>(Ty)->getAddressSpace();
- Ty = Ty->getPointerElementType();
+ Ty = getElementTypeByID(Record[0]);
+ if (!Ty)
+ return error("Missing element type for old-style global");
}
uint64_t RawLinkage = Record[3];
@@ -3380,8 +3413,11 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) {
Type *FTy = getTypeByID(Record[0]);
if (!FTy)
return error("Invalid record");
- if (auto *PTy = dyn_cast<PointerType>(FTy))
- FTy = PTy->getPointerElementType();
+ if (isa<PointerType>(FTy)) {
+ FTy = getElementTypeByID(Record[0]);
+ if (!FTy)
+ return error("Missing element type for old-style function");
+ }
if (!isa<FunctionType>(FTy))
return error("Invalid type for value");
@@ -3536,7 +3572,8 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord(
if (Record.size() < (3 + (unsigned)NewRecord))
return error("Invalid record");
unsigned OpNum = 0;
- Type *Ty = getTypeByID(Record[OpNum++]);
+ unsigned TypeID = Record[OpNum++];
+ Type *Ty = getTypeByID(TypeID);
if (!Ty)
return error("Invalid record");
@@ -3545,8 +3582,10 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord(
auto *PTy = dyn_cast<PointerType>(Ty);
if (!PTy)
return error("Invalid type for value");
- Ty = PTy->getPointerElementType();
AddrSpace = PTy->getAddressSpace();
+ Ty = getElementTypeByID(TypeID);
+ if (!Ty)
+ return error("Missing element type for old-style indirect symbol");
} else {
AddrSpace = Record[OpNum++];
}
@@ -5005,10 +5044,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
const bool SwiftError = Bitfield::get<APV::SwiftError>(Rec);
Type *Ty = getTypeByID(Record[0]);
if (!Bitfield::get<APV::ExplicitType>(Rec)) {
- auto *PTy = dyn_cast_or_null<PointerType>(Ty);
- if (!PTy)
- return error("Old-style alloca with a non-pointer type");
- Ty = PTy->getPointerElementType();
+ Ty = getElementTypeByID(Record[0]);
+ if (!Ty)
+ return error("Missing element type for old-style alloca");
}
Type *OpTy = getTypeByID(Record[1]);
Value *Size = getFnValueByID(Record[2], OpTy);