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 }
26591312c5SZachary Turner 
27591312c5SZachary Turner Expected<StringRef>
28591312c5SZachary Turner DebugStringTableSubsectionRef::getString(uint32_t Offset) const {
29591312c5SZachary Turner   BinaryStreamReader Reader(Stream);
30591312c5SZachary Turner   Reader.setOffset(Offset);
31591312c5SZachary Turner   StringRef Result;
32591312c5SZachary Turner   if (auto EC = Reader.readCString(Result))
33591312c5SZachary Turner     return std::move(EC);
34591312c5SZachary Turner   return Result;
35591312c5SZachary Turner }
36591312c5SZachary Turner 
37591312c5SZachary Turner DebugStringTableSubsection::DebugStringTableSubsection()
38591312c5SZachary Turner     : DebugSubsection(DebugSubsectionKind::StringTable) {}
39591312c5SZachary Turner 
40591312c5SZachary Turner uint32_t DebugStringTableSubsection::insert(StringRef S) {
41591312c5SZachary Turner   auto P = Strings.insert({S, StringSize});
42591312c5SZachary Turner 
43591312c5SZachary Turner   // If a given string didn't exist in the string table, we want to increment
44591312c5SZachary Turner   // the string table size.
45591312c5SZachary Turner   if (P.second)
46591312c5SZachary Turner     StringSize += S.size() + 1; // +1 for '\0'
47591312c5SZachary Turner   return P.first->second;
48591312c5SZachary Turner }
49591312c5SZachary Turner 
50591312c5SZachary Turner uint32_t DebugStringTableSubsection::calculateSerializedSize() const {
51591312c5SZachary Turner   return StringSize;
52591312c5SZachary Turner }
53591312c5SZachary Turner 
54591312c5SZachary Turner Error DebugStringTableSubsection::commit(BinaryStreamWriter &Writer) const {
55591312c5SZachary Turner   assert(Writer.bytesRemaining() == StringSize);
56591312c5SZachary Turner   uint32_t MaxOffset = 1;
57591312c5SZachary Turner 
58591312c5SZachary Turner   for (auto &Pair : Strings) {
59591312c5SZachary Turner     StringRef S = Pair.getKey();
60591312c5SZachary Turner     uint32_t Offset = Pair.getValue();
61591312c5SZachary Turner     Writer.setOffset(Offset);
62591312c5SZachary Turner     if (auto EC = Writer.writeCString(S))
63591312c5SZachary Turner       return EC;
64591312c5SZachary Turner     MaxOffset = std::max<uint32_t>(MaxOffset, Offset + S.size() + 1);
65591312c5SZachary Turner   }
66591312c5SZachary Turner 
67591312c5SZachary Turner   Writer.setOffset(MaxOffset);
68591312c5SZachary Turner   assert(Writer.bytesRemaining() == 0);
69591312c5SZachary Turner   return Error::success();
70591312c5SZachary Turner }
71591312c5SZachary Turner 
72591312c5SZachary Turner uint32_t DebugStringTableSubsection::size() const { return Strings.size(); }
73591312c5SZachary Turner 
74591312c5SZachary Turner uint32_t DebugStringTableSubsection::getStringId(StringRef S) const {
75*92dcdda6SZachary Turner   auto Iter = Strings.find(S);
76*92dcdda6SZachary Turner   assert(Iter != Strings.end());
77*92dcdda6SZachary Turner   return Iter->second;
78591312c5SZachary Turner }
79