LLDB mainline
CompilerType.cpp
Go to the documentation of this file.
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
10
11#include "lldb/Core/Debugger.h"
12#include "lldb/Symbol/Type.h"
14#include "lldb/Target/Process.h"
19#include "lldb/Utility/Log.h"
20#include "lldb/Utility/Scalar.h"
21#include "lldb/Utility/Stream.h"
24
25#include <iterator>
26#include <mutex>
27#include <optional>
28
29using namespace lldb;
30using namespace lldb_private;
31
32// Tests
33
35 if (IsValid())
36 if (auto type_system_sp = GetTypeSystem())
37 return type_system_sp->IsAggregateType(m_type);
38 return false;
39}
40
42 if (IsValid())
43 if (auto type_system_sp = GetTypeSystem())
44 return type_system_sp->IsAnonymousType(m_type);
45 return false;
46}
47
49 if (IsValid())
50 if (auto type_system_sp = GetTypeSystem())
51 return type_system_sp->IsScopedEnumerationType(m_type);
52 return false;
53}
54
55bool CompilerType::IsArrayType(CompilerType *element_type_ptr, uint64_t *size,
56 bool *is_incomplete) const {
57 if (IsValid())
58 if (auto type_system_sp = GetTypeSystem())
59 return type_system_sp->IsArrayType(m_type, element_type_ptr, size,
60 is_incomplete);
61
62 if (element_type_ptr)
63 element_type_ptr->Clear();
64 if (size)
65 *size = 0;
66 if (is_incomplete)
67 *is_incomplete = false;
68 return false;
69}
70
72 uint64_t *size) const {
73 if (IsValid())
74 if (auto type_system_sp = GetTypeSystem())
75 return type_system_sp->IsVectorType(m_type, element_type, size);
76 return false;
77}
78
80 if (IsValid())
81 if (auto type_system_sp = GetTypeSystem())
82 return type_system_sp->IsRuntimeGeneratedType(m_type);
83 return false;
84}
85
87 if (IsValid())
88 if (auto type_system_sp = GetTypeSystem())
89 return type_system_sp->IsCharType(m_type);
90 return false;
91}
92
94 if (IsValid())
95 if (auto type_system_sp = GetTypeSystem())
96 return type_system_sp->IsCompleteType(m_type);
97 return false;
98}
99
101 if (IsValid())
102 if (auto type_system_sp = GetTypeSystem())
103 return type_system_sp->IsForcefullyCompleted(m_type);
104 return false;
105}
106
108 if (IsValid())
109 if (auto type_system_sp = GetTypeSystem())
110 return type_system_sp->IsConst(m_type);
111 return false;
112}
113
115 if (IsValid())
116 if (auto type_system_sp = GetTypeSystem())
117 return type_system_sp->GetPtrAuthKey(m_type);
118 return 0;
119}
120
122 if (IsValid())
123 if (auto type_system_sp = GetTypeSystem())
124 return type_system_sp->GetPtrAuthDiscriminator(m_type);
125 return 0;
126}
127
129 if (IsValid())
130 if (auto type_system_sp = GetTypeSystem())
131 return type_system_sp->GetPtrAuthAddressDiversity(m_type);
132 return false;
133}
134
136 if (IsValid())
137 if (auto type_system_sp = GetTypeSystem())
138 return type_system_sp->IsFunctionType(m_type);
139 return false;
140}
141
142// Used to detect "Homogeneous Floating-point Aggregates"
143uint32_t
145 if (IsValid())
146 if (auto type_system_sp = GetTypeSystem())
147 return type_system_sp->IsHomogeneousAggregate(m_type, base_type_ptr);
148 return 0;
149}
150
152 if (IsValid())
153 if (auto type_system_sp = GetTypeSystem())
154 return type_system_sp->GetNumberOfFunctionArguments(m_type);
155 return 0;
156}
157
160 if (IsValid())
161 if (auto type_system_sp = GetTypeSystem())
162 return type_system_sp->GetFunctionArgumentAtIndex(m_type, index);
163 return CompilerType();
164}
165
167 if (IsValid())
168 if (auto type_system_sp = GetTypeSystem())
169 return type_system_sp->IsFunctionPointerType(m_type);
170 return false;
171}
172
174 if (IsValid())
175 if (auto type_system_sp = GetTypeSystem())
176 return type_system_sp->IsMemberFunctionPointerType(m_type);
177 return false;
178}
179
181 CompilerType *function_pointer_type_ptr) const {
182 if (IsValid())
183 if (auto type_system_sp = GetTypeSystem())
184 return type_system_sp->IsBlockPointerType(m_type, function_pointer_type_ptr);
185 return false;
186}
187
188bool CompilerType::IsIntegerType(bool &is_signed) const {
189 if (IsValid())
190 if (auto type_system_sp = GetTypeSystem())
191 return type_system_sp->IsIntegerType(m_type, is_signed);
192 return false;
193}
194
195bool CompilerType::IsEnumerationType(bool &is_signed) const {
196 if (IsValid())
197 if (auto type_system_sp = GetTypeSystem())
198 return type_system_sp->IsEnumerationType(m_type, is_signed);
199 return false;
200}
201
202bool CompilerType::IsIntegerOrEnumerationType(bool &is_signed) const {
203 return IsIntegerType(is_signed) || IsEnumerationType(is_signed);
204}
205
206bool CompilerType::IsPointerType(CompilerType *pointee_type) const {
207 if (IsValid()) {
208 if (auto type_system_sp = GetTypeSystem())
209 return type_system_sp->IsPointerType(m_type, pointee_type);
210 }
211 if (pointee_type)
212 pointee_type->Clear();
213 return false;
214}
215
217 if (IsValid()) {
218 if (auto type_system_sp = GetTypeSystem())
219 return type_system_sp->IsPointerOrReferenceType(m_type, pointee_type);
220 }
221 if (pointee_type)
222 pointee_type->Clear();
223 return false;
224}
225
227 bool *is_rvalue) const {
228 if (IsValid()) {
229 if (auto type_system_sp = GetTypeSystem())
230 return type_system_sp->IsReferenceType(m_type, pointee_type, is_rvalue);
231 }
232 if (pointee_type)
233 pointee_type->Clear();
234 return false;
235}
236
238 if (IsValid())
239 if (auto type_system_sp = GetTypeSystem())
240 return type_system_sp->ShouldTreatScalarValueAsAddress(m_type);
241 return false;
242}
243
245 return GetTypeClass() & eTypeClassComplexFloat ||
246 GetTypeClass() & eTypeClassComplexInteger;
247}
248
250 if (IsValid())
251 if (auto type_system_sp = GetTypeSystem())
252 return type_system_sp->IsFloatingPointType(m_type);
253
254 return false;
255}
256
260
262 if (IsValid())
263 if (auto type_system_sp = GetTypeSystem())
264 return type_system_sp->IsDefined(m_type);
265 return true;
266}
267
269 if (IsValid()) {
270 if (auto type_system_sp = GetTypeSystem())
271 return type_system_sp->IsPolymorphicClass(m_type);
272 }
273 return false;
274}
275
277 bool check_cplusplus,
278 bool check_objc) const {
279 if (IsValid())
280 if (auto type_system_sp = GetTypeSystem())
281 return type_system_sp->IsPossibleDynamicType(m_type, dynamic_pointee_type,
282 check_cplusplus, check_objc);
283 return false;
284}
285
287 if (IsValid())
288 if (auto type_system_sp = GetTypeSystem())
289 return type_system_sp->IsScalarType(m_type);
290 return false;
291}
292
294 if (IsValid())
295 if (auto type_system_sp = GetTypeSystem())
296 return type_system_sp->IsTemplateType(m_type);
297 return false;
298}
299
301 if (IsValid())
302 if (auto type_system_sp = GetTypeSystem())
303 return type_system_sp->IsTypedefType(m_type);
304 return false;
305}
306
308 if (IsValid())
309 if (auto type_system_sp = GetTypeSystem())
310 return type_system_sp->IsVoidType(m_type);
311 return false;
312}
313
315 if (!IsValid())
316 return false;
317
319}
320
322 CompilerType element_type;
323 if (IsArrayType(&element_type))
324 return element_type.IsScalarType();
325 return false;
326}
327
329 if (IsValid())
330 if (auto type_system_sp = GetTypeSystem())
331 return type_system_sp->IsBeingDefined(m_type);
332 return false;
333}
334
336 bool is_signed = false; // May be reset by the call below.
337 return IsIntegerType(is_signed);
338}
339
341 bool is_signed = false; // May be reset by the call below.
342 return IsEnumerationType(is_signed);
343}
344
348
352
354 return GetTypeInfo() & lldb::eTypeIsSigned;
355}
356
360
364
366 if (IsValid())
367 return GetEnumerationIntegerType().GetTypeInfo() & lldb::eTypeIsSigned;
368
369 return false;
370}
371
375
377 if (IsValid())
378 if (auto type_system_sp = GetTypeSystem())
379 return type_system_sp->IsPromotableIntegerType(m_type);
380 return false;
381}
382
384 if (!IsValid())
385 return false;
386
387 return IsPointerType() &&
389}
390
392 if (!IsValid())
393 return false;
394
395 return GetCanonicalType().GetTypeClass() &
396 (lldb::eTypeClassClass | lldb::eTypeClassStruct |
397 lldb::eTypeClassUnion);
398}
399
401 CompilerType *virtual_base,
402 bool carry_virtual) const {
403 if (CompareTypes(target_base))
404 return carry_virtual;
405
406 if (!carry_virtual) {
407 uint32_t num_virtual_bases = GetNumVirtualBaseClasses();
408 for (uint32_t i = 0; i < num_virtual_bases; ++i) {
409 uint32_t bit_offset;
410 auto base = GetVirtualBaseClassAtIndex(i, &bit_offset);
411 if (base.IsVirtualBase(target_base, virtual_base,
412 /*carry_virtual*/ true)) {
413 if (virtual_base)
414 *virtual_base = base;
415
416 return true;
417 }
418 }
419 }
420
421 uint32_t num_direct_bases = GetNumDirectBaseClasses();
422 for (uint32_t i = 0; i < num_direct_bases; ++i) {
423 uint32_t bit_offset;
424 auto base = GetDirectBaseClassAtIndex(i, &bit_offset);
425 if (base.IsVirtualBase(target_base, virtual_base, carry_virtual))
426 return true;
427 }
428
429 return false;
430}
431
436
440
442 auto name = GetTypeName();
443 auto canonical_name = GetCanonicalType().GetTypeName();
444 if (name.IsEmpty() || canonical_name.IsEmpty())
445 return "''"; // Should not happen, unless the input is broken somehow.
446
447 if (name == canonical_name)
448 return llvm::formatv("'{0}'", name);
449
450 return llvm::formatv("'{0}' (canonically referred to as '{1}')", name,
451 canonical_name);
452}
453
455 if (*this == rhs)
456 return true;
457
459 const ConstString rhs_name = rhs.GetFullyUnqualifiedType().GetTypeName();
460 return name == rhs_name;
461}
462
464 switch (GetTypeClass()) {
465 case lldb::eTypeClassClass:
466 return "class";
467 case lldb::eTypeClassEnumeration:
468 return "enum";
469 case lldb::eTypeClassStruct:
470 return "struct";
471 case lldb::eTypeClassUnion:
472 return "union";
473 default:
474 return "unknown";
475 }
476 llvm_unreachable("All cases are covered by code above.");
477}
478
480 uint32_t ret = 0;
481 uint32_t num_direct_bases = GetNumDirectBaseClasses();
482
483 for (uint32_t i = 0; i < num_direct_bases; ++i) {
484 uint32_t bit_offset;
485 CompilerType base_type = GetDirectBaseClassAtIndex(i, &bit_offset);
486 if (base_type.GetNumFields() > 0 ||
487 base_type.GetNumberOfNonEmptyBaseClasses() > 0)
488 ret += 1;
489 }
490 return ret;
491}
492
493// Type Completion
494
496 if (IsValid())
497 if (auto type_system_sp = GetTypeSystem())
498 return type_system_sp->GetCompleteType(m_type);
499 return false;
500}
501
502// AST related queries
504 if (auto type_system_sp = GetTypeSystem())
505 return type_system_sp->GetPointerByteSize();
506 return 0;
507}
508
510 if (IsValid()) {
511 if (auto type_system_sp = GetTypeSystem())
512 return type_system_sp->GetTypeName(m_type, BaseOnly);
513 }
514 return ConstString("<invalid>");
515}
516
518 if (IsValid())
519 if (auto type_system_sp = GetTypeSystem())
520 return type_system_sp->GetDisplayTypeName(m_type);
521 return ConstString("<invalid>");
522}
523
525 if (IsValid()) {
526 if (auto type_system_sp = GetTypeSystem())
527 return type_system_sp->GetMangledTypeName(m_type);
528 }
529 return ConstString("<invalid>");
530}
531
533 CompilerType *pointee_or_element_compiler_type) const {
534 if (IsValid())
535 if (auto type_system_sp = GetTypeSystem())
536 return type_system_sp->GetTypeInfo(m_type,
537 pointee_or_element_compiler_type);
538 return 0;
539}
540
542 if (IsValid())
543 if (auto type_system_sp = GetTypeSystem())
544 return type_system_sp->GetMinimumLanguage(m_type);
546}
547
548lldb::TypeClass CompilerType::GetTypeClass() const {
549 if (IsValid())
550 if (auto type_system_sp = GetTypeSystem())
551 return type_system_sp->GetTypeClass(m_type);
552 return lldb::eTypeClassInvalid;
553}
554
557 m_type_system = type_system;
558 m_type = type;
559}
560
566
568 if (IsValid())
569 if (auto type_system_sp = GetTypeSystem())
570 return type_system_sp->GetTypeQualifiers(m_type);
571 return 0;
572}
573
574// Creating related types
575
578 if (IsValid()) {
579 if (auto type_system_sp = GetTypeSystem())
580 return type_system_sp->GetArrayElementType(m_type, exe_scope);
581 }
582 return CompilerType();
583}
584
586 if (IsValid()) {
587 if (auto type_system_sp = GetTypeSystem())
588 return type_system_sp->GetArrayType(m_type, size);
589 }
590 return CompilerType();
591}
592
594 if (IsValid())
595 if (auto type_system_sp = GetTypeSystem())
596 return type_system_sp->GetCanonicalType(m_type);
597 return CompilerType();
598}
599
601 if (IsValid())
602 if (auto type_system_sp = GetTypeSystem())
603 return type_system_sp->GetFullyUnqualifiedType(m_type);
604 return CompilerType();
605}
606
608 if (IsValid())
609 if (auto type_system_sp = GetTypeSystem())
610 return type_system_sp->GetEnumerationIntegerType(m_type);
611 return CompilerType();
612}
613
615 if (IsValid()) {
616 if (auto type_system_sp = GetTypeSystem())
617 return type_system_sp->GetFunctionArgumentCount(m_type);
618 }
619 return -1;
620}
621
623 if (IsValid()) {
624 if (auto type_system_sp = GetTypeSystem())
625 return type_system_sp->GetFunctionArgumentTypeAtIndex(m_type, idx);
626 }
627 return CompilerType();
628}
629
631 if (IsValid()) {
632 if (auto type_system_sp = GetTypeSystem())
633 return type_system_sp->GetFunctionReturnType(m_type);
634 }
635 return CompilerType();
636}
637
639 if (IsValid()) {
640 if (auto type_system_sp = GetTypeSystem())
641 return type_system_sp->GetNumMemberFunctions(m_type);
642 }
643 return 0;
644}
645
647 if (IsValid()) {
648 if (auto type_system_sp = GetTypeSystem())
649 return type_system_sp->GetMemberFunctionAtIndex(m_type, idx);
650 }
651 return TypeMemberFunctionImpl();
652}
653
655 if (IsValid())
656 if (auto type_system_sp = GetTypeSystem())
657 return type_system_sp->GetNonReferenceType(m_type);
658 return CompilerType();
659}
660
662 if (IsValid()) {
663 if (auto type_system_sp = GetTypeSystem())
664 return type_system_sp->GetPointeeType(m_type);
665 }
666 return CompilerType();
667}
668
670 if (IsValid()) {
671 if (auto type_system_sp = GetTypeSystem())
672 return type_system_sp->GetPointerType(m_type);
673 }
674 return CompilerType();
675}
676
678 if (IsValid())
679 if (auto type_system_sp = GetTypeSystem())
680 return type_system_sp->AddPtrAuthModifier(m_type, payload);
681 return CompilerType();
682}
683
685 if (IsValid())
686 if (auto type_system_sp = GetTypeSystem())
687 return type_system_sp->GetLValueReferenceType(m_type);
688 return CompilerType();
689}
690
692 if (IsValid())
693 if (auto type_system_sp = GetTypeSystem())
694 return type_system_sp->GetRValueReferenceType(m_type);
695 return CompilerType();
696}
697
699 if (IsValid())
700 if (auto type_system_sp = GetTypeSystem())
701 return type_system_sp->GetAtomicType(m_type);
702 return CompilerType();
703}
704
706 if (IsValid())
707 if (auto type_system_sp = GetTypeSystem())
708 return type_system_sp->AddConstModifier(m_type);
709 return CompilerType();
710}
711
713 if (IsValid())
714 if (auto type_system_sp = GetTypeSystem())
715 return type_system_sp->AddVolatileModifier(m_type);
716 return CompilerType();
717}
718
720 if (IsValid())
721 if (auto type_system_sp = GetTypeSystem())
722 return type_system_sp->AddRestrictModifier(m_type);
723 return CompilerType();
724}
725
727 const CompilerDeclContext &decl_ctx,
728 uint32_t payload) const {
729 if (IsValid())
730 if (auto type_system_sp = GetTypeSystem())
731 return type_system_sp->CreateTypedef(m_type, name, decl_ctx, payload);
732 return CompilerType();
733}
734
736 if (IsValid())
737 if (auto type_system_sp = GetTypeSystem())
738 return type_system_sp->GetTypedefedType(m_type);
739 return CompilerType();
740}
741
742// Create related types using the current type's AST
743
746 if (IsValid())
747 if (auto type_system_sp = GetTypeSystem())
748 return type_system_sp->GetBasicTypeFromAST(basic_type);
749 return CompilerType();
750}
751// Exploring the type
752
753llvm::Expected<uint64_t>
755 if (IsValid())
756 if (auto type_system_sp = GetTypeSystem())
757 return type_system_sp->GetBitSize(m_type, exe_scope);
758 return llvm::createStringError("Invalid type: Cannot determine size");
759}
760
761llvm::Expected<uint64_t>
763 auto bit_size_or_err = GetBitSize(exe_scope);
764 if (!bit_size_or_err)
765 return bit_size_or_err.takeError();
766 return (*bit_size_or_err + 7) / 8;
767}
768
769std::optional<size_t>
771 if (IsValid())
772 if (auto type_system_sp = GetTypeSystem())
773 return type_system_sp->GetTypeBitAlign(m_type, exe_scope);
774 return {};
775}
776
778 if (IsValid())
779 if (auto type_system_sp = GetTypeSystem())
780 return type_system_sp->GetEncoding(m_type);
782}
783
785 if (IsValid())
786 if (auto type_system_sp = GetTypeSystem())
787 return type_system_sp->GetFormat(m_type);
789}
790
791llvm::Expected<uint32_t>
792CompilerType::GetNumChildren(bool omit_empty_base_classes,
793 const ExecutionContext *exe_ctx) const {
794 if (IsValid())
795 if (auto type_system_sp = GetTypeSystem())
796 return type_system_sp->GetNumChildren(m_type, omit_empty_base_classes,
797 exe_ctx);
798 return llvm::createStringError("invalid type");
799}
800
802 if (IsValid())
803 if (auto type_system_sp = GetTypeSystem())
804 return type_system_sp->GetBasicTypeEnumeration(m_type);
805 return eBasicTypeInvalid;
806}
807
809 std::function<bool(const CompilerType &integer_type,
810 ConstString name,
811 const llvm::APSInt &value)> const &callback) const {
812 if (IsValid())
813 if (auto type_system_sp = GetTypeSystem())
814 return type_system_sp->ForEachEnumerator(m_type, callback);
815}
816
818 if (IsValid())
819 if (auto type_system_sp = GetTypeSystem())
820 return type_system_sp->GetNumFields(m_type);
821 return 0;
822}
823
824CompilerType CompilerType::GetFieldAtIndex(size_t idx, std::string &name,
825 uint64_t *bit_offset_ptr,
826 uint32_t *bitfield_bit_size_ptr,
827 bool *is_bitfield_ptr) const {
828 if (IsValid())
829 if (auto type_system_sp = GetTypeSystem())
830 return type_system_sp->GetFieldAtIndex(m_type, idx, name, bit_offset_ptr,
831 bitfield_bit_size_ptr, is_bitfield_ptr);
832 return CompilerType();
833}
834
836 if (IsValid())
837 if (auto type_system_sp = GetTypeSystem())
838 return type_system_sp->GetNumDirectBaseClasses(m_type);
839 return 0;
840}
841
843 if (IsValid())
844 if (auto type_system_sp = GetTypeSystem())
845 return type_system_sp->GetNumVirtualBaseClasses(m_type);
846 return 0;
847}
848
851 uint32_t *bit_offset_ptr) const {
852 if (IsValid())
853 if (auto type_system_sp = GetTypeSystem())
854 return type_system_sp->GetDirectBaseClassAtIndex(m_type, idx,
855 bit_offset_ptr);
856 return CompilerType();
857}
858
861 uint32_t *bit_offset_ptr) const {
862 if (IsValid())
863 if (auto type_system_sp = GetTypeSystem())
864 return type_system_sp->GetVirtualBaseClassAtIndex(m_type, idx,
865 bit_offset_ptr);
866 return CompilerType();
867}
868
870 if (IsValid())
872 return CompilerDecl();
873}
874
875llvm::Expected<CompilerType> CompilerType::GetDereferencedType(
876 ExecutionContext *exe_ctx, std::string &deref_name,
877 uint32_t &deref_byte_size, int32_t &deref_byte_offset, ValueObject *valobj,
878 uint64_t &language_flags) const {
879 if (IsValid())
880 if (auto type_system_sp = GetTypeSystem())
881 return type_system_sp->GetDereferencedType(
882 m_type, exe_ctx, deref_name, deref_byte_size, deref_byte_offset,
883 valobj, language_flags);
884 return CompilerType();
885}
886
887llvm::Expected<CompilerType> CompilerType::GetChildCompilerTypeAtIndex(
888 ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers,
889 bool omit_empty_base_classes, bool ignore_array_bounds,
890 std::string &child_name, uint32_t &child_byte_size,
891 int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size,
892 uint32_t &child_bitfield_bit_offset, bool &child_is_base_class,
893 bool &child_is_deref_of_parent, ValueObject *valobj,
894 uint64_t &language_flags) const {
895 if (IsValid())
896 if (auto type_system_sp = GetTypeSystem())
897 return type_system_sp->GetChildCompilerTypeAtIndex(
898 m_type, exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
899 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
900 child_bitfield_bit_size, child_bitfield_bit_offset,
901 child_is_base_class, child_is_deref_of_parent, valobj,
902 language_flags);
903 return CompilerType();
904}
905
906// Look for a child member (doesn't include base classes, but it does include
907// their members) in the type hierarchy. Returns an index path into
908// "clang_type" on how to reach the appropriate member.
909//
910// class A
911// {
912// public:
913// int m_a;
914// int m_b;
915// };
916//
917// class B
918// {
919// };
920//
921// class C :
922// public B,
923// public A
924// {
925// };
926//
927// If we have a clang type that describes "class C", and we wanted to looked
928// "m_b" in it:
929//
930// With omit_empty_base_classes == false we would get an integer array back
931// with: { 1, 1 } The first index 1 is the child index for "class A" within
932// class C The second index 1 is the child index for "m_b" within class A
933//
934// With omit_empty_base_classes == true we would get an integer array back
935// with: { 0, 1 } The first index 0 is the child index for "class A" within
936// class C (since class B doesn't have any members it doesn't count) The second
937// index 1 is the child index for "m_b" within class A
938
940 llvm::StringRef name, bool omit_empty_base_classes,
941 std::vector<uint32_t> &child_indexes) const {
942 if (IsValid() && !name.empty()) {
943 if (auto type_system_sp = GetTypeSystem())
944 return type_system_sp->GetIndexOfChildMemberWithName(
945 m_type, name, omit_empty_base_classes, child_indexes);
946 }
947 return 0;
948}
949
951CompilerType::GetDirectNestedTypeWithName(llvm::StringRef name) const {
952 if (IsValid() && !name.empty()) {
953 if (auto type_system_sp = GetTypeSystem())
954 return type_system_sp->GetDirectNestedTypeWithName(m_type, name);
955 }
956 return CompilerType();
957}
958
959size_t CompilerType::GetNumTemplateArguments(bool expand_pack) const {
960 if (IsValid()) {
961 if (auto type_system_sp = GetTypeSystem())
962 return type_system_sp->GetNumTemplateArguments(m_type, expand_pack);
963 }
964 return 0;
965}
966
968CompilerType::GetTemplateArgumentKind(size_t idx, bool expand_pack) const {
969 if (IsValid())
970 if (auto type_system_sp = GetTypeSystem())
971 return type_system_sp->GetTemplateArgumentKind(m_type, idx, expand_pack);
973}
974
976 bool expand_pack) const {
977 if (IsValid()) {
978 if (auto type_system_sp = GetTypeSystem())
979 return type_system_sp->GetTypeTemplateArgument(m_type, idx, expand_pack);
980 }
981 return CompilerType();
982}
983
984std::optional<CompilerType::IntegralTemplateArgument>
985CompilerType::GetIntegralTemplateArgument(size_t idx, bool expand_pack) const {
986 if (IsValid())
987 if (auto type_system_sp = GetTypeSystem())
988 return type_system_sp->GetIntegralTemplateArgument(m_type, idx, expand_pack);
989 return std::nullopt;
990}
991
993 if (IsValid())
994 if (auto type_system_sp = GetTypeSystem())
995 return type_system_sp->GetTypeForFormatters(m_type);
996 return CompilerType();
997}
998
1000 if (IsValid())
1001 if (auto type_system_sp = GetTypeSystem())
1002 return type_system_sp->ShouldPrintAsOneLiner(m_type, valobj);
1003 return eLazyBoolCalculate;
1004}
1005
1007 if (IsValid())
1008 if (auto type_system_sp = GetTypeSystem())
1009 return type_system_sp->IsMeaninglessWithoutDynamicResolution(m_type);
1010 return false;
1011}
1012
1013// Get the index of the child of "clang_type" whose name matches. This function
1014// doesn't descend into the children, but only looks one level deep and name
1015// matches can include base class names.
1016
1017llvm::Expected<uint32_t>
1019 bool omit_empty_base_classes) const {
1020 if (IsValid() && !name.empty()) {
1021 if (auto type_system_sp = GetTypeSystem())
1022 return type_system_sp->GetIndexOfChildWithName(m_type, name,
1023 omit_empty_base_classes);
1024 }
1025 return llvm::createStringError("Type has no child named '%s'",
1026 name.str().c_str());
1027}
1028
1029// Dumping types
1030
1032 const DataExtractor &data,
1033 lldb::offset_t byte_offset, size_t byte_size,
1034 uint32_t bitfield_bit_size,
1035 uint32_t bitfield_bit_offset,
1036 ExecutionContextScope *exe_scope) {
1037 if (IsValid())
1038 if (auto type_system_sp = GetTypeSystem())
1039 return type_system_sp->DumpTypeValue(
1040 m_type, *s, format, data, byte_offset, byte_size, bitfield_bit_size,
1041 bitfield_bit_offset, exe_scope);
1042 return false;
1043}
1044
1046 if (IsValid())
1047 if (auto type_system_sp = GetTypeSystem())
1048 type_system_sp->DumpTypeDescription(m_type, level);
1049}
1050
1052 lldb::DescriptionLevel level) const {
1053 if (IsValid())
1054 if (auto type_system_sp = GetTypeSystem())
1055 type_system_sp->DumpTypeDescription(m_type, *s, level);
1056}
1057
1058#ifndef NDEBUG
1059LLVM_DUMP_METHOD void CompilerType::dump() const {
1060 if (IsValid())
1061 if (auto type_system_sp = GetTypeSystem())
1062 return type_system_sp->dump(m_type);
1063 llvm::errs() << "<invalid>\n";
1064}
1065#endif
1066
1068 lldb::offset_t data_byte_offset,
1069 size_t data_byte_size, Scalar &value,
1070 ExecutionContextScope *exe_scope) const {
1071 if (!IsValid())
1072 return false;
1073
1074 if (IsAggregateType()) {
1075 return false; // Aggregate types don't have scalar values
1076 } else {
1077 // FIXME: check that type is scalar instead of checking encoding?
1078 lldb::Encoding encoding = GetEncoding();
1079
1080 if (encoding == lldb::eEncodingInvalid || (GetTypeInfo() & eTypeIsComplex))
1081 return false;
1082
1083 auto byte_size_or_err = GetByteSize(exe_scope);
1084 if (!byte_size_or_err) {
1086 GetLog(LLDBLog::Types), byte_size_or_err.takeError(),
1087 "Cannot get value as scalar: Cannot determine type size: {0}");
1088 return false;
1089 }
1090 uint64_t byte_size = *byte_size_or_err;
1091
1092 // A bit or byte size of 0 is not a bug, but it doesn't make sense to read a
1093 // scalar of zero size.
1094 if (byte_size == 0)
1095 return false;
1096
1097 lldb::offset_t offset = data_byte_offset;
1098 switch (encoding) {
1100 break;
1102 break;
1104 if (byte_size <= sizeof(unsigned long long)) {
1105 uint64_t uval64 = data.GetMaxU64(&offset, byte_size);
1106 if (byte_size <= sizeof(unsigned int)) {
1107 value = (unsigned int)uval64;
1108 return true;
1109 } else if (byte_size <= sizeof(unsigned long)) {
1110 value = (unsigned long)uval64;
1111 return true;
1112 } else if (byte_size <= sizeof(unsigned long long)) {
1113 value = (unsigned long long)uval64;
1114 return true;
1115 } else
1116 value.Clear();
1117 }
1118 break;
1119
1121 if (byte_size <= sizeof(long long)) {
1122 int64_t sval64 = data.GetMaxS64(&offset, byte_size);
1123 if (byte_size <= sizeof(int)) {
1124 value = (int)sval64;
1125 return true;
1126 } else if (byte_size <= sizeof(long)) {
1127 value = (long)sval64;
1128 return true;
1129 } else if (byte_size <= sizeof(long long)) {
1130 value = (long long)sval64;
1131 return true;
1132 } else
1133 value.Clear();
1134 }
1135 break;
1136
1138 if (byte_size <= sizeof(long double)) {
1139 uint32_t u32;
1140 uint64_t u64;
1141 if (byte_size == sizeof(float)) {
1142 if (sizeof(float) == sizeof(uint32_t)) {
1143 u32 = data.GetU32(&offset);
1144 value = *((float *)&u32);
1145 return true;
1146 } else if (sizeof(float) == sizeof(uint64_t)) {
1147 u64 = data.GetU64(&offset);
1148 value = *((float *)&u64);
1149 return true;
1150 }
1151 } else if (byte_size == sizeof(double)) {
1152 if (sizeof(double) == sizeof(uint32_t)) {
1153 u32 = data.GetU32(&offset);
1154 value = *((double *)&u32);
1155 return true;
1156 } else if (sizeof(double) == sizeof(uint64_t)) {
1157 u64 = data.GetU64(&offset);
1158 value = *((double *)&u64);
1159 return true;
1160 }
1161 } else if (byte_size == sizeof(long double)) {
1162 if (sizeof(long double) == sizeof(uint32_t)) {
1163 u32 = data.GetU32(&offset);
1164 value = *((long double *)&u32);
1165 return true;
1166 } else if (sizeof(long double) == sizeof(uint64_t)) {
1167 u64 = data.GetU64(&offset);
1168 value = *((long double *)&u64);
1169 return true;
1170 }
1171 }
1172 }
1173 break;
1174 }
1175 }
1176 return false;
1177}
1178
1181 : m_type_system(type_system.GetSharedPointer()), m_type(type) {
1182 assert(Verify() && "verification failed");
1183}
1184
1187 : m_type_system(type_system), m_type(type) {
1188 assert(Verify() && "verification failed");
1189}
1190
1191#ifndef NDEBUG
1193 if (!IsValid())
1194 return true;
1195 if (auto type_system_sp = GetTypeSystem())
1196 return type_system_sp->Verify(m_type);
1197 return true;
1198}
1199#endif
1200
1204
1206 const CompilerType::TypeSystemSPWrapper &other) const {
1207 if (!m_typesystem_sp && !other.m_typesystem_sp)
1208 return true;
1209 if (m_typesystem_sp && other.m_typesystem_sp)
1210 return m_typesystem_sp.get() == other.m_typesystem_sp.get();
1211 return false;
1212}
1213
1218
1220 const lldb_private::CompilerType &rhs) {
1221 return lhs.GetTypeSystem() == rhs.GetTypeSystem() &&
1222 lhs.GetOpaqueQualType() == rhs.GetOpaqueQualType();
1223}
1224
1226 const lldb_private::CompilerType &rhs) {
1227 return !(lhs == rhs);
1228}
#define LLDB_LOG_ERRORV(log, error,...)
Definition Log.h:408
Represents a generic declaration context in a program.
Represents a generic declaration such as a function declaration.
This is a minimal wrapper of a TypeSystem shared pointer as returned by CompilerType which conventien...
bool operator==(const TypeSystemSPWrapper &other) const
TypeSystem * operator->() const
Only to be used in a one-off situations like if (typesystem && typesystem->method()) Do not store thi...
Generic representation of a type in a programming language.
uint32_t GetNumberOfNonEmptyBaseClasses()
Go through the base classes and count non-empty ones.
CompilerType GetTypeForFormatters() const
CompilerType GetTypeTemplateArgument(size_t idx, bool expand_pack=false) const
lldb::LanguageType GetMinimumLanguage()
bool GetValueAsScalar(const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size, Scalar &value, ExecutionContextScope *exe_scope) const
bool Verify() const
If the type is valid, ask the TypeSystem to verify the integrity of the type to catch CompilerTypes t...
lldb::BasicType GetBasicTypeEnumeration() const
std::optional< IntegralTemplateArgument > GetIntegralTemplateArgument(size_t idx, bool expand_pack=false) const
Returns the value of the template argument and its type.
TypeSystemSPWrapper GetTypeSystem() const
Accessors.
CompilerType GetArrayType(uint64_t size) const
CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) const
Create related types using the current type's AST.
bool IsPossibleDynamicType(CompilerType *target_type, bool check_cplusplus, bool check_objc) const
void SetCompilerType(lldb::TypeSystemWP type_system, lldb::opaque_compiler_type_t type)
CompilerType AddConstModifier() const
Return a new CompilerType adds a const modifier to this type if this type is valid and the type syste...
bool IsArrayType(CompilerType *element_type=nullptr, uint64_t *size=nullptr, bool *is_incomplete=nullptr) const
ConstString GetDisplayTypeName() const
CompilerType GetVirtualBaseClassAtIndex(size_t idx, uint32_t *bit_offset_ptr) const
size_t GetNumMemberFunctions() const
CompilerType GetFunctionArgumentTypeAtIndex(size_t idx) const
uint32_t IsHomogeneousAggregate(CompilerType *base_type_ptr) const
CompilerType GetFieldAtIndex(size_t idx, std::string &name, uint64_t *bit_offset_ptr, uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr) const
CompilerType GetRValueReferenceType() const
Return a new CompilerType that is a R value reference to this type if this type is valid and the type...
bool IsIntegerOrUnscopedEnumerationType() const
size_t GetIndexOfChildMemberWithName(llvm::StringRef name, bool omit_empty_base_classes, std::vector< uint32_t > &child_indexes) const
Lookup a child member given a name.
bool IsScalarOrUnscopedEnumerationType() const
CompilerType GetPointerType() const
Return a new CompilerType that is a pointer to this type.
bool IsContextuallyConvertibleToBool() const
This may only be defined in TypeSystemClang.
llvm::Expected< uint64_t > GetByteSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bytes.
CompilerDecl GetStaticFieldWithName(llvm::StringRef name) const
lldb::TypeClass GetTypeClass() const
lldb::opaque_compiler_type_t GetOpaqueQualType() const
size_t GetNumTemplateArguments(bool expand_pack=false) const
Return the number of template arguments the type has.
CompilerType AddVolatileModifier() const
Return a new CompilerType adds a volatile modifier to this type if this type is valid and the type sy...
bool IsVirtualBase(CompilerType target_base, CompilerType *virtual_base, bool carry_virtual=false) const
Checks whether target_base is a virtual base of type (direct or indirect).
CompilerType AddRestrictModifier() const
Return a new CompilerType adds a restrict modifier to this type if this type is valid and the type sy...
lldb::TypeSystemWP m_type_system
CompilerType GetDirectNestedTypeWithName(llvm::StringRef name) const
bool GetPtrAuthAddressDiversity() const
uint32_t GetNumVirtualBaseClasses() const
lldb::Encoding GetEncoding() const
size_t GetPointerByteSize() const
AST related queries.
CompilerType GetFunctionArgumentAtIndex(const size_t index) const
void ForEachEnumerator(std::function< bool(const CompilerType &integer_type, ConstString name, const llvm::APSInt &value)> const &callback) const
If this type is an enumeration, iterate through all of its enumerators using a callback.
LLVM_DUMP_METHOD void dump() const
Dumping types.
CompilerType GetLValueReferenceType() const
Return a new CompilerType that is a L value reference to this type if this type is valid and the type...
uint32_t GetNumFields() const
size_t GetNumberOfFunctionArguments() const
bool IsIntegerOrEnumerationType(bool &is_signed) const
bool IsScopedEnumerationType() const
bool ShouldTreatScalarValueAsAddress() const
CompilerType GetNonReferenceType() const
If this type is a reference to a type (L value or R value reference), return a new type with the refe...
uint32_t GetNumDirectBaseClasses() const
bool IsMeaninglessWithoutDynamicResolution() const
bool IsBlockPointerType(CompilerType *function_pointer_type_ptr=nullptr) const
ConstString GetTypeName(bool BaseOnly=false) const
bool IsEnumerationIntegerTypeSigned() const
CompilerType GetTypedefedType() const
If the current object represents a typedef type, get the underlying type.
bool IsReferenceType(CompilerType *pointee_type=nullptr, bool *is_rvalue=nullptr) const
bool DumpTypeValue(Stream *s, lldb::Format format, const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, ExecutionContextScope *exe_scope)
CompilerType GetArrayElementType(ExecutionContextScope *exe_scope) const
Creating related types.
bool IsInteger() const
This is used when you don't care about the signedness of the integer.
llvm::Expected< CompilerType > GetDereferencedType(ExecutionContext *exe_ctx, std::string &deref_name, uint32_t &deref_byte_size, int32_t &deref_byte_offset, ValueObject *valobj, uint64_t &language_flags) const
lldb::Format GetFormat() const
CompilerType GetFullyUnqualifiedType() const
ConstString GetMangledTypeName() const
unsigned GetTypeQualifiers() const
llvm::Expected< CompilerType > GetChildCompilerTypeAtIndex(ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers, bool omit_empty_base_classes, bool ignore_array_bounds, std::string &child_name, uint32_t &child_byte_size, int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, bool &child_is_deref_of_parent, ValueObject *valobj, uint64_t &language_flags) const
CompilerType GetDirectBaseClassAtIndex(size_t idx, uint32_t *bit_offset_ptr) const
std::optional< size_t > GetTypeBitAlign(ExecutionContextScope *exe_scope) const
CompilerType GetPointeeType() const
If this type is a pointer type, return the type that the pointer points to, else return an invalid ty...
bool IsIntegerType(bool &is_signed) const
bool GetCompleteType() const
Type Completion.
bool IsUnscopedEnumerationType() const
bool IsFloatingPointType() const
Returns true for floating point types (including complex floats).
uint32_t GetTypeInfo(CompilerType *pointee_or_element_compiler_type=nullptr) const
int GetFunctionArgumentCount() const
Returns -1 if this isn't a function of if the function doesn't have a prototype Returns a value >= 0 ...
llvm::Expected< uint32_t > GetIndexOfChildWithName(llvm::StringRef name, bool omit_empty_base_classes) const
Lookup a child given a name.
unsigned GetPtrAuthDiscriminator() const
bool IsRealFloatingPointType() const
Returns true for non-complex float types.
llvm::Expected< uint32_t > GetNumChildren(bool omit_empty_base_classes, const ExecutionContext *exe_ctx) const
CompilerType GetEnumerationIntegerType() const
lldb::opaque_compiler_type_t m_type
bool CompareTypes(CompilerType rhs) const
llvm::Expected< uint64_t > GetBitSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bits.
bool IsEnumerationType() const
This is used when you don't care about the signedness of the enum.
unsigned GetPtrAuthKey() const
CompilerType CreateTypedef(const char *name, const CompilerDeclContext &decl_ctx, uint32_t payload) const
Create a typedef to this type using "name" as the name of the typedef this type is valid and the type...
CompilerType GetFunctionReturnType() const
bool IsVectorType(CompilerType *element_type=nullptr, uint64_t *size=nullptr) const
bool IsMemberFunctionPointerType() const
CompilerType GetAtomicType() const
Return a new CompilerType that is the atomic type of this type.
CompilerType GetCanonicalType() const
void DumpTypeDescription(lldb::DescriptionLevel level=lldb::eDescriptionLevelFull) const
Dump to stdout.
bool IsRuntimeGeneratedType() const
lldb::TemplateArgumentKind GetTemplateArgumentKind(size_t idx, bool expand_pack=false) const
LazyBool ShouldPrintAsOneLiner(ValueObject *valobj) const
TypeMemberFunctionImpl GetMemberFunctionAtIndex(size_t idx)
bool IsPointerOrReferenceType(CompilerType *pointee_type=nullptr) const
CompilerType(lldb::TypeSystemWP type_system, lldb::opaque_compiler_type_t type)
Creates a CompilerType with the given TypeSystem and opaque compiler type.
bool IsPointerType(CompilerType *pointee_type=nullptr) const
CompilerType AddPtrAuthModifier(uint32_t payload) const
Return a new CompilerType adds a ptrauth modifier from the given 32-bit opaque payload to this type i...
A uniqued constant string class.
Definition ConstString.h:40
An data extractor class.
int64_t GetMaxS64(lldb::offset_t *offset_ptr, size_t byte_size) const
Extract an signed integer of size byte_size from *offset_ptr.
uint64_t GetU64(lldb::offset_t *offset_ptr) const
Extract a uint64_t value from *offset_ptr.
uint32_t GetU32(lldb::offset_t *offset_ptr) const
Extract a uint32_t value from *offset_ptr.
uint64_t GetMaxU64(lldb::offset_t *offset_ptr, size_t byte_size) const
Extract an unsigned integer of size byte_size from *offset_ptr.
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
A stream class that can stream formatted output to a file.
Definition Stream.h:28
Interface for representing a type system.
Definition TypeSystem.h:70
virtual CompilerDecl GetStaticFieldWithName(lldb::opaque_compiler_type_t type, llvm::StringRef name)
Definition TypeSystem.h:363
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:332
bool operator!=(const Address &lhs, const Address &rhs)
Definition Address.cpp:1017
bool operator==(const Address &lhs, const Address &rhs)
Definition Address.cpp:1011
void * opaque_compiler_type_t
Definition lldb-types.h:90
DescriptionLevel
Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls.
BasicType
Basic types enumeration for the public API SBType::GetBasicType().
Format
Display format definitions.
uint64_t offset_t
Definition lldb-types.h:85
LanguageType
Programming language type.
@ eLanguageTypeC
Non-standardized C, such as K&R.
@ eTemplateArgumentKindNull
Encoding
Register encoding definitions.
@ eEncodingIEEE754
float
@ eEncodingVector
vector registers
@ eEncodingUint
unsigned integer
@ eEncodingSint
signed integer
std::weak_ptr< lldb_private::TypeSystem > TypeSystemWP