1*407dec59SZachary Turner //===- SymbolSerializer.cpp -------------------------------------*- C++ -*-===//
2*407dec59SZachary Turner //
3*407dec59SZachary Turner //                     The LLVM Compiler Infrastructure
4*407dec59SZachary Turner //
5*407dec59SZachary Turner // This file is distributed under the University of Illinois Open Source
6*407dec59SZachary Turner // License. See LICENSE.TXT for details.
7*407dec59SZachary Turner //
8*407dec59SZachary Turner //===----------------------------------------------------------------------===//
9*407dec59SZachary Turner 
10*407dec59SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
11*407dec59SZachary Turner 
12*407dec59SZachary Turner using namespace llvm;
13*407dec59SZachary Turner using namespace llvm::codeview;
14*407dec59SZachary Turner 
15*407dec59SZachary Turner SymbolSerializer::SymbolSerializer(BumpPtrAllocator &Allocator)
16*407dec59SZachary Turner   : Storage(Allocator), RecordBuffer(MaxRecordLength), Stream(RecordBuffer, llvm::support::little),
17*407dec59SZachary Turner   Writer(Stream), Mapping(Writer) { }
18*407dec59SZachary Turner 
19*407dec59SZachary Turner Error SymbolSerializer::visitSymbolBegin(CVSymbol &Record) {
20*407dec59SZachary Turner   assert(!CurrentSymbol.hasValue() && "Already in a symbol mapping!");
21*407dec59SZachary Turner 
22*407dec59SZachary Turner   Writer.setOffset(0);
23*407dec59SZachary Turner 
24*407dec59SZachary Turner   if (auto EC = writeRecordPrefix(Record.kind()))
25*407dec59SZachary Turner     return EC;
26*407dec59SZachary Turner 
27*407dec59SZachary Turner   CurrentSymbol = Record.kind();
28*407dec59SZachary Turner   if (auto EC = Mapping.visitSymbolBegin(Record))
29*407dec59SZachary Turner     return EC;
30*407dec59SZachary Turner 
31*407dec59SZachary Turner   return Error::success();
32*407dec59SZachary Turner }
33*407dec59SZachary Turner 
34*407dec59SZachary Turner Error SymbolSerializer::visitSymbolEnd(CVSymbol &Record) {
35*407dec59SZachary Turner   assert(CurrentSymbol.hasValue() && "Not in a symbol mapping!");
36*407dec59SZachary Turner 
37*407dec59SZachary Turner   if (auto EC = Mapping.visitSymbolEnd(Record))
38*407dec59SZachary Turner     return EC;
39*407dec59SZachary Turner 
40*407dec59SZachary Turner   uint32_t RecordEnd = Writer.getOffset();
41*407dec59SZachary Turner   uint16_t Length = RecordEnd - 2;
42*407dec59SZachary Turner   Writer.setOffset(0);
43*407dec59SZachary Turner   if (auto EC = Writer.writeInteger(Length))
44*407dec59SZachary Turner     return EC;
45*407dec59SZachary Turner 
46*407dec59SZachary Turner   uint8_t *StableStorage = Storage.Allocate<uint8_t>(RecordEnd);
47*407dec59SZachary Turner   ::memcpy(StableStorage, &RecordBuffer[0], RecordEnd);
48*407dec59SZachary Turner   Record.RecordData = ArrayRef<uint8_t>(StableStorage, RecordEnd);
49*407dec59SZachary Turner   CurrentSymbol.reset();
50*407dec59SZachary Turner 
51*407dec59SZachary Turner   return Error::success();
52*407dec59SZachary Turner }
53