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#include "lldb/Core/Debugger.h"
11#include "lldb/Symbol/Type.h"
13#include "lldb/Target/Process.h"
18#include "lldb/Utility/Log.h"
19#include "lldb/Utility/Scalar.h"
20#include "lldb/Utility/Stream.h"
23#include "llvm/Support/ErrorExtras.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
328std::optional<uint32_t> CompilerType::GetTargetAddressSpace() const {
329 if (IsValid())
330 if (auto type_system_sp = GetTypeSystem())
331 return type_system_sp->GetTargetAddressSpace(m_type);
332 return std::nullopt;
333}
334
336 if (!IsValid())
337 return false;
338
340}
341
343 CompilerType element_type;
344 if (IsArrayType(&element_type))
345 return element_type.IsScalarType();
346 return false;
347}
348
350 if (IsValid())
351 if (auto type_system_sp = GetTypeSystem())
352 return type_system_sp->IsBeingDefined(m_type);
353 return false;
354}
355
357 bool is_signed = false; // May be reset by the call below.
358 return IsIntegerType(is_signed);
359}
360
362 bool is_signed = false; // May be reset by the call below.
363 return IsEnumerationType(is_signed);
364}
365
369
373
375 return GetTypeInfo() & lldb::eTypeIsSigned;
376}
377
381
385
387 if (IsValid())
388 return GetEnumerationIntegerType().GetTypeInfo() & lldb::eTypeIsSigned;
389
390 return false;
391}
392
396
398 if (IsValid())
399 if (auto type_system_sp = GetTypeSystem())
400 return type_system_sp->IsPromotableIntegerType(m_type);
401 return false;
402}
403
405 if (!IsValid())
406 return false;
407
408 return IsPointerType() &&
410}
411
413 if (!IsValid())
414 return false;
415
416 return GetCanonicalType().GetTypeClass() &
417 (lldb::eTypeClassClass | lldb::eTypeClassStruct |
418 lldb::eTypeClassUnion);
419}
420
422 CompilerType *virtual_base,
423 bool carry_virtual) const {
424 if (CompareTypes(target_base))
425 return carry_virtual;
426
427 if (!carry_virtual) {
428 uint32_t num_virtual_bases = GetNumVirtualBaseClasses();
429 for (uint32_t i = 0; i < num_virtual_bases; ++i) {
430 uint32_t bit_offset;
431 auto base = GetVirtualBaseClassAtIndex(i, &bit_offset);
432 if (base.IsVirtualBase(target_base, virtual_base,
433 /*carry_virtual*/ true)) {
434 if (virtual_base)
435 *virtual_base = base;
436
437 return true;
438 }
439 }
440 }
441
442 uint32_t num_direct_bases = GetNumDirectBaseClasses();
443 for (uint32_t i = 0; i < num_direct_bases; ++i) {
444 uint32_t bit_offset;
445 auto base = GetDirectBaseClassAtIndex(i, &bit_offset);
446 if (base.IsVirtualBase(target_base, virtual_base, carry_virtual))
447 return true;
448 }
449
450 return false;
451}
452
457
461
463 auto name = GetTypeName();
464 auto canonical_name = GetCanonicalType().GetTypeName();
465 if (name.IsEmpty() || canonical_name.IsEmpty())
466 return "''"; // Should not happen, unless the input is broken somehow.
467
468 if (name == canonical_name)
469 return llvm::formatv("'{0}'", name);
470
471 return llvm::formatv("'{0}' (canonically referred to as '{1}')", name,
472 canonical_name);
473}
474
476 if (*this == rhs)
477 return true;
478
480 const ConstString rhs_name = rhs.GetFullyUnqualifiedType().GetTypeName();
481 return name == rhs_name;
482}
483
485 switch (GetTypeClass()) {
486 case lldb::eTypeClassClass:
487 return "class";
488 case lldb::eTypeClassEnumeration:
489 return "enum";
490 case lldb::eTypeClassStruct:
491 return "struct";
492 case lldb::eTypeClassUnion:
493 return "union";
494 default:
495 return "unknown";
496 }
497 llvm_unreachable("All cases are covered by code above.");
498}
499
501 uint32_t ret = 0;
502 uint32_t num_direct_bases = GetNumDirectBaseClasses();
503
504 for (uint32_t i = 0; i < num_direct_bases; ++i) {
505 uint32_t bit_offset;
506 CompilerType base_type = GetDirectBaseClassAtIndex(i, &bit_offset);
507 if (base_type.GetNumFields() > 0 ||
508 base_type.GetNumberOfNonEmptyBaseClasses() > 0)
509 ret += 1;
510 }
511 return ret;
512}
513
514// Type Completion
515
517 if (IsValid())
518 if (auto type_system_sp = GetTypeSystem())
519 return type_system_sp->GetCompleteType(m_type);
520 return false;
521}
522
523// AST related queries
525 if (auto type_system_sp = GetTypeSystem())
526 return type_system_sp->GetPointerByteSize();
527 return 0;
528}
529
531 if (IsValid()) {
532 if (auto type_system_sp = GetTypeSystem())
533 return type_system_sp->GetTypeName(m_type, BaseOnly);
534 }
535 return ConstString("<invalid>");
536}
537
539 if (IsValid())
540 if (auto type_system_sp = GetTypeSystem())
541 return type_system_sp->GetDisplayTypeName(m_type);
542 return ConstString("<invalid>");
543}
544
546 if (IsValid()) {
547 if (auto type_system_sp = GetTypeSystem())
548 return type_system_sp->GetMangledTypeName(m_type);
549 }
550 return ConstString("<invalid>");
551}
552
554 CompilerType *pointee_or_element_compiler_type) const {
555 if (IsValid())
556 if (auto type_system_sp = GetTypeSystem())
557 return type_system_sp->GetTypeInfo(m_type,
558 pointee_or_element_compiler_type);
559 return 0;
560}
561
563 if (IsValid())
564 if (auto type_system_sp = GetTypeSystem())
565 return type_system_sp->GetMinimumLanguage(m_type);
567}
568
569lldb::TypeClass CompilerType::GetTypeClass() const {
570 if (IsValid())
571 if (auto type_system_sp = GetTypeSystem())
572 return type_system_sp->GetTypeClass(m_type);
573 return lldb::eTypeClassInvalid;
574}
575
578 m_type_system = type_system;
579 m_type = type;
580}
581
587
589 if (IsValid())
590 if (auto type_system_sp = GetTypeSystem())
591 return type_system_sp->GetTypeQualifiers(m_type);
592 return 0;
593}
594
595// Creating related types
596
599 if (IsValid()) {
600 if (auto type_system_sp = GetTypeSystem())
601 return type_system_sp->GetArrayElementType(m_type, exe_scope);
602 }
603 return CompilerType();
604}
605
607 if (IsValid()) {
608 if (auto type_system_sp = GetTypeSystem())
609 return type_system_sp->GetArrayType(m_type, size);
610 }
611 return CompilerType();
612}
613
615 if (IsValid())
616 if (auto type_system_sp = GetTypeSystem())
617 return type_system_sp->GetCanonicalType(m_type);
618 return CompilerType();
619}
620
622 if (IsValid())
623 if (auto type_system_sp = GetTypeSystem())
624 return type_system_sp->GetFullyUnqualifiedType(m_type);
625 return CompilerType();
626}
627
629 if (IsValid())
630 if (auto type_system_sp = GetTypeSystem())
631 return type_system_sp->GetEnumerationIntegerType(m_type);
632 return CompilerType();
633}
634
636 if (IsValid()) {
637 if (auto type_system_sp = GetTypeSystem())
638 return type_system_sp->GetFunctionArgumentCount(m_type);
639 }
640 return -1;
641}
642
644 if (IsValid()) {
645 if (auto type_system_sp = GetTypeSystem())
646 return type_system_sp->GetFunctionArgumentTypeAtIndex(m_type, idx);
647 }
648 return CompilerType();
649}
650
652 if (IsValid()) {
653 if (auto type_system_sp = GetTypeSystem())
654 return type_system_sp->GetFunctionReturnType(m_type);
655 }
656 return CompilerType();
657}
658
660 if (IsValid()) {
661 if (auto type_system_sp = GetTypeSystem())
662 return type_system_sp->GetNumMemberFunctions(m_type);
663 }
664 return 0;
665}
666
668 if (IsValid()) {
669 if (auto type_system_sp = GetTypeSystem())
670 return type_system_sp->GetMemberFunctionAtIndex(m_type, idx);
671 }
672 return TypeMemberFunctionImpl();
673}
674
676 if (IsValid())
677 if (auto type_system_sp = GetTypeSystem())
678 return type_system_sp->GetNonReferenceType(m_type);
679 return CompilerType();
680}
681
683 if (IsValid()) {
684 if (auto type_system_sp = GetTypeSystem())
685 return type_system_sp->GetPointeeType(m_type);
686 }
687 return CompilerType();
688}
689
691 if (IsValid()) {
692 if (auto type_system_sp = GetTypeSystem())
693 return type_system_sp->GetPointerType(m_type);
694 }
695 return CompilerType();
696}
697
699 if (IsValid())
700 if (auto type_system_sp = GetTypeSystem())
701 return type_system_sp->AddPtrAuthModifier(m_type, payload);
702 return CompilerType();
703}
704
706CompilerType::AddAddressSpaceModifier(uint32_t address_space) const {
707 if (IsValid())
708 if (auto type_system_sp = GetTypeSystem())
709 return type_system_sp->AddAddressSpaceModifier(m_type, address_space);
710 return CompilerType();
711}
712
714 if (IsValid())
715 if (auto type_system_sp = GetTypeSystem())
716 return type_system_sp->GetLValueReferenceType(m_type);
717 return CompilerType();
718}
719
721 if (IsValid())
722 if (auto type_system_sp = GetTypeSystem())
723 return type_system_sp->GetRValueReferenceType(m_type);
724 return CompilerType();
725}
726
728 if (IsValid())
729 if (auto type_system_sp = GetTypeSystem())
730 return type_system_sp->GetAtomicType(m_type);
731 return CompilerType();
732}
733
735 if (IsValid())
736 if (auto type_system_sp = GetTypeSystem())
737 return type_system_sp->AddConstModifier(m_type);
738 return CompilerType();
739}
740
742 if (IsValid())
743 if (auto type_system_sp = GetTypeSystem())
744 return type_system_sp->AddVolatileModifier(m_type);
745 return CompilerType();
746}
747
749 if (IsValid())
750 if (auto type_system_sp = GetTypeSystem())
751 return type_system_sp->AddRestrictModifier(m_type);
752 return CompilerType();
753}
754
756 const CompilerDeclContext &decl_ctx,
757 uint32_t payload) const {
758 if (IsValid())
759 if (auto type_system_sp = GetTypeSystem())
760 return type_system_sp->CreateTypedef(m_type, name, decl_ctx, payload);
761 return CompilerType();
762}
763
765 if (IsValid())
766 if (auto type_system_sp = GetTypeSystem())
767 return type_system_sp->GetTypedefedType(m_type);
768 return CompilerType();
769}
770
771// Create related types using the current type's AST
772
775 if (IsValid())
776 if (auto type_system_sp = GetTypeSystem())
777 return type_system_sp->GetBasicTypeFromAST(basic_type);
778 return CompilerType();
779}
780// Exploring the type
781
782llvm::Expected<uint64_t>
784 if (IsValid())
785 if (auto type_system_sp = GetTypeSystem())
786 return type_system_sp->GetBitSize(m_type, exe_scope);
787 return llvm::createStringError("invalid type: cannot determine size");
788}
789
790llvm::Expected<uint64_t>
792 auto bit_size_or_err = GetBitSize(exe_scope);
793 if (!bit_size_or_err)
794 return bit_size_or_err.takeError();
795 return (*bit_size_or_err + 7) / 8;
796}
797
798std::optional<size_t>
800 if (IsValid())
801 if (auto type_system_sp = GetTypeSystem())
802 return type_system_sp->GetTypeBitAlign(m_type, exe_scope);
803 return {};
804}
805
807 if (IsValid())
808 if (auto type_system_sp = GetTypeSystem())
809 return type_system_sp->GetEncoding(m_type);
811}
812
814 if (IsValid())
815 if (auto type_system_sp = GetTypeSystem())
816 return type_system_sp->GetFormat(m_type);
818}
819
820llvm::Expected<uint32_t>
821CompilerType::GetNumChildren(bool omit_empty_base_classes,
822 const ExecutionContext *exe_ctx) const {
823 if (IsValid())
824 if (auto type_system_sp = GetTypeSystem())
825 return type_system_sp->GetNumChildren(m_type, omit_empty_base_classes,
826 exe_ctx);
827 return llvm::createStringError("invalid type");
828}
829
831 if (IsValid())
832 if (auto type_system_sp = GetTypeSystem())
833 return type_system_sp->GetBasicTypeEnumeration(m_type);
834 return eBasicTypeInvalid;
835}
836
838 std::function<bool(const CompilerType &integer_type,
839 ConstString name,
840 const llvm::APSInt &value)> const &callback) const {
841 if (IsValid())
842 if (auto type_system_sp = GetTypeSystem())
843 return type_system_sp->ForEachEnumerator(m_type, callback);
844}
845
847 if (IsValid())
848 if (auto type_system_sp = GetTypeSystem())
849 return type_system_sp->GetNumFields(m_type);
850 return 0;
851}
852
853CompilerType CompilerType::GetFieldAtIndex(size_t idx, std::string &name,
854 uint64_t *bit_offset_ptr,
855 uint32_t *bitfield_bit_size_ptr,
856 bool *is_bitfield_ptr) const {
857 if (IsValid())
858 if (auto type_system_sp = GetTypeSystem())
859 return type_system_sp->GetFieldAtIndex(m_type, idx, name, bit_offset_ptr,
860 bitfield_bit_size_ptr, is_bitfield_ptr);
861 return CompilerType();
862}
863
865 if (IsValid())
866 if (auto type_system_sp = GetTypeSystem())
867 return type_system_sp->GetNumDirectBaseClasses(m_type);
868 return 0;
869}
870
872 if (IsValid())
873 if (auto type_system_sp = GetTypeSystem())
874 return type_system_sp->GetNumVirtualBaseClasses(m_type);
875 return 0;
876}
877
880 uint32_t *bit_offset_ptr) const {
881 if (IsValid())
882 if (auto type_system_sp = GetTypeSystem())
883 return type_system_sp->GetDirectBaseClassAtIndex(m_type, idx,
884 bit_offset_ptr);
885 return CompilerType();
886}
887
890 uint32_t *bit_offset_ptr) const {
891 if (IsValid())
892 if (auto type_system_sp = GetTypeSystem())
893 return type_system_sp->GetVirtualBaseClassAtIndex(m_type, idx,
894 bit_offset_ptr);
895 return CompilerType();
896}
897
899 if (IsValid())
901 return CompilerDecl();
902}
903
904llvm::Expected<CompilerType> CompilerType::GetDereferencedType(
905 ExecutionContext *exe_ctx, std::string &deref_name,
906 uint32_t &deref_byte_size, int32_t &deref_byte_offset, ValueObject *valobj,
907 uint64_t &language_flags) const {
908 if (IsValid())
909 if (auto type_system_sp = GetTypeSystem())
910 return type_system_sp->GetDereferencedType(
911 m_type, exe_ctx, deref_name, deref_byte_size, deref_byte_offset,
912 valobj, language_flags);
913 return CompilerType();
914}
915
916llvm::Expected<CompilerType> CompilerType::GetChildCompilerTypeAtIndex(
917 ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers,
918 bool omit_empty_base_classes, bool ignore_array_bounds,
919 std::string &child_name, uint32_t &child_byte_size,
920 int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size,
921 uint32_t &child_bitfield_bit_offset, bool &child_is_base_class,
922 bool &child_is_deref_of_parent, ValueObject *valobj,
923 uint64_t &language_flags) const {
924 if (IsValid())
925 if (auto type_system_sp = GetTypeSystem())
926 return type_system_sp->GetChildCompilerTypeAtIndex(
927 m_type, exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
928 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
929 child_bitfield_bit_size, child_bitfield_bit_offset,
930 child_is_base_class, child_is_deref_of_parent, valobj,
931 language_flags);
932 return CompilerType();
933}
934
935// Look for a child member (doesn't include base classes, but it does include
936// their members) in the type hierarchy. Returns an index path into
937// "clang_type" on how to reach the appropriate member.
938//
939// class A
940// {
941// public:
942// int m_a;
943// int m_b;
944// };
945//
946// class B
947// {
948// };
949//
950// class C :
951// public B,
952// public A
953// {
954// };
955//
956// If we have a clang type that describes "class C", and we wanted to looked
957// "m_b" in it:
958//
959// With omit_empty_base_classes == false we would get an integer array back
960// with: { 1, 1 } The first index 1 is the child index for "class A" within
961// class C The second index 1 is the child index for "m_b" within class A
962//
963// With omit_empty_base_classes == true we would get an integer array back
964// with: { 0, 1 } The first index 0 is the child index for "class A" within
965// class C (since class B doesn't have any members it doesn't count) The second
966// index 1 is the child index for "m_b" within class A
967
969 llvm::StringRef name, bool omit_empty_base_classes,
970 std::vector<uint32_t> &child_indexes) const {
971 if (IsValid() && !name.empty()) {
972 if (auto type_system_sp = GetTypeSystem())
973 return type_system_sp->GetIndexOfChildMemberWithName(
974 m_type, name, omit_empty_base_classes, child_indexes);
975 }
976 return 0;
977}
978
980CompilerType::GetDirectNestedTypeWithName(llvm::StringRef name) const {
981 if (IsValid() && !name.empty()) {
982 if (auto type_system_sp = GetTypeSystem())
983 return type_system_sp->GetDirectNestedTypeWithName(m_type, name);
984 }
985 return CompilerType();
986}
987
988size_t CompilerType::GetNumTemplateArguments(bool expand_pack) const {
989 if (IsValid()) {
990 if (auto type_system_sp = GetTypeSystem())
991 return type_system_sp->GetNumTemplateArguments(m_type, expand_pack);
992 }
993 return 0;
994}
995
997CompilerType::GetTemplateArgumentKind(size_t idx, bool expand_pack) const {
998 if (IsValid())
999 if (auto type_system_sp = GetTypeSystem())
1000 return type_system_sp->GetTemplateArgumentKind(m_type, idx, expand_pack);
1002}
1003
1005 bool expand_pack) const {
1006 if (IsValid()) {
1007 if (auto type_system_sp = GetTypeSystem())
1008 return type_system_sp->GetTypeTemplateArgument(m_type, idx, expand_pack);
1009 }
1010 return CompilerType();
1011}
1012
1013std::optional<CompilerType::IntegralTemplateArgument>
1014CompilerType::GetIntegralTemplateArgument(size_t idx, bool expand_pack) const {
1015 if (IsValid())
1016 if (auto type_system_sp = GetTypeSystem())
1017 return type_system_sp->GetIntegralTemplateArgument(m_type, idx, expand_pack);
1018 return std::nullopt;
1019}
1020
1022 if (IsValid())
1023 if (auto type_system_sp = GetTypeSystem())
1024 return type_system_sp->GetTypeForFormatters(m_type);
1025 return CompilerType();
1026}
1027
1029 if (IsValid())
1030 if (auto type_system_sp = GetTypeSystem())
1031 return type_system_sp->GetPromotedIntegerType(m_type);
1032 return CompilerType();
1033}
1034
1036 if (IsValid())
1037 if (auto type_system_sp = GetTypeSystem())
1038 return type_system_sp->ShouldPrintAsOneLiner(m_type, valobj);
1039 return eLazyBoolCalculate;
1040}
1041
1043 if (IsValid())
1044 if (auto type_system_sp = GetTypeSystem())
1045 return type_system_sp->IsMeaninglessWithoutDynamicResolution(m_type);
1046 return false;
1047}
1048
1049// Get the index of the child of "clang_type" whose name matches. This function
1050// doesn't descend into the children, but only looks one level deep and name
1051// matches can include base class names.
1052
1053llvm::Expected<uint32_t>
1055 bool omit_empty_base_classes) const {
1056 if (IsValid() && !name.empty()) {
1057 if (auto type_system_sp = GetTypeSystem())
1058 return type_system_sp->GetIndexOfChildWithName(m_type, name,
1059 omit_empty_base_classes);
1060 }
1061 return llvm::createStringErrorV("type has no child named '{0}'", name);
1062}
1063
1064// Dumping types
1065
1067 const DataExtractor &data,
1068 lldb::offset_t byte_offset, size_t byte_size,
1069 uint32_t bitfield_bit_size,
1070 uint32_t bitfield_bit_offset,
1071 ExecutionContextScope *exe_scope) {
1072 if (IsValid())
1073 if (auto type_system_sp = GetTypeSystem())
1074 return type_system_sp->DumpTypeValue(
1075 m_type, *s, format, data, byte_offset, byte_size, bitfield_bit_size,
1076 bitfield_bit_offset, exe_scope);
1077 return false;
1078}
1079
1081 if (IsValid())
1082 if (auto type_system_sp = GetTypeSystem())
1083 type_system_sp->DumpTypeDescription(m_type, level);
1084}
1085
1087 lldb::DescriptionLevel level) const {
1088 if (IsValid())
1089 if (auto type_system_sp = GetTypeSystem())
1090 type_system_sp->DumpTypeDescription(m_type, *s, level);
1091}
1092
1093#ifndef NDEBUG
1094LLVM_DUMP_METHOD void CompilerType::dump() const {
1095 if (IsValid())
1096 if (auto type_system_sp = GetTypeSystem())
1097 return type_system_sp->dump(m_type);
1098 llvm::errs() << "<invalid>\n";
1099}
1100#endif
1101
1103 lldb::offset_t data_byte_offset,
1104 size_t data_byte_size, Scalar &value,
1105 ExecutionContextScope *exe_scope) const {
1106 if (!IsValid())
1107 return false;
1108
1109 if (IsAggregateType()) {
1110 return false; // Aggregate types don't have scalar values
1111 } else {
1112 // FIXME: check that type is scalar instead of checking encoding?
1113 lldb::Encoding encoding = GetEncoding();
1114
1115 if (encoding == lldb::eEncodingInvalid || (GetTypeInfo() & eTypeIsComplex))
1116 return false;
1117
1118 auto byte_size_or_err = GetByteSize(exe_scope);
1119 if (!byte_size_or_err) {
1121 GetLog(LLDBLog::Types), byte_size_or_err.takeError(),
1122 "Cannot get value as scalar: Cannot determine type size: {0}");
1123 return false;
1124 }
1125 uint64_t byte_size = *byte_size_or_err;
1126
1127 // A bit or byte size of 0 is not a bug, but it doesn't make sense to read a
1128 // scalar of zero size.
1129 if (byte_size == 0)
1130 return false;
1131
1132 lldb::offset_t offset = data_byte_offset;
1133 switch (encoding) {
1135 break;
1137 break;
1139 if (byte_size <= sizeof(unsigned long long)) {
1140 uint64_t uval64 = data.GetMaxU64(&offset, byte_size);
1141 if (byte_size <= sizeof(unsigned int)) {
1142 value = (unsigned int)uval64;
1143 return true;
1144 } else if (byte_size <= sizeof(unsigned long)) {
1145 value = (unsigned long)uval64;
1146 return true;
1147 } else if (byte_size <= sizeof(unsigned long long)) {
1148 value = (unsigned long long)uval64;
1149 return true;
1150 } else
1151 value.Clear();
1152 }
1153 break;
1154
1156 if (byte_size <= sizeof(long long)) {
1157 int64_t sval64 = data.GetMaxS64(&offset, byte_size);
1158 if (byte_size <= sizeof(int)) {
1159 value = (int)sval64;
1160 return true;
1161 } else if (byte_size <= sizeof(long)) {
1162 value = (long)sval64;
1163 return true;
1164 } else if (byte_size <= sizeof(long long)) {
1165 value = (long long)sval64;
1166 return true;
1167 } else
1168 value.Clear();
1169 }
1170 break;
1171
1173 if (byte_size <= sizeof(long double)) {
1174 uint32_t u32;
1175 uint64_t u64;
1176 if (byte_size == sizeof(float)) {
1177 if (sizeof(float) == sizeof(uint32_t)) {
1178 u32 = data.GetU32(&offset);
1179 value = *((float *)&u32);
1180 return true;
1181 } else if (sizeof(float) == sizeof(uint64_t)) {
1182 u64 = data.GetU64(&offset);
1183 value = *((float *)&u64);
1184 return true;
1185 }
1186 } else if (byte_size == sizeof(double)) {
1187 if (sizeof(double) == sizeof(uint32_t)) {
1188 u32 = data.GetU32(&offset);
1189 value = *((double *)&u32);
1190 return true;
1191 } else if (sizeof(double) == sizeof(uint64_t)) {
1192 u64 = data.GetU64(&offset);
1193 value = *((double *)&u64);
1194 return true;
1195 }
1196 } else if (byte_size == sizeof(long double)) {
1197 if (sizeof(long double) == sizeof(uint32_t)) {
1198 u32 = data.GetU32(&offset);
1199 value = *((long double *)&u32);
1200 return true;
1201 } else if (sizeof(long double) == sizeof(uint64_t)) {
1202 u64 = data.GetU64(&offset);
1203 value = *((long double *)&u64);
1204 return true;
1205 }
1206 }
1207 }
1208 break;
1209 }
1210 }
1211 return false;
1212}
1213
1216 : m_type_system(type_system.GetSharedPointer()), m_type(type) {
1217 assert(Verify() && "verification failed");
1218}
1219
1222 : m_type_system(type_system), m_type(type) {
1223 assert(Verify() && "verification failed");
1224}
1225
1226#ifndef NDEBUG
1228 if (!IsValid())
1229 return true;
1230 if (auto type_system_sp = GetTypeSystem())
1231 return type_system_sp->Verify(m_type);
1232 return true;
1233}
1234#endif
1235
1239
1241 const CompilerType::TypeSystemSPWrapper &other) const {
1242 if (!m_typesystem_sp && !other.m_typesystem_sp)
1243 return true;
1244 if (m_typesystem_sp && other.m_typesystem_sp)
1245 return m_typesystem_sp.get() == other.m_typesystem_sp.get();
1246 return false;
1247}
1248
1253
1255 const lldb_private::CompilerType &rhs) {
1256 return lhs.GetTypeSystem() == rhs.GetTypeSystem() &&
1257 lhs.GetOpaqueQualType() == rhs.GetOpaqueQualType();
1258}
1259
1261 const lldb_private::CompilerType &rhs) {
1262 return !(lhs == rhs);
1263}
#define LLDB_LOG_ERRORV(log, error,...)
Definition Log.h:421
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
bool IsPromotableIntegerType() const
Checks if the type is eligible for integral promotion.
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.
CompilerType AddAddressSpaceModifier(uint32_t address_space) const
Return a new CompilerType that qualifies this type with the given target address space if this type i...
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
std::optional< uint32_t > GetTargetAddressSpace() 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 GetPromotedIntegerType() const
If the type is promotable, returns the type promoted to a larger integer type according to the type s...
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:72
virtual CompilerDecl GetStaticFieldWithName(lldb::opaque_compiler_type_t type, llvm::StringRef name)
Definition TypeSystem.h:380
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:338
bool operator!=(const Address &lhs, const Address &rhs)
Definition Address.cpp:1011
bool operator==(const Address &lhs, const Address &rhs)
Definition Address.cpp:1005
void * opaque_compiler_type_t
Definition lldb-types.h:91
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:86
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