1591312c5SZachary Turner //===- DebugStringTableSubsection.cpp - CodeView String Table ---*- C++ -*-===//
2591312c5SZachary Turner //
3591312c5SZachary Turner //                     The LLVM Compiler Infrastructure
4591312c5SZachary Turner //
5591312c5SZachary Turner // This file is distributed under the University of Illinois Open Source
6591312c5SZachary Turner // License. See LICENSE.TXT for details.
7591312c5SZachary Turner //
8591312c5SZachary Turner //===----------------------------------------------------------------------===//
9591312c5SZachary Turner 
10591312c5SZachary Turner #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
11591312c5SZachary Turner 
12591312c5SZachary Turner #include "llvm/Support/BinaryStream.h"
13591312c5SZachary Turner #include "llvm/Support/BinaryStreamReader.h"
14591312c5SZachary Turner #include "llvm/Support/BinaryStreamWriter.h"
15591312c5SZachary Turner 
16591312c5SZachary Turner using namespace llvm;
17591312c5SZachary Turner using namespace llvm::codeview;
18591312c5SZachary Turner 
19591312c5SZachary Turner DebugStringTableSubsectionRef::DebugStringTableSubsectionRef()
20591312c5SZachary Turner     : DebugSubsectionRef(DebugSubsectionKind::StringTable) {}
21591312c5SZachary Turner 
22591312c5SZachary Turner Error DebugStringTableSubsectionRef::initialize(BinaryStreamRef Contents) {
23591312c5SZachary Turner   Stream = Contents;
24591312c5SZachary Turner   return Error::success();
25591312c5SZachary Turner }
26*1bf77620SZachary Turner Error DebugStringTableSubsectionRef::initialize(BinaryStreamReader &Reader) {
27*1bf77620SZachary Turner   return Reader.readStreamRef(Stream, Reader.bytesRemaining());
28*1bf77620SZachary Turner }
29591312c5SZachary Turner 
30591312c5SZachary Turner Expected<StringRef>
31591312c5SZachary Turner DebugStringTableSubsectionRef::getString(uint32_t Offset) const {
32591312c5SZachary Turner   BinaryStreamReader Reader(Stream);
33591312c5SZachary Turner   Reader.setOffset(Offset);
34591312c5SZachary Turner   StringRef Result;
35591312c5SZachary Turner   if (auto EC = Reader.readCString(Result))
36591312c5SZachary Turner     return std::move(EC);
37591312c5SZachary Turner   return Result;
38591312c5SZachary Turner }
39591312c5SZachary Turner 
40591312c5SZachary Turner DebugStringTableSubsection::DebugStringTableSubsection()
41591312c5SZachary Turner     : DebugSubsection(DebugSubsectionKind::StringTable) {}
42591312c5SZachary Turner 
43591312c5SZachary Turner uint32_t DebugStringTableSubsection::insert(StringRef S) {
44591312c5SZachary Turner   auto P = Strings.insert({S, StringSize});
45591312c5SZachary Turner 
46591312c5SZachary Turner   // If a given string didn't exist in the string table, we want to increment
47591312c5SZachary Turner   // the string table size.
48591312c5SZachary Turner   if (P.second)
49591312c5SZachary Turner     StringSize += S.size() + 1; // +1 for '\0'
50591312c5SZachary Turner   return P.first->second;
51591312c5SZachary Turner }
52591312c5SZachary Turner 
53591312c5SZachary Turner uint32_t DebugStringTableSubsection::calculateSerializedSize() const {
54591312c5SZachary Turner   return StringSize;
55591312c5SZachary Turner }
56591312c5SZachary Turner 
57591312c5SZachary Turner Error DebugStringTableSubsection::commit(BinaryStreamWriter &Writer) const {
58591312c5SZachary Turner   assert(Writer.bytesRemaining() == StringSize);
59591312c5SZachary Turner   uint32_t MaxOffset = 1;
60591312c5SZachary Turner 
61591312c5SZachary Turner   for (auto &Pair : Strings) {
62591312c5SZachary Turner     StringRef S = Pair.getKey();
63591312c5SZachary Turner     uint32_t Offset = Pair.getValue();
64591312c5SZachary Turner     Writer.setOffset(Offset);
65591312c5SZachary Turner     if (auto EC = Writer.writeCString(S))
66591312c5SZachary Turner       return EC;
67591312c5SZachary Turner     MaxOffset = std::max<uint32_t>(MaxOffset, Offset + S.size() + 1);
68591312c5SZachary Turner   }
69591312c5SZachary Turner 
70591312c5SZachary Turner   Writer.setOffset(MaxOffset);
71591312c5SZachary Turner   assert(Writer.bytesRemaining() == 0);
72591312c5SZachary Turner   return Error::success();
73591312c5SZachary Turner }
74591312c5SZachary Turner 
75591312c5SZachary Turner uint32_t DebugStringTableSubsection::size() const { return Strings.size(); }
76591312c5SZachary Turner 
77591312c5SZachary Turner uint32_t DebugStringTableSubsection::getStringId(StringRef S) const {
7892dcdda6SZachary Turner   auto Iter = Strings.find(S);
7992dcdda6SZachary Turner   assert(Iter != Strings.end());
8092dcdda6SZachary Turner   return Iter->second;
81591312c5SZachary Turner }
82