Line data Source code
1 : //===- TypeDatabaseVisitor.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/TypeDatabaseVisitor.h"
11 :
12 : #include "llvm/ADT/SmallString.h"
13 :
14 : using namespace llvm;
15 :
16 : using namespace llvm::codeview;
17 :
18 2874 : Error TypeDatabaseVisitor::visitTypeBegin(CVType &Record) {
19 : assert(!IsInFieldList);
20 : // Reset Name to the empty string. If the visitor sets it, we know it.
21 2874 : Name = "";
22 :
23 2874 : if (Record.Type == LF_FIELDLIST) {
24 : // Record that we're in a field list so that members do not get assigned
25 : // type indices.
26 294 : IsInFieldList = true;
27 : }
28 8622 : return Error::success();
29 : }
30 :
31 2874 : Error TypeDatabaseVisitor::visitTypeBegin(CVType &Record, TypeIndex Index) {
32 8622 : if (auto EC = visitTypeBegin(Record))
33 0 : return EC;
34 :
35 5748 : CurrentTypeIndex = Index;
36 8622 : return Error::success();
37 : }
38 :
39 1851 : StringRef TypeDatabaseVisitor::getTypeName(TypeIndex Index) const {
40 1851 : return TypeDB->getTypeName(Index);
41 : }
42 :
43 1119 : StringRef TypeDatabaseVisitor::saveTypeName(StringRef Name) {
44 1119 : return TypeDB->saveTypeName(Name);
45 : }
46 :
47 2874 : Error TypeDatabaseVisitor::visitTypeEnd(CVType &CVR) {
48 2874 : if (CVR.Type == LF_FIELDLIST) {
49 : assert(IsInFieldList);
50 294 : IsInFieldList = false;
51 : }
52 : assert(!IsInFieldList);
53 :
54 : // Record every type that is not a field list member, even if Name is empty.
55 : // CVUDTNames is indexed by type index, and must have one entry for every
56 : // type. Field list members are not recorded, and are only referenced by
57 : // their containing field list record.
58 2874 : if (CurrentTypeIndex)
59 5748 : TypeDB->recordType(Name, *CurrentTypeIndex, CVR);
60 : else
61 0 : TypeDB->appendType(Name, CVR);
62 :
63 5748 : CurrentTypeIndex.reset();
64 8622 : return Error::success();
65 : }
66 :
67 0 : Error TypeDatabaseVisitor::visitMemberBegin(CVMemberRecord &Record) {
68 : assert(IsInFieldList);
69 : // Reset Name to the empty string. If the visitor sets it, we know it.
70 0 : Name = "";
71 0 : return Error::success();
72 : }
73 :
74 0 : Error TypeDatabaseVisitor::visitMemberEnd(CVMemberRecord &Record) {
75 : assert(IsInFieldList);
76 0 : return Error::success();
77 : }
78 :
79 294 : Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR,
80 : FieldListRecord &FieldList) {
81 294 : Name = "<field list>";
82 882 : return Error::success();
83 : }
84 :
85 201 : Error TypeDatabaseVisitor::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
86 : StringIdRecord &String) {
87 : // Put this in the database so it gets printed with LF_UDT_SRC_LINE.
88 201 : Name = String.getString();
89 603 : return Error::success();
90 : }
91 :
92 278 : Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, ArgListRecord &Args) {
93 278 : auto Indices = Args.getIndices();
94 278 : uint32_t Size = Indices.size();
95 834 : SmallString<256> TypeName("(");
96 585 : for (uint32_t I = 0; I < Size; ++I) {
97 614 : StringRef ArgTypeName = getTypeName(Indices[I]);
98 307 : TypeName.append(ArgTypeName);
99 307 : if (I + 1 != Size)
100 312 : TypeName.append(", ");
101 : }
102 278 : TypeName.push_back(')');
103 278 : Name = saveTypeName(TypeName);
104 1112 : return Error::success();
105 : }
106 :
107 21 : Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR,
108 : StringListRecord &Strings) {
109 21 : auto Indices = Strings.getIndices();
110 21 : uint32_t Size = Indices.size();
111 63 : SmallString<256> TypeName("\"");
112 43 : for (uint32_t I = 0; I < Size; ++I) {
113 44 : StringRef ArgTypeName = getTypeName(Indices[I]);
114 22 : TypeName.append(ArgTypeName);
115 22 : if (I + 1 != Size)
116 2 : TypeName.append("\" \"");
117 : }
118 21 : TypeName.push_back('\"');
119 21 : Name = saveTypeName(TypeName);
120 84 : return Error::success();
121 : }
122 :
123 424 : Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, ClassRecord &Class) {
124 424 : Name = Class.getName();
125 1272 : return Error::success();
126 : }
127 :
128 14 : Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, UnionRecord &Union) {
129 14 : Name = Union.getName();
130 42 : return Error::success();
131 : }
132 :
133 78 : Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, EnumRecord &Enum) {
134 78 : Name = Enum.getName();
135 234 : return Error::success();
136 : }
137 :
138 76 : Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, ArrayRecord &AT) {
139 76 : Name = AT.getName();
140 228 : return Error::success();
141 : }
142 :
143 7 : Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, VFTableRecord &VFT) {
144 7 : Name = VFT.getName();
145 21 : return Error::success();
146 : }
147 :
148 61 : Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR,
149 : MemberFuncIdRecord &Id) {
150 61 : Name = Id.getName();
151 183 : return Error::success();
152 : }
153 :
154 183 : Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR,
155 : ProcedureRecord &Proc) {
156 183 : StringRef ReturnTypeName = getTypeName(Proc.getReturnType());
157 183 : StringRef ArgListTypeName = getTypeName(Proc.getArgumentList());
158 366 : SmallString<256> TypeName(ReturnTypeName);
159 183 : TypeName.push_back(' ');
160 183 : TypeName.append(ArgListTypeName);
161 183 : Name = saveTypeName(TypeName);
162 732 : return Error::success();
163 : }
164 :
165 258 : Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR,
166 : MemberFunctionRecord &MF) {
167 258 : StringRef ReturnTypeName = getTypeName(MF.getReturnType());
168 258 : StringRef ClassTypeName = getTypeName(MF.getClassType());
169 258 : StringRef ArgListTypeName = getTypeName(MF.getArgumentList());
170 516 : SmallString<256> TypeName(ReturnTypeName);
171 258 : TypeName.push_back(' ');
172 258 : TypeName.append(ClassTypeName);
173 516 : TypeName.append("::");
174 258 : TypeName.append(ArgListTypeName);
175 258 : Name = saveTypeName(TypeName);
176 1032 : return Error::success();
177 : }
178 :
179 255 : Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, FuncIdRecord &Func) {
180 255 : Name = Func.getName();
181 765 : return Error::success();
182 : }
183 :
184 0 : Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR,
185 : TypeServer2Record &TS) {
186 0 : Name = TS.getName();
187 0 : return Error::success();
188 : }
189 :
190 299 : Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
191 :
192 299 : if (Ptr.isPointerToMember()) {
193 24 : const MemberPointerInfo &MI = Ptr.getMemberInfo();
194 :
195 24 : StringRef PointeeName = getTypeName(Ptr.getReferentType());
196 24 : StringRef ClassName = getTypeName(MI.getContainingType());
197 48 : SmallString<256> TypeName(PointeeName);
198 24 : TypeName.push_back(' ');
199 24 : TypeName.append(ClassName);
200 48 : TypeName.append("::*");
201 24 : Name = saveTypeName(TypeName);
202 : } else {
203 550 : SmallString<256> TypeName;
204 550 : if (Ptr.isConst())
205 158 : TypeName.append("const ");
206 550 : if (Ptr.isVolatile())
207 0 : TypeName.append("volatile ");
208 550 : if (Ptr.isUnaligned())
209 0 : TypeName.append("__unaligned ");
210 :
211 550 : TypeName.append(getTypeName(Ptr.getReferentType()));
212 :
213 550 : if (Ptr.getMode() == PointerMode::LValueReference)
214 52 : TypeName.append("&");
215 249 : else if (Ptr.getMode() == PointerMode::RValueReference)
216 6 : TypeName.append("&&");
217 246 : else if (Ptr.getMode() == PointerMode::Pointer)
218 492 : TypeName.append("*");
219 :
220 275 : if (!TypeName.empty())
221 275 : Name = saveTypeName(TypeName);
222 : }
223 897 : return Error::success();
224 : }
225 :
226 59 : Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, ModifierRecord &Mod) {
227 59 : uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
228 :
229 59 : StringRef ModifiedName = getTypeName(Mod.getModifiedType());
230 118 : SmallString<256> TypeName;
231 59 : if (Mods & uint16_t(ModifierOptions::Const))
232 96 : TypeName.append("const ");
233 59 : if (Mods & uint16_t(ModifierOptions::Volatile))
234 26 : TypeName.append("volatile ");
235 59 : if (Mods & uint16_t(ModifierOptions::Unaligned))
236 0 : TypeName.append("__unaligned ");
237 59 : TypeName.append(ModifiedName);
238 59 : Name = saveTypeName(TypeName);
239 236 : return Error::success();
240 : }
241 :
242 21 : Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR,
243 : VFTableShapeRecord &Shape) {
244 : Name =
245 105 : saveTypeName("<vftable " + utostr(Shape.getEntryCount()) + " methods>");
246 63 : return Error::success();
247 : }
248 :
249 0 : Error TypeDatabaseVisitor::visitKnownMember(CVMemberRecord &CVR,
250 : NestedTypeRecord &Nested) {
251 0 : Name = Nested.getName();
252 0 : return Error::success();
253 : }
254 :
255 0 : Error TypeDatabaseVisitor::visitKnownMember(CVMemberRecord &CVR,
256 : OneMethodRecord &Method) {
257 0 : Name = Method.getName();
258 0 : return Error::success();
259 : }
260 :
261 0 : Error TypeDatabaseVisitor::visitKnownMember(CVMemberRecord &CVR,
262 : OverloadedMethodRecord &Method) {
263 0 : Name = Method.getName();
264 0 : return Error::success();
265 : }
266 :
267 0 : Error TypeDatabaseVisitor::visitKnownMember(CVMemberRecord &CVR,
268 : DataMemberRecord &Field) {
269 0 : Name = Field.getName();
270 0 : return Error::success();
271 : }
272 :
273 0 : Error TypeDatabaseVisitor::visitKnownMember(CVMemberRecord &CVR,
274 : StaticDataMemberRecord &Field) {
275 0 : Name = Field.getName();
276 0 : return Error::success();
277 : }
278 :
279 0 : Error TypeDatabaseVisitor::visitKnownMember(CVMemberRecord &CVR,
280 : EnumeratorRecord &Enum) {
281 0 : Name = Enum.getName();
282 0 : return Error::success();
283 : }
284 :
285 0 : Error TypeDatabaseVisitor::visitKnownMember(CVMemberRecord &CVR,
286 : BaseClassRecord &Base) {
287 0 : return Error::success();
288 : }
289 :
290 0 : Error TypeDatabaseVisitor::visitKnownMember(CVMemberRecord &CVR,
291 : VirtualBaseClassRecord &VBase) {
292 0 : return Error::success();
293 : }
294 :
295 0 : Error TypeDatabaseVisitor::visitKnownMember(CVMemberRecord &CVR,
296 : ListContinuationRecord &Cont) {
297 0 : return Error::success();
298 : }
299 :
300 8 : Error TypeDatabaseVisitor::visitKnownRecord(
301 : CVType &CVR, UdtModSourceLineRecord &ModSourceLine) {
302 24 : return Error::success();
303 : }
304 :
305 238 : Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR,
306 : UdtSourceLineRecord &SourceLine) {
307 714 : return Error::success();
308 : }
309 :
310 10 : Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, BitFieldRecord &BF) {
311 20 : return Error::success();
312 : }
313 :
314 65 : Error TypeDatabaseVisitor::visitKnownRecord(
315 : CVType &CVR, MethodOverloadListRecord &Overloads) {
316 195 : return Error::success();
317 : }
318 :
319 23 : Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, BuildInfoRecord &BI) {
320 69 : return Error::success();
321 : }
322 :
323 1 : Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, LabelRecord &R) {
324 3 : return Error::success();
325 : }
326 :
327 0 : Error TypeDatabaseVisitor::visitKnownMember(CVMemberRecord &CVR,
328 : VFPtrRecord &VFP) {
329 0 : return Error::success();
330 : }
|