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/Core/StreamFile.h"
13 #include "lldb/Symbol/Type.h"
14 #include "lldb/Target/ExecutionContext.h"
15 #include "lldb/Target/Process.h"
16 #include "lldb/Utility/ConstString.h"
17 #include "lldb/Utility/DataBufferHeap.h"
18 #include "lldb/Utility/DataExtractor.h"
19 #include "lldb/Utility/Scalar.h"
20 #include "lldb/Utility/Stream.h"
21 #include "lldb/Utility/StreamString.h"
22 
23 #include <iterator>
24 #include <mutex>
25 #include <optional>
26 
27 using namespace lldb;
28 using namespace lldb_private;
29 
30 // Tests
31 
32 bool CompilerType::IsAggregateType() const {
33   if (IsValid())
34     if (auto type_system_sp = GetTypeSystem())
35       return type_system_sp->IsAggregateType(m_type);
36   return false;
37 }
38 
39 bool CompilerType::IsAnonymousType() const {
40   if (IsValid())
41     if (auto type_system_sp = GetTypeSystem())
42       return type_system_sp->IsAnonymousType(m_type);
43   return false;
44 }
45 
46 bool CompilerType::IsScopedEnumerationType() const {
47   if (IsValid())
48     if (auto type_system_sp = GetTypeSystem())
49       return type_system_sp->IsScopedEnumerationType(m_type);
50   return false;
51 }
52 
53 bool CompilerType::IsArrayType(CompilerType *element_type_ptr, uint64_t *size,
54                                bool *is_incomplete) const {
55   if (IsValid())
56     if (auto type_system_sp = GetTypeSystem())
57       return type_system_sp->IsArrayType(m_type, element_type_ptr, size,
58                                       is_incomplete);
59 
60   if (element_type_ptr)
61     element_type_ptr->Clear();
62   if (size)
63     *size = 0;
64   if (is_incomplete)
65     *is_incomplete = false;
66   return false;
67 }
68 
69 bool CompilerType::IsVectorType(CompilerType *element_type,
70                                 uint64_t *size) const {
71   if (IsValid())
72     if (auto type_system_sp = GetTypeSystem())
73       return type_system_sp->IsVectorType(m_type, element_type, size);
74   return false;
75 }
76 
77 bool CompilerType::IsRuntimeGeneratedType() const {
78   if (IsValid())
79     if (auto type_system_sp = GetTypeSystem())
80       return type_system_sp->IsRuntimeGeneratedType(m_type);
81   return false;
82 }
83 
84 bool CompilerType::IsCharType() const {
85   if (IsValid())
86     if (auto type_system_sp = GetTypeSystem())
87       return type_system_sp->IsCharType(m_type);
88   return false;
89 }
90 
91 bool CompilerType::IsCompleteType() const {
92   if (IsValid())
93     if (auto type_system_sp = GetTypeSystem())
94       return type_system_sp->IsCompleteType(m_type);
95   return false;
96 }
97 
98 bool CompilerType::IsForcefullyCompleted() const {
99   if (IsValid())
100     if (auto type_system_sp = GetTypeSystem())
101       return type_system_sp->IsForcefullyCompleted(m_type);
102   return false;
103 }
104 
105 bool CompilerType::IsConst() const {
106   if (IsValid())
107     if (auto type_system_sp = GetTypeSystem())
108       return type_system_sp->IsConst(m_type);
109   return false;
110 }
111 
112 bool CompilerType::IsCStringType(uint32_t &length) const {
113   if (IsValid())
114     if (auto type_system_sp = GetTypeSystem())
115       return type_system_sp->IsCStringType(m_type, length);
116   return false;
117 }
118 
119 bool CompilerType::IsFunctionType() const {
120   if (IsValid())
121     if (auto type_system_sp = GetTypeSystem())
122       return type_system_sp->IsFunctionType(m_type);
123   return false;
124 }
125 
126 // Used to detect "Homogeneous Floating-point Aggregates"
127 uint32_t
128 CompilerType::IsHomogeneousAggregate(CompilerType *base_type_ptr) const {
129   if (IsValid())
130     if (auto type_system_sp = GetTypeSystem())
131       return type_system_sp->IsHomogeneousAggregate(m_type, base_type_ptr);
132   return 0;
133 }
134 
135 size_t CompilerType::GetNumberOfFunctionArguments() const {
136   if (IsValid())
137     if (auto type_system_sp = GetTypeSystem())
138       return type_system_sp->GetNumberOfFunctionArguments(m_type);
139   return 0;
140 }
141 
142 CompilerType
143 CompilerType::GetFunctionArgumentAtIndex(const size_t index) const {
144   if (IsValid())
145     if (auto type_system_sp = GetTypeSystem())
146       return type_system_sp->GetFunctionArgumentAtIndex(m_type, index);
147   return CompilerType();
148 }
149 
150 bool CompilerType::IsFunctionPointerType() const {
151   if (IsValid())
152     if (auto type_system_sp = GetTypeSystem())
153       return type_system_sp->IsFunctionPointerType(m_type);
154   return false;
155 }
156 
157 bool CompilerType::IsBlockPointerType(
158     CompilerType *function_pointer_type_ptr) const {
159   if (IsValid())
160     if (auto type_system_sp = GetTypeSystem())
161       return type_system_sp->IsBlockPointerType(m_type, function_pointer_type_ptr);
162   return false;
163 }
164 
165 bool CompilerType::IsIntegerType(bool &is_signed) const {
166   if (IsValid())
167     if (auto type_system_sp = GetTypeSystem())
168       return type_system_sp->IsIntegerType(m_type, is_signed);
169   return false;
170 }
171 
172 bool CompilerType::IsEnumerationType(bool &is_signed) const {
173   if (IsValid())
174     if (auto type_system_sp = GetTypeSystem())
175       return type_system_sp->IsEnumerationType(m_type, is_signed);
176   return false;
177 }
178 
179 bool CompilerType::IsIntegerOrEnumerationType(bool &is_signed) const {
180   return IsIntegerType(is_signed) || IsEnumerationType(is_signed);
181 }
182 
183 bool CompilerType::IsPointerType(CompilerType *pointee_type) const {
184   if (IsValid()) {
185     if (auto type_system_sp = GetTypeSystem())
186       return type_system_sp->IsPointerType(m_type, pointee_type);
187   }
188   if (pointee_type)
189     pointee_type->Clear();
190   return false;
191 }
192 
193 bool CompilerType::IsPointerOrReferenceType(CompilerType *pointee_type) const {
194   if (IsValid()) {
195     if (auto type_system_sp = GetTypeSystem())
196       return type_system_sp->IsPointerOrReferenceType(m_type, pointee_type);
197   }
198   if (pointee_type)
199     pointee_type->Clear();
200   return false;
201 }
202 
203 bool CompilerType::IsReferenceType(CompilerType *pointee_type,
204                                    bool *is_rvalue) const {
205   if (IsValid()) {
206     if (auto type_system_sp = GetTypeSystem())
207       return type_system_sp->IsReferenceType(m_type, pointee_type, is_rvalue);
208   }
209   if (pointee_type)
210     pointee_type->Clear();
211   return false;
212 }
213 
214 bool CompilerType::ShouldTreatScalarValueAsAddress() const {
215   if (IsValid())
216     if (auto type_system_sp = GetTypeSystem())
217       return type_system_sp->ShouldTreatScalarValueAsAddress(m_type);
218   return false;
219 }
220 
221 bool CompilerType::IsFloatingPointType(uint32_t &count,
222                                        bool &is_complex) const {
223   if (IsValid()) {
224     if (auto type_system_sp = GetTypeSystem())
225       return type_system_sp->IsFloatingPointType(m_type, count, is_complex);
226   }
227   count = 0;
228   is_complex = false;
229   return false;
230 }
231 
232 bool CompilerType::IsDefined() const {
233   if (IsValid())
234     if (auto type_system_sp = GetTypeSystem())
235       return type_system_sp->IsDefined(m_type);
236   return true;
237 }
238 
239 bool CompilerType::IsPolymorphicClass() const {
240   if (IsValid()) {
241     if (auto type_system_sp = GetTypeSystem())
242       return type_system_sp->IsPolymorphicClass(m_type);
243   }
244   return false;
245 }
246 
247 bool CompilerType::IsPossibleDynamicType(CompilerType *dynamic_pointee_type,
248                                          bool check_cplusplus,
249                                          bool check_objc) const {
250   if (IsValid())
251     if (auto type_system_sp = GetTypeSystem())
252       return type_system_sp->IsPossibleDynamicType(m_type, dynamic_pointee_type,
253                                                 check_cplusplus, check_objc);
254   return false;
255 }
256 
257 bool CompilerType::IsScalarType() const {
258   if (IsValid())
259     if (auto type_system_sp = GetTypeSystem())
260       return type_system_sp->IsScalarType(m_type);
261   return false;
262 }
263 
264 bool CompilerType::IsTemplateType() const {
265   if (IsValid())
266     if (auto type_system_sp = GetTypeSystem())
267       return type_system_sp->IsTemplateType(m_type);
268   return false;
269 }
270 
271 bool CompilerType::IsTypedefType() const {
272   if (IsValid())
273     if (auto type_system_sp = GetTypeSystem())
274       return type_system_sp->IsTypedefType(m_type);
275   return false;
276 }
277 
278 bool CompilerType::IsVoidType() const {
279   if (IsValid())
280     if (auto type_system_sp = GetTypeSystem())
281       return type_system_sp->IsVoidType(m_type);
282   return false;
283 }
284 
285 bool CompilerType::IsPointerToScalarType() const {
286   if (!IsValid())
287     return false;
288 
289   return IsPointerType() && GetPointeeType().IsScalarType();
290 }
291 
292 bool CompilerType::IsArrayOfScalarType() const {
293   CompilerType element_type;
294   if (IsArrayType(&element_type))
295     return element_type.IsScalarType();
296   return false;
297 }
298 
299 bool CompilerType::IsBeingDefined() const {
300   if (IsValid())
301     if (auto type_system_sp = GetTypeSystem())
302       return type_system_sp->IsBeingDefined(m_type);
303   return false;
304 }
305 
306 // Type Completion
307 
308 bool CompilerType::GetCompleteType() const {
309   if (IsValid())
310     if (auto type_system_sp = GetTypeSystem())
311       return type_system_sp->GetCompleteType(m_type);
312   return false;
313 }
314 
315 // AST related queries
316 size_t CompilerType::GetPointerByteSize() const {
317   if (auto type_system_sp = GetTypeSystem())
318     return type_system_sp->GetPointerByteSize();
319   return 0;
320 }
321 
322 ConstString CompilerType::GetTypeName(bool BaseOnly) const {
323   if (IsValid()) {
324     if (auto type_system_sp = GetTypeSystem())
325       return type_system_sp->GetTypeName(m_type, BaseOnly);
326   }
327   return ConstString("<invalid>");
328 }
329 
330 ConstString CompilerType::GetDisplayTypeName() const {
331   if (IsValid())
332     if (auto type_system_sp = GetTypeSystem())
333       return type_system_sp->GetDisplayTypeName(m_type);
334   return ConstString("<invalid>");
335 }
336 
337 uint32_t CompilerType::GetTypeInfo(
338     CompilerType *pointee_or_element_compiler_type) const {
339   if (IsValid())
340   if (auto type_system_sp = GetTypeSystem())
341     return type_system_sp->GetTypeInfo(m_type,
342                                        pointee_or_element_compiler_type);
343   return 0;
344 }
345 
346 lldb::LanguageType CompilerType::GetMinimumLanguage() {
347   if (IsValid())
348     if (auto type_system_sp = GetTypeSystem())
349       return type_system_sp->GetMinimumLanguage(m_type);
350   return lldb::eLanguageTypeC;
351 }
352 
353 lldb::TypeClass CompilerType::GetTypeClass() const {
354   if (IsValid())
355     if (auto type_system_sp = GetTypeSystem())
356       return type_system_sp->GetTypeClass(m_type);
357   return lldb::eTypeClassInvalid;
358 }
359 
360 void CompilerType::SetCompilerType(lldb::TypeSystemWP type_system,
361                                    lldb::opaque_compiler_type_t type) {
362   m_type_system = type_system;
363   m_type = type;
364 }
365 
366 void CompilerType::SetCompilerType(CompilerType::TypeSystemSPWrapper type_system,
367                                    lldb::opaque_compiler_type_t type) {
368   m_type_system = type_system.GetSharedPointer();
369   m_type = type;
370 }
371 
372 unsigned CompilerType::GetTypeQualifiers() const {
373   if (IsValid())
374     if (auto type_system_sp = GetTypeSystem())
375       return type_system_sp->GetTypeQualifiers(m_type);
376   return 0;
377 }
378 
379 // Creating related types
380 
381 CompilerType
382 CompilerType::GetArrayElementType(ExecutionContextScope *exe_scope) const {
383   if (IsValid()) {
384     if (auto type_system_sp = GetTypeSystem())
385       return type_system_sp->GetArrayElementType(m_type, exe_scope);
386   }
387   return CompilerType();
388 }
389 
390 CompilerType CompilerType::GetArrayType(uint64_t size) const {
391   if (IsValid()) {
392     if (auto type_system_sp = GetTypeSystem())
393       return type_system_sp->GetArrayType(m_type, size);
394   }
395   return CompilerType();
396 }
397 
398 CompilerType CompilerType::GetCanonicalType() const {
399   if (IsValid())
400     if (auto type_system_sp = GetTypeSystem())
401       return type_system_sp->GetCanonicalType(m_type);
402   return CompilerType();
403 }
404 
405 CompilerType CompilerType::GetFullyUnqualifiedType() const {
406   if (IsValid())
407     if (auto type_system_sp = GetTypeSystem())
408       return type_system_sp->GetFullyUnqualifiedType(m_type);
409   return CompilerType();
410 }
411 
412 CompilerType CompilerType::GetEnumerationIntegerType() const {
413   if (IsValid())
414     if (auto type_system_sp = GetTypeSystem())
415       return type_system_sp->GetEnumerationIntegerType(m_type);
416   return CompilerType();
417 }
418 
419 int CompilerType::GetFunctionArgumentCount() const {
420   if (IsValid()) {
421     if (auto type_system_sp = GetTypeSystem())
422       return type_system_sp->GetFunctionArgumentCount(m_type);
423   }
424   return -1;
425 }
426 
427 CompilerType CompilerType::GetFunctionArgumentTypeAtIndex(size_t idx) const {
428   if (IsValid()) {
429     if (auto type_system_sp = GetTypeSystem())
430       return type_system_sp->GetFunctionArgumentTypeAtIndex(m_type, idx);
431   }
432   return CompilerType();
433 }
434 
435 CompilerType CompilerType::GetFunctionReturnType() const {
436   if (IsValid()) {
437     if (auto type_system_sp = GetTypeSystem())
438       return type_system_sp->GetFunctionReturnType(m_type);
439   }
440   return CompilerType();
441 }
442 
443 size_t CompilerType::GetNumMemberFunctions() const {
444   if (IsValid()) {
445     if (auto type_system_sp = GetTypeSystem())
446       return type_system_sp->GetNumMemberFunctions(m_type);
447   }
448   return 0;
449 }
450 
451 TypeMemberFunctionImpl CompilerType::GetMemberFunctionAtIndex(size_t idx) {
452   if (IsValid()) {
453     if (auto type_system_sp = GetTypeSystem())
454       return type_system_sp->GetMemberFunctionAtIndex(m_type, idx);
455   }
456   return TypeMemberFunctionImpl();
457 }
458 
459 CompilerType CompilerType::GetNonReferenceType() const {
460   if (IsValid())
461     if (auto type_system_sp = GetTypeSystem())
462       return type_system_sp->GetNonReferenceType(m_type);
463   return CompilerType();
464 }
465 
466 CompilerType CompilerType::GetPointeeType() const {
467   if (IsValid()) {
468     if (auto type_system_sp = GetTypeSystem())
469       return type_system_sp->GetPointeeType(m_type);
470   }
471   return CompilerType();
472 }
473 
474 CompilerType CompilerType::GetPointerType() const {
475   if (IsValid()) {
476     if (auto type_system_sp = GetTypeSystem())
477       return type_system_sp->GetPointerType(m_type);
478   }
479   return CompilerType();
480 }
481 
482 CompilerType CompilerType::GetLValueReferenceType() const {
483   if (IsValid())
484     if (auto type_system_sp = GetTypeSystem())
485       return type_system_sp->GetLValueReferenceType(m_type);
486   return CompilerType();
487 }
488 
489 CompilerType CompilerType::GetRValueReferenceType() const {
490   if (IsValid())
491     if (auto type_system_sp = GetTypeSystem())
492       return type_system_sp->GetRValueReferenceType(m_type);
493   return CompilerType();
494 }
495 
496 CompilerType CompilerType::GetAtomicType() const {
497   if (IsValid())
498     if (auto type_system_sp = GetTypeSystem())
499       return type_system_sp->GetAtomicType(m_type);
500   return CompilerType();
501 }
502 
503 CompilerType CompilerType::AddConstModifier() const {
504   if (IsValid())
505     if (auto type_system_sp = GetTypeSystem())
506       return type_system_sp->AddConstModifier(m_type);
507   return CompilerType();
508 }
509 
510 CompilerType CompilerType::AddVolatileModifier() const {
511   if (IsValid())
512     if (auto type_system_sp = GetTypeSystem())
513       return type_system_sp->AddVolatileModifier(m_type);
514   return CompilerType();
515 }
516 
517 CompilerType CompilerType::AddRestrictModifier() const {
518   if (IsValid())
519     if (auto type_system_sp = GetTypeSystem())
520       return type_system_sp->AddRestrictModifier(m_type);
521   return CompilerType();
522 }
523 
524 CompilerType CompilerType::CreateTypedef(const char *name,
525                                          const CompilerDeclContext &decl_ctx,
526                                          uint32_t payload) const {
527   if (IsValid())
528     if (auto type_system_sp = GetTypeSystem())
529       return type_system_sp->CreateTypedef(m_type, name, decl_ctx, payload);
530   return CompilerType();
531 }
532 
533 CompilerType CompilerType::GetTypedefedType() const {
534   if (IsValid())
535     if (auto type_system_sp = GetTypeSystem())
536       return type_system_sp->GetTypedefedType(m_type);
537   return CompilerType();
538 }
539 
540 // Create related types using the current type's AST
541 
542 CompilerType
543 CompilerType::GetBasicTypeFromAST(lldb::BasicType basic_type) const {
544   if (IsValid())
545     if (auto type_system_sp = GetTypeSystem())
546       return type_system_sp->GetBasicTypeFromAST(basic_type);
547   return CompilerType();
548 }
549 // Exploring the type
550 
551 std::optional<uint64_t>
552 CompilerType::GetBitSize(ExecutionContextScope *exe_scope) const {
553   if (IsValid())
554     if (auto type_system_sp = GetTypeSystem())
555       return type_system_sp->GetBitSize(m_type, exe_scope);
556   return {};
557 }
558 
559 std::optional<uint64_t>
560 CompilerType::GetByteSize(ExecutionContextScope *exe_scope) const {
561   if (std::optional<uint64_t> bit_size = GetBitSize(exe_scope))
562     return (*bit_size + 7) / 8;
563   return {};
564 }
565 
566 std::optional<size_t>
567 CompilerType::GetTypeBitAlign(ExecutionContextScope *exe_scope) const {
568   if (IsValid())
569     if (auto type_system_sp = GetTypeSystem())
570       return type_system_sp->GetTypeBitAlign(m_type, exe_scope);
571   return {};
572 }
573 
574 lldb::Encoding CompilerType::GetEncoding(uint64_t &count) const {
575   if (IsValid())
576     if (auto type_system_sp = GetTypeSystem())
577       return type_system_sp->GetEncoding(m_type, count);
578   return lldb::eEncodingInvalid;
579 }
580 
581 lldb::Format CompilerType::GetFormat() const {
582   if (IsValid())
583     if (auto type_system_sp = GetTypeSystem())
584       return type_system_sp->GetFormat(m_type);
585   return lldb::eFormatDefault;
586 }
587 
588 uint32_t CompilerType::GetNumChildren(bool omit_empty_base_classes,
589                                       const ExecutionContext *exe_ctx) const {
590   if (IsValid())
591     if (auto type_system_sp = GetTypeSystem())
592       return type_system_sp->GetNumChildren(m_type, omit_empty_base_classes,
593                                        exe_ctx);
594   return 0;
595 }
596 
597 lldb::BasicType CompilerType::GetBasicTypeEnumeration() const {
598   if (IsValid())
599     if (auto type_system_sp = GetTypeSystem())
600       return type_system_sp->GetBasicTypeEnumeration(m_type);
601   return eBasicTypeInvalid;
602 }
603 
604 void CompilerType::ForEachEnumerator(
605     std::function<bool(const CompilerType &integer_type,
606                        ConstString name,
607                        const llvm::APSInt &value)> const &callback) const {
608   if (IsValid())
609     if (auto type_system_sp = GetTypeSystem())
610       return type_system_sp->ForEachEnumerator(m_type, callback);
611 }
612 
613 uint32_t CompilerType::GetNumFields() const {
614   if (IsValid())
615     if (auto type_system_sp = GetTypeSystem())
616       return type_system_sp->GetNumFields(m_type);
617   return 0;
618 }
619 
620 CompilerType CompilerType::GetFieldAtIndex(size_t idx, std::string &name,
621                                            uint64_t *bit_offset_ptr,
622                                            uint32_t *bitfield_bit_size_ptr,
623                                            bool *is_bitfield_ptr) const {
624   if (IsValid())
625     if (auto type_system_sp = GetTypeSystem())
626       return type_system_sp->GetFieldAtIndex(m_type, idx, name, bit_offset_ptr,
627                                         bitfield_bit_size_ptr, is_bitfield_ptr);
628   return CompilerType();
629 }
630 
631 uint32_t CompilerType::GetNumDirectBaseClasses() const {
632   if (IsValid())
633     if (auto type_system_sp = GetTypeSystem())
634       return type_system_sp->GetNumDirectBaseClasses(m_type);
635   return 0;
636 }
637 
638 uint32_t CompilerType::GetNumVirtualBaseClasses() const {
639   if (IsValid())
640     if (auto type_system_sp = GetTypeSystem())
641       return type_system_sp->GetNumVirtualBaseClasses(m_type);
642   return 0;
643 }
644 
645 CompilerType
646 CompilerType::GetDirectBaseClassAtIndex(size_t idx,
647                                         uint32_t *bit_offset_ptr) const {
648   if (IsValid())
649     if (auto type_system_sp = GetTypeSystem())
650       return type_system_sp->GetDirectBaseClassAtIndex(m_type, idx,
651                                                     bit_offset_ptr);
652   return CompilerType();
653 }
654 
655 CompilerType
656 CompilerType::GetVirtualBaseClassAtIndex(size_t idx,
657                                          uint32_t *bit_offset_ptr) const {
658   if (IsValid())
659     if (auto type_system_sp = GetTypeSystem())
660       return type_system_sp->GetVirtualBaseClassAtIndex(m_type, idx,
661                                                      bit_offset_ptr);
662   return CompilerType();
663 }
664 
665 uint32_t CompilerType::GetIndexOfFieldWithName(
666     const char *name, CompilerType *field_compiler_type_ptr,
667     uint64_t *bit_offset_ptr, uint32_t *bitfield_bit_size_ptr,
668     bool *is_bitfield_ptr) const {
669   unsigned count = GetNumFields();
670   std::string field_name;
671   for (unsigned index = 0; index < count; index++) {
672     CompilerType field_compiler_type(
673         GetFieldAtIndex(index, field_name, bit_offset_ptr,
674                         bitfield_bit_size_ptr, is_bitfield_ptr));
675     if (strcmp(field_name.c_str(), name) == 0) {
676       if (field_compiler_type_ptr)
677         *field_compiler_type_ptr = field_compiler_type;
678       return index;
679     }
680   }
681   return UINT32_MAX;
682 }
683 
684 CompilerType CompilerType::GetChildCompilerTypeAtIndex(
685     ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers,
686     bool omit_empty_base_classes, bool ignore_array_bounds,
687     std::string &child_name, uint32_t &child_byte_size,
688     int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size,
689     uint32_t &child_bitfield_bit_offset, bool &child_is_base_class,
690     bool &child_is_deref_of_parent, ValueObject *valobj,
691     uint64_t &language_flags) const {
692   if (IsValid())
693     if (auto type_system_sp = GetTypeSystem())
694       return type_system_sp->GetChildCompilerTypeAtIndex(
695           m_type, exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
696           ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
697           child_bitfield_bit_size, child_bitfield_bit_offset,
698           child_is_base_class, child_is_deref_of_parent, valobj,
699           language_flags);
700   return CompilerType();
701 }
702 
703 // Look for a child member (doesn't include base classes, but it does include
704 // their members) in the type hierarchy. Returns an index path into
705 // "clang_type" on how to reach the appropriate member.
706 //
707 //    class A
708 //    {
709 //    public:
710 //        int m_a;
711 //        int m_b;
712 //    };
713 //
714 //    class B
715 //    {
716 //    };
717 //
718 //    class C :
719 //        public B,
720 //        public A
721 //    {
722 //    };
723 //
724 // If we have a clang type that describes "class C", and we wanted to looked
725 // "m_b" in it:
726 //
727 // With omit_empty_base_classes == false we would get an integer array back
728 // with: { 1,  1 } The first index 1 is the child index for "class A" within
729 // class C The second index 1 is the child index for "m_b" within class A
730 //
731 // With omit_empty_base_classes == true we would get an integer array back
732 // with: { 0,  1 } The first index 0 is the child index for "class A" within
733 // class C (since class B doesn't have any members it doesn't count) The second
734 // index 1 is the child index for "m_b" within class A
735 
736 size_t CompilerType::GetIndexOfChildMemberWithName(
737     const char *name, bool omit_empty_base_classes,
738     std::vector<uint32_t> &child_indexes) const {
739   if (IsValid() && name && name[0]) {
740     if (auto type_system_sp = GetTypeSystem())
741       return type_system_sp->GetIndexOfChildMemberWithName(
742         m_type, name, omit_empty_base_classes, child_indexes);
743   }
744   return 0;
745 }
746 
747 size_t CompilerType::GetNumTemplateArguments(bool expand_pack) const {
748   if (IsValid()) {
749     if (auto type_system_sp = GetTypeSystem())
750       return type_system_sp->GetNumTemplateArguments(m_type, expand_pack);
751   }
752   return 0;
753 }
754 
755 TemplateArgumentKind
756 CompilerType::GetTemplateArgumentKind(size_t idx, bool expand_pack) const {
757   if (IsValid())
758     if (auto type_system_sp = GetTypeSystem())
759       return type_system_sp->GetTemplateArgumentKind(m_type, idx, expand_pack);
760   return eTemplateArgumentKindNull;
761 }
762 
763 CompilerType CompilerType::GetTypeTemplateArgument(size_t idx,
764                                                    bool expand_pack) const {
765   if (IsValid()) {
766     if (auto type_system_sp = GetTypeSystem())
767       return type_system_sp->GetTypeTemplateArgument(m_type, idx, expand_pack);
768   }
769   return CompilerType();
770 }
771 
772 std::optional<CompilerType::IntegralTemplateArgument>
773 CompilerType::GetIntegralTemplateArgument(size_t idx, bool expand_pack) const {
774   if (IsValid())
775     if (auto type_system_sp = GetTypeSystem())
776       return type_system_sp->GetIntegralTemplateArgument(m_type, idx, expand_pack);
777   return std::nullopt;
778 }
779 
780 CompilerType CompilerType::GetTypeForFormatters() const {
781   if (IsValid())
782     if (auto type_system_sp = GetTypeSystem())
783       return type_system_sp->GetTypeForFormatters(m_type);
784   return CompilerType();
785 }
786 
787 LazyBool CompilerType::ShouldPrintAsOneLiner(ValueObject *valobj) const {
788   if (IsValid())
789     if (auto type_system_sp = GetTypeSystem())
790       return type_system_sp->ShouldPrintAsOneLiner(m_type, valobj);
791   return eLazyBoolCalculate;
792 }
793 
794 bool CompilerType::IsMeaninglessWithoutDynamicResolution() const {
795   if (IsValid())
796     if (auto type_system_sp = GetTypeSystem())
797       return type_system_sp->IsMeaninglessWithoutDynamicResolution(m_type);
798   return false;
799 }
800 
801 // Get the index of the child of "clang_type" whose name matches. This function
802 // doesn't descend into the children, but only looks one level deep and name
803 // matches can include base class names.
804 
805 uint32_t
806 CompilerType::GetIndexOfChildWithName(const char *name,
807                                       bool omit_empty_base_classes) const {
808   if (IsValid() && name && name[0]) {
809     if (auto type_system_sp = GetTypeSystem())
810       return type_system_sp->GetIndexOfChildWithName(m_type, name,
811                                                   omit_empty_base_classes);
812   }
813   return UINT32_MAX;
814 }
815 
816 // Dumping types
817 
818 void CompilerType::DumpValue(ExecutionContext *exe_ctx, Stream *s,
819                              lldb::Format format, const DataExtractor &data,
820                              lldb::offset_t data_byte_offset,
821                              size_t data_byte_size, uint32_t bitfield_bit_size,
822                              uint32_t bitfield_bit_offset, bool show_types,
823                              bool show_summary, bool verbose, uint32_t depth) {
824   if (!IsValid())
825     if (auto type_system_sp = GetTypeSystem())
826       type_system_sp->DumpValue(m_type, exe_ctx, s, format, data,
827                                 data_byte_offset, data_byte_size,
828                                 bitfield_bit_size, bitfield_bit_offset,
829                                 show_types, show_summary, verbose, depth);
830 }
831 
832 bool CompilerType::DumpTypeValue(Stream *s, lldb::Format format,
833                                  const DataExtractor &data,
834                                  lldb::offset_t byte_offset, size_t byte_size,
835                                  uint32_t bitfield_bit_size,
836                                  uint32_t bitfield_bit_offset,
837                                  ExecutionContextScope *exe_scope) {
838   if (IsValid())
839     if (auto type_system_sp = GetTypeSystem())
840       return type_system_sp->DumpTypeValue(m_type, s, format, data, byte_offset,
841                                            byte_size, bitfield_bit_size,
842                                            bitfield_bit_offset, exe_scope);
843   return false;
844 }
845 
846 void CompilerType::DumpSummary(ExecutionContext *exe_ctx, Stream *s,
847                                const DataExtractor &data,
848                                lldb::offset_t data_byte_offset,
849                                size_t data_byte_size) {
850   if (IsValid())
851     if (auto type_system_sp = GetTypeSystem())
852       type_system_sp->DumpSummary(m_type, exe_ctx, s, data, data_byte_offset,
853                                   data_byte_size);
854 }
855 
856 void CompilerType::DumpTypeDescription(lldb::DescriptionLevel level) const {
857   if (IsValid())
858     if (auto type_system_sp = GetTypeSystem())
859       type_system_sp->DumpTypeDescription(m_type, level);
860 }
861 
862 void CompilerType::DumpTypeDescription(Stream *s,
863                                        lldb::DescriptionLevel level) const {
864   if (IsValid())
865     if (auto type_system_sp = GetTypeSystem())
866       type_system_sp->DumpTypeDescription(m_type, s, level);
867 }
868 
869 #ifndef NDEBUG
870 LLVM_DUMP_METHOD void CompilerType::dump() const {
871   if (IsValid())
872     if (auto type_system_sp = GetTypeSystem())
873       return type_system_sp->dump(m_type);
874   llvm::errs() << "<invalid>\n";
875 }
876 #endif
877 
878 bool CompilerType::GetValueAsScalar(const lldb_private::DataExtractor &data,
879                                     lldb::offset_t data_byte_offset,
880                                     size_t data_byte_size, Scalar &value,
881                                     ExecutionContextScope *exe_scope) const {
882   if (!IsValid())
883     return false;
884 
885   if (IsAggregateType()) {
886     return false; // Aggregate types don't have scalar values
887   } else {
888     uint64_t count = 0;
889     lldb::Encoding encoding = GetEncoding(count);
890 
891     if (encoding == lldb::eEncodingInvalid || count != 1)
892       return false;
893 
894     std::optional<uint64_t> byte_size = GetByteSize(exe_scope);
895     if (!byte_size)
896       return false;
897     lldb::offset_t offset = data_byte_offset;
898     switch (encoding) {
899     case lldb::eEncodingInvalid:
900       break;
901     case lldb::eEncodingVector:
902       break;
903     case lldb::eEncodingUint:
904       if (*byte_size <= sizeof(unsigned long long)) {
905         uint64_t uval64 = data.GetMaxU64(&offset, *byte_size);
906         if (*byte_size <= sizeof(unsigned int)) {
907           value = (unsigned int)uval64;
908           return true;
909         } else if (*byte_size <= sizeof(unsigned long)) {
910           value = (unsigned long)uval64;
911           return true;
912         } else if (*byte_size <= sizeof(unsigned long long)) {
913           value = (unsigned long long)uval64;
914           return true;
915         } else
916           value.Clear();
917       }
918       break;
919 
920     case lldb::eEncodingSint:
921       if (*byte_size <= sizeof(long long)) {
922         int64_t sval64 = data.GetMaxS64(&offset, *byte_size);
923         if (*byte_size <= sizeof(int)) {
924           value = (int)sval64;
925           return true;
926         } else if (*byte_size <= sizeof(long)) {
927           value = (long)sval64;
928           return true;
929         } else if (*byte_size <= sizeof(long long)) {
930           value = (long long)sval64;
931           return true;
932         } else
933           value.Clear();
934       }
935       break;
936 
937     case lldb::eEncodingIEEE754:
938       if (*byte_size <= sizeof(long double)) {
939         uint32_t u32;
940         uint64_t u64;
941         if (*byte_size == sizeof(float)) {
942           if (sizeof(float) == sizeof(uint32_t)) {
943             u32 = data.GetU32(&offset);
944             value = *((float *)&u32);
945             return true;
946           } else if (sizeof(float) == sizeof(uint64_t)) {
947             u64 = data.GetU64(&offset);
948             value = *((float *)&u64);
949             return true;
950           }
951         } else if (*byte_size == sizeof(double)) {
952           if (sizeof(double) == sizeof(uint32_t)) {
953             u32 = data.GetU32(&offset);
954             value = *((double *)&u32);
955             return true;
956           } else if (sizeof(double) == sizeof(uint64_t)) {
957             u64 = data.GetU64(&offset);
958             value = *((double *)&u64);
959             return true;
960           }
961         } else if (*byte_size == sizeof(long double)) {
962           if (sizeof(long double) == sizeof(uint32_t)) {
963             u32 = data.GetU32(&offset);
964             value = *((long double *)&u32);
965             return true;
966           } else if (sizeof(long double) == sizeof(uint64_t)) {
967             u64 = data.GetU64(&offset);
968             value = *((long double *)&u64);
969             return true;
970           }
971         }
972       }
973       break;
974     }
975   }
976   return false;
977 }
978 
979 #ifndef NDEBUG
980 bool CompilerType::Verify() const {
981   if (!IsValid())
982     return true;
983   if (auto type_system_sp = GetTypeSystem())
984     return type_system_sp->Verify(m_type);
985   return true;
986 }
987 #endif
988 
989 CompilerType::TypeSystemSPWrapper CompilerType::GetTypeSystem() const {
990   return {m_type_system.lock()};
991 }
992 
993 bool CompilerType::TypeSystemSPWrapper::operator==(
994     const CompilerType::TypeSystemSPWrapper &other) const {
995   if (!m_typesystem_sp && !other.m_typesystem_sp)
996     return true;
997   if (m_typesystem_sp && other.m_typesystem_sp)
998     return m_typesystem_sp.get() == other.m_typesystem_sp.get();
999   return false;
1000 }
1001 
1002 TypeSystem *CompilerType::TypeSystemSPWrapper::operator->() const {
1003   assert(m_typesystem_sp);
1004   return m_typesystem_sp.get();
1005 }
1006 
1007 bool lldb_private::operator==(const lldb_private::CompilerType &lhs,
1008                               const lldb_private::CompilerType &rhs) {
1009   return lhs.GetTypeSystem() == rhs.GetTypeSystem() &&
1010          lhs.GetOpaqueQualType() == rhs.GetOpaqueQualType();
1011 }
1012 
1013 bool lldb_private::operator!=(const lldb_private::CompilerType &lhs,
1014                               const lldb_private::CompilerType &rhs) {
1015   return !(lhs == rhs);
1016 }
1017