Skip to content

Commit

Permalink
[CodeView] Hook up CodeViewRecordIO to type serialization path.
Browse files Browse the repository at this point in the history
Previously support had been added for using CodeViewRecordIO
to read (deserialize) CodeView type records.  This patch adds
support for writing those same records.  With this patch,
reading and writing of CodeView type records finally uses a single
codepath.

Differential Revision: https://reviews.llvm.org/D26253

llvm-svn: 286304
  • Loading branch information
Zachary Turner committed Nov 8, 2016
1 parent cb3c9f6 commit 4efa0a4
Show file tree
Hide file tree
Showing 37 changed files with 853 additions and 1,370 deletions.
43 changes: 32 additions & 11 deletions llvm/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
Expand Up @@ -13,38 +13,40 @@
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/MSF/StreamReader.h"
#include "llvm/DebugInfo/MSF/StreamWriter.h"
#include "llvm/Support/Error.h"

#include <stdint.h>
#include <type_traits>

#include <stdint.h>

namespace llvm {
namespace msf {
class StreamReader;
class StreamWriter;
}
namespace codeview {

class CodeViewRecordIO {
struct ActiveRecord {
uint16_t Kind;
};
uint32_t getCurrentOffset() const {
return (isWriting()) ? Writer->getOffset() : Reader->getOffset();
}

public:
explicit CodeViewRecordIO(msf::StreamReader &Reader) : Reader(&Reader) {}
explicit CodeViewRecordIO(msf::StreamWriter &Writer) : Writer(&Writer) {}

Error beginRecord(uint16_t Kind);
Error beginRecord(Optional<uint32_t> MaxLength);
Error endRecord();

Error mapInteger(TypeIndex &TypeInd);

bool isReading() const { return Reader != nullptr; }
bool isWriting() const { return !isReading(); }

uint32_t maxFieldLength() const;

template <typename T> Error mapInteger(T &Value) {
if (isWriting())
return Writer->writeInteger(Value);
Expand All @@ -53,6 +55,9 @@ class CodeViewRecordIO {
}

template <typename T> Error mapEnum(T &Value) {
if (sizeof(Value) > maxFieldLength())
return make_error<CodeViewError>(cv_error_code::insufficient_buffer);

using U = typename std::underlying_type<T>::type;
U X;
if (isWriting())
Expand Down Expand Up @@ -124,7 +129,23 @@ class CodeViewRecordIO {
Error writeEncodedSignedInteger(const int64_t &Value);
Error writeEncodedUnsignedInteger(const uint64_t &Value);

Optional<ActiveRecord> CurrentRecord;
struct RecordLimit {
uint32_t BeginOffset;
Optional<uint32_t> MaxLength;

Optional<uint32_t> bytesRemaining(uint32_t CurrentOffset) const {
if (!MaxLength.hasValue())
return None;
assert(CurrentOffset >= BeginOffset);

uint32_t BytesUsed = CurrentOffset - BeginOffset;
if (BytesUsed >= *MaxLength)
return 0;
return *MaxLength - BytesUsed;
}
};

SmallVector<RecordLimit, 2> Limits;

msf::StreamReader *Reader = nullptr;
msf::StreamWriter *Writer = nullptr;
Expand Down
67 changes: 0 additions & 67 deletions llvm/include/llvm/DebugInfo/CodeView/FieldListRecordBuilder.h

This file was deleted.

65 changes: 0 additions & 65 deletions llvm/include/llvm/DebugInfo/CodeView/ListRecordBuilder.h

This file was deleted.

50 changes: 0 additions & 50 deletions llvm/include/llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h

This file was deleted.

35 changes: 0 additions & 35 deletions llvm/include/llvm/DebugInfo/CodeView/MethodListRecordBuilder.h

This file was deleted.

2 changes: 1 addition & 1 deletion llvm/include/llvm/DebugInfo/CodeView/RecordSerialization.h
Expand Up @@ -32,7 +32,7 @@ using llvm::support::ulittle32_t;
enum : unsigned { MaxRecordLength = 0xFF00 };

struct RecordPrefix {
ulittle16_t RecordLen; // Record length, starting from &Leaf.
ulittle16_t RecordLen; // Record length, starting from &RecordKind.
ulittle16_t RecordKind; // Record kind enum (SymRecordKind or TypeRecordKind)
};

Expand Down
12 changes: 11 additions & 1 deletion llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
Expand Up @@ -76,7 +76,17 @@ class FieldListDeserializer : public TypeVisitorCallbacks {
};

public:
explicit FieldListDeserializer(msf::StreamReader &Reader) : Mapping(Reader) {}
explicit FieldListDeserializer(msf::StreamReader &Reader) : Mapping(Reader) {
CVType FieldList;
FieldList.Type = TypeLeafKind::LF_FIELDLIST;
consumeError(Mapping.Mapping.visitTypeBegin(FieldList));
}

~FieldListDeserializer() {
CVType FieldList;
FieldList.Type = TypeLeafKind::LF_FIELDLIST;
consumeError(Mapping.Mapping.visitTypeEnd(FieldList));
}

Error visitMemberBegin(CVMemberRecord &Record) override {
Mapping.StartOffset = Mapping.Reader.getOffset();
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/DebugInfo/CodeView/TypeIndex.h
Expand Up @@ -93,7 +93,7 @@ class TypeIndex {
static const uint32_t SimpleModeMask = 0x00000700;

public:
TypeIndex() : Index(0) {}
TypeIndex() : Index(static_cast<uint32_t>(SimpleTypeKind::None)) {}
explicit TypeIndex(uint32_t Index) : Index(Index) {}
explicit TypeIndex(SimpleTypeKind Kind)
: Index(static_cast<uint32_t>(Kind)) {}
Expand Down
11 changes: 5 additions & 6 deletions llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
Expand Up @@ -701,26 +701,25 @@ class OneMethodRecord : public TypeRecord {
StringRef Name)
: TypeRecord(TypeRecordKind::OneMethod), Type(Type), Attrs(Attrs),
VFTableOffset(VFTableOffset), Name(Name) {}
OneMethodRecord(TypeIndex Type, MemberAccess Access, MethodKind Kind,
OneMethodRecord(TypeIndex Type, MemberAccess Access, MethodKind MK,
MethodOptions Options, int32_t VFTableOffset, StringRef Name)
: TypeRecord(TypeRecordKind::OneMethod), Type(Type),
Attrs(Access, Kind, Options), VFTableOffset(VFTableOffset), Name(Name) {
}
Attrs(Access, MK, Options), VFTableOffset(VFTableOffset), Name(Name) {}

/// Rewrite member type indices with IndexMap. Returns false if a type index
/// is not in the map.
bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);

TypeIndex getType() const { return Type; }
MethodKind getKind() const { return Attrs.getMethodKind(); }
MethodKind getMethodKind() const { return Attrs.getMethodKind(); }
MethodOptions getOptions() const { return Attrs.getFlags(); }
MemberAccess getAccess() const { return Attrs.getAccess(); }
int32_t getVFTableOffset() const { return VFTableOffset; }
StringRef getName() const { return Name; }

bool isIntroducingVirtual() const {
return getKind() == MethodKind::IntroducingVirtual ||
getKind() == MethodKind::PureIntroducingVirtual;
return getMethodKind() == MethodKind::IntroducingVirtual ||
getMethodKind() == MethodKind::PureIntroducingVirtual;
}
TypeIndex Type;
MemberAttributes Attrs;
Expand Down
6 changes: 6 additions & 0 deletions llvm/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h
Expand Up @@ -16,10 +16,15 @@
#include "llvm/Support/Error.h"

namespace llvm {
namespace msf {
class StreamReader;
class StreamWriter;
}
namespace codeview {
class TypeRecordMapping : public TypeVisitorCallbacks {
public:
explicit TypeRecordMapping(msf::StreamReader &Reader) : IO(Reader) {}
explicit TypeRecordMapping(msf::StreamWriter &Writer) : IO(Writer) {}

Error visitTypeBegin(CVType &Record) override;
Error visitTypeEnd(CVType &Record) override;
Expand All @@ -37,6 +42,7 @@ class TypeRecordMapping : public TypeVisitorCallbacks {

private:
Optional<TypeLeafKind> TypeKind;
Optional<TypeLeafKind> MemberKind;

CodeViewRecordIO IO;
};
Expand Down

0 comments on commit 4efa0a4

Please sign in to comment.