Line data Source code
1 : //===- TypeDatabase.cpp --------------------------------------- *- C++ --*-===//
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/DebugInfo/CodeView/TypeDatabase.h"
11 :
12 : using namespace llvm;
13 : using namespace llvm::codeview;
14 :
15 3122 : TypeDatabase::TypeDatabase(uint32_t Capacity) : TypeNameStorage(Allocator) {
16 446 : CVUDTNames.resize(Capacity);
17 446 : TypeRecords.resize(Capacity);
18 446 : ValidRecords.resize(Capacity);
19 446 : }
20 :
21 0 : TypeIndex TypeDatabase::appendType(StringRef Name, const CVType &Data) {
22 0 : LargestTypeIndex = getAppendIndex();
23 0 : if (LargestTypeIndex.toArrayIndex() >= capacity())
24 0 : grow();
25 0 : recordType(Name, LargestTypeIndex, Data);
26 0 : return LargestTypeIndex;
27 : }
28 :
29 2874 : void TypeDatabase::recordType(StringRef Name, TypeIndex Index,
30 : const CVType &Data) {
31 5748 : LargestTypeIndex = empty() ? Index : std::max(Index, LargestTypeIndex);
32 :
33 5748 : if (LargestTypeIndex.toArrayIndex() >= capacity())
34 8 : grow(Index);
35 :
36 2874 : uint32_t AI = Index.toArrayIndex();
37 :
38 : assert(!contains(Index));
39 : assert(AI < capacity());
40 :
41 5748 : CVUDTNames[AI] = Name;
42 8622 : TypeRecords[AI] = Data;
43 5748 : ValidRecords.set(AI);
44 2874 : ++Count;
45 2874 : }
46 :
47 : /// Saves the name in a StringSet and creates a stable StringRef.
48 1119 : StringRef TypeDatabase::saveTypeName(StringRef TypeName) {
49 1119 : return TypeNameStorage.save(TypeName);
50 : }
51 :
52 2407 : StringRef TypeDatabase::getTypeName(TypeIndex Index) const {
53 4813 : if (Index.isNoneType() || Index.isSimple())
54 598 : return TypeIndex::simpleTypeName(Index);
55 :
56 1809 : if (contains(Index))
57 3614 : return CVUDTNames[Index.toArrayIndex()];
58 :
59 2 : return "<unknown UDT>";
60 : }
61 :
62 0 : const CVType &TypeDatabase::getTypeRecord(TypeIndex Index) const {
63 : assert(contains(Index));
64 0 : return TypeRecords[Index.toArrayIndex()];
65 : }
66 :
67 4228 : CVType &TypeDatabase::getTypeRecord(TypeIndex Index) {
68 : assert(contains(Index));
69 8456 : return TypeRecords[Index.toArrayIndex()];
70 : }
71 :
72 11712 : bool TypeDatabase::contains(TypeIndex Index) const {
73 11712 : uint32_t AI = Index.toArrayIndex();
74 11712 : if (AI >= capacity())
75 : return false;
76 :
77 23402 : return ValidRecords.test(AI);
78 : }
79 :
80 3028 : uint32_t TypeDatabase::size() const { return Count; }
81 :
82 33836 : uint32_t TypeDatabase::capacity() const { return TypeRecords.size(); }
83 :
84 0 : CVType TypeDatabase::getType(TypeIndex Index) { return getTypeRecord(Index); }
85 :
86 2407 : StringRef TypeDatabase::getTypeName(TypeIndex Index) {
87 2407 : return static_cast<const TypeDatabase *>(this)->getTypeName(Index);
88 : }
89 :
90 9903 : bool TypeDatabase::contains(TypeIndex Index) {
91 9903 : return static_cast<const TypeDatabase *>(this)->contains(Index);
92 : }
93 :
94 5 : uint32_t TypeDatabase::size() {
95 5 : return static_cast<const TypeDatabase *>(this)->size();
96 : }
97 :
98 5206 : uint32_t TypeDatabase::capacity() {
99 5206 : return static_cast<const TypeDatabase *>(this)->capacity();
100 : }
101 :
102 0 : void TypeDatabase::grow() { grow(LargestTypeIndex + 1); }
103 :
104 8 : void TypeDatabase::grow(TypeIndex NewIndex) {
105 8 : uint32_t NewSize = NewIndex.toArrayIndex() + 1;
106 :
107 8 : if (NewSize <= capacity())
108 : return;
109 :
110 8 : uint32_t NewCapacity = NewSize * 3 / 2;
111 :
112 8 : TypeRecords.resize(NewCapacity);
113 8 : CVUDTNames.resize(NewCapacity);
114 8 : ValidRecords.resize(NewCapacity);
115 : }
116 :
117 3023 : bool TypeDatabase::empty() const { return size() == 0; }
118 :
119 73 : Optional<TypeIndex> TypeDatabase::largestTypeIndexLessThan(TypeIndex TI) const {
120 73 : uint32_t AI = TI.toArrayIndex();
121 146 : int N = ValidRecords.find_prev(AI);
122 73 : if (N == -1)
123 : return None;
124 146 : return TypeIndex::fromArrayIndex(N);
125 : }
126 :
127 0 : TypeIndex TypeDatabase::getAppendIndex() const {
128 0 : if (empty())
129 : return TypeIndex::fromArrayIndex(0);
130 :
131 0 : return LargestTypeIndex + 1;
132 : }
133 :
134 0 : Optional<TypeIndex> TypeDatabase::getFirst() {
135 0 : int N = ValidRecords.find_first();
136 0 : if (N == -1)
137 : return None;
138 0 : return TypeIndex::fromArrayIndex(N);
139 : }
140 :
141 0 : Optional<TypeIndex> TypeDatabase::getNext(TypeIndex Prev) {
142 0 : int N = ValidRecords.find_next(Prev.toArrayIndex());
143 0 : if (N == -1)
144 : return None;
145 0 : return TypeIndex::fromArrayIndex(N);
146 : }
|