xref: /llvm-project/lldb/source/Symbol/CompilerType.cpp (revision 8965dd40c63cf00610fcf550017b46dae736d94b)
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 
31 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 
38 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 
45 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 
52 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 
68 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 
76 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 
83 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 
90 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 
97 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 
104 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 
111 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 
118 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 
125 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 
132 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
141 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 
148 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
156 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 
163 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 
170 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 
177 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 
185 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 
192 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 
199 bool CompilerType::IsIntegerOrEnumerationType(bool &is_signed) const {
200   return IsIntegerType(is_signed) || IsEnumerationType(is_signed);
201 }
202 
203 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 
213 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 
223 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 
234 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 
241 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 
252 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 
259 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 
267 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 
277 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 
284 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 
291 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 
298 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 
305 bool CompilerType::IsPointerToScalarType() const {
306   if (!IsValid())
307     return false;
308 
309   return IsPointerType() && GetPointeeType().IsScalarType();
310 }
311 
312 bool CompilerType::IsArrayOfScalarType() const {
313   CompilerType element_type;
314   if (IsArrayType(&element_type))
315     return element_type.IsScalarType();
316   return false;
317 }
318 
319 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 
326 bool CompilerType::IsInteger() const {
327   bool is_signed = false; // May be reset by the call below.
328   return IsIntegerType(is_signed);
329 }
330 
331 bool CompilerType::IsFloat() const {
332   uint32_t count = 0;
333   bool is_complex = false;
334   return IsFloatingPointType(count, is_complex);
335 }
336 
337 bool CompilerType::IsEnumerationType() const {
338   bool is_signed = false; // May be reset by the call below.
339   return IsEnumerationType(is_signed);
340 }
341 
342 bool CompilerType::IsUnscopedEnumerationType() const {
343   return IsEnumerationType() && !IsScopedEnumerationType();
344 }
345 
346 bool CompilerType::IsIntegerOrUnscopedEnumerationType() const {
347   return IsInteger() || IsUnscopedEnumerationType();
348 }
349 
350 bool CompilerType::IsSigned() const {
351   return GetTypeInfo() & lldb::eTypeIsSigned;
352 }
353 
354 bool CompilerType::IsNullPtrType() const {
355   return GetCanonicalType().GetBasicTypeEnumeration() ==
356          lldb::eBasicTypeNullPtr;
357 }
358 
359 bool CompilerType::IsBoolean() const {
360   return GetCanonicalType().GetBasicTypeEnumeration() == lldb::eBasicTypeBool;
361 }
362 
363 bool CompilerType::IsEnumerationIntegerTypeSigned() const {
364   if (IsValid())
365     return GetEnumerationIntegerType().GetTypeInfo() & lldb::eTypeIsSigned;
366 
367   return false;
368 }
369 
370 bool CompilerType::IsScalarOrUnscopedEnumerationType() const {
371   return IsScalarType() || IsUnscopedEnumerationType();
372 }
373 
374 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 
401 bool CompilerType::IsPointerToVoid() const {
402   if (!IsValid())
403     return false;
404 
405   return IsPointerType() &&
406          GetPointeeType().GetBasicTypeEnumeration() == lldb::eBasicTypeVoid;
407 }
408 
409 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 
418 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 
450 bool CompilerType::IsContextuallyConvertibleToBool() const {
451   return IsScalarType() || IsUnscopedEnumerationType() || IsPointerType() ||
452          IsNullPtrType() || IsArrayType();
453 }
454 
455 bool CompilerType::IsBasicType() const {
456   return GetCanonicalType().GetBasicTypeEnumeration() !=
457          lldb::eBasicTypeInvalid;
458 }
459 
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 
473 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 
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 
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 
514 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
522 size_t CompilerType::GetPointerByteSize() const {
523   if (auto type_system_sp = GetTypeSystem())
524     return type_system_sp->GetPointerByteSize();
525   return 0;
526 }
527 
528 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 
536 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 
543 ConstString CompilerType::GetMangledTypeName() const {
544   if (IsValid()) {
545     if (auto type_system_sp = GetTypeSystem())
546       return type_system_sp->GetMangledTypeName(m_type);
547   }
548   return ConstString("<invalid>");
549 }
550 
551 uint32_t CompilerType::GetTypeInfo(
552     CompilerType *pointee_or_element_compiler_type) const {
553   if (IsValid())
554   if (auto type_system_sp = GetTypeSystem())
555     return type_system_sp->GetTypeInfo(m_type,
556                                        pointee_or_element_compiler_type);
557   return 0;
558 }
559 
560 lldb::LanguageType CompilerType::GetMinimumLanguage() {
561   if (IsValid())
562     if (auto type_system_sp = GetTypeSystem())
563       return type_system_sp->GetMinimumLanguage(m_type);
564   return lldb::eLanguageTypeC;
565 }
566 
567 lldb::TypeClass CompilerType::GetTypeClass() const {
568   if (IsValid())
569     if (auto type_system_sp = GetTypeSystem())
570       return type_system_sp->GetTypeClass(m_type);
571   return lldb::eTypeClassInvalid;
572 }
573 
574 void CompilerType::SetCompilerType(lldb::TypeSystemWP type_system,
575                                    lldb::opaque_compiler_type_t type) {
576   m_type_system = type_system;
577   m_type = type;
578 }
579 
580 void CompilerType::SetCompilerType(CompilerType::TypeSystemSPWrapper type_system,
581                                    lldb::opaque_compiler_type_t type) {
582   m_type_system = type_system.GetSharedPointer();
583   m_type = type;
584 }
585 
586 unsigned CompilerType::GetTypeQualifiers() const {
587   if (IsValid())
588     if (auto type_system_sp = GetTypeSystem())
589       return type_system_sp->GetTypeQualifiers(m_type);
590   return 0;
591 }
592 
593 // Creating related types
594 
595 CompilerType
596 CompilerType::GetArrayElementType(ExecutionContextScope *exe_scope) const {
597   if (IsValid()) {
598     if (auto type_system_sp = GetTypeSystem())
599       return type_system_sp->GetArrayElementType(m_type, exe_scope);
600   }
601   return CompilerType();
602 }
603 
604 CompilerType CompilerType::GetArrayType(uint64_t size) const {
605   if (IsValid()) {
606     if (auto type_system_sp = GetTypeSystem())
607       return type_system_sp->GetArrayType(m_type, size);
608   }
609   return CompilerType();
610 }
611 
612 CompilerType CompilerType::GetCanonicalType() const {
613   if (IsValid())
614     if (auto type_system_sp = GetTypeSystem())
615       return type_system_sp->GetCanonicalType(m_type);
616   return CompilerType();
617 }
618 
619 CompilerType CompilerType::GetFullyUnqualifiedType() const {
620   if (IsValid())
621     if (auto type_system_sp = GetTypeSystem())
622       return type_system_sp->GetFullyUnqualifiedType(m_type);
623   return CompilerType();
624 }
625 
626 CompilerType CompilerType::GetEnumerationIntegerType() const {
627   if (IsValid())
628     if (auto type_system_sp = GetTypeSystem())
629       return type_system_sp->GetEnumerationIntegerType(m_type);
630   return CompilerType();
631 }
632 
633 int CompilerType::GetFunctionArgumentCount() const {
634   if (IsValid()) {
635     if (auto type_system_sp = GetTypeSystem())
636       return type_system_sp->GetFunctionArgumentCount(m_type);
637   }
638   return -1;
639 }
640 
641 CompilerType CompilerType::GetFunctionArgumentTypeAtIndex(size_t idx) const {
642   if (IsValid()) {
643     if (auto type_system_sp = GetTypeSystem())
644       return type_system_sp->GetFunctionArgumentTypeAtIndex(m_type, idx);
645   }
646   return CompilerType();
647 }
648 
649 CompilerType CompilerType::GetFunctionReturnType() const {
650   if (IsValid()) {
651     if (auto type_system_sp = GetTypeSystem())
652       return type_system_sp->GetFunctionReturnType(m_type);
653   }
654   return CompilerType();
655 }
656 
657 size_t CompilerType::GetNumMemberFunctions() const {
658   if (IsValid()) {
659     if (auto type_system_sp = GetTypeSystem())
660       return type_system_sp->GetNumMemberFunctions(m_type);
661   }
662   return 0;
663 }
664 
665 TypeMemberFunctionImpl CompilerType::GetMemberFunctionAtIndex(size_t idx) {
666   if (IsValid()) {
667     if (auto type_system_sp = GetTypeSystem())
668       return type_system_sp->GetMemberFunctionAtIndex(m_type, idx);
669   }
670   return TypeMemberFunctionImpl();
671 }
672 
673 CompilerType CompilerType::GetNonReferenceType() const {
674   if (IsValid())
675     if (auto type_system_sp = GetTypeSystem())
676       return type_system_sp->GetNonReferenceType(m_type);
677   return CompilerType();
678 }
679 
680 CompilerType CompilerType::GetPointeeType() const {
681   if (IsValid()) {
682     if (auto type_system_sp = GetTypeSystem())
683       return type_system_sp->GetPointeeType(m_type);
684   }
685   return CompilerType();
686 }
687 
688 CompilerType CompilerType::GetPointerType() const {
689   if (IsValid()) {
690     if (auto type_system_sp = GetTypeSystem())
691       return type_system_sp->GetPointerType(m_type);
692   }
693   return CompilerType();
694 }
695 
696 CompilerType CompilerType::AddPtrAuthModifier(uint32_t payload) const {
697   if (IsValid())
698     if (auto type_system_sp = GetTypeSystem())
699       return type_system_sp->AddPtrAuthModifier(m_type, payload);
700   return CompilerType();
701 }
702 
703 CompilerType CompilerType::GetLValueReferenceType() const {
704   if (IsValid())
705     if (auto type_system_sp = GetTypeSystem())
706       return type_system_sp->GetLValueReferenceType(m_type);
707   return CompilerType();
708 }
709 
710 CompilerType CompilerType::GetRValueReferenceType() const {
711   if (IsValid())
712     if (auto type_system_sp = GetTypeSystem())
713       return type_system_sp->GetRValueReferenceType(m_type);
714   return CompilerType();
715 }
716 
717 CompilerType CompilerType::GetAtomicType() const {
718   if (IsValid())
719     if (auto type_system_sp = GetTypeSystem())
720       return type_system_sp->GetAtomicType(m_type);
721   return CompilerType();
722 }
723 
724 CompilerType CompilerType::AddConstModifier() const {
725   if (IsValid())
726     if (auto type_system_sp = GetTypeSystem())
727       return type_system_sp->AddConstModifier(m_type);
728   return CompilerType();
729 }
730 
731 CompilerType CompilerType::AddVolatileModifier() const {
732   if (IsValid())
733     if (auto type_system_sp = GetTypeSystem())
734       return type_system_sp->AddVolatileModifier(m_type);
735   return CompilerType();
736 }
737 
738 CompilerType CompilerType::AddRestrictModifier() const {
739   if (IsValid())
740     if (auto type_system_sp = GetTypeSystem())
741       return type_system_sp->AddRestrictModifier(m_type);
742   return CompilerType();
743 }
744 
745 CompilerType CompilerType::CreateTypedef(const char *name,
746                                          const CompilerDeclContext &decl_ctx,
747                                          uint32_t payload) const {
748   if (IsValid())
749     if (auto type_system_sp = GetTypeSystem())
750       return type_system_sp->CreateTypedef(m_type, name, decl_ctx, payload);
751   return CompilerType();
752 }
753 
754 CompilerType CompilerType::GetTypedefedType() const {
755   if (IsValid())
756     if (auto type_system_sp = GetTypeSystem())
757       return type_system_sp->GetTypedefedType(m_type);
758   return CompilerType();
759 }
760 
761 // Create related types using the current type's AST
762 
763 CompilerType
764 CompilerType::GetBasicTypeFromAST(lldb::BasicType basic_type) const {
765   if (IsValid())
766     if (auto type_system_sp = GetTypeSystem())
767       return type_system_sp->GetBasicTypeFromAST(basic_type);
768   return CompilerType();
769 }
770 // Exploring the type
771 
772 std::optional<uint64_t>
773 CompilerType::GetBitSize(ExecutionContextScope *exe_scope) const {
774   if (IsValid())
775     if (auto type_system_sp = GetTypeSystem())
776       return type_system_sp->GetBitSize(m_type, exe_scope);
777   return {};
778 }
779 
780 std::optional<uint64_t>
781 CompilerType::GetByteSize(ExecutionContextScope *exe_scope) const {
782   if (std::optional<uint64_t> bit_size = GetBitSize(exe_scope))
783     return (*bit_size + 7) / 8;
784   return {};
785 }
786 
787 std::optional<size_t>
788 CompilerType::GetTypeBitAlign(ExecutionContextScope *exe_scope) const {
789   if (IsValid())
790     if (auto type_system_sp = GetTypeSystem())
791       return type_system_sp->GetTypeBitAlign(m_type, exe_scope);
792   return {};
793 }
794 
795 lldb::Encoding CompilerType::GetEncoding(uint64_t &count) const {
796   if (IsValid())
797     if (auto type_system_sp = GetTypeSystem())
798       return type_system_sp->GetEncoding(m_type, count);
799   return lldb::eEncodingInvalid;
800 }
801 
802 lldb::Format CompilerType::GetFormat() const {
803   if (IsValid())
804     if (auto type_system_sp = GetTypeSystem())
805       return type_system_sp->GetFormat(m_type);
806   return lldb::eFormatDefault;
807 }
808 
809 llvm::Expected<uint32_t>
810 CompilerType::GetNumChildren(bool omit_empty_base_classes,
811                              const ExecutionContext *exe_ctx) const {
812   if (IsValid())
813     if (auto type_system_sp = GetTypeSystem())
814       return type_system_sp->GetNumChildren(m_type, omit_empty_base_classes,
815                                        exe_ctx);
816   return llvm::createStringError("invalid type");
817 }
818 
819 lldb::BasicType CompilerType::GetBasicTypeEnumeration() const {
820   if (IsValid())
821     if (auto type_system_sp = GetTypeSystem())
822       return type_system_sp->GetBasicTypeEnumeration(m_type);
823   return eBasicTypeInvalid;
824 }
825 
826 void CompilerType::ForEachEnumerator(
827     std::function<bool(const CompilerType &integer_type,
828                        ConstString name,
829                        const llvm::APSInt &value)> const &callback) const {
830   if (IsValid())
831     if (auto type_system_sp = GetTypeSystem())
832       return type_system_sp->ForEachEnumerator(m_type, callback);
833 }
834 
835 uint32_t CompilerType::GetNumFields() const {
836   if (IsValid())
837     if (auto type_system_sp = GetTypeSystem())
838       return type_system_sp->GetNumFields(m_type);
839   return 0;
840 }
841 
842 CompilerType CompilerType::GetFieldAtIndex(size_t idx, std::string &name,
843                                            uint64_t *bit_offset_ptr,
844                                            uint32_t *bitfield_bit_size_ptr,
845                                            bool *is_bitfield_ptr) const {
846   if (IsValid())
847     if (auto type_system_sp = GetTypeSystem())
848       return type_system_sp->GetFieldAtIndex(m_type, idx, name, bit_offset_ptr,
849                                         bitfield_bit_size_ptr, is_bitfield_ptr);
850   return CompilerType();
851 }
852 
853 uint32_t CompilerType::GetNumDirectBaseClasses() const {
854   if (IsValid())
855     if (auto type_system_sp = GetTypeSystem())
856       return type_system_sp->GetNumDirectBaseClasses(m_type);
857   return 0;
858 }
859 
860 uint32_t CompilerType::GetNumVirtualBaseClasses() const {
861   if (IsValid())
862     if (auto type_system_sp = GetTypeSystem())
863       return type_system_sp->GetNumVirtualBaseClasses(m_type);
864   return 0;
865 }
866 
867 CompilerType
868 CompilerType::GetDirectBaseClassAtIndex(size_t idx,
869                                         uint32_t *bit_offset_ptr) const {
870   if (IsValid())
871     if (auto type_system_sp = GetTypeSystem())
872       return type_system_sp->GetDirectBaseClassAtIndex(m_type, idx,
873                                                     bit_offset_ptr);
874   return CompilerType();
875 }
876 
877 CompilerType
878 CompilerType::GetVirtualBaseClassAtIndex(size_t idx,
879                                          uint32_t *bit_offset_ptr) const {
880   if (IsValid())
881     if (auto type_system_sp = GetTypeSystem())
882       return type_system_sp->GetVirtualBaseClassAtIndex(m_type, idx,
883                                                      bit_offset_ptr);
884   return CompilerType();
885 }
886 
887 CompilerDecl CompilerType::GetStaticFieldWithName(llvm::StringRef name) const {
888   if (IsValid())
889     return GetTypeSystem()->GetStaticFieldWithName(m_type, name);
890   return CompilerDecl();
891 }
892 
893 uint32_t CompilerType::GetIndexOfFieldWithName(
894     const char *name, CompilerType *field_compiler_type_ptr,
895     uint64_t *bit_offset_ptr, uint32_t *bitfield_bit_size_ptr,
896     bool *is_bitfield_ptr) const {
897   unsigned count = GetNumFields();
898   std::string field_name;
899   for (unsigned index = 0; index < count; index++) {
900     CompilerType field_compiler_type(
901         GetFieldAtIndex(index, field_name, bit_offset_ptr,
902                         bitfield_bit_size_ptr, is_bitfield_ptr));
903     if (strcmp(field_name.c_str(), name) == 0) {
904       if (field_compiler_type_ptr)
905         *field_compiler_type_ptr = field_compiler_type;
906       return index;
907     }
908   }
909   return UINT32_MAX;
910 }
911 
912 llvm::Expected<CompilerType> CompilerType::GetChildCompilerTypeAtIndex(
913     ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers,
914     bool omit_empty_base_classes, bool ignore_array_bounds,
915     std::string &child_name, uint32_t &child_byte_size,
916     int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size,
917     uint32_t &child_bitfield_bit_offset, bool &child_is_base_class,
918     bool &child_is_deref_of_parent, ValueObject *valobj,
919     uint64_t &language_flags) const {
920   if (IsValid())
921     if (auto type_system_sp = GetTypeSystem())
922       return type_system_sp->GetChildCompilerTypeAtIndex(
923           m_type, exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
924           ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
925           child_bitfield_bit_size, child_bitfield_bit_offset,
926           child_is_base_class, child_is_deref_of_parent, valobj,
927           language_flags);
928   return CompilerType();
929 }
930 
931 // Look for a child member (doesn't include base classes, but it does include
932 // their members) in the type hierarchy. Returns an index path into
933 // "clang_type" on how to reach the appropriate member.
934 //
935 //    class A
936 //    {
937 //    public:
938 //        int m_a;
939 //        int m_b;
940 //    };
941 //
942 //    class B
943 //    {
944 //    };
945 //
946 //    class C :
947 //        public B,
948 //        public A
949 //    {
950 //    };
951 //
952 // If we have a clang type that describes "class C", and we wanted to looked
953 // "m_b" in it:
954 //
955 // With omit_empty_base_classes == false we would get an integer array back
956 // with: { 1,  1 } The first index 1 is the child index for "class A" within
957 // class C The second index 1 is the child index for "m_b" within class A
958 //
959 // With omit_empty_base_classes == true we would get an integer array back
960 // with: { 0,  1 } The first index 0 is the child index for "class A" within
961 // class C (since class B doesn't have any members it doesn't count) The second
962 // index 1 is the child index for "m_b" within class A
963 
964 size_t CompilerType::GetIndexOfChildMemberWithName(
965     llvm::StringRef name, bool omit_empty_base_classes,
966     std::vector<uint32_t> &child_indexes) const {
967   if (IsValid() && !name.empty()) {
968     if (auto type_system_sp = GetTypeSystem())
969       return type_system_sp->GetIndexOfChildMemberWithName(
970         m_type, name, omit_empty_base_classes, child_indexes);
971   }
972   return 0;
973 }
974 
975 CompilerType
976 CompilerType::GetDirectNestedTypeWithName(llvm::StringRef name) const {
977   if (IsValid() && !name.empty()) {
978     if (auto type_system_sp = GetTypeSystem())
979       return type_system_sp->GetDirectNestedTypeWithName(m_type, name);
980   }
981   return CompilerType();
982 }
983 
984 size_t CompilerType::GetNumTemplateArguments(bool expand_pack) const {
985   if (IsValid()) {
986     if (auto type_system_sp = GetTypeSystem())
987       return type_system_sp->GetNumTemplateArguments(m_type, expand_pack);
988   }
989   return 0;
990 }
991 
992 TemplateArgumentKind
993 CompilerType::GetTemplateArgumentKind(size_t idx, bool expand_pack) const {
994   if (IsValid())
995     if (auto type_system_sp = GetTypeSystem())
996       return type_system_sp->GetTemplateArgumentKind(m_type, idx, expand_pack);
997   return eTemplateArgumentKindNull;
998 }
999 
1000 CompilerType CompilerType::GetTypeTemplateArgument(size_t idx,
1001                                                    bool expand_pack) const {
1002   if (IsValid()) {
1003     if (auto type_system_sp = GetTypeSystem())
1004       return type_system_sp->GetTypeTemplateArgument(m_type, idx, expand_pack);
1005   }
1006   return CompilerType();
1007 }
1008 
1009 std::optional<CompilerType::IntegralTemplateArgument>
1010 CompilerType::GetIntegralTemplateArgument(size_t idx, bool expand_pack) const {
1011   if (IsValid())
1012     if (auto type_system_sp = GetTypeSystem())
1013       return type_system_sp->GetIntegralTemplateArgument(m_type, idx, expand_pack);
1014   return std::nullopt;
1015 }
1016 
1017 CompilerType CompilerType::GetTypeForFormatters() const {
1018   if (IsValid())
1019     if (auto type_system_sp = GetTypeSystem())
1020       return type_system_sp->GetTypeForFormatters(m_type);
1021   return CompilerType();
1022 }
1023 
1024 LazyBool CompilerType::ShouldPrintAsOneLiner(ValueObject *valobj) const {
1025   if (IsValid())
1026     if (auto type_system_sp = GetTypeSystem())
1027       return type_system_sp->ShouldPrintAsOneLiner(m_type, valobj);
1028   return eLazyBoolCalculate;
1029 }
1030 
1031 bool CompilerType::IsMeaninglessWithoutDynamicResolution() const {
1032   if (IsValid())
1033     if (auto type_system_sp = GetTypeSystem())
1034       return type_system_sp->IsMeaninglessWithoutDynamicResolution(m_type);
1035   return false;
1036 }
1037 
1038 // Get the index of the child of "clang_type" whose name matches. This function
1039 // doesn't descend into the children, but only looks one level deep and name
1040 // matches can include base class names.
1041 
1042 uint32_t
1043 CompilerType::GetIndexOfChildWithName(llvm::StringRef name,
1044                                       bool omit_empty_base_classes) const {
1045   if (IsValid() && !name.empty()) {
1046     if (auto type_system_sp = GetTypeSystem())
1047       return type_system_sp->GetIndexOfChildWithName(m_type, name,
1048                                                      omit_empty_base_classes);
1049   }
1050   return UINT32_MAX;
1051 }
1052 
1053 // Dumping types
1054 
1055 bool CompilerType::DumpTypeValue(Stream *s, lldb::Format format,
1056                                  const DataExtractor &data,
1057                                  lldb::offset_t byte_offset, size_t byte_size,
1058                                  uint32_t bitfield_bit_size,
1059                                  uint32_t bitfield_bit_offset,
1060                                  ExecutionContextScope *exe_scope) {
1061   if (IsValid())
1062     if (auto type_system_sp = GetTypeSystem())
1063       return type_system_sp->DumpTypeValue(
1064           m_type, *s, format, data, byte_offset, byte_size, bitfield_bit_size,
1065           bitfield_bit_offset, exe_scope);
1066   return false;
1067 }
1068 
1069 void CompilerType::DumpTypeDescription(lldb::DescriptionLevel level) const {
1070   if (IsValid())
1071     if (auto type_system_sp = GetTypeSystem())
1072       type_system_sp->DumpTypeDescription(m_type, level);
1073 }
1074 
1075 void CompilerType::DumpTypeDescription(Stream *s,
1076                                        lldb::DescriptionLevel level) const {
1077   if (IsValid())
1078     if (auto type_system_sp = GetTypeSystem())
1079       type_system_sp->DumpTypeDescription(m_type, *s, level);
1080 }
1081 
1082 #ifndef NDEBUG
1083 LLVM_DUMP_METHOD void CompilerType::dump() const {
1084   if (IsValid())
1085     if (auto type_system_sp = GetTypeSystem())
1086       return type_system_sp->dump(m_type);
1087   llvm::errs() << "<invalid>\n";
1088 }
1089 #endif
1090 
1091 bool CompilerType::GetValueAsScalar(const lldb_private::DataExtractor &data,
1092                                     lldb::offset_t data_byte_offset,
1093                                     size_t data_byte_size, Scalar &value,
1094                                     ExecutionContextScope *exe_scope) const {
1095   if (!IsValid())
1096     return false;
1097 
1098   if (IsAggregateType()) {
1099     return false; // Aggregate types don't have scalar values
1100   } else {
1101     uint64_t count = 0;
1102     lldb::Encoding encoding = GetEncoding(count);
1103 
1104     if (encoding == lldb::eEncodingInvalid || count != 1)
1105       return false;
1106 
1107     std::optional<uint64_t> byte_size = GetByteSize(exe_scope);
1108     // A bit or byte size of 0 is not a bug, but it doesn't make sense to read a
1109     // scalar of zero size.
1110     if (!byte_size || *byte_size == 0)
1111       return false;
1112 
1113     lldb::offset_t offset = data_byte_offset;
1114     switch (encoding) {
1115     case lldb::eEncodingInvalid:
1116       break;
1117     case lldb::eEncodingVector:
1118       break;
1119     case lldb::eEncodingUint:
1120       if (*byte_size <= sizeof(unsigned long long)) {
1121         uint64_t uval64 = data.GetMaxU64(&offset, *byte_size);
1122         if (*byte_size <= sizeof(unsigned int)) {
1123           value = (unsigned int)uval64;
1124           return true;
1125         } else if (*byte_size <= sizeof(unsigned long)) {
1126           value = (unsigned long)uval64;
1127           return true;
1128         } else if (*byte_size <= sizeof(unsigned long long)) {
1129           value = (unsigned long long)uval64;
1130           return true;
1131         } else
1132           value.Clear();
1133       }
1134       break;
1135 
1136     case lldb::eEncodingSint:
1137       if (*byte_size <= sizeof(long long)) {
1138         int64_t sval64 = data.GetMaxS64(&offset, *byte_size);
1139         if (*byte_size <= sizeof(int)) {
1140           value = (int)sval64;
1141           return true;
1142         } else if (*byte_size <= sizeof(long)) {
1143           value = (long)sval64;
1144           return true;
1145         } else if (*byte_size <= sizeof(long long)) {
1146           value = (long long)sval64;
1147           return true;
1148         } else
1149           value.Clear();
1150       }
1151       break;
1152 
1153     case lldb::eEncodingIEEE754:
1154       if (*byte_size <= sizeof(long double)) {
1155         uint32_t u32;
1156         uint64_t u64;
1157         if (*byte_size == sizeof(float)) {
1158           if (sizeof(float) == sizeof(uint32_t)) {
1159             u32 = data.GetU32(&offset);
1160             value = *((float *)&u32);
1161             return true;
1162           } else if (sizeof(float) == sizeof(uint64_t)) {
1163             u64 = data.GetU64(&offset);
1164             value = *((float *)&u64);
1165             return true;
1166           }
1167         } else if (*byte_size == sizeof(double)) {
1168           if (sizeof(double) == sizeof(uint32_t)) {
1169             u32 = data.GetU32(&offset);
1170             value = *((double *)&u32);
1171             return true;
1172           } else if (sizeof(double) == sizeof(uint64_t)) {
1173             u64 = data.GetU64(&offset);
1174             value = *((double *)&u64);
1175             return true;
1176           }
1177         } else if (*byte_size == sizeof(long double)) {
1178           if (sizeof(long double) == sizeof(uint32_t)) {
1179             u32 = data.GetU32(&offset);
1180             value = *((long double *)&u32);
1181             return true;
1182           } else if (sizeof(long double) == sizeof(uint64_t)) {
1183             u64 = data.GetU64(&offset);
1184             value = *((long double *)&u64);
1185             return true;
1186           }
1187         }
1188       }
1189       break;
1190     }
1191   }
1192   return false;
1193 }
1194 
1195 CompilerType::CompilerType(CompilerType::TypeSystemSPWrapper type_system,
1196                            lldb::opaque_compiler_type_t type)
1197     : m_type_system(type_system.GetSharedPointer()), m_type(type) {
1198   assert(Verify() && "verification failed");
1199 }
1200 
1201 CompilerType::CompilerType(lldb::TypeSystemWP type_system,
1202                            lldb::opaque_compiler_type_t type)
1203     : m_type_system(type_system), m_type(type) {
1204   assert(Verify() && "verification failed");
1205 }
1206 
1207 #ifndef NDEBUG
1208 bool CompilerType::Verify() const {
1209   if (!IsValid())
1210     return true;
1211   if (auto type_system_sp = GetTypeSystem())
1212     return type_system_sp->Verify(m_type);
1213   return true;
1214 }
1215 #endif
1216 
1217 CompilerType::TypeSystemSPWrapper CompilerType::GetTypeSystem() const {
1218   return {m_type_system.lock()};
1219 }
1220 
1221 bool CompilerType::TypeSystemSPWrapper::operator==(
1222     const CompilerType::TypeSystemSPWrapper &other) const {
1223   if (!m_typesystem_sp && !other.m_typesystem_sp)
1224     return true;
1225   if (m_typesystem_sp && other.m_typesystem_sp)
1226     return m_typesystem_sp.get() == other.m_typesystem_sp.get();
1227   return false;
1228 }
1229 
1230 TypeSystem *CompilerType::TypeSystemSPWrapper::operator->() const {
1231   assert(m_typesystem_sp);
1232   return m_typesystem_sp.get();
1233 }
1234 
1235 bool lldb_private::operator==(const lldb_private::CompilerType &lhs,
1236                               const lldb_private::CompilerType &rhs) {
1237   return lhs.GetTypeSystem() == rhs.GetTypeSystem() &&
1238          lhs.GetOpaqueQualType() == rhs.GetOpaqueQualType();
1239 }
1240 
1241 bool lldb_private::operator!=(const lldb_private::CompilerType &lhs,
1242                               const lldb_private::CompilerType &rhs) {
1243   return !(lhs == rhs);
1244 }
1245