]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/DebugInfo/CodeView/TypeDatabase.cpp
Merge ^/head r318380 through r318559.
[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   TypeIndex TI;
76   TI = getAppendIndex();
77   if (TI.toArrayIndex() >= capacity())
78     grow();
79   recordType(Name, TI, Data);
80   return TI;
81 }
82
83 void TypeDatabase::recordType(StringRef Name, TypeIndex Index,
84                               const CVType &Data) {
85   uint32_t AI = Index.toArrayIndex();
86
87   assert(!contains(Index));
88   assert(AI < capacity());
89
90   CVUDTNames[AI] = Name;
91   TypeRecords[AI] = Data;
92   ValidRecords.set(AI);
93   ++Count;
94 }
95
96 /// Saves the name in a StringSet and creates a stable StringRef.
97 StringRef TypeDatabase::saveTypeName(StringRef TypeName) {
98   return TypeNameStorage.save(TypeName);
99 }
100
101 StringRef TypeDatabase::getTypeName(TypeIndex Index) const {
102   if (Index.isNoneType())
103     return "<no type>";
104
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;
114       }
115     }
116     return "<unknown simple type>";
117   }
118
119   if (contains(Index))
120     return CVUDTNames[Index.toArrayIndex()];
121
122   return "<unknown UDT>";
123 }
124
125 const CVType &TypeDatabase::getTypeRecord(TypeIndex Index) const {
126   assert(contains(Index));
127   return TypeRecords[Index.toArrayIndex()];
128 }
129
130 CVType &TypeDatabase::getTypeRecord(TypeIndex Index) {
131   assert(contains(Index));
132   return TypeRecords[Index.toArrayIndex()];
133 }
134
135 bool TypeDatabase::contains(TypeIndex Index) const {
136   uint32_t AI = Index.toArrayIndex();
137   if (AI >= capacity())
138     return false;
139
140   return ValidRecords.test(AI);
141 }
142
143 uint32_t TypeDatabase::size() const { return Count; }
144
145 uint32_t TypeDatabase::capacity() const { return TypeRecords.size(); }
146
147 void TypeDatabase::grow() {
148   TypeRecords.emplace_back();
149   CVUDTNames.emplace_back();
150   ValidRecords.resize(ValidRecords.size() + 1);
151 }
152
153 bool TypeDatabase::empty() const { return size() == 0; }
154
155 TypeIndex TypeDatabase::getAppendIndex() const {
156   if (empty())
157     return TypeIndex::fromArrayIndex(0);
158
159   int Index = ValidRecords.find_last();
160   assert(Index != -1);
161   return TypeIndex::fromArrayIndex(Index) + 1;
162 }