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
9#include "lldb/Symbol/CompilerType.h"
10
11#include "lldb/Core/Debugger.h"
12#include "lldb/Symbol/Type.h"
13#include "lldb/Target/ExecutionContext.h"
14#include "lldb/Target/Process.h"
15#include "lldb/Utility/ConstString.h"
16#include "lldb/Utility/DataBufferHeap.h"
17#include "lldb/Utility/DataExtractor.h"
18#include "lldb/Utility/LLDBLog.h"
19#include "lldb/Utility/Log.h"
20#include "lldb/Utility/Scalar.h"
21#include "lldb/Utility/Stream.h"
22#include "lldb/Utility/StreamString.h"
23
24#include <iterator>
25#include <mutex>
26#include <optional>
27
28using namespace lldb;
29using namespace lldb_private;
30
31// Tests
32
33bool CompilerType::IsAggregateType() const {
34 if (IsValid())
35 if (auto type_system_sp = GetTypeSystem())
36 return type_system_sp->IsAggregateType(type: m_type);
37 return false;
38}
39
40bool CompilerType::IsAnonymousType() const {
41 if (IsValid())
42 if (auto type_system_sp = GetTypeSystem())
43 return type_system_sp->IsAnonymousType(type: m_type);
44 return false;
45}
46
47bool CompilerType::IsScopedEnumerationType() const {
48 if (IsValid())
49 if (auto type_system_sp = GetTypeSystem())
50 return type_system_sp->IsScopedEnumerationType(type: 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(type: m_type, element_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
70bool CompilerType::IsVectorType(CompilerType *element_type,
71 uint64_t *size) const {
72 if (IsValid())
73 if (auto type_system_sp = GetTypeSystem())
74 return type_system_sp->IsVectorType(type: m_type, element_type, size);
75 return false;
76}
77
78bool CompilerType::IsRuntimeGeneratedType() const {
79 if (IsValid())
80 if (auto type_system_sp = GetTypeSystem())
81 return type_system_sp->IsRuntimeGeneratedType(type: m_type);
82 return false;
83}
84
85bool CompilerType::IsCharType() const {
86 if (IsValid())
87 if (auto type_system_sp = GetTypeSystem())
88 return type_system_sp->IsCharType(type: m_type);
89 return false;
90}
91
92bool CompilerType::IsCompleteType() const {
93 if (IsValid())
94 if (auto type_system_sp = GetTypeSystem())
95 return type_system_sp->IsCompleteType(type: m_type);
96 return false;
97}
98
99bool CompilerType::IsForcefullyCompleted() const {
100 if (IsValid())
101 if (auto type_system_sp = GetTypeSystem())
102 return type_system_sp->IsForcefullyCompleted(type: m_type);
103 return false;
104}
105
106bool CompilerType::IsConst() const {
107 if (IsValid())
108 if (auto type_system_sp = GetTypeSystem())
109 return type_system_sp->IsConst(type: m_type);
110 return false;
111}
112
113unsigned CompilerType::GetPtrAuthKey() const {
114 if (IsValid())
115 if (auto type_system_sp = GetTypeSystem())
116 return type_system_sp->GetPtrAuthKey(type: m_type);
117 return 0;
118}
119
120unsigned CompilerType::GetPtrAuthDiscriminator() const {
121 if (IsValid())
122 if (auto type_system_sp = GetTypeSystem())
123 return type_system_sp->GetPtrAuthDiscriminator(type: m_type);
124 return 0;
125}
126
127bool CompilerType::GetPtrAuthAddressDiversity() const {
128 if (IsValid())
129 if (auto type_system_sp = GetTypeSystem())
130 return type_system_sp->GetPtrAuthAddressDiversity(type: m_type);
131 return false;
132}
133
134bool CompilerType::IsFunctionType() const {
135 if (IsValid())
136 if (auto type_system_sp = GetTypeSystem())
137 return type_system_sp->IsFunctionType(type: m_type);
138 return false;
139}
140
141// Used to detect "Homogeneous Floating-point Aggregates"
142uint32_t
143CompilerType::IsHomogeneousAggregate(CompilerType *base_type_ptr) const {
144 if (IsValid())
145 if (auto type_system_sp = GetTypeSystem())
146 return type_system_sp->IsHomogeneousAggregate(type: m_type, base_type_ptr);
147 return 0;
148}
149
150size_t CompilerType::GetNumberOfFunctionArguments() const {
151 if (IsValid())
152 if (auto type_system_sp = GetTypeSystem())
153 return type_system_sp->GetNumberOfFunctionArguments(type: m_type);
154 return 0;
155}
156
157CompilerType
158CompilerType::GetFunctionArgumentAtIndex(const size_t index) const {
159 if (IsValid())
160 if (auto type_system_sp = GetTypeSystem())
161 return type_system_sp->GetFunctionArgumentAtIndex(type: m_type, index);
162 return CompilerType();
163}
164
165bool CompilerType::IsFunctionPointerType() const {
166 if (IsValid())
167 if (auto type_system_sp = GetTypeSystem())
168 return type_system_sp->IsFunctionPointerType(type: m_type);
169 return false;
170}
171
172bool CompilerType::IsMemberFunctionPointerType() const {
173 if (IsValid())
174 if (auto type_system_sp = GetTypeSystem())
175 return type_system_sp->IsMemberFunctionPointerType(type: m_type);
176 return false;
177}
178
179bool CompilerType::IsBlockPointerType(
180 CompilerType *function_pointer_type_ptr) const {
181 if (IsValid())
182 if (auto type_system_sp = GetTypeSystem())
183 return type_system_sp->IsBlockPointerType(type: 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(type: 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(type: 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(type: m_type, pointee_type);
209 }
210 if (pointee_type)
211 pointee_type->Clear();
212 return false;
213}
214
215bool CompilerType::IsPointerOrReferenceType(CompilerType *pointee_type) const {
216 if (IsValid()) {
217 if (auto type_system_sp = GetTypeSystem())
218 return type_system_sp->IsPointerOrReferenceType(type: m_type, pointee_type);
219 }
220 if (pointee_type)
221 pointee_type->Clear();
222 return false;
223}
224
225bool CompilerType::IsReferenceType(CompilerType *pointee_type,
226 bool *is_rvalue) const {
227 if (IsValid()) {
228 if (auto type_system_sp = GetTypeSystem())
229 return type_system_sp->IsReferenceType(type: m_type, pointee_type, is_rvalue);
230 }
231 if (pointee_type)
232 pointee_type->Clear();
233 return false;
234}
235
236bool CompilerType::ShouldTreatScalarValueAsAddress() const {
237 if (IsValid())
238 if (auto type_system_sp = GetTypeSystem())
239 return type_system_sp->ShouldTreatScalarValueAsAddress(type: m_type);
240 return false;
241}
242
243bool CompilerType::IsFloatingPointType(uint32_t &count,
244 bool &is_complex) const {
245 if (IsValid()) {
246 if (auto type_system_sp = GetTypeSystem())
247 return type_system_sp->IsFloatingPointType(type: m_type, count, is_complex);
248 }
249 count = 0;
250 is_complex = false;
251 return false;
252}
253
254bool CompilerType::IsDefined() const {
255 if (IsValid())
256 if (auto type_system_sp = GetTypeSystem())
257 return type_system_sp->IsDefined(type: m_type);
258 return true;
259}
260
261bool CompilerType::IsPolymorphicClass() const {
262 if (IsValid()) {
263 if (auto type_system_sp = GetTypeSystem())
264 return type_system_sp->IsPolymorphicClass(type: m_type);
265 }
266 return false;
267}
268
269bool CompilerType::IsPossibleDynamicType(CompilerType *dynamic_pointee_type,
270 bool check_cplusplus,
271 bool check_objc) const {
272 if (IsValid())
273 if (auto type_system_sp = GetTypeSystem())
274 return type_system_sp->IsPossibleDynamicType(type: m_type, target_type: dynamic_pointee_type,
275 check_cplusplus, check_objc);
276 return false;
277}
278
279bool CompilerType::IsScalarType() const {
280 if (IsValid())
281 if (auto type_system_sp = GetTypeSystem())
282 return type_system_sp->IsScalarType(type: m_type);
283 return false;
284}
285
286bool CompilerType::IsTemplateType() const {
287 if (IsValid())
288 if (auto type_system_sp = GetTypeSystem())
289 return type_system_sp->IsTemplateType(type: m_type);
290 return false;
291}
292
293bool CompilerType::IsTypedefType() const {
294 if (IsValid())
295 if (auto type_system_sp = GetTypeSystem())
296 return type_system_sp->IsTypedefType(type: m_type);
297 return false;
298}
299
300bool CompilerType::IsVoidType() const {
301 if (IsValid())
302 if (auto type_system_sp = GetTypeSystem())
303 return type_system_sp->IsVoidType(type: m_type);
304 return false;
305}
306
307bool CompilerType::IsPointerToScalarType() const {
308 if (!IsValid())
309 return false;
310
311 return IsPointerType() && GetPointeeType().IsScalarType();
312}
313
314bool CompilerType::IsArrayOfScalarType() const {
315 CompilerType element_type;
316 if (IsArrayType(element_type_ptr: &element_type))
317 return element_type.IsScalarType();
318 return false;
319}
320
321bool CompilerType::IsBeingDefined() const {
322 if (IsValid())
323 if (auto type_system_sp = GetTypeSystem())
324 return type_system_sp->IsBeingDefined(type: m_type);
325 return false;
326}
327
328bool CompilerType::IsInteger() const {
329 bool is_signed = false; // May be reset by the call below.
330 return IsIntegerType(is_signed);
331}
332
333bool CompilerType::IsFloat() const {
334 uint32_t count = 0;
335 bool is_complex = false;
336 return IsFloatingPointType(count, is_complex);
337}
338
339bool CompilerType::IsEnumerationType() const {
340 bool is_signed = false; // May be reset by the call below.
341 return IsEnumerationType(is_signed);
342}
343
344bool CompilerType::IsUnscopedEnumerationType() const {
345 return IsEnumerationType() && !IsScopedEnumerationType();
346}
347
348bool CompilerType::IsIntegerOrUnscopedEnumerationType() const {
349 return IsInteger() || IsUnscopedEnumerationType();
350}
351
352bool CompilerType::IsSigned() const {
353 return GetTypeInfo() & lldb::eTypeIsSigned;
354}
355
356bool CompilerType::IsNullPtrType() const {
357 return GetCanonicalType().GetBasicTypeEnumeration() ==
358 lldb::eBasicTypeNullPtr;
359}
360
361bool CompilerType::IsBoolean() const {
362 return GetCanonicalType().GetBasicTypeEnumeration() == lldb::eBasicTypeBool;
363}
364
365bool CompilerType::IsEnumerationIntegerTypeSigned() const {
366 if (IsValid())
367 return GetEnumerationIntegerType().GetTypeInfo() & lldb::eTypeIsSigned;
368
369 return false;
370}
371
372bool CompilerType::IsScalarOrUnscopedEnumerationType() const {
373 return IsScalarType() || IsUnscopedEnumerationType();
374}
375
376bool CompilerType::IsPromotableIntegerType() const {
377 // Unscoped enums are always considered as promotable, even if their
378 // underlying type does not need to be promoted (e.g. "int").
379 if (IsUnscopedEnumerationType())
380 return true;
381
382 switch (GetCanonicalType().GetBasicTypeEnumeration()) {
383 case lldb::eBasicTypeBool:
384 case lldb::eBasicTypeChar:
385 case lldb::eBasicTypeSignedChar:
386 case lldb::eBasicTypeUnsignedChar:
387 case lldb::eBasicTypeShort:
388 case lldb::eBasicTypeUnsignedShort:
389 case lldb::eBasicTypeWChar:
390 case lldb::eBasicTypeSignedWChar:
391 case lldb::eBasicTypeUnsignedWChar:
392 case lldb::eBasicTypeChar16:
393 case lldb::eBasicTypeChar32:
394 return true;
395
396 default:
397 return false;
398 }
399
400 llvm_unreachable("All cases handled above.");
401}
402
403bool CompilerType::IsPointerToVoid() const {
404 if (!IsValid())
405 return false;
406
407 return IsPointerType() &&
408 GetPointeeType().GetBasicTypeEnumeration() == lldb::eBasicTypeVoid;
409}
410
411bool CompilerType::IsRecordType() const {
412 if (!IsValid())
413 return false;
414
415 return GetCanonicalType().GetTypeClass() &
416 (lldb::eTypeClassClass | lldb::eTypeClassStruct |
417 lldb::eTypeClassUnion);
418}
419
420bool CompilerType::IsVirtualBase(CompilerType target_base,
421 CompilerType *virtual_base,
422 bool carry_virtual) const {
423 if (CompareTypes(rhs: target_base))
424 return carry_virtual;
425
426 if (!carry_virtual) {
427 uint32_t num_virtual_bases = GetNumVirtualBaseClasses();
428 for (uint32_t i = 0; i < num_virtual_bases; ++i) {
429 uint32_t bit_offset;
430 auto base = GetVirtualBaseClassAtIndex(idx: i, bit_offset_ptr: &bit_offset);
431 if (base.IsVirtualBase(target_base, virtual_base,
432 /*carry_virtual*/ true)) {
433 if (virtual_base)
434 *virtual_base = base;
435
436 return true;
437 }
438 }
439 }
440
441 uint32_t num_direct_bases = GetNumDirectBaseClasses();
442 for (uint32_t i = 0; i < num_direct_bases; ++i) {
443 uint32_t bit_offset;
444 auto base = GetDirectBaseClassAtIndex(idx: i, bit_offset_ptr: &bit_offset);
445 if (base.IsVirtualBase(target_base, virtual_base, carry_virtual))
446 return true;
447 }
448
449 return false;
450}
451
452bool CompilerType::IsContextuallyConvertibleToBool() const {
453 return IsScalarType() || IsUnscopedEnumerationType() || IsPointerType() ||
454 IsNullPtrType() || IsArrayType();
455}
456
457bool CompilerType::IsBasicType() const {
458 return GetCanonicalType().GetBasicTypeEnumeration() !=
459 lldb::eBasicTypeInvalid;
460}
461
462std::string CompilerType::TypeDescription() {
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(Fmt: "'{0}'", Vals&: name);
470
471 return llvm::formatv(Fmt: "'{0}' (canonically referred to as '{1}')", Vals&: name,
472 Vals&: canonical_name);
473}
474
475bool CompilerType::CompareTypes(CompilerType rhs) const {
476 if (*this == rhs)
477 return true;
478
479 const ConstString name = GetFullyUnqualifiedType().GetTypeName();
480 const ConstString rhs_name = rhs.GetFullyUnqualifiedType().GetTypeName();
481 return name == rhs_name;
482}
483
484const char *CompilerType::GetTypeTag() {
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
500uint32_t CompilerType::GetNumberOfNonEmptyBaseClasses() {
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(idx: i, bit_offset_ptr: &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
516bool CompilerType::GetCompleteType() const {
517 if (IsValid())
518 if (auto type_system_sp = GetTypeSystem())
519 return type_system_sp->GetCompleteType(type: m_type);
520 return false;
521}
522
523// AST related queries
524size_t CompilerType::GetPointerByteSize() const {
525 if (auto type_system_sp = GetTypeSystem())
526 return type_system_sp->GetPointerByteSize();
527 return 0;
528}
529
530ConstString CompilerType::GetTypeName(bool BaseOnly) const {
531 if (IsValid()) {
532 if (auto type_system_sp = GetTypeSystem())
533 return type_system_sp->GetTypeName(type: m_type, BaseOnly);
534 }
535 return ConstString("<invalid>");
536}
537
538ConstString CompilerType::GetDisplayTypeName() const {
539 if (IsValid())
540 if (auto type_system_sp = GetTypeSystem())
541 return type_system_sp->GetDisplayTypeName(type: m_type);
542 return ConstString("<invalid>");
543}
544
545ConstString CompilerType::GetMangledTypeName() const {
546 if (IsValid()) {
547 if (auto type_system_sp = GetTypeSystem())
548 return type_system_sp->GetMangledTypeName(type: m_type);
549 }
550 return ConstString("<invalid>");
551}
552
553uint32_t CompilerType::GetTypeInfo(
554 CompilerType *pointee_or_element_compiler_type) const {
555 if (IsValid())
556 if (auto type_system_sp = GetTypeSystem())
557 return type_system_sp->GetTypeInfo(type: m_type,
558 pointee_or_element_compiler_type);
559 return 0;
560}
561
562lldb::LanguageType CompilerType::GetMinimumLanguage() {
563 if (IsValid())
564 if (auto type_system_sp = GetTypeSystem())
565 return type_system_sp->GetMinimumLanguage(type: m_type);
566 return lldb::eLanguageTypeC;
567}
568
569lldb::TypeClass CompilerType::GetTypeClass() const {
570 if (IsValid())
571 if (auto type_system_sp = GetTypeSystem())
572 return type_system_sp->GetTypeClass(type: m_type);
573 return lldb::eTypeClassInvalid;
574}
575
576void CompilerType::SetCompilerType(lldb::TypeSystemWP type_system,
577 lldb::opaque_compiler_type_t type) {
578 m_type_system = type_system;
579 m_type = type;
580}
581
582void CompilerType::SetCompilerType(CompilerType::TypeSystemSPWrapper type_system,
583 lldb::opaque_compiler_type_t type) {
584 m_type_system = type_system.GetSharedPointer();
585 m_type = type;
586}
587
588unsigned CompilerType::GetTypeQualifiers() const {
589 if (IsValid())
590 if (auto type_system_sp = GetTypeSystem())
591 return type_system_sp->GetTypeQualifiers(type: m_type);
592 return 0;
593}
594
595// Creating related types
596
597CompilerType
598CompilerType::GetArrayElementType(ExecutionContextScope *exe_scope) const {
599 if (IsValid()) {
600 if (auto type_system_sp = GetTypeSystem())
601 return type_system_sp->GetArrayElementType(type: m_type, exe_scope);
602 }
603 return CompilerType();
604}
605
606CompilerType CompilerType::GetArrayType(uint64_t size) const {
607 if (IsValid()) {
608 if (auto type_system_sp = GetTypeSystem())
609 return type_system_sp->GetArrayType(type: m_type, size);
610 }
611 return CompilerType();
612}
613
614CompilerType CompilerType::GetCanonicalType() const {
615 if (IsValid())
616 if (auto type_system_sp = GetTypeSystem())
617 return type_system_sp->GetCanonicalType(type: m_type);
618 return CompilerType();
619}
620
621CompilerType CompilerType::GetFullyUnqualifiedType() const {
622 if (IsValid())
623 if (auto type_system_sp = GetTypeSystem())
624 return type_system_sp->GetFullyUnqualifiedType(type: m_type);
625 return CompilerType();
626}
627
628CompilerType CompilerType::GetEnumerationIntegerType() const {
629 if (IsValid())
630 if (auto type_system_sp = GetTypeSystem())
631 return type_system_sp->GetEnumerationIntegerType(type: m_type);
632 return CompilerType();
633}
634
635int CompilerType::GetFunctionArgumentCount() const {
636 if (IsValid()) {
637 if (auto type_system_sp = GetTypeSystem())
638 return type_system_sp->GetFunctionArgumentCount(type: m_type);
639 }
640 return -1;
641}
642
643CompilerType CompilerType::GetFunctionArgumentTypeAtIndex(size_t idx) const {
644 if (IsValid()) {
645 if (auto type_system_sp = GetTypeSystem())
646 return type_system_sp->GetFunctionArgumentTypeAtIndex(type: m_type, idx);
647 }
648 return CompilerType();
649}
650
651CompilerType CompilerType::GetFunctionReturnType() const {
652 if (IsValid()) {
653 if (auto type_system_sp = GetTypeSystem())
654 return type_system_sp->GetFunctionReturnType(type: m_type);
655 }
656 return CompilerType();
657}
658
659size_t CompilerType::GetNumMemberFunctions() const {
660 if (IsValid()) {
661 if (auto type_system_sp = GetTypeSystem())
662 return type_system_sp->GetNumMemberFunctions(type: m_type);
663 }
664 return 0;
665}
666
667TypeMemberFunctionImpl CompilerType::GetMemberFunctionAtIndex(size_t idx) {
668 if (IsValid()) {
669 if (auto type_system_sp = GetTypeSystem())
670 return type_system_sp->GetMemberFunctionAtIndex(type: m_type, idx);
671 }
672 return TypeMemberFunctionImpl();
673}
674
675CompilerType CompilerType::GetNonReferenceType() const {
676 if (IsValid())
677 if (auto type_system_sp = GetTypeSystem())
678 return type_system_sp->GetNonReferenceType(type: m_type);
679 return CompilerType();
680}
681
682CompilerType CompilerType::GetPointeeType() const {
683 if (IsValid()) {
684 if (auto type_system_sp = GetTypeSystem())
685 return type_system_sp->GetPointeeType(type: m_type);
686 }
687 return CompilerType();
688}
689
690CompilerType CompilerType::GetPointerType() const {
691 if (IsValid()) {
692 if (auto type_system_sp = GetTypeSystem())
693 return type_system_sp->GetPointerType(type: m_type);
694 }
695 return CompilerType();
696}
697
698CompilerType CompilerType::AddPtrAuthModifier(uint32_t payload) const {
699 if (IsValid())
700 if (auto type_system_sp = GetTypeSystem())
701 return type_system_sp->AddPtrAuthModifier(type: m_type, payload);
702 return CompilerType();
703}
704
705CompilerType CompilerType::GetLValueReferenceType() const {
706 if (IsValid())
707 if (auto type_system_sp = GetTypeSystem())
708 return type_system_sp->GetLValueReferenceType(type: m_type);
709 return CompilerType();
710}
711
712CompilerType CompilerType::GetRValueReferenceType() const {
713 if (IsValid())
714 if (auto type_system_sp = GetTypeSystem())
715 return type_system_sp->GetRValueReferenceType(type: m_type);
716 return CompilerType();
717}
718
719CompilerType CompilerType::GetAtomicType() const {
720 if (IsValid())
721 if (auto type_system_sp = GetTypeSystem())
722 return type_system_sp->GetAtomicType(type: m_type);
723 return CompilerType();
724}
725
726CompilerType CompilerType::AddConstModifier() const {
727 if (IsValid())
728 if (auto type_system_sp = GetTypeSystem())
729 return type_system_sp->AddConstModifier(type: m_type);
730 return CompilerType();
731}
732
733CompilerType CompilerType::AddVolatileModifier() const {
734 if (IsValid())
735 if (auto type_system_sp = GetTypeSystem())
736 return type_system_sp->AddVolatileModifier(type: m_type);
737 return CompilerType();
738}
739
740CompilerType CompilerType::AddRestrictModifier() const {
741 if (IsValid())
742 if (auto type_system_sp = GetTypeSystem())
743 return type_system_sp->AddRestrictModifier(type: m_type);
744 return CompilerType();
745}
746
747CompilerType CompilerType::CreateTypedef(const char *name,
748 const CompilerDeclContext &decl_ctx,
749 uint32_t payload) const {
750 if (IsValid())
751 if (auto type_system_sp = GetTypeSystem())
752 return type_system_sp->CreateTypedef(type: m_type, name, decl_ctx, opaque_payload: payload);
753 return CompilerType();
754}
755
756CompilerType CompilerType::GetTypedefedType() const {
757 if (IsValid())
758 if (auto type_system_sp = GetTypeSystem())
759 return type_system_sp->GetTypedefedType(type: m_type);
760 return CompilerType();
761}
762
763// Create related types using the current type's AST
764
765CompilerType
766CompilerType::GetBasicTypeFromAST(lldb::BasicType basic_type) const {
767 if (IsValid())
768 if (auto type_system_sp = GetTypeSystem())
769 return type_system_sp->GetBasicTypeFromAST(basic_type);
770 return CompilerType();
771}
772// Exploring the type
773
774llvm::Expected<uint64_t>
775CompilerType::GetBitSize(ExecutionContextScope *exe_scope) const {
776 if (IsValid())
777 if (auto type_system_sp = GetTypeSystem())
778 return type_system_sp->GetBitSize(type: m_type, exe_scope);
779 return llvm::createStringError(Fmt: "Invalid type: Cannot determine size");
780}
781
782llvm::Expected<uint64_t>
783CompilerType::GetByteSize(ExecutionContextScope *exe_scope) const {
784 auto bit_size_or_err = GetBitSize(exe_scope);
785 if (!bit_size_or_err)
786 return bit_size_or_err.takeError();
787 return (*bit_size_or_err + 7) / 8;
788}
789
790std::optional<size_t>
791CompilerType::GetTypeBitAlign(ExecutionContextScope *exe_scope) const {
792 if (IsValid())
793 if (auto type_system_sp = GetTypeSystem())
794 return type_system_sp->GetTypeBitAlign(type: m_type, exe_scope);
795 return {};
796}
797
798lldb::Encoding CompilerType::GetEncoding(uint64_t &count) const {
799 if (IsValid())
800 if (auto type_system_sp = GetTypeSystem())
801 return type_system_sp->GetEncoding(type: m_type, count);
802 return lldb::eEncodingInvalid;
803}
804
805lldb::Format CompilerType::GetFormat() const {
806 if (IsValid())
807 if (auto type_system_sp = GetTypeSystem())
808 return type_system_sp->GetFormat(type: m_type);
809 return lldb::eFormatDefault;
810}
811
812llvm::Expected<uint32_t>
813CompilerType::GetNumChildren(bool omit_empty_base_classes,
814 const ExecutionContext *exe_ctx) const {
815 if (IsValid())
816 if (auto type_system_sp = GetTypeSystem())
817 return type_system_sp->GetNumChildren(type: m_type, omit_empty_base_classes,
818 exe_ctx);
819 return llvm::createStringError(Fmt: "invalid type");
820}
821
822lldb::BasicType CompilerType::GetBasicTypeEnumeration() const {
823 if (IsValid())
824 if (auto type_system_sp = GetTypeSystem())
825 return type_system_sp->GetBasicTypeEnumeration(type: m_type);
826 return eBasicTypeInvalid;
827}
828
829void CompilerType::ForEachEnumerator(
830 std::function<bool(const CompilerType &integer_type,
831 ConstString name,
832 const llvm::APSInt &value)> const &callback) const {
833 if (IsValid())
834 if (auto type_system_sp = GetTypeSystem())
835 return type_system_sp->ForEachEnumerator(type: m_type, callback);
836}
837
838uint32_t CompilerType::GetNumFields() const {
839 if (IsValid())
840 if (auto type_system_sp = GetTypeSystem())
841 return type_system_sp->GetNumFields(type: m_type);
842 return 0;
843}
844
845CompilerType CompilerType::GetFieldAtIndex(size_t idx, std::string &name,
846 uint64_t *bit_offset_ptr,
847 uint32_t *bitfield_bit_size_ptr,
848 bool *is_bitfield_ptr) const {
849 if (IsValid())
850 if (auto type_system_sp = GetTypeSystem())
851 return type_system_sp->GetFieldAtIndex(type: m_type, idx, name, bit_offset_ptr,
852 bitfield_bit_size_ptr, is_bitfield_ptr);
853 return CompilerType();
854}
855
856uint32_t CompilerType::GetNumDirectBaseClasses() const {
857 if (IsValid())
858 if (auto type_system_sp = GetTypeSystem())
859 return type_system_sp->GetNumDirectBaseClasses(type: m_type);
860 return 0;
861}
862
863uint32_t CompilerType::GetNumVirtualBaseClasses() const {
864 if (IsValid())
865 if (auto type_system_sp = GetTypeSystem())
866 return type_system_sp->GetNumVirtualBaseClasses(type: m_type);
867 return 0;
868}
869
870CompilerType
871CompilerType::GetDirectBaseClassAtIndex(size_t idx,
872 uint32_t *bit_offset_ptr) const {
873 if (IsValid())
874 if (auto type_system_sp = GetTypeSystem())
875 return type_system_sp->GetDirectBaseClassAtIndex(type: m_type, idx,
876 bit_offset_ptr);
877 return CompilerType();
878}
879
880CompilerType
881CompilerType::GetVirtualBaseClassAtIndex(size_t idx,
882 uint32_t *bit_offset_ptr) const {
883 if (IsValid())
884 if (auto type_system_sp = GetTypeSystem())
885 return type_system_sp->GetVirtualBaseClassAtIndex(type: m_type, idx,
886 bit_offset_ptr);
887 return CompilerType();
888}
889
890CompilerDecl CompilerType::GetStaticFieldWithName(llvm::StringRef name) const {
891 if (IsValid())
892 return GetTypeSystem()->GetStaticFieldWithName(type: m_type, name);
893 return CompilerDecl();
894}
895
896llvm::Expected<CompilerType> CompilerType::GetDereferencedType(
897 ExecutionContext *exe_ctx, std::string &deref_name,
898 uint32_t &deref_byte_size, int32_t &deref_byte_offset, ValueObject *valobj,
899 uint64_t &language_flags) const {
900 if (IsValid())
901 if (auto type_system_sp = GetTypeSystem())
902 return type_system_sp->GetDereferencedType(
903 type: m_type, exe_ctx, deref_name, deref_byte_size, deref_byte_offset,
904 valobj, language_flags);
905 return CompilerType();
906}
907
908llvm::Expected<CompilerType> CompilerType::GetChildCompilerTypeAtIndex(
909 ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers,
910 bool omit_empty_base_classes, bool ignore_array_bounds,
911 std::string &child_name, uint32_t &child_byte_size,
912 int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size,
913 uint32_t &child_bitfield_bit_offset, bool &child_is_base_class,
914 bool &child_is_deref_of_parent, ValueObject *valobj,
915 uint64_t &language_flags) const {
916 if (IsValid())
917 if (auto type_system_sp = GetTypeSystem())
918 return type_system_sp->GetChildCompilerTypeAtIndex(
919 type: m_type, exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
920 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
921 child_bitfield_bit_size, child_bitfield_bit_offset,
922 child_is_base_class, child_is_deref_of_parent, valobj,
923 language_flags);
924 return CompilerType();
925}
926
927// Look for a child member (doesn't include base classes, but it does include
928// their members) in the type hierarchy. Returns an index path into
929// "clang_type" on how to reach the appropriate member.
930//
931// class A
932// {
933// public:
934// int m_a;
935// int m_b;
936// };
937//
938// class B
939// {
940// };
941//
942// class C :
943// public B,
944// public A
945// {
946// };
947//
948// If we have a clang type that describes "class C", and we wanted to looked
949// "m_b" in it:
950//
951// With omit_empty_base_classes == false we would get an integer array back
952// with: { 1, 1 } The first index 1 is the child index for "class A" within
953// class C The second index 1 is the child index for "m_b" within class A
954//
955// With omit_empty_base_classes == true we would get an integer array back
956// with: { 0, 1 } The first index 0 is the child index for "class A" within
957// class C (since class B doesn't have any members it doesn't count) The second
958// index 1 is the child index for "m_b" within class A
959
960size_t CompilerType::GetIndexOfChildMemberWithName(
961 llvm::StringRef name, bool omit_empty_base_classes,
962 std::vector<uint32_t> &child_indexes) const {
963 if (IsValid() && !name.empty()) {
964 if (auto type_system_sp = GetTypeSystem())
965 return type_system_sp->GetIndexOfChildMemberWithName(
966 type: m_type, name, omit_empty_base_classes, child_indexes);
967 }
968 return 0;
969}
970
971CompilerType
972CompilerType::GetDirectNestedTypeWithName(llvm::StringRef name) const {
973 if (IsValid() && !name.empty()) {
974 if (auto type_system_sp = GetTypeSystem())
975 return type_system_sp->GetDirectNestedTypeWithName(type: m_type, name);
976 }
977 return CompilerType();
978}
979
980size_t CompilerType::GetNumTemplateArguments(bool expand_pack) const {
981 if (IsValid()) {
982 if (auto type_system_sp = GetTypeSystem())
983 return type_system_sp->GetNumTemplateArguments(type: m_type, expand_pack);
984 }
985 return 0;
986}
987
988TemplateArgumentKind
989CompilerType::GetTemplateArgumentKind(size_t idx, bool expand_pack) const {
990 if (IsValid())
991 if (auto type_system_sp = GetTypeSystem())
992 return type_system_sp->GetTemplateArgumentKind(type: m_type, idx, expand_pack);
993 return eTemplateArgumentKindNull;
994}
995
996CompilerType CompilerType::GetTypeTemplateArgument(size_t idx,
997 bool expand_pack) const {
998 if (IsValid()) {
999 if (auto type_system_sp = GetTypeSystem())
1000 return type_system_sp->GetTypeTemplateArgument(type: m_type, idx, expand_pack);
1001 }
1002 return CompilerType();
1003}
1004
1005std::optional<CompilerType::IntegralTemplateArgument>
1006CompilerType::GetIntegralTemplateArgument(size_t idx, bool expand_pack) const {
1007 if (IsValid())
1008 if (auto type_system_sp = GetTypeSystem())
1009 return type_system_sp->GetIntegralTemplateArgument(type: m_type, idx, expand_pack);
1010 return std::nullopt;
1011}
1012
1013CompilerType CompilerType::GetTypeForFormatters() const {
1014 if (IsValid())
1015 if (auto type_system_sp = GetTypeSystem())
1016 return type_system_sp->GetTypeForFormatters(type: m_type);
1017 return CompilerType();
1018}
1019
1020LazyBool CompilerType::ShouldPrintAsOneLiner(ValueObject *valobj) const {
1021 if (IsValid())
1022 if (auto type_system_sp = GetTypeSystem())
1023 return type_system_sp->ShouldPrintAsOneLiner(type: m_type, valobj);
1024 return eLazyBoolCalculate;
1025}
1026
1027bool CompilerType::IsMeaninglessWithoutDynamicResolution() const {
1028 if (IsValid())
1029 if (auto type_system_sp = GetTypeSystem())
1030 return type_system_sp->IsMeaninglessWithoutDynamicResolution(type: m_type);
1031 return false;
1032}
1033
1034// Get the index of the child of "clang_type" whose name matches. This function
1035// doesn't descend into the children, but only looks one level deep and name
1036// matches can include base class names.
1037
1038llvm::Expected<uint32_t>
1039CompilerType::GetIndexOfChildWithName(llvm::StringRef name,
1040 bool omit_empty_base_classes) const {
1041 if (IsValid() && !name.empty()) {
1042 if (auto type_system_sp = GetTypeSystem())
1043 return type_system_sp->GetIndexOfChildWithName(type: m_type, name,
1044 omit_empty_base_classes);
1045 }
1046 return llvm::createStringError(Fmt: "Type has no child named '%s'",
1047 Vals: name.str().c_str());
1048}
1049
1050// Dumping types
1051
1052bool CompilerType::DumpTypeValue(Stream *s, lldb::Format format,
1053 const DataExtractor &data,
1054 lldb::offset_t byte_offset, size_t byte_size,
1055 uint32_t bitfield_bit_size,
1056 uint32_t bitfield_bit_offset,
1057 ExecutionContextScope *exe_scope) {
1058 if (IsValid())
1059 if (auto type_system_sp = GetTypeSystem())
1060 return type_system_sp->DumpTypeValue(
1061 type: m_type, s&: *s, format, data, data_offset: byte_offset, data_byte_size: byte_size, bitfield_bit_size,
1062 bitfield_bit_offset, exe_scope);
1063 return false;
1064}
1065
1066void CompilerType::DumpTypeDescription(lldb::DescriptionLevel level) const {
1067 if (IsValid())
1068 if (auto type_system_sp = GetTypeSystem())
1069 type_system_sp->DumpTypeDescription(type: m_type, level);
1070}
1071
1072void CompilerType::DumpTypeDescription(Stream *s,
1073 lldb::DescriptionLevel level) const {
1074 if (IsValid())
1075 if (auto type_system_sp = GetTypeSystem())
1076 type_system_sp->DumpTypeDescription(type: m_type, s&: *s, level);
1077}
1078
1079#ifndef NDEBUG
1080LLVM_DUMP_METHOD void CompilerType::dump() const {
1081 if (IsValid())
1082 if (auto type_system_sp = GetTypeSystem())
1083 return type_system_sp->dump(type: m_type);
1084 llvm::errs() << "<invalid>\n";
1085}
1086#endif
1087
1088bool CompilerType::GetValueAsScalar(const lldb_private::DataExtractor &data,
1089 lldb::offset_t data_byte_offset,
1090 size_t data_byte_size, Scalar &value,
1091 ExecutionContextScope *exe_scope) const {
1092 if (!IsValid())
1093 return false;
1094
1095 if (IsAggregateType()) {
1096 return false; // Aggregate types don't have scalar values
1097 } else {
1098 uint64_t count = 0;
1099 lldb::Encoding encoding = GetEncoding(count);
1100
1101 if (encoding == lldb::eEncodingInvalid || count != 1)
1102 return false;
1103
1104 auto byte_size_or_err = GetByteSize(exe_scope);
1105 if (!byte_size_or_err) {
1106 LLDB_LOG_ERRORV(
1107 GetLog(LLDBLog::Types), byte_size_or_err.takeError(),
1108 "Cannot get value as scalar: Cannot determine type size: {0}");
1109 return false;
1110 }
1111 uint64_t byte_size = *byte_size_or_err;
1112
1113 // A bit or byte size of 0 is not a bug, but it doesn't make sense to read a
1114 // scalar of zero size.
1115 if (byte_size == 0)
1116 return false;
1117
1118 lldb::offset_t offset = data_byte_offset;
1119 switch (encoding) {
1120 case lldb::eEncodingInvalid:
1121 break;
1122 case lldb::eEncodingVector:
1123 break;
1124 case lldb::eEncodingUint:
1125 if (byte_size <= sizeof(unsigned long long)) {
1126 uint64_t uval64 = data.GetMaxU64(offset_ptr: &offset, byte_size);
1127 if (byte_size <= sizeof(unsigned int)) {
1128 value = (unsigned int)uval64;
1129 return true;
1130 } else if (byte_size <= sizeof(unsigned long)) {
1131 value = (unsigned long)uval64;
1132 return true;
1133 } else if (byte_size <= sizeof(unsigned long long)) {
1134 value = (unsigned long long)uval64;
1135 return true;
1136 } else
1137 value.Clear();
1138 }
1139 break;
1140
1141 case lldb::eEncodingSint:
1142 if (byte_size <= sizeof(long long)) {
1143 int64_t sval64 = data.GetMaxS64(offset_ptr: &offset, byte_size);
1144 if (byte_size <= sizeof(int)) {
1145 value = (int)sval64;
1146 return true;
1147 } else if (byte_size <= sizeof(long)) {
1148 value = (long)sval64;
1149 return true;
1150 } else if (byte_size <= sizeof(long long)) {
1151 value = (long long)sval64;
1152 return true;
1153 } else
1154 value.Clear();
1155 }
1156 break;
1157
1158 case lldb::eEncodingIEEE754:
1159 if (byte_size <= sizeof(long double)) {
1160 uint32_t u32;
1161 uint64_t u64;
1162 if (byte_size == sizeof(float)) {
1163 if (sizeof(float) == sizeof(uint32_t)) {
1164 u32 = data.GetU32(offset_ptr: &offset);
1165 value = *((float *)&u32);
1166 return true;
1167 } else if (sizeof(float) == sizeof(uint64_t)) {
1168 u64 = data.GetU64(offset_ptr: &offset);
1169 value = *((float *)&u64);
1170 return true;
1171 }
1172 } else if (byte_size == sizeof(double)) {
1173 if (sizeof(double) == sizeof(uint32_t)) {
1174 u32 = data.GetU32(offset_ptr: &offset);
1175 value = *((double *)&u32);
1176 return true;
1177 } else if (sizeof(double) == sizeof(uint64_t)) {
1178 u64 = data.GetU64(offset_ptr: &offset);
1179 value = *((double *)&u64);
1180 return true;
1181 }
1182 } else if (byte_size == sizeof(long double)) {
1183 if (sizeof(long double) == sizeof(uint32_t)) {
1184 u32 = data.GetU32(offset_ptr: &offset);
1185 value = *((long double *)&u32);
1186 return true;
1187 } else if (sizeof(long double) == sizeof(uint64_t)) {
1188 u64 = data.GetU64(offset_ptr: &offset);
1189 value = *((long double *)&u64);
1190 return true;
1191 }
1192 }
1193 }
1194 break;
1195 }
1196 }
1197 return false;
1198}
1199
1200CompilerType::CompilerType(CompilerType::TypeSystemSPWrapper type_system,
1201 lldb::opaque_compiler_type_t type)
1202 : m_type_system(type_system.GetSharedPointer()), m_type(type) {
1203 assert(Verify() && "verification failed");
1204}
1205
1206CompilerType::CompilerType(lldb::TypeSystemWP type_system,
1207 lldb::opaque_compiler_type_t type)
1208 : m_type_system(type_system), m_type(type) {
1209 assert(Verify() && "verification failed");
1210}
1211
1212#ifndef NDEBUG
1213bool CompilerType::Verify() const {
1214 if (!IsValid())
1215 return true;
1216 if (auto type_system_sp = GetTypeSystem())
1217 return type_system_sp->Verify(type: m_type);
1218 return true;
1219}
1220#endif
1221
1222CompilerType::TypeSystemSPWrapper CompilerType::GetTypeSystem() const {
1223 return {m_type_system.lock()};
1224}
1225
1226bool CompilerType::TypeSystemSPWrapper::operator==(
1227 const CompilerType::TypeSystemSPWrapper &other) const {
1228 if (!m_typesystem_sp && !other.m_typesystem_sp)
1229 return true;
1230 if (m_typesystem_sp && other.m_typesystem_sp)
1231 return m_typesystem_sp.get() == other.m_typesystem_sp.get();
1232 return false;
1233}
1234
1235TypeSystem *CompilerType::TypeSystemSPWrapper::operator->() const {
1236 assert(m_typesystem_sp);
1237 return m_typesystem_sp.get();
1238}
1239
1240bool lldb_private::operator==(const lldb_private::CompilerType &lhs,
1241 const lldb_private::CompilerType &rhs) {
1242 return lhs.GetTypeSystem() == rhs.GetTypeSystem() &&
1243 lhs.GetOpaqueQualType() == rhs.GetOpaqueQualType();
1244}
1245
1246bool lldb_private::operator!=(const lldb_private::CompilerType &lhs,
1247 const lldb_private::CompilerType &rhs) {
1248 return !(lhs == rhs);
1249}
1250

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of lldb/source/Symbol/CompilerType.cpp