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
243bool CompilerType::IsFloatingPointType(bool &is_complex) const {
244 if (IsValid()) {
245 if (auto type_system_sp = GetTypeSystem())
246 return type_system_sp->IsFloatingPointType(m_type, is_complex);
247 }
248 is_complex = false;
249 return false;
250}
251
253 if (IsValid())
254 if (auto type_system_sp = GetTypeSystem())
255 return type_system_sp->IsDefined(m_type);
256 return true;
257}
258
260 if (IsValid()) {
261 if (auto type_system_sp = GetTypeSystem())
262 return type_system_sp->IsPolymorphicClass(m_type);
263 }
264 return false;
265}
266
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
278 if (IsValid())
279 if (auto type_system_sp = GetTypeSystem())
280 return type_system_sp->IsScalarType(m_type);
281 return false;
282}
283
285 if (IsValid())
286 if (auto type_system_sp = GetTypeSystem())
287 return type_system_sp->IsTemplateType(m_type);
288 return false;
289}
290
292 if (IsValid())
293 if (auto type_system_sp = GetTypeSystem())
294 return type_system_sp->IsTypedefType(m_type);
295 return false;
296}
297
299 if (IsValid())
300 if (auto type_system_sp = GetTypeSystem())
301 return type_system_sp->IsVoidType(m_type);
302 return false;
303}
304
306 if (!IsValid())
307 return false;
308
310}
311
313 CompilerType element_type;
314 if (IsArrayType(&element_type))
315 return element_type.IsScalarType();
316 return false;
317}
318
320 if (IsValid())
321 if (auto type_system_sp = GetTypeSystem())
322 return type_system_sp->IsBeingDefined(m_type);
323 return false;
324}
325
327 bool is_signed = false; // May be reset by the call below.
328 return IsIntegerType(is_signed);
329}
330
332 bool is_complex = false;
333 return IsFloatingPointType(is_complex);
334}
335
337 bool is_signed = false; // May be reset by the call below.
338 return IsEnumerationType(is_signed);
339}
340
344
348
350 return GetTypeInfo() & lldb::eTypeIsSigned;
351}
352
356
360
362 if (IsValid())
363 return GetEnumerationIntegerType().GetTypeInfo() & lldb::eTypeIsSigned;
364
365 return false;
366}
367
371
373 if (IsValid())
374 if (auto type_system_sp = GetTypeSystem())
375 return type_system_sp->IsPromotableIntegerType(m_type);
376 return false;
377}
378
380 if (!IsValid())
381 return false;
382
383 return IsPointerType() &&
385}
386
388 if (!IsValid())
389 return false;
390
391 return GetCanonicalType().GetTypeClass() &
392 (lldb::eTypeClassClass | lldb::eTypeClassStruct |
393 lldb::eTypeClassUnion);
394}
395
397 CompilerType *virtual_base,
398 bool carry_virtual) const {
399 if (CompareTypes(target_base))
400 return carry_virtual;
401
402 if (!carry_virtual) {
403 uint32_t num_virtual_bases = GetNumVirtualBaseClasses();
404 for (uint32_t i = 0; i < num_virtual_bases; ++i) {
405 uint32_t bit_offset;
406 auto base = GetVirtualBaseClassAtIndex(i, &bit_offset);
407 if (base.IsVirtualBase(target_base, virtual_base,
408 /*carry_virtual*/ true)) {
409 if (virtual_base)
410 *virtual_base = base;
411
412 return true;
413 }
414 }
415 }
416
417 uint32_t num_direct_bases = GetNumDirectBaseClasses();
418 for (uint32_t i = 0; i < num_direct_bases; ++i) {
419 uint32_t bit_offset;
420 auto base = GetDirectBaseClassAtIndex(i, &bit_offset);
421 if (base.IsVirtualBase(target_base, virtual_base, carry_virtual))
422 return true;
423 }
424
425 return false;
426}
427
432
436
438 auto name = GetTypeName();
439 auto canonical_name = GetCanonicalType().GetTypeName();
440 if (name.IsEmpty() || canonical_name.IsEmpty())
441 return "''"; // Should not happen, unless the input is broken somehow.
442
443 if (name == canonical_name)
444 return llvm::formatv("'{0}'", name);
445
446 return llvm::formatv("'{0}' (canonically referred to as '{1}')", name,
447 canonical_name);
448}
449
451 if (*this == rhs)
452 return true;
453
455 const ConstString rhs_name = rhs.GetFullyUnqualifiedType().GetTypeName();
456 return name == rhs_name;
457}
458
460 switch (GetTypeClass()) {
461 case lldb::eTypeClassClass:
462 return "class";
463 case lldb::eTypeClassEnumeration:
464 return "enum";
465 case lldb::eTypeClassStruct:
466 return "struct";
467 case lldb::eTypeClassUnion:
468 return "union";
469 default:
470 return "unknown";
471 }
472 llvm_unreachable("All cases are covered by code above.");
473}
474
476 uint32_t ret = 0;
477 uint32_t num_direct_bases = GetNumDirectBaseClasses();
478
479 for (uint32_t i = 0; i < num_direct_bases; ++i) {
480 uint32_t bit_offset;
481 CompilerType base_type = GetDirectBaseClassAtIndex(i, &bit_offset);
482 if (base_type.GetNumFields() > 0 ||
483 base_type.GetNumberOfNonEmptyBaseClasses() > 0)
484 ret += 1;
485 }
486 return ret;
487}
488
489// Type Completion
490
492 if (IsValid())
493 if (auto type_system_sp = GetTypeSystem())
494 return type_system_sp->GetCompleteType(m_type);
495 return false;
496}
497
498// AST related queries
500 if (auto type_system_sp = GetTypeSystem())
501 return type_system_sp->GetPointerByteSize();
502 return 0;
503}
504
506 if (IsValid()) {
507 if (auto type_system_sp = GetTypeSystem())
508 return type_system_sp->GetTypeName(m_type, BaseOnly);
509 }
510 return ConstString("<invalid>");
511}
512
514 if (IsValid())
515 if (auto type_system_sp = GetTypeSystem())
516 return type_system_sp->GetDisplayTypeName(m_type);
517 return ConstString("<invalid>");
518}
519
521 if (IsValid()) {
522 if (auto type_system_sp = GetTypeSystem())
523 return type_system_sp->GetMangledTypeName(m_type);
524 }
525 return ConstString("<invalid>");
526}
527
529 CompilerType *pointee_or_element_compiler_type) const {
530 if (IsValid())
531 if (auto type_system_sp = GetTypeSystem())
532 return type_system_sp->GetTypeInfo(m_type,
533 pointee_or_element_compiler_type);
534 return 0;
535}
536
538 if (IsValid())
539 if (auto type_system_sp = GetTypeSystem())
540 return type_system_sp->GetMinimumLanguage(m_type);
542}
543
544lldb::TypeClass CompilerType::GetTypeClass() const {
545 if (IsValid())
546 if (auto type_system_sp = GetTypeSystem())
547 return type_system_sp->GetTypeClass(m_type);
548 return lldb::eTypeClassInvalid;
549}
550
553 m_type_system = type_system;
554 m_type = type;
555}
556
562
564 if (IsValid())
565 if (auto type_system_sp = GetTypeSystem())
566 return type_system_sp->GetTypeQualifiers(m_type);
567 return 0;
568}
569
570// Creating related types
571
574 if (IsValid()) {
575 if (auto type_system_sp = GetTypeSystem())
576 return type_system_sp->GetArrayElementType(m_type, exe_scope);
577 }
578 return CompilerType();
579}
580
582 if (IsValid()) {
583 if (auto type_system_sp = GetTypeSystem())
584 return type_system_sp->GetArrayType(m_type, size);
585 }
586 return CompilerType();
587}
588
590 if (IsValid())
591 if (auto type_system_sp = GetTypeSystem())
592 return type_system_sp->GetCanonicalType(m_type);
593 return CompilerType();
594}
595
597 if (IsValid())
598 if (auto type_system_sp = GetTypeSystem())
599 return type_system_sp->GetFullyUnqualifiedType(m_type);
600 return CompilerType();
601}
602
604 if (IsValid())
605 if (auto type_system_sp = GetTypeSystem())
606 return type_system_sp->GetEnumerationIntegerType(m_type);
607 return CompilerType();
608}
609
611 if (IsValid()) {
612 if (auto type_system_sp = GetTypeSystem())
613 return type_system_sp->GetFunctionArgumentCount(m_type);
614 }
615 return -1;
616}
617
619 if (IsValid()) {
620 if (auto type_system_sp = GetTypeSystem())
621 return type_system_sp->GetFunctionArgumentTypeAtIndex(m_type, idx);
622 }
623 return CompilerType();
624}
625
627 if (IsValid()) {
628 if (auto type_system_sp = GetTypeSystem())
629 return type_system_sp->GetFunctionReturnType(m_type);
630 }
631 return CompilerType();
632}
633
635 if (IsValid()) {
636 if (auto type_system_sp = GetTypeSystem())
637 return type_system_sp->GetNumMemberFunctions(m_type);
638 }
639 return 0;
640}
641
643 if (IsValid()) {
644 if (auto type_system_sp = GetTypeSystem())
645 return type_system_sp->GetMemberFunctionAtIndex(m_type, idx);
646 }
647 return TypeMemberFunctionImpl();
648}
649
651 if (IsValid())
652 if (auto type_system_sp = GetTypeSystem())
653 return type_system_sp->GetNonReferenceType(m_type);
654 return CompilerType();
655}
656
658 if (IsValid()) {
659 if (auto type_system_sp = GetTypeSystem())
660 return type_system_sp->GetPointeeType(m_type);
661 }
662 return CompilerType();
663}
664
666 if (IsValid()) {
667 if (auto type_system_sp = GetTypeSystem())
668 return type_system_sp->GetPointerType(m_type);
669 }
670 return CompilerType();
671}
672
674 if (IsValid())
675 if (auto type_system_sp = GetTypeSystem())
676 return type_system_sp->AddPtrAuthModifier(m_type, payload);
677 return CompilerType();
678}
679
681 if (IsValid())
682 if (auto type_system_sp = GetTypeSystem())
683 return type_system_sp->GetLValueReferenceType(m_type);
684 return CompilerType();
685}
686
688 if (IsValid())
689 if (auto type_system_sp = GetTypeSystem())
690 return type_system_sp->GetRValueReferenceType(m_type);
691 return CompilerType();
692}
693
695 if (IsValid())
696 if (auto type_system_sp = GetTypeSystem())
697 return type_system_sp->GetAtomicType(m_type);
698 return CompilerType();
699}
700
702 if (IsValid())
703 if (auto type_system_sp = GetTypeSystem())
704 return type_system_sp->AddConstModifier(m_type);
705 return CompilerType();
706}
707
709 if (IsValid())
710 if (auto type_system_sp = GetTypeSystem())
711 return type_system_sp->AddVolatileModifier(m_type);
712 return CompilerType();
713}
714
716 if (IsValid())
717 if (auto type_system_sp = GetTypeSystem())
718 return type_system_sp->AddRestrictModifier(m_type);
719 return CompilerType();
720}
721
723 const CompilerDeclContext &decl_ctx,
724 uint32_t payload) const {
725 if (IsValid())
726 if (auto type_system_sp = GetTypeSystem())
727 return type_system_sp->CreateTypedef(m_type, name, decl_ctx, payload);
728 return CompilerType();
729}
730
732 if (IsValid())
733 if (auto type_system_sp = GetTypeSystem())
734 return type_system_sp->GetTypedefedType(m_type);
735 return CompilerType();
736}
737
738// Create related types using the current type's AST
739
742 if (IsValid())
743 if (auto type_system_sp = GetTypeSystem())
744 return type_system_sp->GetBasicTypeFromAST(basic_type);
745 return CompilerType();
746}
747// Exploring the type
748
749llvm::Expected<uint64_t>
751 if (IsValid())
752 if (auto type_system_sp = GetTypeSystem())
753 return type_system_sp->GetBitSize(m_type, exe_scope);
754 return llvm::createStringError("Invalid type: Cannot determine size");
755}
756
757llvm::Expected<uint64_t>
759 auto bit_size_or_err = GetBitSize(exe_scope);
760 if (!bit_size_or_err)
761 return bit_size_or_err.takeError();
762 return (*bit_size_or_err + 7) / 8;
763}
764
765std::optional<size_t>
767 if (IsValid())
768 if (auto type_system_sp = GetTypeSystem())
769 return type_system_sp->GetTypeBitAlign(m_type, exe_scope);
770 return {};
771}
772
774 if (IsValid())
775 if (auto type_system_sp = GetTypeSystem())
776 return type_system_sp->GetEncoding(m_type);
778}
779
781 if (IsValid())
782 if (auto type_system_sp = GetTypeSystem())
783 return type_system_sp->GetFormat(m_type);
785}
786
787llvm::Expected<uint32_t>
788CompilerType::GetNumChildren(bool omit_empty_base_classes,
789 const ExecutionContext *exe_ctx) const {
790 if (IsValid())
791 if (auto type_system_sp = GetTypeSystem())
792 return type_system_sp->GetNumChildren(m_type, omit_empty_base_classes,
793 exe_ctx);
794 return llvm::createStringError("invalid type");
795}
796
798 if (IsValid())
799 if (auto type_system_sp = GetTypeSystem())
800 return type_system_sp->GetBasicTypeEnumeration(m_type);
801 return eBasicTypeInvalid;
802}
803
805 std::function<bool(const CompilerType &integer_type,
806 ConstString name,
807 const llvm::APSInt &value)> const &callback) const {
808 if (IsValid())
809 if (auto type_system_sp = GetTypeSystem())
810 return type_system_sp->ForEachEnumerator(m_type, callback);
811}
812
814 if (IsValid())
815 if (auto type_system_sp = GetTypeSystem())
816 return type_system_sp->GetNumFields(m_type);
817 return 0;
818}
819
820CompilerType CompilerType::GetFieldAtIndex(size_t idx, std::string &name,
821 uint64_t *bit_offset_ptr,
822 uint32_t *bitfield_bit_size_ptr,
823 bool *is_bitfield_ptr) const {
824 if (IsValid())
825 if (auto type_system_sp = GetTypeSystem())
826 return type_system_sp->GetFieldAtIndex(m_type, idx, name, bit_offset_ptr,
827 bitfield_bit_size_ptr, is_bitfield_ptr);
828 return CompilerType();
829}
830
832 if (IsValid())
833 if (auto type_system_sp = GetTypeSystem())
834 return type_system_sp->GetNumDirectBaseClasses(m_type);
835 return 0;
836}
837
839 if (IsValid())
840 if (auto type_system_sp = GetTypeSystem())
841 return type_system_sp->GetNumVirtualBaseClasses(m_type);
842 return 0;
843}
844
847 uint32_t *bit_offset_ptr) const {
848 if (IsValid())
849 if (auto type_system_sp = GetTypeSystem())
850 return type_system_sp->GetDirectBaseClassAtIndex(m_type, idx,
851 bit_offset_ptr);
852 return CompilerType();
853}
854
857 uint32_t *bit_offset_ptr) const {
858 if (IsValid())
859 if (auto type_system_sp = GetTypeSystem())
860 return type_system_sp->GetVirtualBaseClassAtIndex(m_type, idx,
861 bit_offset_ptr);
862 return CompilerType();
863}
864
866 if (IsValid())
868 return CompilerDecl();
869}
870
871llvm::Expected<CompilerType> CompilerType::GetDereferencedType(
872 ExecutionContext *exe_ctx, std::string &deref_name,
873 uint32_t &deref_byte_size, int32_t &deref_byte_offset, ValueObject *valobj,
874 uint64_t &language_flags) const {
875 if (IsValid())
876 if (auto type_system_sp = GetTypeSystem())
877 return type_system_sp->GetDereferencedType(
878 m_type, exe_ctx, deref_name, deref_byte_size, deref_byte_offset,
879 valobj, language_flags);
880 return CompilerType();
881}
882
883llvm::Expected<CompilerType> CompilerType::GetChildCompilerTypeAtIndex(
884 ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers,
885 bool omit_empty_base_classes, bool ignore_array_bounds,
886 std::string &child_name, uint32_t &child_byte_size,
887 int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size,
888 uint32_t &child_bitfield_bit_offset, bool &child_is_base_class,
889 bool &child_is_deref_of_parent, ValueObject *valobj,
890 uint64_t &language_flags) const {
891 if (IsValid())
892 if (auto type_system_sp = GetTypeSystem())
893 return type_system_sp->GetChildCompilerTypeAtIndex(
894 m_type, exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
895 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
896 child_bitfield_bit_size, child_bitfield_bit_offset,
897 child_is_base_class, child_is_deref_of_parent, valobj,
898 language_flags);
899 return CompilerType();
900}
901
902// Look for a child member (doesn't include base classes, but it does include
903// their members) in the type hierarchy. Returns an index path into
904// "clang_type" on how to reach the appropriate member.
905//
906// class A
907// {
908// public:
909// int m_a;
910// int m_b;
911// };
912//
913// class B
914// {
915// };
916//
917// class C :
918// public B,
919// public A
920// {
921// };
922//
923// If we have a clang type that describes "class C", and we wanted to looked
924// "m_b" in it:
925//
926// With omit_empty_base_classes == false we would get an integer array back
927// with: { 1, 1 } The first index 1 is the child index for "class A" within
928// class C The second index 1 is the child index for "m_b" within class A
929//
930// With omit_empty_base_classes == true we would get an integer array back
931// with: { 0, 1 } The first index 0 is the child index for "class A" within
932// class C (since class B doesn't have any members it doesn't count) The second
933// index 1 is the child index for "m_b" within class A
934
936 llvm::StringRef name, bool omit_empty_base_classes,
937 std::vector<uint32_t> &child_indexes) const {
938 if (IsValid() && !name.empty()) {
939 if (auto type_system_sp = GetTypeSystem())
940 return type_system_sp->GetIndexOfChildMemberWithName(
941 m_type, name, omit_empty_base_classes, child_indexes);
942 }
943 return 0;
944}
945
947CompilerType::GetDirectNestedTypeWithName(llvm::StringRef name) const {
948 if (IsValid() && !name.empty()) {
949 if (auto type_system_sp = GetTypeSystem())
950 return type_system_sp->GetDirectNestedTypeWithName(m_type, name);
951 }
952 return CompilerType();
953}
954
955size_t CompilerType::GetNumTemplateArguments(bool expand_pack) const {
956 if (IsValid()) {
957 if (auto type_system_sp = GetTypeSystem())
958 return type_system_sp->GetNumTemplateArguments(m_type, expand_pack);
959 }
960 return 0;
961}
962
964CompilerType::GetTemplateArgumentKind(size_t idx, bool expand_pack) const {
965 if (IsValid())
966 if (auto type_system_sp = GetTypeSystem())
967 return type_system_sp->GetTemplateArgumentKind(m_type, idx, expand_pack);
969}
970
972 bool expand_pack) const {
973 if (IsValid()) {
974 if (auto type_system_sp = GetTypeSystem())
975 return type_system_sp->GetTypeTemplateArgument(m_type, idx, expand_pack);
976 }
977 return CompilerType();
978}
979
980std::optional<CompilerType::IntegralTemplateArgument>
981CompilerType::GetIntegralTemplateArgument(size_t idx, bool expand_pack) const {
982 if (IsValid())
983 if (auto type_system_sp = GetTypeSystem())
984 return type_system_sp->GetIntegralTemplateArgument(m_type, idx, expand_pack);
985 return std::nullopt;
986}
987
989 if (IsValid())
990 if (auto type_system_sp = GetTypeSystem())
991 return type_system_sp->GetTypeForFormatters(m_type);
992 return CompilerType();
993}
994
996 if (IsValid())
997 if (auto type_system_sp = GetTypeSystem())
998 return type_system_sp->ShouldPrintAsOneLiner(m_type, valobj);
999 return eLazyBoolCalculate;
1000}
1001
1003 if (IsValid())
1004 if (auto type_system_sp = GetTypeSystem())
1005 return type_system_sp->IsMeaninglessWithoutDynamicResolution(m_type);
1006 return false;
1007}
1008
1009// Get the index of the child of "clang_type" whose name matches. This function
1010// doesn't descend into the children, but only looks one level deep and name
1011// matches can include base class names.
1012
1013llvm::Expected<uint32_t>
1015 bool omit_empty_base_classes) const {
1016 if (IsValid() && !name.empty()) {
1017 if (auto type_system_sp = GetTypeSystem())
1018 return type_system_sp->GetIndexOfChildWithName(m_type, name,
1019 omit_empty_base_classes);
1020 }
1021 return llvm::createStringError("Type has no child named '%s'",
1022 name.str().c_str());
1023}
1024
1025// Dumping types
1026
1028 const DataExtractor &data,
1029 lldb::offset_t byte_offset, size_t byte_size,
1030 uint32_t bitfield_bit_size,
1031 uint32_t bitfield_bit_offset,
1032 ExecutionContextScope *exe_scope) {
1033 if (IsValid())
1034 if (auto type_system_sp = GetTypeSystem())
1035 return type_system_sp->DumpTypeValue(
1036 m_type, *s, format, data, byte_offset, byte_size, bitfield_bit_size,
1037 bitfield_bit_offset, exe_scope);
1038 return false;
1039}
1040
1042 if (IsValid())
1043 if (auto type_system_sp = GetTypeSystem())
1044 type_system_sp->DumpTypeDescription(m_type, level);
1045}
1046
1048 lldb::DescriptionLevel level) const {
1049 if (IsValid())
1050 if (auto type_system_sp = GetTypeSystem())
1051 type_system_sp->DumpTypeDescription(m_type, *s, level);
1052}
1053
1054#ifndef NDEBUG
1055LLVM_DUMP_METHOD void CompilerType::dump() const {
1056 if (IsValid())
1057 if (auto type_system_sp = GetTypeSystem())
1058 return type_system_sp->dump(m_type);
1059 llvm::errs() << "<invalid>\n";
1060}
1061#endif
1062
1064 lldb::offset_t data_byte_offset,
1065 size_t data_byte_size, Scalar &value,
1066 ExecutionContextScope *exe_scope) const {
1067 if (!IsValid())
1068 return false;
1069
1070 if (IsAggregateType()) {
1071 return false; // Aggregate types don't have scalar values
1072 } else {
1073 // FIXME: check that type is scalar instead of checking encoding?
1074 lldb::Encoding encoding = GetEncoding();
1075
1076 if (encoding == lldb::eEncodingInvalid || (GetTypeInfo() & eTypeIsComplex))
1077 return false;
1078
1079 auto byte_size_or_err = GetByteSize(exe_scope);
1080 if (!byte_size_or_err) {
1082 GetLog(LLDBLog::Types), byte_size_or_err.takeError(),
1083 "Cannot get value as scalar: Cannot determine type size: {0}");
1084 return false;
1085 }
1086 uint64_t byte_size = *byte_size_or_err;
1087
1088 // A bit or byte size of 0 is not a bug, but it doesn't make sense to read a
1089 // scalar of zero size.
1090 if (byte_size == 0)
1091 return false;
1092
1093 lldb::offset_t offset = data_byte_offset;
1094 switch (encoding) {
1096 break;
1098 break;
1100 if (byte_size <= sizeof(unsigned long long)) {
1101 uint64_t uval64 = data.GetMaxU64(&offset, byte_size);
1102 if (byte_size <= sizeof(unsigned int)) {
1103 value = (unsigned int)uval64;
1104 return true;
1105 } else if (byte_size <= sizeof(unsigned long)) {
1106 value = (unsigned long)uval64;
1107 return true;
1108 } else if (byte_size <= sizeof(unsigned long long)) {
1109 value = (unsigned long long)uval64;
1110 return true;
1111 } else
1112 value.Clear();
1113 }
1114 break;
1115
1117 if (byte_size <= sizeof(long long)) {
1118 int64_t sval64 = data.GetMaxS64(&offset, byte_size);
1119 if (byte_size <= sizeof(int)) {
1120 value = (int)sval64;
1121 return true;
1122 } else if (byte_size <= sizeof(long)) {
1123 value = (long)sval64;
1124 return true;
1125 } else if (byte_size <= sizeof(long long)) {
1126 value = (long long)sval64;
1127 return true;
1128 } else
1129 value.Clear();
1130 }
1131 break;
1132
1134 if (byte_size <= sizeof(long double)) {
1135 uint32_t u32;
1136 uint64_t u64;
1137 if (byte_size == sizeof(float)) {
1138 if (sizeof(float) == sizeof(uint32_t)) {
1139 u32 = data.GetU32(&offset);
1140 value = *((float *)&u32);
1141 return true;
1142 } else if (sizeof(float) == sizeof(uint64_t)) {
1143 u64 = data.GetU64(&offset);
1144 value = *((float *)&u64);
1145 return true;
1146 }
1147 } else if (byte_size == sizeof(double)) {
1148 if (sizeof(double) == sizeof(uint32_t)) {
1149 u32 = data.GetU32(&offset);
1150 value = *((double *)&u32);
1151 return true;
1152 } else if (sizeof(double) == sizeof(uint64_t)) {
1153 u64 = data.GetU64(&offset);
1154 value = *((double *)&u64);
1155 return true;
1156 }
1157 } else if (byte_size == sizeof(long double)) {
1158 if (sizeof(long double) == sizeof(uint32_t)) {
1159 u32 = data.GetU32(&offset);
1160 value = *((long double *)&u32);
1161 return true;
1162 } else if (sizeof(long double) == sizeof(uint64_t)) {
1163 u64 = data.GetU64(&offset);
1164 value = *((long double *)&u64);
1165 return true;
1166 }
1167 }
1168 }
1169 break;
1170 }
1171 }
1172 return false;
1173}
1174
1177 : m_type_system(type_system.GetSharedPointer()), m_type(type) {
1178 assert(Verify() && "verification failed");
1179}
1180
1183 : m_type_system(type_system), m_type(type) {
1184 assert(Verify() && "verification failed");
1185}
1186
1187#ifndef NDEBUG
1189 if (!IsValid())
1190 return true;
1191 if (auto type_system_sp = GetTypeSystem())
1192 return type_system_sp->Verify(m_type);
1193 return true;
1194}
1195#endif
1196
1200
1202 const CompilerType::TypeSystemSPWrapper &other) const {
1203 if (!m_typesystem_sp && !other.m_typesystem_sp)
1204 return true;
1205 if (m_typesystem_sp && other.m_typesystem_sp)
1206 return m_typesystem_sp.get() == other.m_typesystem_sp.get();
1207 return false;
1208}
1209
1214
1216 const lldb_private::CompilerType &rhs) {
1217 return lhs.GetTypeSystem() == rhs.GetTypeSystem() &&
1218 lhs.GetOpaqueQualType() == rhs.GetOpaqueQualType();
1219}
1220
1222 const lldb_private::CompilerType &rhs) {
1223 return !(lhs == rhs);
1224}
#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
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.
bool IsFloatingPointType(bool &is_complex) const
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:362
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().
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