1 //===-- CompilerType.cpp --------------------------------------------------===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "lldb/Symbol/CompilerType.h"
10
11 #include "lldb/Core/Debugger.h"
12 #include "lldb/Symbol/Type.h"
13 #include "lldb/Target/ExecutionContext.h"
14 #include "lldb/Target/Process.h"
15 #include "lldb/Utility/ConstString.h"
16 #include "lldb/Utility/DataBufferHeap.h"
17 #include "lldb/Utility/DataExtractor.h"
18 #include "lldb/Utility/Scalar.h"
19 #include "lldb/Utility/Stream.h"
20 #include "lldb/Utility/StreamString.h"
21
22 #include <iterator>
23 #include <mutex>
24 #include <optional>
25
26 using namespace lldb;
27 using namespace lldb_private;
28
29 // Tests
30
IsAggregateType() const31 bool CompilerType::IsAggregateType() const {
32 if (IsValid())
33 if (auto type_system_sp = GetTypeSystem())
34 return type_system_sp->IsAggregateType(m_type);
35 return false;
36 }
37
IsAnonymousType() const38 bool CompilerType::IsAnonymousType() const {
39 if (IsValid())
40 if (auto type_system_sp = GetTypeSystem())
41 return type_system_sp->IsAnonymousType(m_type);
42 return false;
43 }
44
IsScopedEnumerationType() const45 bool CompilerType::IsScopedEnumerationType() const {
46 if (IsValid())
47 if (auto type_system_sp = GetTypeSystem())
48 return type_system_sp->IsScopedEnumerationType(m_type);
49 return false;
50 }
51
IsArrayType(CompilerType * element_type_ptr,uint64_t * size,bool * is_incomplete) const52 bool CompilerType::IsArrayType(CompilerType *element_type_ptr, uint64_t *size,
53 bool *is_incomplete) const {
54 if (IsValid())
55 if (auto type_system_sp = GetTypeSystem())
56 return type_system_sp->IsArrayType(m_type, element_type_ptr, size,
57 is_incomplete);
58
59 if (element_type_ptr)
60 element_type_ptr->Clear();
61 if (size)
62 *size = 0;
63 if (is_incomplete)
64 *is_incomplete = false;
65 return false;
66 }
67
IsVectorType(CompilerType * element_type,uint64_t * size) const68 bool CompilerType::IsVectorType(CompilerType *element_type,
69 uint64_t *size) const {
70 if (IsValid())
71 if (auto type_system_sp = GetTypeSystem())
72 return type_system_sp->IsVectorType(m_type, element_type, size);
73 return false;
74 }
75
IsRuntimeGeneratedType() const76 bool CompilerType::IsRuntimeGeneratedType() const {
77 if (IsValid())
78 if (auto type_system_sp = GetTypeSystem())
79 return type_system_sp->IsRuntimeGeneratedType(m_type);
80 return false;
81 }
82
IsCharType() const83 bool CompilerType::IsCharType() const {
84 if (IsValid())
85 if (auto type_system_sp = GetTypeSystem())
86 return type_system_sp->IsCharType(m_type);
87 return false;
88 }
89
IsCompleteType() const90 bool CompilerType::IsCompleteType() const {
91 if (IsValid())
92 if (auto type_system_sp = GetTypeSystem())
93 return type_system_sp->IsCompleteType(m_type);
94 return false;
95 }
96
IsForcefullyCompleted() const97 bool CompilerType::IsForcefullyCompleted() const {
98 if (IsValid())
99 if (auto type_system_sp = GetTypeSystem())
100 return type_system_sp->IsForcefullyCompleted(m_type);
101 return false;
102 }
103
IsConst() const104 bool CompilerType::IsConst() const {
105 if (IsValid())
106 if (auto type_system_sp = GetTypeSystem())
107 return type_system_sp->IsConst(m_type);
108 return false;
109 }
110
GetPtrAuthKey() const111 unsigned CompilerType::GetPtrAuthKey() const {
112 if (IsValid())
113 if (auto type_system_sp = GetTypeSystem())
114 return type_system_sp->GetPtrAuthKey(m_type);
115 return 0;
116 }
117
GetPtrAuthDiscriminator() const118 unsigned CompilerType::GetPtrAuthDiscriminator() const {
119 if (IsValid())
120 if (auto type_system_sp = GetTypeSystem())
121 return type_system_sp->GetPtrAuthDiscriminator(m_type);
122 return 0;
123 }
124
GetPtrAuthAddressDiversity() const125 bool CompilerType::GetPtrAuthAddressDiversity() const {
126 if (IsValid())
127 if (auto type_system_sp = GetTypeSystem())
128 return type_system_sp->GetPtrAuthAddressDiversity(m_type);
129 return false;
130 }
131
IsFunctionType() const132 bool CompilerType::IsFunctionType() const {
133 if (IsValid())
134 if (auto type_system_sp = GetTypeSystem())
135 return type_system_sp->IsFunctionType(m_type);
136 return false;
137 }
138
139 // Used to detect "Homogeneous Floating-point Aggregates"
140 uint32_t
IsHomogeneousAggregate(CompilerType * base_type_ptr) const141 CompilerType::IsHomogeneousAggregate(CompilerType *base_type_ptr) const {
142 if (IsValid())
143 if (auto type_system_sp = GetTypeSystem())
144 return type_system_sp->IsHomogeneousAggregate(m_type, base_type_ptr);
145 return 0;
146 }
147
GetNumberOfFunctionArguments() const148 size_t CompilerType::GetNumberOfFunctionArguments() const {
149 if (IsValid())
150 if (auto type_system_sp = GetTypeSystem())
151 return type_system_sp->GetNumberOfFunctionArguments(m_type);
152 return 0;
153 }
154
155 CompilerType
GetFunctionArgumentAtIndex(const size_t index) const156 CompilerType::GetFunctionArgumentAtIndex(const size_t index) const {
157 if (IsValid())
158 if (auto type_system_sp = GetTypeSystem())
159 return type_system_sp->GetFunctionArgumentAtIndex(m_type, index);
160 return CompilerType();
161 }
162
IsFunctionPointerType() const163 bool CompilerType::IsFunctionPointerType() const {
164 if (IsValid())
165 if (auto type_system_sp = GetTypeSystem())
166 return type_system_sp->IsFunctionPointerType(m_type);
167 return false;
168 }
169
IsMemberFunctionPointerType() const170 bool CompilerType::IsMemberFunctionPointerType() const {
171 if (IsValid())
172 if (auto type_system_sp = GetTypeSystem())
173 return type_system_sp->IsMemberFunctionPointerType(m_type);
174 return false;
175 }
176
IsBlockPointerType(CompilerType * function_pointer_type_ptr) const177 bool CompilerType::IsBlockPointerType(
178 CompilerType *function_pointer_type_ptr) const {
179 if (IsValid())
180 if (auto type_system_sp = GetTypeSystem())
181 return type_system_sp->IsBlockPointerType(m_type, function_pointer_type_ptr);
182 return false;
183 }
184
IsIntegerType(bool & is_signed) const185 bool CompilerType::IsIntegerType(bool &is_signed) const {
186 if (IsValid())
187 if (auto type_system_sp = GetTypeSystem())
188 return type_system_sp->IsIntegerType(m_type, is_signed);
189 return false;
190 }
191
IsEnumerationType(bool & is_signed) const192 bool CompilerType::IsEnumerationType(bool &is_signed) const {
193 if (IsValid())
194 if (auto type_system_sp = GetTypeSystem())
195 return type_system_sp->IsEnumerationType(m_type, is_signed);
196 return false;
197 }
198
IsIntegerOrEnumerationType(bool & is_signed) const199 bool CompilerType::IsIntegerOrEnumerationType(bool &is_signed) const {
200 return IsIntegerType(is_signed) || IsEnumerationType(is_signed);
201 }
202
IsPointerType(CompilerType * pointee_type) const203 bool CompilerType::IsPointerType(CompilerType *pointee_type) const {
204 if (IsValid()) {
205 if (auto type_system_sp = GetTypeSystem())
206 return type_system_sp->IsPointerType(m_type, pointee_type);
207 }
208 if (pointee_type)
209 pointee_type->Clear();
210 return false;
211 }
212
IsPointerOrReferenceType(CompilerType * pointee_type) const213 bool CompilerType::IsPointerOrReferenceType(CompilerType *pointee_type) const {
214 if (IsValid()) {
215 if (auto type_system_sp = GetTypeSystem())
216 return type_system_sp->IsPointerOrReferenceType(m_type, pointee_type);
217 }
218 if (pointee_type)
219 pointee_type->Clear();
220 return false;
221 }
222
IsReferenceType(CompilerType * pointee_type,bool * is_rvalue) const223 bool CompilerType::IsReferenceType(CompilerType *pointee_type,
224 bool *is_rvalue) const {
225 if (IsValid()) {
226 if (auto type_system_sp = GetTypeSystem())
227 return type_system_sp->IsReferenceType(m_type, pointee_type, is_rvalue);
228 }
229 if (pointee_type)
230 pointee_type->Clear();
231 return false;
232 }
233
ShouldTreatScalarValueAsAddress() const234 bool CompilerType::ShouldTreatScalarValueAsAddress() const {
235 if (IsValid())
236 if (auto type_system_sp = GetTypeSystem())
237 return type_system_sp->ShouldTreatScalarValueAsAddress(m_type);
238 return false;
239 }
240
IsFloatingPointType(uint32_t & count,bool & is_complex) const241 bool CompilerType::IsFloatingPointType(uint32_t &count,
242 bool &is_complex) const {
243 if (IsValid()) {
244 if (auto type_system_sp = GetTypeSystem())
245 return type_system_sp->IsFloatingPointType(m_type, count, is_complex);
246 }
247 count = 0;
248 is_complex = false;
249 return false;
250 }
251
IsDefined() const252 bool CompilerType::IsDefined() const {
253 if (IsValid())
254 if (auto type_system_sp = GetTypeSystem())
255 return type_system_sp->IsDefined(m_type);
256 return true;
257 }
258
IsPolymorphicClass() const259 bool CompilerType::IsPolymorphicClass() const {
260 if (IsValid()) {
261 if (auto type_system_sp = GetTypeSystem())
262 return type_system_sp->IsPolymorphicClass(m_type);
263 }
264 return false;
265 }
266
IsPossibleDynamicType(CompilerType * dynamic_pointee_type,bool check_cplusplus,bool check_objc) const267 bool CompilerType::IsPossibleDynamicType(CompilerType *dynamic_pointee_type,
268 bool check_cplusplus,
269 bool check_objc) const {
270 if (IsValid())
271 if (auto type_system_sp = GetTypeSystem())
272 return type_system_sp->IsPossibleDynamicType(m_type, dynamic_pointee_type,
273 check_cplusplus, check_objc);
274 return false;
275 }
276
IsScalarType() const277 bool CompilerType::IsScalarType() const {
278 if (IsValid())
279 if (auto type_system_sp = GetTypeSystem())
280 return type_system_sp->IsScalarType(m_type);
281 return false;
282 }
283
IsTemplateType() const284 bool CompilerType::IsTemplateType() const {
285 if (IsValid())
286 if (auto type_system_sp = GetTypeSystem())
287 return type_system_sp->IsTemplateType(m_type);
288 return false;
289 }
290
IsTypedefType() const291 bool CompilerType::IsTypedefType() const {
292 if (IsValid())
293 if (auto type_system_sp = GetTypeSystem())
294 return type_system_sp->IsTypedefType(m_type);
295 return false;
296 }
297
IsVoidType() const298 bool CompilerType::IsVoidType() const {
299 if (IsValid())
300 if (auto type_system_sp = GetTypeSystem())
301 return type_system_sp->IsVoidType(m_type);
302 return false;
303 }
304
IsPointerToScalarType() const305 bool CompilerType::IsPointerToScalarType() const {
306 if (!IsValid())
307 return false;
308
309 return IsPointerType() && GetPointeeType().IsScalarType();
310 }
311
IsArrayOfScalarType() const312 bool CompilerType::IsArrayOfScalarType() const {
313 CompilerType element_type;
314 if (IsArrayType(&element_type))
315 return element_type.IsScalarType();
316 return false;
317 }
318
IsBeingDefined() const319 bool CompilerType::IsBeingDefined() const {
320 if (IsValid())
321 if (auto type_system_sp = GetTypeSystem())
322 return type_system_sp->IsBeingDefined(m_type);
323 return false;
324 }
325
IsInteger() const326 bool CompilerType::IsInteger() const {
327 bool is_signed = false; // May be reset by the call below.
328 return IsIntegerType(is_signed);
329 }
330
IsFloat() const331 bool CompilerType::IsFloat() const {
332 uint32_t count = 0;
333 bool is_complex = false;
334 return IsFloatingPointType(count, is_complex);
335 }
336
IsEnumerationType() const337 bool CompilerType::IsEnumerationType() const {
338 bool is_signed = false; // May be reset by the call below.
339 return IsEnumerationType(is_signed);
340 }
341
IsUnscopedEnumerationType() const342 bool CompilerType::IsUnscopedEnumerationType() const {
343 return IsEnumerationType() && !IsScopedEnumerationType();
344 }
345
IsIntegerOrUnscopedEnumerationType() const346 bool CompilerType::IsIntegerOrUnscopedEnumerationType() const {
347 return IsInteger() || IsUnscopedEnumerationType();
348 }
349
IsSigned() const350 bool CompilerType::IsSigned() const {
351 return GetTypeInfo() & lldb::eTypeIsSigned;
352 }
353
IsNullPtrType() const354 bool CompilerType::IsNullPtrType() const {
355 return GetCanonicalType().GetBasicTypeEnumeration() ==
356 lldb::eBasicTypeNullPtr;
357 }
358
IsBoolean() const359 bool CompilerType::IsBoolean() const {
360 return GetCanonicalType().GetBasicTypeEnumeration() == lldb::eBasicTypeBool;
361 }
362
IsEnumerationIntegerTypeSigned() const363 bool CompilerType::IsEnumerationIntegerTypeSigned() const {
364 if (IsValid())
365 return GetEnumerationIntegerType().GetTypeInfo() & lldb::eTypeIsSigned;
366
367 return false;
368 }
369
IsScalarOrUnscopedEnumerationType() const370 bool CompilerType::IsScalarOrUnscopedEnumerationType() const {
371 return IsScalarType() || IsUnscopedEnumerationType();
372 }
373
IsPromotableIntegerType() const374 bool CompilerType::IsPromotableIntegerType() const {
375 // Unscoped enums are always considered as promotable, even if their
376 // underlying type does not need to be promoted (e.g. "int").
377 if (IsUnscopedEnumerationType())
378 return true;
379
380 switch (GetCanonicalType().GetBasicTypeEnumeration()) {
381 case lldb::eBasicTypeBool:
382 case lldb::eBasicTypeChar:
383 case lldb::eBasicTypeSignedChar:
384 case lldb::eBasicTypeUnsignedChar:
385 case lldb::eBasicTypeShort:
386 case lldb::eBasicTypeUnsignedShort:
387 case lldb::eBasicTypeWChar:
388 case lldb::eBasicTypeSignedWChar:
389 case lldb::eBasicTypeUnsignedWChar:
390 case lldb::eBasicTypeChar16:
391 case lldb::eBasicTypeChar32:
392 return true;
393
394 default:
395 return false;
396 }
397
398 llvm_unreachable("All cases handled above.");
399 }
400
IsPointerToVoid() const401 bool CompilerType::IsPointerToVoid() const {
402 if (!IsValid())
403 return false;
404
405 return IsPointerType() &&
406 GetPointeeType().GetBasicTypeEnumeration() == lldb::eBasicTypeVoid;
407 }
408
IsRecordType() const409 bool CompilerType::IsRecordType() const {
410 if (!IsValid())
411 return false;
412
413 return GetCanonicalType().GetTypeClass() &
414 (lldb::eTypeClassClass | lldb::eTypeClassStruct |
415 lldb::eTypeClassUnion);
416 }
417
IsVirtualBase(CompilerType target_base,CompilerType * virtual_base,bool carry_virtual) const418 bool CompilerType::IsVirtualBase(CompilerType target_base,
419 CompilerType *virtual_base,
420 bool carry_virtual) const {
421 if (CompareTypes(target_base))
422 return carry_virtual;
423
424 if (!carry_virtual) {
425 uint32_t num_virtual_bases = GetNumVirtualBaseClasses();
426 for (uint32_t i = 0; i < num_virtual_bases; ++i) {
427 uint32_t bit_offset;
428 auto base = GetVirtualBaseClassAtIndex(i, &bit_offset);
429 if (base.IsVirtualBase(target_base, virtual_base,
430 /*carry_virtual*/ true)) {
431 if (virtual_base)
432 *virtual_base = base;
433
434 return true;
435 }
436 }
437 }
438
439 uint32_t num_direct_bases = GetNumDirectBaseClasses();
440 for (uint32_t i = 0; i < num_direct_bases; ++i) {
441 uint32_t bit_offset;
442 auto base = GetDirectBaseClassAtIndex(i, &bit_offset);
443 if (base.IsVirtualBase(target_base, virtual_base, carry_virtual))
444 return true;
445 }
446
447 return false;
448 }
449
IsContextuallyConvertibleToBool() const450 bool CompilerType::IsContextuallyConvertibleToBool() const {
451 return IsScalarType() || IsUnscopedEnumerationType() || IsPointerType() ||
452 IsNullPtrType() || IsArrayType();
453 }
454
IsBasicType() const455 bool CompilerType::IsBasicType() const {
456 return GetCanonicalType().GetBasicTypeEnumeration() !=
457 lldb::eBasicTypeInvalid;
458 }
459
TypeDescription()460 std::string CompilerType::TypeDescription() {
461 auto name = GetTypeName();
462 auto canonical_name = GetCanonicalType().GetTypeName();
463 if (name.IsEmpty() || canonical_name.IsEmpty())
464 return "''"; // Should not happen, unless the input is broken somehow.
465
466 if (name == canonical_name)
467 return llvm::formatv("'{0}'", name);
468
469 return llvm::formatv("'{0}' (canonically referred to as '{1}')", name,
470 canonical_name);
471 }
472
CompareTypes(CompilerType rhs) const473 bool CompilerType::CompareTypes(CompilerType rhs) const {
474 if (*this == rhs)
475 return true;
476
477 const ConstString name = GetFullyUnqualifiedType().GetTypeName();
478 const ConstString rhs_name = rhs.GetFullyUnqualifiedType().GetTypeName();
479 return name == rhs_name;
480 }
481
GetTypeTag()482 const char *CompilerType::GetTypeTag() {
483 switch (GetTypeClass()) {
484 case lldb::eTypeClassClass:
485 return "class";
486 case lldb::eTypeClassEnumeration:
487 return "enum";
488 case lldb::eTypeClassStruct:
489 return "struct";
490 case lldb::eTypeClassUnion:
491 return "union";
492 default:
493 return "unknown";
494 }
495 llvm_unreachable("All cases are covered by code above.");
496 }
497
GetNumberOfNonEmptyBaseClasses()498 uint32_t CompilerType::GetNumberOfNonEmptyBaseClasses() {
499 uint32_t ret = 0;
500 uint32_t num_direct_bases = GetNumDirectBaseClasses();
501
502 for (uint32_t i = 0; i < num_direct_bases; ++i) {
503 uint32_t bit_offset;
504 CompilerType base_type = GetDirectBaseClassAtIndex(i, &bit_offset);
505 if (base_type.GetNumFields() > 0 ||
506 base_type.GetNumberOfNonEmptyBaseClasses() > 0)
507 ret += 1;
508 }
509 return ret;
510 }
511
512 // Type Completion
513
GetCompleteType() const514 bool CompilerType::GetCompleteType() const {
515 if (IsValid())
516 if (auto type_system_sp = GetTypeSystem())
517 return type_system_sp->GetCompleteType(m_type);
518 return false;
519 }
520
521 // AST related queries
GetPointerByteSize() const522 size_t CompilerType::GetPointerByteSize() const {
523 if (auto type_system_sp = GetTypeSystem())
524 return type_system_sp->GetPointerByteSize();
525 return 0;
526 }
527
GetTypeName(bool BaseOnly) const528 ConstString CompilerType::GetTypeName(bool BaseOnly) const {
529 if (IsValid()) {
530 if (auto type_system_sp = GetTypeSystem())
531 return type_system_sp->GetTypeName(m_type, BaseOnly);
532 }
533 return ConstString("<invalid>");
534 }
535
GetDisplayTypeName() const536 ConstString CompilerType::GetDisplayTypeName() const {
537 if (IsValid())
538 if (auto type_system_sp = GetTypeSystem())
539 return type_system_sp->GetDisplayTypeName(m_type);
540 return ConstString("<invalid>");
541 }
542
GetTypeInfo(CompilerType * pointee_or_element_compiler_type) const543 uint32_t CompilerType::GetTypeInfo(
544 CompilerType *pointee_or_element_compiler_type) const {
545 if (IsValid())
546 if (auto type_system_sp = GetTypeSystem())
547 return type_system_sp->GetTypeInfo(m_type,
548 pointee_or_element_compiler_type);
549 return 0;
550 }
551
GetMinimumLanguage()552 lldb::LanguageType CompilerType::GetMinimumLanguage() {
553 if (IsValid())
554 if (auto type_system_sp = GetTypeSystem())
555 return type_system_sp->GetMinimumLanguage(m_type);
556 return lldb::eLanguageTypeC;
557 }
558
GetTypeClass() const559 lldb::TypeClass CompilerType::GetTypeClass() const {
560 if (IsValid())
561 if (auto type_system_sp = GetTypeSystem())
562 return type_system_sp->GetTypeClass(m_type);
563 return lldb::eTypeClassInvalid;
564 }
565
SetCompilerType(lldb::TypeSystemWP type_system,lldb::opaque_compiler_type_t type)566 void CompilerType::SetCompilerType(lldb::TypeSystemWP type_system,
567 lldb::opaque_compiler_type_t type) {
568 m_type_system = type_system;
569 m_type = type;
570 }
571
SetCompilerType(CompilerType::TypeSystemSPWrapper type_system,lldb::opaque_compiler_type_t type)572 void CompilerType::SetCompilerType(CompilerType::TypeSystemSPWrapper type_system,
573 lldb::opaque_compiler_type_t type) {
574 m_type_system = type_system.GetSharedPointer();
575 m_type = type;
576 }
577
GetTypeQualifiers() const578 unsigned CompilerType::GetTypeQualifiers() const {
579 if (IsValid())
580 if (auto type_system_sp = GetTypeSystem())
581 return type_system_sp->GetTypeQualifiers(m_type);
582 return 0;
583 }
584
585 // Creating related types
586
587 CompilerType
GetArrayElementType(ExecutionContextScope * exe_scope) const588 CompilerType::GetArrayElementType(ExecutionContextScope *exe_scope) const {
589 if (IsValid()) {
590 if (auto type_system_sp = GetTypeSystem())
591 return type_system_sp->GetArrayElementType(m_type, exe_scope);
592 }
593 return CompilerType();
594 }
595
GetArrayType(uint64_t size) const596 CompilerType CompilerType::GetArrayType(uint64_t size) const {
597 if (IsValid()) {
598 if (auto type_system_sp = GetTypeSystem())
599 return type_system_sp->GetArrayType(m_type, size);
600 }
601 return CompilerType();
602 }
603
GetCanonicalType() const604 CompilerType CompilerType::GetCanonicalType() const {
605 if (IsValid())
606 if (auto type_system_sp = GetTypeSystem())
607 return type_system_sp->GetCanonicalType(m_type);
608 return CompilerType();
609 }
610
GetFullyUnqualifiedType() const611 CompilerType CompilerType::GetFullyUnqualifiedType() const {
612 if (IsValid())
613 if (auto type_system_sp = GetTypeSystem())
614 return type_system_sp->GetFullyUnqualifiedType(m_type);
615 return CompilerType();
616 }
617
GetEnumerationIntegerType() const618 CompilerType CompilerType::GetEnumerationIntegerType() const {
619 if (IsValid())
620 if (auto type_system_sp = GetTypeSystem())
621 return type_system_sp->GetEnumerationIntegerType(m_type);
622 return CompilerType();
623 }
624
GetFunctionArgumentCount() const625 int CompilerType::GetFunctionArgumentCount() const {
626 if (IsValid()) {
627 if (auto type_system_sp = GetTypeSystem())
628 return type_system_sp->GetFunctionArgumentCount(m_type);
629 }
630 return -1;
631 }
632
GetFunctionArgumentTypeAtIndex(size_t idx) const633 CompilerType CompilerType::GetFunctionArgumentTypeAtIndex(size_t idx) const {
634 if (IsValid()) {
635 if (auto type_system_sp = GetTypeSystem())
636 return type_system_sp->GetFunctionArgumentTypeAtIndex(m_type, idx);
637 }
638 return CompilerType();
639 }
640
GetFunctionReturnType() const641 CompilerType CompilerType::GetFunctionReturnType() const {
642 if (IsValid()) {
643 if (auto type_system_sp = GetTypeSystem())
644 return type_system_sp->GetFunctionReturnType(m_type);
645 }
646 return CompilerType();
647 }
648
GetNumMemberFunctions() const649 size_t CompilerType::GetNumMemberFunctions() const {
650 if (IsValid()) {
651 if (auto type_system_sp = GetTypeSystem())
652 return type_system_sp->GetNumMemberFunctions(m_type);
653 }
654 return 0;
655 }
656
GetMemberFunctionAtIndex(size_t idx)657 TypeMemberFunctionImpl CompilerType::GetMemberFunctionAtIndex(size_t idx) {
658 if (IsValid()) {
659 if (auto type_system_sp = GetTypeSystem())
660 return type_system_sp->GetMemberFunctionAtIndex(m_type, idx);
661 }
662 return TypeMemberFunctionImpl();
663 }
664
GetNonReferenceType() const665 CompilerType CompilerType::GetNonReferenceType() const {
666 if (IsValid())
667 if (auto type_system_sp = GetTypeSystem())
668 return type_system_sp->GetNonReferenceType(m_type);
669 return CompilerType();
670 }
671
GetPointeeType() const672 CompilerType CompilerType::GetPointeeType() const {
673 if (IsValid()) {
674 if (auto type_system_sp = GetTypeSystem())
675 return type_system_sp->GetPointeeType(m_type);
676 }
677 return CompilerType();
678 }
679
GetPointerType() const680 CompilerType CompilerType::GetPointerType() const {
681 if (IsValid()) {
682 if (auto type_system_sp = GetTypeSystem())
683 return type_system_sp->GetPointerType(m_type);
684 }
685 return CompilerType();
686 }
687
AddPtrAuthModifier(uint32_t payload) const688 CompilerType CompilerType::AddPtrAuthModifier(uint32_t payload) const {
689 if (IsValid())
690 if (auto type_system_sp = GetTypeSystem())
691 return type_system_sp->AddPtrAuthModifier(m_type, payload);
692 return CompilerType();
693 }
694
GetLValueReferenceType() const695 CompilerType CompilerType::GetLValueReferenceType() const {
696 if (IsValid())
697 if (auto type_system_sp = GetTypeSystem())
698 return type_system_sp->GetLValueReferenceType(m_type);
699 return CompilerType();
700 }
701
GetRValueReferenceType() const702 CompilerType CompilerType::GetRValueReferenceType() const {
703 if (IsValid())
704 if (auto type_system_sp = GetTypeSystem())
705 return type_system_sp->GetRValueReferenceType(m_type);
706 return CompilerType();
707 }
708
GetAtomicType() const709 CompilerType CompilerType::GetAtomicType() const {
710 if (IsValid())
711 if (auto type_system_sp = GetTypeSystem())
712 return type_system_sp->GetAtomicType(m_type);
713 return CompilerType();
714 }
715
AddConstModifier() const716 CompilerType CompilerType::AddConstModifier() const {
717 if (IsValid())
718 if (auto type_system_sp = GetTypeSystem())
719 return type_system_sp->AddConstModifier(m_type);
720 return CompilerType();
721 }
722
AddVolatileModifier() const723 CompilerType CompilerType::AddVolatileModifier() const {
724 if (IsValid())
725 if (auto type_system_sp = GetTypeSystem())
726 return type_system_sp->AddVolatileModifier(m_type);
727 return CompilerType();
728 }
729
AddRestrictModifier() const730 CompilerType CompilerType::AddRestrictModifier() const {
731 if (IsValid())
732 if (auto type_system_sp = GetTypeSystem())
733 return type_system_sp->AddRestrictModifier(m_type);
734 return CompilerType();
735 }
736
CreateTypedef(const char * name,const CompilerDeclContext & decl_ctx,uint32_t payload) const737 CompilerType CompilerType::CreateTypedef(const char *name,
738 const CompilerDeclContext &decl_ctx,
739 uint32_t payload) const {
740 if (IsValid())
741 if (auto type_system_sp = GetTypeSystem())
742 return type_system_sp->CreateTypedef(m_type, name, decl_ctx, payload);
743 return CompilerType();
744 }
745
GetTypedefedType() const746 CompilerType CompilerType::GetTypedefedType() const {
747 if (IsValid())
748 if (auto type_system_sp = GetTypeSystem())
749 return type_system_sp->GetTypedefedType(m_type);
750 return CompilerType();
751 }
752
753 // Create related types using the current type's AST
754
755 CompilerType
GetBasicTypeFromAST(lldb::BasicType basic_type) const756 CompilerType::GetBasicTypeFromAST(lldb::BasicType basic_type) const {
757 if (IsValid())
758 if (auto type_system_sp = GetTypeSystem())
759 return type_system_sp->GetBasicTypeFromAST(basic_type);
760 return CompilerType();
761 }
762 // Exploring the type
763
764 std::optional<uint64_t>
GetBitSize(ExecutionContextScope * exe_scope) const765 CompilerType::GetBitSize(ExecutionContextScope *exe_scope) const {
766 if (IsValid())
767 if (auto type_system_sp = GetTypeSystem())
768 return type_system_sp->GetBitSize(m_type, exe_scope);
769 return {};
770 }
771
772 std::optional<uint64_t>
GetByteSize(ExecutionContextScope * exe_scope) const773 CompilerType::GetByteSize(ExecutionContextScope *exe_scope) const {
774 if (std::optional<uint64_t> bit_size = GetBitSize(exe_scope))
775 return (*bit_size + 7) / 8;
776 return {};
777 }
778
779 std::optional<size_t>
GetTypeBitAlign(ExecutionContextScope * exe_scope) const780 CompilerType::GetTypeBitAlign(ExecutionContextScope *exe_scope) const {
781 if (IsValid())
782 if (auto type_system_sp = GetTypeSystem())
783 return type_system_sp->GetTypeBitAlign(m_type, exe_scope);
784 return {};
785 }
786
GetEncoding(uint64_t & count) const787 lldb::Encoding CompilerType::GetEncoding(uint64_t &count) const {
788 if (IsValid())
789 if (auto type_system_sp = GetTypeSystem())
790 return type_system_sp->GetEncoding(m_type, count);
791 return lldb::eEncodingInvalid;
792 }
793
GetFormat() const794 lldb::Format CompilerType::GetFormat() const {
795 if (IsValid())
796 if (auto type_system_sp = GetTypeSystem())
797 return type_system_sp->GetFormat(m_type);
798 return lldb::eFormatDefault;
799 }
800
801 llvm::Expected<uint32_t>
GetNumChildren(bool omit_empty_base_classes,const ExecutionContext * exe_ctx) const802 CompilerType::GetNumChildren(bool omit_empty_base_classes,
803 const ExecutionContext *exe_ctx) const {
804 if (IsValid())
805 if (auto type_system_sp = GetTypeSystem())
806 return type_system_sp->GetNumChildren(m_type, omit_empty_base_classes,
807 exe_ctx);
808 return llvm::createStringError("invalid type");
809 }
810
GetBasicTypeEnumeration() const811 lldb::BasicType CompilerType::GetBasicTypeEnumeration() const {
812 if (IsValid())
813 if (auto type_system_sp = GetTypeSystem())
814 return type_system_sp->GetBasicTypeEnumeration(m_type);
815 return eBasicTypeInvalid;
816 }
817
ForEachEnumerator(std::function<bool (const CompilerType & integer_type,ConstString name,const llvm::APSInt & value)> const & callback) const818 void CompilerType::ForEachEnumerator(
819 std::function<bool(const CompilerType &integer_type,
820 ConstString name,
821 const llvm::APSInt &value)> const &callback) const {
822 if (IsValid())
823 if (auto type_system_sp = GetTypeSystem())
824 return type_system_sp->ForEachEnumerator(m_type, callback);
825 }
826
GetNumFields() const827 uint32_t CompilerType::GetNumFields() const {
828 if (IsValid())
829 if (auto type_system_sp = GetTypeSystem())
830 return type_system_sp->GetNumFields(m_type);
831 return 0;
832 }
833
GetFieldAtIndex(size_t idx,std::string & name,uint64_t * bit_offset_ptr,uint32_t * bitfield_bit_size_ptr,bool * is_bitfield_ptr) const834 CompilerType CompilerType::GetFieldAtIndex(size_t idx, std::string &name,
835 uint64_t *bit_offset_ptr,
836 uint32_t *bitfield_bit_size_ptr,
837 bool *is_bitfield_ptr) const {
838 if (IsValid())
839 if (auto type_system_sp = GetTypeSystem())
840 return type_system_sp->GetFieldAtIndex(m_type, idx, name, bit_offset_ptr,
841 bitfield_bit_size_ptr, is_bitfield_ptr);
842 return CompilerType();
843 }
844
GetNumDirectBaseClasses() const845 uint32_t CompilerType::GetNumDirectBaseClasses() const {
846 if (IsValid())
847 if (auto type_system_sp = GetTypeSystem())
848 return type_system_sp->GetNumDirectBaseClasses(m_type);
849 return 0;
850 }
851
GetNumVirtualBaseClasses() const852 uint32_t CompilerType::GetNumVirtualBaseClasses() const {
853 if (IsValid())
854 if (auto type_system_sp = GetTypeSystem())
855 return type_system_sp->GetNumVirtualBaseClasses(m_type);
856 return 0;
857 }
858
859 CompilerType
GetDirectBaseClassAtIndex(size_t idx,uint32_t * bit_offset_ptr) const860 CompilerType::GetDirectBaseClassAtIndex(size_t idx,
861 uint32_t *bit_offset_ptr) const {
862 if (IsValid())
863 if (auto type_system_sp = GetTypeSystem())
864 return type_system_sp->GetDirectBaseClassAtIndex(m_type, idx,
865 bit_offset_ptr);
866 return CompilerType();
867 }
868
869 CompilerType
GetVirtualBaseClassAtIndex(size_t idx,uint32_t * bit_offset_ptr) const870 CompilerType::GetVirtualBaseClassAtIndex(size_t idx,
871 uint32_t *bit_offset_ptr) const {
872 if (IsValid())
873 if (auto type_system_sp = GetTypeSystem())
874 return type_system_sp->GetVirtualBaseClassAtIndex(m_type, idx,
875 bit_offset_ptr);
876 return CompilerType();
877 }
878
GetStaticFieldWithName(llvm::StringRef name) const879 CompilerDecl CompilerType::GetStaticFieldWithName(llvm::StringRef name) const {
880 if (IsValid())
881 return GetTypeSystem()->GetStaticFieldWithName(m_type, name);
882 return CompilerDecl();
883 }
884
GetIndexOfFieldWithName(const char * name,CompilerType * field_compiler_type_ptr,uint64_t * bit_offset_ptr,uint32_t * bitfield_bit_size_ptr,bool * is_bitfield_ptr) const885 uint32_t CompilerType::GetIndexOfFieldWithName(
886 const char *name, CompilerType *field_compiler_type_ptr,
887 uint64_t *bit_offset_ptr, uint32_t *bitfield_bit_size_ptr,
888 bool *is_bitfield_ptr) const {
889 unsigned count = GetNumFields();
890 std::string field_name;
891 for (unsigned index = 0; index < count; index++) {
892 CompilerType field_compiler_type(
893 GetFieldAtIndex(index, field_name, bit_offset_ptr,
894 bitfield_bit_size_ptr, is_bitfield_ptr));
895 if (strcmp(field_name.c_str(), name) == 0) {
896 if (field_compiler_type_ptr)
897 *field_compiler_type_ptr = field_compiler_type;
898 return index;
899 }
900 }
901 return UINT32_MAX;
902 }
903
GetChildCompilerTypeAtIndex(ExecutionContext * exe_ctx,size_t idx,bool transparent_pointers,bool omit_empty_base_classes,bool ignore_array_bounds,std::string & child_name,uint32_t & child_byte_size,int32_t & child_byte_offset,uint32_t & child_bitfield_bit_size,uint32_t & child_bitfield_bit_offset,bool & child_is_base_class,bool & child_is_deref_of_parent,ValueObject * valobj,uint64_t & language_flags) const904 llvm::Expected<CompilerType> CompilerType::GetChildCompilerTypeAtIndex(
905 ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers,
906 bool omit_empty_base_classes, bool ignore_array_bounds,
907 std::string &child_name, uint32_t &child_byte_size,
908 int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size,
909 uint32_t &child_bitfield_bit_offset, bool &child_is_base_class,
910 bool &child_is_deref_of_parent, ValueObject *valobj,
911 uint64_t &language_flags) const {
912 if (IsValid())
913 if (auto type_system_sp = GetTypeSystem())
914 return type_system_sp->GetChildCompilerTypeAtIndex(
915 m_type, exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
916 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
917 child_bitfield_bit_size, child_bitfield_bit_offset,
918 child_is_base_class, child_is_deref_of_parent, valobj,
919 language_flags);
920 return CompilerType();
921 }
922
923 // Look for a child member (doesn't include base classes, but it does include
924 // their members) in the type hierarchy. Returns an index path into
925 // "clang_type" on how to reach the appropriate member.
926 //
927 // class A
928 // {
929 // public:
930 // int m_a;
931 // int m_b;
932 // };
933 //
934 // class B
935 // {
936 // };
937 //
938 // class C :
939 // public B,
940 // public A
941 // {
942 // };
943 //
944 // If we have a clang type that describes "class C", and we wanted to looked
945 // "m_b" in it:
946 //
947 // With omit_empty_base_classes == false we would get an integer array back
948 // with: { 1, 1 } The first index 1 is the child index for "class A" within
949 // class C The second index 1 is the child index for "m_b" within class A
950 //
951 // With omit_empty_base_classes == true we would get an integer array back
952 // with: { 0, 1 } The first index 0 is the child index for "class A" within
953 // class C (since class B doesn't have any members it doesn't count) The second
954 // index 1 is the child index for "m_b" within class A
955
GetIndexOfChildMemberWithName(llvm::StringRef name,bool omit_empty_base_classes,std::vector<uint32_t> & child_indexes) const956 size_t CompilerType::GetIndexOfChildMemberWithName(
957 llvm::StringRef name, bool omit_empty_base_classes,
958 std::vector<uint32_t> &child_indexes) const {
959 if (IsValid() && !name.empty()) {
960 if (auto type_system_sp = GetTypeSystem())
961 return type_system_sp->GetIndexOfChildMemberWithName(
962 m_type, name, omit_empty_base_classes, child_indexes);
963 }
964 return 0;
965 }
966
967 CompilerType
GetDirectNestedTypeWithName(llvm::StringRef name) const968 CompilerType::GetDirectNestedTypeWithName(llvm::StringRef name) const {
969 if (IsValid() && !name.empty()) {
970 if (auto type_system_sp = GetTypeSystem())
971 return type_system_sp->GetDirectNestedTypeWithName(m_type, name);
972 }
973 return CompilerType();
974 }
975
GetNumTemplateArguments(bool expand_pack) const976 size_t CompilerType::GetNumTemplateArguments(bool expand_pack) const {
977 if (IsValid()) {
978 if (auto type_system_sp = GetTypeSystem())
979 return type_system_sp->GetNumTemplateArguments(m_type, expand_pack);
980 }
981 return 0;
982 }
983
984 TemplateArgumentKind
GetTemplateArgumentKind(size_t idx,bool expand_pack) const985 CompilerType::GetTemplateArgumentKind(size_t idx, bool expand_pack) const {
986 if (IsValid())
987 if (auto type_system_sp = GetTypeSystem())
988 return type_system_sp->GetTemplateArgumentKind(m_type, idx, expand_pack);
989 return eTemplateArgumentKindNull;
990 }
991
GetTypeTemplateArgument(size_t idx,bool expand_pack) const992 CompilerType CompilerType::GetTypeTemplateArgument(size_t idx,
993 bool expand_pack) const {
994 if (IsValid()) {
995 if (auto type_system_sp = GetTypeSystem())
996 return type_system_sp->GetTypeTemplateArgument(m_type, idx, expand_pack);
997 }
998 return CompilerType();
999 }
1000
1001 std::optional<CompilerType::IntegralTemplateArgument>
GetIntegralTemplateArgument(size_t idx,bool expand_pack) const1002 CompilerType::GetIntegralTemplateArgument(size_t idx, bool expand_pack) const {
1003 if (IsValid())
1004 if (auto type_system_sp = GetTypeSystem())
1005 return type_system_sp->GetIntegralTemplateArgument(m_type, idx, expand_pack);
1006 return std::nullopt;
1007 }
1008
GetTypeForFormatters() const1009 CompilerType CompilerType::GetTypeForFormatters() const {
1010 if (IsValid())
1011 if (auto type_system_sp = GetTypeSystem())
1012 return type_system_sp->GetTypeForFormatters(m_type);
1013 return CompilerType();
1014 }
1015
ShouldPrintAsOneLiner(ValueObject * valobj) const1016 LazyBool CompilerType::ShouldPrintAsOneLiner(ValueObject *valobj) const {
1017 if (IsValid())
1018 if (auto type_system_sp = GetTypeSystem())
1019 return type_system_sp->ShouldPrintAsOneLiner(m_type, valobj);
1020 return eLazyBoolCalculate;
1021 }
1022
IsMeaninglessWithoutDynamicResolution() const1023 bool CompilerType::IsMeaninglessWithoutDynamicResolution() const {
1024 if (IsValid())
1025 if (auto type_system_sp = GetTypeSystem())
1026 return type_system_sp->IsMeaninglessWithoutDynamicResolution(m_type);
1027 return false;
1028 }
1029
1030 // Get the index of the child of "clang_type" whose name matches. This function
1031 // doesn't descend into the children, but only looks one level deep and name
1032 // matches can include base class names.
1033
1034 uint32_t
GetIndexOfChildWithName(llvm::StringRef name,bool omit_empty_base_classes) const1035 CompilerType::GetIndexOfChildWithName(llvm::StringRef name,
1036 bool omit_empty_base_classes) const {
1037 if (IsValid() && !name.empty()) {
1038 if (auto type_system_sp = GetTypeSystem())
1039 return type_system_sp->GetIndexOfChildWithName(m_type, name,
1040 omit_empty_base_classes);
1041 }
1042 return UINT32_MAX;
1043 }
1044
1045 // Dumping types
1046
DumpTypeValue(Stream * s,lldb::Format format,const DataExtractor & data,lldb::offset_t byte_offset,size_t byte_size,uint32_t bitfield_bit_size,uint32_t bitfield_bit_offset,ExecutionContextScope * exe_scope)1047 bool CompilerType::DumpTypeValue(Stream *s, lldb::Format format,
1048 const DataExtractor &data,
1049 lldb::offset_t byte_offset, size_t byte_size,
1050 uint32_t bitfield_bit_size,
1051 uint32_t bitfield_bit_offset,
1052 ExecutionContextScope *exe_scope) {
1053 if (IsValid())
1054 if (auto type_system_sp = GetTypeSystem())
1055 return type_system_sp->DumpTypeValue(
1056 m_type, *s, format, data, byte_offset, byte_size, bitfield_bit_size,
1057 bitfield_bit_offset, exe_scope);
1058 return false;
1059 }
1060
DumpTypeDescription(lldb::DescriptionLevel level) const1061 void CompilerType::DumpTypeDescription(lldb::DescriptionLevel level) const {
1062 if (IsValid())
1063 if (auto type_system_sp = GetTypeSystem())
1064 type_system_sp->DumpTypeDescription(m_type, level);
1065 }
1066
DumpTypeDescription(Stream * s,lldb::DescriptionLevel level) const1067 void CompilerType::DumpTypeDescription(Stream *s,
1068 lldb::DescriptionLevel level) const {
1069 if (IsValid())
1070 if (auto type_system_sp = GetTypeSystem())
1071 type_system_sp->DumpTypeDescription(m_type, *s, level);
1072 }
1073
1074 #ifndef NDEBUG
dump() const1075 LLVM_DUMP_METHOD void CompilerType::dump() const {
1076 if (IsValid())
1077 if (auto type_system_sp = GetTypeSystem())
1078 return type_system_sp->dump(m_type);
1079 llvm::errs() << "<invalid>\n";
1080 }
1081 #endif
1082
GetValueAsScalar(const lldb_private::DataExtractor & data,lldb::offset_t data_byte_offset,size_t data_byte_size,Scalar & value,ExecutionContextScope * exe_scope) const1083 bool CompilerType::GetValueAsScalar(const lldb_private::DataExtractor &data,
1084 lldb::offset_t data_byte_offset,
1085 size_t data_byte_size, Scalar &value,
1086 ExecutionContextScope *exe_scope) const {
1087 if (!IsValid())
1088 return false;
1089
1090 if (IsAggregateType()) {
1091 return false; // Aggregate types don't have scalar values
1092 } else {
1093 uint64_t count = 0;
1094 lldb::Encoding encoding = GetEncoding(count);
1095
1096 if (encoding == lldb::eEncodingInvalid || count != 1)
1097 return false;
1098
1099 std::optional<uint64_t> byte_size = GetByteSize(exe_scope);
1100 if (!byte_size)
1101 return false;
1102 lldb::offset_t offset = data_byte_offset;
1103 switch (encoding) {
1104 case lldb::eEncodingInvalid:
1105 break;
1106 case lldb::eEncodingVector:
1107 break;
1108 case lldb::eEncodingUint:
1109 if (*byte_size <= sizeof(unsigned long long)) {
1110 uint64_t uval64 = data.GetMaxU64(&offset, *byte_size);
1111 if (*byte_size <= sizeof(unsigned int)) {
1112 value = (unsigned int)uval64;
1113 return true;
1114 } else if (*byte_size <= sizeof(unsigned long)) {
1115 value = (unsigned long)uval64;
1116 return true;
1117 } else if (*byte_size <= sizeof(unsigned long long)) {
1118 value = (unsigned long long)uval64;
1119 return true;
1120 } else
1121 value.Clear();
1122 }
1123 break;
1124
1125 case lldb::eEncodingSint:
1126 if (*byte_size <= sizeof(long long)) {
1127 int64_t sval64 = data.GetMaxS64(&offset, *byte_size);
1128 if (*byte_size <= sizeof(int)) {
1129 value = (int)sval64;
1130 return true;
1131 } else if (*byte_size <= sizeof(long)) {
1132 value = (long)sval64;
1133 return true;
1134 } else if (*byte_size <= sizeof(long long)) {
1135 value = (long long)sval64;
1136 return true;
1137 } else
1138 value.Clear();
1139 }
1140 break;
1141
1142 case lldb::eEncodingIEEE754:
1143 if (*byte_size <= sizeof(long double)) {
1144 uint32_t u32;
1145 uint64_t u64;
1146 if (*byte_size == sizeof(float)) {
1147 if (sizeof(float) == sizeof(uint32_t)) {
1148 u32 = data.GetU32(&offset);
1149 value = *((float *)&u32);
1150 return true;
1151 } else if (sizeof(float) == sizeof(uint64_t)) {
1152 u64 = data.GetU64(&offset);
1153 value = *((float *)&u64);
1154 return true;
1155 }
1156 } else if (*byte_size == sizeof(double)) {
1157 if (sizeof(double) == sizeof(uint32_t)) {
1158 u32 = data.GetU32(&offset);
1159 value = *((double *)&u32);
1160 return true;
1161 } else if (sizeof(double) == sizeof(uint64_t)) {
1162 u64 = data.GetU64(&offset);
1163 value = *((double *)&u64);
1164 return true;
1165 }
1166 } else if (*byte_size == sizeof(long double)) {
1167 if (sizeof(long double) == sizeof(uint32_t)) {
1168 u32 = data.GetU32(&offset);
1169 value = *((long double *)&u32);
1170 return true;
1171 } else if (sizeof(long double) == sizeof(uint64_t)) {
1172 u64 = data.GetU64(&offset);
1173 value = *((long double *)&u64);
1174 return true;
1175 }
1176 }
1177 }
1178 break;
1179 }
1180 }
1181 return false;
1182 }
1183
CompilerType(CompilerType::TypeSystemSPWrapper type_system,lldb::opaque_compiler_type_t type)1184 CompilerType::CompilerType(CompilerType::TypeSystemSPWrapper type_system,
1185 lldb::opaque_compiler_type_t type)
1186 : m_type_system(type_system.GetSharedPointer()), m_type(type) {
1187 assert(Verify() && "verification failed");
1188 }
1189
CompilerType(lldb::TypeSystemWP type_system,lldb::opaque_compiler_type_t type)1190 CompilerType::CompilerType(lldb::TypeSystemWP type_system,
1191 lldb::opaque_compiler_type_t type)
1192 : m_type_system(type_system), m_type(type) {
1193 assert(Verify() && "verification failed");
1194 }
1195
1196 #ifndef NDEBUG
Verify() const1197 bool CompilerType::Verify() const {
1198 if (!IsValid())
1199 return true;
1200 if (auto type_system_sp = GetTypeSystem())
1201 return type_system_sp->Verify(m_type);
1202 return true;
1203 }
1204 #endif
1205
GetTypeSystem() const1206 CompilerType::TypeSystemSPWrapper CompilerType::GetTypeSystem() const {
1207 return {m_type_system.lock()};
1208 }
1209
operator ==(const CompilerType::TypeSystemSPWrapper & other) const1210 bool CompilerType::TypeSystemSPWrapper::operator==(
1211 const CompilerType::TypeSystemSPWrapper &other) const {
1212 if (!m_typesystem_sp && !other.m_typesystem_sp)
1213 return true;
1214 if (m_typesystem_sp && other.m_typesystem_sp)
1215 return m_typesystem_sp.get() == other.m_typesystem_sp.get();
1216 return false;
1217 }
1218
operator ->() const1219 TypeSystem *CompilerType::TypeSystemSPWrapper::operator->() const {
1220 assert(m_typesystem_sp);
1221 return m_typesystem_sp.get();
1222 }
1223
operator ==(const lldb_private::CompilerType & lhs,const lldb_private::CompilerType & rhs)1224 bool lldb_private::operator==(const lldb_private::CompilerType &lhs,
1225 const lldb_private::CompilerType &rhs) {
1226 return lhs.GetTypeSystem() == rhs.GetTypeSystem() &&
1227 lhs.GetOpaqueQualType() == rhs.GetOpaqueQualType();
1228 }
1229
operator !=(const lldb_private::CompilerType & lhs,const lldb_private::CompilerType & rhs)1230 bool lldb_private::operator!=(const lldb_private::CompilerType &lhs,
1231 const lldb_private::CompilerType &rhs) {
1232 return !(lhs == rhs);
1233 }
1234