blob: 0677554c4cfb6e969b38fd3b77d58de2a5ccc848 [file] [log] [blame]
Zachary Turner307f5ae2018-10-12 19:47:13 +00001//===-- PdbUtil.cpp ---------------------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Zachary Turner307f5ae2018-10-12 19:47:13 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "PdbUtil.h"
Zachary Turner594c85e2018-12-17 19:43:33 +000010
11#include "DWARFLocationExpression.h"
12#include "PdbIndex.h"
Zachary Turner6284aee2018-11-16 02:42:32 +000013#include "PdbSymUid.h"
Zachary Turner307f5ae2018-10-12 19:47:13 +000014
15#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
Zachary Turnerb96181c2018-10-22 16:19:07 +000016#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
Zachary Turner6284aee2018-11-16 02:42:32 +000017#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
Zachary Turner307f5ae2018-10-12 19:47:13 +000018
Zachary Turner44f19512019-01-10 20:57:32 +000019#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
Zachary Turner307f5ae2018-10-12 19:47:13 +000020#include "lldb/Utility/LLDBAssert.h"
Zachary Turnerb96181c2018-10-22 16:19:07 +000021#include "lldb/lldb-enumerations.h"
22
Zachary Turner307f5ae2018-10-12 19:47:13 +000023using namespace lldb_private;
24using namespace lldb_private::npdb;
25using namespace llvm::codeview;
26using namespace llvm::pdb;
27
Zachary Turner594c85e2018-12-17 19:43:33 +000028static Variable::RangeList
29MakeRangeList(const PdbIndex &index, const LocalVariableAddrRange &range,
30 llvm::ArrayRef<LocalVariableAddrGap> gaps) {
31 lldb::addr_t start =
32 index.MakeVirtualAddress(range.ISectStart, range.OffsetStart);
33 lldb::addr_t end = start + range.Range;
34
35 Variable::RangeList result;
36 while (!gaps.empty()) {
37 const LocalVariableAddrGap &gap = gaps.front();
38
39 lldb::addr_t size = gap.GapStartOffset - start;
40 result.Append(start, size);
41 start += gap.Range;
42 gaps = gaps.drop_front();
43 }
44
45 result.Append(start, end);
46 return result;
47}
48
Zachary Turner056e4ab2018-11-08 18:50:11 +000049CVTagRecord CVTagRecord::create(CVType type) {
50 assert(IsTagRecord(type) && "type is not a tag record!");
51 switch (type.kind()) {
52 case LF_CLASS:
53 case LF_STRUCTURE:
54 case LF_INTERFACE: {
55 ClassRecord cr;
56 llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(type, cr));
57 return CVTagRecord(std::move(cr));
58 }
59 case LF_UNION: {
60 UnionRecord ur;
61 llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(type, ur));
62 return CVTagRecord(std::move(ur));
63 }
64 case LF_ENUM: {
65 EnumRecord er;
66 llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(type, er));
67 return CVTagRecord(std::move(er));
68 }
69 default:
70 llvm_unreachable("Unreachable!");
71 }
72}
73
74CVTagRecord::CVTagRecord(ClassRecord &&c)
75 : cvclass(std::move(c)),
76 m_kind(cvclass.Kind == TypeRecordKind::Struct ? Struct : Class) {}
77CVTagRecord::CVTagRecord(UnionRecord &&u)
78 : cvunion(std::move(u)), m_kind(Union) {}
79CVTagRecord::CVTagRecord(EnumRecord &&e) : cvenum(std::move(e)), m_kind(Enum) {}
80
Zachary Turnerb96181c2018-10-22 16:19:07 +000081PDB_SymType lldb_private::npdb::CVSymToPDBSym(SymbolKind kind) {
Zachary Turner307f5ae2018-10-12 19:47:13 +000082 switch (kind) {
83 case S_COMPILE3:
84 case S_OBJNAME:
85 return PDB_SymType::CompilandDetails;
86 case S_ENVBLOCK:
87 return PDB_SymType::CompilandEnv;
88 case S_THUNK32:
89 case S_TRAMPOLINE:
90 return PDB_SymType::Thunk;
91 case S_COFFGROUP:
92 return PDB_SymType::CoffGroup;
93 case S_EXPORT:
94 return PDB_SymType::Export;
95 case S_LPROC32:
96 case S_GPROC32:
97 case S_LPROC32_DPC:
98 return PDB_SymType::Function;
99 case S_PUB32:
100 return PDB_SymType::PublicSymbol;
101 case S_INLINESITE:
102 return PDB_SymType::InlineSite;
103 case S_LOCAL:
104 case S_BPREL32:
105 case S_REGREL32:
106 case S_MANCONSTANT:
107 case S_CONSTANT:
108 case S_LDATA32:
109 case S_GDATA32:
110 case S_LMANDATA:
111 case S_GMANDATA:
112 case S_LTHREAD32:
113 case S_GTHREAD32:
114 return PDB_SymType::Data;
115 case S_BLOCK32:
116 return PDB_SymType::Block;
117 case S_LABEL32:
118 return PDB_SymType::Label;
119 case S_CALLSITEINFO:
120 return PDB_SymType::CallSite;
121 case S_HEAPALLOCSITE:
122 return PDB_SymType::HeapAllocationSite;
123 case S_CALLEES:
124 return PDB_SymType::Callee;
125 case S_CALLERS:
126 return PDB_SymType::Caller;
127 default:
128 lldbassert(false && "Invalid symbol record kind!");
129 }
130 return PDB_SymType::None;
131}
132
Zachary Turnerb96181c2018-10-22 16:19:07 +0000133PDB_SymType lldb_private::npdb::CVTypeToPDBType(TypeLeafKind kind) {
134 switch (kind) {
135 case LF_ARRAY:
136 return PDB_SymType::ArrayType;
137 case LF_ARGLIST:
138 return PDB_SymType::FunctionSig;
139 case LF_BCLASS:
140 return PDB_SymType::BaseClass;
141 case LF_BINTERFACE:
142 return PDB_SymType::BaseInterface;
143 case LF_CLASS:
144 case LF_STRUCTURE:
145 case LF_INTERFACE:
146 case LF_UNION:
147 return PDB_SymType::UDT;
148 case LF_POINTER:
149 return PDB_SymType::PointerType;
150 case LF_ENUM:
151 return PDB_SymType::Enum;
Zachary Turner544a66d82018-11-01 16:37:29 +0000152 case LF_PROCEDURE:
153 return PDB_SymType::FunctionSig;
Zachary Turner056e4ab2018-11-08 18:50:11 +0000154 case LF_BITFIELD:
155 return PDB_SymType::BuiltinType;
Zachary Turnerb96181c2018-10-22 16:19:07 +0000156 default:
157 lldbassert(false && "Invalid type record kind!");
158 }
159 return PDB_SymType::None;
160}
161
162bool lldb_private::npdb::SymbolHasAddress(const CVSymbol &sym) {
Zachary Turner307f5ae2018-10-12 19:47:13 +0000163 switch (sym.kind()) {
164 case S_GPROC32:
165 case S_LPROC32:
166 case S_GPROC32_ID:
167 case S_LPROC32_ID:
168 case S_LPROC32_DPC:
169 case S_LPROC32_DPC_ID:
170 case S_THUNK32:
171 case S_TRAMPOLINE:
172 case S_COFFGROUP:
173 case S_BLOCK32:
174 case S_LABEL32:
175 case S_CALLSITEINFO:
176 case S_HEAPALLOCSITE:
177 case S_LDATA32:
178 case S_GDATA32:
179 case S_LMANDATA:
180 case S_GMANDATA:
181 case S_LTHREAD32:
182 case S_GTHREAD32:
183 return true;
184 default:
185 return false;
186 }
187}
188
Zachary Turnerb96181c2018-10-22 16:19:07 +0000189bool lldb_private::npdb::SymbolIsCode(const CVSymbol &sym) {
Zachary Turner307f5ae2018-10-12 19:47:13 +0000190 switch (sym.kind()) {
191 case S_GPROC32:
192 case S_LPROC32:
193 case S_GPROC32_ID:
194 case S_LPROC32_ID:
195 case S_LPROC32_DPC:
196 case S_LPROC32_DPC_ID:
197 case S_THUNK32:
198 case S_TRAMPOLINE:
199 case S_COFFGROUP:
200 case S_BLOCK32:
201 return true;
202 default:
203 return false;
204 }
205}
206
207template <typename RecordT> RecordT createRecord(const CVSymbol &sym) {
208 RecordT record(static_cast<SymbolRecordKind>(sym.kind()));
209 cantFail(SymbolDeserializer::deserializeAs<RecordT>(sym, record));
210 return record;
211}
212
213template <typename RecordT>
214static SegmentOffset GetSegmentAndOffset(const CVSymbol &sym) {
215 RecordT record = createRecord<RecordT>(sym);
216 return {record.Segment, record.CodeOffset};
217}
218
219template <>
220SegmentOffset GetSegmentAndOffset<TrampolineSym>(const CVSymbol &sym) {
221 TrampolineSym record = createRecord<TrampolineSym>(sym);
222 return {record.ThunkSection, record.ThunkOffset};
223}
224
225template <> SegmentOffset GetSegmentAndOffset<Thunk32Sym>(const CVSymbol &sym) {
226 Thunk32Sym record = createRecord<Thunk32Sym>(sym);
227 return {record.Segment, record.Offset};
228}
229
230template <>
231SegmentOffset GetSegmentAndOffset<CoffGroupSym>(const CVSymbol &sym) {
232 CoffGroupSym record = createRecord<CoffGroupSym>(sym);
233 return {record.Segment, record.Offset};
234}
235
236template <> SegmentOffset GetSegmentAndOffset<DataSym>(const CVSymbol &sym) {
237 DataSym record = createRecord<DataSym>(sym);
238 return {record.Segment, record.DataOffset};
239}
240
241template <>
242SegmentOffset GetSegmentAndOffset<ThreadLocalDataSym>(const CVSymbol &sym) {
243 ThreadLocalDataSym record = createRecord<ThreadLocalDataSym>(sym);
244 return {record.Segment, record.DataOffset};
245}
246
Zachary Turnerb96181c2018-10-22 16:19:07 +0000247SegmentOffset lldb_private::npdb::GetSegmentAndOffset(const CVSymbol &sym) {
Zachary Turner307f5ae2018-10-12 19:47:13 +0000248 switch (sym.kind()) {
249 case S_GPROC32:
250 case S_LPROC32:
251 case S_GPROC32_ID:
252 case S_LPROC32_ID:
253 case S_LPROC32_DPC:
254 case S_LPROC32_DPC_ID:
255 return ::GetSegmentAndOffset<ProcSym>(sym);
256 case S_THUNK32:
257 return ::GetSegmentAndOffset<Thunk32Sym>(sym);
258 break;
259 case S_TRAMPOLINE:
260 return ::GetSegmentAndOffset<TrampolineSym>(sym);
261 break;
262 case S_COFFGROUP:
263 return ::GetSegmentAndOffset<CoffGroupSym>(sym);
264 break;
265 case S_BLOCK32:
266 return ::GetSegmentAndOffset<BlockSym>(sym);
267 break;
268 case S_LABEL32:
269 return ::GetSegmentAndOffset<LabelSym>(sym);
270 break;
271 case S_CALLSITEINFO:
272 return ::GetSegmentAndOffset<CallSiteInfoSym>(sym);
273 break;
274 case S_HEAPALLOCSITE:
275 return ::GetSegmentAndOffset<HeapAllocationSiteSym>(sym);
276 break;
277 case S_LDATA32:
278 case S_GDATA32:
279 case S_LMANDATA:
280 case S_GMANDATA:
281 return ::GetSegmentAndOffset<DataSym>(sym);
282 break;
283 case S_LTHREAD32:
284 case S_GTHREAD32:
285 return ::GetSegmentAndOffset<ThreadLocalDataSym>(sym);
286 break;
287 default:
288 lldbassert(false && "Record does not have a segment/offset!");
289 }
290 return {0, 0};
291}
292
293template <typename RecordT>
294SegmentOffsetLength GetSegmentOffsetAndLength(const CVSymbol &sym) {
295 RecordT record = createRecord<RecordT>(sym);
296 return {record.Segment, record.CodeOffset, record.CodeSize};
297}
298
299template <>
300SegmentOffsetLength
301GetSegmentOffsetAndLength<TrampolineSym>(const CVSymbol &sym) {
302 TrampolineSym record = createRecord<TrampolineSym>(sym);
303 return {record.ThunkSection, record.ThunkOffset, record.Size};
304}
305
306template <>
307SegmentOffsetLength GetSegmentOffsetAndLength<Thunk32Sym>(const CVSymbol &sym) {
308 Thunk32Sym record = createRecord<Thunk32Sym>(sym);
309 return SegmentOffsetLength{record.Segment, record.Offset, record.Length};
310}
311
312template <>
313SegmentOffsetLength
314GetSegmentOffsetAndLength<CoffGroupSym>(const CVSymbol &sym) {
315 CoffGroupSym record = createRecord<CoffGroupSym>(sym);
316 return SegmentOffsetLength{record.Segment, record.Offset, record.Size};
317}
318
Zachary Turnerb96181c2018-10-22 16:19:07 +0000319SegmentOffsetLength
320lldb_private::npdb::GetSegmentOffsetAndLength(const CVSymbol &sym) {
Zachary Turner307f5ae2018-10-12 19:47:13 +0000321 switch (sym.kind()) {
322 case S_GPROC32:
323 case S_LPROC32:
324 case S_GPROC32_ID:
325 case S_LPROC32_ID:
326 case S_LPROC32_DPC:
327 case S_LPROC32_DPC_ID:
328 return ::GetSegmentOffsetAndLength<ProcSym>(sym);
329 case S_THUNK32:
330 return ::GetSegmentOffsetAndLength<Thunk32Sym>(sym);
331 break;
332 case S_TRAMPOLINE:
333 return ::GetSegmentOffsetAndLength<TrampolineSym>(sym);
334 break;
335 case S_COFFGROUP:
336 return ::GetSegmentOffsetAndLength<CoffGroupSym>(sym);
337 break;
338 case S_BLOCK32:
339 return ::GetSegmentOffsetAndLength<BlockSym>(sym);
340 break;
341 default:
342 lldbassert(false && "Record does not have a segment/offset/length triple!");
343 }
344 return {0, 0, 0};
345}
Zachary Turnerb96181c2018-10-22 16:19:07 +0000346
347bool lldb_private::npdb::IsForwardRefUdt(CVType cvt) {
348 ClassRecord cr;
349 UnionRecord ur;
350 EnumRecord er;
351 switch (cvt.kind()) {
352 case LF_CLASS:
353 case LF_STRUCTURE:
354 case LF_INTERFACE:
355 llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr));
356 return cr.isForwardRef();
357 case LF_UNION:
358 llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur));
359 return ur.isForwardRef();
360 case LF_ENUM:
361 llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
362 return er.isForwardRef();
363 default:
364 return false;
365 }
366}
367
Zachary Turner056e4ab2018-11-08 18:50:11 +0000368bool lldb_private::npdb::IsTagRecord(llvm::codeview::CVType cvt) {
369 switch (cvt.kind()) {
370 case LF_CLASS:
371 case LF_STRUCTURE:
372 case LF_UNION:
373 case LF_ENUM:
374 return true;
375 default:
376 return false;
377 }
378}
379
Zachary Turner594c85e2018-12-17 19:43:33 +0000380bool lldb_private::npdb::IsClassStructUnion(llvm::codeview::CVType cvt) {
381 switch (cvt.kind()) {
382 case LF_CLASS:
383 case LF_STRUCTURE:
384 case LF_UNION:
385 return true;
386 default:
387 return false;
388 }
389}
390
Zachary Turner6284aee2018-11-16 02:42:32 +0000391bool lldb_private::npdb::IsForwardRefUdt(const PdbTypeSymId &id,
392 TpiStream &tpi) {
393 if (id.is_ipi || id.index.isSimple())
394 return false;
395 return IsForwardRefUdt(tpi.getType(id.index));
396}
397
398bool lldb_private::npdb::IsTagRecord(const PdbTypeSymId &id, TpiStream &tpi) {
399 if (id.is_ipi || id.index.isSimple())
400 return false;
401 return IsTagRecord(tpi.getType(id.index));
402}
403
Zachary Turnerb96181c2018-10-22 16:19:07 +0000404lldb::AccessType
405lldb_private::npdb::TranslateMemberAccess(MemberAccess access) {
406 switch (access) {
407 case MemberAccess::Private:
408 return lldb::eAccessPrivate;
409 case MemberAccess::Protected:
410 return lldb::eAccessProtected;
411 case MemberAccess::Public:
412 return lldb::eAccessPublic;
413 case MemberAccess::None:
414 return lldb::eAccessNone;
415 }
416 llvm_unreachable("unreachable");
417}
418
419TypeIndex lldb_private::npdb::GetFieldListIndex(CVType cvt) {
420 switch (cvt.kind()) {
421 case LF_CLASS:
422 case LF_STRUCTURE:
423 case LF_INTERFACE: {
424 ClassRecord cr;
425 cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr));
426 return cr.FieldList;
427 }
428 case LF_UNION: {
429 UnionRecord ur;
430 cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur));
431 return ur.FieldList;
432 }
433 case LF_ENUM: {
434 EnumRecord er;
435 cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
436 return er.FieldList;
437 }
438 default:
439 llvm_unreachable("Unreachable!");
440 }
441}
442
Zachary Turner511bff22018-10-30 18:57:08 +0000443TypeIndex lldb_private::npdb::LookThroughModifierRecord(CVType modifier) {
444 lldbassert(modifier.kind() == LF_MODIFIER);
445 ModifierRecord mr;
446 llvm::cantFail(TypeDeserializer::deserializeAs<ModifierRecord>(modifier, mr));
447 return mr.ModifiedType;
448}
449
Zachary Turnerb96181c2018-10-22 16:19:07 +0000450llvm::StringRef lldb_private::npdb::DropNameScope(llvm::StringRef name) {
Zachary Turner44f19512019-01-10 20:57:32 +0000451 return MSVCUndecoratedNameParser::DropScope(name);
Zachary Turner544a66d82018-11-01 16:37:29 +0000452}
Zachary Turnera93458b2018-12-06 17:49:15 +0000453
Zachary Turner594c85e2018-12-17 19:43:33 +0000454VariableInfo lldb_private::npdb::GetVariableNameInfo(CVSymbol sym) {
455 VariableInfo result;
456
457 if (sym.kind() == S_REGREL32) {
458 RegRelativeSym reg(SymbolRecordKind::RegRelativeSym);
459 cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg));
460 result.type = reg.Type;
461 result.name = reg.Name;
462 return result;
463 }
464
465 if (sym.kind() == S_REGISTER) {
466 RegisterSym reg(SymbolRecordKind::RegisterSym);
467 cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg));
468 result.type = reg.Index;
469 result.name = reg.Name;
470 return result;
471 }
472
473 if (sym.kind() == S_LOCAL) {
474 LocalSym local(SymbolRecordKind::LocalSym);
475 cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local));
476 result.type = local.Type;
477 result.name = local.Name;
478 return result;
479 }
480
Zachary Turner37900292018-12-20 23:32:37 +0000481 if (sym.kind() == S_GDATA32 || sym.kind() == S_LDATA32) {
482 DataSym data(SymbolRecordKind::DataSym);
483 cantFail(SymbolDeserializer::deserializeAs<DataSym>(sym, data));
484 result.type = data.Type;
485 result.name = data.Name;
486 return result;
487 }
488
489 if (sym.kind() == S_GTHREAD32 || sym.kind() == S_LTHREAD32) {
490 ThreadLocalDataSym data(SymbolRecordKind::ThreadLocalDataSym);
491 cantFail(SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym, data));
492 result.type = data.Type;
493 result.name = data.Name;
494 return result;
495 }
496
497 if (sym.kind() == S_CONSTANT) {
498 ConstantSym constant(SymbolRecordKind::ConstantSym);
499 cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(sym, constant));
500 result.type = constant.Type;
501 result.name = constant.Name;
502 return result;
503 }
504
Zachary Turner594c85e2018-12-17 19:43:33 +0000505 lldbassert(false && "Invalid variable record kind!");
506 return {};
507}
508
509VariableInfo lldb_private::npdb::GetVariableLocationInfo(
510 PdbIndex &index, PdbCompilandSymId var_id, lldb::ModuleSP module) {
511
512 CVSymbol sym = index.ReadSymbolRecord(var_id);
513
514 VariableInfo result = GetVariableNameInfo(sym);
515
516 if (sym.kind() == S_REGREL32) {
517 RegRelativeSym reg(SymbolRecordKind::RegRelativeSym);
518 cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg));
519 result.location =
520 MakeRegRelLocationExpression(reg.Register, reg.Offset, module);
521 result.ranges.emplace();
522 return result;
523 }
524
525 if (sym.kind() == S_REGISTER) {
526 RegisterSym reg(SymbolRecordKind::RegisterSym);
527 cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg));
528 result.location = MakeEnregisteredLocationExpression(reg.Register, module);
529 result.ranges.emplace();
530 return result;
531 }
532
533 if (sym.kind() == S_LOCAL) {
534 LocalSym local(SymbolRecordKind::LocalSym);
535 cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local));
536
537 PdbCompilandSymId loc_specifier_id(var_id.modi,
538 var_id.offset + sym.RecordData.size());
539 CVSymbol loc_specifier_cvs = index.ReadSymbolRecord(loc_specifier_id);
540 if (loc_specifier_cvs.kind() == S_DEFRANGE_FRAMEPOINTER_REL) {
541 DefRangeFramePointerRelSym loc(
542 SymbolRecordKind::DefRangeFramePointerRelSym);
543 cantFail(SymbolDeserializer::deserializeAs<DefRangeFramePointerRelSym>(
544 loc_specifier_cvs, loc));
545 // FIXME: The register needs to come from the S_FRAMEPROC symbol.
546 result.location =
547 MakeRegRelLocationExpression(RegisterId::RSP, loc.Offset, module);
548 result.ranges = MakeRangeList(index, loc.Range, loc.Gaps);
549 } else {
550 // FIXME: Handle other kinds
Zachary Turner594c85e2018-12-17 19:43:33 +0000551 }
552 return result;
553 }
554 llvm_unreachable("Symbol is not a local variable!");
555 return result;
556}
557
Zachary Turnera93458b2018-12-06 17:49:15 +0000558lldb::BasicType
559lldb_private::npdb::GetCompilerTypeForSimpleKind(SimpleTypeKind kind) {
560 switch (kind) {
561 case SimpleTypeKind::Boolean128:
562 case SimpleTypeKind::Boolean16:
563 case SimpleTypeKind::Boolean32:
564 case SimpleTypeKind::Boolean64:
565 case SimpleTypeKind::Boolean8:
566 return lldb::eBasicTypeBool;
567 case SimpleTypeKind::Byte:
568 case SimpleTypeKind::UnsignedCharacter:
569 return lldb::eBasicTypeUnsignedChar;
570 case SimpleTypeKind::NarrowCharacter:
571 return lldb::eBasicTypeChar;
572 case SimpleTypeKind::SignedCharacter:
573 case SimpleTypeKind::SByte:
574 return lldb::eBasicTypeSignedChar;
575 case SimpleTypeKind::Character16:
576 return lldb::eBasicTypeChar16;
577 case SimpleTypeKind::Character32:
578 return lldb::eBasicTypeChar32;
579 case SimpleTypeKind::Complex80:
580 return lldb::eBasicTypeLongDoubleComplex;
581 case SimpleTypeKind::Complex64:
582 return lldb::eBasicTypeDoubleComplex;
583 case SimpleTypeKind::Complex32:
584 return lldb::eBasicTypeFloatComplex;
585 case SimpleTypeKind::Float128:
586 case SimpleTypeKind::Float80:
587 return lldb::eBasicTypeLongDouble;
588 case SimpleTypeKind::Float64:
589 return lldb::eBasicTypeDouble;
590 case SimpleTypeKind::Float32:
591 return lldb::eBasicTypeFloat;
592 case SimpleTypeKind::Float16:
593 return lldb::eBasicTypeHalf;
594 case SimpleTypeKind::Int128:
595 return lldb::eBasicTypeInt128;
596 case SimpleTypeKind::Int64:
597 case SimpleTypeKind::Int64Quad:
598 return lldb::eBasicTypeLongLong;
599 case SimpleTypeKind::Int32:
600 return lldb::eBasicTypeInt;
601 case SimpleTypeKind::Int16:
602 case SimpleTypeKind::Int16Short:
603 return lldb::eBasicTypeShort;
604 case SimpleTypeKind::UInt128:
605 return lldb::eBasicTypeUnsignedInt128;
606 case SimpleTypeKind::UInt64:
607 case SimpleTypeKind::UInt64Quad:
608 return lldb::eBasicTypeUnsignedLongLong;
609 case SimpleTypeKind::HResult:
610 case SimpleTypeKind::UInt32:
611 return lldb::eBasicTypeUnsignedInt;
612 case SimpleTypeKind::UInt16:
613 case SimpleTypeKind::UInt16Short:
614 return lldb::eBasicTypeUnsignedShort;
615 case SimpleTypeKind::Int32Long:
616 return lldb::eBasicTypeLong;
617 case SimpleTypeKind::UInt32Long:
618 return lldb::eBasicTypeUnsignedLong;
619 case SimpleTypeKind::Void:
620 return lldb::eBasicTypeVoid;
621 case SimpleTypeKind::WideCharacter:
622 return lldb::eBasicTypeWChar;
623 default:
624 return lldb::eBasicTypeInvalid;
625 }
626}
627
628size_t lldb_private::npdb::GetTypeSizeForSimpleKind(SimpleTypeKind kind) {
629 switch (kind) {
630 case SimpleTypeKind::Boolean128:
631 case SimpleTypeKind::Int128:
632 case SimpleTypeKind::UInt128:
633 case SimpleTypeKind::Float128:
634 return 16;
635 case SimpleTypeKind::Complex80:
636 case SimpleTypeKind::Float80:
637 return 10;
638 case SimpleTypeKind::Boolean64:
639 case SimpleTypeKind::Complex64:
640 case SimpleTypeKind::UInt64:
641 case SimpleTypeKind::UInt64Quad:
642 case SimpleTypeKind::Float64:
643 case SimpleTypeKind::Int64:
644 case SimpleTypeKind::Int64Quad:
645 return 8;
646 case SimpleTypeKind::Boolean32:
647 case SimpleTypeKind::Character32:
648 case SimpleTypeKind::Complex32:
649 case SimpleTypeKind::Float32:
650 case SimpleTypeKind::Int32:
651 case SimpleTypeKind::Int32Long:
652 case SimpleTypeKind::UInt32Long:
653 case SimpleTypeKind::HResult:
654 case SimpleTypeKind::UInt32:
655 return 4;
656 case SimpleTypeKind::Boolean16:
657 case SimpleTypeKind::Character16:
658 case SimpleTypeKind::Float16:
659 case SimpleTypeKind::Int16:
660 case SimpleTypeKind::Int16Short:
661 case SimpleTypeKind::UInt16:
662 case SimpleTypeKind::UInt16Short:
663 case SimpleTypeKind::WideCharacter:
664 return 2;
665 case SimpleTypeKind::Boolean8:
666 case SimpleTypeKind::Byte:
667 case SimpleTypeKind::UnsignedCharacter:
668 case SimpleTypeKind::NarrowCharacter:
669 case SimpleTypeKind::SignedCharacter:
670 case SimpleTypeKind::SByte:
671 return 1;
672 case SimpleTypeKind::Void:
673 default:
674 return 0;
675 }
676}
Zachary Turner594c85e2018-12-17 19:43:33 +0000677
678PdbTypeSymId lldb_private::npdb::GetBestPossibleDecl(PdbTypeSymId id,
679 TpiStream &tpi) {
680 if (id.index.isSimple())
681 return id;
682
683 CVType cvt = tpi.getType(id.index);
684
685 // Only tag records have a best and a worst record.
686 if (!IsTagRecord(cvt))
687 return id;
688
689 // Tag records that are not forward decls are full decls, hence they are the
690 // best.
691 if (!IsForwardRefUdt(cvt))
692 return id;
693
694 return llvm::cantFail(tpi.findFullDeclForForwardRef(id.index));
695}
696
697template <typename RecordType> static size_t GetSizeOfTypeInternal(CVType cvt) {
698 RecordType record;
699 llvm::cantFail(TypeDeserializer::deserializeAs<RecordType>(cvt, record));
700 return record.getSize();
701}
702
703size_t lldb_private::npdb::GetSizeOfType(PdbTypeSymId id,
704 llvm::pdb::TpiStream &tpi) {
705 if (id.index.isSimple()) {
706 switch (id.index.getSimpleMode()) {
707 case SimpleTypeMode::Direct:
708 return GetTypeSizeForSimpleKind(id.index.getSimpleKind());
709 case SimpleTypeMode::NearPointer32:
710 case SimpleTypeMode::FarPointer32:
711 return 4;
712 case SimpleTypeMode::NearPointer64:
713 return 8;
714 case SimpleTypeMode::NearPointer128:
715 return 16;
716 default:
717 break;
718 }
719 return 0;
720 }
721
Zachary Turner22566332019-01-02 18:33:54 +0000722 TypeIndex index = id.index;
723 if (IsForwardRefUdt(index, tpi))
724 index = llvm::cantFail(tpi.findFullDeclForForwardRef(index));
725
726 CVType cvt = tpi.getType(index);
Zachary Turner594c85e2018-12-17 19:43:33 +0000727 switch (cvt.kind()) {
728 case LF_MODIFIER:
729 return GetSizeOfType({LookThroughModifierRecord(cvt)}, tpi);
730 case LF_ENUM: {
731 EnumRecord record;
732 llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, record));
733 return GetSizeOfType({record.UnderlyingType}, tpi);
734 }
735 case LF_POINTER:
736 return GetSizeOfTypeInternal<PointerRecord>(cvt);
737 case LF_ARRAY:
738 return GetSizeOfTypeInternal<ArrayRecord>(cvt);
739 case LF_CLASS:
740 case LF_STRUCTURE:
741 case LF_INTERFACE:
742 return GetSizeOfTypeInternal<ClassRecord>(cvt);
743 case LF_UNION:
744 return GetSizeOfTypeInternal<UnionRecord>(cvt);
745 default:
746 break;
747 }
748 return 0;
749}