1 //===- TypeDatabase.cpp --------------------------------------- *- C++ --*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/DebugInfo/CodeView/TypeDatabase.h"
13 using namespace llvm::codeview;
16 struct SimpleTypeEntry {
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
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},
68 TypeDatabase::TypeDatabase(uint32_t Capacity) : TypeNameStorage(Allocator) {
69 CVUDTNames.resize(Capacity);
70 TypeRecords.resize(Capacity);
71 ValidRecords.resize(Capacity);
74 TypeIndex TypeDatabase::appendType(StringRef Name, const CVType &Data) {
75 LargestTypeIndex = getAppendIndex();
76 if (LargestTypeIndex.toArrayIndex() >= capacity())
78 recordType(Name, LargestTypeIndex, Data);
79 return LargestTypeIndex;
82 void TypeDatabase::recordType(StringRef Name, TypeIndex Index,
84 LargestTypeIndex = empty() ? Index : std::max(Index, LargestTypeIndex);
86 if (LargestTypeIndex.toArrayIndex() >= capacity())
89 uint32_t AI = Index.toArrayIndex();
91 assert(!contains(Index));
92 assert(AI < capacity());
94 CVUDTNames[AI] = Name;
95 TypeRecords[AI] = Data;
100 /// Saves the name in a StringSet and creates a stable StringRef.
101 StringRef TypeDatabase::saveTypeName(StringRef TypeName) {
102 return TypeNameStorage.save(TypeName);
105 StringRef TypeDatabase::getTypeName(TypeIndex Index) const {
106 if (Index.isNoneType())
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;
120 return "<unknown simple type>";
124 return CVUDTNames[Index.toArrayIndex()];
126 return "<unknown UDT>";
129 const CVType &TypeDatabase::getTypeRecord(TypeIndex Index) const {
130 assert(contains(Index));
131 return TypeRecords[Index.toArrayIndex()];
134 CVType &TypeDatabase::getTypeRecord(TypeIndex Index) {
135 assert(contains(Index));
136 return TypeRecords[Index.toArrayIndex()];
139 bool TypeDatabase::contains(TypeIndex Index) const {
140 uint32_t AI = Index.toArrayIndex();
141 if (AI >= capacity())
144 return ValidRecords.test(AI);
147 uint32_t TypeDatabase::size() const { return Count; }
149 uint32_t TypeDatabase::capacity() const { return TypeRecords.size(); }
151 CVType TypeDatabase::getType(TypeIndex Index) { return getTypeRecord(Index); }
153 StringRef TypeDatabase::getTypeName(TypeIndex Index) {
154 return static_cast<const TypeDatabase *>(this)->getTypeName(Index);
157 bool TypeDatabase::contains(TypeIndex Index) {
158 return static_cast<const TypeDatabase *>(this)->contains(Index);
161 uint32_t TypeDatabase::size() {
162 return static_cast<const TypeDatabase *>(this)->size();
165 uint32_t TypeDatabase::capacity() {
166 return static_cast<const TypeDatabase *>(this)->capacity();
169 void TypeDatabase::grow() { grow(LargestTypeIndex + 1); }
171 void TypeDatabase::grow(TypeIndex NewIndex) {
172 uint32_t NewSize = NewIndex.toArrayIndex() + 1;
174 if (NewSize <= capacity())
177 uint32_t NewCapacity = NewSize * 3 / 2;
179 TypeRecords.resize(NewCapacity);
180 CVUDTNames.resize(NewCapacity);
181 ValidRecords.resize(NewCapacity);
184 bool TypeDatabase::empty() const { return size() == 0; }
186 Optional<TypeIndex> TypeDatabase::largestTypeIndexLessThan(TypeIndex TI) const {
187 uint32_t AI = TI.toArrayIndex();
188 int N = ValidRecords.find_prev(AI);
191 return TypeIndex::fromArrayIndex(N);
194 TypeIndex TypeDatabase::getAppendIndex() const {
196 return TypeIndex::fromArrayIndex(0);
198 return LargestTypeIndex + 1;
201 Optional<TypeIndex> TypeDatabase::getFirst() {
202 int N = ValidRecords.find_first();
205 return TypeIndex::fromArrayIndex(N);
208 Optional<TypeIndex> TypeDatabase::getNext(TypeIndex Prev) {
209 int N = ValidRecords.find_next(Prev.toArrayIndex());
212 return TypeIndex::fromArrayIndex(N);