blob: 0f15d3035eafc828586319f0d91f0debde52b901 [file] [log] [blame]
Hans Wennborg83e6e1e2014-04-30 16:25:02 +00001//===-- StringTableBuilder.cpp - String table building utility ------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Rafael Espindola97de4742014-07-03 02:01:39 +000010#include "llvm/MC/StringTableBuilder.h"
Hans Wennborg83e6e1e2014-04-30 16:25:02 +000011#include "llvm/ADT/SmallVector.h"
Rafael Espindola0169a452015-10-22 15:15:44 +000012#include "llvm/ADT/STLExtras.h"
Hans Wennborgf26bfc12014-09-29 22:43:20 +000013#include "llvm/Support/COFF.h"
14#include "llvm/Support/Endian.h"
Hans Wennborg83e6e1e2014-04-30 16:25:02 +000015
Zachary Turnerc55a5042015-10-22 16:42:31 +000016#include <vector>
17
Hans Wennborg83e6e1e2014-04-30 16:25:02 +000018using namespace llvm;
19
Rafael Espindolae015f662015-10-22 15:26:35 +000020static int compareBySuffix(StringMapEntry<size_t> *const *AP,
21 StringMapEntry<size_t> *const *BP) {
22 StringRef a = (*AP)->first();
23 StringRef b = (*BP)->first();
Akira Hatanaka8e77dbb2014-09-24 20:37:14 +000024 size_t sizeA = a.size();
25 size_t sizeB = b.size();
26 size_t len = std::min(sizeA, sizeB);
27 for (size_t i = 0; i < len; ++i) {
28 char ca = a[sizeA - i - 1];
29 char cb = b[sizeB - i - 1];
30 if (ca != cb)
Rafael Espindola0169a452015-10-22 15:15:44 +000031 return cb - ca;
Akira Hatanaka8e77dbb2014-09-24 20:37:14 +000032 }
Rafael Espindola0169a452015-10-22 15:15:44 +000033 return sizeB - sizeA;
Akira Hatanaka8e77dbb2014-09-24 20:37:14 +000034}
35
Hans Wennborgf26bfc12014-09-29 22:43:20 +000036void StringTableBuilder::finalize(Kind kind) {
Rafael Espindolae015f662015-10-22 15:26:35 +000037 std::vector<StringMapEntry<size_t> *> Strings;
Hans Wennborgf26bfc12014-09-29 22:43:20 +000038 Strings.reserve(StringIndexMap.size());
Rafael Espindolae015f662015-10-22 15:26:35 +000039 for (StringMapEntry<size_t> &P : StringIndexMap)
40 Strings.push_back(&P);
Hans Wennborg83e6e1e2014-04-30 16:25:02 +000041
Rafael Espindola0169a452015-10-22 15:15:44 +000042 array_pod_sort(Strings.begin(), Strings.end(), compareBySuffix);
Hans Wennborg83e6e1e2014-04-30 16:25:02 +000043
Hans Wennborg1b1a3992014-10-06 17:05:19 +000044 switch (kind) {
45 case ELF:
46 case MachO:
Hans Wennborgf26bfc12014-09-29 22:43:20 +000047 // Start the table with a NUL byte.
48 StringTable += '\x00';
Hans Wennborg1b1a3992014-10-06 17:05:19 +000049 break;
50 case WinCOFF:
Hans Wennborgf26bfc12014-09-29 22:43:20 +000051 // Make room to write the table size later.
52 StringTable.append(4, '\x00');
Hans Wennborg1b1a3992014-10-06 17:05:19 +000053 break;
Hans Wennborgf26bfc12014-09-29 22:43:20 +000054 }
Hans Wennborg83e6e1e2014-04-30 16:25:02 +000055
56 StringRef Previous;
Rafael Espindolae015f662015-10-22 15:26:35 +000057 for (StringMapEntry<size_t> *P : Strings) {
58 StringRef s = P->first();
Hans Wennborgf26bfc12014-09-29 22:43:20 +000059 if (kind == WinCOFF)
60 assert(s.size() > COFF::NameSize && "Short string in COFF string table!");
61
Hans Wennborg83e6e1e2014-04-30 16:25:02 +000062 if (Previous.endswith(s)) {
Rafael Espindolae015f662015-10-22 15:26:35 +000063 P->second = StringTable.size() - 1 - s.size();
Hans Wennborg83e6e1e2014-04-30 16:25:02 +000064 continue;
65 }
66
Rafael Espindolae015f662015-10-22 15:26:35 +000067 P->second = StringTable.size();
Hans Wennborg83e6e1e2014-04-30 16:25:02 +000068 StringTable += s;
69 StringTable += '\x00';
70 Previous = s;
71 }
Hans Wennborgf26bfc12014-09-29 22:43:20 +000072
Hans Wennborg1b1a3992014-10-06 17:05:19 +000073 switch (kind) {
74 case ELF:
75 break;
76 case MachO:
77 // Pad to multiple of 4.
78 while (StringTable.size() % 4)
79 StringTable += '\x00';
80 break;
81 case WinCOFF:
82 // Write the table size in the first word.
Hans Wennborgf26bfc12014-09-29 22:43:20 +000083 assert(StringTable.size() <= std::numeric_limits<uint32_t>::max());
84 uint32_t size = static_cast<uint32_t>(StringTable.size());
85 support::endian::write<uint32_t, support::little, support::unaligned>(
86 StringTable.data(), size);
Hans Wennborg1b1a3992014-10-06 17:05:19 +000087 break;
Hans Wennborgf26bfc12014-09-29 22:43:20 +000088 }
89}
90
91void StringTableBuilder::clear() {
92 StringTable.clear();
93 StringIndexMap.clear();
Hans Wennborg83e6e1e2014-04-30 16:25:02 +000094}