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 // Unscoped enums are always considered as promotable, even if their
374 // underlying type does not need to be promoted (e.g. "int").
376 return true;
377
378 switch (GetBasicTypeEnumeration()) {
390 return true;
391
392 default:
393 return false;
394 }
395
396 llvm_unreachable("All cases handled above.");
397}
398
400 if (!IsValid())
401 return false;
402
403 return IsPointerType() &&
405}
406
408 if (!IsValid())
409 return false;
410
411 return GetCanonicalType().GetTypeClass() &
412 (lldb::eTypeClassClass | lldb::eTypeClassStruct |
413 lldb::eTypeClassUnion);
414}
415
417 CompilerType *virtual_base,
418 bool carry_virtual) const {
419 if (CompareTypes(target_base))
420 return carry_virtual;
421
422 if (!carry_virtual) {
423 uint32_t num_virtual_bases = GetNumVirtualBaseClasses();
424 for (uint32_t i = 0; i < num_virtual_bases; ++i) {
425 uint32_t bit_offset;
426 auto base = GetVirtualBaseClassAtIndex(i, &bit_offset);
427 if (base.IsVirtualBase(target_base, virtual_base,
428 /*carry_virtual*/ true)) {
429 if (virtual_base)
430 *virtual_base = base;
431
432 return true;
433 }
434 }
435 }
436
437 uint32_t num_direct_bases = GetNumDirectBaseClasses();
438 for (uint32_t i = 0; i < num_direct_bases; ++i) {
439 uint32_t bit_offset;
440 auto base = GetDirectBaseClassAtIndex(i, &bit_offset);
441 if (base.IsVirtualBase(target_base, virtual_base, carry_virtual))
442 return true;
443 }
444
445 return false;
446}
447
452
456
458 auto name = GetTypeName();
459 auto canonical_name = GetCanonicalType().GetTypeName();
460 if (name.IsEmpty() || canonical_name.IsEmpty())
461 return "''"; // Should not happen, unless the input is broken somehow.
462
463 if (name == canonical_name)
464 return llvm::formatv("'{0}'", name);
465
466 return llvm::formatv("'{0}' (canonically referred to as '{1}')", name,
467 canonical_name);
468}
469
471 if (*this == rhs)
472 return true;
473
475 const ConstString rhs_name = rhs.GetFullyUnqualifiedType().GetTypeName();
476 return name == rhs_name;
477}
478
480 switch (GetTypeClass()) {
481 case lldb::eTypeClassClass:
482 return "class";
483 case lldb::eTypeClassEnumeration:
484 return "enum";
485 case lldb::eTypeClassStruct:
486 return "struct";
487 case lldb::eTypeClassUnion:
488 return "union";
489 default:
490 return "unknown";
491 }
492 llvm_unreachable("All cases are covered by code above.");
493}
494
496 uint32_t ret = 0;
497 uint32_t num_direct_bases = GetNumDirectBaseClasses();
498
499 for (uint32_t i = 0; i < num_direct_bases; ++i) {
500 uint32_t bit_offset;
501 CompilerType base_type = GetDirectBaseClassAtIndex(i, &bit_offset);
502 if (base_type.GetNumFields() > 0 ||
503 base_type.GetNumberOfNonEmptyBaseClasses() > 0)
504 ret += 1;
505 }
506 return ret;
507}
508
509// Type Completion
510
512 if (IsValid())
513 if (auto type_system_sp = GetTypeSystem())
514 return type_system_sp->GetCompleteType(m_type);
515 return false;
516}
517
518// AST related queries
520 if (auto type_system_sp = GetTypeSystem())
521 return type_system_sp->GetPointerByteSize();
522 return 0;
523}
524
526 if (IsValid()) {
527 if (auto type_system_sp = GetTypeSystem())
528 return type_system_sp->GetTypeName(m_type, BaseOnly);
529 }
530 return ConstString("<invalid>");
531}
532
534 if (IsValid())
535 if (auto type_system_sp = GetTypeSystem())
536 return type_system_sp->GetDisplayTypeName(m_type);
537 return ConstString("<invalid>");
538}
539
541 if (IsValid()) {
542 if (auto type_system_sp = GetTypeSystem())
543 return type_system_sp->GetMangledTypeName(m_type);
544 }
545 return ConstString("<invalid>");
546}
547
549 CompilerType *pointee_or_element_compiler_type) const {
550 if (IsValid())
551 if (auto type_system_sp = GetTypeSystem())
552 return type_system_sp->GetTypeInfo(m_type,
553 pointee_or_element_compiler_type);
554 return 0;
555}
556
558 if (IsValid())
559 if (auto type_system_sp = GetTypeSystem())
560 return type_system_sp->GetMinimumLanguage(m_type);
562}
563
564lldb::TypeClass CompilerType::GetTypeClass() const {
565 if (IsValid())
566 if (auto type_system_sp = GetTypeSystem())
567 return type_system_sp->GetTypeClass(m_type);
568 return lldb::eTypeClassInvalid;
569}
570
573 m_type_system = type_system;
574 m_type = type;
575}
576
582
584 if (IsValid())
585 if (auto type_system_sp = GetTypeSystem())
586 return type_system_sp->GetTypeQualifiers(m_type);
587 return 0;
588}
589
590// Creating related types
591
594 if (IsValid()) {
595 if (auto type_system_sp = GetTypeSystem())
596 return type_system_sp->GetArrayElementType(m_type, exe_scope);
597 }
598 return CompilerType();
599}
600
602 if (IsValid()) {
603 if (auto type_system_sp = GetTypeSystem())
604 return type_system_sp->GetArrayType(m_type, size);
605 }
606 return CompilerType();
607}
608
610 if (IsValid())
611 if (auto type_system_sp = GetTypeSystem())
612 return type_system_sp->GetCanonicalType(m_type);
613 return CompilerType();
614}
615
617 if (IsValid())
618 if (auto type_system_sp = GetTypeSystem())
619 return type_system_sp->GetFullyUnqualifiedType(m_type);
620 return CompilerType();
621}
622
624 if (IsValid())
625 if (auto type_system_sp = GetTypeSystem())
626 return type_system_sp->GetEnumerationIntegerType(m_type);
627 return CompilerType();
628}
629
631 if (IsValid()) {
632 if (auto type_system_sp = GetTypeSystem())
633 return type_system_sp->GetFunctionArgumentCount(m_type);
634 }
635 return -1;
636}
637
639 if (IsValid()) {
640 if (auto type_system_sp = GetTypeSystem())
641 return type_system_sp->GetFunctionArgumentTypeAtIndex(m_type, idx);
642 }
643 return CompilerType();
644}
645
647 if (IsValid()) {
648 if (auto type_system_sp = GetTypeSystem())
649 return type_system_sp->GetFunctionReturnType(m_type);
650 }
651 return CompilerType();
652}
653
655 if (IsValid()) {
656 if (auto type_system_sp = GetTypeSystem())
657 return type_system_sp->GetNumMemberFunctions(m_type);
658 }
659 return 0;
660}
661
663 if (IsValid()) {
664 if (auto type_system_sp = GetTypeSystem())
665 return type_system_sp->GetMemberFunctionAtIndex(m_type, idx);
666 }
667 return TypeMemberFunctionImpl();
668}
669
671 if (IsValid())
672 if (auto type_system_sp = GetTypeSystem())
673 return type_system_sp->GetNonReferenceType(m_type);
674 return CompilerType();
675}
676
678 if (IsValid()) {
679 if (auto type_system_sp = GetTypeSystem())
680 return type_system_sp->GetPointeeType(m_type);
681 }
682 return CompilerType();
683}
684
686 if (IsValid()) {
687 if (auto type_system_sp = GetTypeSystem())
688 return type_system_sp->GetPointerType(m_type);
689 }
690 return CompilerType();
691}
692
694 if (IsValid())
695 if (auto type_system_sp = GetTypeSystem())
696 return type_system_sp->AddPtrAuthModifier(m_type, payload);
697 return CompilerType();
698}
699
701 if (IsValid())
702 if (auto type_system_sp = GetTypeSystem())
703 return type_system_sp->GetLValueReferenceType(m_type);
704 return CompilerType();
705}
706
708 if (IsValid())
709 if (auto type_system_sp = GetTypeSystem())
710 return type_system_sp->GetRValueReferenceType(m_type);
711 return CompilerType();
712}
713
715 if (IsValid())
716 if (auto type_system_sp = GetTypeSystem())
717 return type_system_sp->GetAtomicType(m_type);
718 return CompilerType();
719}
720
722 if (IsValid())
723 if (auto type_system_sp = GetTypeSystem())
724 return type_system_sp->AddConstModifier(m_type);
725 return CompilerType();
726}
727
729 if (IsValid())
730 if (auto type_system_sp = GetTypeSystem())
731 return type_system_sp->AddVolatileModifier(m_type);
732 return CompilerType();
733}
734
736 if (IsValid())
737 if (auto type_system_sp = GetTypeSystem())
738 return type_system_sp->AddRestrictModifier(m_type);
739 return CompilerType();
740}
741
743 const CompilerDeclContext &decl_ctx,
744 uint32_t payload) const {
745 if (IsValid())
746 if (auto type_system_sp = GetTypeSystem())
747 return type_system_sp->CreateTypedef(m_type, name, decl_ctx, payload);
748 return CompilerType();
749}
750
752 if (IsValid())
753 if (auto type_system_sp = GetTypeSystem())
754 return type_system_sp->GetTypedefedType(m_type);
755 return CompilerType();
756}
757
758// Create related types using the current type's AST
759
762 if (IsValid())
763 if (auto type_system_sp = GetTypeSystem())
764 return type_system_sp->GetBasicTypeFromAST(basic_type);
765 return CompilerType();
766}
767// Exploring the type
768
769llvm::Expected<uint64_t>
771 if (IsValid())
772 if (auto type_system_sp = GetTypeSystem())
773 return type_system_sp->GetBitSize(m_type, exe_scope);
774 return llvm::createStringError("Invalid type: Cannot determine size");
775}
776
777llvm::Expected<uint64_t>
779 auto bit_size_or_err = GetBitSize(exe_scope);
780 if (!bit_size_or_err)
781 return bit_size_or_err.takeError();
782 return (*bit_size_or_err + 7) / 8;
783}
784
785std::optional<size_t>
787 if (IsValid())
788 if (auto type_system_sp = GetTypeSystem())
789 return type_system_sp->GetTypeBitAlign(m_type, exe_scope);
790 return {};
791}
792
794 if (IsValid())
795 if (auto type_system_sp = GetTypeSystem())
796 return type_system_sp->GetEncoding(m_type);
798}
799
801 if (IsValid())
802 if (auto type_system_sp = GetTypeSystem())
803 return type_system_sp->GetFormat(m_type);
805}
806
807llvm::Expected<uint32_t>
808CompilerType::GetNumChildren(bool omit_empty_base_classes,
809 const ExecutionContext *exe_ctx) const {
810 if (IsValid())
811 if (auto type_system_sp = GetTypeSystem())
812 return type_system_sp->GetNumChildren(m_type, omit_empty_base_classes,
813 exe_ctx);
814 return llvm::createStringError("invalid type");
815}
816
818 if (IsValid())
819 if (auto type_system_sp = GetTypeSystem())
820 return type_system_sp->GetBasicTypeEnumeration(m_type);
821 return eBasicTypeInvalid;
822}
823
825 std::function<bool(const CompilerType &integer_type,
826 ConstString name,
827 const llvm::APSInt &value)> const &callback) const {
828 if (IsValid())
829 if (auto type_system_sp = GetTypeSystem())
830 return type_system_sp->ForEachEnumerator(m_type, callback);
831}
832
834 if (IsValid())
835 if (auto type_system_sp = GetTypeSystem())
836 return type_system_sp->GetNumFields(m_type);
837 return 0;
838}
839
840CompilerType CompilerType::GetFieldAtIndex(size_t idx, std::string &name,
841 uint64_t *bit_offset_ptr,
842 uint32_t *bitfield_bit_size_ptr,
843 bool *is_bitfield_ptr) const {
844 if (IsValid())
845 if (auto type_system_sp = GetTypeSystem())
846 return type_system_sp->GetFieldAtIndex(m_type, idx, name, bit_offset_ptr,
847 bitfield_bit_size_ptr, is_bitfield_ptr);
848 return CompilerType();
849}
850
852 if (IsValid())
853 if (auto type_system_sp = GetTypeSystem())
854 return type_system_sp->GetNumDirectBaseClasses(m_type);
855 return 0;
856}
857
859 if (IsValid())
860 if (auto type_system_sp = GetTypeSystem())
861 return type_system_sp->GetNumVirtualBaseClasses(m_type);
862 return 0;
863}
864
867 uint32_t *bit_offset_ptr) const {
868 if (IsValid())
869 if (auto type_system_sp = GetTypeSystem())
870 return type_system_sp->GetDirectBaseClassAtIndex(m_type, idx,
871 bit_offset_ptr);
872 return CompilerType();
873}
874
877 uint32_t *bit_offset_ptr) const {
878 if (IsValid())
879 if (auto type_system_sp = GetTypeSystem())
880 return type_system_sp->GetVirtualBaseClassAtIndex(m_type, idx,
881 bit_offset_ptr);
882 return CompilerType();
883}
884
886 if (IsValid())
888 return CompilerDecl();
889}
890
891llvm::Expected<CompilerType> CompilerType::GetDereferencedType(
892 ExecutionContext *exe_ctx, std::string &deref_name,
893 uint32_t &deref_byte_size, int32_t &deref_byte_offset, ValueObject *valobj,
894 uint64_t &language_flags) const {
895 if (IsValid())
896 if (auto type_system_sp = GetTypeSystem())
897 return type_system_sp->GetDereferencedType(
898 m_type, exe_ctx, deref_name, deref_byte_size, deref_byte_offset,
899 valobj, language_flags);
900 return CompilerType();
901}
902
903llvm::Expected<CompilerType> CompilerType::GetChildCompilerTypeAtIndex(
904 ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers,
905 bool omit_empty_base_classes, bool ignore_array_bounds,
906 std::string &child_name, uint32_t &child_byte_size,
907 int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size,
908 uint32_t &child_bitfield_bit_offset, bool &child_is_base_class,
909 bool &child_is_deref_of_parent, ValueObject *valobj,
910 uint64_t &language_flags) const {
911 if (IsValid())
912 if (auto type_system_sp = GetTypeSystem())
913 return type_system_sp->GetChildCompilerTypeAtIndex(
914 m_type, exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
915 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
916 child_bitfield_bit_size, child_bitfield_bit_offset,
917 child_is_base_class, child_is_deref_of_parent, valobj,
918 language_flags);
919 return CompilerType();
920}
921
922// Look for a child member (doesn't include base classes, but it does include
923// their members) in the type hierarchy. Returns an index path into
924// "clang_type" on how to reach the appropriate member.
925//
926// class A
927// {
928// public:
929// int m_a;
930// int m_b;
931// };
932//
933// class B
934// {
935// };
936//
937// class C :
938// public B,
939// public A
940// {
941// };
942//
943// If we have a clang type that describes "class C", and we wanted to looked
944// "m_b" in it:
945//
946// With omit_empty_base_classes == false we would get an integer array back
947// with: { 1, 1 } The first index 1 is the child index for "class A" within
948// class C The second index 1 is the child index for "m_b" within class A
949//
950// With omit_empty_base_classes == true we would get an integer array back
951// with: { 0, 1 } The first index 0 is the child index for "class A" within
952// class C (since class B doesn't have any members it doesn't count) The second
953// index 1 is the child index for "m_b" within class A
954
956 llvm::StringRef name, bool omit_empty_base_classes,
957 std::vector<uint32_t> &child_indexes) const {
958 if (IsValid() && !name.empty()) {
959 if (auto type_system_sp = GetTypeSystem())
960 return type_system_sp->GetIndexOfChildMemberWithName(
961 m_type, name, omit_empty_base_classes, child_indexes);
962 }
963 return 0;
964}
965
967CompilerType::GetDirectNestedTypeWithName(llvm::StringRef name) const {
968 if (IsValid() && !name.empty()) {
969 if (auto type_system_sp = GetTypeSystem())
970 return type_system_sp->GetDirectNestedTypeWithName(m_type, name);
971 }
972 return CompilerType();
973}
974
975size_t CompilerType::GetNumTemplateArguments(bool expand_pack) const {
976 if (IsValid()) {
977 if (auto type_system_sp = GetTypeSystem())
978 return type_system_sp->GetNumTemplateArguments(m_type, expand_pack);
979 }
980 return 0;
981}
982
984CompilerType::GetTemplateArgumentKind(size_t idx, bool expand_pack) const {
985 if (IsValid())
986 if (auto type_system_sp = GetTypeSystem())
987 return type_system_sp->GetTemplateArgumentKind(m_type, idx, expand_pack);
989}
990
992 bool expand_pack) const {
993 if (IsValid()) {
994 if (auto type_system_sp = GetTypeSystem())
995 return type_system_sp->GetTypeTemplateArgument(m_type, idx, expand_pack);
996 }
997 return CompilerType();
998}
999
1000std::optional<CompilerType::IntegralTemplateArgument>
1001CompilerType::GetIntegralTemplateArgument(size_t idx, bool expand_pack) const {
1002 if (IsValid())
1003 if (auto type_system_sp = GetTypeSystem())
1004 return type_system_sp->GetIntegralTemplateArgument(m_type, idx, expand_pack);
1005 return std::nullopt;
1006}
1007
1009 if (IsValid())
1010 if (auto type_system_sp = GetTypeSystem())
1011 return type_system_sp->GetTypeForFormatters(m_type);
1012 return CompilerType();
1013}
1014
1016 if (IsValid())
1017 if (auto type_system_sp = GetTypeSystem())
1018 return type_system_sp->ShouldPrintAsOneLiner(m_type, valobj);
1019 return eLazyBoolCalculate;
1020}
1021
1023 if (IsValid())
1024 if (auto type_system_sp = GetTypeSystem())
1025 return type_system_sp->IsMeaninglessWithoutDynamicResolution(m_type);
1026 return false;
1027}
1028
1029// Get the index of the child of "clang_type" whose name matches. This function
1030// doesn't descend into the children, but only looks one level deep and name
1031// matches can include base class names.
1032
1033llvm::Expected<uint32_t>
1035 bool omit_empty_base_classes) const {
1036 if (IsValid() && !name.empty()) {
1037 if (auto type_system_sp = GetTypeSystem())
1038 return type_system_sp->GetIndexOfChildWithName(m_type, name,
1039 omit_empty_base_classes);
1040 }
1041 return llvm::createStringError("Type has no child named '%s'",
1042 name.str().c_str());
1043}
1044
1045// Dumping types
1046
1048 const DataExtractor &data,
1049 lldb::offset_t byte_offset, size_t byte_size,
1050 uint32_t bitfield_bit_size,
1051 uint32_t bitfield_bit_offset,
1052 ExecutionContextScope *exe_scope) {
1053 if (IsValid())
1054 if (auto type_system_sp = GetTypeSystem())
1055 return type_system_sp->DumpTypeValue(
1056 m_type, *s, format, data, byte_offset, byte_size, bitfield_bit_size,
1057 bitfield_bit_offset, exe_scope);
1058 return false;
1059}
1060
1062 if (IsValid())
1063 if (auto type_system_sp = GetTypeSystem())
1064 type_system_sp->DumpTypeDescription(m_type, level);
1065}
1066
1068 lldb::DescriptionLevel level) const {
1069 if (IsValid())
1070 if (auto type_system_sp = GetTypeSystem())
1071 type_system_sp->DumpTypeDescription(m_type, *s, level);
1072}
1073
1074#ifndef NDEBUG
1075LLVM_DUMP_METHOD void CompilerType::dump() const {
1076 if (IsValid())
1077 if (auto type_system_sp = GetTypeSystem())
1078 return type_system_sp->dump(m_type);
1079 llvm::errs() << "<invalid>\n";
1080}
1081#endif
1082
1084 lldb::offset_t data_byte_offset,
1085 size_t data_byte_size, Scalar &value,
1086 ExecutionContextScope *exe_scope) const {
1087 if (!IsValid())
1088 return false;
1089
1090 if (IsAggregateType()) {
1091 return false; // Aggregate types don't have scalar values
1092 } else {
1093 // FIXME: check that type is scalar instead of checking encoding?
1094 lldb::Encoding encoding = GetEncoding();
1095
1096 if (encoding == lldb::eEncodingInvalid || (GetTypeInfo() & eTypeIsComplex))
1097 return false;
1098
1099 auto byte_size_or_err = GetByteSize(exe_scope);
1100 if (!byte_size_or_err) {
1102 GetLog(LLDBLog::Types), byte_size_or_err.takeError(),
1103 "Cannot get value as scalar: Cannot determine type size: {0}");
1104 return false;
1105 }
1106 uint64_t byte_size = *byte_size_or_err;
1107
1108 // A bit or byte size of 0 is not a bug, but it doesn't make sense to read a
1109 // scalar of zero size.
1110 if (byte_size == 0)
1111 return false;
1112
1113 lldb::offset_t offset = data_byte_offset;
1114 switch (encoding) {
1116 break;
1118 break;
1120 if (byte_size <= sizeof(unsigned long long)) {
1121 uint64_t uval64 = data.GetMaxU64(&offset, byte_size);
1122 if (byte_size <= sizeof(unsigned int)) {
1123 value = (unsigned int)uval64;
1124 return true;
1125 } else if (byte_size <= sizeof(unsigned long)) {
1126 value = (unsigned long)uval64;
1127 return true;
1128 } else if (byte_size <= sizeof(unsigned long long)) {
1129 value = (unsigned long long)uval64;
1130 return true;
1131 } else
1132 value.Clear();
1133 }
1134 break;
1135
1137 if (byte_size <= sizeof(long long)) {
1138 int64_t sval64 = data.GetMaxS64(&offset, byte_size);
1139 if (byte_size <= sizeof(int)) {
1140 value = (int)sval64;
1141 return true;
1142 } else if (byte_size <= sizeof(long)) {
1143 value = (long)sval64;
1144 return true;
1145 } else if (byte_size <= sizeof(long long)) {
1146 value = (long long)sval64;
1147 return true;
1148 } else
1149 value.Clear();
1150 }
1151 break;
1152
1154 if (byte_size <= sizeof(long double)) {
1155 uint32_t u32;
1156 uint64_t u64;
1157 if (byte_size == sizeof(float)) {
1158 if (sizeof(float) == sizeof(uint32_t)) {
1159 u32 = data.GetU32(&offset);
1160 value = *((float *)&u32);
1161 return true;
1162 } else if (sizeof(float) == sizeof(uint64_t)) {
1163 u64 = data.GetU64(&offset);
1164 value = *((float *)&u64);
1165 return true;
1166 }
1167 } else if (byte_size == sizeof(double)) {
1168 if (sizeof(double) == sizeof(uint32_t)) {
1169 u32 = data.GetU32(&offset);
1170 value = *((double *)&u32);
1171 return true;
1172 } else if (sizeof(double) == sizeof(uint64_t)) {
1173 u64 = data.GetU64(&offset);
1174 value = *((double *)&u64);
1175 return true;
1176 }
1177 } else if (byte_size == sizeof(long double)) {
1178 if (sizeof(long double) == sizeof(uint32_t)) {
1179 u32 = data.GetU32(&offset);
1180 value = *((long double *)&u32);
1181 return true;
1182 } else if (sizeof(long double) == sizeof(uint64_t)) {
1183 u64 = data.GetU64(&offset);
1184 value = *((long double *)&u64);
1185 return true;
1186 }
1187 }
1188 }
1189 break;
1190 }
1191 }
1192 return false;
1193}
1194
1197 : m_type_system(type_system.GetSharedPointer()), m_type(type) {
1198 assert(Verify() && "verification failed");
1199}
1200
1203 : m_type_system(type_system), m_type(type) {
1204 assert(Verify() && "verification failed");
1205}
1206
1207#ifndef NDEBUG
1209 if (!IsValid())
1210 return true;
1211 if (auto type_system_sp = GetTypeSystem())
1212 return type_system_sp->Verify(m_type);
1213 return true;
1214}
1215#endif
1216
1220
1222 const CompilerType::TypeSystemSPWrapper &other) const {
1223 if (!m_typesystem_sp && !other.m_typesystem_sp)
1224 return true;
1225 if (m_typesystem_sp && other.m_typesystem_sp)
1226 return m_typesystem_sp.get() == other.m_typesystem_sp.get();
1227 return false;
1228}
1229
1234
1236 const lldb_private::CompilerType &rhs) {
1237 return lhs.GetTypeSystem() == rhs.GetTypeSystem() &&
1238 lhs.GetOpaqueQualType() == rhs.GetOpaqueQualType();
1239}
1240
1242 const lldb_private::CompilerType &rhs) {
1243 return !(lhs == rhs);
1244}
#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().
@ 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