#include "BitcodeReader.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/AutoUpgrade.h"
#include "llvm/Bitcode/LLVMBitCodes.h"
+#include "llvm/IR/AutoUpgrade.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/InlineAsm.h"
case 2: return GlobalValue::AppendingLinkage;
case 3: return GlobalValue::InternalLinkage;
case 4: return GlobalValue::LinkOnceAnyLinkage;
- case 5: return GlobalValue::DLLImportLinkage;
- case 6: return GlobalValue::DLLExportLinkage;
+ case 5: return GlobalValue::ExternalLinkage; // Obsolete DLLImportLinkage
+ case 6: return GlobalValue::ExternalLinkage; // Obsolete DLLExportLinkage
case 7: return GlobalValue::ExternalWeakLinkage;
case 8: return GlobalValue::CommonLinkage;
case 9: return GlobalValue::PrivateLinkage;
}
}
+static GlobalValue::DLLStorageClassTypes
+GetDecodedDLLStorageClass(unsigned Val) {
+ switch (Val) {
+ default: // Map unknown values to default.
+ case 0: return GlobalValue::DefaultStorageClass;
+ case 1: return GlobalValue::DLLImportStorageClass;
+ case 2: return GlobalValue::DLLExportStorageClass;
+ }
+}
+
static GlobalVariable::ThreadLocalMode GetDecodedThreadLocalMode(unsigned Val) {
switch (Val) {
case 0: return GlobalVariable::NotThreadLocal;
case bitc::CAST_PTRTOINT: return Instruction::PtrToInt;
case bitc::CAST_INTTOPTR: return Instruction::IntToPtr;
case bitc::CAST_BITCAST : return Instruction::BitCast;
+ case bitc::CAST_ADDRSPACECAST: return Instruction::AddrSpaceCast;
}
}
static int GetDecodedBinaryOpcode(unsigned Val, Type *Ty) {
}
}
+static void UpgradeDLLImportExportLinkage(llvm::GlobalValue *GV, unsigned Val) {
+ switch (Val) {
+ case 5: GV->setDLLStorageClass(GlobalValue::DLLImportStorageClass); break;
+ case 6: GV->setDLLStorageClass(GlobalValue::DLLExportStorageClass); break;
+ }
+}
+
namespace llvm {
namespace {
/// @brief A class for maintaining the slot number definition
// new value. If they reference more than one placeholder, update them all
// at once.
while (!Placeholder->use_empty()) {
- Value::use_iterator UI = Placeholder->use_begin();
+ auto UI = Placeholder->user_begin();
User *U = *UI;
// If the using object isn't uniqued, just update the operands. This
}
}
-error_code BitcodeReader::ParseAttrKind(uint64_t Code,
- Attribute::AttrKind *Kind) {
+// Returns Attribute::None on unrecognized codes.
+static Attribute::AttrKind GetAttrFromCode(uint64_t Code) {
switch (Code) {
+ default:
+ return Attribute::None;
case bitc::ATTR_KIND_ALIGNMENT:
- *Kind = Attribute::Alignment;
- return error_code::success();
+ return Attribute::Alignment;
case bitc::ATTR_KIND_ALWAYS_INLINE:
- *Kind = Attribute::AlwaysInline;
- return error_code::success();
+ return Attribute::AlwaysInline;
case bitc::ATTR_KIND_BUILTIN:
- *Kind = Attribute::Builtin;
- return error_code::success();
+ return Attribute::Builtin;
case bitc::ATTR_KIND_BY_VAL:
- *Kind = Attribute::ByVal;
- return error_code::success();
+ return Attribute::ByVal;
+ case bitc::ATTR_KIND_IN_ALLOCA:
+ return Attribute::InAlloca;
case bitc::ATTR_KIND_COLD:
- *Kind = Attribute::Cold;
- return error_code::success();
+ return Attribute::Cold;
case bitc::ATTR_KIND_INLINE_HINT:
- *Kind = Attribute::InlineHint;
- return error_code::success();
+ return Attribute::InlineHint;
case bitc::ATTR_KIND_IN_REG:
- *Kind = Attribute::InReg;
- return error_code::success();
+ return Attribute::InReg;
case bitc::ATTR_KIND_MIN_SIZE:
- *Kind = Attribute::MinSize;
- return error_code::success();
+ return Attribute::MinSize;
case bitc::ATTR_KIND_NAKED:
- *Kind = Attribute::Naked;
- return error_code::success();
+ return Attribute::Naked;
case bitc::ATTR_KIND_NEST:
- *Kind = Attribute::Nest;
- return error_code::success();
+ return Attribute::Nest;
case bitc::ATTR_KIND_NO_ALIAS:
- *Kind = Attribute::NoAlias;
- return error_code::success();
+ return Attribute::NoAlias;
case bitc::ATTR_KIND_NO_BUILTIN:
- *Kind = Attribute::NoBuiltin;
- return error_code::success();
+ return Attribute::NoBuiltin;
case bitc::ATTR_KIND_NO_CAPTURE:
- *Kind = Attribute::NoCapture;
- return error_code::success();
+ return Attribute::NoCapture;
case bitc::ATTR_KIND_NO_DUPLICATE:
- *Kind = Attribute::NoDuplicate;
- return error_code::success();
+ return Attribute::NoDuplicate;
case bitc::ATTR_KIND_NO_IMPLICIT_FLOAT:
- *Kind = Attribute::NoImplicitFloat;
- return error_code::success();
+ return Attribute::NoImplicitFloat;
case bitc::ATTR_KIND_NO_INLINE:
- *Kind = Attribute::NoInline;
- return error_code::success();
+ return Attribute::NoInline;
case bitc::ATTR_KIND_NON_LAZY_BIND:
- *Kind = Attribute::NonLazyBind;
- return error_code::success();
+ return Attribute::NonLazyBind;
case bitc::ATTR_KIND_NO_RED_ZONE:
- *Kind = Attribute::NoRedZone;
- return error_code::success();
+ return Attribute::NoRedZone;
case bitc::ATTR_KIND_NO_RETURN:
- *Kind = Attribute::NoReturn;
- return error_code::success();
+ return Attribute::NoReturn;
case bitc::ATTR_KIND_NO_UNWIND:
- *Kind = Attribute::NoUnwind;
- return error_code::success();
+ return Attribute::NoUnwind;
case bitc::ATTR_KIND_OPTIMIZE_FOR_SIZE:
- *Kind = Attribute::OptimizeForSize;
- return error_code::success();
+ return Attribute::OptimizeForSize;
case bitc::ATTR_KIND_OPTIMIZE_NONE:
- *Kind = Attribute::OptimizeNone;
- return error_code::success();
+ return Attribute::OptimizeNone;
case bitc::ATTR_KIND_READ_NONE:
- *Kind = Attribute::ReadNone;
- return error_code::success();
+ return Attribute::ReadNone;
case bitc::ATTR_KIND_READ_ONLY:
- *Kind = Attribute::ReadOnly;
- return error_code::success();
+ return Attribute::ReadOnly;
case bitc::ATTR_KIND_RETURNED:
- *Kind = Attribute::Returned;
- return error_code::success();
+ return Attribute::Returned;
case bitc::ATTR_KIND_RETURNS_TWICE:
- *Kind = Attribute::ReturnsTwice;
- return error_code::success();
+ return Attribute::ReturnsTwice;
case bitc::ATTR_KIND_S_EXT:
- *Kind = Attribute::SExt;
- return error_code::success();
+ return Attribute::SExt;
case bitc::ATTR_KIND_STACK_ALIGNMENT:
- *Kind = Attribute::StackAlignment;
- return error_code::success();
+ return Attribute::StackAlignment;
case bitc::ATTR_KIND_STACK_PROTECT:
- *Kind = Attribute::StackProtect;
- return error_code::success();
+ return Attribute::StackProtect;
case bitc::ATTR_KIND_STACK_PROTECT_REQ:
- *Kind = Attribute::StackProtectReq;
- return error_code::success();
+ return Attribute::StackProtectReq;
case bitc::ATTR_KIND_STACK_PROTECT_STRONG:
- *Kind = Attribute::StackProtectStrong;
- return error_code::success();
+ return Attribute::StackProtectStrong;
case bitc::ATTR_KIND_STRUCT_RET:
- *Kind = Attribute::StructRet;
- return error_code::success();
+ return Attribute::StructRet;
case bitc::ATTR_KIND_SANITIZE_ADDRESS:
- *Kind = Attribute::SanitizeAddress;
- return error_code::success();
+ return Attribute::SanitizeAddress;
case bitc::ATTR_KIND_SANITIZE_THREAD:
- *Kind = Attribute::SanitizeThread;
- return error_code::success();
+ return Attribute::SanitizeThread;
case bitc::ATTR_KIND_SANITIZE_MEMORY:
- *Kind = Attribute::SanitizeMemory;
- return error_code::success();
+ return Attribute::SanitizeMemory;
case bitc::ATTR_KIND_UW_TABLE:
- *Kind = Attribute::UWTable;
- return error_code::success();
+ return Attribute::UWTable;
case bitc::ATTR_KIND_Z_EXT:
- *Kind = Attribute::ZExt;
- return error_code::success();
- default:
- return Error(InvalidValue);
+ return Attribute::ZExt;
}
}
+error_code BitcodeReader::ParseAttrKind(uint64_t Code,
+ Attribute::AttrKind *Kind) {
+ *Kind = GetAttrFromCode(Code);
+ if (*Kind == Attribute::None)
+ return Error(InvalidValue);
+ return error_code::success();
+}
+
error_code BitcodeReader::ParseAttributeGroupBlock() {
if (Stream.EnterSubBlock(bitc::PARAMATTR_GROUP_BLOCK_ID))
return Error(InvalidRecord);
if (!OpTy)
return Error(InvalidRecord);
Constant *Op = ValueList.getConstantFwdRef(Record[2], OpTy);
- V = ConstantExpr::getCast(Opc, Op, CurTy);
+ V = UpgradeBitCastExpr(Opc, Op, CurTy);
+ if (!V) V = ConstantExpr::getCast(Opc, Op, CurTy);
}
break;
}
}
// GLOBALVAR: [pointer type, isconst, initid,
// linkage, alignment, section, visibility, threadlocal,
- // unnamed_addr]
+ // unnamed_addr, dllstorageclass]
case bitc::MODULE_CODE_GLOBALVAR: {
if (Record.size() < 6)
return Error(InvalidRecord);
NewGV->setVisibility(Visibility);
NewGV->setUnnamedAddr(UnnamedAddr);
+ if (Record.size() > 10)
+ NewGV->setDLLStorageClass(GetDecodedDLLStorageClass(Record[10]));
+ else
+ UpgradeDLLImportExportLinkage(NewGV, Record[3]);
+
ValueList.push_back(NewGV);
// Remember which value to use for the global initializer.
break;
}
// FUNCTION: [type, callingconv, isproto, linkage, paramattr,
- // alignment, section, visibility, gc, unnamed_addr]
+ // alignment, section, visibility, gc, unnamed_addr,
+ // dllstorageclass]
case bitc::MODULE_CODE_FUNCTION: {
if (Record.size() < 8)
return Error(InvalidRecord);
Func->setUnnamedAddr(UnnamedAddr);
if (Record.size() > 10 && Record[10] != 0)
FunctionPrefixes.push_back(std::make_pair(Func, Record[10]-1));
+
+ if (Record.size() > 11)
+ Func->setDLLStorageClass(GetDecodedDLLStorageClass(Record[11]));
+ else
+ UpgradeDLLImportExportLinkage(Func, Record[3]);
+
ValueList.push_back(Func);
// If this is a function with a body, remember the prototype we are
break;
}
// ALIAS: [alias type, aliasee val#, linkage]
- // ALIAS: [alias type, aliasee val#, linkage, visibility]
+ // ALIAS: [alias type, aliasee val#, linkage, visibility, dllstorageclass]
case bitc::MODULE_CODE_ALIAS: {
if (Record.size() < 3)
return Error(InvalidRecord);
// Old bitcode files didn't have visibility field.
if (Record.size() > 3)
NewGA->setVisibility(GetDecodedVisibility(Record[3]));
+ if (Record.size() > 4)
+ NewGA->setDLLStorageClass(GetDecodedDLLStorageClass(Record[4]));
+ else
+ UpgradeDLLImportExportLinkage(NewGA, Record[2]);
ValueList.push_back(NewGA);
AliasInits.push_back(std::make_pair(NewGA, Record[1]));
break;
int Opc = GetDecodedCastOpcode(Record[OpNum+1]);
if (Opc == -1 || ResTy == 0)
return Error(InvalidRecord);
- I = CastInst::Create((Instruction::CastOps)Opc, Op, ResTy);
+ Instruction *Temp = 0;
+ if ((I = UpgradeBitCastInst(Opc, Op, ResTy, Temp))) {
+ if (Temp) {
+ InstructionList.push_back(Temp);
+ CurBB->getInstList().push_back(Temp);
+ }
+ } else {
+ I = CastInst::Create((Instruction::CastOps)Opc, Op, ResTy);
+ }
InstructionList.push_back(I);
break;
}
return false;
}
-bool BitcodeReader::Materialize(GlobalValue *GV, std::string *ErrInfo) {
+error_code BitcodeReader::Materialize(GlobalValue *GV) {
Function *F = dyn_cast<Function>(GV);
// If it's not a function or is already material, ignore the request.
- if (!F || !F->isMaterializable()) return false;
+ if (!F || !F->isMaterializable())
+ return error_code::success();
DenseMap<Function*, uint64_t>::iterator DFII = DeferredFunctionInfo.find(F);
assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!");
// If its position is recorded as 0, its body is somewhere in the stream
// but we haven't seen it yet.
- if (DFII->second == 0)
- if (LazyStreamer && FindFunctionInStream(F, DFII)) return true;
+ if (DFII->second == 0 && LazyStreamer)
+ if (error_code EC = FindFunctionInStream(F, DFII))
+ return EC;
// Move the bit stream to the saved position of the deferred function body.
Stream.JumpToBit(DFII->second);
- if (error_code EC = ParseFunctionBody(F)) {
- if (ErrInfo)
- *ErrInfo = EC.message();
- return true;
- }
+ if (error_code EC = ParseFunctionBody(F))
+ return EC;
// Upgrade any old intrinsic calls in the function.
for (UpgradedIntrinsicMap::iterator I = UpgradedIntrinsics.begin(),
E = UpgradedIntrinsics.end(); I != E; ++I) {
if (I->first != I->second) {
- for (Value::use_iterator UI = I->first->use_begin(),
- UE = I->first->use_end(); UI != UE; ) {
+ for (auto UI = I->first->user_begin(), UE = I->first->user_end();
+ UI != UE;) {
if (CallInst* CI = dyn_cast<CallInst>(*UI++))
UpgradeIntrinsicCall(CI, I->second);
}
}
}
- return false;
+ return error_code::success();
}
bool BitcodeReader::isDematerializable(const GlobalValue *GV) const {
}
-bool BitcodeReader::MaterializeModule(Module *M, std::string *ErrInfo) {
+error_code BitcodeReader::MaterializeModule(Module *M) {
assert(M == TheModule &&
"Can only Materialize the Module this BitcodeReader is attached to.");
// Iterate over the module, deserializing any functions that are still on
// disk.
for (Module::iterator F = TheModule->begin(), E = TheModule->end();
- F != E; ++F)
- if (F->isMaterializable() &&
- Materialize(F, ErrInfo))
- return true;
-
+ F != E; ++F) {
+ if (F->isMaterializable()) {
+ if (error_code EC = Materialize(F))
+ return EC;
+ }
+ }
// At this point, if there are any function bodies, the current bit is
// pointing to the END_BLOCK record after them. Now make sure the rest
// of the bits in the module have been read.
for (std::vector<std::pair<Function*, Function*> >::iterator I =
UpgradedIntrinsics.begin(), E = UpgradedIntrinsics.end(); I != E; ++I) {
if (I->first != I->second) {
- for (Value::use_iterator UI = I->first->use_begin(),
- UE = I->first->use_end(); UI != UE; ) {
+ for (auto UI = I->first->user_begin(), UE = I->first->user_end();
+ UI != UE;) {
if (CallInst* CI = dyn_cast<CallInst>(*UI++))
UpgradeIntrinsicCall(CI, I->second);
}
for (unsigned I = 0, E = InstsWithTBAATag.size(); I < E; I++)
UpgradeInstWithTBAATag(InstsWithTBAATag[I]);
- return false;
+ UpgradeDebugInfo(*M);
+ return error_code::success();
}
error_code BitcodeReader::InitStream() {
namespace {
class BitcodeErrorCategoryType : public _do_message {
- const char *name() const LLVM_OVERRIDE {
+ const char *name() const override {
return "llvm.bitcode";
}
- std::string message(int IE) const LLVM_OVERRIDE {
+ std::string message(int IE) const override {
BitcodeReader::ErrorType E = static_cast<BitcodeReader::ErrorType>(IE);
switch (E) {
case BitcodeReader::BitcodeStreamInvalidSize:
/// getLazyBitcodeModule - lazy function-at-a-time loading from a file.
///
-Module *llvm::getLazyBitcodeModule(MemoryBuffer *Buffer,
- LLVMContext& Context,
- std::string *ErrMsg) {
+ErrorOr<Module *> llvm::getLazyBitcodeModule(MemoryBuffer *Buffer,
+ LLVMContext &Context) {
Module *M = new Module(Buffer->getBufferIdentifier(), Context);
BitcodeReader *R = new BitcodeReader(Buffer, Context);
M->setMaterializer(R);
if (error_code EC = R->ParseBitcodeInto(M)) {
- if (ErrMsg)
- *ErrMsg = EC.message();
-
delete M; // Also deletes R.
- return 0;
+ return EC;
}
// Have the BitcodeReader dtor delete 'Buffer'.
R->setBufferOwned(true);
return M;
}
-/// ParseBitcodeFile - Read the specified bitcode file, returning the module.
-/// If an error occurs, return null and fill in *ErrMsg if non-null.
-Module *llvm::ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context,
- std::string *ErrMsg){
- Module *M = getLazyBitcodeModule(Buffer, Context, ErrMsg);
- if (!M) return 0;
+ErrorOr<Module *> llvm::parseBitcodeFile(MemoryBuffer *Buffer,
+ LLVMContext &Context) {
+ ErrorOr<Module *> ModuleOrErr = getLazyBitcodeModule(Buffer, Context);
+ if (!ModuleOrErr)
+ return ModuleOrErr;
+ Module *M = ModuleOrErr.get();
// Don't let the BitcodeReader dtor delete 'Buffer', regardless of whether
// there was an error.
static_cast<BitcodeReader*>(M->getMaterializer())->setBufferOwned(false);
// Read in the entire module, and destroy the BitcodeReader.
- if (M->MaterializeAllPermanently(ErrMsg)) {
+ if (error_code EC = M->materializeAllPermanently()) {
delete M;
- return 0;
+ return EC;
}
// TODO: Restore the use-lists to the in-memory state when the bitcode was