1 //===-- CompilerType.cpp ----------------------------------------*- C++ -*-===//
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/ClangASTContext.h"
14 #include "lldb/Symbol/ClangExternalASTSourceCommon.h"
15 #include "lldb/Symbol/Type.h"
16 #include "lldb/Target/ExecutionContext.h"
17 #include "lldb/Target/Process.h"
18 #include "lldb/Utility/ConstString.h"
19 #include "lldb/Utility/DataBufferHeap.h"
20 #include "lldb/Utility/DataExtractor.h"
21 #include "lldb/Utility/Scalar.h"
22 #include "lldb/Utility/Stream.h"
23 #include "lldb/Utility/StreamString.h"
24 
25 #include <iterator>
26 #include <mutex>
27 
28 using namespace lldb;
29 using namespace lldb_private;
30 
31 CompilerType::CompilerType(TypeSystem *type_system,
32                            lldb::opaque_compiler_type_t type)
33     : m_type(type), m_type_system(type_system) {}
34 
35 CompilerType::CompilerType(clang::ASTContext *ast, clang::QualType qual_type)
36     : m_type(qual_type.getAsOpaquePtr()),
37       m_type_system(ClangASTContext::GetASTContext(ast)) {
38 #ifdef LLDB_CONFIGURATION_DEBUG
39   if (m_type)
40     assert(m_type_system != nullptr);
41 #endif
42 }
43 
44 CompilerType::~CompilerType() {}
45 
46 //----------------------------------------------------------------------
47 // Tests
48 //----------------------------------------------------------------------
49 
50 bool CompilerType::IsAggregateType() const {
51   if (IsValid())
52     return m_type_system->IsAggregateType(m_type);
53   return false;
54 }
55 
56 bool CompilerType::IsAnonymousType() const {
57   if (IsValid())
58     return m_type_system->IsAnonymousType(m_type);
59   return false;
60 }
61 
62 bool CompilerType::IsArrayType(CompilerType *element_type_ptr, uint64_t *size,
63                                bool *is_incomplete) const {
64   if (IsValid())
65     return m_type_system->IsArrayType(m_type, element_type_ptr, size,
66                                       is_incomplete);
67 
68   if (element_type_ptr)
69     element_type_ptr->Clear();
70   if (size)
71     *size = 0;
72   if (is_incomplete)
73     *is_incomplete = false;
74   return false;
75 }
76 
77 bool CompilerType::IsVectorType(CompilerType *element_type,
78                                 uint64_t *size) const {
79   if (IsValid())
80     return m_type_system->IsVectorType(m_type, element_type, size);
81   return false;
82 }
83 
84 bool CompilerType::IsRuntimeGeneratedType() const {
85   if (IsValid())
86     return m_type_system->IsRuntimeGeneratedType(m_type);
87   return false;
88 }
89 
90 bool CompilerType::IsCharType() const {
91   if (IsValid())
92     return m_type_system->IsCharType(m_type);
93   return false;
94 }
95 
96 bool CompilerType::IsCompleteType() const {
97   if (IsValid())
98     return m_type_system->IsCompleteType(m_type);
99   return false;
100 }
101 
102 bool CompilerType::IsConst() const {
103   if (IsValid())
104     return m_type_system->IsConst(m_type);
105   return false;
106 }
107 
108 bool CompilerType::IsCStringType(uint32_t &length) const {
109   if (IsValid())
110     return m_type_system->IsCStringType(m_type, length);
111   return false;
112 }
113 
114 bool CompilerType::IsFunctionType(bool *is_variadic_ptr) const {
115   if (IsValid())
116     return m_type_system->IsFunctionType(m_type, is_variadic_ptr);
117   return false;
118 }
119 
120 // Used to detect "Homogeneous Floating-point Aggregates"
121 uint32_t
122 CompilerType::IsHomogeneousAggregate(CompilerType *base_type_ptr) const {
123   if (IsValid())
124     return m_type_system->IsHomogeneousAggregate(m_type, base_type_ptr);
125   return 0;
126 }
127 
128 size_t CompilerType::GetNumberOfFunctionArguments() const {
129   if (IsValid())
130     return m_type_system->GetNumberOfFunctionArguments(m_type);
131   return 0;
132 }
133 
134 CompilerType
135 CompilerType::GetFunctionArgumentAtIndex(const size_t index) const {
136   if (IsValid())
137     return m_type_system->GetFunctionArgumentAtIndex(m_type, index);
138   return CompilerType();
139 }
140 
141 bool CompilerType::IsFunctionPointerType() const {
142   if (IsValid())
143     return m_type_system->IsFunctionPointerType(m_type);
144   return false;
145 }
146 
147 bool CompilerType::IsBlockPointerType(
148     CompilerType *function_pointer_type_ptr) const {
149   if (IsValid())
150     return m_type_system->IsBlockPointerType(m_type, function_pointer_type_ptr);
151   return 0;
152 }
153 
154 bool CompilerType::IsIntegerType(bool &is_signed) const {
155   if (IsValid())
156     return m_type_system->IsIntegerType(m_type, is_signed);
157   return false;
158 }
159 
160 bool CompilerType::IsEnumerationType(bool &is_signed) const {
161   if (IsValid())
162     return m_type_system->IsEnumerationType(m_type, is_signed);
163   return false;
164 }
165 
166 bool CompilerType::IsIntegerOrEnumerationType(bool &is_signed) const {
167   return IsIntegerType(is_signed) || IsEnumerationType(is_signed);
168 }
169 
170 bool CompilerType::IsPointerType(CompilerType *pointee_type) const {
171   if (IsValid()) {
172     return m_type_system->IsPointerType(m_type, pointee_type);
173   }
174   if (pointee_type)
175     pointee_type->Clear();
176   return false;
177 }
178 
179 bool CompilerType::IsPointerOrReferenceType(CompilerType *pointee_type) const {
180   if (IsValid()) {
181     return m_type_system->IsPointerOrReferenceType(m_type, pointee_type);
182   }
183   if (pointee_type)
184     pointee_type->Clear();
185   return false;
186 }
187 
188 bool CompilerType::IsReferenceType(CompilerType *pointee_type,
189                                    bool *is_rvalue) const {
190   if (IsValid()) {
191     return m_type_system->IsReferenceType(m_type, pointee_type, is_rvalue);
192   }
193   if (pointee_type)
194     pointee_type->Clear();
195   return false;
196 }
197 
198 bool CompilerType::ShouldTreatScalarValueAsAddress() const {
199   if (IsValid())
200     return m_type_system->ShouldTreatScalarValueAsAddress(m_type);
201   return false;
202 }
203 
204 bool CompilerType::IsFloatingPointType(uint32_t &count,
205                                        bool &is_complex) const {
206   if (IsValid()) {
207     return m_type_system->IsFloatingPointType(m_type, count, is_complex);
208   }
209   count = 0;
210   is_complex = false;
211   return false;
212 }
213 
214 bool CompilerType::IsDefined() const {
215   if (IsValid())
216     return m_type_system->IsDefined(m_type);
217   return true;
218 }
219 
220 bool CompilerType::IsPolymorphicClass() const {
221   if (IsValid()) {
222     return m_type_system->IsPolymorphicClass(m_type);
223   }
224   return false;
225 }
226 
227 bool CompilerType::IsPossibleDynamicType(CompilerType *dynamic_pointee_type,
228                                          bool check_cplusplus,
229                                          bool check_objc) const {
230   if (IsValid())
231     return m_type_system->IsPossibleDynamicType(m_type, dynamic_pointee_type,
232                                                 check_cplusplus, check_objc);
233   return false;
234 }
235 
236 bool CompilerType::IsScalarType() const {
237   if (!IsValid())
238     return false;
239 
240   return m_type_system->IsScalarType(m_type);
241 }
242 
243 bool CompilerType::IsTypedefType() const {
244   if (!IsValid())
245     return false;
246   return m_type_system->IsTypedefType(m_type);
247 }
248 
249 bool CompilerType::IsVoidType() const {
250   if (!IsValid())
251     return false;
252   return m_type_system->IsVoidType(m_type);
253 }
254 
255 bool CompilerType::IsPointerToScalarType() const {
256   if (!IsValid())
257     return false;
258 
259   return IsPointerType() && GetPointeeType().IsScalarType();
260 }
261 
262 bool CompilerType::IsArrayOfScalarType() const {
263   CompilerType element_type;
264   if (IsArrayType(&element_type, nullptr, nullptr))
265     return element_type.IsScalarType();
266   return false;
267 }
268 
269 bool CompilerType::IsBeingDefined() const {
270   if (!IsValid())
271     return false;
272   return m_type_system->IsBeingDefined(m_type);
273 }
274 
275 //----------------------------------------------------------------------
276 // Type Completion
277 //----------------------------------------------------------------------
278 
279 bool CompilerType::GetCompleteType() const {
280   if (!IsValid())
281     return false;
282   return m_type_system->GetCompleteType(m_type);
283 }
284 
285 //----------------------------------------------------------------------
286 // AST related queries
287 //----------------------------------------------------------------------
288 size_t CompilerType::GetPointerByteSize() const {
289   if (m_type_system)
290     return m_type_system->GetPointerByteSize();
291   return 0;
292 }
293 
294 ConstString CompilerType::GetConstQualifiedTypeName() const {
295   return GetConstTypeName();
296 }
297 
298 ConstString CompilerType::GetConstTypeName() const {
299   if (IsValid()) {
300     ConstString type_name(GetTypeName());
301     if (type_name)
302       return type_name;
303   }
304   return ConstString("<invalid>");
305 }
306 
307 ConstString CompilerType::GetTypeName() const {
308   if (IsValid()) {
309     return m_type_system->GetTypeName(m_type);
310   }
311   return ConstString("<invalid>");
312 }
313 
314 ConstString CompilerType::GetDisplayTypeName() const { return GetTypeName(); }
315 
316 uint32_t CompilerType::GetTypeInfo(
317     CompilerType *pointee_or_element_compiler_type) const {
318   if (!IsValid())
319     return 0;
320 
321   return m_type_system->GetTypeInfo(m_type, pointee_or_element_compiler_type);
322 }
323 
324 lldb::LanguageType CompilerType::GetMinimumLanguage() {
325   if (!IsValid())
326     return lldb::eLanguageTypeC;
327 
328   return m_type_system->GetMinimumLanguage(m_type);
329 }
330 
331 lldb::TypeClass CompilerType::GetTypeClass() const {
332   if (!IsValid())
333     return lldb::eTypeClassInvalid;
334 
335   return m_type_system->GetTypeClass(m_type);
336 }
337 
338 void CompilerType::SetCompilerType(TypeSystem *type_system,
339                                    lldb::opaque_compiler_type_t type) {
340   m_type_system = type_system;
341   m_type = type;
342 }
343 
344 void CompilerType::SetCompilerType(clang::ASTContext *ast,
345                                    clang::QualType qual_type) {
346   m_type_system = ClangASTContext::GetASTContext(ast);
347   m_type = qual_type.getAsOpaquePtr();
348 }
349 
350 unsigned CompilerType::GetTypeQualifiers() const {
351   if (IsValid())
352     return m_type_system->GetTypeQualifiers(m_type);
353   return 0;
354 }
355 
356 //----------------------------------------------------------------------
357 // Creating related types
358 //----------------------------------------------------------------------
359 
360 CompilerType CompilerType::GetArrayElementType(uint64_t *stride) const {
361   if (IsValid()) {
362     return m_type_system->GetArrayElementType(m_type, stride);
363   }
364   return CompilerType();
365 }
366 
367 CompilerType CompilerType::GetArrayType(uint64_t size) const {
368   if (IsValid()) {
369     return m_type_system->GetArrayType(m_type, size);
370   }
371   return CompilerType();
372 }
373 
374 CompilerType CompilerType::GetCanonicalType() const {
375   if (IsValid())
376     return m_type_system->GetCanonicalType(m_type);
377   return CompilerType();
378 }
379 
380 CompilerType CompilerType::GetFullyUnqualifiedType() const {
381   if (IsValid())
382     return m_type_system->GetFullyUnqualifiedType(m_type);
383   return CompilerType();
384 }
385 
386 int CompilerType::GetFunctionArgumentCount() const {
387   if (IsValid()) {
388     return m_type_system->GetFunctionArgumentCount(m_type);
389   }
390   return -1;
391 }
392 
393 CompilerType CompilerType::GetFunctionArgumentTypeAtIndex(size_t idx) const {
394   if (IsValid()) {
395     return m_type_system->GetFunctionArgumentTypeAtIndex(m_type, idx);
396   }
397   return CompilerType();
398 }
399 
400 CompilerType CompilerType::GetFunctionReturnType() const {
401   if (IsValid()) {
402     return m_type_system->GetFunctionReturnType(m_type);
403   }
404   return CompilerType();
405 }
406 
407 size_t CompilerType::GetNumMemberFunctions() const {
408   if (IsValid()) {
409     return m_type_system->GetNumMemberFunctions(m_type);
410   }
411   return 0;
412 }
413 
414 TypeMemberFunctionImpl CompilerType::GetMemberFunctionAtIndex(size_t idx) {
415   if (IsValid()) {
416     return m_type_system->GetMemberFunctionAtIndex(m_type, idx);
417   }
418   return TypeMemberFunctionImpl();
419 }
420 
421 CompilerType CompilerType::GetNonReferenceType() const {
422   if (IsValid())
423     return m_type_system->GetNonReferenceType(m_type);
424   return CompilerType();
425 }
426 
427 CompilerType CompilerType::GetPointeeType() const {
428   if (IsValid()) {
429     return m_type_system->GetPointeeType(m_type);
430   }
431   return CompilerType();
432 }
433 
434 CompilerType CompilerType::GetPointerType() const {
435   if (IsValid()) {
436     return m_type_system->GetPointerType(m_type);
437   }
438   return CompilerType();
439 }
440 
441 CompilerType CompilerType::GetLValueReferenceType() const {
442   if (IsValid())
443     return m_type_system->GetLValueReferenceType(m_type);
444   else
445     return CompilerType();
446 }
447 
448 CompilerType CompilerType::GetRValueReferenceType() const {
449   if (IsValid())
450     return m_type_system->GetRValueReferenceType(m_type);
451   else
452     return CompilerType();
453 }
454 
455 CompilerType CompilerType::AddConstModifier() const {
456   if (IsValid())
457     return m_type_system->AddConstModifier(m_type);
458   else
459     return CompilerType();
460 }
461 
462 CompilerType CompilerType::AddVolatileModifier() const {
463   if (IsValid())
464     return m_type_system->AddVolatileModifier(m_type);
465   else
466     return CompilerType();
467 }
468 
469 CompilerType CompilerType::AddRestrictModifier() const {
470   if (IsValid())
471     return m_type_system->AddRestrictModifier(m_type);
472   else
473     return CompilerType();
474 }
475 
476 CompilerType
477 CompilerType::CreateTypedef(const char *name,
478                             const CompilerDeclContext &decl_ctx) const {
479   if (IsValid())
480     return m_type_system->CreateTypedef(m_type, name, decl_ctx);
481   else
482     return CompilerType();
483 }
484 
485 CompilerType CompilerType::GetTypedefedType() const {
486   if (IsValid())
487     return m_type_system->GetTypedefedType(m_type);
488   else
489     return CompilerType();
490 }
491 
492 //----------------------------------------------------------------------
493 // Create related types using the current type's AST
494 //----------------------------------------------------------------------
495 
496 CompilerType
497 CompilerType::GetBasicTypeFromAST(lldb::BasicType basic_type) const {
498   if (IsValid())
499     return m_type_system->GetBasicTypeFromAST(basic_type);
500   return CompilerType();
501 }
502 //----------------------------------------------------------------------
503 // Exploring the type
504 //----------------------------------------------------------------------
505 
506 llvm::Optional<uint64_t>
507 CompilerType::GetBitSize(ExecutionContextScope *exe_scope) const {
508   if (IsValid())
509     return m_type_system->GetBitSize(m_type, exe_scope);
510   return {};
511 }
512 
513 llvm::Optional<uint64_t>
514 CompilerType::GetByteSize(ExecutionContextScope *exe_scope) const {
515   if (llvm::Optional<uint64_t> bit_size = GetBitSize(exe_scope))
516     return (*bit_size + 7) / 8;
517   return {};
518 }
519 
520 size_t CompilerType::GetTypeBitAlign() const {
521   if (IsValid())
522     return m_type_system->GetTypeBitAlign(m_type);
523   return 0;
524 }
525 
526 lldb::Encoding CompilerType::GetEncoding(uint64_t &count) const {
527   if (!IsValid())
528     return lldb::eEncodingInvalid;
529 
530   return m_type_system->GetEncoding(m_type, count);
531 }
532 
533 lldb::Format CompilerType::GetFormat() const {
534   if (!IsValid())
535     return lldb::eFormatDefault;
536 
537   return m_type_system->GetFormat(m_type);
538 }
539 
540 uint32_t CompilerType::GetNumChildren(bool omit_empty_base_classes,
541                                       const ExecutionContext *exe_ctx) const {
542   if (!IsValid())
543     return 0;
544   return m_type_system->GetNumChildren(m_type, omit_empty_base_classes,
545                                        exe_ctx);
546 }
547 
548 lldb::BasicType CompilerType::GetBasicTypeEnumeration() const {
549   if (IsValid())
550     return m_type_system->GetBasicTypeEnumeration(m_type);
551   return eBasicTypeInvalid;
552 }
553 
554 void CompilerType::ForEachEnumerator(
555     std::function<bool(const CompilerType &integer_type,
556                        const ConstString &name,
557                        const llvm::APSInt &value)> const &callback) const {
558   if (IsValid())
559     return m_type_system->ForEachEnumerator(m_type, callback);
560 }
561 
562 uint32_t CompilerType::GetNumFields() const {
563   if (!IsValid())
564     return 0;
565   return m_type_system->GetNumFields(m_type);
566 }
567 
568 CompilerType CompilerType::GetFieldAtIndex(size_t idx, std::string &name,
569                                            uint64_t *bit_offset_ptr,
570                                            uint32_t *bitfield_bit_size_ptr,
571                                            bool *is_bitfield_ptr) const {
572   if (!IsValid())
573     return CompilerType();
574   return m_type_system->GetFieldAtIndex(m_type, idx, name, bit_offset_ptr,
575                                         bitfield_bit_size_ptr, is_bitfield_ptr);
576 }
577 
578 uint32_t CompilerType::GetNumDirectBaseClasses() const {
579   if (IsValid())
580     return m_type_system->GetNumDirectBaseClasses(m_type);
581   return 0;
582 }
583 
584 uint32_t CompilerType::GetNumVirtualBaseClasses() const {
585   if (IsValid())
586     return m_type_system->GetNumVirtualBaseClasses(m_type);
587   return 0;
588 }
589 
590 CompilerType
591 CompilerType::GetDirectBaseClassAtIndex(size_t idx,
592                                         uint32_t *bit_offset_ptr) const {
593   if (IsValid())
594     return m_type_system->GetDirectBaseClassAtIndex(m_type, idx,
595                                                     bit_offset_ptr);
596   return CompilerType();
597 }
598 
599 CompilerType
600 CompilerType::GetVirtualBaseClassAtIndex(size_t idx,
601                                          uint32_t *bit_offset_ptr) const {
602   if (IsValid())
603     return m_type_system->GetVirtualBaseClassAtIndex(m_type, idx,
604                                                      bit_offset_ptr);
605   return CompilerType();
606 }
607 
608 uint32_t CompilerType::GetIndexOfFieldWithName(
609     const char *name, CompilerType *field_compiler_type_ptr,
610     uint64_t *bit_offset_ptr, uint32_t *bitfield_bit_size_ptr,
611     bool *is_bitfield_ptr) const {
612   unsigned count = GetNumFields();
613   std::string field_name;
614   for (unsigned index = 0; index < count; index++) {
615     CompilerType field_compiler_type(
616         GetFieldAtIndex(index, field_name, bit_offset_ptr,
617                         bitfield_bit_size_ptr, is_bitfield_ptr));
618     if (strcmp(field_name.c_str(), name) == 0) {
619       if (field_compiler_type_ptr)
620         *field_compiler_type_ptr = field_compiler_type;
621       return index;
622     }
623   }
624   return UINT32_MAX;
625 }
626 
627 CompilerType CompilerType::GetChildCompilerTypeAtIndex(
628     ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers,
629     bool omit_empty_base_classes, bool ignore_array_bounds,
630     std::string &child_name, uint32_t &child_byte_size,
631     int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size,
632     uint32_t &child_bitfield_bit_offset, bool &child_is_base_class,
633     bool &child_is_deref_of_parent, ValueObject *valobj,
634     uint64_t &language_flags) const {
635   if (!IsValid())
636     return CompilerType();
637   return m_type_system->GetChildCompilerTypeAtIndex(
638       m_type, exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
639       ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
640       child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
641       child_is_deref_of_parent, valobj, language_flags);
642 }
643 
644 // Look for a child member (doesn't include base classes, but it does include
645 // their members) in the type hierarchy. Returns an index path into
646 // "clang_type" on how to reach the appropriate member.
647 //
648 //    class A
649 //    {
650 //    public:
651 //        int m_a;
652 //        int m_b;
653 //    };
654 //
655 //    class B
656 //    {
657 //    };
658 //
659 //    class C :
660 //        public B,
661 //        public A
662 //    {
663 //    };
664 //
665 // If we have a clang type that describes "class C", and we wanted to looked
666 // "m_b" in it:
667 //
668 // With omit_empty_base_classes == false we would get an integer array back
669 // with: { 1,  1 } The first index 1 is the child index for "class A" within
670 // class C The second index 1 is the child index for "m_b" within class A
671 //
672 // With omit_empty_base_classes == true we would get an integer array back
673 // with: { 0,  1 } The first index 0 is the child index for "class A" within
674 // class C (since class B doesn't have any members it doesn't count) The second
675 // index 1 is the child index for "m_b" within class A
676 
677 size_t CompilerType::GetIndexOfChildMemberWithName(
678     const char *name, bool omit_empty_base_classes,
679     std::vector<uint32_t> &child_indexes) const {
680   if (IsValid() && name && name[0]) {
681     return m_type_system->GetIndexOfChildMemberWithName(
682         m_type, name, omit_empty_base_classes, child_indexes);
683   }
684   return 0;
685 }
686 
687 size_t CompilerType::GetNumTemplateArguments() const {
688   if (IsValid()) {
689     return m_type_system->GetNumTemplateArguments(m_type);
690   }
691   return 0;
692 }
693 
694 TemplateArgumentKind CompilerType::GetTemplateArgumentKind(size_t idx) const {
695   if (IsValid())
696     return m_type_system->GetTemplateArgumentKind(m_type, idx);
697   return eTemplateArgumentKindNull;
698 }
699 
700 CompilerType CompilerType::GetTypeTemplateArgument(size_t idx) const {
701   if (IsValid()) {
702     return m_type_system->GetTypeTemplateArgument(m_type, idx);
703   }
704   return CompilerType();
705 }
706 
707 llvm::Optional<CompilerType::IntegralTemplateArgument>
708 CompilerType::GetIntegralTemplateArgument(size_t idx) const {
709   if (IsValid())
710     return m_type_system->GetIntegralTemplateArgument(m_type, idx);
711   return llvm::None;
712 }
713 
714 CompilerType CompilerType::GetTypeForFormatters() const {
715   if (IsValid())
716     return m_type_system->GetTypeForFormatters(m_type);
717   return CompilerType();
718 }
719 
720 LazyBool CompilerType::ShouldPrintAsOneLiner(ValueObject *valobj) const {
721   if (IsValid())
722     return m_type_system->ShouldPrintAsOneLiner(m_type, valobj);
723   return eLazyBoolCalculate;
724 }
725 
726 bool CompilerType::IsMeaninglessWithoutDynamicResolution() const {
727   if (IsValid())
728     return m_type_system->IsMeaninglessWithoutDynamicResolution(m_type);
729   return false;
730 }
731 
732 // Get the index of the child of "clang_type" whose name matches. This function
733 // doesn't descend into the children, but only looks one level deep and name
734 // matches can include base class names.
735 
736 uint32_t
737 CompilerType::GetIndexOfChildWithName(const char *name,
738                                       bool omit_empty_base_classes) const {
739   if (IsValid() && name && name[0]) {
740     return m_type_system->GetIndexOfChildWithName(m_type, name,
741                                                   omit_empty_base_classes);
742   }
743   return UINT32_MAX;
744 }
745 
746 size_t CompilerType::ConvertStringToFloatValue(const char *s, uint8_t *dst,
747                                                size_t dst_size) const {
748   if (IsValid())
749     return m_type_system->ConvertStringToFloatValue(m_type, s, dst, dst_size);
750   return 0;
751 }
752 
753 //----------------------------------------------------------------------
754 // Dumping types
755 //----------------------------------------------------------------------
756 #define DEPTH_INCREMENT 2
757 
758 void CompilerType::DumpValue(ExecutionContext *exe_ctx, Stream *s,
759                              lldb::Format format, const DataExtractor &data,
760                              lldb::offset_t data_byte_offset,
761                              size_t data_byte_size, uint32_t bitfield_bit_size,
762                              uint32_t bitfield_bit_offset, bool show_types,
763                              bool show_summary, bool verbose, uint32_t depth) {
764   if (!IsValid())
765     return;
766   m_type_system->DumpValue(m_type, exe_ctx, s, format, data, data_byte_offset,
767                            data_byte_size, bitfield_bit_size,
768                            bitfield_bit_offset, show_types, show_summary,
769                            verbose, depth);
770 }
771 
772 bool CompilerType::DumpTypeValue(Stream *s, lldb::Format format,
773                                  const DataExtractor &data,
774                                  lldb::offset_t byte_offset, size_t byte_size,
775                                  uint32_t bitfield_bit_size,
776                                  uint32_t bitfield_bit_offset,
777                                  ExecutionContextScope *exe_scope) {
778   if (!IsValid())
779     return false;
780   return m_type_system->DumpTypeValue(m_type, s, format, data, byte_offset,
781                                       byte_size, bitfield_bit_size,
782                                       bitfield_bit_offset, exe_scope);
783 }
784 
785 void CompilerType::DumpSummary(ExecutionContext *exe_ctx, Stream *s,
786                                const DataExtractor &data,
787                                lldb::offset_t data_byte_offset,
788                                size_t data_byte_size) {
789   if (IsValid())
790     m_type_system->DumpSummary(m_type, exe_ctx, s, data, data_byte_offset,
791                                data_byte_size);
792 }
793 
794 void CompilerType::DumpTypeDescription() const {
795   if (IsValid())
796     m_type_system->DumpTypeDescription(m_type);
797 }
798 
799 void CompilerType::DumpTypeDescription(Stream *s) const {
800   if (IsValid()) {
801     m_type_system->DumpTypeDescription(m_type, s);
802   }
803 }
804 
805 bool CompilerType::GetValueAsScalar(const lldb_private::DataExtractor &data,
806                                     lldb::offset_t data_byte_offset,
807                                     size_t data_byte_size,
808                                     Scalar &value) const {
809   if (!IsValid())
810     return false;
811 
812   if (IsAggregateType()) {
813     return false; // Aggregate types don't have scalar values
814   } else {
815     uint64_t count = 0;
816     lldb::Encoding encoding = GetEncoding(count);
817 
818     if (encoding == lldb::eEncodingInvalid || count != 1)
819       return false;
820 
821     llvm::Optional<uint64_t> byte_size = GetByteSize(nullptr);
822     if (!byte_size)
823       return false;
824     lldb::offset_t offset = data_byte_offset;
825     switch (encoding) {
826     case lldb::eEncodingInvalid:
827       break;
828     case lldb::eEncodingVector:
829       break;
830     case lldb::eEncodingUint:
831       if (*byte_size <= sizeof(unsigned long long)) {
832         uint64_t uval64 = data.GetMaxU64(&offset, *byte_size);
833         if (*byte_size <= sizeof(unsigned int)) {
834           value = (unsigned int)uval64;
835           return true;
836         } else if (*byte_size <= sizeof(unsigned long)) {
837           value = (unsigned long)uval64;
838           return true;
839         } else if (*byte_size <= sizeof(unsigned long long)) {
840           value = (unsigned long long)uval64;
841           return true;
842         } else
843           value.Clear();
844       }
845       break;
846 
847     case lldb::eEncodingSint:
848       if (*byte_size <= sizeof(long long)) {
849         int64_t sval64 = data.GetMaxS64(&offset, *byte_size);
850         if (*byte_size <= sizeof(int)) {
851           value = (int)sval64;
852           return true;
853         } else if (*byte_size <= sizeof(long)) {
854           value = (long)sval64;
855           return true;
856         } else if (*byte_size <= sizeof(long long)) {
857           value = (long long)sval64;
858           return true;
859         } else
860           value.Clear();
861       }
862       break;
863 
864     case lldb::eEncodingIEEE754:
865       if (*byte_size <= sizeof(long double)) {
866         uint32_t u32;
867         uint64_t u64;
868         if (*byte_size == sizeof(float)) {
869           if (sizeof(float) == sizeof(uint32_t)) {
870             u32 = data.GetU32(&offset);
871             value = *((float *)&u32);
872             return true;
873           } else if (sizeof(float) == sizeof(uint64_t)) {
874             u64 = data.GetU64(&offset);
875             value = *((float *)&u64);
876             return true;
877           }
878         } else if (*byte_size == sizeof(double)) {
879           if (sizeof(double) == sizeof(uint32_t)) {
880             u32 = data.GetU32(&offset);
881             value = *((double *)&u32);
882             return true;
883           } else if (sizeof(double) == sizeof(uint64_t)) {
884             u64 = data.GetU64(&offset);
885             value = *((double *)&u64);
886             return true;
887           }
888         } else if (*byte_size == sizeof(long double)) {
889           if (sizeof(long double) == sizeof(uint32_t)) {
890             u32 = data.GetU32(&offset);
891             value = *((long double *)&u32);
892             return true;
893           } else if (sizeof(long double) == sizeof(uint64_t)) {
894             u64 = data.GetU64(&offset);
895             value = *((long double *)&u64);
896             return true;
897           }
898         }
899       }
900       break;
901     }
902   }
903   return false;
904 }
905 
906 bool CompilerType::SetValueFromScalar(const Scalar &value, Stream &strm) {
907   if (!IsValid())
908     return false;
909 
910   // Aggregate types don't have scalar values
911   if (!IsAggregateType()) {
912     strm.GetFlags().Set(Stream::eBinary);
913     uint64_t count = 0;
914     lldb::Encoding encoding = GetEncoding(count);
915 
916     if (encoding == lldb::eEncodingInvalid || count != 1)
917       return false;
918 
919     llvm::Optional<uint64_t> bit_width = GetBitSize(nullptr);
920     if (!bit_width)
921       return false;
922 
923     // This function doesn't currently handle non-byte aligned assignments
924     if ((*bit_width % 8) != 0)
925       return false;
926 
927     const uint64_t byte_size = (*bit_width + 7) / 8;
928     switch (encoding) {
929     case lldb::eEncodingInvalid:
930       break;
931     case lldb::eEncodingVector:
932       break;
933     case lldb::eEncodingUint:
934       switch (byte_size) {
935       case 1:
936         strm.PutHex8(value.UInt());
937         return true;
938       case 2:
939         strm.PutHex16(value.UInt());
940         return true;
941       case 4:
942         strm.PutHex32(value.UInt());
943         return true;
944       case 8:
945         strm.PutHex64(value.ULongLong());
946         return true;
947       default:
948         break;
949       }
950       break;
951 
952     case lldb::eEncodingSint:
953       switch (byte_size) {
954       case 1:
955         strm.PutHex8(value.SInt());
956         return true;
957       case 2:
958         strm.PutHex16(value.SInt());
959         return true;
960       case 4:
961         strm.PutHex32(value.SInt());
962         return true;
963       case 8:
964         strm.PutHex64(value.SLongLong());
965         return true;
966       default:
967         break;
968       }
969       break;
970 
971     case lldb::eEncodingIEEE754:
972       if (byte_size <= sizeof(long double)) {
973         if (byte_size == sizeof(float)) {
974           strm.PutFloat(value.Float());
975           return true;
976         } else if (byte_size == sizeof(double)) {
977           strm.PutDouble(value.Double());
978           return true;
979         } else if (byte_size == sizeof(long double)) {
980           strm.PutDouble(value.LongDouble());
981           return true;
982         }
983       }
984       break;
985     }
986   }
987   return false;
988 }
989 
990 bool CompilerType::ReadFromMemory(lldb_private::ExecutionContext *exe_ctx,
991                                   lldb::addr_t addr, AddressType address_type,
992                                   lldb_private::DataExtractor &data) {
993   if (!IsValid())
994     return false;
995 
996   // Can't convert a file address to anything valid without more context (which
997   // Module it came from)
998   if (address_type == eAddressTypeFile)
999     return false;
1000 
1001   if (!GetCompleteType())
1002     return false;
1003 
1004   auto byte_size =
1005       GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
1006   if (!byte_size)
1007     return false;
1008 
1009   if (data.GetByteSize() < *byte_size) {
1010     lldb::DataBufferSP data_sp(new DataBufferHeap(*byte_size, '\0'));
1011     data.SetData(data_sp);
1012   }
1013 
1014   uint8_t *dst = const_cast<uint8_t *>(data.PeekData(0, *byte_size));
1015   if (dst != nullptr) {
1016     if (address_type == eAddressTypeHost) {
1017       if (addr == 0)
1018         return false;
1019       // The address is an address in this process, so just copy it
1020       memcpy(dst, reinterpret_cast<uint8_t *>(addr), *byte_size);
1021       return true;
1022     } else {
1023       Process *process = nullptr;
1024       if (exe_ctx)
1025         process = exe_ctx->GetProcessPtr();
1026       if (process) {
1027         Status error;
1028         return process->ReadMemory(addr, dst, *byte_size, error) == *byte_size;
1029       }
1030     }
1031   }
1032   return false;
1033 }
1034 
1035 bool CompilerType::WriteToMemory(lldb_private::ExecutionContext *exe_ctx,
1036                                  lldb::addr_t addr, AddressType address_type,
1037                                  StreamString &new_value) {
1038   if (!IsValid())
1039     return false;
1040 
1041   // Can't convert a file address to anything valid without more context (which
1042   // Module it came from)
1043   if (address_type == eAddressTypeFile)
1044     return false;
1045 
1046   if (!GetCompleteType())
1047     return false;
1048 
1049   auto byte_size =
1050       GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
1051   if (!byte_size)
1052     return false;
1053 
1054   if (*byte_size > 0) {
1055     if (address_type == eAddressTypeHost) {
1056       // The address is an address in this process, so just copy it
1057       memcpy((void *)addr, new_value.GetData(), *byte_size);
1058       return true;
1059     } else {
1060       Process *process = nullptr;
1061       if (exe_ctx)
1062         process = exe_ctx->GetProcessPtr();
1063       if (process) {
1064         Status error;
1065         return process->WriteMemory(addr, new_value.GetData(), *byte_size,
1066                                     error) == *byte_size;
1067       }
1068     }
1069   }
1070   return false;
1071 }
1072 
1073 bool lldb_private::operator==(const lldb_private::CompilerType &lhs,
1074                               const lldb_private::CompilerType &rhs) {
1075   return lhs.GetTypeSystem() == rhs.GetTypeSystem() &&
1076          lhs.GetOpaqueQualType() == rhs.GetOpaqueQualType();
1077 }
1078 
1079 bool lldb_private::operator!=(const lldb_private::CompilerType &lhs,
1080                               const lldb_private::CompilerType &rhs) {
1081   return !(lhs == rhs);
1082 }
1083