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