summaryrefslogtreecommitdiff
path: root/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Bitcode/Reader/MetadataLoader.cpp')
-rw-r--r--llvm/lib/Bitcode/Reader/MetadataLoader.cpp109
1 files changed, 82 insertions, 27 deletions
diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
index 1cd1797c1092..738e47b8b16c 100644
--- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
+++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
@@ -1156,8 +1156,10 @@ void MetadataLoader::MetadataLoaderImpl::lazyLoadOneMetadata(
assert(ID >= MDStringRef.size() && "Unexpected lazy-loading of MDString");
// Lookup first if the metadata hasn't already been loaded.
if (auto *MD = MetadataList.lookup(ID)) {
- auto *N = cast<MDNode>(MD);
- if (!N->isTemporary())
+ auto *N = dyn_cast<MDNode>(MD);
+ // If the node is not an MDNode, or if it is not temporary, then
+ // we're done.
+ if (!N || !N->isTemporary())
return;
}
SmallVector<uint64_t, 64> Record;
@@ -1287,6 +1289,14 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
return MetadataList.upgradeTypeRef(getMDOrNull(ID));
};
+ auto getMetadataOrConstant = [&](bool IsMetadata,
+ uint64_t Entry) -> Metadata * {
+ if (IsMetadata)
+ return getMDOrNull(Entry);
+ return ConstantAsMetadata::get(
+ ConstantInt::get(Type::getInt64Ty(Context), Entry));
+ };
+
#define GET_OR_DISTINCT(CLASS, ARGS) \
(IsDistinct ? CLASS::getDistinct ARGS : CLASS::get ARGS)
@@ -1416,7 +1426,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
break;
}
case bitc::METADATA_LOCATION: {
- if (Record.size() != 5 && Record.size() != 6)
+ // 5: inlinedAt, 6: isImplicit, 8: Key Instructions fields.
+ if (Record.size() != 5 && Record.size() != 6 && Record.size() != 8)
return error("Invalid record");
IsDistinct = Record[0];
@@ -1424,10 +1435,12 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
unsigned Column = Record[2];
Metadata *Scope = getMD(Record[3]);
Metadata *InlinedAt = getMDOrNull(Record[4]);
- bool ImplicitCode = Record.size() == 6 && Record[5];
+ bool ImplicitCode = Record.size() >= 6 && Record[5];
+ uint64_t AtomGroup = Record.size() == 8 ? Record[6] : 0;
+ uint8_t AtomRank = Record.size() == 8 ? Record[7] : 0;
MetadataList.assignValue(
GET_OR_DISTINCT(DILocation, (Context, Line, Column, Scope, InlinedAt,
- ImplicitCode)),
+ ImplicitCode, AtomGroup, AtomRank)),
NextMetadataNo);
NextMetadataNo++;
break;
@@ -1525,15 +1538,18 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
if (Record.size() < 6 || Record.size() > 8)
return error("Invalid record");
- IsDistinct = Record[0];
+ IsDistinct = Record[0] & 1;
+ bool SizeIsMetadata = Record[0] & 2;
DINode::DIFlags Flags = (Record.size() > 6)
? static_cast<DINode::DIFlags>(Record[6])
: DINode::FlagZero;
uint32_t NumExtraInhabitants = (Record.size() > 7) ? Record[7] : 0;
+ Metadata *SizeInBits = getMetadataOrConstant(SizeIsMetadata, Record[3]);
+
MetadataList.assignValue(
GET_OR_DISTINCT(DIBasicType,
- (Context, Record[1], getMDString(Record[2]), Record[3],
+ (Context, Record[1], getMDString(Record[2]), SizeInBits,
Record[4], Record[5], NumExtraInhabitants, Flags)),
NextMetadataNo);
NextMetadataNo++;
@@ -1543,9 +1559,12 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
if (Record.size() < 11)
return error("Invalid record");
- IsDistinct = Record[0];
+ IsDistinct = Record[0] & 1;
+ bool SizeIsMetadata = Record[0] & 2;
DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[6]);
+ Metadata *SizeInBits = getMetadataOrConstant(SizeIsMetadata, Record[3]);
+
size_t Offset = 9;
auto ReadWideInt = [&]() {
@@ -1565,7 +1584,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
MetadataList.assignValue(
GET_OR_DISTINCT(DIFixedPointType,
- (Context, Record[1], getMDString(Record[2]), Record[3],
+ (Context, Record[1], getMDString(Record[2]), SizeInBits,
Record[4], Record[5], Flags, Record[7], Record[8],
Numerator, Denominator)),
NextMetadataNo);
@@ -1576,17 +1595,21 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
if (Record.size() > 9 || Record.size() < 8)
return error("Invalid record");
- IsDistinct = Record[0];
+ IsDistinct = Record[0] & 1;
+ bool SizeIsMetadata = Record[0] & 2;
bool SizeIs8 = Record.size() == 8;
// StringLocationExp (i.e. Record[5]) is added at a later time
// than the other fields. The code here enables backward compatibility.
Metadata *StringLocationExp = SizeIs8 ? nullptr : getMDOrNull(Record[5]);
unsigned Offset = SizeIs8 ? 5 : 6;
+ Metadata *SizeInBits =
+ getMetadataOrConstant(SizeIsMetadata, Record[Offset]);
+
MetadataList.assignValue(
GET_OR_DISTINCT(DIStringType,
(Context, Record[1], getMDString(Record[2]),
getMDOrNull(Record[3]), getMDOrNull(Record[4]),
- StringLocationExp, Record[Offset], Record[Offset + 1],
+ StringLocationExp, SizeInBits, Record[Offset + 1],
Record[Offset + 2])),
NextMetadataNo);
NextMetadataNo++;
@@ -1615,15 +1638,20 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
PtrAuthData.emplace(Record[14]);
}
- IsDistinct = Record[0];
+ IsDistinct = Record[0] & 1;
+ bool SizeIsMetadata = Record[0] & 2;
DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[10]);
+
+ Metadata *SizeInBits = getMetadataOrConstant(SizeIsMetadata, Record[7]);
+ Metadata *OffsetInBits = getMetadataOrConstant(SizeIsMetadata, Record[9]);
+
MetadataList.assignValue(
GET_OR_DISTINCT(DIDerivedType,
(Context, Record[1], getMDString(Record[2]),
getMDOrNull(Record[3]), Record[4],
getDITypeRefOrNull(Record[5]),
- getDITypeRefOrNull(Record[6]), Record[7], Record[8],
- Record[9], DWARFAddressSpace, PtrAuthData, Flags,
+ getDITypeRefOrNull(Record[6]), SizeInBits, Record[8],
+ OffsetInBits, DWARFAddressSpace, PtrAuthData, Flags,
getDITypeRefOrNull(Record[11]), Annotations)),
NextMetadataNo);
NextMetadataNo++;
@@ -1633,13 +1661,17 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
if (Record.size() != 13)
return error("Invalid record");
- IsDistinct = Record[0];
+ IsDistinct = Record[0] & 1;
+ bool SizeIsMetadata = Record[0] & 2;
DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[7]);
+
+ Metadata *SizeInBits = getMetadataOrConstant(SizeIsMetadata, Record[5]);
+
MetadataList.assignValue(
GET_OR_DISTINCT(DISubrangeType,
(Context, getMDString(Record[1]),
getMDOrNull(Record[2]), Record[3],
- getMDOrNull(Record[4]), Record[5], Record[6], Flags,
+ getMDOrNull(Record[4]), SizeInBits, Record[6], Flags,
getDITypeRefOrNull(Record[8]), getMDOrNull(Record[9]),
getMDOrNull(Record[10]), getMDOrNull(Record[11]),
getMDOrNull(Record[12]))),
@@ -1654,18 +1686,18 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
// If we have a UUID and this is not a forward declaration, lookup the
// mapping.
IsDistinct = Record[0] & 0x1;
- bool IsNotUsedInTypeRef = Record[0] >= 2;
+ bool IsNotUsedInTypeRef = Record[0] & 2;
+ bool SizeIsMetadata = Record[0] & 4;
unsigned Tag = Record[1];
MDString *Name = getMDString(Record[2]);
Metadata *File = getMDOrNull(Record[3]);
unsigned Line = Record[4];
Metadata *Scope = getDITypeRefOrNull(Record[5]);
Metadata *BaseType = nullptr;
- uint64_t SizeInBits = Record[7];
if (Record[8] > (uint64_t)std::numeric_limits<uint32_t>::max())
return error("Alignment value is too large");
uint32_t AlignInBits = Record[8];
- uint64_t OffsetInBits = 0;
+ Metadata *OffsetInBits = nullptr;
uint32_t NumExtraInhabitants = (Record.size() > 22) ? Record[22] : 0;
DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[10]);
Metadata *Elements = nullptr;
@@ -1712,7 +1744,9 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
TemplateParams = getMDOrNull(Record[14]);
} else {
BaseType = getDITypeRefOrNull(Record[6]);
- OffsetInBits = Record[9];
+
+ OffsetInBits = getMetadataOrConstant(SizeIsMetadata, Record[9]);
+
Elements = getMDOrNull(Record[11]);
VTableHolder = getDITypeRefOrNull(Record[13]);
TemplateParams = getMDOrNull(Record[14]);
@@ -1740,6 +1774,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
if (Record.size() > 24 && Record[24] != dwarf::DW_APPLE_ENUM_KIND_invalid)
EnumKind = Record[24];
+ Metadata *SizeInBits = getMetadataOrConstant(SizeIsMetadata, Record[7]);
+
DICompositeType *CT = nullptr;
if (Identifier)
CT = DICompositeType::buildODRType(
@@ -1857,7 +1893,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
break;
}
case bitc::METADATA_SUBPROGRAM: {
- if (Record.size() < 18 || Record.size() > 21)
+ if (Record.size() < 18 || Record.size() > 22)
return error("Invalid record");
bool HasSPFlags = Record[0] & 4;
@@ -1909,6 +1945,9 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
bool HasTargetFuncName = false;
unsigned OffsetA = 0;
unsigned OffsetB = 0;
+ // Key instructions won't be enabled in old-format bitcode, so only
+ // check it if HasSPFlags is true.
+ bool UsesKeyInstructions = false;
if (!HasSPFlags) {
OffsetA = 2;
OffsetB = 2;
@@ -1921,7 +1960,9 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
} else {
HasAnnotations = Record.size() >= 19;
HasTargetFuncName = Record.size() >= 20;
+ UsesKeyInstructions = Record.size() >= 21 ? Record[20] : 0;
}
+
Metadata *CUorFn = getMDOrNull(Record[12 + OffsetB]);
DISubprogram *SP = GET_OR_DISTINCT(
DISubprogram,
@@ -1947,8 +1988,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
HasAnnotations ? getMDOrNull(Record[18 + OffsetB])
: nullptr, // annotations
HasTargetFuncName ? getMDString(Record[19 + OffsetB])
- : nullptr // targetFuncName
- ));
+ : nullptr, // targetFuncName
+ UsesKeyInstructions));
MetadataList.assignValue(SP, NextMetadataNo);
NextMetadataNo++;
@@ -2209,14 +2250,28 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
break;
}
case bitc::METADATA_LABEL: {
- if (Record.size() != 5)
+ if (Record.size() < 5 || Record.size() > 7)
return error("Invalid record");
IsDistinct = Record[0] & 1;
+ uint64_t Line = Record[4];
+ uint64_t Column = Record.size() > 5 ? Record[5] : 0;
+ bool IsArtificial = Record[0] & 2;
+ std::optional<unsigned> CoroSuspendIdx;
+ if (Record.size() > 6) {
+ uint64_t RawSuspendIdx = Record[6];
+ if (RawSuspendIdx != std::numeric_limits<uint64_t>::max()) {
+ if (RawSuspendIdx > (uint64_t)std::numeric_limits<unsigned>::max())
+ return error("CoroSuspendIdx value is too large");
+ CoroSuspendIdx = RawSuspendIdx;
+ }
+ }
+
MetadataList.assignValue(
- GET_OR_DISTINCT(DILabel, (Context, getMDOrNull(Record[1]),
- getMDString(Record[2]),
- getMDOrNull(Record[3]), Record[4])),
+ GET_OR_DISTINCT(DILabel,
+ (Context, getMDOrNull(Record[1]),
+ getMDString(Record[2]), getMDOrNull(Record[3]), Line,
+ Column, IsArtificial, CoroSuspendIdx)),
NextMetadataNo);
NextMetadataNo++;
break;