precompSrc->tpiMap.begin() +
precompDependency.getTypesCount());
- if (config->debugGHashes)
- funcIdToType = precompSrc->funcIdToType; // FIXME: Save copy
-
return Error::success();
}
});
}
-void TpiSource::mergeTypeRecord(CVType ty) {
+void TpiSource::mergeTypeRecord(TypeIndex curIndex, CVType ty) {
// Decide if the merged type goes into TPI or IPI.
bool isItem = isIdRecord(ty.kind());
MergedInfo &merged = isItem ? mergedIpi : mergedTpi;
uint32_t pdbHash = check(pdb::hashTypeRecord(CVType(newRec)));
merged.recSizes.push_back(static_cast<uint16_t>(newSize));
merged.recHashes.push_back(pdbHash);
+
+ // Retain a mapping from PDB function id to PDB function type. This mapping is
+ // used during symbol procesing to rewrite S_GPROC32_ID symbols to S_GPROC32
+ // symbols.
+ if (ty.kind() == LF_FUNC_ID || ty.kind() == LF_MFUNC_ID) {
+ bool success = ty.length() >= 12;
+ TypeIndex funcId = curIndex;
+ if (success)
+ success &= remapTypeIndex(funcId, TiRefKind::IndexRef);
+ TypeIndex funcType =
+ *reinterpret_cast<const TypeIndex *>(&newRec.data()[8]);
+ if (success) {
+ funcIdToType.push_back({funcId, funcType});
+ } else {
+ StringRef fname = file ? file->getName() : "<unknown PDB>";
+ warn("corrupt LF_[M]FUNC_ID record 0x" + utohexstr(curIndex.getIndex()) +
+ " in " + fname);
+ }
+ }
}
void TpiSource::mergeUniqueTypeRecords(ArrayRef<uint8_t> typeRecords,
forEachTypeChecked(typeRecords, [&](const CVType &ty) {
if (nextUniqueIndex != uniqueTypes.end() &&
*nextUniqueIndex == ghashIndex) {
- mergeTypeRecord(ty);
+ mergeTypeRecord(beginIndex + ghashIndex, ty);
++nextUniqueIndex;
}
- if (ty.kind() == LF_FUNC_ID || ty.kind() == LF_MFUNC_ID) {
- bool success = ty.length() >= 12;
- TypeIndex srcFuncIdIndex = beginIndex + ghashIndex;
- TypeIndex funcId = srcFuncIdIndex;
- TypeIndex funcType;
- if (success) {
- funcType = *reinterpret_cast<const TypeIndex *>(&ty.data()[8]);
- success &= remapTypeIndex(funcId, TiRefKind::IndexRef);
- success &= remapTypeIndex(funcType, TiRefKind::TypeRef);
- }
- if (success) {
- funcIdToType.insert({funcId, funcType});
- } else {
- StringRef fname = file ? file->getName() : "<unknown PDB>";
- warn("corrupt LF_[M]FUNC_ID record 0x" +
- utohexstr(srcFuncIdIndex.getIndex()) + " in " + fname);
- }
- }
++ghashIndex;
});
assert(nextUniqueIndex == uniqueTypes.end() &&
ipiSrc->tpiMap = tpiMap;
ipiSrc->ipiMap = ipiMap;
ipiSrc->mergeUniqueTypeRecords(typeArrayToBytes(ipi.typeArray()));
- funcIdToType = ipiSrc->funcIdToType; // FIXME: Save copy
}
}
TypeServerSource *tsSrc = *maybeTsSrc;
tpiMap = tsSrc->tpiMap;
ipiMap = tsSrc->ipiMap;
- funcIdToType = tsSrc->funcIdToType; // FIXME: Save copy
}
void PrecompSource::loadGHashes() {
source->remapTpiWithGHashes(&ghashState);
});
+ // Build a global map of from function ID to function type.
+ for (TpiSource *source : TpiSource::instances) {
+ for (auto idToType : source->funcIdToType)
+ funcIdToType.insert(idToType);
+ source->funcIdToType.clear();
+ }
+
TpiSource::clearGHashes();
}
void remapRecord(MutableArrayRef<uint8_t> rec,
ArrayRef<llvm::codeview::TiReference> typeRefs);
- void mergeTypeRecord(llvm::codeview::CVType ty);
+ void mergeTypeRecord(TypeIndex curIndex, llvm::codeview::CVType ty);
// Merge the type records listed in uniqueTypes. beginIndex is the TypeIndex
// of the first record in this source, typically 0x1000. When PCHs are
/// When ghashing is used, record the mapping from LF_[M]FUNC_ID to function
/// type index here. Both indices are PDB indices, not object type indexes.
- llvm::DenseMap<TypeIndex, TypeIndex> funcIdToType;
+ std::vector<std::pair<TypeIndex, TypeIndex>> funcIdToType;
/// Indicates if a type record is an item index or a type index.
llvm::BitVector isItemIndex;
// in both cases we just need the second type index.
if (!ti->isSimple() && !ti->isNoneType()) {
if (config->debugGHashes) {
- auto idToType = source->funcIdToType.find(*ti);
- if (idToType == source->funcIdToType.end()) {
+ auto idToType = tMerger.funcIdToType.find(*ti);
+ if (idToType == tMerger.funcIdToType.end()) {
warn(formatv("S_[GL]PROC32_ID record in {0} refers to PDB item "
"index {1:X} which is not a LF_[M]FUNC_ID record",
source->file->getName(), ti->getIndex()));