Files
archived-llvm/include/llvm/DebugInfo/CodeView/SymbolSerializer.h
Zachary Turner 3b75dc7441 Resubmit "[CodeView] Hook CodeViewRecordIO for reading/writing symbols."
The original patch was broken due to some undefined behavior
as well as warnings that were triggering -Werror.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@290000 91177308-0d34-0410-b5e6-96231b3b80d8
2016-12-16 22:48:14 +00:00

97 lines
2.8 KiB
C++

//===- symbolSerializer.h ---------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H
#define LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H
#include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
#include "llvm/DebugInfo/MSF/ByteStream.h"
#include "llvm/DebugInfo/MSF/StreamWriter.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Error.h"
namespace llvm {
namespace codeview {
class SymbolSerializer : public SymbolVisitorCallbacks {
uint32_t RecordStart = 0;
msf::StreamWriter &Writer;
SymbolRecordMapping Mapping;
Optional<SymbolKind> CurrentSymbol;
Error writeRecordPrefix(SymbolKind Kind) {
RecordPrefix Prefix;
Prefix.RecordKind = Kind;
Prefix.RecordLen = 0;
if (auto EC = Writer.writeObject(Prefix))
return EC;
return Error::success();
}
public:
explicit SymbolSerializer(msf::StreamWriter &Writer)
: Writer(Writer), Mapping(Writer) {}
virtual Error visitSymbolBegin(CVSymbol &Record) override {
assert(!CurrentSymbol.hasValue() && "Already in a symbol mapping!");
RecordStart = Writer.getOffset();
if (auto EC = writeRecordPrefix(Record.kind()))
return EC;
CurrentSymbol = Record.kind();
if (auto EC = Mapping.visitSymbolBegin(Record))
return EC;
return Error::success();
}
virtual Error visitSymbolEnd(CVSymbol &Record) override {
assert(CurrentSymbol.hasValue() && "Not in a symbol mapping!");
if (auto EC = Mapping.visitSymbolEnd(Record))
return EC;
uint32_t RecordEnd = Writer.getOffset();
Writer.setOffset(RecordStart);
uint16_t Length = RecordEnd - Writer.getOffset() - 2;
if (auto EC = Writer.writeInteger(Length))
return EC;
Writer.setOffset(RecordEnd);
CurrentSymbol.reset();
return Error::success();
}
#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
virtual Error visitKnownRecord(CVSymbol &CVR, Name &Record) override { \
return visitKnownRecordImpl(CVR, Record); \
}
#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#include "CVSymbolTypes.def"
private:
template <typename RecordKind>
Error visitKnownRecordImpl(CVSymbol &CVR, RecordKind &Record) {
return Mapping.visitKnownRecord(CVR, Record);
}
};
}
}
#endif