Bitcode: Move version and global value module code parsers to separate functions. NFCI.
This will make it easier to teach this code about the string table. Differential Revision: https://reviews.llvm.org/D31828 llvm-svn: 300099
This commit is contained in:
@@ -379,6 +379,8 @@ protected:
|
||||
BitstreamBlockInfo BlockInfo;
|
||||
BitstreamCursor Stream;
|
||||
|
||||
Expected<unsigned> parseVersionRecord(ArrayRef<uint64_t> Record);
|
||||
|
||||
bool readBlockInfo();
|
||||
|
||||
// Contains an arbitrary and optional string identifying the bitcode producer
|
||||
@@ -395,6 +397,16 @@ Error BitcodeReaderBase::error(const Twine &Message) {
|
||||
return ::error(FullMsg);
|
||||
}
|
||||
|
||||
Expected<unsigned>
|
||||
BitcodeReaderBase::parseVersionRecord(ArrayRef<uint64_t> Record) {
|
||||
if (Record.size() < 1)
|
||||
return error("Invalid record");
|
||||
unsigned ModuleVersion = Record[0];
|
||||
if (ModuleVersion > 1)
|
||||
return error("Invalid value");
|
||||
return ModuleVersion;
|
||||
}
|
||||
|
||||
class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
|
||||
LLVMContext &Context;
|
||||
Module *TheModule = nullptr;
|
||||
@@ -405,6 +417,9 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
|
||||
bool SeenValueSymbolTable = false;
|
||||
uint64_t VSTOffset = 0;
|
||||
|
||||
std::vector<std::string> SectionTable;
|
||||
std::vector<std::string> GCTable;
|
||||
|
||||
std::vector<Type*> TypeList;
|
||||
BitcodeReaderValueList ValueList;
|
||||
Optional<MetadataLoader> MDLoader;
|
||||
@@ -598,6 +613,13 @@ private:
|
||||
Error parseAlignmentValue(uint64_t Exponent, unsigned &Alignment);
|
||||
Error parseAttrKind(uint64_t Code, Attribute::AttrKind *Kind);
|
||||
Error parseModule(uint64_t ResumeBit, bool ShouldLazyLoadMetadata = false);
|
||||
|
||||
Error parseComdatRecord(ArrayRef<uint64_t> Record);
|
||||
Error parseGlobalVarRecord(ArrayRef<uint64_t> Record);
|
||||
Error parseFunctionRecord(ArrayRef<uint64_t> Record);
|
||||
Error parseGlobalIndirectSymbolRecord(unsigned BitCode,
|
||||
ArrayRef<uint64_t> Record);
|
||||
|
||||
Error parseAttributeBlock();
|
||||
Error parseAttributeGroupBlock();
|
||||
Error parseTypeTable();
|
||||
@@ -2603,6 +2625,246 @@ bool BitcodeReaderBase::readBlockInfo() {
|
||||
return false;
|
||||
}
|
||||
|
||||
Error BitcodeReader::parseComdatRecord(ArrayRef<uint64_t> Record) {
|
||||
// [selection_kind, name]
|
||||
if (Record.size() < 2)
|
||||
return error("Invalid record");
|
||||
Comdat::SelectionKind SK = getDecodedComdatSelectionKind(Record[0]);
|
||||
std::string Name;
|
||||
unsigned ComdatNameSize = Record[1];
|
||||
Name.reserve(ComdatNameSize);
|
||||
for (unsigned i = 0; i != ComdatNameSize; ++i)
|
||||
Name += (char)Record[2 + i];
|
||||
Comdat *C = TheModule->getOrInsertComdat(Name);
|
||||
C->setSelectionKind(SK);
|
||||
ComdatList.push_back(C);
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) {
|
||||
// [pointer type, isconst, initid, linkage, alignment, section,
|
||||
// visibility, threadlocal, unnamed_addr, externally_initialized,
|
||||
// dllstorageclass, comdat]
|
||||
if (Record.size() < 6)
|
||||
return error("Invalid record");
|
||||
Type *Ty = getTypeByID(Record[0]);
|
||||
if (!Ty)
|
||||
return error("Invalid record");
|
||||
bool isConstant = Record[1] & 1;
|
||||
bool explicitType = Record[1] & 2;
|
||||
unsigned AddressSpace;
|
||||
if (explicitType) {
|
||||
AddressSpace = Record[1] >> 2;
|
||||
} else {
|
||||
if (!Ty->isPointerTy())
|
||||
return error("Invalid type for value");
|
||||
AddressSpace = cast<PointerType>(Ty)->getAddressSpace();
|
||||
Ty = cast<PointerType>(Ty)->getElementType();
|
||||
}
|
||||
|
||||
uint64_t RawLinkage = Record[3];
|
||||
GlobalValue::LinkageTypes Linkage = getDecodedLinkage(RawLinkage);
|
||||
unsigned Alignment;
|
||||
if (Error Err = parseAlignmentValue(Record[4], Alignment))
|
||||
return Err;
|
||||
std::string Section;
|
||||
if (Record[5]) {
|
||||
if (Record[5] - 1 >= SectionTable.size())
|
||||
return error("Invalid ID");
|
||||
Section = SectionTable[Record[5] - 1];
|
||||
}
|
||||
GlobalValue::VisibilityTypes Visibility = GlobalValue::DefaultVisibility;
|
||||
// Local linkage must have default visibility.
|
||||
if (Record.size() > 6 && !GlobalValue::isLocalLinkage(Linkage))
|
||||
// FIXME: Change to an error if non-default in 4.0.
|
||||
Visibility = getDecodedVisibility(Record[6]);
|
||||
|
||||
GlobalVariable::ThreadLocalMode TLM = GlobalVariable::NotThreadLocal;
|
||||
if (Record.size() > 7)
|
||||
TLM = getDecodedThreadLocalMode(Record[7]);
|
||||
|
||||
GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::None;
|
||||
if (Record.size() > 8)
|
||||
UnnamedAddr = getDecodedUnnamedAddrType(Record[8]);
|
||||
|
||||
bool ExternallyInitialized = false;
|
||||
if (Record.size() > 9)
|
||||
ExternallyInitialized = Record[9];
|
||||
|
||||
GlobalVariable *NewGV =
|
||||
new GlobalVariable(*TheModule, Ty, isConstant, Linkage, nullptr, "",
|
||||
nullptr, TLM, AddressSpace, ExternallyInitialized);
|
||||
NewGV->setAlignment(Alignment);
|
||||
if (!Section.empty())
|
||||
NewGV->setSection(Section);
|
||||
NewGV->setVisibility(Visibility);
|
||||
NewGV->setUnnamedAddr(UnnamedAddr);
|
||||
|
||||
if (Record.size() > 10)
|
||||
NewGV->setDLLStorageClass(getDecodedDLLStorageClass(Record[10]));
|
||||
else
|
||||
upgradeDLLImportExportLinkage(NewGV, RawLinkage);
|
||||
|
||||
ValueList.push_back(NewGV);
|
||||
|
||||
// Remember which value to use for the global initializer.
|
||||
if (unsigned InitID = Record[2])
|
||||
GlobalInits.push_back(std::make_pair(NewGV, InitID - 1));
|
||||
|
||||
if (Record.size() > 11) {
|
||||
if (unsigned ComdatID = Record[11]) {
|
||||
if (ComdatID > ComdatList.size())
|
||||
return error("Invalid global variable comdat ID");
|
||||
NewGV->setComdat(ComdatList[ComdatID - 1]);
|
||||
}
|
||||
} else if (hasImplicitComdat(RawLinkage)) {
|
||||
NewGV->setComdat(reinterpret_cast<Comdat *>(1));
|
||||
}
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) {
|
||||
// [type, callingconv, isproto, linkage, paramattr, alignment, section,
|
||||
// visibility, gc, unnamed_addr, prologuedata, dllstorageclass, comdat,
|
||||
// prefixdata]
|
||||
if (Record.size() < 8)
|
||||
return error("Invalid record");
|
||||
Type *Ty = getTypeByID(Record[0]);
|
||||
if (!Ty)
|
||||
return error("Invalid record");
|
||||
if (auto *PTy = dyn_cast<PointerType>(Ty))
|
||||
Ty = PTy->getElementType();
|
||||
auto *FTy = dyn_cast<FunctionType>(Ty);
|
||||
if (!FTy)
|
||||
return error("Invalid type for value");
|
||||
auto CC = static_cast<CallingConv::ID>(Record[1]);
|
||||
if (CC & ~CallingConv::MaxID)
|
||||
return error("Invalid calling convention ID");
|
||||
|
||||
Function *Func =
|
||||
Function::Create(FTy, GlobalValue::ExternalLinkage, "", TheModule);
|
||||
|
||||
Func->setCallingConv(CC);
|
||||
bool isProto = Record[2];
|
||||
uint64_t RawLinkage = Record[3];
|
||||
Func->setLinkage(getDecodedLinkage(RawLinkage));
|
||||
Func->setAttributes(getAttributes(Record[4]));
|
||||
|
||||
unsigned Alignment;
|
||||
if (Error Err = parseAlignmentValue(Record[5], Alignment))
|
||||
return Err;
|
||||
Func->setAlignment(Alignment);
|
||||
if (Record[6]) {
|
||||
if (Record[6] - 1 >= SectionTable.size())
|
||||
return error("Invalid ID");
|
||||
Func->setSection(SectionTable[Record[6] - 1]);
|
||||
}
|
||||
// Local linkage must have default visibility.
|
||||
if (!Func->hasLocalLinkage())
|
||||
// FIXME: Change to an error if non-default in 4.0.
|
||||
Func->setVisibility(getDecodedVisibility(Record[7]));
|
||||
if (Record.size() > 8 && Record[8]) {
|
||||
if (Record[8] - 1 >= GCTable.size())
|
||||
return error("Invalid ID");
|
||||
Func->setGC(GCTable[Record[8] - 1]);
|
||||
}
|
||||
GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::None;
|
||||
if (Record.size() > 9)
|
||||
UnnamedAddr = getDecodedUnnamedAddrType(Record[9]);
|
||||
Func->setUnnamedAddr(UnnamedAddr);
|
||||
if (Record.size() > 10 && Record[10] != 0)
|
||||
FunctionPrologues.push_back(std::make_pair(Func, Record[10] - 1));
|
||||
|
||||
if (Record.size() > 11)
|
||||
Func->setDLLStorageClass(getDecodedDLLStorageClass(Record[11]));
|
||||
else
|
||||
upgradeDLLImportExportLinkage(Func, RawLinkage);
|
||||
|
||||
if (Record.size() > 12) {
|
||||
if (unsigned ComdatID = Record[12]) {
|
||||
if (ComdatID > ComdatList.size())
|
||||
return error("Invalid function comdat ID");
|
||||
Func->setComdat(ComdatList[ComdatID - 1]);
|
||||
}
|
||||
} else if (hasImplicitComdat(RawLinkage)) {
|
||||
Func->setComdat(reinterpret_cast<Comdat *>(1));
|
||||
}
|
||||
|
||||
if (Record.size() > 13 && Record[13] != 0)
|
||||
FunctionPrefixes.push_back(std::make_pair(Func, Record[13] - 1));
|
||||
|
||||
if (Record.size() > 14 && Record[14] != 0)
|
||||
FunctionPersonalityFns.push_back(std::make_pair(Func, Record[14] - 1));
|
||||
|
||||
ValueList.push_back(Func);
|
||||
|
||||
// If this is a function with a body, remember the prototype we are
|
||||
// creating now, so that we can match up the body with them later.
|
||||
if (!isProto) {
|
||||
Func->setIsMaterializable(true);
|
||||
FunctionsWithBodies.push_back(Func);
|
||||
DeferredFunctionInfo[Func] = 0;
|
||||
}
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error BitcodeReader::parseGlobalIndirectSymbolRecord(
|
||||
unsigned BitCode, ArrayRef<uint64_t> Record) {
|
||||
// ALIAS_OLD: [alias type, aliasee val#, linkage]
|
||||
// ALIAS: [alias type, addrspace, aliasee val#, linkage, visibility,
|
||||
// dllstorageclass]
|
||||
// IFUNC: [alias type, addrspace, aliasee val#, linkage,
|
||||
// visibility, dllstorageclass]
|
||||
bool NewRecord = BitCode != bitc::MODULE_CODE_ALIAS_OLD;
|
||||
if (Record.size() < (3 + (unsigned)NewRecord))
|
||||
return error("Invalid record");
|
||||
unsigned OpNum = 0;
|
||||
Type *Ty = getTypeByID(Record[OpNum++]);
|
||||
if (!Ty)
|
||||
return error("Invalid record");
|
||||
|
||||
unsigned AddrSpace;
|
||||
if (!NewRecord) {
|
||||
auto *PTy = dyn_cast<PointerType>(Ty);
|
||||
if (!PTy)
|
||||
return error("Invalid type for value");
|
||||
Ty = PTy->getElementType();
|
||||
AddrSpace = PTy->getAddressSpace();
|
||||
} else {
|
||||
AddrSpace = Record[OpNum++];
|
||||
}
|
||||
|
||||
auto Val = Record[OpNum++];
|
||||
auto Linkage = Record[OpNum++];
|
||||
GlobalIndirectSymbol *NewGA;
|
||||
if (BitCode == bitc::MODULE_CODE_ALIAS ||
|
||||
BitCode == bitc::MODULE_CODE_ALIAS_OLD)
|
||||
NewGA = GlobalAlias::create(Ty, AddrSpace, getDecodedLinkage(Linkage), "",
|
||||
TheModule);
|
||||
else
|
||||
NewGA = GlobalIFunc::create(Ty, AddrSpace, getDecodedLinkage(Linkage), "",
|
||||
nullptr, TheModule);
|
||||
// Old bitcode files didn't have visibility field.
|
||||
// Local linkage must have default visibility.
|
||||
if (OpNum != Record.size()) {
|
||||
auto VisInd = OpNum++;
|
||||
if (!NewGA->hasLocalLinkage())
|
||||
// FIXME: Change to an error if non-default in 4.0.
|
||||
NewGA->setVisibility(getDecodedVisibility(Record[VisInd]));
|
||||
}
|
||||
if (OpNum != Record.size())
|
||||
NewGA->setDLLStorageClass(getDecodedDLLStorageClass(Record[OpNum++]));
|
||||
else
|
||||
upgradeDLLImportExportLinkage(NewGA, Linkage);
|
||||
if (OpNum != Record.size())
|
||||
NewGA->setThreadLocalMode(getDecodedThreadLocalMode(Record[OpNum++]));
|
||||
if (OpNum != Record.size())
|
||||
NewGA->setUnnamedAddr(getDecodedUnnamedAddrType(Record[OpNum++]));
|
||||
ValueList.push_back(NewGA);
|
||||
IndirectSymbolInits.push_back(std::make_pair(NewGA, Val));
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error BitcodeReader::parseModule(uint64_t ResumeBit,
|
||||
bool ShouldLazyLoadMetadata) {
|
||||
if (ResumeBit)
|
||||
@@ -2611,8 +2873,6 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit,
|
||||
return error("Invalid record");
|
||||
|
||||
SmallVector<uint64_t, 64> Record;
|
||||
std::vector<std::string> SectionTable;
|
||||
std::vector<std::string> GCTable;
|
||||
|
||||
// Read all the records for this module.
|
||||
while (true) {
|
||||
@@ -2758,21 +3018,11 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit,
|
||||
auto BitCode = Stream.readRecord(Entry.ID, Record);
|
||||
switch (BitCode) {
|
||||
default: break; // Default behavior, ignore unknown content.
|
||||
case bitc::MODULE_CODE_VERSION: { // VERSION: [version#]
|
||||
if (Record.size() < 1)
|
||||
return error("Invalid record");
|
||||
// Only version #0 and #1 are supported so far.
|
||||
unsigned module_version = Record[0];
|
||||
switch (module_version) {
|
||||
default:
|
||||
return error("Invalid value");
|
||||
case 0:
|
||||
UseRelativeIDs = false;
|
||||
break;
|
||||
case 1:
|
||||
UseRelativeIDs = true;
|
||||
break;
|
||||
}
|
||||
case bitc::MODULE_CODE_VERSION: {
|
||||
Expected<unsigned> VersionOrErr = parseVersionRecord(Record);
|
||||
if (!VersionOrErr)
|
||||
return VersionOrErr.takeError();
|
||||
UseRelativeIDs = *VersionOrErr >= 1;
|
||||
break;
|
||||
}
|
||||
case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N]
|
||||
@@ -2818,240 +3068,26 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit,
|
||||
GCTable.push_back(S);
|
||||
break;
|
||||
}
|
||||
case bitc::MODULE_CODE_COMDAT: { // COMDAT: [selection_kind, name]
|
||||
if (Record.size() < 2)
|
||||
return error("Invalid record");
|
||||
Comdat::SelectionKind SK = getDecodedComdatSelectionKind(Record[0]);
|
||||
unsigned ComdatNameSize = Record[1];
|
||||
std::string ComdatName;
|
||||
ComdatName.reserve(ComdatNameSize);
|
||||
for (unsigned i = 0; i != ComdatNameSize; ++i)
|
||||
ComdatName += (char)Record[2 + i];
|
||||
Comdat *C = TheModule->getOrInsertComdat(ComdatName);
|
||||
C->setSelectionKind(SK);
|
||||
ComdatList.push_back(C);
|
||||
case bitc::MODULE_CODE_COMDAT: {
|
||||
if (Error Err = parseComdatRecord(Record))
|
||||
return Err;
|
||||
break;
|
||||
}
|
||||
// GLOBALVAR: [pointer type, isconst, initid,
|
||||
// linkage, alignment, section, visibility, threadlocal,
|
||||
// unnamed_addr, externally_initialized, dllstorageclass,
|
||||
// comdat]
|
||||
case bitc::MODULE_CODE_GLOBALVAR: {
|
||||
if (Record.size() < 6)
|
||||
return error("Invalid record");
|
||||
Type *Ty = getTypeByID(Record[0]);
|
||||
if (!Ty)
|
||||
return error("Invalid record");
|
||||
bool isConstant = Record[1] & 1;
|
||||
bool explicitType = Record[1] & 2;
|
||||
unsigned AddressSpace;
|
||||
if (explicitType) {
|
||||
AddressSpace = Record[1] >> 2;
|
||||
} else {
|
||||
if (!Ty->isPointerTy())
|
||||
return error("Invalid type for value");
|
||||
AddressSpace = cast<PointerType>(Ty)->getAddressSpace();
|
||||
Ty = cast<PointerType>(Ty)->getElementType();
|
||||
}
|
||||
|
||||
uint64_t RawLinkage = Record[3];
|
||||
GlobalValue::LinkageTypes Linkage = getDecodedLinkage(RawLinkage);
|
||||
unsigned Alignment;
|
||||
if (Error Err = parseAlignmentValue(Record[4], Alignment))
|
||||
if (Error Err = parseGlobalVarRecord(Record))
|
||||
return Err;
|
||||
std::string Section;
|
||||
if (Record[5]) {
|
||||
if (Record[5]-1 >= SectionTable.size())
|
||||
return error("Invalid ID");
|
||||
Section = SectionTable[Record[5]-1];
|
||||
}
|
||||
GlobalValue::VisibilityTypes Visibility = GlobalValue::DefaultVisibility;
|
||||
// Local linkage must have default visibility.
|
||||
if (Record.size() > 6 && !GlobalValue::isLocalLinkage(Linkage))
|
||||
// FIXME: Change to an error if non-default in 4.0.
|
||||
Visibility = getDecodedVisibility(Record[6]);
|
||||
|
||||
GlobalVariable::ThreadLocalMode TLM = GlobalVariable::NotThreadLocal;
|
||||
if (Record.size() > 7)
|
||||
TLM = getDecodedThreadLocalMode(Record[7]);
|
||||
|
||||
GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::None;
|
||||
if (Record.size() > 8)
|
||||
UnnamedAddr = getDecodedUnnamedAddrType(Record[8]);
|
||||
|
||||
bool ExternallyInitialized = false;
|
||||
if (Record.size() > 9)
|
||||
ExternallyInitialized = Record[9];
|
||||
|
||||
GlobalVariable *NewGV =
|
||||
new GlobalVariable(*TheModule, Ty, isConstant, Linkage, nullptr, "", nullptr,
|
||||
TLM, AddressSpace, ExternallyInitialized);
|
||||
NewGV->setAlignment(Alignment);
|
||||
if (!Section.empty())
|
||||
NewGV->setSection(Section);
|
||||
NewGV->setVisibility(Visibility);
|
||||
NewGV->setUnnamedAddr(UnnamedAddr);
|
||||
|
||||
if (Record.size() > 10)
|
||||
NewGV->setDLLStorageClass(getDecodedDLLStorageClass(Record[10]));
|
||||
else
|
||||
upgradeDLLImportExportLinkage(NewGV, RawLinkage);
|
||||
|
||||
ValueList.push_back(NewGV);
|
||||
|
||||
// Remember which value to use for the global initializer.
|
||||
if (unsigned InitID = Record[2])
|
||||
GlobalInits.push_back(std::make_pair(NewGV, InitID-1));
|
||||
|
||||
if (Record.size() > 11) {
|
||||
if (unsigned ComdatID = Record[11]) {
|
||||
if (ComdatID > ComdatList.size())
|
||||
return error("Invalid global variable comdat ID");
|
||||
NewGV->setComdat(ComdatList[ComdatID - 1]);
|
||||
}
|
||||
} else if (hasImplicitComdat(RawLinkage)) {
|
||||
NewGV->setComdat(reinterpret_cast<Comdat *>(1));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
// FUNCTION: [type, callingconv, isproto, linkage, paramattr,
|
||||
// alignment, section, visibility, gc, unnamed_addr,
|
||||
// prologuedata, dllstorageclass, comdat, prefixdata]
|
||||
case bitc::MODULE_CODE_FUNCTION: {
|
||||
if (Record.size() < 8)
|
||||
return error("Invalid record");
|
||||
Type *Ty = getTypeByID(Record[0]);
|
||||
if (!Ty)
|
||||
return error("Invalid record");
|
||||
if (auto *PTy = dyn_cast<PointerType>(Ty))
|
||||
Ty = PTy->getElementType();
|
||||
auto *FTy = dyn_cast<FunctionType>(Ty);
|
||||
if (!FTy)
|
||||
return error("Invalid type for value");
|
||||
auto CC = static_cast<CallingConv::ID>(Record[1]);
|
||||
if (CC & ~CallingConv::MaxID)
|
||||
return error("Invalid calling convention ID");
|
||||
|
||||
Function *Func = Function::Create(FTy, GlobalValue::ExternalLinkage,
|
||||
"", TheModule);
|
||||
|
||||
Func->setCallingConv(CC);
|
||||
bool isProto = Record[2];
|
||||
uint64_t RawLinkage = Record[3];
|
||||
Func->setLinkage(getDecodedLinkage(RawLinkage));
|
||||
Func->setAttributes(getAttributes(Record[4]));
|
||||
|
||||
unsigned Alignment;
|
||||
if (Error Err = parseAlignmentValue(Record[5], Alignment))
|
||||
if (Error Err = parseFunctionRecord(Record))
|
||||
return Err;
|
||||
Func->setAlignment(Alignment);
|
||||
if (Record[6]) {
|
||||
if (Record[6]-1 >= SectionTable.size())
|
||||
return error("Invalid ID");
|
||||
Func->setSection(SectionTable[Record[6]-1]);
|
||||
}
|
||||
// Local linkage must have default visibility.
|
||||
if (!Func->hasLocalLinkage())
|
||||
// FIXME: Change to an error if non-default in 4.0.
|
||||
Func->setVisibility(getDecodedVisibility(Record[7]));
|
||||
if (Record.size() > 8 && Record[8]) {
|
||||
if (Record[8]-1 >= GCTable.size())
|
||||
return error("Invalid ID");
|
||||
Func->setGC(GCTable[Record[8] - 1]);
|
||||
}
|
||||
GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::None;
|
||||
if (Record.size() > 9)
|
||||
UnnamedAddr = getDecodedUnnamedAddrType(Record[9]);
|
||||
Func->setUnnamedAddr(UnnamedAddr);
|
||||
if (Record.size() > 10 && Record[10] != 0)
|
||||
FunctionPrologues.push_back(std::make_pair(Func, Record[10]-1));
|
||||
|
||||
if (Record.size() > 11)
|
||||
Func->setDLLStorageClass(getDecodedDLLStorageClass(Record[11]));
|
||||
else
|
||||
upgradeDLLImportExportLinkage(Func, RawLinkage);
|
||||
|
||||
if (Record.size() > 12) {
|
||||
if (unsigned ComdatID = Record[12]) {
|
||||
if (ComdatID > ComdatList.size())
|
||||
return error("Invalid function comdat ID");
|
||||
Func->setComdat(ComdatList[ComdatID - 1]);
|
||||
}
|
||||
} else if (hasImplicitComdat(RawLinkage)) {
|
||||
Func->setComdat(reinterpret_cast<Comdat *>(1));
|
||||
}
|
||||
|
||||
if (Record.size() > 13 && Record[13] != 0)
|
||||
FunctionPrefixes.push_back(std::make_pair(Func, Record[13]-1));
|
||||
|
||||
if (Record.size() > 14 && Record[14] != 0)
|
||||
FunctionPersonalityFns.push_back(std::make_pair(Func, Record[14] - 1));
|
||||
|
||||
ValueList.push_back(Func);
|
||||
|
||||
// If this is a function with a body, remember the prototype we are
|
||||
// creating now, so that we can match up the body with them later.
|
||||
if (!isProto) {
|
||||
Func->setIsMaterializable(true);
|
||||
FunctionsWithBodies.push_back(Func);
|
||||
DeferredFunctionInfo[Func] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// ALIAS: [alias type, addrspace, aliasee val#, linkage]
|
||||
// ALIAS: [alias type, addrspace, aliasee val#, linkage, visibility, dllstorageclass]
|
||||
// IFUNC: [alias type, addrspace, aliasee val#, linkage, visibility, dllstorageclass]
|
||||
case bitc::MODULE_CODE_IFUNC:
|
||||
case bitc::MODULE_CODE_ALIAS:
|
||||
case bitc::MODULE_CODE_ALIAS_OLD: {
|
||||
bool NewRecord = BitCode != bitc::MODULE_CODE_ALIAS_OLD;
|
||||
if (Record.size() < (3 + (unsigned)NewRecord))
|
||||
return error("Invalid record");
|
||||
unsigned OpNum = 0;
|
||||
Type *Ty = getTypeByID(Record[OpNum++]);
|
||||
if (!Ty)
|
||||
return error("Invalid record");
|
||||
|
||||
unsigned AddrSpace;
|
||||
if (!NewRecord) {
|
||||
auto *PTy = dyn_cast<PointerType>(Ty);
|
||||
if (!PTy)
|
||||
return error("Invalid type for value");
|
||||
Ty = PTy->getElementType();
|
||||
AddrSpace = PTy->getAddressSpace();
|
||||
} else {
|
||||
AddrSpace = Record[OpNum++];
|
||||
}
|
||||
|
||||
auto Val = Record[OpNum++];
|
||||
auto Linkage = Record[OpNum++];
|
||||
GlobalIndirectSymbol *NewGA;
|
||||
if (BitCode == bitc::MODULE_CODE_ALIAS ||
|
||||
BitCode == bitc::MODULE_CODE_ALIAS_OLD)
|
||||
NewGA = GlobalAlias::create(Ty, AddrSpace, getDecodedLinkage(Linkage),
|
||||
"", TheModule);
|
||||
else
|
||||
NewGA = GlobalIFunc::create(Ty, AddrSpace, getDecodedLinkage(Linkage),
|
||||
"", nullptr, TheModule);
|
||||
// Old bitcode files didn't have visibility field.
|
||||
// Local linkage must have default visibility.
|
||||
if (OpNum != Record.size()) {
|
||||
auto VisInd = OpNum++;
|
||||
if (!NewGA->hasLocalLinkage())
|
||||
// FIXME: Change to an error if non-default in 4.0.
|
||||
NewGA->setVisibility(getDecodedVisibility(Record[VisInd]));
|
||||
}
|
||||
if (OpNum != Record.size())
|
||||
NewGA->setDLLStorageClass(getDecodedDLLStorageClass(Record[OpNum++]));
|
||||
else
|
||||
upgradeDLLImportExportLinkage(NewGA, Linkage);
|
||||
if (OpNum != Record.size())
|
||||
NewGA->setThreadLocalMode(getDecodedThreadLocalMode(Record[OpNum++]));
|
||||
if (OpNum != Record.size())
|
||||
NewGA->setUnnamedAddr(getDecodedUnnamedAddrType(Record[OpNum++]));
|
||||
ValueList.push_back(NewGA);
|
||||
IndirectSymbolInits.push_back(std::make_pair(NewGA, Val));
|
||||
if (Error Err = parseGlobalIndirectSymbolRecord(BitCode, Record))
|
||||
return Err;
|
||||
break;
|
||||
}
|
||||
/// MODULE_CODE_VSTOFFSET: [offset]
|
||||
|
||||
Reference in New Issue
Block a user