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