mirror of
https://github.com/RPCS3/llvm.git
synced 2025-04-08 00:01:37 +00:00

Summary: This code is intended to be used as part of LLD's PDB writing. Until that exists, this is exposed via llvm-readobj for testing purposes. Type stream merging uses the following algorithm: - Begin with a new empty stream, and a new empty hash table that maps from type record contents to new type index. - For each new type stream, maintain a map from source type index to destination type index. - For each record, copy it and rewrite its type indices to be valid in the destination type stream. - If the new type record is not already present in the destination stream hash table, append it to the destination type stream, assign it the next type index, and update the two hash tables. - If the type record already exists in the destination stream, discard it and update the type index map to forward the source type index to the existing destination type index. Reviewers: zturner, ruiu Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D20122 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@269521 91177308-0d34-0410-b5e6-96231b3b80d8
133 lines
4.3 KiB
C++
133 lines
4.3 KiB
C++
//===-- FieldListRecordBuilder.cpp ----------------------------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/DebugInfo/CodeView/FieldListRecordBuilder.h"
|
|
|
|
using namespace llvm;
|
|
using namespace codeview;
|
|
|
|
FieldListRecordBuilder::FieldListRecordBuilder()
|
|
: ListRecordBuilder(TypeRecordKind::FieldList) {}
|
|
|
|
void FieldListRecordBuilder::writeBaseClass(const BaseClassRecord &Record) {
|
|
TypeRecordBuilder &Builder = getBuilder();
|
|
|
|
Builder.writeTypeRecordKind(TypeRecordKind::BaseClass);
|
|
Builder.writeUInt16(static_cast<uint16_t>(Record.getAccess()));
|
|
Builder.writeTypeIndex(Record.getBaseType());
|
|
Builder.writeEncodedUnsignedInteger(Record.getBaseOffset());
|
|
|
|
finishSubRecord();
|
|
}
|
|
|
|
void FieldListRecordBuilder::writeEnumerator(const EnumeratorRecord &Record) {
|
|
TypeRecordBuilder &Builder = getBuilder();
|
|
|
|
Builder.writeTypeRecordKind(TypeRecordKind::Enumerator);
|
|
Builder.writeUInt16(static_cast<uint16_t>(Record.getAccess()));
|
|
// FIXME: Handle full APInt such as __int128.
|
|
Builder.writeEncodedUnsignedInteger(Record.getValue().getZExtValue());
|
|
Builder.writeNullTerminatedString(Record.getName());
|
|
|
|
finishSubRecord();
|
|
}
|
|
|
|
void FieldListRecordBuilder::writeDataMember(const DataMemberRecord &Record) {
|
|
TypeRecordBuilder &Builder = getBuilder();
|
|
|
|
Builder.writeTypeRecordKind(Record.getKind());
|
|
Builder.writeUInt16(static_cast<uint16_t>(Record.getAccess()));
|
|
Builder.writeTypeIndex(Record.getType());
|
|
Builder.writeEncodedUnsignedInteger(Record.getFieldOffset());
|
|
Builder.writeNullTerminatedString(Record.getName());
|
|
|
|
finishSubRecord();
|
|
}
|
|
|
|
void FieldListRecordBuilder::writeOverloadedMethod(
|
|
const OverloadedMethodRecord &Record) {
|
|
TypeRecordBuilder &Builder = getBuilder();
|
|
|
|
Builder.writeTypeRecordKind(TypeRecordKind::OverloadedMethod);
|
|
Builder.writeUInt16(Record.getNumOverloads());
|
|
Builder.writeTypeIndex(Record.getMethodList());
|
|
Builder.writeNullTerminatedString(Record.getName());
|
|
|
|
finishSubRecord();
|
|
}
|
|
|
|
void FieldListRecordBuilder::writeOneMethod(const OneMethodRecord &Record) {
|
|
TypeRecordBuilder &Builder = getBuilder();
|
|
|
|
uint16_t Flags = static_cast<uint16_t>(Record.getAccess());
|
|
Flags |= static_cast<uint16_t>(Record.getKind()) << MethodKindShift;
|
|
Flags |= static_cast<uint16_t>(Record.getOptions());
|
|
|
|
Builder.writeTypeRecordKind(TypeRecordKind::OneMethod);
|
|
Builder.writeUInt16(Flags);
|
|
Builder.writeTypeIndex(Record.getType());
|
|
if (Record.isIntroducingVirtual()) {
|
|
assert(Record.getVFTableOffset() >= 0);
|
|
Builder.writeInt32(Record.getVFTableOffset());
|
|
} else {
|
|
assert(Record.getVFTableOffset() == -1);
|
|
}
|
|
|
|
Builder.writeNullTerminatedString(Record.getName());
|
|
|
|
finishSubRecord();
|
|
}
|
|
|
|
void FieldListRecordBuilder::writeNestedType(const NestedTypeRecord &Record) {
|
|
TypeRecordBuilder &Builder = getBuilder();
|
|
|
|
Builder.writeTypeRecordKind(Record.getKind());
|
|
Builder.writeUInt16(0);
|
|
Builder.writeTypeIndex(Record.getNestedType());
|
|
Builder.writeNullTerminatedString(Record.getName());
|
|
|
|
finishSubRecord();
|
|
}
|
|
|
|
void FieldListRecordBuilder::writeStaticDataMember(
|
|
const StaticDataMemberRecord &Record) {
|
|
TypeRecordBuilder &Builder = getBuilder();
|
|
|
|
Builder.writeTypeRecordKind(Record.getKind());
|
|
Builder.writeUInt16(static_cast<uint16_t>(Record.getAccess()));
|
|
Builder.writeTypeIndex(Record.getType());
|
|
Builder.writeNullTerminatedString(Record.getName());
|
|
|
|
finishSubRecord();
|
|
}
|
|
|
|
void FieldListRecordBuilder::writeVirtualBaseClass(
|
|
const VirtualBaseClassRecord &Record) {
|
|
TypeRecordBuilder &Builder = getBuilder();
|
|
|
|
Builder.writeTypeRecordKind(Record.getKind());
|
|
Builder.writeUInt16(static_cast<uint16_t>(Record.getAccess()));
|
|
Builder.writeTypeIndex(Record.getBaseType());
|
|
Builder.writeTypeIndex(Record.getVBPtrType());
|
|
Builder.writeEncodedInteger(Record.getVBPtrOffset());
|
|
Builder.writeEncodedUnsignedInteger(Record.getVTableIndex());
|
|
|
|
finishSubRecord();
|
|
}
|
|
|
|
void FieldListRecordBuilder::writeVFPtr(const VFPtrRecord &Record) {
|
|
TypeRecordBuilder &Builder = getBuilder();
|
|
|
|
Builder.writeTypeRecordKind(TypeRecordKind::VFPtr);
|
|
Builder.writeUInt16(0);
|
|
Builder.writeTypeIndex(Record.getType());
|
|
|
|
finishSubRecord();
|
|
}
|