aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/DebugInfo/CodeView
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-07-30 16:33:32 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-07-30 16:33:32 +0000
commit51315c45ff5643a27f9c84b816db54ee870ba29b (patch)
tree1d87443fa0e53d3e6b315ce25787e64be0906bf7 /contrib/llvm/lib/DebugInfo/CodeView
parent6dfd050075216be8538ae375a22d30db72916f7e (diff)
parenteb11fae6d08f479c0799db45860a98af528fa6e7 (diff)
Merge llvm trunk r338150, and resolve conflicts.
Notes
Notes: svn path=/projects/clang700-import/; revision=336916
Diffstat (limited to 'contrib/llvm/lib/DebugInfo/CodeView')
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/DebugChecksumsSubsection.cpp2
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp8
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp34
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp37
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/RecordName.cpp31
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp1
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp16
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/TypeHashing.cpp11
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp4
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp15
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp179
11 files changed, 191 insertions, 147 deletions
diff --git a/contrib/llvm/lib/DebugInfo/CodeView/DebugChecksumsSubsection.cpp b/contrib/llvm/lib/DebugInfo/CodeView/DebugChecksumsSubsection.cpp
index ccc20eb74887..0f155a95d607 100644
--- a/contrib/llvm/lib/DebugInfo/CodeView/DebugChecksumsSubsection.cpp
+++ b/contrib/llvm/lib/DebugInfo/CodeView/DebugChecksumsSubsection.cpp
@@ -109,7 +109,7 @@ Error DebugChecksumsSubsection::commit(BinaryStreamWriter &Writer) const {
}
uint32_t DebugChecksumsSubsection::mapChecksumOffset(StringRef FileName) const {
- uint32_t Offset = Strings.getStringId(FileName);
+ uint32_t Offset = Strings.getIdForString(FileName);
auto Iter = OffsetMap.find(Offset);
assert(Iter != OffsetMap.end());
return Iter->second;
diff --git a/contrib/llvm/lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp b/contrib/llvm/lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp
index 88c0076915b5..bf9dd7c86862 100644
--- a/contrib/llvm/lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp
+++ b/contrib/llvm/lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp
@@ -79,14 +79,14 @@ Error DebugCrossModuleImportsSubsection::commit(
for (const auto &M : Mappings)
Ids.push_back(&M);
- std::sort(Ids.begin(), Ids.end(), [this](const T &L1, const T &L2) {
- return Strings.getStringId(L1->getKey()) <
- Strings.getStringId(L2->getKey());
+ llvm::sort(Ids.begin(), Ids.end(), [this](const T &L1, const T &L2) {
+ return Strings.getIdForString(L1->getKey()) <
+ Strings.getIdForString(L2->getKey());
});
for (const auto &Item : Ids) {
CrossModuleImport Imp;
- Imp.ModuleNameOffset = Strings.getStringId(Item->getKey());
+ Imp.ModuleNameOffset = Strings.getIdForString(Item->getKey());
Imp.Count = Item->getValue().size();
if (auto EC = Writer.writeObject(Imp))
return EC;
diff --git a/contrib/llvm/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp b/contrib/llvm/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp
index d723282eb715..d2acc9a21003 100644
--- a/contrib/llvm/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp
+++ b/contrib/llvm/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp
@@ -46,12 +46,15 @@ DebugStringTableSubsection::DebugStringTableSubsection()
: DebugSubsection(DebugSubsectionKind::StringTable) {}
uint32_t DebugStringTableSubsection::insert(StringRef S) {
- auto P = Strings.insert({S, StringSize});
+ auto P = StringToId.insert({S, StringSize});
// If a given string didn't exist in the string table, we want to increment
- // the string table size.
- if (P.second)
+ // the string table size and insert it into the reverse lookup.
+ if (P.second) {
+ IdToString.insert({P.first->getValue(), P.first->getKey()});
StringSize += S.size() + 1; // +1 for '\0'
+ }
+
return P.first->second;
}
@@ -67,7 +70,7 @@ Error DebugStringTableSubsection::commit(BinaryStreamWriter &Writer) const {
if (auto EC = Writer.writeCString(StringRef()))
return EC;
- for (auto &Pair : Strings) {
+ for (auto &Pair : StringToId) {
StringRef S = Pair.getKey();
uint32_t Offset = Begin + Pair.getValue();
Writer.setOffset(Offset);
@@ -81,10 +84,25 @@ Error DebugStringTableSubsection::commit(BinaryStreamWriter &Writer) const {
return Error::success();
}
-uint32_t DebugStringTableSubsection::size() const { return Strings.size(); }
+uint32_t DebugStringTableSubsection::size() const { return StringToId.size(); }
+
+std::vector<uint32_t> DebugStringTableSubsection::sortedIds() const {
+ std::vector<uint32_t> Result;
+ Result.reserve(IdToString.size());
+ for (const auto &Entry : IdToString)
+ Result.push_back(Entry.first);
+ llvm::sort(Result.begin(), Result.end());
+ return Result;
+}
+
+uint32_t DebugStringTableSubsection::getIdForString(StringRef S) const {
+ auto Iter = StringToId.find(S);
+ assert(Iter != StringToId.end());
+ return Iter->second;
+}
-uint32_t DebugStringTableSubsection::getStringId(StringRef S) const {
- auto Iter = Strings.find(S);
- assert(Iter != Strings.end());
+StringRef DebugStringTableSubsection::getStringForId(uint32_t Id) const {
+ auto Iter = IdToString.find(Id);
+ assert(Iter != IdToString.end());
return Iter->second;
}
diff --git a/contrib/llvm/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp b/contrib/llvm/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp
index 3ecd684c1e39..e76f9e12f0af 100644
--- a/contrib/llvm/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp
+++ b/contrib/llvm/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp
@@ -55,9 +55,12 @@ Optional<TypeIndex> GlobalTypeTableBuilder::getNext(TypeIndex Prev) {
CVType GlobalTypeTableBuilder::getType(TypeIndex Index) {
CVType Type;
Type.RecordData = SeenRecords[Index.toArrayIndex()];
- const RecordPrefix *P =
- reinterpret_cast<const RecordPrefix *>(Type.RecordData.data());
- Type.Type = static_cast<TypeLeafKind>(uint16_t(P->RecordKind));
+ if (!Type.RecordData.empty()) {
+ assert(Type.RecordData.size() >= sizeof(RecordPrefix));
+ const RecordPrefix *P =
+ reinterpret_cast<const RecordPrefix *>(Type.RecordData.data());
+ Type.Type = static_cast<TypeLeafKind>(uint16_t(P->RecordKind));
+ }
return Type;
}
@@ -89,31 +92,15 @@ void GlobalTypeTableBuilder::reset() {
SeenRecords.clear();
}
-static inline ArrayRef<uint8_t> stabilize(BumpPtrAllocator &Alloc,
- ArrayRef<uint8_t> Data) {
- uint8_t *Stable = Alloc.Allocate<uint8_t>(Data.size());
- memcpy(Stable, Data.data(), Data.size());
- return makeArrayRef(Stable, Data.size());
-}
-
-TypeIndex GlobalTypeTableBuilder::insertRecordAs(GloballyHashedType Hash,
- CreateRecord Create) {
- auto Result = HashedRecords.try_emplace(Hash, nextTypeIndex());
-
- if (Result.second) {
- ArrayRef<uint8_t> RecordData = stabilize(RecordStorage, Create());
- SeenRecords.push_back(RecordData);
- SeenHashes.push_back(Hash);
- }
-
- // Update the caller's copy of Record to point a stable copy.
- return Result.first->second;
-}
-
TypeIndex GlobalTypeTableBuilder::insertRecordBytes(ArrayRef<uint8_t> Record) {
GloballyHashedType GHT =
GloballyHashedType::hashType(Record, SeenHashes, SeenHashes);
- return insertRecordAs(GHT, [Record]() { return Record; });
+ return insertRecordAs(GHT, Record.size(),
+ [Record](MutableArrayRef<uint8_t> Data) {
+ assert(Data.size() == Record.size());
+ ::memcpy(Data.data(), Record.data(), Record.size());
+ return Data;
+ });
}
TypeIndex
diff --git a/contrib/llvm/lib/DebugInfo/CodeView/RecordName.cpp b/contrib/llvm/lib/DebugInfo/CodeView/RecordName.cpp
index 15fb1724d23d..e50c43a1d481 100644
--- a/contrib/llvm/lib/DebugInfo/CodeView/RecordName.cpp
+++ b/contrib/llvm/lib/DebugInfo/CodeView/RecordName.cpp
@@ -167,13 +167,6 @@ Error TypeNameComputer::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
StringRef Class = Types.getTypeName(MI.getContainingType());
Name = formatv("{0} {1}::*", Pointee, Class);
} else {
- if (Ptr.isConst())
- Name.append("const ");
- if (Ptr.isVolatile())
- Name.append("volatile ");
- if (Ptr.isUnaligned())
- Name.append("__unaligned ");
-
Name.append(Types.getTypeName(Ptr.getReferentType()));
if (Ptr.getMode() == PointerMode::LValueReference)
@@ -182,6 +175,17 @@ Error TypeNameComputer::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
Name.append("&&");
else if (Ptr.getMode() == PointerMode::Pointer)
Name.append("*");
+
+ // Qualifiers in pointer records apply to the pointer, not the pointee, so
+ // they go on the right.
+ if (Ptr.isConst())
+ Name.append(" const");
+ if (Ptr.isVolatile())
+ Name.append(" volatile");
+ if (Ptr.isUnaligned())
+ Name.append(" __unaligned");
+ if (Ptr.isRestrict())
+ Name.append(" __restrict");
}
return Error::success();
}
@@ -189,7 +193,6 @@ Error TypeNameComputer::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
Error TypeNameComputer::visitKnownRecord(CVType &CVR, ModifierRecord &Mod) {
uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
- SmallString<256> TypeName;
if (Mods & uint16_t(ModifierOptions::Const))
Name.append("const ");
if (Mods & uint16_t(ModifierOptions::Volatile))
@@ -233,6 +236,16 @@ Error TypeNameComputer::visitKnownRecord(CVType &CVR, LabelRecord &R) {
return Error::success();
}
+Error TypeNameComputer::visitKnownRecord(CVType &CVR,
+ PrecompRecord &Precomp) {
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR,
+ EndPrecompRecord &EndPrecomp) {
+ return Error::success();
+}
+
std::string llvm::codeview::computeTypeName(TypeCollection &Types,
TypeIndex Index) {
TypeNameComputer Computer(Types);
@@ -273,6 +286,8 @@ static int getSymbolNameOffset(CVSymbol Sym) {
case SymbolKind::S_GMANDATA:
case SymbolKind::S_LTHREAD32:
case SymbolKind::S_GTHREAD32:
+ case SymbolKind::S_PROCREF:
+ case SymbolKind::S_LPROCREF:
return 10;
// See RegisterSym and LocalSym
case SymbolKind::S_REGISTER:
diff --git a/contrib/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp b/contrib/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
index df75f52661e1..af249adc9774 100644
--- a/contrib/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
+++ b/contrib/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
@@ -129,6 +129,7 @@ Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, BlockSym &Block) {
}
Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, Thunk32Sym &Thunk) {
+ W.printString("Name", Thunk.Name);
W.printNumber("Parent", Thunk.Parent);
W.printNumber("End", Thunk.End);
W.printNumber("Next", Thunk.Next);
diff --git a/contrib/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp b/contrib/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
index e7998b8732fe..7c68c9167c98 100644
--- a/contrib/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
+++ b/contrib/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
@@ -370,6 +370,7 @@ Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
W->printNumber("IsConst", Ptr.isConst());
W->printNumber("IsVolatile", Ptr.isVolatile());
W->printNumber("IsUnaligned", Ptr.isUnaligned());
+ W->printNumber("IsRestrict", Ptr.isRestrict());
W->printNumber("SizeOf", Ptr.getSize());
if (Ptr.isPointerToMember()) {
@@ -552,3 +553,18 @@ Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, LabelRecord &LR) {
W->printEnum("Mode", uint16_t(LR.Mode), makeArrayRef(LabelTypeEnum));
return Error::success();
}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
+ PrecompRecord &Precomp) {
+ W->printHex("StartIndex", Precomp.getStartTypeIndex());
+ W->printHex("Count", Precomp.getTypesCount());
+ W->printHex("Signature", Precomp.getSignature());
+ W->printString("PrecompFile", Precomp.getPrecompFilePath());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
+ EndPrecompRecord &EndPrecomp) {
+ W->printHex("Signature", EndPrecomp.getSignature());
+ return Error::success();
+}
diff --git a/contrib/llvm/lib/DebugInfo/CodeView/TypeHashing.cpp b/contrib/llvm/lib/DebugInfo/CodeView/TypeHashing.cpp
index f5b28b2a2070..826faef35875 100644
--- a/contrib/llvm/lib/DebugInfo/CodeView/TypeHashing.cpp
+++ b/contrib/llvm/lib/DebugInfo/CodeView/TypeHashing.cpp
@@ -18,10 +18,10 @@ using namespace llvm::codeview;
LocallyHashedType DenseMapInfo<LocallyHashedType>::Empty{0, {}};
LocallyHashedType DenseMapInfo<LocallyHashedType>::Tombstone{hash_code(-1), {}};
-static std::array<uint8_t, 20> EmptyHash;
-static std::array<uint8_t, 20> TombstoneHash = {
- {0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
+static std::array<uint8_t, 8> EmptyHash = {
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
+static std::array<uint8_t, 8> TombstoneHash = {
+ {0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
GloballyHashedType DenseMapInfo<GloballyHashedType>::Empty{EmptyHash};
GloballyHashedType DenseMapInfo<GloballyHashedType>::Tombstone{TombstoneHash};
@@ -39,6 +39,7 @@ GloballyHashedType::hashType(ArrayRef<uint8_t> RecordData,
SHA1 S;
S.init();
uint32_t Off = 0;
+ S.update(RecordData.take_front(sizeof(RecordPrefix)));
RecordData = RecordData.drop_front(sizeof(RecordPrefix));
for (const auto &Ref : Refs) {
// Hash any data that comes before this TiRef.
@@ -70,5 +71,5 @@ GloballyHashedType::hashType(ArrayRef<uint8_t> RecordData,
auto TrailingBytes = RecordData.drop_front(Off);
S.update(TrailingBytes);
- return {S.final()};
+ return {S.final().take_back(8)};
}
diff --git a/contrib/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp b/contrib/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
index d283e9e6d2f1..95082d4a8e03 100644
--- a/contrib/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
+++ b/contrib/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
@@ -58,7 +58,7 @@ static inline uint32_t getEncodedIntegerLength(ArrayRef<uint8_t> Data) {
8, // LF_UQUADWORD
};
- return Sizes[N - LF_NUMERIC];
+ return 2 + Sizes[N - LF_NUMERIC];
}
static inline uint32_t getCStringLength(ArrayRef<uint8_t> Data) {
@@ -393,7 +393,7 @@ static bool discoverTypeIndices(ArrayRef<uint8_t> Content, SymbolKind Kind,
Refs.push_back({TiRefKind::TypeRef, 0, 1}); // Type
break;
case SymbolKind::S_REGISTER:
- Refs.push_back({TiRefKind::TypeRef, 0, 1}); // Type;
+ Refs.push_back({TiRefKind::TypeRef, 0, 1}); // Type
break;
case SymbolKind::S_CONSTANT:
Refs.push_back({TiRefKind::TypeRef, 0, 1}); // Type
diff --git a/contrib/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp b/contrib/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
index 9b8a6053da84..3203ff64d3b1 100644
--- a/contrib/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
+++ b/contrib/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
@@ -480,3 +480,18 @@ Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
return Error::success();
}
+
+Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
+ PrecompRecord &Precomp) {
+ error(IO.mapInteger(Precomp.StartTypeIndex));
+ error(IO.mapInteger(Precomp.TypesCount));
+ error(IO.mapInteger(Precomp.Signature));
+ error(IO.mapStringZ(Precomp.PrecompFilePath));
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
+ EndPrecompRecord &EndPrecomp) {
+ error(IO.mapInteger(EndPrecomp.Signature));
+ return Error::success();
+}
diff --git a/contrib/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp b/contrib/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
index 6a94952c175b..e4f39dd988e1 100644
--- a/contrib/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
+++ b/contrib/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
@@ -20,6 +20,11 @@
using namespace llvm;
using namespace llvm::codeview;
+static inline size_t slotForIndex(TypeIndex Idx) {
+ assert(!Idx.isSimple() && "simple type indices have no slots");
+ return Idx.getIndex() - TypeIndex::FirstNonSimpleIndex;
+}
+
namespace {
/// Implementation of CodeView type stream merging.
@@ -94,8 +99,22 @@ private:
void addMapping(TypeIndex Idx);
- bool remapTypeIndex(TypeIndex &Idx);
- bool remapItemIndex(TypeIndex &Idx);
+ inline bool remapTypeIndex(TypeIndex &Idx) {
+ // If we're mapping a pure index stream, then IndexMap only contains
+ // mappings from OldIdStream -> NewIdStream, in which case we will need to
+ // use the special mapping from OldTypeStream -> NewTypeStream which was
+ // computed externally. Regardless, we use this special map if and only if
+ // we are doing an id-only mapping.
+ if (!hasTypeStream())
+ return remapIndex(Idx, TypeLookup);
+
+ assert(TypeLookup.empty());
+ return remapIndex(Idx, IndexMap);
+ }
+ inline bool remapItemIndex(TypeIndex &Idx) {
+ assert(hasIdStream());
+ return remapIndex(Idx, IndexMap);
+ }
bool hasTypeStream() const {
return (UseGlobalHashes) ? (!!DestGlobalTypeStream) : (!!DestTypeStream);
@@ -105,17 +124,34 @@ private:
return (UseGlobalHashes) ? (!!DestGlobalIdStream) : (!!DestIdStream);
}
- ArrayRef<uint8_t> serializeRemapped(const RemappedType &Record);
+ ArrayRef<uint8_t> remapIndices(const CVType &OriginalType,
+ MutableArrayRef<uint8_t> Storage);
- bool remapIndices(RemappedType &Record, ArrayRef<TiReference> Refs);
+ inline bool remapIndex(TypeIndex &Idx, ArrayRef<TypeIndex> Map) {
+ if (LLVM_LIKELY(remapIndexSimple(Idx, Map)))
+ return true;
- bool remapIndex(TypeIndex &Idx, ArrayRef<TypeIndex> Map);
+ return remapIndexFallback(Idx, Map);
+ }
+
+ inline bool remapIndexSimple(TypeIndex &Idx, ArrayRef<TypeIndex> Map) const {
+ // Simple types are unchanged.
+ if (Idx.isSimple())
+ return true;
- size_t slotForIndex(TypeIndex Idx) const {
- assert(!Idx.isSimple() && "simple type indices have no slots");
- return Idx.getIndex() - TypeIndex::FirstNonSimpleIndex;
+ // Check if this type index refers to a record we've already translated
+ // successfully. If it refers to a type later in the stream or a record we
+ // had to defer, defer it until later pass.
+ unsigned MapPos = slotForIndex(Idx);
+ if (LLVM_UNLIKELY(MapPos >= Map.size() || Map[MapPos] == Untranslated))
+ return false;
+
+ Idx = Map[MapPos];
+ return true;
}
+ bool remapIndexFallback(TypeIndex &Idx, ArrayRef<TypeIndex> Map);
+
Error errorCorruptRecord() const {
return llvm::make_error<CodeViewError>(cv_error_code::corrupt_record);
}
@@ -153,27 +189,6 @@ private:
} // end anonymous namespace
-ArrayRef<uint8_t>
-TypeStreamMerger::serializeRemapped(const RemappedType &Record) {
- TypeIndex TI;
- ArrayRef<uint8_t> OriginalData = Record.OriginalRecord.RecordData;
- if (Record.Mappings.empty())
- return OriginalData;
-
- // At least one type index was remapped. We copy the full record bytes,
- // re-write each type index, then return that.
- RemapStorage.resize(OriginalData.size());
- ::memcpy(&RemapStorage[0], OriginalData.data(), OriginalData.size());
- uint8_t *ContentBegin = RemapStorage.data() + sizeof(RecordPrefix);
- for (const auto &M : Record.Mappings) {
- // First 4 bytes of every record are the record prefix, but the mapping
- // offset is relative to the content which starts after.
- *(TypeIndex *)(ContentBegin + M.first) = M.second;
- }
- auto RemapRef = makeArrayRef(RemapStorage);
- return RemapRef;
-}
-
const TypeIndex TypeStreamMerger::Untranslated(SimpleTypeKind::NotTranslated);
static bool isIdRecord(TypeLeafKind K) {
@@ -202,19 +217,9 @@ void TypeStreamMerger::addMapping(TypeIndex Idx) {
}
}
-bool TypeStreamMerger::remapIndex(TypeIndex &Idx, ArrayRef<TypeIndex> Map) {
- // Simple types are unchanged.
- if (Idx.isSimple())
- return true;
-
- // Check if this type index refers to a record we've already translated
- // successfully. If it refers to a type later in the stream or a record we
- // had to defer, defer it until later pass.
- unsigned MapPos = slotForIndex(Idx);
- if (MapPos < Map.size() && Map[MapPos] != Untranslated) {
- Idx = Map[MapPos];
- return true;
- }
+bool TypeStreamMerger::remapIndexFallback(TypeIndex &Idx,
+ ArrayRef<TypeIndex> Map) {
+ size_t MapPos = slotForIndex(Idx);
// If this is the second pass and this index isn't in the map, then it points
// outside the current type stream, and this is a corrupt record.
@@ -232,24 +237,6 @@ bool TypeStreamMerger::remapIndex(TypeIndex &Idx, ArrayRef<TypeIndex> Map) {
return false;
}
-bool TypeStreamMerger::remapTypeIndex(TypeIndex &Idx) {
- // If we're mapping a pure index stream, then IndexMap only contains mappings
- // from OldIdStream -> NewIdStream, in which case we will need to use the
- // special mapping from OldTypeStream -> NewTypeStream which was computed
- // externally. Regardless, we use this special map if and only if we are
- // doing an id-only mapping.
- if (!hasTypeStream())
- return remapIndex(Idx, TypeLookup);
-
- assert(TypeLookup.empty());
- return remapIndex(Idx, IndexMap);
-}
-
-bool TypeStreamMerger::remapItemIndex(TypeIndex &Idx) {
- assert(hasIdStream());
- return remapIndex(Idx, IndexMap);
-}
-
// Local hashing entry points
Error TypeStreamMerger::mergeTypeRecords(MergingTypeTableBuilder &Dest,
const CVTypeArray &Types) {
@@ -346,35 +333,34 @@ Error TypeStreamMerger::doit(const CVTypeArray &Types) {
}
Error TypeStreamMerger::remapAllTypes(const CVTypeArray &Types) {
- for (const CVType &Type : Types)
- if (auto EC = remapType(Type))
- return EC;
- return Error::success();
+ BinaryStreamRef Stream = Types.getUnderlyingStream();
+ ArrayRef<uint8_t> Buffer;
+ cantFail(Stream.readBytes(0, Stream.getLength(), Buffer));
+
+ return forEachCodeViewRecord<CVType>(
+ Buffer, [this](const CVType &T) { return remapType(T); });
}
Error TypeStreamMerger::remapType(const CVType &Type) {
- auto DoSerialize = [this, Type]() -> ArrayRef<uint8_t> {
- RemappedType R(Type);
- SmallVector<TiReference, 32> Refs;
- discoverTypeIndices(Type.RecordData, Refs);
- if (!remapIndices(R, Refs))
- return {};
- return serializeRemapped(R);
+ auto DoSerialize =
+ [this, Type](MutableArrayRef<uint8_t> Storage) -> ArrayRef<uint8_t> {
+ return remapIndices(Type, Storage);
};
TypeIndex DestIdx = Untranslated;
- if (UseGlobalHashes) {
+ if (LLVM_LIKELY(UseGlobalHashes)) {
GlobalTypeTableBuilder &Dest =
isIdRecord(Type.kind()) ? *DestGlobalIdStream : *DestGlobalTypeStream;
GloballyHashedType H = GlobalHashes[CurIndex.toArrayIndex()];
- DestIdx = Dest.insertRecordAs(H, DoSerialize);
+ DestIdx = Dest.insertRecordAs(H, Type.RecordData.size(), DoSerialize);
} else {
MergingTypeTableBuilder &Dest =
isIdRecord(Type.kind()) ? *DestIdStream : *DestTypeStream;
- auto Data = DoSerialize();
- if (!Data.empty())
- DestIdx = Dest.insertRecordBytes(Data);
+ RemapStorage.resize(Type.RecordData.size());
+ ArrayRef<uint8_t> Result = DoSerialize(RemapStorage);
+ if (!Result.empty())
+ DestIdx = Dest.insertRecordBytes(Result);
}
addMapping(DestIdx);
@@ -384,27 +370,32 @@ Error TypeStreamMerger::remapType(const CVType &Type) {
return Error::success();
}
-bool TypeStreamMerger::remapIndices(RemappedType &Record,
- ArrayRef<TiReference> Refs) {
- ArrayRef<uint8_t> OriginalData = Record.OriginalRecord.content();
- bool Success = true;
+ArrayRef<uint8_t>
+TypeStreamMerger::remapIndices(const CVType &OriginalType,
+ MutableArrayRef<uint8_t> Storage) {
+ SmallVector<TiReference, 4> Refs;
+ discoverTypeIndices(OriginalType.RecordData, Refs);
+ if (Refs.empty())
+ return OriginalType.RecordData;
+
+ ::memcpy(Storage.data(), OriginalType.RecordData.data(),
+ OriginalType.RecordData.size());
+
+ uint8_t *DestContent = Storage.data() + sizeof(RecordPrefix);
+
for (auto &Ref : Refs) {
- uint32_t Offset = Ref.Offset;
- ArrayRef<uint8_t> Bytes = OriginalData.slice(Ref.Offset, sizeof(TypeIndex));
- ArrayRef<TypeIndex> TIs(reinterpret_cast<const TypeIndex *>(Bytes.data()),
- Ref.Count);
- for (auto TI : TIs) {
- TypeIndex NewTI = TI;
- bool ThisSuccess = (Ref.Kind == TiRefKind::IndexRef)
- ? remapItemIndex(NewTI)
- : remapTypeIndex(NewTI);
- if (ThisSuccess && NewTI != TI)
- Record.Mappings.emplace_back(Offset, NewTI);
- Offset += sizeof(TypeIndex);
- Success &= ThisSuccess;
+ TypeIndex *DestTIs =
+ reinterpret_cast<TypeIndex *>(DestContent + Ref.Offset);
+
+ for (size_t I = 0; I < Ref.Count; ++I) {
+ TypeIndex &TI = DestTIs[I];
+ bool Success = (Ref.Kind == TiRefKind::IndexRef) ? remapItemIndex(TI)
+ : remapTypeIndex(TI);
+ if (LLVM_UNLIKELY(!Success))
+ return {};
}
}
- return Success;
+ return Storage;
}
Error llvm::codeview::mergeTypeRecords(MergingTypeTableBuilder &Dest,