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/Core/StreamFile.h"
13 #include "lldb/Symbol/Type.h"
14 #include "lldb/Target/ExecutionContext.h"
15 #include "lldb/Target/Process.h"
16 #include "lldb/Utility/ConstString.h"
17 #include "lldb/Utility/DataBufferHeap.h"
18 #include "lldb/Utility/DataExtractor.h"
19 #include "lldb/Utility/Scalar.h"
20 #include "lldb/Utility/Stream.h"
21 #include "lldb/Utility/StreamString.h"
22
23 #include <iterator>
24 #include <mutex>
25 #include <optional>
26
27 using namespace lldb;
28 using namespace lldb_private;
29
30 // Tests
31
IsAggregateType() const32 bool CompilerType::IsAggregateType() const {
33 if (IsValid())
34 if (auto type_system_sp = GetTypeSystem())
35 return type_system_sp->IsAggregateType(m_type);
36 return false;
37 }
38
IsAnonymousType() const39 bool CompilerType::IsAnonymousType() const {
40 if (IsValid())
41 if (auto type_system_sp = GetTypeSystem())
42 return type_system_sp->IsAnonymousType(m_type);
43 return false;
44 }
45
IsScopedEnumerationType() const46 bool CompilerType::IsScopedEnumerationType() const {
47 if (IsValid())
48 if (auto type_system_sp = GetTypeSystem())
49 return type_system_sp->IsScopedEnumerationType(m_type);
50 return false;
51 }
52
IsArrayType(CompilerType * element_type_ptr,uint64_t * size,bool * is_incomplete) const53 bool CompilerType::IsArrayType(CompilerType *element_type_ptr, uint64_t *size,
54 bool *is_incomplete) const {
55 if (IsValid())
56 if (auto type_system_sp = GetTypeSystem())
57 return type_system_sp->IsArrayType(m_type, element_type_ptr, size,
58 is_incomplete);
59
60 if (element_type_ptr)
61 element_type_ptr->Clear();
62 if (size)
63 *size = 0;
64 if (is_incomplete)
65 *is_incomplete = false;
66 return false;
67 }
68
IsVectorType(CompilerType * element_type,uint64_t * size) const69 bool CompilerType::IsVectorType(CompilerType *element_type,
70 uint64_t *size) const {
71 if (IsValid())
72 if (auto type_system_sp = GetTypeSystem())
73 return type_system_sp->IsVectorType(m_type, element_type, size);
74 return false;
75 }
76
IsRuntimeGeneratedType() const77 bool CompilerType::IsRuntimeGeneratedType() const {
78 if (IsValid())
79 if (auto type_system_sp = GetTypeSystem())
80 return type_system_sp->IsRuntimeGeneratedType(m_type);
81 return false;
82 }
83
IsCharType() const84 bool CompilerType::IsCharType() const {
85 if (IsValid())
86 if (auto type_system_sp = GetTypeSystem())
87 return type_system_sp->IsCharType(m_type);
88 return false;
89 }
90
IsCompleteType() const91 bool CompilerType::IsCompleteType() const {
92 if (IsValid())
93 if (auto type_system_sp = GetTypeSystem())
94 return type_system_sp->IsCompleteType(m_type);
95 return false;
96 }
97
IsForcefullyCompleted() const98 bool CompilerType::IsForcefullyCompleted() const {
99 if (IsValid())
100 if (auto type_system_sp = GetTypeSystem())
101 return type_system_sp->IsForcefullyCompleted(m_type);
102 return false;
103 }
104
IsConst() const105 bool CompilerType::IsConst() const {
106 if (IsValid())
107 if (auto type_system_sp = GetTypeSystem())
108 return type_system_sp->IsConst(m_type);
109 return false;
110 }
111
IsCStringType(uint32_t & length) const112 bool CompilerType::IsCStringType(uint32_t &length) const {
113 if (IsValid())
114 if (auto type_system_sp = GetTypeSystem())
115 return type_system_sp->IsCStringType(m_type, length);
116 return false;
117 }
118
IsFunctionType() const119 bool CompilerType::IsFunctionType() const {
120 if (IsValid())
121 if (auto type_system_sp = GetTypeSystem())
122 return type_system_sp->IsFunctionType(m_type);
123 return false;
124 }
125
126 // Used to detect "Homogeneous Floating-point Aggregates"
127 uint32_t
IsHomogeneousAggregate(CompilerType * base_type_ptr) const128 CompilerType::IsHomogeneousAggregate(CompilerType *base_type_ptr) const {
129 if (IsValid())
130 if (auto type_system_sp = GetTypeSystem())
131 return type_system_sp->IsHomogeneousAggregate(m_type, base_type_ptr);
132 return 0;
133 }
134
GetNumberOfFunctionArguments() const135 size_t CompilerType::GetNumberOfFunctionArguments() const {
136 if (IsValid())
137 if (auto type_system_sp = GetTypeSystem())
138 return type_system_sp->GetNumberOfFunctionArguments(m_type);
139 return 0;
140 }
141
142 CompilerType
GetFunctionArgumentAtIndex(const size_t index) const143 CompilerType::GetFunctionArgumentAtIndex(const size_t index) const {
144 if (IsValid())
145 if (auto type_system_sp = GetTypeSystem())
146 return type_system_sp->GetFunctionArgumentAtIndex(m_type, index);
147 return CompilerType();
148 }
149
IsFunctionPointerType() const150 bool CompilerType::IsFunctionPointerType() const {
151 if (IsValid())
152 if (auto type_system_sp = GetTypeSystem())
153 return type_system_sp->IsFunctionPointerType(m_type);
154 return false;
155 }
156
IsBlockPointerType(CompilerType * function_pointer_type_ptr) const157 bool CompilerType::IsBlockPointerType(
158 CompilerType *function_pointer_type_ptr) const {
159 if (IsValid())
160 if (auto type_system_sp = GetTypeSystem())
161 return type_system_sp->IsBlockPointerType(m_type, function_pointer_type_ptr);
162 return false;
163 }
164
IsIntegerType(bool & is_signed) const165 bool CompilerType::IsIntegerType(bool &is_signed) const {
166 if (IsValid())
167 if (auto type_system_sp = GetTypeSystem())
168 return type_system_sp->IsIntegerType(m_type, is_signed);
169 return false;
170 }
171
IsEnumerationType(bool & is_signed) const172 bool CompilerType::IsEnumerationType(bool &is_signed) const {
173 if (IsValid())
174 if (auto type_system_sp = GetTypeSystem())
175 return type_system_sp->IsEnumerationType(m_type, is_signed);
176 return false;
177 }
178
IsIntegerOrEnumerationType(bool & is_signed) const179 bool CompilerType::IsIntegerOrEnumerationType(bool &is_signed) const {
180 return IsIntegerType(is_signed) || IsEnumerationType(is_signed);
181 }
182
IsPointerType(CompilerType * pointee_type) const183 bool CompilerType::IsPointerType(CompilerType *pointee_type) const {
184 if (IsValid()) {
185 if (auto type_system_sp = GetTypeSystem())
186 return type_system_sp->IsPointerType(m_type, pointee_type);
187 }
188 if (pointee_type)
189 pointee_type->Clear();
190 return false;
191 }
192
IsPointerOrReferenceType(CompilerType * pointee_type) const193 bool CompilerType::IsPointerOrReferenceType(CompilerType *pointee_type) const {
194 if (IsValid()) {
195 if (auto type_system_sp = GetTypeSystem())
196 return type_system_sp->IsPointerOrReferenceType(m_type, pointee_type);
197 }
198 if (pointee_type)
199 pointee_type->Clear();
200 return false;
201 }
202
IsReferenceType(CompilerType * pointee_type,bool * is_rvalue) const203 bool CompilerType::IsReferenceType(CompilerType *pointee_type,
204 bool *is_rvalue) const {
205 if (IsValid()) {
206 if (auto type_system_sp = GetTypeSystem())
207 return type_system_sp->IsReferenceType(m_type, pointee_type, is_rvalue);
208 }
209 if (pointee_type)
210 pointee_type->Clear();
211 return false;
212 }
213
ShouldTreatScalarValueAsAddress() const214 bool CompilerType::ShouldTreatScalarValueAsAddress() const {
215 if (IsValid())
216 if (auto type_system_sp = GetTypeSystem())
217 return type_system_sp->ShouldTreatScalarValueAsAddress(m_type);
218 return false;
219 }
220
IsFloatingPointType(uint32_t & count,bool & is_complex) const221 bool CompilerType::IsFloatingPointType(uint32_t &count,
222 bool &is_complex) const {
223 if (IsValid()) {
224 if (auto type_system_sp = GetTypeSystem())
225 return type_system_sp->IsFloatingPointType(m_type, count, is_complex);
226 }
227 count = 0;
228 is_complex = false;
229 return false;
230 }
231
IsDefined() const232 bool CompilerType::IsDefined() const {
233 if (IsValid())
234 if (auto type_system_sp = GetTypeSystem())
235 return type_system_sp->IsDefined(m_type);
236 return true;
237 }
238
IsPolymorphicClass() const239 bool CompilerType::IsPolymorphicClass() const {
240 if (IsValid()) {
241 if (auto type_system_sp = GetTypeSystem())
242 return type_system_sp->IsPolymorphicClass(m_type);
243 }
244 return false;
245 }
246
IsPossibleDynamicType(CompilerType * dynamic_pointee_type,bool check_cplusplus,bool check_objc) const247 bool CompilerType::IsPossibleDynamicType(CompilerType *dynamic_pointee_type,
248 bool check_cplusplus,
249 bool check_objc) const {
250 if (IsValid())
251 if (auto type_system_sp = GetTypeSystem())
252 return type_system_sp->IsPossibleDynamicType(m_type, dynamic_pointee_type,
253 check_cplusplus, check_objc);
254 return false;
255 }
256
IsScalarType() const257 bool CompilerType::IsScalarType() const {
258 if (IsValid())
259 if (auto type_system_sp = GetTypeSystem())
260 return type_system_sp->IsScalarType(m_type);
261 return false;
262 }
263
IsTemplateType() const264 bool CompilerType::IsTemplateType() const {
265 if (IsValid())
266 if (auto type_system_sp = GetTypeSystem())
267 return type_system_sp->IsTemplateType(m_type);
268 return false;
269 }
270
IsTypedefType() const271 bool CompilerType::IsTypedefType() const {
272 if (IsValid())
273 if (auto type_system_sp = GetTypeSystem())
274 return type_system_sp->IsTypedefType(m_type);
275 return false;
276 }
277
IsVoidType() const278 bool CompilerType::IsVoidType() const {
279 if (IsValid())
280 if (auto type_system_sp = GetTypeSystem())
281 return type_system_sp->IsVoidType(m_type);
282 return false;
283 }
284
IsPointerToScalarType() const285 bool CompilerType::IsPointerToScalarType() const {
286 if (!IsValid())
287 return false;
288
289 return IsPointerType() && GetPointeeType().IsScalarType();
290 }
291
IsArrayOfScalarType() const292 bool CompilerType::IsArrayOfScalarType() const {
293 CompilerType element_type;
294 if (IsArrayType(&element_type))
295 return element_type.IsScalarType();
296 return false;
297 }
298
IsBeingDefined() const299 bool CompilerType::IsBeingDefined() const {
300 if (IsValid())
301 if (auto type_system_sp = GetTypeSystem())
302 return type_system_sp->IsBeingDefined(m_type);
303 return false;
304 }
305
306 // Type Completion
307
GetCompleteType() const308 bool CompilerType::GetCompleteType() const {
309 if (IsValid())
310 if (auto type_system_sp = GetTypeSystem())
311 return type_system_sp->GetCompleteType(m_type);
312 return false;
313 }
314
315 // AST related queries
GetPointerByteSize() const316 size_t CompilerType::GetPointerByteSize() const {
317 if (auto type_system_sp = GetTypeSystem())
318 return type_system_sp->GetPointerByteSize();
319 return 0;
320 }
321
GetTypeName(bool BaseOnly) const322 ConstString CompilerType::GetTypeName(bool BaseOnly) const {
323 if (IsValid()) {
324 if (auto type_system_sp = GetTypeSystem())
325 return type_system_sp->GetTypeName(m_type, BaseOnly);
326 }
327 return ConstString("<invalid>");
328 }
329
GetDisplayTypeName() const330 ConstString CompilerType::GetDisplayTypeName() const {
331 if (IsValid())
332 if (auto type_system_sp = GetTypeSystem())
333 return type_system_sp->GetDisplayTypeName(m_type);
334 return ConstString("<invalid>");
335 }
336
GetTypeInfo(CompilerType * pointee_or_element_compiler_type) const337 uint32_t CompilerType::GetTypeInfo(
338 CompilerType *pointee_or_element_compiler_type) const {
339 if (IsValid())
340 if (auto type_system_sp = GetTypeSystem())
341 return type_system_sp->GetTypeInfo(m_type,
342 pointee_or_element_compiler_type);
343 return 0;
344 }
345
GetMinimumLanguage()346 lldb::LanguageType CompilerType::GetMinimumLanguage() {
347 if (IsValid())
348 if (auto type_system_sp = GetTypeSystem())
349 return type_system_sp->GetMinimumLanguage(m_type);
350 return lldb::eLanguageTypeC;
351 }
352
GetTypeClass() const353 lldb::TypeClass CompilerType::GetTypeClass() const {
354 if (IsValid())
355 if (auto type_system_sp = GetTypeSystem())
356 return type_system_sp->GetTypeClass(m_type);
357 return lldb::eTypeClassInvalid;
358 }
359
SetCompilerType(lldb::TypeSystemWP type_system,lldb::opaque_compiler_type_t type)360 void CompilerType::SetCompilerType(lldb::TypeSystemWP type_system,
361 lldb::opaque_compiler_type_t type) {
362 m_type_system = type_system;
363 m_type = type;
364 }
365
SetCompilerType(CompilerType::TypeSystemSPWrapper type_system,lldb::opaque_compiler_type_t type)366 void CompilerType::SetCompilerType(CompilerType::TypeSystemSPWrapper type_system,
367 lldb::opaque_compiler_type_t type) {
368 m_type_system = type_system.GetSharedPointer();
369 m_type = type;
370 }
371
GetTypeQualifiers() const372 unsigned CompilerType::GetTypeQualifiers() const {
373 if (IsValid())
374 if (auto type_system_sp = GetTypeSystem())
375 return type_system_sp->GetTypeQualifiers(m_type);
376 return 0;
377 }
378
379 // Creating related types
380
381 CompilerType
GetArrayElementType(ExecutionContextScope * exe_scope) const382 CompilerType::GetArrayElementType(ExecutionContextScope *exe_scope) const {
383 if (IsValid()) {
384 if (auto type_system_sp = GetTypeSystem())
385 return type_system_sp->GetArrayElementType(m_type, exe_scope);
386 }
387 return CompilerType();
388 }
389
GetArrayType(uint64_t size) const390 CompilerType CompilerType::GetArrayType(uint64_t size) const {
391 if (IsValid()) {
392 if (auto type_system_sp = GetTypeSystem())
393 return type_system_sp->GetArrayType(m_type, size);
394 }
395 return CompilerType();
396 }
397
GetCanonicalType() const398 CompilerType CompilerType::GetCanonicalType() const {
399 if (IsValid())
400 if (auto type_system_sp = GetTypeSystem())
401 return type_system_sp->GetCanonicalType(m_type);
402 return CompilerType();
403 }
404
GetFullyUnqualifiedType() const405 CompilerType CompilerType::GetFullyUnqualifiedType() const {
406 if (IsValid())
407 if (auto type_system_sp = GetTypeSystem())
408 return type_system_sp->GetFullyUnqualifiedType(m_type);
409 return CompilerType();
410 }
411
GetEnumerationIntegerType() const412 CompilerType CompilerType::GetEnumerationIntegerType() const {
413 if (IsValid())
414 if (auto type_system_sp = GetTypeSystem())
415 return type_system_sp->GetEnumerationIntegerType(m_type);
416 return CompilerType();
417 }
418
GetFunctionArgumentCount() const419 int CompilerType::GetFunctionArgumentCount() const {
420 if (IsValid()) {
421 if (auto type_system_sp = GetTypeSystem())
422 return type_system_sp->GetFunctionArgumentCount(m_type);
423 }
424 return -1;
425 }
426
GetFunctionArgumentTypeAtIndex(size_t idx) const427 CompilerType CompilerType::GetFunctionArgumentTypeAtIndex(size_t idx) const {
428 if (IsValid()) {
429 if (auto type_system_sp = GetTypeSystem())
430 return type_system_sp->GetFunctionArgumentTypeAtIndex(m_type, idx);
431 }
432 return CompilerType();
433 }
434
GetFunctionReturnType() const435 CompilerType CompilerType::GetFunctionReturnType() const {
436 if (IsValid()) {
437 if (auto type_system_sp = GetTypeSystem())
438 return type_system_sp->GetFunctionReturnType(m_type);
439 }
440 return CompilerType();
441 }
442
GetNumMemberFunctions() const443 size_t CompilerType::GetNumMemberFunctions() const {
444 if (IsValid()) {
445 if (auto type_system_sp = GetTypeSystem())
446 return type_system_sp->GetNumMemberFunctions(m_type);
447 }
448 return 0;
449 }
450
GetMemberFunctionAtIndex(size_t idx)451 TypeMemberFunctionImpl CompilerType::GetMemberFunctionAtIndex(size_t idx) {
452 if (IsValid()) {
453 if (auto type_system_sp = GetTypeSystem())
454 return type_system_sp->GetMemberFunctionAtIndex(m_type, idx);
455 }
456 return TypeMemberFunctionImpl();
457 }
458
GetNonReferenceType() const459 CompilerType CompilerType::GetNonReferenceType() const {
460 if (IsValid())
461 if (auto type_system_sp = GetTypeSystem())
462 return type_system_sp->GetNonReferenceType(m_type);
463 return CompilerType();
464 }
465
GetPointeeType() const466 CompilerType CompilerType::GetPointeeType() const {
467 if (IsValid()) {
468 if (auto type_system_sp = GetTypeSystem())
469 return type_system_sp->GetPointeeType(m_type);
470 }
471 return CompilerType();
472 }
473
GetPointerType() const474 CompilerType CompilerType::GetPointerType() const {
475 if (IsValid()) {
476 if (auto type_system_sp = GetTypeSystem())
477 return type_system_sp->GetPointerType(m_type);
478 }
479 return CompilerType();
480 }
481
GetLValueReferenceType() const482 CompilerType CompilerType::GetLValueReferenceType() const {
483 if (IsValid())
484 if (auto type_system_sp = GetTypeSystem())
485 return type_system_sp->GetLValueReferenceType(m_type);
486 return CompilerType();
487 }
488
GetRValueReferenceType() const489 CompilerType CompilerType::GetRValueReferenceType() const {
490 if (IsValid())
491 if (auto type_system_sp = GetTypeSystem())
492 return type_system_sp->GetRValueReferenceType(m_type);
493 return CompilerType();
494 }
495
GetAtomicType() const496 CompilerType CompilerType::GetAtomicType() const {
497 if (IsValid())
498 if (auto type_system_sp = GetTypeSystem())
499 return type_system_sp->GetAtomicType(m_type);
500 return CompilerType();
501 }
502
AddConstModifier() const503 CompilerType CompilerType::AddConstModifier() const {
504 if (IsValid())
505 if (auto type_system_sp = GetTypeSystem())
506 return type_system_sp->AddConstModifier(m_type);
507 return CompilerType();
508 }
509
AddVolatileModifier() const510 CompilerType CompilerType::AddVolatileModifier() const {
511 if (IsValid())
512 if (auto type_system_sp = GetTypeSystem())
513 return type_system_sp->AddVolatileModifier(m_type);
514 return CompilerType();
515 }
516
AddRestrictModifier() const517 CompilerType CompilerType::AddRestrictModifier() const {
518 if (IsValid())
519 if (auto type_system_sp = GetTypeSystem())
520 return type_system_sp->AddRestrictModifier(m_type);
521 return CompilerType();
522 }
523
CreateTypedef(const char * name,const CompilerDeclContext & decl_ctx,uint32_t payload) const524 CompilerType CompilerType::CreateTypedef(const char *name,
525 const CompilerDeclContext &decl_ctx,
526 uint32_t payload) const {
527 if (IsValid())
528 if (auto type_system_sp = GetTypeSystem())
529 return type_system_sp->CreateTypedef(m_type, name, decl_ctx, payload);
530 return CompilerType();
531 }
532
GetTypedefedType() const533 CompilerType CompilerType::GetTypedefedType() const {
534 if (IsValid())
535 if (auto type_system_sp = GetTypeSystem())
536 return type_system_sp->GetTypedefedType(m_type);
537 return CompilerType();
538 }
539
540 // Create related types using the current type's AST
541
542 CompilerType
GetBasicTypeFromAST(lldb::BasicType basic_type) const543 CompilerType::GetBasicTypeFromAST(lldb::BasicType basic_type) const {
544 if (IsValid())
545 if (auto type_system_sp = GetTypeSystem())
546 return type_system_sp->GetBasicTypeFromAST(basic_type);
547 return CompilerType();
548 }
549 // Exploring the type
550
551 std::optional<uint64_t>
GetBitSize(ExecutionContextScope * exe_scope) const552 CompilerType::GetBitSize(ExecutionContextScope *exe_scope) const {
553 if (IsValid())
554 if (auto type_system_sp = GetTypeSystem())
555 return type_system_sp->GetBitSize(m_type, exe_scope);
556 return {};
557 }
558
559 std::optional<uint64_t>
GetByteSize(ExecutionContextScope * exe_scope) const560 CompilerType::GetByteSize(ExecutionContextScope *exe_scope) const {
561 if (std::optional<uint64_t> bit_size = GetBitSize(exe_scope))
562 return (*bit_size + 7) / 8;
563 return {};
564 }
565
566 std::optional<size_t>
GetTypeBitAlign(ExecutionContextScope * exe_scope) const567 CompilerType::GetTypeBitAlign(ExecutionContextScope *exe_scope) const {
568 if (IsValid())
569 if (auto type_system_sp = GetTypeSystem())
570 return type_system_sp->GetTypeBitAlign(m_type, exe_scope);
571 return {};
572 }
573
GetEncoding(uint64_t & count) const574 lldb::Encoding CompilerType::GetEncoding(uint64_t &count) const {
575 if (IsValid())
576 if (auto type_system_sp = GetTypeSystem())
577 return type_system_sp->GetEncoding(m_type, count);
578 return lldb::eEncodingInvalid;
579 }
580
GetFormat() const581 lldb::Format CompilerType::GetFormat() const {
582 if (IsValid())
583 if (auto type_system_sp = GetTypeSystem())
584 return type_system_sp->GetFormat(m_type);
585 return lldb::eFormatDefault;
586 }
587
GetNumChildren(bool omit_empty_base_classes,const ExecutionContext * exe_ctx) const588 uint32_t CompilerType::GetNumChildren(bool omit_empty_base_classes,
589 const ExecutionContext *exe_ctx) const {
590 if (IsValid())
591 if (auto type_system_sp = GetTypeSystem())
592 return type_system_sp->GetNumChildren(m_type, omit_empty_base_classes,
593 exe_ctx);
594 return 0;
595 }
596
GetBasicTypeEnumeration() const597 lldb::BasicType CompilerType::GetBasicTypeEnumeration() const {
598 if (IsValid())
599 if (auto type_system_sp = GetTypeSystem())
600 return type_system_sp->GetBasicTypeEnumeration(m_type);
601 return eBasicTypeInvalid;
602 }
603
ForEachEnumerator(std::function<bool (const CompilerType & integer_type,ConstString name,const llvm::APSInt & value)> const & callback) const604 void CompilerType::ForEachEnumerator(
605 std::function<bool(const CompilerType &integer_type,
606 ConstString name,
607 const llvm::APSInt &value)> const &callback) const {
608 if (IsValid())
609 if (auto type_system_sp = GetTypeSystem())
610 return type_system_sp->ForEachEnumerator(m_type, callback);
611 }
612
GetNumFields() const613 uint32_t CompilerType::GetNumFields() const {
614 if (IsValid())
615 if (auto type_system_sp = GetTypeSystem())
616 return type_system_sp->GetNumFields(m_type);
617 return 0;
618 }
619
GetFieldAtIndex(size_t idx,std::string & name,uint64_t * bit_offset_ptr,uint32_t * bitfield_bit_size_ptr,bool * is_bitfield_ptr) const620 CompilerType CompilerType::GetFieldAtIndex(size_t idx, std::string &name,
621 uint64_t *bit_offset_ptr,
622 uint32_t *bitfield_bit_size_ptr,
623 bool *is_bitfield_ptr) const {
624 if (IsValid())
625 if (auto type_system_sp = GetTypeSystem())
626 return type_system_sp->GetFieldAtIndex(m_type, idx, name, bit_offset_ptr,
627 bitfield_bit_size_ptr, is_bitfield_ptr);
628 return CompilerType();
629 }
630
GetNumDirectBaseClasses() const631 uint32_t CompilerType::GetNumDirectBaseClasses() const {
632 if (IsValid())
633 if (auto type_system_sp = GetTypeSystem())
634 return type_system_sp->GetNumDirectBaseClasses(m_type);
635 return 0;
636 }
637
GetNumVirtualBaseClasses() const638 uint32_t CompilerType::GetNumVirtualBaseClasses() const {
639 if (IsValid())
640 if (auto type_system_sp = GetTypeSystem())
641 return type_system_sp->GetNumVirtualBaseClasses(m_type);
642 return 0;
643 }
644
645 CompilerType
GetDirectBaseClassAtIndex(size_t idx,uint32_t * bit_offset_ptr) const646 CompilerType::GetDirectBaseClassAtIndex(size_t idx,
647 uint32_t *bit_offset_ptr) const {
648 if (IsValid())
649 if (auto type_system_sp = GetTypeSystem())
650 return type_system_sp->GetDirectBaseClassAtIndex(m_type, idx,
651 bit_offset_ptr);
652 return CompilerType();
653 }
654
655 CompilerType
GetVirtualBaseClassAtIndex(size_t idx,uint32_t * bit_offset_ptr) const656 CompilerType::GetVirtualBaseClassAtIndex(size_t idx,
657 uint32_t *bit_offset_ptr) const {
658 if (IsValid())
659 if (auto type_system_sp = GetTypeSystem())
660 return type_system_sp->GetVirtualBaseClassAtIndex(m_type, idx,
661 bit_offset_ptr);
662 return CompilerType();
663 }
664
GetIndexOfFieldWithName(const char * name,CompilerType * field_compiler_type_ptr,uint64_t * bit_offset_ptr,uint32_t * bitfield_bit_size_ptr,bool * is_bitfield_ptr) const665 uint32_t CompilerType::GetIndexOfFieldWithName(
666 const char *name, CompilerType *field_compiler_type_ptr,
667 uint64_t *bit_offset_ptr, uint32_t *bitfield_bit_size_ptr,
668 bool *is_bitfield_ptr) const {
669 unsigned count = GetNumFields();
670 std::string field_name;
671 for (unsigned index = 0; index < count; index++) {
672 CompilerType field_compiler_type(
673 GetFieldAtIndex(index, field_name, bit_offset_ptr,
674 bitfield_bit_size_ptr, is_bitfield_ptr));
675 if (strcmp(field_name.c_str(), name) == 0) {
676 if (field_compiler_type_ptr)
677 *field_compiler_type_ptr = field_compiler_type;
678 return index;
679 }
680 }
681 return UINT32_MAX;
682 }
683
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) const684 CompilerType CompilerType::GetChildCompilerTypeAtIndex(
685 ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers,
686 bool omit_empty_base_classes, bool ignore_array_bounds,
687 std::string &child_name, uint32_t &child_byte_size,
688 int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size,
689 uint32_t &child_bitfield_bit_offset, bool &child_is_base_class,
690 bool &child_is_deref_of_parent, ValueObject *valobj,
691 uint64_t &language_flags) const {
692 if (IsValid())
693 if (auto type_system_sp = GetTypeSystem())
694 return type_system_sp->GetChildCompilerTypeAtIndex(
695 m_type, exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
696 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
697 child_bitfield_bit_size, child_bitfield_bit_offset,
698 child_is_base_class, child_is_deref_of_parent, valobj,
699 language_flags);
700 return CompilerType();
701 }
702
703 // Look for a child member (doesn't include base classes, but it does include
704 // their members) in the type hierarchy. Returns an index path into
705 // "clang_type" on how to reach the appropriate member.
706 //
707 // class A
708 // {
709 // public:
710 // int m_a;
711 // int m_b;
712 // };
713 //
714 // class B
715 // {
716 // };
717 //
718 // class C :
719 // public B,
720 // public A
721 // {
722 // };
723 //
724 // If we have a clang type that describes "class C", and we wanted to looked
725 // "m_b" in it:
726 //
727 // With omit_empty_base_classes == false we would get an integer array back
728 // with: { 1, 1 } The first index 1 is the child index for "class A" within
729 // class C The second index 1 is the child index for "m_b" within class A
730 //
731 // With omit_empty_base_classes == true we would get an integer array back
732 // with: { 0, 1 } The first index 0 is the child index for "class A" within
733 // class C (since class B doesn't have any members it doesn't count) The second
734 // index 1 is the child index for "m_b" within class A
735
GetIndexOfChildMemberWithName(const char * name,bool omit_empty_base_classes,std::vector<uint32_t> & child_indexes) const736 size_t CompilerType::GetIndexOfChildMemberWithName(
737 const char *name, bool omit_empty_base_classes,
738 std::vector<uint32_t> &child_indexes) const {
739 if (IsValid() && name && name[0]) {
740 if (auto type_system_sp = GetTypeSystem())
741 return type_system_sp->GetIndexOfChildMemberWithName(
742 m_type, name, omit_empty_base_classes, child_indexes);
743 }
744 return 0;
745 }
746
GetNumTemplateArguments(bool expand_pack) const747 size_t CompilerType::GetNumTemplateArguments(bool expand_pack) const {
748 if (IsValid()) {
749 if (auto type_system_sp = GetTypeSystem())
750 return type_system_sp->GetNumTemplateArguments(m_type, expand_pack);
751 }
752 return 0;
753 }
754
755 TemplateArgumentKind
GetTemplateArgumentKind(size_t idx,bool expand_pack) const756 CompilerType::GetTemplateArgumentKind(size_t idx, bool expand_pack) const {
757 if (IsValid())
758 if (auto type_system_sp = GetTypeSystem())
759 return type_system_sp->GetTemplateArgumentKind(m_type, idx, expand_pack);
760 return eTemplateArgumentKindNull;
761 }
762
GetTypeTemplateArgument(size_t idx,bool expand_pack) const763 CompilerType CompilerType::GetTypeTemplateArgument(size_t idx,
764 bool expand_pack) const {
765 if (IsValid()) {
766 if (auto type_system_sp = GetTypeSystem())
767 return type_system_sp->GetTypeTemplateArgument(m_type, idx, expand_pack);
768 }
769 return CompilerType();
770 }
771
772 std::optional<CompilerType::IntegralTemplateArgument>
GetIntegralTemplateArgument(size_t idx,bool expand_pack) const773 CompilerType::GetIntegralTemplateArgument(size_t idx, bool expand_pack) const {
774 if (IsValid())
775 if (auto type_system_sp = GetTypeSystem())
776 return type_system_sp->GetIntegralTemplateArgument(m_type, idx, expand_pack);
777 return std::nullopt;
778 }
779
GetTypeForFormatters() const780 CompilerType CompilerType::GetTypeForFormatters() const {
781 if (IsValid())
782 if (auto type_system_sp = GetTypeSystem())
783 return type_system_sp->GetTypeForFormatters(m_type);
784 return CompilerType();
785 }
786
ShouldPrintAsOneLiner(ValueObject * valobj) const787 LazyBool CompilerType::ShouldPrintAsOneLiner(ValueObject *valobj) const {
788 if (IsValid())
789 if (auto type_system_sp = GetTypeSystem())
790 return type_system_sp->ShouldPrintAsOneLiner(m_type, valobj);
791 return eLazyBoolCalculate;
792 }
793
IsMeaninglessWithoutDynamicResolution() const794 bool CompilerType::IsMeaninglessWithoutDynamicResolution() const {
795 if (IsValid())
796 if (auto type_system_sp = GetTypeSystem())
797 return type_system_sp->IsMeaninglessWithoutDynamicResolution(m_type);
798 return false;
799 }
800
801 // Get the index of the child of "clang_type" whose name matches. This function
802 // doesn't descend into the children, but only looks one level deep and name
803 // matches can include base class names.
804
805 uint32_t
GetIndexOfChildWithName(const char * name,bool omit_empty_base_classes) const806 CompilerType::GetIndexOfChildWithName(const char *name,
807 bool omit_empty_base_classes) const {
808 if (IsValid() && name && name[0]) {
809 if (auto type_system_sp = GetTypeSystem())
810 return type_system_sp->GetIndexOfChildWithName(m_type, name,
811 omit_empty_base_classes);
812 }
813 return UINT32_MAX;
814 }
815
816 // Dumping types
817
DumpValue(ExecutionContext * exe_ctx,Stream * s,lldb::Format format,const DataExtractor & data,lldb::offset_t data_byte_offset,size_t data_byte_size,uint32_t bitfield_bit_size,uint32_t bitfield_bit_offset,bool show_types,bool show_summary,bool verbose,uint32_t depth)818 void CompilerType::DumpValue(ExecutionContext *exe_ctx, Stream *s,
819 lldb::Format format, const DataExtractor &data,
820 lldb::offset_t data_byte_offset,
821 size_t data_byte_size, uint32_t bitfield_bit_size,
822 uint32_t bitfield_bit_offset, bool show_types,
823 bool show_summary, bool verbose, uint32_t depth) {
824 if (!IsValid())
825 if (auto type_system_sp = GetTypeSystem())
826 type_system_sp->DumpValue(m_type, exe_ctx, s, format, data,
827 data_byte_offset, data_byte_size,
828 bitfield_bit_size, bitfield_bit_offset,
829 show_types, show_summary, verbose, depth);
830 }
831
DumpTypeValue(Stream * s,lldb::Format format,const DataExtractor & data,lldb::offset_t byte_offset,size_t byte_size,uint32_t bitfield_bit_size,uint32_t bitfield_bit_offset,ExecutionContextScope * exe_scope)832 bool CompilerType::DumpTypeValue(Stream *s, lldb::Format format,
833 const DataExtractor &data,
834 lldb::offset_t byte_offset, size_t byte_size,
835 uint32_t bitfield_bit_size,
836 uint32_t bitfield_bit_offset,
837 ExecutionContextScope *exe_scope) {
838 if (IsValid())
839 if (auto type_system_sp = GetTypeSystem())
840 return type_system_sp->DumpTypeValue(m_type, s, format, data, byte_offset,
841 byte_size, bitfield_bit_size,
842 bitfield_bit_offset, exe_scope);
843 return false;
844 }
845
DumpSummary(ExecutionContext * exe_ctx,Stream * s,const DataExtractor & data,lldb::offset_t data_byte_offset,size_t data_byte_size)846 void CompilerType::DumpSummary(ExecutionContext *exe_ctx, Stream *s,
847 const DataExtractor &data,
848 lldb::offset_t data_byte_offset,
849 size_t data_byte_size) {
850 if (IsValid())
851 if (auto type_system_sp = GetTypeSystem())
852 type_system_sp->DumpSummary(m_type, exe_ctx, s, data, data_byte_offset,
853 data_byte_size);
854 }
855
DumpTypeDescription(lldb::DescriptionLevel level) const856 void CompilerType::DumpTypeDescription(lldb::DescriptionLevel level) const {
857 if (IsValid())
858 if (auto type_system_sp = GetTypeSystem())
859 type_system_sp->DumpTypeDescription(m_type, level);
860 }
861
DumpTypeDescription(Stream * s,lldb::DescriptionLevel level) const862 void CompilerType::DumpTypeDescription(Stream *s,
863 lldb::DescriptionLevel level) const {
864 if (IsValid())
865 if (auto type_system_sp = GetTypeSystem())
866 type_system_sp->DumpTypeDescription(m_type, s, level);
867 }
868
869 #ifndef NDEBUG
dump() const870 LLVM_DUMP_METHOD void CompilerType::dump() const {
871 if (IsValid())
872 if (auto type_system_sp = GetTypeSystem())
873 return type_system_sp->dump(m_type);
874 llvm::errs() << "<invalid>\n";
875 }
876 #endif
877
GetValueAsScalar(const lldb_private::DataExtractor & data,lldb::offset_t data_byte_offset,size_t data_byte_size,Scalar & value,ExecutionContextScope * exe_scope) const878 bool CompilerType::GetValueAsScalar(const lldb_private::DataExtractor &data,
879 lldb::offset_t data_byte_offset,
880 size_t data_byte_size, Scalar &value,
881 ExecutionContextScope *exe_scope) const {
882 if (!IsValid())
883 return false;
884
885 if (IsAggregateType()) {
886 return false; // Aggregate types don't have scalar values
887 } else {
888 uint64_t count = 0;
889 lldb::Encoding encoding = GetEncoding(count);
890
891 if (encoding == lldb::eEncodingInvalid || count != 1)
892 return false;
893
894 std::optional<uint64_t> byte_size = GetByteSize(exe_scope);
895 if (!byte_size)
896 return false;
897 lldb::offset_t offset = data_byte_offset;
898 switch (encoding) {
899 case lldb::eEncodingInvalid:
900 break;
901 case lldb::eEncodingVector:
902 break;
903 case lldb::eEncodingUint:
904 if (*byte_size <= sizeof(unsigned long long)) {
905 uint64_t uval64 = data.GetMaxU64(&offset, *byte_size);
906 if (*byte_size <= sizeof(unsigned int)) {
907 value = (unsigned int)uval64;
908 return true;
909 } else if (*byte_size <= sizeof(unsigned long)) {
910 value = (unsigned long)uval64;
911 return true;
912 } else if (*byte_size <= sizeof(unsigned long long)) {
913 value = (unsigned long long)uval64;
914 return true;
915 } else
916 value.Clear();
917 }
918 break;
919
920 case lldb::eEncodingSint:
921 if (*byte_size <= sizeof(long long)) {
922 int64_t sval64 = data.GetMaxS64(&offset, *byte_size);
923 if (*byte_size <= sizeof(int)) {
924 value = (int)sval64;
925 return true;
926 } else if (*byte_size <= sizeof(long)) {
927 value = (long)sval64;
928 return true;
929 } else if (*byte_size <= sizeof(long long)) {
930 value = (long long)sval64;
931 return true;
932 } else
933 value.Clear();
934 }
935 break;
936
937 case lldb::eEncodingIEEE754:
938 if (*byte_size <= sizeof(long double)) {
939 uint32_t u32;
940 uint64_t u64;
941 if (*byte_size == sizeof(float)) {
942 if (sizeof(float) == sizeof(uint32_t)) {
943 u32 = data.GetU32(&offset);
944 value = *((float *)&u32);
945 return true;
946 } else if (sizeof(float) == sizeof(uint64_t)) {
947 u64 = data.GetU64(&offset);
948 value = *((float *)&u64);
949 return true;
950 }
951 } else if (*byte_size == sizeof(double)) {
952 if (sizeof(double) == sizeof(uint32_t)) {
953 u32 = data.GetU32(&offset);
954 value = *((double *)&u32);
955 return true;
956 } else if (sizeof(double) == sizeof(uint64_t)) {
957 u64 = data.GetU64(&offset);
958 value = *((double *)&u64);
959 return true;
960 }
961 } else if (*byte_size == sizeof(long double)) {
962 if (sizeof(long double) == sizeof(uint32_t)) {
963 u32 = data.GetU32(&offset);
964 value = *((long double *)&u32);
965 return true;
966 } else if (sizeof(long double) == sizeof(uint64_t)) {
967 u64 = data.GetU64(&offset);
968 value = *((long double *)&u64);
969 return true;
970 }
971 }
972 }
973 break;
974 }
975 }
976 return false;
977 }
978
979 #ifndef NDEBUG
Verify() const980 bool CompilerType::Verify() const {
981 if (!IsValid())
982 return true;
983 if (auto type_system_sp = GetTypeSystem())
984 return type_system_sp->Verify(m_type);
985 return true;
986 }
987 #endif
988
GetTypeSystem() const989 CompilerType::TypeSystemSPWrapper CompilerType::GetTypeSystem() const {
990 return {m_type_system.lock()};
991 }
992
operator ==(const CompilerType::TypeSystemSPWrapper & other) const993 bool CompilerType::TypeSystemSPWrapper::operator==(
994 const CompilerType::TypeSystemSPWrapper &other) const {
995 if (!m_typesystem_sp && !other.m_typesystem_sp)
996 return true;
997 if (m_typesystem_sp && other.m_typesystem_sp)
998 return m_typesystem_sp.get() == other.m_typesystem_sp.get();
999 return false;
1000 }
1001
operator ->() const1002 TypeSystem *CompilerType::TypeSystemSPWrapper::operator->() const {
1003 assert(m_typesystem_sp);
1004 return m_typesystem_sp.get();
1005 }
1006
operator ==(const lldb_private::CompilerType & lhs,const lldb_private::CompilerType & rhs)1007 bool lldb_private::operator==(const lldb_private::CompilerType &lhs,
1008 const lldb_private::CompilerType &rhs) {
1009 return lhs.GetTypeSystem() == rhs.GetTypeSystem() &&
1010 lhs.GetOpaqueQualType() == rhs.GetOpaqueQualType();
1011 }
1012
operator !=(const lldb_private::CompilerType & lhs,const lldb_private::CompilerType & rhs)1013 bool lldb_private::operator!=(const lldb_private::CompilerType &lhs,
1014 const lldb_private::CompilerType &rhs) {
1015 return !(lhs == rhs);
1016 }
1017