diff options
Diffstat (limited to 'lib/Bytecode/Reader')
-rw-r--r-- | lib/Bytecode/Reader/ConstantReader.cpp | 15 | ||||
-rw-r--r-- | lib/Bytecode/Reader/InstructionReader.cpp | 33 | ||||
-rw-r--r-- | lib/Bytecode/Reader/Reader.cpp | 11 | ||||
-rw-r--r-- | lib/Bytecode/Reader/ReaderInternals.h | 7 |
4 files changed, 59 insertions, 7 deletions
diff --git a/lib/Bytecode/Reader/ConstantReader.cpp b/lib/Bytecode/Reader/ConstantReader.cpp index b4a219df6b..8691b26544 100644 --- a/lib/Bytecode/Reader/ConstantReader.cpp +++ b/lib/Bytecode/Reader/ConstantReader.cpp @@ -15,6 +15,7 @@ #include "ReaderInternals.h" #include "llvm/Module.h" #include "llvm/Constants.h" +#include "llvm/Support/GetElementPtrTypeIterator.h" #include <algorithm> using namespace llvm; @@ -164,6 +165,20 @@ Constant *BytecodeParser::parseConstantValue(const unsigned char *&Buf, return ConstantExpr::getCast(ArgVec[0], getType(TypeID)); } else if (Opcode == Instruction::GetElementPtr) { // GetElementPtr std::vector<Constant*> IdxList(ArgVec.begin()+1, ArgVec.end()); + + if (hasRestrictedGEPTypes) { + const Type *BaseTy = ArgVec[0]->getType(); + generic_gep_type_iterator<std::vector<Constant*>::iterator> + GTI = gep_type_begin(BaseTy, IdxList.begin(), IdxList.end()), + E = gep_type_end(BaseTy, IdxList.begin(), IdxList.end()); + for (unsigned i = 0; GTI != E; ++GTI, ++i) + if (isa<StructType>(*GTI)) { + if (IdxList[i]->getType() != Type::UByteTy) + throw std::string("Invalid index for getelementptr!"); + IdxList[i] = ConstantExpr::getCast(IdxList[i], Type::UIntTy); + } + } + return ConstantExpr::getGetElementPtr(ArgVec[0], IdxList); } else if (Opcode == Instruction::Select) { assert(ArgVec.size() == 3); diff --git a/lib/Bytecode/Reader/InstructionReader.cpp b/lib/Bytecode/Reader/InstructionReader.cpp index 90be8cd6f5..d66b12cf0d 100644 --- a/lib/Bytecode/Reader/InstructionReader.cpp +++ b/lib/Bytecode/Reader/InstructionReader.cpp @@ -308,10 +308,35 @@ void BytecodeParser::ParseInstruction(const unsigned char *&Buf, for (unsigned i = 1, e = Args.size(); i != e; ++i) { const CompositeType *TopTy = dyn_cast_or_null<CompositeType>(NextTy); if (!TopTy) throw std::string("Invalid getelementptr instruction!"); - // FIXME: when PR82 is resolved. - unsigned IdxTy = isa<StructType>(TopTy) ? Type::UByteTyID :Type::LongTyID; - - Idx.push_back(getValue(IdxTy, Args[i])); + + unsigned ValIdx = Args[i]; + unsigned IdxTy; + if (!hasRestrictedGEPTypes) { + // Struct indices are always uints, sequential type indices can be any + // of the 32 or 64-bit integer types. The actual choice of type is + // encoded in the low two bits of the slot number. + if (isa<StructType>(TopTy)) + IdxTy = Type::UIntTyID; + else { + switch (ValIdx & 3) { + case 0: IdxTy = Type::UIntTyID; break; + case 1: IdxTy = Type::IntTyID; break; + case 2: IdxTy = Type::ULongTyID; break; + case 3: IdxTy = Type::LongTyID; break; + } + ValIdx >>= 2; + } + } else { + IdxTy = isa<StructType>(TopTy) ? Type::UByteTyID : Type::LongTyID; + } + + Idx.push_back(getValue(IdxTy, ValIdx)); + + // Convert ubyte struct indices into uint struct indices. + if (isa<StructType>(TopTy) && hasRestrictedGEPTypes) + if (ConstantUInt *C = dyn_cast<ConstantUInt>(Idx.back())) + Idx[Idx.size()-1] = ConstantExpr::getCast(C, Type::UIntTy); + NextTy = GetElementPtrInst::getIndexedType(InstTy, Idx, true); } diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp index 54c91811a9..2f0879ba39 100644 --- a/lib/Bytecode/Reader/Reader.cpp +++ b/lib/Bytecode/Reader/Reader.cpp @@ -647,12 +647,10 @@ void BytecodeParser::ParseVersionInfo(const unsigned char *&Buf, // Default values for the current bytecode version hasInconsistentModuleGlobalInfo = false; hasExplicitPrimitiveZeros = false; + hasRestrictedGEPTypes = false; switch (RevisionNum) { case 0: // LLVM 1.0, 1.1 release version - // Compared to rev #2, we added support for weak linkage, a more dense - // encoding, and better varargs support. - // Base LLVM 1.0 bytecode format. hasInconsistentModuleGlobalInfo = true; hasExplicitPrimitiveZeros = true; @@ -663,6 +661,13 @@ void BytecodeParser::ParseVersionInfo(const unsigned char *&Buf, // Also, it fixed the problem where the size of the ModuleGlobalInfo block // included the size for the alignment at the end, where the rest of the // blocks did not. + + // LLVM 1.2 and before required that GEP indices be ubyte constants for + // structures and longs for sequential types. + hasRestrictedGEPTypes = true; + + // FALL THROUGH + case 2: // LLVM 1.3 release version break; default: diff --git a/lib/Bytecode/Reader/ReaderInternals.h b/lib/Bytecode/Reader/ReaderInternals.h index 86bf800ca6..9e0ffc2c36 100644 --- a/lib/Bytecode/Reader/ReaderInternals.h +++ b/lib/Bytecode/Reader/ReaderInternals.h @@ -108,6 +108,13 @@ private: // int/sbyte/etc. bool hasExplicitPrimitiveZeros; + // Flags to control features specific the LLVM 1.2 and before (revision #1) + + // LLVM 1.2 and earlier required that getelementptr structure indices were + // ubyte constants and that sequential type indices were longs. + bool hasRestrictedGEPTypes; + + typedef std::vector<ValueList*> ValueTable; ValueTable Values; ValueTable ModuleValues; |