]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/DebugInfo/CodeView/TypeDatabase.cpp
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r303571, and update
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / DebugInfo / CodeView / TypeDatabase.cpp
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 namespace {
16 struct SimpleTypeEntry {
17   StringRef Name;
18   SimpleTypeKind Kind;
19 };
20 }
21
22 /// The names here all end in "*". If the simple type is a pointer type, we
23 /// return the whole name. Otherwise we lop off the last character in our
24 /// StringRef.
25 static const SimpleTypeEntry SimpleTypeNames[] = {
26     {"void*", SimpleTypeKind::Void},
27     {"<not translated>*", SimpleTypeKind::NotTranslated},
28     {"HRESULT*", SimpleTypeKind::HResult},
29     {"signed char*", SimpleTypeKind::SignedCharacter},
30     {"unsigned char*", SimpleTypeKind::UnsignedCharacter},
31     {"char*", SimpleTypeKind::NarrowCharacter},
32     {"wchar_t*", SimpleTypeKind::WideCharacter},
33     {"char16_t*", SimpleTypeKind::Character16},
34     {"char32_t*", SimpleTypeKind::Character32},
35     {"__int8*", SimpleTypeKind::SByte},
36     {"unsigned __int8*", SimpleTypeKind::Byte},
37     {"short*", SimpleTypeKind::Int16Short},
38     {"unsigned short*", SimpleTypeKind::UInt16Short},
39     {"__int16*", SimpleTypeKind::Int16},
40     {"unsigned __int16*", SimpleTypeKind::UInt16},
41     {"long*", SimpleTypeKind::Int32Long},
42     {"unsigned long*", SimpleTypeKind::UInt32Long},
43     {"int*", SimpleTypeKind::Int32},
44     {"unsigned*", SimpleTypeKind::UInt32},
45     {"__int64*", SimpleTypeKind::Int64Quad},
46     {"unsigned __int64*", SimpleTypeKind::UInt64Quad},
47     {"__int64*", SimpleTypeKind::Int64},
48     {"unsigned __int64*", SimpleTypeKind::UInt64},
49     {"__int128*", SimpleTypeKind::Int128},
50     {"unsigned __int128*", SimpleTypeKind::UInt128},
51     {"__half*", SimpleTypeKind::Float16},
52     {"float*", SimpleTypeKind::Float32},
53     {"float*", SimpleTypeKind::Float32PartialPrecision},
54     {"__float48*", SimpleTypeKind::Float48},
55     {"double*", SimpleTypeKind::Float64},
56     {"long double*", SimpleTypeKind::Float80},
57     {"__float128*", SimpleTypeKind::Float128},
58     {"_Complex float*", SimpleTypeKind::Complex32},
59     {"_Complex double*", SimpleTypeKind::Complex64},
60     {"_Complex long double*", SimpleTypeKind::Complex80},
61     {"_Complex __float128*", SimpleTypeKind::Complex128},
62     {"bool*", SimpleTypeKind::Boolean8},
63     {"__bool16*", SimpleTypeKind::Boolean16},
64     {"__bool32*", SimpleTypeKind::Boolean32},
65     {"__bool64*", SimpleTypeKind::Boolean64},
66 };
67
68 TypeDatabase::TypeDatabase(uint32_t Capacity) : TypeNameStorage(Allocator) {
69   CVUDTNames.resize(Capacity);
70   TypeRecords.resize(Capacity);
71   ValidRecords.resize(Capacity);
72 }
73
74 TypeIndex TypeDatabase::appendType(StringRef Name, const CVType &Data) {
75   LargestTypeIndex = getAppendIndex();
76   if (LargestTypeIndex.toArrayIndex() >= capacity())
77     grow();
78   recordType(Name, LargestTypeIndex, Data);
79   return LargestTypeIndex;
80 }
81
82 void TypeDatabase::recordType(StringRef Name, TypeIndex Index,
83                               const CVType &Data) {
84   LargestTypeIndex = empty() ? Index : std::max(Index, LargestTypeIndex);
85
86   if (LargestTypeIndex.toArrayIndex() >= capacity())
87     grow(Index);
88
89   uint32_t AI = Index.toArrayIndex();
90
91   assert(!contains(Index));
92   assert(AI < capacity());
93
94   CVUDTNames[AI] = Name;
95   TypeRecords[AI] = Data;
96   ValidRecords.set(AI);
97   ++Count;
98 }
99
100 /// Saves the name in a StringSet and creates a stable StringRef.
101 StringRef TypeDatabase::saveTypeName(StringRef TypeName) {
102   return TypeNameStorage.save(TypeName);
103 }
104
105 StringRef TypeDatabase::getTypeName(TypeIndex Index) const {
106   if (Index.isNoneType())
107     return "<no type>";
108
109   if (Index.isSimple()) {
110     // This is a simple type.
111     for (const auto &SimpleTypeName : SimpleTypeNames) {
112       if (SimpleTypeName.Kind == Index.getSimpleKind()) {
113         if (Index.getSimpleMode() == SimpleTypeMode::Direct)
114           return SimpleTypeName.Name.drop_back(1);
115         // Otherwise, this is a pointer type. We gloss over the distinction
116         // between near, far, 64, 32, etc, and just give a pointer type.
117         return SimpleTypeName.Name;
118       }
119     }
120     return "<unknown simple type>";
121   }
122
123   if (contains(Index))
124     return CVUDTNames[Index.toArrayIndex()];
125
126   return "<unknown UDT>";
127 }
128
129 const CVType &TypeDatabase::getTypeRecord(TypeIndex Index) const {
130   assert(contains(Index));
131   return TypeRecords[Index.toArrayIndex()];
132 }
133
134 CVType &TypeDatabase::getTypeRecord(TypeIndex Index) {
135   assert(contains(Index));
136   return TypeRecords[Index.toArrayIndex()];
137 }
138
139 bool TypeDatabase::contains(TypeIndex Index) const {
140   uint32_t AI = Index.toArrayIndex();
141   if (AI >= capacity())
142     return false;
143
144   return ValidRecords.test(AI);
145 }
146
147 uint32_t TypeDatabase::size() const { return Count; }
148
149 uint32_t TypeDatabase::capacity() const { return TypeRecords.size(); }
150
151 CVType TypeDatabase::getType(TypeIndex Index) { return getTypeRecord(Index); }
152
153 StringRef TypeDatabase::getTypeName(TypeIndex Index) {
154   return static_cast<const TypeDatabase *>(this)->getTypeName(Index);
155 }
156
157 bool TypeDatabase::contains(TypeIndex Index) {
158   return static_cast<const TypeDatabase *>(this)->contains(Index);
159 }
160
161 uint32_t TypeDatabase::size() {
162   return static_cast<const TypeDatabase *>(this)->size();
163 }
164
165 uint32_t TypeDatabase::capacity() {
166   return static_cast<const TypeDatabase *>(this)->capacity();
167 }
168
169 void TypeDatabase::grow() { grow(LargestTypeIndex + 1); }
170
171 void TypeDatabase::grow(TypeIndex NewIndex) {
172   uint32_t NewSize = NewIndex.toArrayIndex() + 1;
173
174   if (NewSize <= capacity())
175     return;
176
177   uint32_t NewCapacity = NewSize * 3 / 2;
178
179   TypeRecords.resize(NewCapacity);
180   CVUDTNames.resize(NewCapacity);
181   ValidRecords.resize(NewCapacity);
182 }
183
184 bool TypeDatabase::empty() const { return size() == 0; }
185
186 Optional<TypeIndex> TypeDatabase::largestTypeIndexLessThan(TypeIndex TI) const {
187   uint32_t AI = TI.toArrayIndex();
188   int N = ValidRecords.find_prev(AI);
189   if (N == -1)
190     return None;
191   return TypeIndex::fromArrayIndex(N);
192 }
193
194 TypeIndex TypeDatabase::getAppendIndex() const {
195   if (empty())
196     return TypeIndex::fromArrayIndex(0);
197
198   return LargestTypeIndex + 1;
199 }
200
201 Optional<TypeIndex> TypeDatabase::getFirst() {
202   int N = ValidRecords.find_first();
203   if (N == -1)
204     return None;
205   return TypeIndex::fromArrayIndex(N);
206 }
207
208 Optional<TypeIndex> TypeDatabase::getNext(TypeIndex Prev) {
209   int N = ValidRecords.find_next(Prev.toArrayIndex());
210   if (N == -1)
211     return None;
212   return TypeIndex::fromArrayIndex(N);
213 }