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