~pali/+junk/llvm-toolchain-3.7

« back to all changes in this revision

Viewing changes to lib/MC/StringTableBuilder.cpp

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2015-07-15 17:51:08 UTC
  • Revision ID: package-import@ubuntu.com-20150715175108-l8mynwovkx4zx697
Tags: upstream-3.7~+rc2
ImportĀ upstreamĀ versionĀ 3.7~+rc2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//===-- 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
 
 
10
#include "llvm/MC/StringTableBuilder.h"
 
11
#include "llvm/ADT/SmallVector.h"
 
12
#include "llvm/Support/COFF.h"
 
13
#include "llvm/Support/Endian.h"
 
14
 
 
15
using namespace llvm;
 
16
 
 
17
static bool compareBySuffix(StringRef a, StringRef b) {
 
18
  size_t sizeA = a.size();
 
19
  size_t sizeB = b.size();
 
20
  size_t len = std::min(sizeA, sizeB);
 
21
  for (size_t i = 0; i < len; ++i) {
 
22
    char ca = a[sizeA - i - 1];
 
23
    char cb = b[sizeB - i - 1];
 
24
    if (ca != cb)
 
25
      return ca > cb;
 
26
  }
 
27
  return sizeA > sizeB;
 
28
}
 
29
 
 
30
void StringTableBuilder::finalize(Kind kind) {
 
31
  SmallVector<StringRef, 8> Strings;
 
32
  Strings.reserve(StringIndexMap.size());
 
33
 
 
34
  for (auto i = StringIndexMap.begin(), e = StringIndexMap.end(); i != e; ++i)
 
35
    Strings.push_back(i->getKey());
 
36
 
 
37
  std::sort(Strings.begin(), Strings.end(), compareBySuffix);
 
38
 
 
39
  switch (kind) {
 
40
  case ELF:
 
41
  case MachO:
 
42
    // Start the table with a NUL byte.
 
43
    StringTable += '\x00';
 
44
    break;
 
45
  case WinCOFF:
 
46
    // Make room to write the table size later.
 
47
    StringTable.append(4, '\x00');
 
48
    break;
 
49
  }
 
50
 
 
51
  StringRef Previous;
 
52
  for (StringRef s : Strings) {
 
53
    if (kind == WinCOFF)
 
54
      assert(s.size() > COFF::NameSize && "Short string in COFF string table!");
 
55
 
 
56
    if (Previous.endswith(s)) {
 
57
      StringIndexMap[s] = StringTable.size() - 1 - s.size();
 
58
      continue;
 
59
    }
 
60
 
 
61
    StringIndexMap[s] = StringTable.size();
 
62
    StringTable += s;
 
63
    StringTable += '\x00';
 
64
    Previous = s;
 
65
  }
 
66
 
 
67
  switch (kind) {
 
68
  case ELF:
 
69
    break;
 
70
  case MachO:
 
71
    // Pad to multiple of 4.
 
72
    while (StringTable.size() % 4)
 
73
      StringTable += '\x00';
 
74
    break;
 
75
  case WinCOFF:
 
76
    // Write the table size in the first word.
 
77
    assert(StringTable.size() <= std::numeric_limits<uint32_t>::max());
 
78
    uint32_t size = static_cast<uint32_t>(StringTable.size());
 
79
    support::endian::write<uint32_t, support::little, support::unaligned>(
 
80
        StringTable.data(), size);
 
81
    break;
 
82
  }
 
83
}
 
84
 
 
85
void StringTableBuilder::clear() {
 
86
  StringTable.clear();
 
87
  StringIndexMap.clear();
 
88
}