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"
23
24#include <iterator>
25#include <mutex>
26#include <optional>
27
28using namespace lldb;
29using namespace lldb_private;
30
31// Tests
32
34 if (IsValid())
35 if (auto type_system_sp = GetTypeSystem())
36 return type_system_sp->IsAggregateType(m_type);
37 return false;
38}
39
41 if (IsValid())
42 if (auto type_system_sp = GetTypeSystem())
43 return type_system_sp->IsAnonymousType(m_type);
44 return false;
45}
46
48 if (IsValid())
49 if (auto type_system_sp = GetTypeSystem())
50 return type_system_sp->IsScopedEnumerationType(m_type);
51 return false;
52}
53
54bool CompilerType::IsArrayType(CompilerType *element_type_ptr, uint64_t *size,
55 bool *is_incomplete) const {
56 if (IsValid())
57 if (auto type_system_sp = GetTypeSystem())
58 return type_system_sp->IsArrayType(m_type, element_type_ptr, size,
59 is_incomplete);
60
61 if (element_type_ptr)
62 element_type_ptr->Clear();
63 if (size)
64 *size = 0;
65 if (is_incomplete)
66 *is_incomplete = false;
67 return false;
68}
69
71 uint64_t *size) const {
72 if (IsValid())
73 if (auto type_system_sp = GetTypeSystem())
74 return type_system_sp->IsVectorType(m_type, element_type, size);
75 return false;
76}
77
79 if (IsValid())
80 if (auto type_system_sp = GetTypeSystem())
81 return type_system_sp->IsRuntimeGeneratedType(m_type);
82 return false;
83}
84
86 if (IsValid())
87 if (auto type_system_sp = GetTypeSystem())
88 return type_system_sp->IsCharType(m_type);
89 return false;
90}
91
93 if (IsValid())
94 if (auto type_system_sp = GetTypeSystem())
95 return type_system_sp->IsCompleteType(m_type);
96 return false;
97}
98
100 if (IsValid())
101 if (auto type_system_sp = GetTypeSystem())
102 return type_system_sp->IsForcefullyCompleted(m_type);
103 return false;
104}
105
107 if (IsValid())
108 if (auto type_system_sp = GetTypeSystem())
109 return type_system_sp->IsConst(m_type);
110 return false;
111}
112
114 if (IsValid())
115 if (auto type_system_sp = GetTypeSystem())
116 return type_system_sp->GetPtrAuthKey(m_type);
117 return 0;
118}
119
121 if (IsValid())
122 if (auto type_system_sp = GetTypeSystem())
123 return type_system_sp->GetPtrAuthDiscriminator(m_type);
124 return 0;
125}
126
128 if (IsValid())
129 if (auto type_system_sp = GetTypeSystem())
130 return type_system_sp->GetPtrAuthAddressDiversity(m_type);
131 return false;
132}
133
135 if (IsValid())
136 if (auto type_system_sp = GetTypeSystem())
137 return type_system_sp->IsFunctionType(m_type);
138 return false;
139}
140
141// Used to detect "Homogeneous Floating-point Aggregates"
142uint32_t
144 if (IsValid())
145 if (auto type_system_sp = GetTypeSystem())
146 return type_system_sp->IsHomogeneousAggregate(m_type, base_type_ptr);
147 return 0;
148}
149
151 if (IsValid())
152 if (auto type_system_sp = GetTypeSystem())
153 return type_system_sp->GetNumberOfFunctionArguments(m_type);
154 return 0;
155}
156
159 if (IsValid())
160 if (auto type_system_sp = GetTypeSystem())
161 return type_system_sp->GetFunctionArgumentAtIndex(m_type, index);
162 return CompilerType();
163}
164
166 if (IsValid())
167 if (auto type_system_sp = GetTypeSystem())
168 return type_system_sp->IsFunctionPointerType(m_type);
169 return false;
170}
171
173 if (IsValid())
174 if (auto type_system_sp = GetTypeSystem())
175 return type_system_sp->IsMemberFunctionPointerType(m_type);
176 return false;
177}
178
180 CompilerType *function_pointer_type_ptr) const {
181 if (IsValid())
182 if (auto type_system_sp = GetTypeSystem())
183 return type_system_sp->IsBlockPointerType(m_type, function_pointer_type_ptr);
184 return false;
185}
186
187bool CompilerType::IsIntegerType(bool &is_signed) const {
188 if (IsValid())
189 if (auto type_system_sp = GetTypeSystem())
190 return type_system_sp->IsIntegerType(m_type, is_signed);
191 return false;
192}
193
194bool CompilerType::IsEnumerationType(bool &is_signed) const {
195 if (IsValid())
196 if (auto type_system_sp = GetTypeSystem())
197 return type_system_sp->IsEnumerationType(m_type, is_signed);
198 return false;
199}
200
201bool CompilerType::IsIntegerOrEnumerationType(bool &is_signed) const {
202 return IsIntegerType(is_signed) || IsEnumerationType(is_signed);
203}
204
205bool CompilerType::IsPointerType(CompilerType *pointee_type) const {
206 if (IsValid()) {
207 if (auto type_system_sp = GetTypeSystem())
208 return type_system_sp->IsPointerType(m_type, pointee_type);
209 }
210 if (pointee_type)
211 pointee_type->Clear();
212 return false;
213}
214
216 if (IsValid()) {
217 if (auto type_system_sp = GetTypeSystem())
218 return type_system_sp->IsPointerOrReferenceType(m_type, pointee_type);
219 }
220 if (pointee_type)
221 pointee_type->Clear();
222 return false;
223}
224
226 bool *is_rvalue) const {
227 if (IsValid()) {
228 if (auto type_system_sp = GetTypeSystem())
229 return type_system_sp->IsReferenceType(m_type, pointee_type, is_rvalue);
230 }
231 if (pointee_type)
232 pointee_type->Clear();
233 return false;
234}
235
237 if (IsValid())
238 if (auto type_system_sp = GetTypeSystem())
239 return type_system_sp->ShouldTreatScalarValueAsAddress(m_type);
240 return false;
241}
242
244 bool &is_complex) const {
245 if (IsValid()) {
246 if (auto type_system_sp = GetTypeSystem())
247 return type_system_sp->IsFloatingPointType(m_type, count, is_complex);
248 }
249 count = 0;
250 is_complex = false;
251 return false;
252}
253
255 if (IsValid())
256 if (auto type_system_sp = GetTypeSystem())
257 return type_system_sp->IsDefined(m_type);
258 return true;
259}
260
262 if (IsValid()) {
263 if (auto type_system_sp = GetTypeSystem())
264 return type_system_sp->IsPolymorphicClass(m_type);
265 }
266 return false;
267}
268
270 bool check_cplusplus,
271 bool check_objc) const {
272 if (IsValid())
273 if (auto type_system_sp = GetTypeSystem())
274 return type_system_sp->IsPossibleDynamicType(m_type, dynamic_pointee_type,
275 check_cplusplus, check_objc);
276 return false;
277}
278
280 if (IsValid())
281 if (auto type_system_sp = GetTypeSystem())
282 return type_system_sp->IsScalarType(m_type);
283 return false;
284}
285
287 if (IsValid())
288 if (auto type_system_sp = GetTypeSystem())
289 return type_system_sp->IsTemplateType(m_type);
290 return false;
291}
292
294 if (IsValid())
295 if (auto type_system_sp = GetTypeSystem())
296 return type_system_sp->IsTypedefType(m_type);
297 return false;
298}
299
301 if (IsValid())
302 if (auto type_system_sp = GetTypeSystem())
303 return type_system_sp->IsVoidType(m_type);
304 return false;
305}
306
308 if (!IsValid())
309 return false;
310
312}
313
315 CompilerType element_type;
316 if (IsArrayType(&element_type))
317 return element_type.IsScalarType();
318 return false;
319}
320
322 if (IsValid())
323 if (auto type_system_sp = GetTypeSystem())
324 return type_system_sp->IsBeingDefined(m_type);
325 return false;
326}
327
329 bool is_signed = false; // May be reset by the call below.
330 return IsIntegerType(is_signed);
331}
332
334 uint32_t count = 0;
335 bool is_complex = false;
336 return IsFloatingPointType(count, is_complex);
337}
338
340 bool is_signed = false; // May be reset by the call below.
341 return IsEnumerationType(is_signed);
342}
343
347
351
353 return GetTypeInfo() & lldb::eTypeIsSigned;
354}
355
359
363
365 if (IsValid())
366 return GetEnumerationIntegerType().GetTypeInfo() & lldb::eTypeIsSigned;
367
368 return false;
369}
370
374
376 // Unscoped enums are always considered as promotable, even if their
377 // underlying type does not need to be promoted (e.g. "int").
379 return true;
380
381 switch (GetBasicTypeEnumeration()) {
393 return true;
394
395 default:
396 return false;
397 }
398
399 llvm_unreachable("All cases handled above.");
400}
401
403 if (!IsValid())
404 return false;
405
406 return IsPointerType() &&
408}
409
411 if (!IsValid())
412 return false;
413
414 return GetCanonicalType().GetTypeClass() &
415 (lldb::eTypeClassClass | lldb::eTypeClassStruct |
416 lldb::eTypeClassUnion);
417}
418
420 CompilerType *virtual_base,
421 bool carry_virtual) const {
422 if (CompareTypes(target_base))
423 return carry_virtual;
424
425 if (!carry_virtual) {
426 uint32_t num_virtual_bases = GetNumVirtualBaseClasses();
427 for (uint32_t i = 0; i < num_virtual_bases; ++i) {
428 uint32_t bit_offset;
429 auto base = GetVirtualBaseClassAtIndex(i, &bit_offset);
430 if (base.IsVirtualBase(target_base, virtual_base,
431 /*carry_virtual*/ true)) {
432 if (virtual_base)
433 *virtual_base = base;
434
435 return true;
436 }
437 }
438 }
439
440 uint32_t num_direct_bases = GetNumDirectBaseClasses();
441 for (uint32_t i = 0; i < num_direct_bases; ++i) {
442 uint32_t bit_offset;
443 auto base = GetDirectBaseClassAtIndex(i, &bit_offset);
444 if (base.IsVirtualBase(target_base, virtual_base, carry_virtual))
445 return true;
446 }
447
448 return false;
449}
450
455
459
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
474 if (*this == rhs)
475 return true;
476
478 const ConstString rhs_name = rhs.GetFullyUnqualifiedType().GetTypeName();
479 return name == rhs_name;
480}
481
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
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
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
523 if (auto type_system_sp = GetTypeSystem())
524 return type_system_sp->GetPointerByteSize();
525 return 0;
526}
527
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
537 if (IsValid())
538 if (auto type_system_sp = GetTypeSystem())
539 return type_system_sp->GetDisplayTypeName(m_type);
540 return ConstString("<invalid>");
541}
542
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
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
561 if (IsValid())
562 if (auto type_system_sp = GetTypeSystem())
563 return type_system_sp->GetMinimumLanguage(m_type);
565}
566
567lldb::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
576 m_type_system = type_system;
577 m_type = type;
578}
579
585
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
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
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
613 if (IsValid())
614 if (auto type_system_sp = GetTypeSystem())
615 return type_system_sp->GetCanonicalType(m_type);
616 return CompilerType();
617}
618
620 if (IsValid())
621 if (auto type_system_sp = GetTypeSystem())
622 return type_system_sp->GetFullyUnqualifiedType(m_type);
623 return CompilerType();
624}
625
627 if (IsValid())
628 if (auto type_system_sp = GetTypeSystem())
629 return type_system_sp->GetEnumerationIntegerType(m_type);
630 return CompilerType();
631}
632
634 if (IsValid()) {
635 if (auto type_system_sp = GetTypeSystem())
636 return type_system_sp->GetFunctionArgumentCount(m_type);
637 }
638 return -1;
639}
640
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
650 if (IsValid()) {
651 if (auto type_system_sp = GetTypeSystem())
652 return type_system_sp->GetFunctionReturnType(m_type);
653 }
654 return CompilerType();
655}
656
658 if (IsValid()) {
659 if (auto type_system_sp = GetTypeSystem())
660 return type_system_sp->GetNumMemberFunctions(m_type);
661 }
662 return 0;
663}
664
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
674 if (IsValid())
675 if (auto type_system_sp = GetTypeSystem())
676 return type_system_sp->GetNonReferenceType(m_type);
677 return CompilerType();
678}
679
681 if (IsValid()) {
682 if (auto type_system_sp = GetTypeSystem())
683 return type_system_sp->GetPointeeType(m_type);
684 }
685 return CompilerType();
686}
687
689 if (IsValid()) {
690 if (auto type_system_sp = GetTypeSystem())
691 return type_system_sp->GetPointerType(m_type);
692 }
693 return CompilerType();
694}
695
697 if (IsValid())
698 if (auto type_system_sp = GetTypeSystem())
699 return type_system_sp->AddPtrAuthModifier(m_type, payload);
700 return CompilerType();
701}
702
704 if (IsValid())
705 if (auto type_system_sp = GetTypeSystem())
706 return type_system_sp->GetLValueReferenceType(m_type);
707 return CompilerType();
708}
709
711 if (IsValid())
712 if (auto type_system_sp = GetTypeSystem())
713 return type_system_sp->GetRValueReferenceType(m_type);
714 return CompilerType();
715}
716
718 if (IsValid())
719 if (auto type_system_sp = GetTypeSystem())
720 return type_system_sp->GetAtomicType(m_type);
721 return CompilerType();
722}
723
725 if (IsValid())
726 if (auto type_system_sp = GetTypeSystem())
727 return type_system_sp->AddConstModifier(m_type);
728 return CompilerType();
729}
730
732 if (IsValid())
733 if (auto type_system_sp = GetTypeSystem())
734 return type_system_sp->AddVolatileModifier(m_type);
735 return CompilerType();
736}
737
739 if (IsValid())
740 if (auto type_system_sp = GetTypeSystem())
741 return type_system_sp->AddRestrictModifier(m_type);
742 return CompilerType();
743}
744
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
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
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
772llvm::Expected<uint64_t>
774 if (IsValid())
775 if (auto type_system_sp = GetTypeSystem())
776 return type_system_sp->GetBitSize(m_type, exe_scope);
777 return llvm::createStringError("Invalid type: Cannot determine size");
778}
779
780llvm::Expected<uint64_t>
782 auto bit_size_or_err = GetBitSize(exe_scope);
783 if (!bit_size_or_err)
784 return bit_size_or_err.takeError();
785 return (*bit_size_or_err + 7) / 8;
786}
787
788std::optional<size_t>
790 if (IsValid())
791 if (auto type_system_sp = GetTypeSystem())
792 return type_system_sp->GetTypeBitAlign(m_type, exe_scope);
793 return {};
794}
795
797 if (IsValid())
798 if (auto type_system_sp = GetTypeSystem())
799 return type_system_sp->GetEncoding(m_type, count);
801}
802
804 if (IsValid())
805 if (auto type_system_sp = GetTypeSystem())
806 return type_system_sp->GetFormat(m_type);
808}
809
810llvm::Expected<uint32_t>
811CompilerType::GetNumChildren(bool omit_empty_base_classes,
812 const ExecutionContext *exe_ctx) const {
813 if (IsValid())
814 if (auto type_system_sp = GetTypeSystem())
815 return type_system_sp->GetNumChildren(m_type, omit_empty_base_classes,
816 exe_ctx);
817 return llvm::createStringError("invalid type");
818}
819
821 if (IsValid())
822 if (auto type_system_sp = GetTypeSystem())
823 return type_system_sp->GetBasicTypeEnumeration(m_type);
824 return eBasicTypeInvalid;
825}
826
828 std::function<bool(const CompilerType &integer_type,
829 ConstString name,
830 const llvm::APSInt &value)> const &callback) const {
831 if (IsValid())
832 if (auto type_system_sp = GetTypeSystem())
833 return type_system_sp->ForEachEnumerator(m_type, callback);
834}
835
837 if (IsValid())
838 if (auto type_system_sp = GetTypeSystem())
839 return type_system_sp->GetNumFields(m_type);
840 return 0;
841}
842
843CompilerType CompilerType::GetFieldAtIndex(size_t idx, std::string &name,
844 uint64_t *bit_offset_ptr,
845 uint32_t *bitfield_bit_size_ptr,
846 bool *is_bitfield_ptr) const {
847 if (IsValid())
848 if (auto type_system_sp = GetTypeSystem())
849 return type_system_sp->GetFieldAtIndex(m_type, idx, name, bit_offset_ptr,
850 bitfield_bit_size_ptr, is_bitfield_ptr);
851 return CompilerType();
852}
853
855 if (IsValid())
856 if (auto type_system_sp = GetTypeSystem())
857 return type_system_sp->GetNumDirectBaseClasses(m_type);
858 return 0;
859}
860
862 if (IsValid())
863 if (auto type_system_sp = GetTypeSystem())
864 return type_system_sp->GetNumVirtualBaseClasses(m_type);
865 return 0;
866}
867
870 uint32_t *bit_offset_ptr) const {
871 if (IsValid())
872 if (auto type_system_sp = GetTypeSystem())
873 return type_system_sp->GetDirectBaseClassAtIndex(m_type, idx,
874 bit_offset_ptr);
875 return CompilerType();
876}
877
880 uint32_t *bit_offset_ptr) const {
881 if (IsValid())
882 if (auto type_system_sp = GetTypeSystem())
883 return type_system_sp->GetVirtualBaseClassAtIndex(m_type, idx,
884 bit_offset_ptr);
885 return CompilerType();
886}
887
889 if (IsValid())
891 return CompilerDecl();
892}
893
894llvm::Expected<CompilerType> CompilerType::GetDereferencedType(
895 ExecutionContext *exe_ctx, std::string &deref_name,
896 uint32_t &deref_byte_size, int32_t &deref_byte_offset, ValueObject *valobj,
897 uint64_t &language_flags) const {
898 if (IsValid())
899 if (auto type_system_sp = GetTypeSystem())
900 return type_system_sp->GetDereferencedType(
901 m_type, exe_ctx, deref_name, deref_byte_size, deref_byte_offset,
902 valobj, language_flags);
903 return CompilerType();
904}
905
906llvm::Expected<CompilerType> CompilerType::GetChildCompilerTypeAtIndex(
907 ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers,
908 bool omit_empty_base_classes, bool ignore_array_bounds,
909 std::string &child_name, uint32_t &child_byte_size,
910 int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size,
911 uint32_t &child_bitfield_bit_offset, bool &child_is_base_class,
912 bool &child_is_deref_of_parent, ValueObject *valobj,
913 uint64_t &language_flags) const {
914 if (IsValid())
915 if (auto type_system_sp = GetTypeSystem())
916 return type_system_sp->GetChildCompilerTypeAtIndex(
917 m_type, exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
918 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
919 child_bitfield_bit_size, child_bitfield_bit_offset,
920 child_is_base_class, child_is_deref_of_parent, valobj,
921 language_flags);
922 return CompilerType();
923}
924
925// Look for a child member (doesn't include base classes, but it does include
926// their members) in the type hierarchy. Returns an index path into
927// "clang_type" on how to reach the appropriate member.
928//
929// class A
930// {
931// public:
932// int m_a;
933// int m_b;
934// };
935//
936// class B
937// {
938// };
939//
940// class C :
941// public B,
942// public A
943// {
944// };
945//
946// If we have a clang type that describes "class C", and we wanted to looked
947// "m_b" in it:
948//
949// With omit_empty_base_classes == false we would get an integer array back
950// with: { 1, 1 } The first index 1 is the child index for "class A" within
951// class C The second index 1 is the child index for "m_b" within class A
952//
953// With omit_empty_base_classes == true we would get an integer array back
954// with: { 0, 1 } The first index 0 is the child index for "class A" within
955// class C (since class B doesn't have any members it doesn't count) The second
956// index 1 is the child index for "m_b" within class A
957
959 llvm::StringRef name, bool omit_empty_base_classes,
960 std::vector<uint32_t> &child_indexes) const {
961 if (IsValid() && !name.empty()) {
962 if (auto type_system_sp = GetTypeSystem())
963 return type_system_sp->GetIndexOfChildMemberWithName(
964 m_type, name, omit_empty_base_classes, child_indexes);
965 }
966 return 0;
967}
968
970CompilerType::GetDirectNestedTypeWithName(llvm::StringRef name) const {
971 if (IsValid() && !name.empty()) {
972 if (auto type_system_sp = GetTypeSystem())
973 return type_system_sp->GetDirectNestedTypeWithName(m_type, name);
974 }
975 return CompilerType();
976}
977
978size_t CompilerType::GetNumTemplateArguments(bool expand_pack) const {
979 if (IsValid()) {
980 if (auto type_system_sp = GetTypeSystem())
981 return type_system_sp->GetNumTemplateArguments(m_type, expand_pack);
982 }
983 return 0;
984}
985
987CompilerType::GetTemplateArgumentKind(size_t idx, bool expand_pack) const {
988 if (IsValid())
989 if (auto type_system_sp = GetTypeSystem())
990 return type_system_sp->GetTemplateArgumentKind(m_type, idx, expand_pack);
992}
993
995 bool expand_pack) const {
996 if (IsValid()) {
997 if (auto type_system_sp = GetTypeSystem())
998 return type_system_sp->GetTypeTemplateArgument(m_type, idx, expand_pack);
999 }
1000 return CompilerType();
1001}
1002
1003std::optional<CompilerType::IntegralTemplateArgument>
1004CompilerType::GetIntegralTemplateArgument(size_t idx, bool expand_pack) const {
1005 if (IsValid())
1006 if (auto type_system_sp = GetTypeSystem())
1007 return type_system_sp->GetIntegralTemplateArgument(m_type, idx, expand_pack);
1008 return std::nullopt;
1009}
1010
1012 if (IsValid())
1013 if (auto type_system_sp = GetTypeSystem())
1014 return type_system_sp->GetTypeForFormatters(m_type);
1015 return CompilerType();
1016}
1017
1019 if (IsValid())
1020 if (auto type_system_sp = GetTypeSystem())
1021 return type_system_sp->ShouldPrintAsOneLiner(m_type, valobj);
1022 return eLazyBoolCalculate;
1023}
1024
1026 if (IsValid())
1027 if (auto type_system_sp = GetTypeSystem())
1028 return type_system_sp->IsMeaninglessWithoutDynamicResolution(m_type);
1029 return false;
1030}
1031
1032// Get the index of the child of "clang_type" whose name matches. This function
1033// doesn't descend into the children, but only looks one level deep and name
1034// matches can include base class names.
1035
1036llvm::Expected<uint32_t>
1038 bool omit_empty_base_classes) const {
1039 if (IsValid() && !name.empty()) {
1040 if (auto type_system_sp = GetTypeSystem())
1041 return type_system_sp->GetIndexOfChildWithName(m_type, name,
1042 omit_empty_base_classes);
1043 }
1044 return llvm::createStringError("Type has no child named '%s'",
1045 name.str().c_str());
1046}
1047
1048// Dumping types
1049
1051 const DataExtractor &data,
1052 lldb::offset_t byte_offset, size_t byte_size,
1053 uint32_t bitfield_bit_size,
1054 uint32_t bitfield_bit_offset,
1055 ExecutionContextScope *exe_scope) {
1056 if (IsValid())
1057 if (auto type_system_sp = GetTypeSystem())
1058 return type_system_sp->DumpTypeValue(
1059 m_type, *s, format, data, byte_offset, byte_size, bitfield_bit_size,
1060 bitfield_bit_offset, exe_scope);
1061 return false;
1062}
1063
1065 if (IsValid())
1066 if (auto type_system_sp = GetTypeSystem())
1067 type_system_sp->DumpTypeDescription(m_type, level);
1068}
1069
1071 lldb::DescriptionLevel level) const {
1072 if (IsValid())
1073 if (auto type_system_sp = GetTypeSystem())
1074 type_system_sp->DumpTypeDescription(m_type, *s, level);
1075}
1076
1077#ifndef NDEBUG
1078LLVM_DUMP_METHOD void CompilerType::dump() const {
1079 if (IsValid())
1080 if (auto type_system_sp = GetTypeSystem())
1081 return type_system_sp->dump(m_type);
1082 llvm::errs() << "<invalid>\n";
1083}
1084#endif
1085
1087 lldb::offset_t data_byte_offset,
1088 size_t data_byte_size, Scalar &value,
1089 ExecutionContextScope *exe_scope) const {
1090 if (!IsValid())
1091 return false;
1092
1093 if (IsAggregateType()) {
1094 return false; // Aggregate types don't have scalar values
1095 } else {
1096 uint64_t count = 0;
1097 lldb::Encoding encoding = GetEncoding(count);
1098
1099 if (encoding == lldb::eEncodingInvalid || count != 1)
1100 return false;
1101
1102 auto byte_size_or_err = GetByteSize(exe_scope);
1103 if (!byte_size_or_err) {
1105 GetLog(LLDBLog::Types), byte_size_or_err.takeError(),
1106 "Cannot get value as scalar: Cannot determine type size: {0}");
1107 return false;
1108 }
1109 uint64_t byte_size = *byte_size_or_err;
1110
1111 // A bit or byte size of 0 is not a bug, but it doesn't make sense to read a
1112 // scalar of zero size.
1113 if (byte_size == 0)
1114 return false;
1115
1116 lldb::offset_t offset = data_byte_offset;
1117 switch (encoding) {
1119 break;
1121 break;
1123 if (byte_size <= sizeof(unsigned long long)) {
1124 uint64_t uval64 = data.GetMaxU64(&offset, byte_size);
1125 if (byte_size <= sizeof(unsigned int)) {
1126 value = (unsigned int)uval64;
1127 return true;
1128 } else if (byte_size <= sizeof(unsigned long)) {
1129 value = (unsigned long)uval64;
1130 return true;
1131 } else if (byte_size <= sizeof(unsigned long long)) {
1132 value = (unsigned long long)uval64;
1133 return true;
1134 } else
1135 value.Clear();
1136 }
1137 break;
1138
1140 if (byte_size <= sizeof(long long)) {
1141 int64_t sval64 = data.GetMaxS64(&offset, byte_size);
1142 if (byte_size <= sizeof(int)) {
1143 value = (int)sval64;
1144 return true;
1145 } else if (byte_size <= sizeof(long)) {
1146 value = (long)sval64;
1147 return true;
1148 } else if (byte_size <= sizeof(long long)) {
1149 value = (long long)sval64;
1150 return true;
1151 } else
1152 value.Clear();
1153 }
1154 break;
1155
1157 if (byte_size <= sizeof(long double)) {
1158 uint32_t u32;
1159 uint64_t u64;
1160 if (byte_size == sizeof(float)) {
1161 if (sizeof(float) == sizeof(uint32_t)) {
1162 u32 = data.GetU32(&offset);
1163 value = *((float *)&u32);
1164 return true;
1165 } else if (sizeof(float) == sizeof(uint64_t)) {
1166 u64 = data.GetU64(&offset);
1167 value = *((float *)&u64);
1168 return true;
1169 }
1170 } else if (byte_size == sizeof(double)) {
1171 if (sizeof(double) == sizeof(uint32_t)) {
1172 u32 = data.GetU32(&offset);
1173 value = *((double *)&u32);
1174 return true;
1175 } else if (sizeof(double) == sizeof(uint64_t)) {
1176 u64 = data.GetU64(&offset);
1177 value = *((double *)&u64);
1178 return true;
1179 }
1180 } else if (byte_size == sizeof(long double)) {
1181 if (sizeof(long double) == sizeof(uint32_t)) {
1182 u32 = data.GetU32(&offset);
1183 value = *((long double *)&u32);
1184 return true;
1185 } else if (sizeof(long double) == sizeof(uint64_t)) {
1186 u64 = data.GetU64(&offset);
1187 value = *((long double *)&u64);
1188 return true;
1189 }
1190 }
1191 }
1192 break;
1193 }
1194 }
1195 return false;
1196}
1197
1200 : m_type_system(type_system.GetSharedPointer()), m_type(type) {
1201 assert(Verify() && "verification failed");
1202}
1203
1206 : m_type_system(type_system), m_type(type) {
1207 assert(Verify() && "verification failed");
1208}
1209
1210#ifndef NDEBUG
1212 if (!IsValid())
1213 return true;
1214 if (auto type_system_sp = GetTypeSystem())
1215 return type_system_sp->Verify(m_type);
1216 return true;
1217}
1218#endif
1219
1223
1225 const CompilerType::TypeSystemSPWrapper &other) const {
1226 if (!m_typesystem_sp && !other.m_typesystem_sp)
1227 return true;
1228 if (m_typesystem_sp && other.m_typesystem_sp)
1229 return m_typesystem_sp.get() == other.m_typesystem_sp.get();
1230 return false;
1231}
1232
1237
1239 const lldb_private::CompilerType &rhs) {
1240 return lhs.GetTypeSystem() == rhs.GetTypeSystem() &&
1241 lhs.GetOpaqueQualType() == rhs.GetOpaqueQualType();
1242}
1243
1245 const lldb_private::CompilerType &rhs) {
1246 return !(lhs == rhs);
1247}
#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...
lldb::Encoding GetEncoding(uint64_t &count) const
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
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.
bool IsFloatingPointType(uint32_t &count, bool &is_complex) const
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
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
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:89
DescriptionLevel
Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls.
BasicType
Basic types enumeration for the public API SBType::GetBasicType().
@ eBasicTypeUnsignedShort
@ eBasicTypeSignedChar
@ eBasicTypeUnsignedWChar
@ eBasicTypeSignedWChar
@ eBasicTypeUnsignedChar
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