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) {
76 TI = getAppendIndex();
77 if (TI.toArrayIndex() >= capacity())
79 recordType(Name, TI, Data);
83 void TypeDatabase::recordType(StringRef Name, TypeIndex Index,
85 uint32_t AI = Index.toArrayIndex();
87 assert(!contains(Index));
88 assert(AI < capacity());
90 CVUDTNames[AI] = Name;
91 TypeRecords[AI] = Data;
96 /// Saves the name in a StringSet and creates a stable StringRef.
97 StringRef TypeDatabase::saveTypeName(StringRef TypeName) {
98 return TypeNameStorage.save(TypeName);
101 StringRef TypeDatabase::getTypeName(TypeIndex Index) const {
102 if (Index.isNoneType())
105 if (Index.isSimple()) {
106 // This is a simple type.
107 for (const auto &SimpleTypeName : SimpleTypeNames) {
108 if (SimpleTypeName.Kind == Index.getSimpleKind()) {
109 if (Index.getSimpleMode() == SimpleTypeMode::Direct)
110 return SimpleTypeName.Name.drop_back(1);
111 // Otherwise, this is a pointer type. We gloss over the distinction
112 // between near, far, 64, 32, etc, and just give a pointer type.
113 return SimpleTypeName.Name;
116 return "<unknown simple type>";
120 return CVUDTNames[Index.toArrayIndex()];
122 return "<unknown UDT>";
125 const CVType &TypeDatabase::getTypeRecord(TypeIndex Index) const {
126 assert(contains(Index));
127 return TypeRecords[Index.toArrayIndex()];
130 CVType &TypeDatabase::getTypeRecord(TypeIndex Index) {
131 assert(contains(Index));
132 return TypeRecords[Index.toArrayIndex()];
135 bool TypeDatabase::contains(TypeIndex Index) const {
136 uint32_t AI = Index.toArrayIndex();
137 if (AI >= capacity())
140 return ValidRecords.test(AI);
143 uint32_t TypeDatabase::size() const { return Count; }
145 uint32_t TypeDatabase::capacity() const { return TypeRecords.size(); }
147 void TypeDatabase::grow() {
148 TypeRecords.emplace_back();
149 CVUDTNames.emplace_back();
150 ValidRecords.resize(ValidRecords.size() + 1);
153 bool TypeDatabase::empty() const { return size() == 0; }
155 TypeIndex TypeDatabase::getAppendIndex() const {
157 return TypeIndex::fromArrayIndex(0);
159 int Index = ValidRecords.find_last();
161 return TypeIndex::fromArrayIndex(Index) + 1;