1 //===-- ClangASTType.cpp ----------------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/Symbol/ClangASTType.h"
11
12 #include "clang/AST/ASTConsumer.h"
13 #include "clang/AST/ASTContext.h"
14 #include "clang/AST/Attr.h"
15 #include "clang/AST/CXXInheritance.h"
16 #include "clang/AST/Decl.h"
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/DeclObjC.h"
19 #include "clang/AST/DeclGroup.h"
20 #include "clang/AST/DeclTemplate.h"
21 #include "clang/AST/RecordLayout.h"
22 #include "clang/AST/Type.h"
23 #include "clang/AST/VTableBuilder.h"
24
25 #include "clang/Basic/Builtins.h"
26 #include "clang/Basic/IdentifierTable.h"
27 #include "clang/Basic/LangOptions.h"
28 #include "clang/Basic/SourceManager.h"
29 #include "clang/Basic/TargetInfo.h"
30
31 #include "llvm/Support/Format.h"
32 #include "llvm/Support/Signals.h"
33 #include "llvm/Support/FormattedStream.h"
34 #include "llvm/Support/raw_ostream.h"
35
36 #include "lldb/Core/ConstString.h"
37 #include "lldb/Core/DataBufferHeap.h"
38 #include "lldb/Core/DataExtractor.h"
39 #include "lldb/Core/Debugger.h"
40 #include "lldb/Core/Scalar.h"
41 #include "lldb/Core/Stream.h"
42 #include "lldb/Core/StreamFile.h"
43 #include "lldb/Core/StreamString.h"
44 #include "lldb/Symbol/ClangASTContext.h"
45 #include "lldb/Symbol/ClangExternalASTSourceCommon.h"
46 #include "lldb/Symbol/Type.h"
47 #include "lldb/Symbol/VerifyDecl.h"
48 #include "lldb/Target/ExecutionContext.h"
49 #include "lldb/Target/ObjCLanguageRuntime.h"
50 #include "lldb/Target/Process.h"
51
52 #include <iterator>
53 #include <mutex>
54
55 using namespace lldb;
56 using namespace lldb_private;
57
58 static bool
GetCompleteQualType(clang::ASTContext * ast,clang::QualType qual_type,bool allow_completion=true)59 GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type, bool allow_completion = true)
60 {
61 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
62 switch (type_class)
63 {
64 case clang::Type::ConstantArray:
65 case clang::Type::IncompleteArray:
66 case clang::Type::VariableArray:
67 {
68 const clang::ArrayType *array_type = llvm::dyn_cast<clang::ArrayType>(qual_type.getTypePtr());
69
70 if (array_type)
71 return GetCompleteQualType (ast, array_type->getElementType(), allow_completion);
72 }
73 break;
74
75 case clang::Type::Record:
76 case clang::Type::Enum:
77 {
78 const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
79 if (tag_type)
80 {
81 clang::TagDecl *tag_decl = tag_type->getDecl();
82 if (tag_decl)
83 {
84 if (tag_decl->isCompleteDefinition())
85 return true;
86
87 if (!allow_completion)
88 return false;
89
90 if (tag_decl->hasExternalLexicalStorage())
91 {
92 if (ast)
93 {
94 clang::ExternalASTSource *external_ast_source = ast->getExternalSource();
95 if (external_ast_source)
96 {
97 external_ast_source->CompleteType(tag_decl);
98 return !tag_type->isIncompleteType();
99 }
100 }
101 }
102 return false;
103 }
104 }
105
106 }
107 break;
108
109 case clang::Type::ObjCObject:
110 case clang::Type::ObjCInterface:
111 {
112 const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
113 if (objc_class_type)
114 {
115 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
116 // We currently can't complete objective C types through the newly added ASTContext
117 // because it only supports TagDecl objects right now...
118 if (class_interface_decl)
119 {
120 if (class_interface_decl->getDefinition())
121 return true;
122
123 if (!allow_completion)
124 return false;
125
126 if (class_interface_decl->hasExternalLexicalStorage())
127 {
128 if (ast)
129 {
130 clang::ExternalASTSource *external_ast_source = ast->getExternalSource();
131 if (external_ast_source)
132 {
133 external_ast_source->CompleteType (class_interface_decl);
134 return !objc_class_type->isIncompleteType();
135 }
136 }
137 }
138 return false;
139 }
140 }
141 }
142 break;
143
144 case clang::Type::Typedef:
145 return GetCompleteQualType (ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType(), allow_completion);
146
147 case clang::Type::Elaborated:
148 return GetCompleteQualType (ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType(), allow_completion);
149
150 case clang::Type::Paren:
151 return GetCompleteQualType (ast, llvm::cast<clang::ParenType>(qual_type)->desugar(), allow_completion);
152
153 default:
154 break;
155 }
156
157 return true;
158 }
159
160 static clang::ObjCIvarDecl::AccessControl
ConvertAccessTypeToObjCIvarAccessControl(AccessType access)161 ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
162 {
163 switch (access)
164 {
165 case eAccessNone: return clang::ObjCIvarDecl::None;
166 case eAccessPublic: return clang::ObjCIvarDecl::Public;
167 case eAccessPrivate: return clang::ObjCIvarDecl::Private;
168 case eAccessProtected: return clang::ObjCIvarDecl::Protected;
169 case eAccessPackage: return clang::ObjCIvarDecl::Package;
170 }
171 return clang::ObjCIvarDecl::None;
172 }
173
174 //----------------------------------------------------------------------
175 // Tests
176 //----------------------------------------------------------------------
177
ClangASTType(clang::ASTContext * ast,clang::QualType qual_type)178 ClangASTType::ClangASTType (clang::ASTContext *ast,
179 clang::QualType qual_type) :
180 m_type (qual_type.getAsOpaquePtr()),
181 m_ast (ast)
182 {
183 }
184
~ClangASTType()185 ClangASTType::~ClangASTType()
186 {
187 }
188
189 //----------------------------------------------------------------------
190 // Tests
191 //----------------------------------------------------------------------
192
193 bool
IsAggregateType() const194 ClangASTType::IsAggregateType () const
195 {
196 if (!IsValid())
197 return false;
198
199 clang::QualType qual_type (GetCanonicalQualType());
200
201 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
202 switch (type_class)
203 {
204 case clang::Type::IncompleteArray:
205 case clang::Type::VariableArray:
206 case clang::Type::ConstantArray:
207 case clang::Type::ExtVector:
208 case clang::Type::Vector:
209 case clang::Type::Record:
210 case clang::Type::ObjCObject:
211 case clang::Type::ObjCInterface:
212 return true;
213 case clang::Type::Elaborated:
214 return ClangASTType(m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).IsAggregateType();
215 case clang::Type::Typedef:
216 return ClangASTType(m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsAggregateType();
217 case clang::Type::Paren:
218 return ClangASTType(m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).IsAggregateType();
219 default:
220 break;
221 }
222 // The clang type does have a value
223 return false;
224 }
225
226 bool
IsArrayType(ClangASTType * element_type_ptr,uint64_t * size,bool * is_incomplete) const227 ClangASTType::IsArrayType (ClangASTType *element_type_ptr,
228 uint64_t *size,
229 bool *is_incomplete) const
230 {
231 if (IsValid())
232 {
233 clang::QualType qual_type (GetCanonicalQualType());
234
235 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
236 switch (type_class)
237 {
238 default:
239 break;
240
241 case clang::Type::ConstantArray:
242 if (element_type_ptr)
243 element_type_ptr->SetClangType (m_ast, llvm::cast<clang::ConstantArrayType>(qual_type)->getElementType());
244 if (size)
245 *size = llvm::cast<clang::ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULLONG_MAX);
246 return true;
247
248 case clang::Type::IncompleteArray:
249 if (element_type_ptr)
250 element_type_ptr->SetClangType (m_ast, llvm::cast<clang::IncompleteArrayType>(qual_type)->getElementType());
251 if (size)
252 *size = 0;
253 if (is_incomplete)
254 *is_incomplete = true;
255 return true;
256
257 case clang::Type::VariableArray:
258 if (element_type_ptr)
259 element_type_ptr->SetClangType (m_ast, llvm::cast<clang::VariableArrayType>(qual_type)->getElementType());
260 if (size)
261 *size = 0;
262 return true;
263
264 case clang::Type::DependentSizedArray:
265 if (element_type_ptr)
266 element_type_ptr->SetClangType (m_ast, llvm::cast<clang::DependentSizedArrayType>(qual_type)->getElementType());
267 if (size)
268 *size = 0;
269 return true;
270
271 case clang::Type::Typedef:
272 return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsArrayType (element_type_ptr,
273 size,
274 is_incomplete);
275 case clang::Type::Elaborated:
276 return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).IsArrayType (element_type_ptr,
277 size,
278 is_incomplete);
279 case clang::Type::Paren:
280 return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).IsArrayType (element_type_ptr,
281 size,
282 is_incomplete);
283 }
284 }
285 if (element_type_ptr)
286 element_type_ptr->Clear();
287 if (size)
288 *size = 0;
289 if (is_incomplete)
290 *is_incomplete = false;
291 return 0;
292 }
293
294 bool
IsVectorType(ClangASTType * element_type,uint64_t * size) const295 ClangASTType::IsVectorType (ClangASTType *element_type,
296 uint64_t *size) const
297 {
298 if (IsValid())
299 {
300 clang::QualType qual_type (GetCanonicalQualType());
301
302 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
303 switch (type_class)
304 {
305 case clang::Type::Vector:
306 {
307 const clang::VectorType *vector_type = qual_type->getAs<clang::VectorType>();
308 if (vector_type)
309 {
310 if (size)
311 *size = vector_type->getNumElements();
312 if (element_type)
313 *element_type = ClangASTType(m_ast, vector_type->getElementType().getAsOpaquePtr());
314 }
315 return true;
316 }
317 break;
318 case clang::Type::ExtVector:
319 {
320 const clang::ExtVectorType *ext_vector_type = qual_type->getAs<clang::ExtVectorType>();
321 if (ext_vector_type)
322 {
323 if (size)
324 *size = ext_vector_type->getNumElements();
325 if (element_type)
326 *element_type = ClangASTType(m_ast, ext_vector_type->getElementType().getAsOpaquePtr());
327 }
328 return true;
329 }
330 default:
331 break;
332 }
333 }
334 return false;
335 }
336
337 bool
IsRuntimeGeneratedType() const338 ClangASTType::IsRuntimeGeneratedType () const
339 {
340 if (!IsValid())
341 return false;
342
343 clang::DeclContext* decl_ctx = GetDeclContextForType();
344 if (!decl_ctx)
345 return false;
346
347 if (!llvm::isa<clang::ObjCInterfaceDecl>(decl_ctx))
348 return false;
349
350 clang::ObjCInterfaceDecl *result_iface_decl = llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl_ctx);
351
352 ClangASTMetadata* ast_metadata = ClangASTContext::GetMetadata(m_ast, result_iface_decl);
353 if (!ast_metadata)
354 return false;
355 return (ast_metadata->GetISAPtr() != 0);
356 }
357
358 bool
IsCharType() const359 ClangASTType::IsCharType () const
360 {
361 if (!IsValid())
362 return false;
363 return GetQualType().getUnqualifiedType()->isCharType();
364 }
365
366
367 bool
IsCompleteType() const368 ClangASTType::IsCompleteType () const
369 {
370 if (!IsValid())
371 return false;
372 const bool allow_completion = false;
373 return GetCompleteQualType (m_ast, GetQualType(), allow_completion);
374 }
375
376 bool
IsConst() const377 ClangASTType::IsConst() const
378 {
379 return GetQualType().isConstQualified();
380 }
381
382 bool
IsCStringType(uint32_t & length) const383 ClangASTType::IsCStringType (uint32_t &length) const
384 {
385 ClangASTType pointee_or_element_clang_type;
386 length = 0;
387 Flags type_flags (GetTypeInfo (&pointee_or_element_clang_type));
388
389 if (!pointee_or_element_clang_type.IsValid())
390 return false;
391
392 if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
393 {
394 if (pointee_or_element_clang_type.IsCharType())
395 {
396 if (type_flags.Test (eTypeIsArray))
397 {
398 // We know the size of the array and it could be a C string
399 // since it is an array of characters
400 length = llvm::cast<clang::ConstantArrayType>(GetCanonicalQualType().getTypePtr())->getSize().getLimitedValue();
401 }
402 return true;
403
404 }
405 }
406 return false;
407 }
408
409 bool
IsFunctionType(bool * is_variadic_ptr) const410 ClangASTType::IsFunctionType (bool *is_variadic_ptr) const
411 {
412 if (IsValid())
413 {
414 clang::QualType qual_type (GetCanonicalQualType());
415
416 if (qual_type->isFunctionType())
417 {
418 if (is_variadic_ptr)
419 {
420 const clang::FunctionProtoType *function_proto_type = llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
421 if (function_proto_type)
422 *is_variadic_ptr = function_proto_type->isVariadic();
423 else
424 *is_variadic_ptr = false;
425 }
426 return true;
427 }
428
429 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
430 switch (type_class)
431 {
432 default:
433 break;
434 case clang::Type::Typedef:
435 return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsFunctionType();
436 case clang::Type::Elaborated:
437 return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).IsFunctionType();
438 case clang::Type::Paren:
439 return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).IsFunctionType();
440
441 case clang::Type::LValueReference:
442 case clang::Type::RValueReference:
443 {
444 const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
445 if (reference_type)
446 return ClangASTType (m_ast, reference_type->getPointeeType()).IsFunctionType();
447 }
448 break;
449 }
450 }
451 return false;
452 }
453
454 // Used to detect "Homogeneous Floating-point Aggregates"
455 uint32_t
IsHomogeneousAggregate(ClangASTType * base_type_ptr) const456 ClangASTType::IsHomogeneousAggregate (ClangASTType* base_type_ptr) const
457 {
458 if (!IsValid())
459 return 0;
460
461 clang::QualType qual_type(GetCanonicalQualType());
462 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
463 switch (type_class)
464 {
465 case clang::Type::Record:
466 if (GetCompleteType ())
467 {
468 const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
469 if (cxx_record_decl)
470 {
471 if (cxx_record_decl->getNumBases() ||
472 cxx_record_decl->isDynamicClass())
473 return 0;
474 }
475 const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
476 if (record_type)
477 {
478 const clang::RecordDecl *record_decl = record_type->getDecl();
479 if (record_decl)
480 {
481 // We are looking for a structure that contains only floating point types
482 clang::RecordDecl::field_iterator field_pos, field_end = record_decl->field_end();
483 uint32_t num_fields = 0;
484 bool is_hva = false;
485 bool is_hfa = false;
486 clang::QualType base_qual_type;
487 for (field_pos = record_decl->field_begin(); field_pos != field_end; ++field_pos)
488 {
489 clang::QualType field_qual_type = field_pos->getType();
490 if (field_qual_type->isFloatingType())
491 {
492 if (field_qual_type->isComplexType())
493 return 0;
494 else
495 {
496 if (num_fields == 0)
497 base_qual_type = field_qual_type;
498 else
499 {
500 if (is_hva)
501 return 0;
502 is_hfa = true;
503 if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr())
504 return 0;
505 }
506 }
507 }
508 else if (field_qual_type->isVectorType() || field_qual_type->isExtVectorType())
509 {
510 const clang::VectorType *array = field_qual_type.getTypePtr()->getAs<clang::VectorType>();
511 if (array && array->getNumElements() <= 4)
512 {
513 if (num_fields == 0)
514 base_qual_type = array->getElementType();
515 else
516 {
517 if (is_hfa)
518 return 0;
519 is_hva = true;
520 if (field_qual_type.getTypePtr() != base_qual_type.getTypePtr())
521 return 0;
522 }
523 }
524 else
525 return 0;
526 }
527 else
528 return 0;
529 ++num_fields;
530 }
531 if (base_type_ptr)
532 *base_type_ptr = ClangASTType (m_ast, base_qual_type);
533 return num_fields;
534 }
535 }
536 }
537 break;
538
539 case clang::Type::Typedef:
540 return ClangASTType(m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsHomogeneousAggregate (base_type_ptr);
541
542 case clang::Type::Elaborated:
543 return ClangASTType(m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).IsHomogeneousAggregate (base_type_ptr);
544 default:
545 break;
546 }
547 return 0;
548 }
549
550 size_t
GetNumberOfFunctionArguments() const551 ClangASTType::GetNumberOfFunctionArguments () const
552 {
553 if (IsValid())
554 {
555 clang::QualType qual_type (GetCanonicalQualType());
556 const clang::FunctionProtoType* func = llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
557 if (func)
558 return func->getNumParams();
559 }
560 return 0;
561 }
562
563 ClangASTType
GetFunctionArgumentAtIndex(const size_t index) const564 ClangASTType::GetFunctionArgumentAtIndex (const size_t index) const
565 {
566 if (IsValid())
567 {
568 clang::QualType qual_type (GetCanonicalQualType());
569 const clang::FunctionProtoType* func = llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
570 if (func)
571 {
572 if (index < func->getNumParams())
573 return ClangASTType(m_ast, func->getParamType(index).getAsOpaquePtr());
574 }
575 }
576 return ClangASTType();
577 }
578
579 bool
IsFunctionPointerType() const580 ClangASTType::IsFunctionPointerType () const
581 {
582 if (IsValid())
583 {
584 clang::QualType qual_type (GetCanonicalQualType());
585
586 if (qual_type->isFunctionPointerType())
587 return true;
588
589 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
590 switch (type_class)
591 {
592 default:
593 break;
594 case clang::Type::Typedef:
595 return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsFunctionPointerType();
596 case clang::Type::Elaborated:
597 return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).IsFunctionPointerType();
598 case clang::Type::Paren:
599 return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).IsFunctionPointerType();
600
601 case clang::Type::LValueReference:
602 case clang::Type::RValueReference:
603 {
604 const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
605 if (reference_type)
606 return ClangASTType (m_ast, reference_type->getPointeeType()).IsFunctionPointerType();
607 }
608 break;
609 }
610 }
611 return false;
612
613 }
614
615 bool
IsIntegerType(bool & is_signed) const616 ClangASTType::IsIntegerType (bool &is_signed) const
617 {
618 if (!IsValid())
619 return false;
620
621 clang::QualType qual_type (GetCanonicalQualType());
622 const clang::BuiltinType *builtin_type = llvm::dyn_cast<clang::BuiltinType>(qual_type->getCanonicalTypeInternal());
623
624 if (builtin_type)
625 {
626 if (builtin_type->isInteger())
627 {
628 is_signed = builtin_type->isSignedInteger();
629 return true;
630 }
631 }
632
633 return false;
634 }
635
636 bool
IsPointerType(ClangASTType * pointee_type) const637 ClangASTType::IsPointerType (ClangASTType *pointee_type) const
638 {
639 if (IsValid())
640 {
641 clang::QualType qual_type (GetCanonicalQualType());
642 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
643 switch (type_class)
644 {
645 case clang::Type::Builtin:
646 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
647 {
648 default:
649 break;
650 case clang::BuiltinType::ObjCId:
651 case clang::BuiltinType::ObjCClass:
652 return true;
653 }
654 return false;
655 case clang::Type::ObjCObjectPointer:
656 if (pointee_type)
657 pointee_type->SetClangType (m_ast, llvm::cast<clang::ObjCObjectPointerType>(qual_type)->getPointeeType());
658 return true;
659 case clang::Type::BlockPointer:
660 if (pointee_type)
661 pointee_type->SetClangType (m_ast, llvm::cast<clang::BlockPointerType>(qual_type)->getPointeeType());
662 return true;
663 case clang::Type::Pointer:
664 if (pointee_type)
665 pointee_type->SetClangType (m_ast, llvm::cast<clang::PointerType>(qual_type)->getPointeeType());
666 return true;
667 case clang::Type::MemberPointer:
668 if (pointee_type)
669 pointee_type->SetClangType (m_ast, llvm::cast<clang::MemberPointerType>(qual_type)->getPointeeType());
670 return true;
671 case clang::Type::Typedef:
672 return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsPointerType(pointee_type);
673 case clang::Type::Elaborated:
674 return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).IsPointerType(pointee_type);
675 case clang::Type::Paren:
676 return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).IsPointerType(pointee_type);
677 default:
678 break;
679 }
680 }
681 if (pointee_type)
682 pointee_type->Clear();
683 return false;
684 }
685
686
687 bool
IsPointerOrReferenceType(ClangASTType * pointee_type) const688 ClangASTType::IsPointerOrReferenceType (ClangASTType *pointee_type) const
689 {
690 if (IsValid())
691 {
692 clang::QualType qual_type (GetCanonicalQualType());
693 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
694 switch (type_class)
695 {
696 case clang::Type::Builtin:
697 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
698 {
699 default:
700 break;
701 case clang::BuiltinType::ObjCId:
702 case clang::BuiltinType::ObjCClass:
703 return true;
704 }
705 return false;
706 case clang::Type::ObjCObjectPointer:
707 if (pointee_type)
708 pointee_type->SetClangType(m_ast, llvm::cast<clang::ObjCObjectPointerType>(qual_type)->getPointeeType());
709 return true;
710 case clang::Type::BlockPointer:
711 if (pointee_type)
712 pointee_type->SetClangType(m_ast, llvm::cast<clang::BlockPointerType>(qual_type)->getPointeeType());
713 return true;
714 case clang::Type::Pointer:
715 if (pointee_type)
716 pointee_type->SetClangType(m_ast, llvm::cast<clang::PointerType>(qual_type)->getPointeeType());
717 return true;
718 case clang::Type::MemberPointer:
719 if (pointee_type)
720 pointee_type->SetClangType(m_ast, llvm::cast<clang::MemberPointerType>(qual_type)->getPointeeType());
721 return true;
722 case clang::Type::LValueReference:
723 if (pointee_type)
724 pointee_type->SetClangType(m_ast, llvm::cast<clang::LValueReferenceType>(qual_type)->desugar());
725 return true;
726 case clang::Type::RValueReference:
727 if (pointee_type)
728 pointee_type->SetClangType(m_ast, llvm::cast<clang::RValueReferenceType>(qual_type)->desugar());
729 return true;
730 case clang::Type::Typedef:
731 return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsPointerOrReferenceType(pointee_type);
732 case clang::Type::Elaborated:
733 return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).IsPointerOrReferenceType(pointee_type);
734 case clang::Type::Paren:
735 return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).IsPointerOrReferenceType(pointee_type);
736 default:
737 break;
738 }
739 }
740 if (pointee_type)
741 pointee_type->Clear();
742 return false;
743 }
744
745
746 bool
IsReferenceType(ClangASTType * pointee_type,bool * is_rvalue) const747 ClangASTType::IsReferenceType (ClangASTType *pointee_type, bool* is_rvalue) const
748 {
749 if (IsValid())
750 {
751 clang::QualType qual_type (GetCanonicalQualType());
752 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
753
754 switch (type_class)
755 {
756 case clang::Type::LValueReference:
757 if (pointee_type)
758 pointee_type->SetClangType(m_ast, llvm::cast<clang::LValueReferenceType>(qual_type)->desugar());
759 if (is_rvalue)
760 *is_rvalue = false;
761 return true;
762 case clang::Type::RValueReference:
763 if (pointee_type)
764 pointee_type->SetClangType(m_ast, llvm::cast<clang::RValueReferenceType>(qual_type)->desugar());
765 if (is_rvalue)
766 *is_rvalue = true;
767 return true;
768 case clang::Type::Typedef:
769 return ClangASTType(m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsReferenceType(pointee_type, is_rvalue);
770 case clang::Type::Elaborated:
771 return ClangASTType(m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).IsReferenceType(pointee_type, is_rvalue);
772 case clang::Type::Paren:
773 return ClangASTType(m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).IsReferenceType(pointee_type, is_rvalue);
774
775 default:
776 break;
777 }
778 }
779 if (pointee_type)
780 pointee_type->Clear();
781 return false;
782 }
783
784 bool
IsFloatingPointType(uint32_t & count,bool & is_complex) const785 ClangASTType::IsFloatingPointType (uint32_t &count, bool &is_complex) const
786 {
787 if (IsValid())
788 {
789 clang::QualType qual_type (GetCanonicalQualType());
790
791 if (const clang::BuiltinType *BT = llvm::dyn_cast<clang::BuiltinType>(qual_type->getCanonicalTypeInternal()))
792 {
793 clang::BuiltinType::Kind kind = BT->getKind();
794 if (kind >= clang::BuiltinType::Float && kind <= clang::BuiltinType::LongDouble)
795 {
796 count = 1;
797 is_complex = false;
798 return true;
799 }
800 }
801 else if (const clang::ComplexType *CT = llvm::dyn_cast<clang::ComplexType>(qual_type->getCanonicalTypeInternal()))
802 {
803 if (ClangASTType (m_ast, CT->getElementType()).IsFloatingPointType (count, is_complex))
804 {
805 count = 2;
806 is_complex = true;
807 return true;
808 }
809 }
810 else if (const clang::VectorType *VT = llvm::dyn_cast<clang::VectorType>(qual_type->getCanonicalTypeInternal()))
811 {
812 if (ClangASTType (m_ast, VT->getElementType()).IsFloatingPointType (count, is_complex))
813 {
814 count = VT->getNumElements();
815 is_complex = false;
816 return true;
817 }
818 }
819 }
820 count = 0;
821 is_complex = false;
822 return false;
823 }
824
825
826 bool
IsDefined() const827 ClangASTType::IsDefined() const
828 {
829 if (!IsValid())
830 return false;
831
832 clang::QualType qual_type(GetQualType());
833 const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
834 if (tag_type)
835 {
836 clang::TagDecl *tag_decl = tag_type->getDecl();
837 if (tag_decl)
838 return tag_decl->isCompleteDefinition();
839 return false;
840 }
841 else
842 {
843 const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
844 if (objc_class_type)
845 {
846 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
847 if (class_interface_decl)
848 return class_interface_decl->getDefinition() != nullptr;
849 return false;
850 }
851 }
852 return true;
853 }
854
855 bool
IsObjCClassType() const856 ClangASTType::IsObjCClassType () const
857 {
858 if (IsValid())
859 {
860 clang::QualType qual_type (GetCanonicalQualType());
861
862 const clang::ObjCObjectPointerType *obj_pointer_type = llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type);
863
864 if (obj_pointer_type)
865 return obj_pointer_type->isObjCClassType();
866 }
867 return false;
868 }
869
870 bool
IsObjCObjectOrInterfaceType() const871 ClangASTType::IsObjCObjectOrInterfaceType () const
872 {
873 if (IsValid())
874 return GetCanonicalQualType()->isObjCObjectOrInterfaceType();
875 return false;
876 }
877
878 bool
IsPolymorphicClass() const879 ClangASTType::IsPolymorphicClass () const
880 {
881 if (IsValid())
882 {
883 clang::QualType qual_type(GetCanonicalQualType());
884 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
885 switch (type_class)
886 {
887 case clang::Type::Record:
888 if (GetCompleteType())
889 {
890 const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
891 const clang::RecordDecl *record_decl = record_type->getDecl();
892 if (record_decl)
893 {
894 const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
895 if (cxx_record_decl)
896 return cxx_record_decl->isPolymorphic();
897 }
898 }
899 break;
900
901 default:
902 break;
903 }
904 }
905 return false;
906 }
907
908 bool
IsPossibleDynamicType(ClangASTType * dynamic_pointee_type,bool check_cplusplus,bool check_objc) const909 ClangASTType::IsPossibleDynamicType (ClangASTType *dynamic_pointee_type,
910 bool check_cplusplus,
911 bool check_objc) const
912 {
913 clang::QualType pointee_qual_type;
914 if (m_type)
915 {
916 clang::QualType qual_type (GetCanonicalQualType());
917 bool success = false;
918 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
919 switch (type_class)
920 {
921 case clang::Type::Builtin:
922 if (check_objc && llvm::cast<clang::BuiltinType>(qual_type)->getKind() == clang::BuiltinType::ObjCId)
923 {
924 if (dynamic_pointee_type)
925 dynamic_pointee_type->SetClangType(m_ast, m_type);
926 return true;
927 }
928 break;
929
930 case clang::Type::ObjCObjectPointer:
931 if (check_objc)
932 {
933 if (dynamic_pointee_type)
934 dynamic_pointee_type->SetClangType(m_ast, llvm::cast<clang::ObjCObjectPointerType>(qual_type)->getPointeeType());
935 return true;
936 }
937 break;
938
939 case clang::Type::Pointer:
940 pointee_qual_type = llvm::cast<clang::PointerType>(qual_type)->getPointeeType();
941 success = true;
942 break;
943
944 case clang::Type::LValueReference:
945 case clang::Type::RValueReference:
946 pointee_qual_type = llvm::cast<clang::ReferenceType>(qual_type)->getPointeeType();
947 success = true;
948 break;
949
950 case clang::Type::Typedef:
951 return ClangASTType (m_ast,
952 llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).IsPossibleDynamicType (dynamic_pointee_type,
953 check_cplusplus,
954 check_objc);
955
956 case clang::Type::Elaborated:
957 return ClangASTType (m_ast,
958 llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).IsPossibleDynamicType (dynamic_pointee_type,
959 check_cplusplus,
960 check_objc);
961
962 case clang::Type::Paren:
963 return ClangASTType (m_ast,
964 llvm::cast<clang::ParenType>(qual_type)->desugar()).IsPossibleDynamicType (dynamic_pointee_type,
965 check_cplusplus,
966 check_objc);
967 default:
968 break;
969 }
970
971 if (success)
972 {
973 // Check to make sure what we are pointing too is a possible dynamic C++ type
974 // We currently accept any "void *" (in case we have a class that has been
975 // watered down to an opaque pointer) and virtual C++ classes.
976 const clang::Type::TypeClass pointee_type_class = pointee_qual_type.getCanonicalType()->getTypeClass();
977 switch (pointee_type_class)
978 {
979 case clang::Type::Builtin:
980 switch (llvm::cast<clang::BuiltinType>(pointee_qual_type)->getKind())
981 {
982 case clang::BuiltinType::UnknownAny:
983 case clang::BuiltinType::Void:
984 if (dynamic_pointee_type)
985 dynamic_pointee_type->SetClangType(m_ast, pointee_qual_type);
986 return true;
987
988 case clang::BuiltinType::NullPtr:
989 case clang::BuiltinType::Bool:
990 case clang::BuiltinType::Char_U:
991 case clang::BuiltinType::UChar:
992 case clang::BuiltinType::WChar_U:
993 case clang::BuiltinType::Char16:
994 case clang::BuiltinType::Char32:
995 case clang::BuiltinType::UShort:
996 case clang::BuiltinType::UInt:
997 case clang::BuiltinType::ULong:
998 case clang::BuiltinType::ULongLong:
999 case clang::BuiltinType::UInt128:
1000 case clang::BuiltinType::Char_S:
1001 case clang::BuiltinType::SChar:
1002 case clang::BuiltinType::WChar_S:
1003 case clang::BuiltinType::Short:
1004 case clang::BuiltinType::Int:
1005 case clang::BuiltinType::Long:
1006 case clang::BuiltinType::LongLong:
1007 case clang::BuiltinType::Int128:
1008 case clang::BuiltinType::Float:
1009 case clang::BuiltinType::Double:
1010 case clang::BuiltinType::LongDouble:
1011 case clang::BuiltinType::Dependent:
1012 case clang::BuiltinType::Overload:
1013 case clang::BuiltinType::ObjCId:
1014 case clang::BuiltinType::ObjCClass:
1015 case clang::BuiltinType::ObjCSel:
1016 case clang::BuiltinType::BoundMember:
1017 case clang::BuiltinType::Half:
1018 case clang::BuiltinType::ARCUnbridgedCast:
1019 case clang::BuiltinType::PseudoObject:
1020 case clang::BuiltinType::BuiltinFn:
1021 case clang::BuiltinType::OCLEvent:
1022 case clang::BuiltinType::OCLImage1d:
1023 case clang::BuiltinType::OCLImage1dArray:
1024 case clang::BuiltinType::OCLImage1dBuffer:
1025 case clang::BuiltinType::OCLImage2d:
1026 case clang::BuiltinType::OCLImage2dArray:
1027 case clang::BuiltinType::OCLImage3d:
1028 case clang::BuiltinType::OCLSampler:
1029 break;
1030 }
1031 break;
1032
1033 case clang::Type::Record:
1034 if (check_cplusplus)
1035 {
1036 clang::CXXRecordDecl *cxx_record_decl = pointee_qual_type->getAsCXXRecordDecl();
1037 if (cxx_record_decl)
1038 {
1039 bool is_complete = cxx_record_decl->isCompleteDefinition();
1040
1041 if (is_complete)
1042 success = cxx_record_decl->isDynamicClass();
1043 else
1044 {
1045 ClangASTMetadata *metadata = ClangASTContext::GetMetadata (m_ast, cxx_record_decl);
1046 if (metadata)
1047 success = metadata->GetIsDynamicCXXType();
1048 else
1049 {
1050 is_complete = ClangASTType(m_ast, pointee_qual_type).GetCompleteType();
1051 if (is_complete)
1052 success = cxx_record_decl->isDynamicClass();
1053 else
1054 success = false;
1055 }
1056 }
1057
1058 if (success)
1059 {
1060 if (dynamic_pointee_type)
1061 dynamic_pointee_type->SetClangType(m_ast, pointee_qual_type);
1062 return true;
1063 }
1064 }
1065 }
1066 break;
1067
1068 case clang::Type::ObjCObject:
1069 case clang::Type::ObjCInterface:
1070 if (check_objc)
1071 {
1072 if (dynamic_pointee_type)
1073 dynamic_pointee_type->SetClangType(m_ast, pointee_qual_type);
1074 return true;
1075 }
1076 break;
1077
1078 default:
1079 break;
1080 }
1081 }
1082 }
1083 if (dynamic_pointee_type)
1084 dynamic_pointee_type->Clear();
1085 return false;
1086 }
1087
1088
1089 bool
IsScalarType() const1090 ClangASTType::IsScalarType () const
1091 {
1092 if (!IsValid())
1093 return false;
1094
1095 return (GetTypeInfo (nullptr) & eTypeIsScalar) != 0;
1096 }
1097
1098 bool
IsTypedefType() const1099 ClangASTType::IsTypedefType () const
1100 {
1101 if (!IsValid())
1102 return false;
1103 return GetQualType()->getTypeClass() == clang::Type::Typedef;
1104 }
1105
1106 bool
IsVoidType() const1107 ClangASTType::IsVoidType () const
1108 {
1109 if (!IsValid())
1110 return false;
1111 return GetCanonicalQualType()->isVoidType();
1112 }
1113
1114 bool
IsPointerToScalarType() const1115 ClangASTType::IsPointerToScalarType () const
1116 {
1117 if (!IsValid())
1118 return false;
1119
1120 return IsPointerType() && GetPointeeType().IsScalarType();
1121 }
1122
1123 bool
IsArrayOfScalarType() const1124 ClangASTType::IsArrayOfScalarType () const
1125 {
1126 ClangASTType element_type;
1127 if (IsArrayType(&element_type, nullptr, nullptr))
1128 return element_type.IsScalarType();
1129 return false;
1130 }
1131
1132
1133 bool
GetCXXClassName(std::string & class_name) const1134 ClangASTType::GetCXXClassName (std::string &class_name) const
1135 {
1136 if (IsValid())
1137 {
1138 clang::QualType qual_type (GetCanonicalQualType());
1139
1140 clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
1141 if (cxx_record_decl)
1142 {
1143 class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
1144 return true;
1145 }
1146 }
1147 class_name.clear();
1148 return false;
1149 }
1150
1151
1152 bool
IsCXXClassType() const1153 ClangASTType::IsCXXClassType () const
1154 {
1155 if (!IsValid())
1156 return false;
1157
1158 clang::QualType qual_type (GetCanonicalQualType());
1159 if (qual_type->getAsCXXRecordDecl() != nullptr)
1160 return true;
1161 return false;
1162 }
1163
1164 bool
IsBeingDefined() const1165 ClangASTType::IsBeingDefined () const
1166 {
1167 if (!IsValid())
1168 return false;
1169 clang::QualType qual_type (GetCanonicalQualType());
1170 const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type);
1171 if (tag_type)
1172 return tag_type->isBeingDefined();
1173 return false;
1174 }
1175
1176 bool
IsObjCObjectPointerType(ClangASTType * class_type_ptr)1177 ClangASTType::IsObjCObjectPointerType (ClangASTType *class_type_ptr)
1178 {
1179 if (!IsValid())
1180 return false;
1181
1182 clang::QualType qual_type (GetCanonicalQualType());
1183
1184 if (qual_type->isObjCObjectPointerType())
1185 {
1186 if (class_type_ptr)
1187 {
1188 if (!qual_type->isObjCClassType() &&
1189 !qual_type->isObjCIdType())
1190 {
1191 const clang::ObjCObjectPointerType *obj_pointer_type = llvm::dyn_cast<clang::ObjCObjectPointerType>(qual_type);
1192 if (obj_pointer_type == nullptr)
1193 class_type_ptr->Clear();
1194 else
1195 class_type_ptr->SetClangType (m_ast, clang::QualType(obj_pointer_type->getInterfaceType(), 0));
1196 }
1197 }
1198 return true;
1199 }
1200 if (class_type_ptr)
1201 class_type_ptr->Clear();
1202 return false;
1203 }
1204
1205 bool
GetObjCClassName(std::string & class_name)1206 ClangASTType::GetObjCClassName (std::string &class_name)
1207 {
1208 if (!IsValid())
1209 return false;
1210
1211 clang::QualType qual_type (GetCanonicalQualType());
1212
1213 const clang::ObjCObjectType *object_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
1214 if (object_type)
1215 {
1216 const clang::ObjCInterfaceDecl *interface = object_type->getInterface();
1217 if (interface)
1218 {
1219 class_name = interface->getNameAsString();
1220 return true;
1221 }
1222 }
1223 return false;
1224 }
1225
1226
1227 //----------------------------------------------------------------------
1228 // Type Completion
1229 //----------------------------------------------------------------------
1230
1231 bool
GetCompleteType() const1232 ClangASTType::GetCompleteType () const
1233 {
1234 if (!IsValid())
1235 return false;
1236 const bool allow_completion = true;
1237 return GetCompleteQualType (m_ast, GetQualType(), allow_completion);
1238 }
1239
1240 //----------------------------------------------------------------------
1241 // AST related queries
1242 //----------------------------------------------------------------------
1243 size_t
GetPointerByteSize() const1244 ClangASTType::GetPointerByteSize () const
1245 {
1246 if (m_ast)
1247 return m_ast->getTypeSize(m_ast->VoidPtrTy) / 8;
1248 return 0;
1249 }
1250
1251 ConstString
GetConstQualifiedTypeName() const1252 ClangASTType::GetConstQualifiedTypeName () const
1253 {
1254 return GetConstTypeName ();
1255 }
1256
1257 ConstString
GetConstTypeName() const1258 ClangASTType::GetConstTypeName () const
1259 {
1260 if (IsValid())
1261 {
1262 ConstString type_name (GetTypeName());
1263 if (type_name)
1264 return type_name;
1265 }
1266 return ConstString("<invalid>");
1267 }
1268
1269 ConstString
GetTypeName() const1270 ClangASTType::GetTypeName () const
1271 {
1272 std::string type_name;
1273 if (IsValid())
1274 {
1275 clang::PrintingPolicy printing_policy (m_ast->getPrintingPolicy());
1276 clang::QualType qual_type(GetQualType());
1277 printing_policy.SuppressTagKeyword = true;
1278 printing_policy.LangOpts.WChar = true;
1279 const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
1280 if (typedef_type)
1281 {
1282 const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
1283 type_name = typedef_decl->getQualifiedNameAsString();
1284 }
1285 else
1286 {
1287 type_name = qual_type.getAsString(printing_policy);
1288 }
1289 }
1290 return ConstString(type_name);
1291 }
1292
1293 ConstString
GetDisplayTypeName() const1294 ClangASTType::GetDisplayTypeName () const
1295 {
1296 return GetTypeName();
1297 }
1298
1299 uint32_t
GetTypeInfo(ClangASTType * pointee_or_element_clang_type) const1300 ClangASTType::GetTypeInfo (ClangASTType *pointee_or_element_clang_type) const
1301 {
1302 if (!IsValid())
1303 return 0;
1304
1305 if (pointee_or_element_clang_type)
1306 pointee_or_element_clang_type->Clear();
1307
1308 clang::QualType qual_type (GetQualType());
1309
1310 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1311 switch (type_class)
1312 {
1313 case clang::Type::Builtin:
1314 {
1315 const clang::BuiltinType *builtin_type = llvm::dyn_cast<clang::BuiltinType>(qual_type->getCanonicalTypeInternal());
1316
1317 uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue;
1318 switch (builtin_type->getKind())
1319 {
1320 case clang::BuiltinType::ObjCId:
1321 case clang::BuiltinType::ObjCClass:
1322 if (pointee_or_element_clang_type)
1323 pointee_or_element_clang_type->SetClangType(m_ast, m_ast->ObjCBuiltinClassTy);
1324 builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
1325 break;
1326
1327 case clang::BuiltinType::ObjCSel:
1328 if (pointee_or_element_clang_type)
1329 pointee_or_element_clang_type->SetClangType(m_ast, m_ast->CharTy);
1330 builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
1331 break;
1332
1333 case clang::BuiltinType::Bool:
1334 case clang::BuiltinType::Char_U:
1335 case clang::BuiltinType::UChar:
1336 case clang::BuiltinType::WChar_U:
1337 case clang::BuiltinType::Char16:
1338 case clang::BuiltinType::Char32:
1339 case clang::BuiltinType::UShort:
1340 case clang::BuiltinType::UInt:
1341 case clang::BuiltinType::ULong:
1342 case clang::BuiltinType::ULongLong:
1343 case clang::BuiltinType::UInt128:
1344 case clang::BuiltinType::Char_S:
1345 case clang::BuiltinType::SChar:
1346 case clang::BuiltinType::WChar_S:
1347 case clang::BuiltinType::Short:
1348 case clang::BuiltinType::Int:
1349 case clang::BuiltinType::Long:
1350 case clang::BuiltinType::LongLong:
1351 case clang::BuiltinType::Int128:
1352 case clang::BuiltinType::Float:
1353 case clang::BuiltinType::Double:
1354 case clang::BuiltinType::LongDouble:
1355 builtin_type_flags |= eTypeIsScalar;
1356 if (builtin_type->isInteger())
1357 {
1358 builtin_type_flags |= eTypeIsInteger;
1359 if (builtin_type->isSignedInteger())
1360 builtin_type_flags |= eTypeIsSigned;
1361 }
1362 else if (builtin_type->isFloatingPoint())
1363 builtin_type_flags |= eTypeIsFloat;
1364 break;
1365 default:
1366 break;
1367 }
1368 return builtin_type_flags;
1369 }
1370
1371 case clang::Type::BlockPointer:
1372 if (pointee_or_element_clang_type)
1373 pointee_or_element_clang_type->SetClangType(m_ast, qual_type->getPointeeType());
1374 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
1375
1376 case clang::Type::Complex:
1377 {
1378 uint32_t complex_type_flags = eTypeIsBuiltIn | eTypeHasValue | eTypeIsComplex;
1379 const clang::ComplexType *complex_type = llvm::dyn_cast<clang::ComplexType>(qual_type->getCanonicalTypeInternal());
1380 if (complex_type)
1381 {
1382 clang::QualType complex_element_type (complex_type->getElementType());
1383 if (complex_element_type->isIntegerType())
1384 complex_type_flags |= eTypeIsFloat;
1385 else if (complex_element_type->isFloatingType())
1386 complex_type_flags |= eTypeIsInteger;
1387 }
1388 return complex_type_flags;
1389 }
1390 break;
1391
1392 case clang::Type::ConstantArray:
1393 case clang::Type::DependentSizedArray:
1394 case clang::Type::IncompleteArray:
1395 case clang::Type::VariableArray:
1396 if (pointee_or_element_clang_type)
1397 pointee_or_element_clang_type->SetClangType(m_ast, llvm::cast<clang::ArrayType>(qual_type.getTypePtr())->getElementType());
1398 return eTypeHasChildren | eTypeIsArray;
1399
1400 case clang::Type::DependentName: return 0;
1401 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector;
1402 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate;
1403 case clang::Type::Decltype: return 0;
1404
1405 case clang::Type::Enum:
1406 if (pointee_or_element_clang_type)
1407 pointee_or_element_clang_type->SetClangType(m_ast, llvm::cast<clang::EnumType>(qual_type)->getDecl()->getIntegerType());
1408 return eTypeIsEnumeration | eTypeHasValue;
1409
1410 case clang::Type::Elaborated:
1411 return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetTypeInfo (pointee_or_element_clang_type);
1412 case clang::Type::Paren:
1413 return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetTypeInfo (pointee_or_element_clang_type);
1414
1415 case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue;
1416 case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue;
1417 case clang::Type::InjectedClassName: return 0;
1418
1419 case clang::Type::LValueReference:
1420 case clang::Type::RValueReference:
1421 if (pointee_or_element_clang_type)
1422 pointee_or_element_clang_type->SetClangType(m_ast, llvm::cast<clang::ReferenceType>(qual_type.getTypePtr())->getPointeeType());
1423 return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
1424
1425 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue;
1426
1427 case clang::Type::ObjCObjectPointer:
1428 if (pointee_or_element_clang_type)
1429 pointee_or_element_clang_type->SetClangType(m_ast, qual_type->getPointeeType());
1430 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
1431
1432 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
1433 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
1434
1435 case clang::Type::Pointer:
1436 if (pointee_or_element_clang_type)
1437 pointee_or_element_clang_type->SetClangType(m_ast, qual_type->getPointeeType());
1438 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
1439
1440 case clang::Type::Record:
1441 if (qual_type->getAsCXXRecordDecl())
1442 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
1443 else
1444 return eTypeHasChildren | eTypeIsStructUnion;
1445 break;
1446 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate;
1447 case clang::Type::TemplateTypeParm: return eTypeIsTemplate;
1448 case clang::Type::TemplateSpecialization: return eTypeIsTemplate;
1449
1450 case clang::Type::Typedef:
1451 return eTypeIsTypedef | ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetTypeInfo (pointee_or_element_clang_type);
1452 case clang::Type::TypeOfExpr: return 0;
1453 case clang::Type::TypeOf: return 0;
1454 case clang::Type::UnresolvedUsing: return 0;
1455
1456 case clang::Type::ExtVector:
1457 case clang::Type::Vector:
1458 {
1459 uint32_t vector_type_flags = eTypeHasChildren | eTypeIsVector;
1460 const clang::VectorType *vector_type = llvm::dyn_cast<clang::VectorType>(qual_type->getCanonicalTypeInternal());
1461 if (vector_type)
1462 {
1463 if (vector_type->isIntegerType())
1464 vector_type_flags |= eTypeIsFloat;
1465 else if (vector_type->isFloatingType())
1466 vector_type_flags |= eTypeIsInteger;
1467 }
1468 return vector_type_flags;
1469 }
1470 default: return 0;
1471 }
1472 return 0;
1473 }
1474
1475
1476
1477 lldb::LanguageType
GetMinimumLanguage()1478 ClangASTType::GetMinimumLanguage ()
1479 {
1480 if (!IsValid())
1481 return lldb::eLanguageTypeC;
1482
1483 // If the type is a reference, then resolve it to what it refers to first:
1484 clang::QualType qual_type (GetCanonicalQualType().getNonReferenceType());
1485 if (qual_type->isAnyPointerType())
1486 {
1487 if (qual_type->isObjCObjectPointerType())
1488 return lldb::eLanguageTypeObjC;
1489
1490 clang::QualType pointee_type (qual_type->getPointeeType());
1491 if (pointee_type->getPointeeCXXRecordDecl() != nullptr)
1492 return lldb::eLanguageTypeC_plus_plus;
1493 if (pointee_type->isObjCObjectOrInterfaceType())
1494 return lldb::eLanguageTypeObjC;
1495 if (pointee_type->isObjCClassType())
1496 return lldb::eLanguageTypeObjC;
1497 if (pointee_type.getTypePtr() == m_ast->ObjCBuiltinIdTy.getTypePtr())
1498 return lldb::eLanguageTypeObjC;
1499 }
1500 else
1501 {
1502 if (qual_type->isObjCObjectOrInterfaceType())
1503 return lldb::eLanguageTypeObjC;
1504 if (qual_type->getAsCXXRecordDecl())
1505 return lldb::eLanguageTypeC_plus_plus;
1506 switch (qual_type->getTypeClass())
1507 {
1508 default:
1509 break;
1510 case clang::Type::Builtin:
1511 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
1512 {
1513 default:
1514 case clang::BuiltinType::Void:
1515 case clang::BuiltinType::Bool:
1516 case clang::BuiltinType::Char_U:
1517 case clang::BuiltinType::UChar:
1518 case clang::BuiltinType::WChar_U:
1519 case clang::BuiltinType::Char16:
1520 case clang::BuiltinType::Char32:
1521 case clang::BuiltinType::UShort:
1522 case clang::BuiltinType::UInt:
1523 case clang::BuiltinType::ULong:
1524 case clang::BuiltinType::ULongLong:
1525 case clang::BuiltinType::UInt128:
1526 case clang::BuiltinType::Char_S:
1527 case clang::BuiltinType::SChar:
1528 case clang::BuiltinType::WChar_S:
1529 case clang::BuiltinType::Short:
1530 case clang::BuiltinType::Int:
1531 case clang::BuiltinType::Long:
1532 case clang::BuiltinType::LongLong:
1533 case clang::BuiltinType::Int128:
1534 case clang::BuiltinType::Float:
1535 case clang::BuiltinType::Double:
1536 case clang::BuiltinType::LongDouble:
1537 break;
1538
1539 case clang::BuiltinType::NullPtr:
1540 return eLanguageTypeC_plus_plus;
1541
1542 case clang::BuiltinType::ObjCId:
1543 case clang::BuiltinType::ObjCClass:
1544 case clang::BuiltinType::ObjCSel:
1545 return eLanguageTypeObjC;
1546
1547 case clang::BuiltinType::Dependent:
1548 case clang::BuiltinType::Overload:
1549 case clang::BuiltinType::BoundMember:
1550 case clang::BuiltinType::UnknownAny:
1551 break;
1552 }
1553 break;
1554 case clang::Type::Typedef:
1555 return ClangASTType(m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetMinimumLanguage();
1556 }
1557 }
1558 return lldb::eLanguageTypeC;
1559 }
1560
1561 lldb::TypeClass
GetTypeClass() const1562 ClangASTType::GetTypeClass () const
1563 {
1564 if (!IsValid())
1565 return lldb::eTypeClassInvalid;
1566
1567 clang::QualType qual_type(GetQualType());
1568
1569 switch (qual_type->getTypeClass())
1570 {
1571 case clang::Type::UnaryTransform: break;
1572 case clang::Type::FunctionNoProto: return lldb::eTypeClassFunction;
1573 case clang::Type::FunctionProto: return lldb::eTypeClassFunction;
1574 case clang::Type::IncompleteArray: return lldb::eTypeClassArray;
1575 case clang::Type::VariableArray: return lldb::eTypeClassArray;
1576 case clang::Type::ConstantArray: return lldb::eTypeClassArray;
1577 case clang::Type::DependentSizedArray: return lldb::eTypeClassArray;
1578 case clang::Type::DependentSizedExtVector: return lldb::eTypeClassVector;
1579 case clang::Type::ExtVector: return lldb::eTypeClassVector;
1580 case clang::Type::Vector: return lldb::eTypeClassVector;
1581 case clang::Type::Builtin: return lldb::eTypeClassBuiltin;
1582 case clang::Type::ObjCObjectPointer: return lldb::eTypeClassObjCObjectPointer;
1583 case clang::Type::BlockPointer: return lldb::eTypeClassBlockPointer;
1584 case clang::Type::Pointer: return lldb::eTypeClassPointer;
1585 case clang::Type::LValueReference: return lldb::eTypeClassReference;
1586 case clang::Type::RValueReference: return lldb::eTypeClassReference;
1587 case clang::Type::MemberPointer: return lldb::eTypeClassMemberPointer;
1588 case clang::Type::Complex:
1589 if (qual_type->isComplexType())
1590 return lldb::eTypeClassComplexFloat;
1591 else
1592 return lldb::eTypeClassComplexInteger;
1593 case clang::Type::ObjCObject: return lldb::eTypeClassObjCObject;
1594 case clang::Type::ObjCInterface: return lldb::eTypeClassObjCInterface;
1595 case clang::Type::Record:
1596 {
1597 const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
1598 const clang::RecordDecl *record_decl = record_type->getDecl();
1599 if (record_decl->isUnion())
1600 return lldb::eTypeClassUnion;
1601 else if (record_decl->isStruct())
1602 return lldb::eTypeClassStruct;
1603 else
1604 return lldb::eTypeClassClass;
1605 }
1606 break;
1607 case clang::Type::Enum: return lldb::eTypeClassEnumeration;
1608 case clang::Type::Typedef: return lldb::eTypeClassTypedef;
1609 case clang::Type::UnresolvedUsing: break;
1610 case clang::Type::Paren:
1611 return ClangASTType(m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetTypeClass();
1612 case clang::Type::Elaborated:
1613 return ClangASTType(m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetTypeClass();
1614
1615 case clang::Type::Attributed: break;
1616 case clang::Type::TemplateTypeParm: break;
1617 case clang::Type::SubstTemplateTypeParm: break;
1618 case clang::Type::SubstTemplateTypeParmPack:break;
1619 case clang::Type::Auto: break;
1620 case clang::Type::InjectedClassName: break;
1621 case clang::Type::DependentName: break;
1622 case clang::Type::DependentTemplateSpecialization: break;
1623 case clang::Type::PackExpansion: break;
1624
1625 case clang::Type::TypeOfExpr: break;
1626 case clang::Type::TypeOf: break;
1627 case clang::Type::Decltype: break;
1628 case clang::Type::TemplateSpecialization: break;
1629 case clang::Type::Atomic: break;
1630
1631 // pointer type decayed from an array or function type.
1632 case clang::Type::Decayed: break;
1633 case clang::Type::Adjusted: break;
1634 }
1635 // We don't know hot to display this type...
1636 return lldb::eTypeClassOther;
1637
1638 }
1639
1640 void
SetClangType(clang::ASTContext * ast,clang::QualType qual_type)1641 ClangASTType::SetClangType (clang::ASTContext *ast, clang::QualType qual_type)
1642 {
1643 m_ast = ast;
1644 m_type = qual_type.getAsOpaquePtr();
1645 }
1646
1647 unsigned
GetTypeQualifiers() const1648 ClangASTType::GetTypeQualifiers() const
1649 {
1650 if (IsValid())
1651 return GetQualType().getQualifiers().getCVRQualifiers();
1652 return 0;
1653 }
1654
1655 //----------------------------------------------------------------------
1656 // Creating related types
1657 //----------------------------------------------------------------------
1658
1659 ClangASTType
AddConstModifier() const1660 ClangASTType::AddConstModifier () const
1661 {
1662 if (m_type)
1663 {
1664 clang::QualType result(GetQualType());
1665 result.addConst();
1666 return ClangASTType (m_ast, result);
1667 }
1668 return ClangASTType();
1669 }
1670
1671 ClangASTType
AddRestrictModifier() const1672 ClangASTType::AddRestrictModifier () const
1673 {
1674 if (m_type)
1675 {
1676 clang::QualType result(GetQualType());
1677 result.getQualifiers().setRestrict (true);
1678 return ClangASTType (m_ast, result);
1679 }
1680 return ClangASTType();
1681 }
1682
1683 ClangASTType
AddVolatileModifier() const1684 ClangASTType::AddVolatileModifier () const
1685 {
1686 if (m_type)
1687 {
1688 clang::QualType result(GetQualType());
1689 result.getQualifiers().setVolatile (true);
1690 return ClangASTType (m_ast, result);
1691 }
1692 return ClangASTType();
1693 }
1694
1695 ClangASTType
GetArrayElementType(uint64_t * stride) const1696 ClangASTType::GetArrayElementType (uint64_t *stride) const
1697 {
1698 if (IsValid())
1699 {
1700 clang::QualType qual_type(GetCanonicalQualType());
1701
1702 const clang::Type *array_elem_type = qual_type.getTypePtr()->getArrayElementTypeNoTypeQual();
1703
1704 if (!array_elem_type)
1705 return ClangASTType();
1706
1707 ClangASTType element_type (m_ast, array_elem_type->getCanonicalTypeUnqualified());
1708
1709 // TODO: the real stride will be >= this value.. find the real one!
1710 if (stride)
1711 *stride = element_type.GetByteSize(nullptr);
1712
1713 return element_type;
1714
1715 }
1716 return ClangASTType();
1717 }
1718
1719 ClangASTType
GetCanonicalType() const1720 ClangASTType::GetCanonicalType () const
1721 {
1722 if (IsValid())
1723 return ClangASTType (m_ast, GetCanonicalQualType());
1724 return ClangASTType();
1725 }
1726
1727 static clang::QualType
GetFullyUnqualifiedType_Impl(clang::ASTContext * ast,clang::QualType qual_type)1728 GetFullyUnqualifiedType_Impl (clang::ASTContext *ast, clang::QualType qual_type)
1729 {
1730 if (qual_type->isPointerType())
1731 qual_type = ast->getPointerType(GetFullyUnqualifiedType_Impl(ast, qual_type->getPointeeType()));
1732 else
1733 qual_type = qual_type.getUnqualifiedType();
1734 qual_type.removeLocalConst();
1735 qual_type.removeLocalRestrict();
1736 qual_type.removeLocalVolatile();
1737 return qual_type;
1738 }
1739
1740 ClangASTType
GetFullyUnqualifiedType() const1741 ClangASTType::GetFullyUnqualifiedType () const
1742 {
1743 if (IsValid())
1744 return ClangASTType(m_ast, GetFullyUnqualifiedType_Impl(m_ast, GetQualType()));
1745 return ClangASTType();
1746 }
1747
1748
1749 int
GetFunctionArgumentCount() const1750 ClangASTType::GetFunctionArgumentCount () const
1751 {
1752 if (IsValid())
1753 {
1754 const clang::FunctionProtoType* func = llvm::dyn_cast<clang::FunctionProtoType>(GetCanonicalQualType());
1755 if (func)
1756 return func->getNumParams();
1757 }
1758 return -1;
1759 }
1760
1761 ClangASTType
GetFunctionArgumentTypeAtIndex(size_t idx) const1762 ClangASTType::GetFunctionArgumentTypeAtIndex (size_t idx) const
1763 {
1764 if (IsValid())
1765 {
1766 const clang::FunctionProtoType* func = llvm::dyn_cast<clang::FunctionProtoType>(GetCanonicalQualType());
1767 if (func)
1768 {
1769 const uint32_t num_args = func->getNumParams();
1770 if (idx < num_args)
1771 return ClangASTType(m_ast, func->getParamType(idx));
1772 }
1773 }
1774 return ClangASTType();
1775 }
1776
1777 ClangASTType
GetFunctionReturnType() const1778 ClangASTType::GetFunctionReturnType () const
1779 {
1780 if (IsValid())
1781 {
1782 clang::QualType qual_type(GetCanonicalQualType());
1783 const clang::FunctionProtoType* func = llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
1784 if (func)
1785 return ClangASTType(m_ast, func->getReturnType());
1786 }
1787 return ClangASTType();
1788 }
1789
1790 size_t
GetNumMemberFunctions() const1791 ClangASTType::GetNumMemberFunctions () const
1792 {
1793 size_t num_functions = 0;
1794 if (IsValid())
1795 {
1796 clang::QualType qual_type(GetCanonicalQualType());
1797 switch (qual_type->getTypeClass()) {
1798 case clang::Type::Record:
1799 if (GetCompleteQualType (m_ast, qual_type))
1800 {
1801 const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
1802 const clang::RecordDecl *record_decl = record_type->getDecl();
1803 assert(record_decl);
1804 const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
1805 if (cxx_record_decl)
1806 num_functions = std::distance(cxx_record_decl->method_begin(), cxx_record_decl->method_end());
1807 }
1808 break;
1809
1810 case clang::Type::ObjCObjectPointer:
1811 if (GetCompleteType())
1812 {
1813 const clang::ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
1814 if (objc_class_type)
1815 {
1816 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
1817 if (class_interface_decl)
1818 num_functions = std::distance(class_interface_decl->meth_begin(), class_interface_decl->meth_end());
1819 }
1820 }
1821 break;
1822
1823 case clang::Type::ObjCObject:
1824 case clang::Type::ObjCInterface:
1825 if (GetCompleteType())
1826 {
1827 const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
1828 if (objc_class_type)
1829 {
1830 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1831 if (class_interface_decl)
1832 num_functions = std::distance(class_interface_decl->meth_begin(), class_interface_decl->meth_end());
1833 }
1834 }
1835 break;
1836
1837
1838 case clang::Type::Typedef:
1839 return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumMemberFunctions();
1840
1841 case clang::Type::Elaborated:
1842 return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetNumMemberFunctions();
1843
1844 case clang::Type::Paren:
1845 return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetNumMemberFunctions();
1846
1847 default:
1848 break;
1849 }
1850 }
1851 return num_functions;
1852 }
1853
1854 TypeMemberFunctionImpl
GetMemberFunctionAtIndex(size_t idx)1855 ClangASTType::GetMemberFunctionAtIndex (size_t idx)
1856 {
1857 std::string name("");
1858 MemberFunctionKind kind(MemberFunctionKind::eMemberFunctionKindUnknown);
1859 ClangASTType type{};
1860 clang::ObjCMethodDecl *method_decl(nullptr);
1861 if (IsValid())
1862 {
1863 clang::QualType qual_type(GetCanonicalQualType());
1864 switch (qual_type->getTypeClass()) {
1865 case clang::Type::Record:
1866 if (GetCompleteQualType (m_ast, qual_type))
1867 {
1868 const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
1869 const clang::RecordDecl *record_decl = record_type->getDecl();
1870 assert(record_decl);
1871 const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
1872 if (cxx_record_decl)
1873 {
1874 auto method_iter = cxx_record_decl->method_begin();
1875 auto method_end = cxx_record_decl->method_end();
1876 if (idx < static_cast<size_t>(std::distance(method_iter, method_end)))
1877 {
1878 std::advance(method_iter, idx);
1879 auto method_decl = method_iter->getCanonicalDecl();
1880 if (method_decl)
1881 {
1882 if (!method_decl->getName().empty())
1883 name.assign(method_decl->getName().data());
1884 else
1885 name.clear();
1886 if (method_decl->isStatic())
1887 kind = lldb::eMemberFunctionKindStaticMethod;
1888 else if (llvm::isa<clang::CXXConstructorDecl>(method_decl))
1889 kind = lldb::eMemberFunctionKindConstructor;
1890 else if (llvm::isa<clang::CXXDestructorDecl>(method_decl))
1891 kind = lldb::eMemberFunctionKindDestructor;
1892 else
1893 kind = lldb::eMemberFunctionKindInstanceMethod;
1894 type = ClangASTType(m_ast,method_decl->getType().getAsOpaquePtr());
1895 }
1896 }
1897 }
1898 }
1899 break;
1900
1901 case clang::Type::ObjCObjectPointer:
1902 if (GetCompleteType())
1903 {
1904 const clang::ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
1905 if (objc_class_type)
1906 {
1907 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
1908 if (class_interface_decl)
1909 {
1910 auto method_iter = class_interface_decl->meth_begin();
1911 auto method_end = class_interface_decl->meth_end();
1912 if (idx < static_cast<size_t>(std::distance(method_iter, method_end)))
1913 {
1914 std::advance(method_iter, idx);
1915 method_decl = method_iter->getCanonicalDecl();
1916 if (method_decl)
1917 {
1918 name = method_decl->getSelector().getAsString();
1919 if (method_decl->isClassMethod())
1920 kind = lldb::eMemberFunctionKindStaticMethod;
1921 else
1922 kind = lldb::eMemberFunctionKindInstanceMethod;
1923 }
1924 }
1925 }
1926 }
1927 }
1928 break;
1929
1930 case clang::Type::ObjCObject:
1931 case clang::Type::ObjCInterface:
1932 if (GetCompleteType())
1933 {
1934 const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
1935 if (objc_class_type)
1936 {
1937 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1938 if (class_interface_decl)
1939 {
1940 auto method_iter = class_interface_decl->meth_begin();
1941 auto method_end = class_interface_decl->meth_end();
1942 if (idx < static_cast<size_t>(std::distance(method_iter, method_end)))
1943 {
1944 std::advance(method_iter, idx);
1945 method_decl = method_iter->getCanonicalDecl();
1946 if (method_decl)
1947 {
1948 name = method_decl->getSelector().getAsString();
1949 if (method_decl->isClassMethod())
1950 kind = lldb::eMemberFunctionKindStaticMethod;
1951 else
1952 kind = lldb::eMemberFunctionKindInstanceMethod;
1953 }
1954 }
1955 }
1956 }
1957 }
1958 break;
1959
1960 case clang::Type::Typedef:
1961 return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetMemberFunctionAtIndex(idx);
1962
1963 case clang::Type::Elaborated:
1964 return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetMemberFunctionAtIndex(idx);
1965
1966 case clang::Type::Paren:
1967 return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetMemberFunctionAtIndex(idx);
1968
1969 default:
1970 break;
1971 }
1972 }
1973
1974 if (kind == eMemberFunctionKindUnknown)
1975 return TypeMemberFunctionImpl();
1976 if (method_decl)
1977 return TypeMemberFunctionImpl(method_decl, name, kind);
1978 if (type)
1979 return TypeMemberFunctionImpl(type, name, kind);
1980
1981 return TypeMemberFunctionImpl();
1982 }
1983
1984 ClangASTType
GetLValueReferenceType() const1985 ClangASTType::GetLValueReferenceType () const
1986 {
1987 if (IsValid())
1988 {
1989 return ClangASTType(m_ast, m_ast->getLValueReferenceType(GetQualType()));
1990 }
1991 return ClangASTType();
1992 }
1993
1994 ClangASTType
GetRValueReferenceType() const1995 ClangASTType::GetRValueReferenceType () const
1996 {
1997 if (IsValid())
1998 {
1999 return ClangASTType(m_ast, m_ast->getRValueReferenceType(GetQualType()));
2000 }
2001 return ClangASTType();
2002 }
2003
2004 ClangASTType
GetNonReferenceType() const2005 ClangASTType::GetNonReferenceType () const
2006 {
2007 if (IsValid())
2008 return ClangASTType(m_ast, GetQualType().getNonReferenceType());
2009 return ClangASTType();
2010 }
2011
2012 ClangASTType
CreateTypedefType(const char * typedef_name,clang::DeclContext * decl_ctx) const2013 ClangASTType::CreateTypedefType (const char *typedef_name,
2014 clang::DeclContext *decl_ctx) const
2015 {
2016 if (IsValid() && typedef_name && typedef_name[0])
2017 {
2018 clang::QualType qual_type (GetQualType());
2019 if (decl_ctx == nullptr)
2020 decl_ctx = m_ast->getTranslationUnitDecl();
2021 clang::TypedefDecl *decl = clang::TypedefDecl::Create (*m_ast,
2022 decl_ctx,
2023 clang::SourceLocation(),
2024 clang::SourceLocation(),
2025 &m_ast->Idents.get(typedef_name),
2026 m_ast->getTrivialTypeSourceInfo(qual_type));
2027
2028 decl->setAccess(clang::AS_public); // TODO respect proper access specifier
2029
2030 // Get a uniqued clang::QualType for the typedef decl type
2031 return ClangASTType (m_ast, m_ast->getTypedefType (decl));
2032 }
2033 return ClangASTType();
2034
2035 }
2036
2037 ClangASTType
GetPointeeType() const2038 ClangASTType::GetPointeeType () const
2039 {
2040 if (m_type)
2041 {
2042 clang::QualType qual_type(GetQualType());
2043 return ClangASTType (m_ast, qual_type.getTypePtr()->getPointeeType());
2044 }
2045 return ClangASTType();
2046 }
2047
2048 ClangASTType
GetPointerType() const2049 ClangASTType::GetPointerType () const
2050 {
2051 if (IsValid())
2052 {
2053 clang::QualType qual_type (GetQualType());
2054
2055 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2056 switch (type_class)
2057 {
2058 case clang::Type::ObjCObject:
2059 case clang::Type::ObjCInterface:
2060 return ClangASTType(m_ast, m_ast->getObjCObjectPointerType(qual_type).getAsOpaquePtr());
2061
2062 default:
2063 return ClangASTType(m_ast, m_ast->getPointerType(qual_type).getAsOpaquePtr());
2064 }
2065 }
2066 return ClangASTType();
2067 }
2068
2069 ClangASTType
GetTypedefedType() const2070 ClangASTType::GetTypedefedType () const
2071 {
2072 if (IsValid())
2073 {
2074 const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(GetQualType());
2075 if (typedef_type)
2076 return ClangASTType (m_ast, typedef_type->getDecl()->getUnderlyingType());
2077 }
2078 return ClangASTType();
2079 }
2080
2081 ClangASTType
RemoveFastQualifiers() const2082 ClangASTType::RemoveFastQualifiers () const
2083 {
2084 if (m_type)
2085 {
2086 clang::QualType qual_type(GetQualType());
2087 qual_type.getQualifiers().removeFastQualifiers();
2088 return ClangASTType (m_ast, qual_type);
2089 }
2090 return ClangASTType();
2091 }
2092
2093
2094 //----------------------------------------------------------------------
2095 // Create related types using the current type's AST
2096 //----------------------------------------------------------------------
2097
2098 ClangASTType
GetBasicTypeFromAST(lldb::BasicType basic_type) const2099 ClangASTType::GetBasicTypeFromAST (lldb::BasicType basic_type) const
2100 {
2101 if (IsValid())
2102 return ClangASTContext::GetBasicType(m_ast, basic_type);
2103 return ClangASTType();
2104 }
2105 //----------------------------------------------------------------------
2106 // Exploring the type
2107 //----------------------------------------------------------------------
2108
2109 uint64_t
GetBitSize(ExecutionContextScope * exe_scope) const2110 ClangASTType::GetBitSize (ExecutionContextScope *exe_scope) const
2111 {
2112 if (GetCompleteType ())
2113 {
2114 clang::QualType qual_type(GetCanonicalQualType());
2115 switch (qual_type->getTypeClass())
2116 {
2117 case clang::Type::ObjCInterface:
2118 case clang::Type::ObjCObject:
2119 {
2120 ExecutionContext exe_ctx (exe_scope);
2121 Process *process = exe_ctx.GetProcessPtr();
2122 if (process)
2123 {
2124 ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
2125 if (objc_runtime)
2126 {
2127 uint64_t bit_size = 0;
2128 if (objc_runtime->GetTypeBitSize(*this, bit_size))
2129 return bit_size;
2130 }
2131 }
2132 else
2133 {
2134 static bool g_printed = false;
2135 if (!g_printed)
2136 {
2137 StreamString s;
2138 DumpTypeDescription(&s);
2139
2140 llvm::outs() << "warning: trying to determine the size of type ";
2141 llvm::outs() << s.GetString() << "\n";
2142 llvm::outs() << "without a valid ExecutionContext. this is not reliable. please file a bug against LLDB.\n";
2143 llvm::outs() << "backtrace:\n";
2144 llvm::sys::PrintStackTrace(llvm::outs());
2145 llvm::outs() << "\n";
2146 g_printed = true;
2147 }
2148 }
2149 }
2150 // fallthrough
2151 default:
2152 const uint32_t bit_size = m_ast->getTypeSize (qual_type);
2153 if (bit_size == 0)
2154 {
2155 if (qual_type->isIncompleteArrayType())
2156 return m_ast->getTypeSize (qual_type->getArrayElementTypeNoTypeQual()->getCanonicalTypeUnqualified());
2157 }
2158 if (qual_type->isObjCObjectOrInterfaceType())
2159 return bit_size + m_ast->getTypeSize(m_ast->ObjCBuiltinClassTy);
2160 return bit_size;
2161 }
2162 }
2163 return 0;
2164 }
2165
2166 uint64_t
GetByteSize(ExecutionContextScope * exe_scope) const2167 ClangASTType::GetByteSize (ExecutionContextScope *exe_scope) const
2168 {
2169 return (GetBitSize (exe_scope) + 7) / 8;
2170 }
2171
2172
2173 size_t
GetTypeBitAlign() const2174 ClangASTType::GetTypeBitAlign () const
2175 {
2176 if (GetCompleteType ())
2177 return m_ast->getTypeAlign(GetQualType());
2178 return 0;
2179 }
2180
2181
2182 lldb::Encoding
GetEncoding(uint64_t & count) const2183 ClangASTType::GetEncoding (uint64_t &count) const
2184 {
2185 if (!IsValid())
2186 return lldb::eEncodingInvalid;
2187
2188 count = 1;
2189 clang::QualType qual_type(GetCanonicalQualType());
2190
2191 switch (qual_type->getTypeClass())
2192 {
2193 case clang::Type::UnaryTransform:
2194 break;
2195
2196 case clang::Type::FunctionNoProto:
2197 case clang::Type::FunctionProto:
2198 break;
2199
2200 case clang::Type::IncompleteArray:
2201 case clang::Type::VariableArray:
2202 break;
2203
2204 case clang::Type::ConstantArray:
2205 break;
2206
2207 case clang::Type::ExtVector:
2208 case clang::Type::Vector:
2209 // TODO: Set this to more than one???
2210 break;
2211
2212 case clang::Type::Builtin:
2213 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
2214 {
2215 default: assert(0 && "Unknown builtin type!");
2216 case clang::BuiltinType::Void:
2217 break;
2218
2219 case clang::BuiltinType::Bool:
2220 case clang::BuiltinType::Char_S:
2221 case clang::BuiltinType::SChar:
2222 case clang::BuiltinType::WChar_S:
2223 case clang::BuiltinType::Char16:
2224 case clang::BuiltinType::Char32:
2225 case clang::BuiltinType::Short:
2226 case clang::BuiltinType::Int:
2227 case clang::BuiltinType::Long:
2228 case clang::BuiltinType::LongLong:
2229 case clang::BuiltinType::Int128: return lldb::eEncodingSint;
2230
2231 case clang::BuiltinType::Char_U:
2232 case clang::BuiltinType::UChar:
2233 case clang::BuiltinType::WChar_U:
2234 case clang::BuiltinType::UShort:
2235 case clang::BuiltinType::UInt:
2236 case clang::BuiltinType::ULong:
2237 case clang::BuiltinType::ULongLong:
2238 case clang::BuiltinType::UInt128: return lldb::eEncodingUint;
2239
2240 case clang::BuiltinType::Float:
2241 case clang::BuiltinType::Double:
2242 case clang::BuiltinType::LongDouble: return lldb::eEncodingIEEE754;
2243
2244 case clang::BuiltinType::ObjCClass:
2245 case clang::BuiltinType::ObjCId:
2246 case clang::BuiltinType::ObjCSel: return lldb::eEncodingUint;
2247
2248 case clang::BuiltinType::NullPtr: return lldb::eEncodingUint;
2249
2250 case clang::BuiltinType::Kind::ARCUnbridgedCast:
2251 case clang::BuiltinType::Kind::BoundMember:
2252 case clang::BuiltinType::Kind::BuiltinFn:
2253 case clang::BuiltinType::Kind::Dependent:
2254 case clang::BuiltinType::Kind::Half:
2255 case clang::BuiltinType::Kind::OCLEvent:
2256 case clang::BuiltinType::Kind::OCLImage1d:
2257 case clang::BuiltinType::Kind::OCLImage1dArray:
2258 case clang::BuiltinType::Kind::OCLImage1dBuffer:
2259 case clang::BuiltinType::Kind::OCLImage2d:
2260 case clang::BuiltinType::Kind::OCLImage2dArray:
2261 case clang::BuiltinType::Kind::OCLImage3d:
2262 case clang::BuiltinType::Kind::OCLSampler:
2263 case clang::BuiltinType::Kind::Overload:
2264 case clang::BuiltinType::Kind::PseudoObject:
2265 case clang::BuiltinType::Kind::UnknownAny:
2266 break;
2267 }
2268 break;
2269 // All pointer types are represented as unsigned integer encodings.
2270 // We may nee to add a eEncodingPointer if we ever need to know the
2271 // difference
2272 case clang::Type::ObjCObjectPointer:
2273 case clang::Type::BlockPointer:
2274 case clang::Type::Pointer:
2275 case clang::Type::LValueReference:
2276 case clang::Type::RValueReference:
2277 case clang::Type::MemberPointer: return lldb::eEncodingUint;
2278 case clang::Type::Complex:
2279 {
2280 lldb::Encoding encoding = lldb::eEncodingIEEE754;
2281 if (qual_type->isComplexType())
2282 encoding = lldb::eEncodingIEEE754;
2283 else
2284 {
2285 const clang::ComplexType *complex_type = qual_type->getAsComplexIntegerType();
2286 if (complex_type)
2287 encoding = ClangASTType(m_ast, complex_type->getElementType()).GetEncoding(count);
2288 else
2289 encoding = lldb::eEncodingSint;
2290 }
2291 count = 2;
2292 return encoding;
2293 }
2294
2295 case clang::Type::ObjCInterface: break;
2296 case clang::Type::Record: break;
2297 case clang::Type::Enum: return lldb::eEncodingSint;
2298 case clang::Type::Typedef:
2299 return ClangASTType(m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetEncoding(count);
2300
2301 case clang::Type::Elaborated:
2302 return ClangASTType(m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetEncoding(count);
2303
2304 case clang::Type::Paren:
2305 return ClangASTType(m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetEncoding(count);
2306
2307 case clang::Type::DependentSizedArray:
2308 case clang::Type::DependentSizedExtVector:
2309 case clang::Type::UnresolvedUsing:
2310 case clang::Type::Attributed:
2311 case clang::Type::TemplateTypeParm:
2312 case clang::Type::SubstTemplateTypeParm:
2313 case clang::Type::SubstTemplateTypeParmPack:
2314 case clang::Type::Auto:
2315 case clang::Type::InjectedClassName:
2316 case clang::Type::DependentName:
2317 case clang::Type::DependentTemplateSpecialization:
2318 case clang::Type::PackExpansion:
2319 case clang::Type::ObjCObject:
2320
2321 case clang::Type::TypeOfExpr:
2322 case clang::Type::TypeOf:
2323 case clang::Type::Decltype:
2324 case clang::Type::TemplateSpecialization:
2325 case clang::Type::Atomic:
2326 case clang::Type::Adjusted:
2327 break;
2328
2329 // pointer type decayed from an array or function type.
2330 case clang::Type::Decayed:
2331 break;
2332 }
2333 count = 0;
2334 return lldb::eEncodingInvalid;
2335 }
2336
2337 lldb::Format
GetFormat() const2338 ClangASTType::GetFormat () const
2339 {
2340 if (!IsValid())
2341 return lldb::eFormatDefault;
2342
2343 clang::QualType qual_type(GetCanonicalQualType());
2344
2345 switch (qual_type->getTypeClass())
2346 {
2347 case clang::Type::UnaryTransform:
2348 break;
2349
2350 case clang::Type::FunctionNoProto:
2351 case clang::Type::FunctionProto:
2352 break;
2353
2354 case clang::Type::IncompleteArray:
2355 case clang::Type::VariableArray:
2356 break;
2357
2358 case clang::Type::ConstantArray:
2359 return lldb::eFormatVoid; // no value
2360
2361 case clang::Type::ExtVector:
2362 case clang::Type::Vector:
2363 break;
2364
2365 case clang::Type::Builtin:
2366 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
2367 {
2368 //default: assert(0 && "Unknown builtin type!");
2369 case clang::BuiltinType::UnknownAny:
2370 case clang::BuiltinType::Void:
2371 case clang::BuiltinType::BoundMember:
2372 break;
2373
2374 case clang::BuiltinType::Bool: return lldb::eFormatBoolean;
2375 case clang::BuiltinType::Char_S:
2376 case clang::BuiltinType::SChar:
2377 case clang::BuiltinType::WChar_S:
2378 case clang::BuiltinType::Char_U:
2379 case clang::BuiltinType::UChar:
2380 case clang::BuiltinType::WChar_U: return lldb::eFormatChar;
2381 case clang::BuiltinType::Char16: return lldb::eFormatUnicode16;
2382 case clang::BuiltinType::Char32: return lldb::eFormatUnicode32;
2383 case clang::BuiltinType::UShort: return lldb::eFormatUnsigned;
2384 case clang::BuiltinType::Short: return lldb::eFormatDecimal;
2385 case clang::BuiltinType::UInt: return lldb::eFormatUnsigned;
2386 case clang::BuiltinType::Int: return lldb::eFormatDecimal;
2387 case clang::BuiltinType::ULong: return lldb::eFormatUnsigned;
2388 case clang::BuiltinType::Long: return lldb::eFormatDecimal;
2389 case clang::BuiltinType::ULongLong: return lldb::eFormatUnsigned;
2390 case clang::BuiltinType::LongLong: return lldb::eFormatDecimal;
2391 case clang::BuiltinType::UInt128: return lldb::eFormatUnsigned;
2392 case clang::BuiltinType::Int128: return lldb::eFormatDecimal;
2393 case clang::BuiltinType::Float: return lldb::eFormatFloat;
2394 case clang::BuiltinType::Double: return lldb::eFormatFloat;
2395 case clang::BuiltinType::LongDouble: return lldb::eFormatFloat;
2396 case clang::BuiltinType::NullPtr:
2397 case clang::BuiltinType::Overload:
2398 case clang::BuiltinType::Dependent:
2399 case clang::BuiltinType::ObjCId:
2400 case clang::BuiltinType::ObjCClass:
2401 case clang::BuiltinType::ObjCSel:
2402 case clang::BuiltinType::Half:
2403 case clang::BuiltinType::ARCUnbridgedCast:
2404 case clang::BuiltinType::PseudoObject:
2405 case clang::BuiltinType::BuiltinFn:
2406 case clang::BuiltinType::OCLEvent:
2407 case clang::BuiltinType::OCLImage1d:
2408 case clang::BuiltinType::OCLImage1dArray:
2409 case clang::BuiltinType::OCLImage1dBuffer:
2410 case clang::BuiltinType::OCLImage2d:
2411 case clang::BuiltinType::OCLImage2dArray:
2412 case clang::BuiltinType::OCLImage3d:
2413 case clang::BuiltinType::OCLSampler:
2414 return lldb::eFormatHex;
2415 }
2416 break;
2417 case clang::Type::ObjCObjectPointer: return lldb::eFormatHex;
2418 case clang::Type::BlockPointer: return lldb::eFormatHex;
2419 case clang::Type::Pointer: return lldb::eFormatHex;
2420 case clang::Type::LValueReference:
2421 case clang::Type::RValueReference: return lldb::eFormatHex;
2422 case clang::Type::MemberPointer: break;
2423 case clang::Type::Complex:
2424 {
2425 if (qual_type->isComplexType())
2426 return lldb::eFormatComplex;
2427 else
2428 return lldb::eFormatComplexInteger;
2429 }
2430 case clang::Type::ObjCInterface: break;
2431 case clang::Type::Record: break;
2432 case clang::Type::Enum: return lldb::eFormatEnum;
2433 case clang::Type::Typedef:
2434 return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetFormat();
2435 case clang::Type::Auto:
2436 return ClangASTType (m_ast, llvm::cast<clang::AutoType>(qual_type)->desugar()).GetFormat();
2437 case clang::Type::Paren:
2438 return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetFormat();
2439 case clang::Type::Elaborated:
2440 return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetFormat();
2441 case clang::Type::DependentSizedArray:
2442 case clang::Type::DependentSizedExtVector:
2443 case clang::Type::UnresolvedUsing:
2444 case clang::Type::Attributed:
2445 case clang::Type::TemplateTypeParm:
2446 case clang::Type::SubstTemplateTypeParm:
2447 case clang::Type::SubstTemplateTypeParmPack:
2448 case clang::Type::InjectedClassName:
2449 case clang::Type::DependentName:
2450 case clang::Type::DependentTemplateSpecialization:
2451 case clang::Type::PackExpansion:
2452 case clang::Type::ObjCObject:
2453
2454 case clang::Type::TypeOfExpr:
2455 case clang::Type::TypeOf:
2456 case clang::Type::Decltype:
2457 case clang::Type::TemplateSpecialization:
2458 case clang::Type::Atomic:
2459 case clang::Type::Adjusted:
2460 break;
2461
2462 // pointer type decayed from an array or function type.
2463 case clang::Type::Decayed:
2464 break;
2465 }
2466 // We don't know hot to display this type...
2467 return lldb::eFormatBytes;
2468 }
2469
2470 static bool
ObjCDeclHasIVars(clang::ObjCInterfaceDecl * class_interface_decl,bool check_superclass)2471 ObjCDeclHasIVars (clang::ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
2472 {
2473 while (class_interface_decl)
2474 {
2475 if (class_interface_decl->ivar_size() > 0)
2476 return true;
2477
2478 if (check_superclass)
2479 class_interface_decl = class_interface_decl->getSuperClass();
2480 else
2481 break;
2482 }
2483 return false;
2484 }
2485
2486 uint32_t
GetNumChildren(bool omit_empty_base_classes) const2487 ClangASTType::GetNumChildren (bool omit_empty_base_classes) const
2488 {
2489 if (!IsValid())
2490 return 0;
2491
2492 uint32_t num_children = 0;
2493 clang::QualType qual_type(GetQualType());
2494 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2495 switch (type_class)
2496 {
2497 case clang::Type::Builtin:
2498 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
2499 {
2500 case clang::BuiltinType::ObjCId: // child is Class
2501 case clang::BuiltinType::ObjCClass: // child is Class
2502 num_children = 1;
2503 break;
2504
2505 default:
2506 break;
2507 }
2508 break;
2509
2510 case clang::Type::Complex: return 0;
2511
2512 case clang::Type::Record:
2513 if (GetCompleteQualType (m_ast, qual_type))
2514 {
2515 const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
2516 const clang::RecordDecl *record_decl = record_type->getDecl();
2517 assert(record_decl);
2518 const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
2519 if (cxx_record_decl)
2520 {
2521 if (omit_empty_base_classes)
2522 {
2523 // Check each base classes to see if it or any of its
2524 // base classes contain any fields. This can help
2525 // limit the noise in variable views by not having to
2526 // show base classes that contain no members.
2527 clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2528 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2529 base_class != base_class_end;
2530 ++base_class)
2531 {
2532 const clang::CXXRecordDecl *base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl());
2533
2534 // Skip empty base classes
2535 if (ClangASTContext::RecordHasFields(base_class_decl) == false)
2536 continue;
2537
2538 num_children++;
2539 }
2540 }
2541 else
2542 {
2543 // Include all base classes
2544 num_children += cxx_record_decl->getNumBases();
2545 }
2546
2547 }
2548 clang::RecordDecl::field_iterator field, field_end;
2549 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
2550 ++num_children;
2551 }
2552 break;
2553
2554 case clang::Type::ObjCObject:
2555 case clang::Type::ObjCInterface:
2556 if (GetCompleteQualType (m_ast, qual_type))
2557 {
2558 const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
2559 assert (objc_class_type);
2560 if (objc_class_type)
2561 {
2562 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2563
2564 if (class_interface_decl)
2565 {
2566
2567 clang::ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2568 if (superclass_interface_decl)
2569 {
2570 if (omit_empty_base_classes)
2571 {
2572 if (ObjCDeclHasIVars (superclass_interface_decl, true))
2573 ++num_children;
2574 }
2575 else
2576 ++num_children;
2577 }
2578
2579 num_children += class_interface_decl->ivar_size();
2580 }
2581 }
2582 }
2583 break;
2584
2585 case clang::Type::ObjCObjectPointer:
2586 {
2587 const clang::ObjCObjectPointerType *pointer_type = llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr());
2588 clang::QualType pointee_type = pointer_type->getPointeeType();
2589 uint32_t num_pointee_children = ClangASTType (m_ast,pointee_type).GetNumChildren (omit_empty_base_classes);
2590 // If this type points to a simple type, then it has 1 child
2591 if (num_pointee_children == 0)
2592 num_children = 1;
2593 else
2594 num_children = num_pointee_children;
2595 }
2596 break;
2597
2598 case clang::Type::Vector:
2599 case clang::Type::ExtVector:
2600 num_children = llvm::cast<clang::VectorType>(qual_type.getTypePtr())->getNumElements();
2601 break;
2602
2603 case clang::Type::ConstantArray:
2604 num_children = llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
2605 break;
2606
2607 case clang::Type::Pointer:
2608 {
2609 const clang::PointerType *pointer_type = llvm::cast<clang::PointerType>(qual_type.getTypePtr());
2610 clang::QualType pointee_type (pointer_type->getPointeeType());
2611 uint32_t num_pointee_children = ClangASTType (m_ast,pointee_type).GetNumChildren (omit_empty_base_classes);
2612 if (num_pointee_children == 0)
2613 {
2614 // We have a pointer to a pointee type that claims it has no children.
2615 // We will want to look at
2616 num_children = ClangASTType (m_ast, pointee_type).GetNumPointeeChildren();
2617 }
2618 else
2619 num_children = num_pointee_children;
2620 }
2621 break;
2622
2623 case clang::Type::LValueReference:
2624 case clang::Type::RValueReference:
2625 {
2626 const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
2627 clang::QualType pointee_type = reference_type->getPointeeType();
2628 uint32_t num_pointee_children = ClangASTType (m_ast, pointee_type).GetNumChildren (omit_empty_base_classes);
2629 // If this type points to a simple type, then it has 1 child
2630 if (num_pointee_children == 0)
2631 num_children = 1;
2632 else
2633 num_children = num_pointee_children;
2634 }
2635 break;
2636
2637
2638 case clang::Type::Typedef:
2639 num_children = ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumChildren (omit_empty_base_classes);
2640 break;
2641
2642 case clang::Type::Elaborated:
2643 num_children = ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetNumChildren (omit_empty_base_classes);
2644 break;
2645
2646 case clang::Type::Paren:
2647 num_children = ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetNumChildren (omit_empty_base_classes);
2648 break;
2649 default:
2650 break;
2651 }
2652 return num_children;
2653 }
2654
2655 lldb::BasicType
GetBasicTypeEnumeration() const2656 ClangASTType::GetBasicTypeEnumeration () const
2657 {
2658 if (IsValid())
2659 {
2660 clang::QualType qual_type(GetQualType());
2661 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2662 if (type_class == clang::Type::Builtin)
2663 {
2664 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
2665 {
2666 case clang::BuiltinType::Void: return eBasicTypeVoid;
2667 case clang::BuiltinType::Bool: return eBasicTypeBool;
2668 case clang::BuiltinType::Char_S: return eBasicTypeSignedChar;
2669 case clang::BuiltinType::Char_U: return eBasicTypeUnsignedChar;
2670 case clang::BuiltinType::Char16: return eBasicTypeChar16;
2671 case clang::BuiltinType::Char32: return eBasicTypeChar32;
2672 case clang::BuiltinType::UChar: return eBasicTypeUnsignedChar;
2673 case clang::BuiltinType::SChar: return eBasicTypeSignedChar;
2674 case clang::BuiltinType::WChar_S: return eBasicTypeSignedWChar;
2675 case clang::BuiltinType::WChar_U: return eBasicTypeUnsignedWChar;
2676 case clang::BuiltinType::Short: return eBasicTypeShort;
2677 case clang::BuiltinType::UShort: return eBasicTypeUnsignedShort;
2678 case clang::BuiltinType::Int: return eBasicTypeInt;
2679 case clang::BuiltinType::UInt: return eBasicTypeUnsignedInt;
2680 case clang::BuiltinType::Long: return eBasicTypeLong;
2681 case clang::BuiltinType::ULong: return eBasicTypeUnsignedLong;
2682 case clang::BuiltinType::LongLong: return eBasicTypeLongLong;
2683 case clang::BuiltinType::ULongLong: return eBasicTypeUnsignedLongLong;
2684 case clang::BuiltinType::Int128: return eBasicTypeInt128;
2685 case clang::BuiltinType::UInt128: return eBasicTypeUnsignedInt128;
2686
2687 case clang::BuiltinType::Half: return eBasicTypeHalf;
2688 case clang::BuiltinType::Float: return eBasicTypeFloat;
2689 case clang::BuiltinType::Double: return eBasicTypeDouble;
2690 case clang::BuiltinType::LongDouble:return eBasicTypeLongDouble;
2691
2692 case clang::BuiltinType::NullPtr: return eBasicTypeNullPtr;
2693 case clang::BuiltinType::ObjCId: return eBasicTypeObjCID;
2694 case clang::BuiltinType::ObjCClass: return eBasicTypeObjCClass;
2695 case clang::BuiltinType::ObjCSel: return eBasicTypeObjCSel;
2696 case clang::BuiltinType::Dependent:
2697 case clang::BuiltinType::Overload:
2698 case clang::BuiltinType::BoundMember:
2699 case clang::BuiltinType::PseudoObject:
2700 case clang::BuiltinType::UnknownAny:
2701 case clang::BuiltinType::BuiltinFn:
2702 case clang::BuiltinType::ARCUnbridgedCast:
2703 case clang::BuiltinType::OCLEvent:
2704 case clang::BuiltinType::OCLImage1d:
2705 case clang::BuiltinType::OCLImage1dArray:
2706 case clang::BuiltinType::OCLImage1dBuffer:
2707 case clang::BuiltinType::OCLImage2d:
2708 case clang::BuiltinType::OCLImage2dArray:
2709 case clang::BuiltinType::OCLImage3d:
2710 case clang::BuiltinType::OCLSampler:
2711 return eBasicTypeOther;
2712 }
2713 }
2714 }
2715 return eBasicTypeInvalid;
2716 }
2717
2718
2719 #pragma mark Aggregate Types
2720
2721 uint32_t
GetNumDirectBaseClasses() const2722 ClangASTType::GetNumDirectBaseClasses () const
2723 {
2724 if (!IsValid())
2725 return 0;
2726
2727 uint32_t count = 0;
2728 clang::QualType qual_type(GetCanonicalQualType());
2729 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2730 switch (type_class)
2731 {
2732 case clang::Type::Record:
2733 if (GetCompleteType())
2734 {
2735 const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2736 if (cxx_record_decl)
2737 count = cxx_record_decl->getNumBases();
2738 }
2739 break;
2740
2741 case clang::Type::ObjCObjectPointer:
2742 count = GetPointeeType().GetNumDirectBaseClasses();
2743 break;
2744
2745 case clang::Type::ObjCObject:
2746 if (GetCompleteType())
2747 {
2748 const clang::ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
2749 if (objc_class_type)
2750 {
2751 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2752
2753 if (class_interface_decl && class_interface_decl->getSuperClass())
2754 count = 1;
2755 }
2756 }
2757 break;
2758 case clang::Type::ObjCInterface:
2759 if (GetCompleteType())
2760 {
2761 const clang::ObjCInterfaceType *objc_interface_type = qual_type->getAs<clang::ObjCInterfaceType>();
2762 if (objc_interface_type)
2763 {
2764 clang::ObjCInterfaceDecl *class_interface_decl = objc_interface_type->getInterface();
2765
2766 if (class_interface_decl && class_interface_decl->getSuperClass())
2767 count = 1;
2768 }
2769 }
2770 break;
2771
2772
2773 case clang::Type::Typedef:
2774 count = ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumDirectBaseClasses ();
2775 break;
2776
2777 case clang::Type::Elaborated:
2778 count = ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetNumDirectBaseClasses ();
2779 break;
2780
2781 case clang::Type::Paren:
2782 return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetNumDirectBaseClasses ();
2783
2784 default:
2785 break;
2786 }
2787 return count;
2788 }
2789
2790 uint32_t
GetNumVirtualBaseClasses() const2791 ClangASTType::GetNumVirtualBaseClasses () const
2792 {
2793 if (!IsValid())
2794 return 0;
2795
2796 uint32_t count = 0;
2797 clang::QualType qual_type(GetCanonicalQualType());
2798 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2799 switch (type_class)
2800 {
2801 case clang::Type::Record:
2802 if (GetCompleteType())
2803 {
2804 const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2805 if (cxx_record_decl)
2806 count = cxx_record_decl->getNumVBases();
2807 }
2808 break;
2809
2810 case clang::Type::Typedef:
2811 count = ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumVirtualBaseClasses();
2812 break;
2813
2814 case clang::Type::Elaborated:
2815 count = ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetNumVirtualBaseClasses();
2816 break;
2817
2818 case clang::Type::Paren:
2819 count = ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetNumVirtualBaseClasses();
2820 break;
2821
2822 default:
2823 break;
2824 }
2825 return count;
2826 }
2827
2828 uint32_t
GetNumFields() const2829 ClangASTType::GetNumFields () const
2830 {
2831 if (!IsValid())
2832 return 0;
2833
2834 uint32_t count = 0;
2835 clang::QualType qual_type(GetCanonicalQualType());
2836 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2837 switch (type_class)
2838 {
2839 case clang::Type::Record:
2840 if (GetCompleteType())
2841 {
2842 const clang::RecordType *record_type = llvm::dyn_cast<clang::RecordType>(qual_type.getTypePtr());
2843 if (record_type)
2844 {
2845 clang::RecordDecl *record_decl = record_type->getDecl();
2846 if (record_decl)
2847 {
2848 uint32_t field_idx = 0;
2849 clang::RecordDecl::field_iterator field, field_end;
2850 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
2851 ++field_idx;
2852 count = field_idx;
2853 }
2854 }
2855 }
2856 break;
2857
2858 case clang::Type::Typedef:
2859 count = ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumFields();
2860 break;
2861
2862 case clang::Type::Elaborated:
2863 count = ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetNumFields();
2864 break;
2865
2866 case clang::Type::Paren:
2867 count = ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetNumFields();
2868 break;
2869
2870 case clang::Type::ObjCObjectPointer:
2871 if (GetCompleteType())
2872 {
2873 const clang::ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
2874 if (objc_class_type)
2875 {
2876 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
2877
2878 if (class_interface_decl)
2879 count = class_interface_decl->ivar_size();
2880 }
2881 }
2882 break;
2883
2884 case clang::Type::ObjCObject:
2885 case clang::Type::ObjCInterface:
2886 if (GetCompleteType())
2887 {
2888 const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
2889 if (objc_class_type)
2890 {
2891 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2892
2893 if (class_interface_decl)
2894 count = class_interface_decl->ivar_size();
2895 }
2896 }
2897 break;
2898
2899 default:
2900 break;
2901 }
2902 return count;
2903 }
2904
2905 ClangASTType
GetDirectBaseClassAtIndex(size_t idx,uint32_t * bit_offset_ptr) const2906 ClangASTType::GetDirectBaseClassAtIndex (size_t idx, uint32_t *bit_offset_ptr) const
2907 {
2908 if (!IsValid())
2909 return ClangASTType();
2910
2911 clang::QualType qual_type(GetCanonicalQualType());
2912 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
2913 switch (type_class)
2914 {
2915 case clang::Type::Record:
2916 if (GetCompleteType())
2917 {
2918 const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
2919 if (cxx_record_decl)
2920 {
2921 uint32_t curr_idx = 0;
2922 clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
2923 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
2924 base_class != base_class_end;
2925 ++base_class, ++curr_idx)
2926 {
2927 if (curr_idx == idx)
2928 {
2929 if (bit_offset_ptr)
2930 {
2931 const clang::ASTRecordLayout &record_layout = m_ast->getASTRecordLayout(cxx_record_decl);
2932 const clang::CXXRecordDecl *base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl());
2933 if (base_class->isVirtual())
2934 *bit_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
2935 else
2936 *bit_offset_ptr = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
2937 }
2938 return ClangASTType (m_ast, base_class->getType());
2939 }
2940 }
2941 }
2942 }
2943 break;
2944
2945 case clang::Type::ObjCObjectPointer:
2946 return GetPointeeType().GetDirectBaseClassAtIndex(idx,bit_offset_ptr);
2947
2948 case clang::Type::ObjCObject:
2949 if (idx == 0 && GetCompleteType())
2950 {
2951 const clang::ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
2952 if (objc_class_type)
2953 {
2954 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
2955
2956 if (class_interface_decl)
2957 {
2958 clang::ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2959 if (superclass_interface_decl)
2960 {
2961 if (bit_offset_ptr)
2962 *bit_offset_ptr = 0;
2963 return ClangASTType (m_ast, m_ast->getObjCInterfaceType(superclass_interface_decl));
2964 }
2965 }
2966 }
2967 }
2968 break;
2969 case clang::Type::ObjCInterface:
2970 if (idx == 0 && GetCompleteType())
2971 {
2972 const clang::ObjCObjectType *objc_interface_type = qual_type->getAs<clang::ObjCInterfaceType>();
2973 if (objc_interface_type)
2974 {
2975 clang::ObjCInterfaceDecl *class_interface_decl = objc_interface_type->getInterface();
2976
2977 if (class_interface_decl)
2978 {
2979 clang::ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
2980 if (superclass_interface_decl)
2981 {
2982 if (bit_offset_ptr)
2983 *bit_offset_ptr = 0;
2984 return ClangASTType (m_ast, m_ast->getObjCInterfaceType(superclass_interface_decl));
2985 }
2986 }
2987 }
2988 }
2989 break;
2990
2991
2992 case clang::Type::Typedef:
2993 return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetDirectBaseClassAtIndex (idx, bit_offset_ptr);
2994
2995 case clang::Type::Elaborated:
2996 return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetDirectBaseClassAtIndex (idx, bit_offset_ptr);
2997
2998 case clang::Type::Paren:
2999 return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetDirectBaseClassAtIndex (idx, bit_offset_ptr);
3000
3001 default:
3002 break;
3003 }
3004 return ClangASTType();
3005 }
3006
3007 ClangASTType
GetVirtualBaseClassAtIndex(size_t idx,uint32_t * bit_offset_ptr) const3008 ClangASTType::GetVirtualBaseClassAtIndex (size_t idx, uint32_t *bit_offset_ptr) const
3009 {
3010 if (!IsValid())
3011 return ClangASTType();
3012
3013 clang::QualType qual_type(GetCanonicalQualType());
3014 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3015 switch (type_class)
3016 {
3017 case clang::Type::Record:
3018 if (GetCompleteType())
3019 {
3020 const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
3021 if (cxx_record_decl)
3022 {
3023 uint32_t curr_idx = 0;
3024 clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3025 for (base_class = cxx_record_decl->vbases_begin(), base_class_end = cxx_record_decl->vbases_end();
3026 base_class != base_class_end;
3027 ++base_class, ++curr_idx)
3028 {
3029 if (curr_idx == idx)
3030 {
3031 if (bit_offset_ptr)
3032 {
3033 const clang::ASTRecordLayout &record_layout = m_ast->getASTRecordLayout(cxx_record_decl);
3034 const clang::CXXRecordDecl *base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl());
3035 *bit_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
3036
3037 }
3038 return ClangASTType (m_ast, base_class->getType());
3039 }
3040 }
3041 }
3042 }
3043 break;
3044
3045 case clang::Type::Typedef:
3046 return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetVirtualBaseClassAtIndex (idx, bit_offset_ptr);
3047
3048 case clang::Type::Elaborated:
3049 return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetVirtualBaseClassAtIndex (idx, bit_offset_ptr);
3050
3051 case clang::Type::Paren:
3052 return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetVirtualBaseClassAtIndex (idx, bit_offset_ptr);
3053
3054 default:
3055 break;
3056 }
3057 return ClangASTType();
3058 }
3059
3060 static clang_type_t
GetObjCFieldAtIndex(clang::ASTContext * ast,clang::ObjCInterfaceDecl * class_interface_decl,size_t idx,std::string & name,uint64_t * bit_offset_ptr,uint32_t * bitfield_bit_size_ptr,bool * is_bitfield_ptr)3061 GetObjCFieldAtIndex (clang::ASTContext *ast,
3062 clang::ObjCInterfaceDecl *class_interface_decl,
3063 size_t idx,
3064 std::string& name,
3065 uint64_t *bit_offset_ptr,
3066 uint32_t *bitfield_bit_size_ptr,
3067 bool *is_bitfield_ptr)
3068 {
3069 if (class_interface_decl)
3070 {
3071 if (idx < (class_interface_decl->ivar_size()))
3072 {
3073 clang::ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3074 uint32_t ivar_idx = 0;
3075
3076 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++ivar_idx)
3077 {
3078 if (ivar_idx == idx)
3079 {
3080 const clang::ObjCIvarDecl* ivar_decl = *ivar_pos;
3081
3082 clang::QualType ivar_qual_type(ivar_decl->getType());
3083
3084 name.assign(ivar_decl->getNameAsString());
3085
3086 if (bit_offset_ptr)
3087 {
3088 const clang::ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
3089 *bit_offset_ptr = interface_layout.getFieldOffset (ivar_idx);
3090 }
3091
3092 const bool is_bitfield = ivar_pos->isBitField();
3093
3094 if (bitfield_bit_size_ptr)
3095 {
3096 *bitfield_bit_size_ptr = 0;
3097
3098 if (is_bitfield && ast)
3099 {
3100 clang::Expr *bitfield_bit_size_expr = ivar_pos->getBitWidth();
3101 llvm::APSInt bitfield_apsint;
3102 if (bitfield_bit_size_expr && bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, *ast))
3103 {
3104 *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
3105 }
3106 }
3107 }
3108 if (is_bitfield_ptr)
3109 *is_bitfield_ptr = is_bitfield;
3110
3111 return ivar_qual_type.getAsOpaquePtr();
3112 }
3113 }
3114 }
3115 }
3116 return nullptr;
3117 }
3118
3119 ClangASTType
GetFieldAtIndex(size_t idx,std::string & name,uint64_t * bit_offset_ptr,uint32_t * bitfield_bit_size_ptr,bool * is_bitfield_ptr) const3120 ClangASTType::GetFieldAtIndex (size_t idx,
3121 std::string& name,
3122 uint64_t *bit_offset_ptr,
3123 uint32_t *bitfield_bit_size_ptr,
3124 bool *is_bitfield_ptr) const
3125 {
3126 if (!IsValid())
3127 return ClangASTType();
3128
3129 clang::QualType qual_type(GetCanonicalQualType());
3130 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3131 switch (type_class)
3132 {
3133 case clang::Type::Record:
3134 if (GetCompleteType())
3135 {
3136 const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
3137 const clang::RecordDecl *record_decl = record_type->getDecl();
3138 uint32_t field_idx = 0;
3139 clang::RecordDecl::field_iterator field, field_end;
3140 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx)
3141 {
3142 if (idx == field_idx)
3143 {
3144 // Print the member type if requested
3145 // Print the member name and equal sign
3146 name.assign(field->getNameAsString());
3147
3148 // Figure out the type byte size (field_type_info.first) and
3149 // alignment (field_type_info.second) from the AST context.
3150 if (bit_offset_ptr)
3151 {
3152 const clang::ASTRecordLayout &record_layout = m_ast->getASTRecordLayout(record_decl);
3153 *bit_offset_ptr = record_layout.getFieldOffset (field_idx);
3154 }
3155
3156 const bool is_bitfield = field->isBitField();
3157
3158 if (bitfield_bit_size_ptr)
3159 {
3160 *bitfield_bit_size_ptr = 0;
3161
3162 if (is_bitfield)
3163 {
3164 clang::Expr *bitfield_bit_size_expr = field->getBitWidth();
3165 llvm::APSInt bitfield_apsint;
3166 if (bitfield_bit_size_expr && bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, *m_ast))
3167 {
3168 *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
3169 }
3170 }
3171 }
3172 if (is_bitfield_ptr)
3173 *is_bitfield_ptr = is_bitfield;
3174
3175 return ClangASTType (m_ast, field->getType());
3176 }
3177 }
3178 }
3179 break;
3180
3181 case clang::Type::ObjCObjectPointer:
3182 if (GetCompleteType())
3183 {
3184 const clang::ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
3185 if (objc_class_type)
3186 {
3187 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
3188 return ClangASTType (m_ast, GetObjCFieldAtIndex(m_ast, class_interface_decl, idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr));
3189 }
3190 }
3191 break;
3192
3193 case clang::Type::ObjCObject:
3194 case clang::Type::ObjCInterface:
3195 if (GetCompleteType())
3196 {
3197 const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
3198 assert (objc_class_type);
3199 if (objc_class_type)
3200 {
3201 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3202 return ClangASTType (m_ast, GetObjCFieldAtIndex(m_ast, class_interface_decl, idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr));
3203 }
3204 }
3205 break;
3206
3207
3208 case clang::Type::Typedef:
3209 return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).
3210 GetFieldAtIndex (idx,
3211 name,
3212 bit_offset_ptr,
3213 bitfield_bit_size_ptr,
3214 is_bitfield_ptr);
3215
3216 case clang::Type::Elaborated:
3217 return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).
3218 GetFieldAtIndex (idx,
3219 name,
3220 bit_offset_ptr,
3221 bitfield_bit_size_ptr,
3222 is_bitfield_ptr);
3223
3224 case clang::Type::Paren:
3225 return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).
3226 GetFieldAtIndex (idx,
3227 name,
3228 bit_offset_ptr,
3229 bitfield_bit_size_ptr,
3230 is_bitfield_ptr);
3231
3232 default:
3233 break;
3234 }
3235 return ClangASTType();
3236 }
3237
3238 uint32_t
GetIndexOfFieldWithName(const char * name,ClangASTType * field_clang_type_ptr,uint64_t * bit_offset_ptr,uint32_t * bitfield_bit_size_ptr,bool * is_bitfield_ptr) const3239 ClangASTType::GetIndexOfFieldWithName (const char* name,
3240 ClangASTType* field_clang_type_ptr,
3241 uint64_t *bit_offset_ptr,
3242 uint32_t *bitfield_bit_size_ptr,
3243 bool *is_bitfield_ptr) const
3244 {
3245 unsigned count = GetNumFields();
3246 std::string field_name;
3247 for (unsigned index = 0; index < count; index++)
3248 {
3249 ClangASTType field_clang_type (GetFieldAtIndex(index, field_name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr));
3250 if (strcmp(field_name.c_str(), name) == 0)
3251 {
3252 if (field_clang_type_ptr)
3253 *field_clang_type_ptr = field_clang_type;
3254 return index;
3255 }
3256 }
3257 return UINT32_MAX;
3258 }
3259
3260 // If a pointer to a pointee type (the clang_type arg) says that it has no
3261 // children, then we either need to trust it, or override it and return a
3262 // different result. For example, an "int *" has one child that is an integer,
3263 // but a function pointer doesn't have any children. Likewise if a Record type
3264 // claims it has no children, then there really is nothing to show.
3265 uint32_t
GetNumPointeeChildren() const3266 ClangASTType::GetNumPointeeChildren () const
3267 {
3268 if (!IsValid())
3269 return 0;
3270
3271 clang::QualType qual_type(GetCanonicalQualType());
3272 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
3273 switch (type_class)
3274 {
3275 case clang::Type::Builtin:
3276 switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
3277 {
3278 case clang::BuiltinType::UnknownAny:
3279 case clang::BuiltinType::Void:
3280 case clang::BuiltinType::NullPtr:
3281 case clang::BuiltinType::OCLEvent:
3282 case clang::BuiltinType::OCLImage1d:
3283 case clang::BuiltinType::OCLImage1dArray:
3284 case clang::BuiltinType::OCLImage1dBuffer:
3285 case clang::BuiltinType::OCLImage2d:
3286 case clang::BuiltinType::OCLImage2dArray:
3287 case clang::BuiltinType::OCLImage3d:
3288 case clang::BuiltinType::OCLSampler:
3289 return 0;
3290 case clang::BuiltinType::Bool:
3291 case clang::BuiltinType::Char_U:
3292 case clang::BuiltinType::UChar:
3293 case clang::BuiltinType::WChar_U:
3294 case clang::BuiltinType::Char16:
3295 case clang::BuiltinType::Char32:
3296 case clang::BuiltinType::UShort:
3297 case clang::BuiltinType::UInt:
3298 case clang::BuiltinType::ULong:
3299 case clang::BuiltinType::ULongLong:
3300 case clang::BuiltinType::UInt128:
3301 case clang::BuiltinType::Char_S:
3302 case clang::BuiltinType::SChar:
3303 case clang::BuiltinType::WChar_S:
3304 case clang::BuiltinType::Short:
3305 case clang::BuiltinType::Int:
3306 case clang::BuiltinType::Long:
3307 case clang::BuiltinType::LongLong:
3308 case clang::BuiltinType::Int128:
3309 case clang::BuiltinType::Float:
3310 case clang::BuiltinType::Double:
3311 case clang::BuiltinType::LongDouble:
3312 case clang::BuiltinType::Dependent:
3313 case clang::BuiltinType::Overload:
3314 case clang::BuiltinType::ObjCId:
3315 case clang::BuiltinType::ObjCClass:
3316 case clang::BuiltinType::ObjCSel:
3317 case clang::BuiltinType::BoundMember:
3318 case clang::BuiltinType::Half:
3319 case clang::BuiltinType::ARCUnbridgedCast:
3320 case clang::BuiltinType::PseudoObject:
3321 case clang::BuiltinType::BuiltinFn:
3322 return 1;
3323 }
3324 break;
3325
3326 case clang::Type::Complex: return 1;
3327 case clang::Type::Pointer: return 1;
3328 case clang::Type::BlockPointer: return 0; // If block pointers don't have debug info, then no children for them
3329 case clang::Type::LValueReference: return 1;
3330 case clang::Type::RValueReference: return 1;
3331 case clang::Type::MemberPointer: return 0;
3332 case clang::Type::ConstantArray: return 0;
3333 case clang::Type::IncompleteArray: return 0;
3334 case clang::Type::VariableArray: return 0;
3335 case clang::Type::DependentSizedArray: return 0;
3336 case clang::Type::DependentSizedExtVector: return 0;
3337 case clang::Type::Vector: return 0;
3338 case clang::Type::ExtVector: return 0;
3339 case clang::Type::FunctionProto: return 0; // When we function pointers, they have no children...
3340 case clang::Type::FunctionNoProto: return 0; // When we function pointers, they have no children...
3341 case clang::Type::UnresolvedUsing: return 0;
3342 case clang::Type::Paren: return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetNumPointeeChildren ();
3343 case clang::Type::Typedef: return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumPointeeChildren ();
3344 case clang::Type::Elaborated: return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetNumPointeeChildren ();
3345 case clang::Type::TypeOfExpr: return 0;
3346 case clang::Type::TypeOf: return 0;
3347 case clang::Type::Decltype: return 0;
3348 case clang::Type::Record: return 0;
3349 case clang::Type::Enum: return 1;
3350 case clang::Type::TemplateTypeParm: return 1;
3351 case clang::Type::SubstTemplateTypeParm: return 1;
3352 case clang::Type::TemplateSpecialization: return 1;
3353 case clang::Type::InjectedClassName: return 0;
3354 case clang::Type::DependentName: return 1;
3355 case clang::Type::DependentTemplateSpecialization: return 1;
3356 case clang::Type::ObjCObject: return 0;
3357 case clang::Type::ObjCInterface: return 0;
3358 case clang::Type::ObjCObjectPointer: return 1;
3359 default:
3360 break;
3361 }
3362 return 0;
3363 }
3364
3365
3366 ClangASTType
GetChildClangTypeAtIndex(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) const3367 ClangASTType::GetChildClangTypeAtIndex (ExecutionContext *exe_ctx,
3368 size_t idx,
3369 bool transparent_pointers,
3370 bool omit_empty_base_classes,
3371 bool ignore_array_bounds,
3372 std::string& child_name,
3373 uint32_t &child_byte_size,
3374 int32_t &child_byte_offset,
3375 uint32_t &child_bitfield_bit_size,
3376 uint32_t &child_bitfield_bit_offset,
3377 bool &child_is_base_class,
3378 bool &child_is_deref_of_parent,
3379 ValueObject *valobj) const
3380 {
3381 if (!IsValid())
3382 return ClangASTType();
3383
3384 clang::QualType parent_qual_type(GetCanonicalQualType());
3385 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
3386 child_bitfield_bit_size = 0;
3387 child_bitfield_bit_offset = 0;
3388 child_is_base_class = false;
3389
3390 const bool idx_is_valid = idx < GetNumChildren (omit_empty_base_classes);
3391 uint32_t bit_offset;
3392 switch (parent_type_class)
3393 {
3394 case clang::Type::Builtin:
3395 if (idx_is_valid)
3396 {
3397 switch (llvm::cast<clang::BuiltinType>(parent_qual_type)->getKind())
3398 {
3399 case clang::BuiltinType::ObjCId:
3400 case clang::BuiltinType::ObjCClass:
3401 child_name = "isa";
3402 child_byte_size = m_ast->getTypeSize(m_ast->ObjCBuiltinClassTy) / CHAR_BIT;
3403 return ClangASTType (m_ast, m_ast->ObjCBuiltinClassTy);
3404
3405 default:
3406 break;
3407 }
3408 }
3409 break;
3410
3411 case clang::Type::Record:
3412 if (idx_is_valid && GetCompleteType())
3413 {
3414 const clang::RecordType *record_type = llvm::cast<clang::RecordType>(parent_qual_type.getTypePtr());
3415 const clang::RecordDecl *record_decl = record_type->getDecl();
3416 assert(record_decl);
3417 const clang::ASTRecordLayout &record_layout = m_ast->getASTRecordLayout(record_decl);
3418 uint32_t child_idx = 0;
3419
3420 const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
3421 if (cxx_record_decl)
3422 {
3423 // We might have base classes to print out first
3424 clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3425 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3426 base_class != base_class_end;
3427 ++base_class)
3428 {
3429 const clang::CXXRecordDecl *base_class_decl = nullptr;
3430
3431 // Skip empty base classes
3432 if (omit_empty_base_classes)
3433 {
3434 base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl());
3435 if (ClangASTContext::RecordHasFields(base_class_decl) == false)
3436 continue;
3437 }
3438
3439 if (idx == child_idx)
3440 {
3441 if (base_class_decl == nullptr)
3442 base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl());
3443
3444
3445 if (base_class->isVirtual())
3446 {
3447 bool handled = false;
3448 if (valobj)
3449 {
3450 Error err;
3451 AddressType addr_type = eAddressTypeInvalid;
3452 lldb::addr_t vtable_ptr_addr = valobj->GetCPPVTableAddress(addr_type);
3453
3454 if (vtable_ptr_addr != LLDB_INVALID_ADDRESS && addr_type == eAddressTypeLoad)
3455 {
3456
3457 ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
3458 Process *process = exe_ctx.GetProcessPtr();
3459 if (process)
3460 {
3461 clang::VTableContextBase *vtable_ctx = m_ast->getVTableContext();
3462 if (vtable_ctx)
3463 {
3464 if (vtable_ctx->isMicrosoft())
3465 {
3466 clang::MicrosoftVTableContext *msoft_vtable_ctx = static_cast<clang::MicrosoftVTableContext *>(vtable_ctx);
3467
3468 if (vtable_ptr_addr)
3469 {
3470 const lldb::addr_t vbtable_ptr_addr = vtable_ptr_addr + record_layout.getVBPtrOffset().getQuantity();
3471
3472 const lldb::addr_t vbtable_ptr = process->ReadPointerFromMemory(vbtable_ptr_addr, err);
3473 if (vbtable_ptr != LLDB_INVALID_ADDRESS)
3474 {
3475 // Get the index into the virtual base table. The index is the index in uint32_t from vbtable_ptr
3476 const unsigned vbtable_index = msoft_vtable_ctx->getVBTableIndex(cxx_record_decl, base_class_decl);
3477 const lldb::addr_t base_offset_addr = vbtable_ptr + vbtable_index * 4;
3478 const uint32_t base_offset = process->ReadUnsignedIntegerFromMemory(base_offset_addr, 4, UINT32_MAX, err);
3479 if (base_offset != UINT32_MAX)
3480 {
3481 handled = true;
3482 bit_offset = base_offset * 8;
3483 }
3484 }
3485 }
3486 }
3487 else
3488 {
3489 clang::ItaniumVTableContext *itanium_vtable_ctx = static_cast<clang::ItaniumVTableContext *>(vtable_ctx);
3490 if (vtable_ptr_addr)
3491 {
3492 const lldb::addr_t vtable_ptr = process->ReadPointerFromMemory(vtable_ptr_addr, err);
3493 if (vtable_ptr != LLDB_INVALID_ADDRESS)
3494 {
3495 clang::CharUnits base_offset_offset = itanium_vtable_ctx->getVirtualBaseOffsetOffset(cxx_record_decl, base_class_decl);
3496 const lldb::addr_t base_offset_addr = vtable_ptr + base_offset_offset.getQuantity();
3497 const uint32_t base_offset = process->ReadUnsignedIntegerFromMemory(base_offset_addr, 4, UINT32_MAX, err);
3498 if (base_offset != UINT32_MAX)
3499 {
3500 handled = true;
3501 bit_offset = base_offset * 8;
3502 }
3503 }
3504 }
3505 }
3506 }
3507 }
3508 }
3509
3510 }
3511 if (!handled)
3512 bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
3513 }
3514 else
3515 bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
3516
3517 // Base classes should be a multiple of 8 bits in size
3518 child_byte_offset = bit_offset/8;
3519 ClangASTType base_class_clang_type(m_ast, base_class->getType());
3520 child_name = base_class_clang_type.GetTypeName().AsCString("");
3521 uint64_t base_class_clang_type_bit_size = base_class_clang_type.GetBitSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
3522
3523 // Base classes bit sizes should be a multiple of 8 bits in size
3524 assert (base_class_clang_type_bit_size % 8 == 0);
3525 child_byte_size = base_class_clang_type_bit_size / 8;
3526 child_is_base_class = true;
3527 return base_class_clang_type;
3528 }
3529 // We don't increment the child index in the for loop since we might
3530 // be skipping empty base classes
3531 ++child_idx;
3532 }
3533 }
3534 // Make sure index is in range...
3535 uint32_t field_idx = 0;
3536 clang::RecordDecl::field_iterator field, field_end;
3537 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
3538 {
3539 if (idx == child_idx)
3540 {
3541 // Print the member type if requested
3542 // Print the member name and equal sign
3543 child_name.assign(field->getNameAsString().c_str());
3544
3545 // Figure out the type byte size (field_type_info.first) and
3546 // alignment (field_type_info.second) from the AST context.
3547 ClangASTType field_clang_type (m_ast, field->getType());
3548 assert(field_idx < record_layout.getFieldCount());
3549 child_byte_size = field_clang_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
3550
3551 // Figure out the field offset within the current struct/union/class type
3552 bit_offset = record_layout.getFieldOffset (field_idx);
3553 child_byte_offset = bit_offset / 8;
3554 if (ClangASTContext::FieldIsBitfield (m_ast, *field, child_bitfield_bit_size))
3555 child_bitfield_bit_offset = bit_offset % 8;
3556
3557 return field_clang_type;
3558 }
3559 }
3560 }
3561 break;
3562
3563 case clang::Type::ObjCObject:
3564 case clang::Type::ObjCInterface:
3565 if (idx_is_valid && GetCompleteType())
3566 {
3567 const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(parent_qual_type.getTypePtr());
3568 assert (objc_class_type);
3569 if (objc_class_type)
3570 {
3571 uint32_t child_idx = 0;
3572 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
3573
3574 if (class_interface_decl)
3575 {
3576
3577 const clang::ASTRecordLayout &interface_layout = m_ast->getASTObjCInterfaceLayout(class_interface_decl);
3578 clang::ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
3579 if (superclass_interface_decl)
3580 {
3581 if (omit_empty_base_classes)
3582 {
3583 ClangASTType base_class_clang_type (m_ast, m_ast->getObjCInterfaceType(superclass_interface_decl));
3584 if (base_class_clang_type.GetNumChildren(omit_empty_base_classes) > 0)
3585 {
3586 if (idx == 0)
3587 {
3588 clang::QualType ivar_qual_type(m_ast->getObjCInterfaceType(superclass_interface_decl));
3589
3590
3591 child_name.assign(superclass_interface_decl->getNameAsString().c_str());
3592
3593 clang::TypeInfo ivar_type_info = m_ast->getTypeInfo(ivar_qual_type.getTypePtr());
3594
3595 child_byte_size = ivar_type_info.Width / 8;
3596 child_byte_offset = 0;
3597 child_is_base_class = true;
3598
3599 return ClangASTType (m_ast, ivar_qual_type);
3600 }
3601
3602 ++child_idx;
3603 }
3604 }
3605 else
3606 ++child_idx;
3607 }
3608
3609 const uint32_t superclass_idx = child_idx;
3610
3611 if (idx < (child_idx + class_interface_decl->ivar_size()))
3612 {
3613 clang::ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
3614
3615 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
3616 {
3617 if (child_idx == idx)
3618 {
3619 clang::ObjCIvarDecl* ivar_decl = *ivar_pos;
3620
3621 clang::QualType ivar_qual_type(ivar_decl->getType());
3622
3623 child_name.assign(ivar_decl->getNameAsString().c_str());
3624
3625 clang::TypeInfo ivar_type_info = m_ast->getTypeInfo(ivar_qual_type.getTypePtr());
3626
3627 child_byte_size = ivar_type_info.Width / 8;
3628
3629 // Figure out the field offset within the current struct/union/class type
3630 // For ObjC objects, we can't trust the bit offset we get from the Clang AST, since
3631 // that doesn't account for the space taken up by unbacked properties, or from
3632 // the changing size of base classes that are newer than this class.
3633 // So if we have a process around that we can ask about this object, do so.
3634 child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
3635 Process *process = nullptr;
3636 if (exe_ctx)
3637 process = exe_ctx->GetProcessPtr();
3638 if (process)
3639 {
3640 ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
3641 if (objc_runtime != nullptr)
3642 {
3643 ClangASTType parent_ast_type (m_ast, parent_qual_type);
3644 child_byte_offset = objc_runtime->GetByteOffsetForIvar (parent_ast_type, ivar_decl->getNameAsString().c_str());
3645 }
3646 }
3647
3648 // Setting this to UINT32_MAX to make sure we don't compute it twice...
3649 bit_offset = UINT32_MAX;
3650
3651 if (child_byte_offset == static_cast<int32_t>(LLDB_INVALID_IVAR_OFFSET))
3652 {
3653 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
3654 child_byte_offset = bit_offset / 8;
3655 }
3656
3657 // Note, the ObjC Ivar Byte offset is just that, it doesn't account for the bit offset
3658 // of a bitfield within its containing object. So regardless of where we get the byte
3659 // offset from, we still need to get the bit offset for bitfields from the layout.
3660
3661 if (ClangASTContext::FieldIsBitfield (m_ast, ivar_decl, child_bitfield_bit_size))
3662 {
3663 if (bit_offset == UINT32_MAX)
3664 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
3665
3666 child_bitfield_bit_offset = bit_offset % 8;
3667 }
3668 return ClangASTType (m_ast, ivar_qual_type);
3669 }
3670 ++child_idx;
3671 }
3672 }
3673 }
3674 }
3675 }
3676 break;
3677
3678 case clang::Type::ObjCObjectPointer:
3679 if (idx_is_valid)
3680 {
3681 ClangASTType pointee_clang_type (GetPointeeType());
3682
3683 if (transparent_pointers && pointee_clang_type.IsAggregateType())
3684 {
3685 child_is_deref_of_parent = false;
3686 bool tmp_child_is_deref_of_parent = false;
3687 return pointee_clang_type.GetChildClangTypeAtIndex (exe_ctx,
3688 idx,
3689 transparent_pointers,
3690 omit_empty_base_classes,
3691 ignore_array_bounds,
3692 child_name,
3693 child_byte_size,
3694 child_byte_offset,
3695 child_bitfield_bit_size,
3696 child_bitfield_bit_offset,
3697 child_is_base_class,
3698 tmp_child_is_deref_of_parent,
3699 valobj);
3700 }
3701 else
3702 {
3703 child_is_deref_of_parent = true;
3704 const char *parent_name = valobj ? valobj->GetName().GetCString() : NULL;
3705 if (parent_name)
3706 {
3707 child_name.assign(1, '*');
3708 child_name += parent_name;
3709 }
3710
3711 // We have a pointer to an simple type
3712 if (idx == 0 && pointee_clang_type.GetCompleteType())
3713 {
3714 child_byte_size = pointee_clang_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
3715 child_byte_offset = 0;
3716 return pointee_clang_type;
3717 }
3718 }
3719 }
3720 break;
3721
3722 case clang::Type::Vector:
3723 case clang::Type::ExtVector:
3724 if (idx_is_valid)
3725 {
3726 const clang::VectorType *array = llvm::cast<clang::VectorType>(parent_qual_type.getTypePtr());
3727 if (array)
3728 {
3729 ClangASTType element_type (m_ast, array->getElementType());
3730 if (element_type.GetCompleteType())
3731 {
3732 char element_name[64];
3733 ::snprintf(element_name, sizeof(element_name), "[%" PRIu64 "]", static_cast<uint64_t>(idx));
3734 child_name.assign(element_name);
3735 child_byte_size = element_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
3736 child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
3737 return element_type;
3738 }
3739 }
3740 }
3741 break;
3742
3743 case clang::Type::ConstantArray:
3744 case clang::Type::IncompleteArray:
3745 if (ignore_array_bounds || idx_is_valid)
3746 {
3747 const clang::ArrayType *array = GetQualType()->getAsArrayTypeUnsafe();
3748 if (array)
3749 {
3750 ClangASTType element_type (m_ast, array->getElementType());
3751 if (element_type.GetCompleteType())
3752 {
3753 char element_name[64];
3754 ::snprintf(element_name, sizeof(element_name), "[%" PRIu64 "]", static_cast<uint64_t>(idx));
3755 child_name.assign(element_name);
3756 child_byte_size = element_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
3757 child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
3758 return element_type;
3759 }
3760 }
3761 }
3762 break;
3763
3764
3765 case clang::Type::Pointer:
3766 if (idx_is_valid)
3767 {
3768 ClangASTType pointee_clang_type (GetPointeeType());
3769
3770 // Don't dereference "void *" pointers
3771 if (pointee_clang_type.IsVoidType())
3772 return ClangASTType();
3773
3774 if (transparent_pointers && pointee_clang_type.IsAggregateType ())
3775 {
3776 child_is_deref_of_parent = false;
3777 bool tmp_child_is_deref_of_parent = false;
3778 return pointee_clang_type.GetChildClangTypeAtIndex (exe_ctx,
3779 idx,
3780 transparent_pointers,
3781 omit_empty_base_classes,
3782 ignore_array_bounds,
3783 child_name,
3784 child_byte_size,
3785 child_byte_offset,
3786 child_bitfield_bit_size,
3787 child_bitfield_bit_offset,
3788 child_is_base_class,
3789 tmp_child_is_deref_of_parent,
3790 valobj);
3791 }
3792 else
3793 {
3794 child_is_deref_of_parent = true;
3795
3796 const char *parent_name = valobj ? valobj->GetName().GetCString() : NULL;
3797 if (parent_name)
3798 {
3799 child_name.assign(1, '*');
3800 child_name += parent_name;
3801 }
3802
3803 // We have a pointer to an simple type
3804 if (idx == 0)
3805 {
3806 child_byte_size = pointee_clang_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
3807 child_byte_offset = 0;
3808 return pointee_clang_type;
3809 }
3810 }
3811 }
3812 break;
3813
3814 case clang::Type::LValueReference:
3815 case clang::Type::RValueReference:
3816 if (idx_is_valid)
3817 {
3818 const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(parent_qual_type.getTypePtr());
3819 ClangASTType pointee_clang_type (m_ast, reference_type->getPointeeType());
3820 if (transparent_pointers && pointee_clang_type.IsAggregateType ())
3821 {
3822 child_is_deref_of_parent = false;
3823 bool tmp_child_is_deref_of_parent = false;
3824 return pointee_clang_type.GetChildClangTypeAtIndex (exe_ctx,
3825 idx,
3826 transparent_pointers,
3827 omit_empty_base_classes,
3828 ignore_array_bounds,
3829 child_name,
3830 child_byte_size,
3831 child_byte_offset,
3832 child_bitfield_bit_size,
3833 child_bitfield_bit_offset,
3834 child_is_base_class,
3835 tmp_child_is_deref_of_parent,
3836 valobj);
3837 }
3838 else
3839 {
3840 const char *parent_name = valobj ? valobj->GetName().GetCString() : NULL;
3841 if (parent_name)
3842 {
3843 child_name.assign(1, '&');
3844 child_name += parent_name;
3845 }
3846
3847 // We have a pointer to an simple type
3848 if (idx == 0)
3849 {
3850 child_byte_size = pointee_clang_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
3851 child_byte_offset = 0;
3852 return pointee_clang_type;
3853 }
3854 }
3855 }
3856 break;
3857
3858 case clang::Type::Typedef:
3859 {
3860 ClangASTType typedefed_clang_type (m_ast, llvm::cast<clang::TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType());
3861 return typedefed_clang_type.GetChildClangTypeAtIndex (exe_ctx,
3862 idx,
3863 transparent_pointers,
3864 omit_empty_base_classes,
3865 ignore_array_bounds,
3866 child_name,
3867 child_byte_size,
3868 child_byte_offset,
3869 child_bitfield_bit_size,
3870 child_bitfield_bit_offset,
3871 child_is_base_class,
3872 child_is_deref_of_parent,
3873 valobj);
3874 }
3875 break;
3876
3877 case clang::Type::Elaborated:
3878 {
3879 ClangASTType elaborated_clang_type (m_ast, llvm::cast<clang::ElaboratedType>(parent_qual_type)->getNamedType());
3880 return elaborated_clang_type.GetChildClangTypeAtIndex (exe_ctx,
3881 idx,
3882 transparent_pointers,
3883 omit_empty_base_classes,
3884 ignore_array_bounds,
3885 child_name,
3886 child_byte_size,
3887 child_byte_offset,
3888 child_bitfield_bit_size,
3889 child_bitfield_bit_offset,
3890 child_is_base_class,
3891 child_is_deref_of_parent,
3892 valobj);
3893 }
3894
3895 case clang::Type::Paren:
3896 {
3897 ClangASTType paren_clang_type (m_ast, llvm::cast<clang::ParenType>(parent_qual_type)->desugar());
3898 return paren_clang_type.GetChildClangTypeAtIndex (exe_ctx,
3899 idx,
3900 transparent_pointers,
3901 omit_empty_base_classes,
3902 ignore_array_bounds,
3903 child_name,
3904 child_byte_size,
3905 child_byte_offset,
3906 child_bitfield_bit_size,
3907 child_bitfield_bit_offset,
3908 child_is_base_class,
3909 child_is_deref_of_parent,
3910 valobj);
3911 }
3912
3913
3914 default:
3915 break;
3916 }
3917 return ClangASTType();
3918 }
3919
3920 static inline bool
BaseSpecifierIsEmpty(const clang::CXXBaseSpecifier * b)3921 BaseSpecifierIsEmpty (const clang::CXXBaseSpecifier *b)
3922 {
3923 return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false;
3924 }
3925
3926 static uint32_t
GetIndexForRecordBase(const clang::RecordDecl * record_decl,const clang::CXXBaseSpecifier * base_spec,bool omit_empty_base_classes)3927 GetIndexForRecordBase
3928 (
3929 const clang::RecordDecl *record_decl,
3930 const clang::CXXBaseSpecifier *base_spec,
3931 bool omit_empty_base_classes
3932 )
3933 {
3934 uint32_t child_idx = 0;
3935
3936 const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
3937
3938 // const char *super_name = record_decl->getNameAsCString();
3939 // const char *base_name = base_spec->getType()->getAs<clang::RecordType>()->getDecl()->getNameAsCString();
3940 // printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
3941 //
3942 if (cxx_record_decl)
3943 {
3944 clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
3945 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
3946 base_class != base_class_end;
3947 ++base_class)
3948 {
3949 if (omit_empty_base_classes)
3950 {
3951 if (BaseSpecifierIsEmpty (base_class))
3952 continue;
3953 }
3954
3955 // printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
3956 // child_idx,
3957 // base_class->getType()->getAs<clang::RecordType>()->getDecl()->getNameAsCString());
3958 //
3959 //
3960 if (base_class == base_spec)
3961 return child_idx;
3962 ++child_idx;
3963 }
3964 }
3965
3966 return UINT32_MAX;
3967 }
3968
3969
3970 static uint32_t
GetIndexForRecordChild(const clang::RecordDecl * record_decl,clang::NamedDecl * canonical_decl,bool omit_empty_base_classes)3971 GetIndexForRecordChild (const clang::RecordDecl *record_decl,
3972 clang::NamedDecl *canonical_decl,
3973 bool omit_empty_base_classes)
3974 {
3975 uint32_t child_idx = ClangASTContext::GetNumBaseClasses (llvm::dyn_cast<clang::CXXRecordDecl>(record_decl),
3976 omit_empty_base_classes);
3977
3978 clang::RecordDecl::field_iterator field, field_end;
3979 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
3980 field != field_end;
3981 ++field, ++child_idx)
3982 {
3983 if (field->getCanonicalDecl() == canonical_decl)
3984 return child_idx;
3985 }
3986
3987 return UINT32_MAX;
3988 }
3989
3990 // Look for a child member (doesn't include base classes, but it does include
3991 // their members) in the type hierarchy. Returns an index path into "clang_type"
3992 // on how to reach the appropriate member.
3993 //
3994 // class A
3995 // {
3996 // public:
3997 // int m_a;
3998 // int m_b;
3999 // };
4000 //
4001 // class B
4002 // {
4003 // };
4004 //
4005 // class C :
4006 // public B,
4007 // public A
4008 // {
4009 // };
4010 //
4011 // If we have a clang type that describes "class C", and we wanted to looked
4012 // "m_b" in it:
4013 //
4014 // With omit_empty_base_classes == false we would get an integer array back with:
4015 // { 1, 1 }
4016 // The first index 1 is the child index for "class A" within class C
4017 // The second index 1 is the child index for "m_b" within class A
4018 //
4019 // With omit_empty_base_classes == true we would get an integer array back with:
4020 // { 0, 1 }
4021 // The first index 0 is the child index for "class A" within class C (since class B doesn't have any members it doesn't count)
4022 // The second index 1 is the child index for "m_b" within class A
4023
4024 size_t
GetIndexOfChildMemberWithName(const char * name,bool omit_empty_base_classes,std::vector<uint32_t> & child_indexes) const4025 ClangASTType::GetIndexOfChildMemberWithName (const char *name,
4026 bool omit_empty_base_classes,
4027 std::vector<uint32_t>& child_indexes) const
4028 {
4029 if (IsValid() && name && name[0])
4030 {
4031 clang::QualType qual_type(GetCanonicalQualType());
4032 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4033 switch (type_class)
4034 {
4035 case clang::Type::Record:
4036 if (GetCompleteType ())
4037 {
4038 const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
4039 const clang::RecordDecl *record_decl = record_type->getDecl();
4040
4041 assert(record_decl);
4042 uint32_t child_idx = 0;
4043
4044 const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
4045
4046 // Try and find a field that matches NAME
4047 clang::RecordDecl::field_iterator field, field_end;
4048 llvm::StringRef name_sref(name);
4049 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
4050 field != field_end;
4051 ++field, ++child_idx)
4052 {
4053 llvm::StringRef field_name = field->getName();
4054 if (field_name.empty())
4055 {
4056 ClangASTType field_type(m_ast,field->getType());
4057 child_indexes.push_back(child_idx);
4058 if (field_type.GetIndexOfChildMemberWithName(name, omit_empty_base_classes, child_indexes))
4059 return child_indexes.size();
4060 child_indexes.pop_back();
4061
4062 }
4063 else if (field_name.equals (name_sref))
4064 {
4065 // We have to add on the number of base classes to this index!
4066 child_indexes.push_back (child_idx + ClangASTContext::GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
4067 return child_indexes.size();
4068 }
4069 }
4070
4071 if (cxx_record_decl)
4072 {
4073 const clang::RecordDecl *parent_record_decl = cxx_record_decl;
4074
4075 //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
4076
4077 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
4078 // Didn't find things easily, lets let clang do its thang...
4079 clang::IdentifierInfo & ident_ref = m_ast->Idents.get(name_sref);
4080 clang::DeclarationName decl_name(&ident_ref);
4081
4082 clang::CXXBasePaths paths;
4083 if (cxx_record_decl->lookupInBases(clang::CXXRecordDecl::FindOrdinaryMember,
4084 decl_name.getAsOpaquePtr(),
4085 paths))
4086 {
4087 clang::CXXBasePaths::const_paths_iterator path, path_end = paths.end();
4088 for (path = paths.begin(); path != path_end; ++path)
4089 {
4090 const size_t num_path_elements = path->size();
4091 for (size_t e=0; e<num_path_elements; ++e)
4092 {
4093 clang::CXXBasePathElement elem = (*path)[e];
4094
4095 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
4096 if (child_idx == UINT32_MAX)
4097 {
4098 child_indexes.clear();
4099 return 0;
4100 }
4101 else
4102 {
4103 child_indexes.push_back (child_idx);
4104 parent_record_decl = llvm::cast<clang::RecordDecl>(elem.Base->getType()->getAs<clang::RecordType>()->getDecl());
4105 }
4106 }
4107 for (clang::NamedDecl *path_decl : path->Decls)
4108 {
4109 child_idx = GetIndexForRecordChild (parent_record_decl, path_decl, omit_empty_base_classes);
4110 if (child_idx == UINT32_MAX)
4111 {
4112 child_indexes.clear();
4113 return 0;
4114 }
4115 else
4116 {
4117 child_indexes.push_back (child_idx);
4118 }
4119 }
4120 }
4121 return child_indexes.size();
4122 }
4123 }
4124
4125 }
4126 break;
4127
4128 case clang::Type::ObjCObject:
4129 case clang::Type::ObjCInterface:
4130 if (GetCompleteType ())
4131 {
4132 llvm::StringRef name_sref(name);
4133 const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
4134 assert (objc_class_type);
4135 if (objc_class_type)
4136 {
4137 uint32_t child_idx = 0;
4138 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
4139
4140 if (class_interface_decl)
4141 {
4142 clang::ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
4143 clang::ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
4144
4145 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
4146 {
4147 const clang::ObjCIvarDecl* ivar_decl = *ivar_pos;
4148
4149 if (ivar_decl->getName().equals (name_sref))
4150 {
4151 if ((!omit_empty_base_classes && superclass_interface_decl) ||
4152 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
4153 ++child_idx;
4154
4155 child_indexes.push_back (child_idx);
4156 return child_indexes.size();
4157 }
4158 }
4159
4160 if (superclass_interface_decl)
4161 {
4162 // The super class index is always zero for ObjC classes,
4163 // so we push it onto the child indexes in case we find
4164 // an ivar in our superclass...
4165 child_indexes.push_back (0);
4166
4167 ClangASTType superclass_clang_type (m_ast, m_ast->getObjCInterfaceType(superclass_interface_decl));
4168 if (superclass_clang_type.GetIndexOfChildMemberWithName (name,
4169 omit_empty_base_classes,
4170 child_indexes))
4171 {
4172 // We did find an ivar in a superclass so just
4173 // return the results!
4174 return child_indexes.size();
4175 }
4176
4177 // We didn't find an ivar matching "name" in our
4178 // superclass, pop the superclass zero index that
4179 // we pushed on above.
4180 child_indexes.pop_back();
4181 }
4182 }
4183 }
4184 }
4185 break;
4186
4187 case clang::Type::ObjCObjectPointer:
4188 {
4189 ClangASTType objc_object_clang_type (m_ast, llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType());
4190 return objc_object_clang_type.GetIndexOfChildMemberWithName (name,
4191 omit_empty_base_classes,
4192 child_indexes);
4193 }
4194 break;
4195
4196
4197 case clang::Type::ConstantArray:
4198 {
4199 // const clang::ConstantArrayType *array = llvm::cast<clang::ConstantArrayType>(parent_qual_type.getTypePtr());
4200 // const uint64_t element_count = array->getSize().getLimitedValue();
4201 //
4202 // if (idx < element_count)
4203 // {
4204 // std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
4205 //
4206 // char element_name[32];
4207 // ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
4208 //
4209 // child_name.assign(element_name);
4210 // assert(field_type_info.first % 8 == 0);
4211 // child_byte_size = field_type_info.first / 8;
4212 // child_byte_offset = idx * child_byte_size;
4213 // return array->getElementType().getAsOpaquePtr();
4214 // }
4215 }
4216 break;
4217
4218 // case clang::Type::MemberPointerType:
4219 // {
4220 // MemberPointerType *mem_ptr_type = llvm::cast<MemberPointerType>(qual_type.getTypePtr());
4221 // clang::QualType pointee_type = mem_ptr_type->getPointeeType();
4222 //
4223 // if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
4224 // {
4225 // return GetIndexOfChildWithName (ast,
4226 // mem_ptr_type->getPointeeType().getAsOpaquePtr(),
4227 // name);
4228 // }
4229 // }
4230 // break;
4231 //
4232 case clang::Type::LValueReference:
4233 case clang::Type::RValueReference:
4234 {
4235 const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
4236 clang::QualType pointee_type(reference_type->getPointeeType());
4237 ClangASTType pointee_clang_type (m_ast, pointee_type);
4238
4239 if (pointee_clang_type.IsAggregateType ())
4240 {
4241 return pointee_clang_type.GetIndexOfChildMemberWithName (name,
4242 omit_empty_base_classes,
4243 child_indexes);
4244 }
4245 }
4246 break;
4247
4248 case clang::Type::Pointer:
4249 {
4250 ClangASTType pointee_clang_type (GetPointeeType());
4251
4252 if (pointee_clang_type.IsAggregateType ())
4253 {
4254 return pointee_clang_type.GetIndexOfChildMemberWithName (name,
4255 omit_empty_base_classes,
4256 child_indexes);
4257 }
4258 }
4259 break;
4260
4261 case clang::Type::Typedef:
4262 return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetIndexOfChildMemberWithName (name,
4263 omit_empty_base_classes,
4264 child_indexes);
4265
4266 case clang::Type::Elaborated:
4267 return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetIndexOfChildMemberWithName (name,
4268 omit_empty_base_classes,
4269 child_indexes);
4270
4271 case clang::Type::Paren:
4272 return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetIndexOfChildMemberWithName (name,
4273 omit_empty_base_classes,
4274 child_indexes);
4275
4276 default:
4277 break;
4278 }
4279 }
4280 return 0;
4281 }
4282
4283
4284 // Get the index of the child of "clang_type" whose name matches. This function
4285 // doesn't descend into the children, but only looks one level deep and name
4286 // matches can include base class names.
4287
4288 uint32_t
GetIndexOfChildWithName(const char * name,bool omit_empty_base_classes) const4289 ClangASTType::GetIndexOfChildWithName (const char *name, bool omit_empty_base_classes) const
4290 {
4291 if (IsValid() && name && name[0])
4292 {
4293 clang::QualType qual_type(GetCanonicalQualType());
4294
4295 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4296
4297 switch (type_class)
4298 {
4299 case clang::Type::Record:
4300 if (GetCompleteType ())
4301 {
4302 const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
4303 const clang::RecordDecl *record_decl = record_type->getDecl();
4304
4305 assert(record_decl);
4306 uint32_t child_idx = 0;
4307
4308 const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
4309
4310 if (cxx_record_decl)
4311 {
4312 clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
4313 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
4314 base_class != base_class_end;
4315 ++base_class)
4316 {
4317 // Skip empty base classes
4318 clang::CXXRecordDecl *base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl());
4319 if (omit_empty_base_classes && ClangASTContext::RecordHasFields(base_class_decl) == false)
4320 continue;
4321
4322 ClangASTType base_class_clang_type (m_ast, base_class->getType());
4323 std::string base_class_type_name (base_class_clang_type.GetTypeName().AsCString(""));
4324 if (base_class_type_name.compare (name) == 0)
4325 return child_idx;
4326 ++child_idx;
4327 }
4328 }
4329
4330 // Try and find a field that matches NAME
4331 clang::RecordDecl::field_iterator field, field_end;
4332 llvm::StringRef name_sref(name);
4333 for (field = record_decl->field_begin(), field_end = record_decl->field_end();
4334 field != field_end;
4335 ++field, ++child_idx)
4336 {
4337 if (field->getName().equals (name_sref))
4338 return child_idx;
4339 }
4340
4341 }
4342 break;
4343
4344 case clang::Type::ObjCObject:
4345 case clang::Type::ObjCInterface:
4346 if (GetCompleteType())
4347 {
4348 llvm::StringRef name_sref(name);
4349 const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
4350 assert (objc_class_type);
4351 if (objc_class_type)
4352 {
4353 uint32_t child_idx = 0;
4354 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
4355
4356 if (class_interface_decl)
4357 {
4358 clang::ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
4359 clang::ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
4360
4361 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
4362 {
4363 const clang::ObjCIvarDecl* ivar_decl = *ivar_pos;
4364
4365 if (ivar_decl->getName().equals (name_sref))
4366 {
4367 if ((!omit_empty_base_classes && superclass_interface_decl) ||
4368 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
4369 ++child_idx;
4370
4371 return child_idx;
4372 }
4373 }
4374
4375 if (superclass_interface_decl)
4376 {
4377 if (superclass_interface_decl->getName().equals (name_sref))
4378 return 0;
4379 }
4380 }
4381 }
4382 }
4383 break;
4384
4385 case clang::Type::ObjCObjectPointer:
4386 {
4387 ClangASTType pointee_clang_type (m_ast, llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType());
4388 return pointee_clang_type.GetIndexOfChildWithName (name, omit_empty_base_classes);
4389 }
4390 break;
4391
4392 case clang::Type::ConstantArray:
4393 {
4394 // const clang::ConstantArrayType *array = llvm::cast<clang::ConstantArrayType>(parent_qual_type.getTypePtr());
4395 // const uint64_t element_count = array->getSize().getLimitedValue();
4396 //
4397 // if (idx < element_count)
4398 // {
4399 // std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
4400 //
4401 // char element_name[32];
4402 // ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
4403 //
4404 // child_name.assign(element_name);
4405 // assert(field_type_info.first % 8 == 0);
4406 // child_byte_size = field_type_info.first / 8;
4407 // child_byte_offset = idx * child_byte_size;
4408 // return array->getElementType().getAsOpaquePtr();
4409 // }
4410 }
4411 break;
4412
4413 // case clang::Type::MemberPointerType:
4414 // {
4415 // MemberPointerType *mem_ptr_type = llvm::cast<MemberPointerType>(qual_type.getTypePtr());
4416 // clang::QualType pointee_type = mem_ptr_type->getPointeeType();
4417 //
4418 // if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
4419 // {
4420 // return GetIndexOfChildWithName (ast,
4421 // mem_ptr_type->getPointeeType().getAsOpaquePtr(),
4422 // name);
4423 // }
4424 // }
4425 // break;
4426 //
4427 case clang::Type::LValueReference:
4428 case clang::Type::RValueReference:
4429 {
4430 const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
4431 ClangASTType pointee_type (m_ast, reference_type->getPointeeType());
4432
4433 if (pointee_type.IsAggregateType ())
4434 {
4435 return pointee_type.GetIndexOfChildWithName (name, omit_empty_base_classes);
4436 }
4437 }
4438 break;
4439
4440 case clang::Type::Pointer:
4441 {
4442 const clang::PointerType *pointer_type = llvm::cast<clang::PointerType>(qual_type.getTypePtr());
4443 ClangASTType pointee_type (m_ast, pointer_type->getPointeeType());
4444
4445 if (pointee_type.IsAggregateType ())
4446 {
4447 return pointee_type.GetIndexOfChildWithName (name, omit_empty_base_classes);
4448 }
4449 else
4450 {
4451 // if (parent_name)
4452 // {
4453 // child_name.assign(1, '*');
4454 // child_name += parent_name;
4455 // }
4456 //
4457 // // We have a pointer to an simple type
4458 // if (idx == 0)
4459 // {
4460 // std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
4461 // assert(clang_type_info.first % 8 == 0);
4462 // child_byte_size = clang_type_info.first / 8;
4463 // child_byte_offset = 0;
4464 // return pointee_type.getAsOpaquePtr();
4465 // }
4466 }
4467 }
4468 break;
4469
4470 case clang::Type::Elaborated:
4471 return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetIndexOfChildWithName (name, omit_empty_base_classes);
4472
4473 case clang::Type::Paren:
4474 return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetIndexOfChildWithName (name, omit_empty_base_classes);
4475
4476 case clang::Type::Typedef:
4477 return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetIndexOfChildWithName (name, omit_empty_base_classes);
4478
4479 default:
4480 break;
4481 }
4482 }
4483 return UINT32_MAX;
4484 }
4485
4486
4487 size_t
GetNumTemplateArguments() const4488 ClangASTType::GetNumTemplateArguments () const
4489 {
4490 if (IsValid())
4491 {
4492 clang::QualType qual_type (GetCanonicalQualType());
4493
4494 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4495 switch (type_class)
4496 {
4497 case clang::Type::Record:
4498 if (GetCompleteType ())
4499 {
4500 const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
4501 if (cxx_record_decl)
4502 {
4503 const clang::ClassTemplateSpecializationDecl *template_decl = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(cxx_record_decl);
4504 if (template_decl)
4505 return template_decl->getTemplateArgs().size();
4506 }
4507 }
4508 break;
4509
4510 case clang::Type::Typedef:
4511 return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumTemplateArguments();
4512
4513 case clang::Type::Elaborated:
4514 return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetNumTemplateArguments();
4515
4516 case clang::Type::Paren:
4517 return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetNumTemplateArguments();
4518
4519 default:
4520 break;
4521 }
4522 }
4523 return 0;
4524 }
4525
4526 ClangASTType
GetTemplateArgument(size_t arg_idx,lldb::TemplateArgumentKind & kind) const4527 ClangASTType::GetTemplateArgument (size_t arg_idx, lldb::TemplateArgumentKind &kind) const
4528 {
4529 if (IsValid())
4530 {
4531 clang::QualType qual_type (GetCanonicalQualType());
4532
4533 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
4534 switch (type_class)
4535 {
4536 case clang::Type::Record:
4537 if (GetCompleteType ())
4538 {
4539 const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
4540 if (cxx_record_decl)
4541 {
4542 const clang::ClassTemplateSpecializationDecl *template_decl = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(cxx_record_decl);
4543 if (template_decl && arg_idx < template_decl->getTemplateArgs().size())
4544 {
4545 const clang::TemplateArgument &template_arg = template_decl->getTemplateArgs()[arg_idx];
4546 switch (template_arg.getKind())
4547 {
4548 case clang::TemplateArgument::Null:
4549 kind = eTemplateArgumentKindNull;
4550 return ClangASTType();
4551
4552 case clang::TemplateArgument::Type:
4553 kind = eTemplateArgumentKindType;
4554 return ClangASTType(m_ast, template_arg.getAsType());
4555
4556 case clang::TemplateArgument::Declaration:
4557 kind = eTemplateArgumentKindDeclaration;
4558 return ClangASTType();
4559
4560 case clang::TemplateArgument::Integral:
4561 kind = eTemplateArgumentKindIntegral;
4562 return ClangASTType(m_ast, template_arg.getIntegralType());
4563
4564 case clang::TemplateArgument::Template:
4565 kind = eTemplateArgumentKindTemplate;
4566 return ClangASTType();
4567
4568 case clang::TemplateArgument::TemplateExpansion:
4569 kind = eTemplateArgumentKindTemplateExpansion;
4570 return ClangASTType();
4571
4572 case clang::TemplateArgument::Expression:
4573 kind = eTemplateArgumentKindExpression;
4574 return ClangASTType();
4575
4576 case clang::TemplateArgument::Pack:
4577 kind = eTemplateArgumentKindPack;
4578 return ClangASTType();
4579
4580 default:
4581 assert (!"Unhandled clang::TemplateArgument::ArgKind");
4582 break;
4583 }
4584 }
4585 }
4586 }
4587 break;
4588
4589 case clang::Type::Typedef:
4590 return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetTemplateArgument (arg_idx, kind);
4591
4592 case clang::Type::Elaborated:
4593 return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetTemplateArgument (arg_idx, kind);
4594
4595 case clang::Type::Paren:
4596 return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetTemplateArgument (arg_idx, kind);
4597
4598 default:
4599 break;
4600 }
4601 }
4602 kind = eTemplateArgumentKindNull;
4603 return ClangASTType ();
4604 }
4605
4606 static bool
IsOperator(const char * name,clang::OverloadedOperatorKind & op_kind)4607 IsOperator (const char *name, clang::OverloadedOperatorKind &op_kind)
4608 {
4609 if (name == nullptr || name[0] == '\0')
4610 return false;
4611
4612 #define OPERATOR_PREFIX "operator"
4613 #define OPERATOR_PREFIX_LENGTH (sizeof (OPERATOR_PREFIX) - 1)
4614
4615 const char *post_op_name = nullptr;
4616
4617 bool no_space = true;
4618
4619 if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH))
4620 return false;
4621
4622 post_op_name = name + OPERATOR_PREFIX_LENGTH;
4623
4624 if (post_op_name[0] == ' ')
4625 {
4626 post_op_name++;
4627 no_space = false;
4628 }
4629
4630 #undef OPERATOR_PREFIX
4631 #undef OPERATOR_PREFIX_LENGTH
4632
4633 // This is an operator, set the overloaded operator kind to invalid
4634 // in case this is a conversion operator...
4635 op_kind = clang::NUM_OVERLOADED_OPERATORS;
4636
4637 switch (post_op_name[0])
4638 {
4639 default:
4640 if (no_space)
4641 return false;
4642 break;
4643 case 'n':
4644 if (no_space)
4645 return false;
4646 if (strcmp (post_op_name, "new") == 0)
4647 op_kind = clang::OO_New;
4648 else if (strcmp (post_op_name, "new[]") == 0)
4649 op_kind = clang::OO_Array_New;
4650 break;
4651
4652 case 'd':
4653 if (no_space)
4654 return false;
4655 if (strcmp (post_op_name, "delete") == 0)
4656 op_kind = clang::OO_Delete;
4657 else if (strcmp (post_op_name, "delete[]") == 0)
4658 op_kind = clang::OO_Array_Delete;
4659 break;
4660
4661 case '+':
4662 if (post_op_name[1] == '\0')
4663 op_kind = clang::OO_Plus;
4664 else if (post_op_name[2] == '\0')
4665 {
4666 if (post_op_name[1] == '=')
4667 op_kind = clang::OO_PlusEqual;
4668 else if (post_op_name[1] == '+')
4669 op_kind = clang::OO_PlusPlus;
4670 }
4671 break;
4672
4673 case '-':
4674 if (post_op_name[1] == '\0')
4675 op_kind = clang::OO_Minus;
4676 else if (post_op_name[2] == '\0')
4677 {
4678 switch (post_op_name[1])
4679 {
4680 case '=': op_kind = clang::OO_MinusEqual; break;
4681 case '-': op_kind = clang::OO_MinusMinus; break;
4682 case '>': op_kind = clang::OO_Arrow; break;
4683 }
4684 }
4685 else if (post_op_name[3] == '\0')
4686 {
4687 if (post_op_name[2] == '*')
4688 op_kind = clang::OO_ArrowStar; break;
4689 }
4690 break;
4691
4692 case '*':
4693 if (post_op_name[1] == '\0')
4694 op_kind = clang::OO_Star;
4695 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
4696 op_kind = clang::OO_StarEqual;
4697 break;
4698
4699 case '/':
4700 if (post_op_name[1] == '\0')
4701 op_kind = clang::OO_Slash;
4702 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
4703 op_kind = clang::OO_SlashEqual;
4704 break;
4705
4706 case '%':
4707 if (post_op_name[1] == '\0')
4708 op_kind = clang::OO_Percent;
4709 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
4710 op_kind = clang::OO_PercentEqual;
4711 break;
4712
4713
4714 case '^':
4715 if (post_op_name[1] == '\0')
4716 op_kind = clang::OO_Caret;
4717 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
4718 op_kind = clang::OO_CaretEqual;
4719 break;
4720
4721 case '&':
4722 if (post_op_name[1] == '\0')
4723 op_kind = clang::OO_Amp;
4724 else if (post_op_name[2] == '\0')
4725 {
4726 switch (post_op_name[1])
4727 {
4728 case '=': op_kind = clang::OO_AmpEqual; break;
4729 case '&': op_kind = clang::OO_AmpAmp; break;
4730 }
4731 }
4732 break;
4733
4734 case '|':
4735 if (post_op_name[1] == '\0')
4736 op_kind = clang::OO_Pipe;
4737 else if (post_op_name[2] == '\0')
4738 {
4739 switch (post_op_name[1])
4740 {
4741 case '=': op_kind = clang::OO_PipeEqual; break;
4742 case '|': op_kind = clang::OO_PipePipe; break;
4743 }
4744 }
4745 break;
4746
4747 case '~':
4748 if (post_op_name[1] == '\0')
4749 op_kind = clang::OO_Tilde;
4750 break;
4751
4752 case '!':
4753 if (post_op_name[1] == '\0')
4754 op_kind = clang::OO_Exclaim;
4755 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
4756 op_kind = clang::OO_ExclaimEqual;
4757 break;
4758
4759 case '=':
4760 if (post_op_name[1] == '\0')
4761 op_kind = clang::OO_Equal;
4762 else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
4763 op_kind = clang::OO_EqualEqual;
4764 break;
4765
4766 case '<':
4767 if (post_op_name[1] == '\0')
4768 op_kind = clang::OO_Less;
4769 else if (post_op_name[2] == '\0')
4770 {
4771 switch (post_op_name[1])
4772 {
4773 case '<': op_kind = clang::OO_LessLess; break;
4774 case '=': op_kind = clang::OO_LessEqual; break;
4775 }
4776 }
4777 else if (post_op_name[3] == '\0')
4778 {
4779 if (post_op_name[2] == '=')
4780 op_kind = clang::OO_LessLessEqual;
4781 }
4782 break;
4783
4784 case '>':
4785 if (post_op_name[1] == '\0')
4786 op_kind = clang::OO_Greater;
4787 else if (post_op_name[2] == '\0')
4788 {
4789 switch (post_op_name[1])
4790 {
4791 case '>': op_kind = clang::OO_GreaterGreater; break;
4792 case '=': op_kind = clang::OO_GreaterEqual; break;
4793 }
4794 }
4795 else if (post_op_name[1] == '>' &&
4796 post_op_name[2] == '=' &&
4797 post_op_name[3] == '\0')
4798 {
4799 op_kind = clang::OO_GreaterGreaterEqual;
4800 }
4801 break;
4802
4803 case ',':
4804 if (post_op_name[1] == '\0')
4805 op_kind = clang::OO_Comma;
4806 break;
4807
4808 case '(':
4809 if (post_op_name[1] == ')' && post_op_name[2] == '\0')
4810 op_kind = clang::OO_Call;
4811 break;
4812
4813 case '[':
4814 if (post_op_name[1] == ']' && post_op_name[2] == '\0')
4815 op_kind = clang::OO_Subscript;
4816 break;
4817 }
4818
4819 return true;
4820 }
4821
4822 clang::EnumDecl *
GetAsEnumDecl() const4823 ClangASTType::GetAsEnumDecl () const
4824 {
4825 const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(GetCanonicalQualType());
4826 if (enum_type)
4827 return enum_type->getDecl();
4828 return NULL;
4829 }
4830
4831 clang::RecordDecl *
GetAsRecordDecl() const4832 ClangASTType::GetAsRecordDecl () const
4833 {
4834 const clang::RecordType *record_type = llvm::dyn_cast<clang::RecordType>(GetCanonicalQualType());
4835 if (record_type)
4836 return record_type->getDecl();
4837 return nullptr;
4838 }
4839
4840 clang::CXXRecordDecl *
GetAsCXXRecordDecl() const4841 ClangASTType::GetAsCXXRecordDecl () const
4842 {
4843 return GetCanonicalQualType()->getAsCXXRecordDecl();
4844 }
4845
4846 clang::ObjCInterfaceDecl *
GetAsObjCInterfaceDecl() const4847 ClangASTType::GetAsObjCInterfaceDecl () const
4848 {
4849 const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(GetCanonicalQualType());
4850 if (objc_class_type)
4851 return objc_class_type->getInterface();
4852 return nullptr;
4853 }
4854
4855 clang::FieldDecl *
AddFieldToRecordType(const char * name,const ClangASTType & field_clang_type,AccessType access,uint32_t bitfield_bit_size)4856 ClangASTType::AddFieldToRecordType (const char *name,
4857 const ClangASTType &field_clang_type,
4858 AccessType access,
4859 uint32_t bitfield_bit_size)
4860 {
4861 if (!IsValid() || !field_clang_type.IsValid())
4862 return nullptr;
4863
4864 clang::FieldDecl *field = nullptr;
4865
4866 clang::Expr *bit_width = nullptr;
4867 if (bitfield_bit_size != 0)
4868 {
4869 llvm::APInt bitfield_bit_size_apint(m_ast->getTypeSize(m_ast->IntTy), bitfield_bit_size);
4870 bit_width = new (*m_ast)clang::IntegerLiteral (*m_ast, bitfield_bit_size_apint, m_ast->IntTy, clang::SourceLocation());
4871 }
4872
4873 clang::RecordDecl *record_decl = GetAsRecordDecl ();
4874 if (record_decl)
4875 {
4876 field = clang::FieldDecl::Create (*m_ast,
4877 record_decl,
4878 clang::SourceLocation(),
4879 clang::SourceLocation(),
4880 name ? &m_ast->Idents.get(name) : nullptr, // Identifier
4881 field_clang_type.GetQualType(), // Field type
4882 nullptr, // TInfo *
4883 bit_width, // BitWidth
4884 false, // Mutable
4885 clang::ICIS_NoInit); // HasInit
4886
4887 if (!name)
4888 {
4889 // Determine whether this field corresponds to an anonymous
4890 // struct or union.
4891 if (const clang::TagType *TagT = field->getType()->getAs<clang::TagType>()) {
4892 if (clang::RecordDecl *Rec = llvm::dyn_cast<clang::RecordDecl>(TagT->getDecl()))
4893 if (!Rec->getDeclName()) {
4894 Rec->setAnonymousStructOrUnion(true);
4895 field->setImplicit();
4896
4897 }
4898 }
4899 }
4900
4901 if (field)
4902 {
4903 field->setAccess (ClangASTContext::ConvertAccessTypeToAccessSpecifier (access));
4904
4905 record_decl->addDecl(field);
4906
4907 #ifdef LLDB_CONFIGURATION_DEBUG
4908 VerifyDecl(field);
4909 #endif
4910 }
4911 }
4912 else
4913 {
4914 clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl ();
4915
4916 if (class_interface_decl)
4917 {
4918 const bool is_synthesized = false;
4919
4920 field_clang_type.GetCompleteType();
4921
4922 field = clang::ObjCIvarDecl::Create (*m_ast,
4923 class_interface_decl,
4924 clang::SourceLocation(),
4925 clang::SourceLocation(),
4926 name ? &m_ast->Idents.get(name) : nullptr, // Identifier
4927 field_clang_type.GetQualType(), // Field type
4928 nullptr, // TypeSourceInfo *
4929 ConvertAccessTypeToObjCIvarAccessControl (access),
4930 bit_width,
4931 is_synthesized);
4932
4933 if (field)
4934 {
4935 class_interface_decl->addDecl(field);
4936
4937 #ifdef LLDB_CONFIGURATION_DEBUG
4938 VerifyDecl(field);
4939 #endif
4940 }
4941 }
4942 }
4943 return field;
4944 }
4945
4946 void
BuildIndirectFields()4947 ClangASTType::BuildIndirectFields ()
4948 {
4949 clang::RecordDecl *record_decl = GetAsRecordDecl();
4950
4951 if (!record_decl)
4952 return;
4953
4954 typedef llvm::SmallVector <clang::IndirectFieldDecl *, 1> IndirectFieldVector;
4955
4956 IndirectFieldVector indirect_fields;
4957 clang::RecordDecl::field_iterator field_pos;
4958 clang::RecordDecl::field_iterator field_end_pos = record_decl->field_end();
4959 clang::RecordDecl::field_iterator last_field_pos = field_end_pos;
4960 for (field_pos = record_decl->field_begin(); field_pos != field_end_pos; last_field_pos = field_pos++)
4961 {
4962 if (field_pos->isAnonymousStructOrUnion())
4963 {
4964 clang::QualType field_qual_type = field_pos->getType();
4965
4966 const clang::RecordType *field_record_type = field_qual_type->getAs<clang::RecordType>();
4967
4968 if (!field_record_type)
4969 continue;
4970
4971 clang::RecordDecl *field_record_decl = field_record_type->getDecl();
4972
4973 if (!field_record_decl)
4974 continue;
4975
4976 for (clang::RecordDecl::decl_iterator di = field_record_decl->decls_begin(), de = field_record_decl->decls_end();
4977 di != de;
4978 ++di)
4979 {
4980 if (clang::FieldDecl *nested_field_decl = llvm::dyn_cast<clang::FieldDecl>(*di))
4981 {
4982 clang::NamedDecl **chain = new (*m_ast) clang::NamedDecl*[2];
4983 chain[0] = *field_pos;
4984 chain[1] = nested_field_decl;
4985 clang::IndirectFieldDecl *indirect_field = clang::IndirectFieldDecl::Create(*m_ast,
4986 record_decl,
4987 clang::SourceLocation(),
4988 nested_field_decl->getIdentifier(),
4989 nested_field_decl->getType(),
4990 chain,
4991 2);
4992
4993 indirect_field->setImplicit();
4994
4995 indirect_field->setAccess(ClangASTContext::UnifyAccessSpecifiers(field_pos->getAccess(),
4996 nested_field_decl->getAccess()));
4997
4998 indirect_fields.push_back(indirect_field);
4999 }
5000 else if (clang::IndirectFieldDecl *nested_indirect_field_decl = llvm::dyn_cast<clang::IndirectFieldDecl>(*di))
5001 {
5002 int nested_chain_size = nested_indirect_field_decl->getChainingSize();
5003 clang::NamedDecl **chain = new (*m_ast) clang::NamedDecl*[nested_chain_size + 1];
5004 chain[0] = *field_pos;
5005
5006 int chain_index = 1;
5007 for (clang::IndirectFieldDecl::chain_iterator nci = nested_indirect_field_decl->chain_begin(),
5008 nce = nested_indirect_field_decl->chain_end();
5009 nci < nce;
5010 ++nci)
5011 {
5012 chain[chain_index] = *nci;
5013 chain_index++;
5014 }
5015
5016 clang::IndirectFieldDecl *indirect_field = clang::IndirectFieldDecl::Create(*m_ast,
5017 record_decl,
5018 clang::SourceLocation(),
5019 nested_indirect_field_decl->getIdentifier(),
5020 nested_indirect_field_decl->getType(),
5021 chain,
5022 nested_chain_size + 1);
5023
5024 indirect_field->setImplicit();
5025
5026 indirect_field->setAccess(ClangASTContext::UnifyAccessSpecifiers(field_pos->getAccess(),
5027 nested_indirect_field_decl->getAccess()));
5028
5029 indirect_fields.push_back(indirect_field);
5030 }
5031 }
5032 }
5033 }
5034
5035 // Check the last field to see if it has an incomplete array type as its
5036 // last member and if it does, the tell the record decl about it
5037 if (last_field_pos != field_end_pos)
5038 {
5039 if (last_field_pos->getType()->isIncompleteArrayType())
5040 record_decl->hasFlexibleArrayMember();
5041 }
5042
5043 for (IndirectFieldVector::iterator ifi = indirect_fields.begin(), ife = indirect_fields.end();
5044 ifi < ife;
5045 ++ifi)
5046 {
5047 record_decl->addDecl(*ifi);
5048 }
5049 }
5050
5051 void
SetIsPacked()5052 ClangASTType::SetIsPacked ()
5053 {
5054 clang::RecordDecl *record_decl = GetAsRecordDecl();
5055
5056 if (!record_decl)
5057 return;
5058
5059 record_decl->addAttr(clang::PackedAttr::CreateImplicit(*m_ast));
5060 }
5061
5062 clang::VarDecl *
AddVariableToRecordType(const char * name,const ClangASTType & var_type,AccessType access)5063 ClangASTType::AddVariableToRecordType (const char *name,
5064 const ClangASTType &var_type,
5065 AccessType access)
5066 {
5067 clang::VarDecl *var_decl = nullptr;
5068
5069 if (!IsValid() || !var_type.IsValid())
5070 return nullptr;
5071
5072 clang::RecordDecl *record_decl = GetAsRecordDecl ();
5073 if (record_decl)
5074 {
5075 var_decl = clang::VarDecl::Create (*m_ast, // ASTContext &
5076 record_decl, // DeclContext *
5077 clang::SourceLocation(), // clang::SourceLocation StartLoc
5078 clang::SourceLocation(), // clang::SourceLocation IdLoc
5079 name ? &m_ast->Idents.get(name) : nullptr, // clang::IdentifierInfo *
5080 var_type.GetQualType(), // Variable clang::QualType
5081 nullptr, // TypeSourceInfo *
5082 clang::SC_Static); // StorageClass
5083 if (var_decl)
5084 {
5085 var_decl->setAccess(ClangASTContext::ConvertAccessTypeToAccessSpecifier (access));
5086 record_decl->addDecl(var_decl);
5087
5088 #ifdef LLDB_CONFIGURATION_DEBUG
5089 VerifyDecl(var_decl);
5090 #endif
5091 }
5092 }
5093 return var_decl;
5094 }
5095
5096
5097 clang::CXXMethodDecl *
AddMethodToCXXRecordType(const char * name,const ClangASTType & method_clang_type,lldb::AccessType access,bool is_virtual,bool is_static,bool is_inline,bool is_explicit,bool is_attr_used,bool is_artificial)5098 ClangASTType::AddMethodToCXXRecordType (const char *name,
5099 const ClangASTType &method_clang_type,
5100 lldb::AccessType access,
5101 bool is_virtual,
5102 bool is_static,
5103 bool is_inline,
5104 bool is_explicit,
5105 bool is_attr_used,
5106 bool is_artificial)
5107 {
5108 if (!IsValid() || !method_clang_type.IsValid() || name == nullptr || name[0] == '\0')
5109 return nullptr;
5110
5111 clang::QualType record_qual_type(GetCanonicalQualType());
5112
5113 clang::CXXRecordDecl *cxx_record_decl = record_qual_type->getAsCXXRecordDecl();
5114
5115 if (cxx_record_decl == nullptr)
5116 return nullptr;
5117
5118 clang::QualType method_qual_type (method_clang_type.GetQualType());
5119
5120 clang::CXXMethodDecl *cxx_method_decl = nullptr;
5121
5122 clang::DeclarationName decl_name (&m_ast->Idents.get(name));
5123
5124 const clang::FunctionType *function_type = llvm::dyn_cast<clang::FunctionType>(method_qual_type.getTypePtr());
5125
5126 if (function_type == nullptr)
5127 return nullptr;
5128
5129 const clang::FunctionProtoType *method_function_prototype (llvm::dyn_cast<clang::FunctionProtoType>(function_type));
5130
5131 if (!method_function_prototype)
5132 return nullptr;
5133
5134 unsigned int num_params = method_function_prototype->getNumParams();
5135
5136 clang::CXXDestructorDecl *cxx_dtor_decl(nullptr);
5137 clang::CXXConstructorDecl *cxx_ctor_decl(nullptr);
5138
5139 if (is_artificial)
5140 return nullptr; // skip everything artificial
5141
5142 if (name[0] == '~')
5143 {
5144 cxx_dtor_decl = clang::CXXDestructorDecl::Create (*m_ast,
5145 cxx_record_decl,
5146 clang::SourceLocation(),
5147 clang::DeclarationNameInfo (m_ast->DeclarationNames.getCXXDestructorName (m_ast->getCanonicalType (record_qual_type)), clang::SourceLocation()),
5148 method_qual_type,
5149 nullptr,
5150 is_inline,
5151 is_artificial);
5152 cxx_method_decl = cxx_dtor_decl;
5153 }
5154 else if (decl_name == cxx_record_decl->getDeclName())
5155 {
5156 cxx_ctor_decl = clang::CXXConstructorDecl::Create (*m_ast,
5157 cxx_record_decl,
5158 clang::SourceLocation(),
5159 clang::DeclarationNameInfo (m_ast->DeclarationNames.getCXXConstructorName (m_ast->getCanonicalType (record_qual_type)), clang::SourceLocation()),
5160 method_qual_type,
5161 nullptr, // TypeSourceInfo *
5162 is_explicit,
5163 is_inline,
5164 is_artificial,
5165 false /*is_constexpr*/);
5166 cxx_method_decl = cxx_ctor_decl;
5167 }
5168 else
5169 {
5170 clang::StorageClass SC = is_static ? clang::SC_Static : clang::SC_None;
5171 clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
5172
5173 if (IsOperator (name, op_kind))
5174 {
5175 if (op_kind != clang::NUM_OVERLOADED_OPERATORS)
5176 {
5177 // Check the number of operator parameters. Sometimes we have
5178 // seen bad DWARF that doesn't correctly describe operators and
5179 // if we try to create a method and add it to the class, clang
5180 // will assert and crash, so we need to make sure things are
5181 // acceptable.
5182 if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount (op_kind, num_params))
5183 return nullptr;
5184 cxx_method_decl = clang::CXXMethodDecl::Create (*m_ast,
5185 cxx_record_decl,
5186 clang::SourceLocation(),
5187 clang::DeclarationNameInfo (m_ast->DeclarationNames.getCXXOperatorName (op_kind), clang::SourceLocation()),
5188 method_qual_type,
5189 nullptr, // TypeSourceInfo *
5190 SC,
5191 is_inline,
5192 false /*is_constexpr*/,
5193 clang::SourceLocation());
5194 }
5195 else if (num_params == 0)
5196 {
5197 // Conversion operators don't take params...
5198 cxx_method_decl = clang::CXXConversionDecl::Create (*m_ast,
5199 cxx_record_decl,
5200 clang::SourceLocation(),
5201 clang::DeclarationNameInfo (m_ast->DeclarationNames.getCXXConversionFunctionName (m_ast->getCanonicalType (function_type->getReturnType())), clang::SourceLocation()),
5202 method_qual_type,
5203 nullptr, // TypeSourceInfo *
5204 is_inline,
5205 is_explicit,
5206 false /*is_constexpr*/,
5207 clang::SourceLocation());
5208 }
5209 }
5210
5211 if (cxx_method_decl == nullptr)
5212 {
5213 cxx_method_decl = clang::CXXMethodDecl::Create (*m_ast,
5214 cxx_record_decl,
5215 clang::SourceLocation(),
5216 clang::DeclarationNameInfo (decl_name, clang::SourceLocation()),
5217 method_qual_type,
5218 nullptr, // TypeSourceInfo *
5219 SC,
5220 is_inline,
5221 false /*is_constexpr*/,
5222 clang::SourceLocation());
5223 }
5224 }
5225
5226 clang::AccessSpecifier access_specifier = ClangASTContext::ConvertAccessTypeToAccessSpecifier (access);
5227
5228 cxx_method_decl->setAccess (access_specifier);
5229 cxx_method_decl->setVirtualAsWritten (is_virtual);
5230
5231 if (is_attr_used)
5232 cxx_method_decl->addAttr(clang::UsedAttr::CreateImplicit(*m_ast));
5233
5234 // Populate the method decl with parameter decls
5235
5236 llvm::SmallVector<clang::ParmVarDecl *, 12> params;
5237
5238 for (unsigned param_index = 0;
5239 param_index < num_params;
5240 ++param_index)
5241 {
5242 params.push_back (clang::ParmVarDecl::Create (*m_ast,
5243 cxx_method_decl,
5244 clang::SourceLocation(),
5245 clang::SourceLocation(),
5246 nullptr, // anonymous
5247 method_function_prototype->getParamType(param_index),
5248 nullptr,
5249 clang::SC_None,
5250 nullptr));
5251 }
5252
5253 cxx_method_decl->setParams (llvm::ArrayRef<clang::ParmVarDecl*>(params));
5254
5255 cxx_record_decl->addDecl (cxx_method_decl);
5256
5257 // Sometimes the debug info will mention a constructor (default/copy/move),
5258 // destructor, or assignment operator (copy/move) but there won't be any
5259 // version of this in the code. So we check if the function was artificially
5260 // generated and if it is trivial and this lets the compiler/backend know
5261 // that it can inline the IR for these when it needs to and we can avoid a
5262 // "missing function" error when running expressions.
5263
5264 if (is_artificial)
5265 {
5266 if (cxx_ctor_decl &&
5267 ((cxx_ctor_decl->isDefaultConstructor() && cxx_record_decl->hasTrivialDefaultConstructor ()) ||
5268 (cxx_ctor_decl->isCopyConstructor() && cxx_record_decl->hasTrivialCopyConstructor ()) ||
5269 (cxx_ctor_decl->isMoveConstructor() && cxx_record_decl->hasTrivialMoveConstructor ()) ))
5270 {
5271 cxx_ctor_decl->setDefaulted();
5272 cxx_ctor_decl->setTrivial(true);
5273 }
5274 else if (cxx_dtor_decl)
5275 {
5276 if (cxx_record_decl->hasTrivialDestructor())
5277 {
5278 cxx_dtor_decl->setDefaulted();
5279 cxx_dtor_decl->setTrivial(true);
5280 }
5281 }
5282 else if ((cxx_method_decl->isCopyAssignmentOperator() && cxx_record_decl->hasTrivialCopyAssignment()) ||
5283 (cxx_method_decl->isMoveAssignmentOperator() && cxx_record_decl->hasTrivialMoveAssignment()))
5284 {
5285 cxx_method_decl->setDefaulted();
5286 cxx_method_decl->setTrivial(true);
5287 }
5288 }
5289
5290 #ifdef LLDB_CONFIGURATION_DEBUG
5291 VerifyDecl(cxx_method_decl);
5292 #endif
5293
5294 // printf ("decl->isPolymorphic() = %i\n", cxx_record_decl->isPolymorphic());
5295 // printf ("decl->isAggregate() = %i\n", cxx_record_decl->isAggregate());
5296 // printf ("decl->isPOD() = %i\n", cxx_record_decl->isPOD());
5297 // printf ("decl->isEmpty() = %i\n", cxx_record_decl->isEmpty());
5298 // printf ("decl->isAbstract() = %i\n", cxx_record_decl->isAbstract());
5299 // printf ("decl->hasTrivialConstructor() = %i\n", cxx_record_decl->hasTrivialConstructor());
5300 // printf ("decl->hasTrivialCopyConstructor() = %i\n", cxx_record_decl->hasTrivialCopyConstructor());
5301 // printf ("decl->hasTrivialCopyAssignment() = %i\n", cxx_record_decl->hasTrivialCopyAssignment());
5302 // printf ("decl->hasTrivialDestructor() = %i\n", cxx_record_decl->hasTrivialDestructor());
5303 return cxx_method_decl;
5304 }
5305
5306
5307 #pragma mark C++ Base Classes
5308
5309 clang::CXXBaseSpecifier *
CreateBaseClassSpecifier(AccessType access,bool is_virtual,bool base_of_class)5310 ClangASTType::CreateBaseClassSpecifier (AccessType access, bool is_virtual, bool base_of_class)
5311 {
5312 if (IsValid())
5313 return new clang::CXXBaseSpecifier (clang::SourceRange(),
5314 is_virtual,
5315 base_of_class,
5316 ClangASTContext::ConvertAccessTypeToAccessSpecifier (access),
5317 m_ast->getTrivialTypeSourceInfo (GetQualType()),
5318 clang::SourceLocation());
5319 return nullptr;
5320 }
5321
5322 void
DeleteBaseClassSpecifiers(clang::CXXBaseSpecifier ** base_classes,unsigned num_base_classes)5323 ClangASTType::DeleteBaseClassSpecifiers (clang::CXXBaseSpecifier **base_classes, unsigned num_base_classes)
5324 {
5325 for (unsigned i=0; i<num_base_classes; ++i)
5326 {
5327 delete base_classes[i];
5328 base_classes[i] = nullptr;
5329 }
5330 }
5331
5332 bool
SetBaseClassesForClassType(clang::CXXBaseSpecifier const * const * base_classes,unsigned num_base_classes)5333 ClangASTType::SetBaseClassesForClassType (clang::CXXBaseSpecifier const * const *base_classes,
5334 unsigned num_base_classes)
5335 {
5336 if (IsValid())
5337 {
5338 clang::CXXRecordDecl *cxx_record_decl = GetAsCXXRecordDecl();
5339 if (cxx_record_decl)
5340 {
5341 cxx_record_decl->setBases(base_classes, num_base_classes);
5342 return true;
5343 }
5344 }
5345 return false;
5346 }
5347
5348 bool
SetObjCSuperClass(const ClangASTType & superclass_clang_type)5349 ClangASTType::SetObjCSuperClass (const ClangASTType &superclass_clang_type)
5350 {
5351 if (IsValid() && superclass_clang_type.IsValid())
5352 {
5353 clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl ();
5354 clang::ObjCInterfaceDecl *super_interface_decl = superclass_clang_type.GetAsObjCInterfaceDecl ();
5355 if (class_interface_decl && super_interface_decl)
5356 {
5357
5358 class_interface_decl->setSuperClass(
5359 m_ast->getTrivialTypeSourceInfo(m_ast->getObjCInterfaceType(super_interface_decl)));
5360 return true;
5361 }
5362 }
5363 return false;
5364 }
5365
5366 bool
AddObjCClassProperty(const char * property_name,const ClangASTType & property_clang_type,clang::ObjCIvarDecl * ivar_decl,const char * property_setter_name,const char * property_getter_name,uint32_t property_attributes,ClangASTMetadata * metadata)5367 ClangASTType::AddObjCClassProperty (const char *property_name,
5368 const ClangASTType &property_clang_type,
5369 clang::ObjCIvarDecl *ivar_decl,
5370 const char *property_setter_name,
5371 const char *property_getter_name,
5372 uint32_t property_attributes,
5373 ClangASTMetadata *metadata)
5374 {
5375 if (!IsValid() || !property_clang_type.IsValid() || property_name == nullptr || property_name[0] == '\0')
5376 return false;
5377
5378 clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl ();
5379
5380 if (class_interface_decl)
5381 {
5382 ClangASTType property_clang_type_to_access;
5383
5384 if (property_clang_type.IsValid())
5385 property_clang_type_to_access = property_clang_type;
5386 else if (ivar_decl)
5387 property_clang_type_to_access = ClangASTType (m_ast, ivar_decl->getType());
5388
5389 if (class_interface_decl && property_clang_type_to_access.IsValid())
5390 {
5391 clang::TypeSourceInfo *prop_type_source;
5392 if (ivar_decl)
5393 prop_type_source = m_ast->getTrivialTypeSourceInfo (ivar_decl->getType());
5394 else
5395 prop_type_source = m_ast->getTrivialTypeSourceInfo (property_clang_type.GetQualType());
5396
5397 clang::ObjCPropertyDecl *property_decl = clang::ObjCPropertyDecl::Create (*m_ast,
5398 class_interface_decl,
5399 clang::SourceLocation(), // Source Location
5400 &m_ast->Idents.get(property_name),
5401 clang::SourceLocation(), //Source Location for AT
5402 clang::SourceLocation(), //Source location for (
5403 ivar_decl ? ivar_decl->getType() : property_clang_type.GetQualType(),
5404 prop_type_source);
5405
5406 if (property_decl)
5407 {
5408 if (metadata)
5409 ClangASTContext::SetMetadata(m_ast, property_decl, *metadata);
5410
5411 class_interface_decl->addDecl (property_decl);
5412
5413 clang::Selector setter_sel, getter_sel;
5414
5415 if (property_setter_name != nullptr)
5416 {
5417 std::string property_setter_no_colon(property_setter_name, strlen(property_setter_name) - 1);
5418 clang::IdentifierInfo *setter_ident = &m_ast->Idents.get(property_setter_no_colon.c_str());
5419 setter_sel = m_ast->Selectors.getSelector(1, &setter_ident);
5420 }
5421 else if (!(property_attributes & DW_APPLE_PROPERTY_readonly))
5422 {
5423 std::string setter_sel_string("set");
5424 setter_sel_string.push_back(::toupper(property_name[0]));
5425 setter_sel_string.append(&property_name[1]);
5426 clang::IdentifierInfo *setter_ident = &m_ast->Idents.get(setter_sel_string.c_str());
5427 setter_sel = m_ast->Selectors.getSelector(1, &setter_ident);
5428 }
5429 property_decl->setSetterName(setter_sel);
5430 property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_setter);
5431
5432 if (property_getter_name != nullptr)
5433 {
5434 clang::IdentifierInfo *getter_ident = &m_ast->Idents.get(property_getter_name);
5435 getter_sel = m_ast->Selectors.getSelector(0, &getter_ident);
5436 }
5437 else
5438 {
5439 clang::IdentifierInfo *getter_ident = &m_ast->Idents.get(property_name);
5440 getter_sel = m_ast->Selectors.getSelector(0, &getter_ident);
5441 }
5442 property_decl->setGetterName(getter_sel);
5443 property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_getter);
5444
5445 if (ivar_decl)
5446 property_decl->setPropertyIvarDecl (ivar_decl);
5447
5448 if (property_attributes & DW_APPLE_PROPERTY_readonly)
5449 property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_readonly);
5450 if (property_attributes & DW_APPLE_PROPERTY_readwrite)
5451 property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_readwrite);
5452 if (property_attributes & DW_APPLE_PROPERTY_assign)
5453 property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_assign);
5454 if (property_attributes & DW_APPLE_PROPERTY_retain)
5455 property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_retain);
5456 if (property_attributes & DW_APPLE_PROPERTY_copy)
5457 property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_copy);
5458 if (property_attributes & DW_APPLE_PROPERTY_nonatomic)
5459 property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_nonatomic);
5460
5461 if (!getter_sel.isNull() && !class_interface_decl->lookupInstanceMethod(getter_sel))
5462 {
5463 const bool isInstance = true;
5464 const bool isVariadic = false;
5465 const bool isSynthesized = false;
5466 const bool isImplicitlyDeclared = true;
5467 const bool isDefined = false;
5468 const clang::ObjCMethodDecl::ImplementationControl impControl = clang::ObjCMethodDecl::None;
5469 const bool HasRelatedResultType = false;
5470
5471 clang::ObjCMethodDecl *getter = clang::ObjCMethodDecl::Create (*m_ast,
5472 clang::SourceLocation(),
5473 clang::SourceLocation(),
5474 getter_sel,
5475 property_clang_type_to_access.GetQualType(),
5476 nullptr,
5477 class_interface_decl,
5478 isInstance,
5479 isVariadic,
5480 isSynthesized,
5481 isImplicitlyDeclared,
5482 isDefined,
5483 impControl,
5484 HasRelatedResultType);
5485
5486 if (getter && metadata)
5487 ClangASTContext::SetMetadata(m_ast, getter, *metadata);
5488
5489 if (getter)
5490 {
5491 getter->setMethodParams(*m_ast, llvm::ArrayRef<clang::ParmVarDecl*>(), llvm::ArrayRef<clang::SourceLocation>());
5492
5493 class_interface_decl->addDecl(getter);
5494 }
5495 }
5496
5497 if (!setter_sel.isNull() && !class_interface_decl->lookupInstanceMethod(setter_sel))
5498 {
5499 clang::QualType result_type = m_ast->VoidTy;
5500
5501 const bool isInstance = true;
5502 const bool isVariadic = false;
5503 const bool isSynthesized = false;
5504 const bool isImplicitlyDeclared = true;
5505 const bool isDefined = false;
5506 const clang::ObjCMethodDecl::ImplementationControl impControl = clang::ObjCMethodDecl::None;
5507 const bool HasRelatedResultType = false;
5508
5509 clang::ObjCMethodDecl *setter = clang::ObjCMethodDecl::Create (*m_ast,
5510 clang::SourceLocation(),
5511 clang::SourceLocation(),
5512 setter_sel,
5513 result_type,
5514 nullptr,
5515 class_interface_decl,
5516 isInstance,
5517 isVariadic,
5518 isSynthesized,
5519 isImplicitlyDeclared,
5520 isDefined,
5521 impControl,
5522 HasRelatedResultType);
5523
5524 if (setter && metadata)
5525 ClangASTContext::SetMetadata(m_ast, setter, *metadata);
5526
5527 llvm::SmallVector<clang::ParmVarDecl *, 1> params;
5528
5529 params.push_back (clang::ParmVarDecl::Create (*m_ast,
5530 setter,
5531 clang::SourceLocation(),
5532 clang::SourceLocation(),
5533 nullptr, // anonymous
5534 property_clang_type_to_access.GetQualType(),
5535 nullptr,
5536 clang::SC_Auto,
5537 nullptr));
5538
5539 if (setter)
5540 {
5541 setter->setMethodParams(*m_ast, llvm::ArrayRef<clang::ParmVarDecl*>(params), llvm::ArrayRef<clang::SourceLocation>());
5542
5543 class_interface_decl->addDecl(setter);
5544 }
5545 }
5546
5547 return true;
5548 }
5549 }
5550 }
5551 return false;
5552 }
5553
5554 bool
IsObjCClassTypeAndHasIVars(bool check_superclass) const5555 ClangASTType::IsObjCClassTypeAndHasIVars (bool check_superclass) const
5556 {
5557 clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl ();
5558 if (class_interface_decl)
5559 return ObjCDeclHasIVars (class_interface_decl, check_superclass);
5560 return false;
5561 }
5562
5563
5564 clang::ObjCMethodDecl *
AddMethodToObjCObjectType(const char * name,const ClangASTType & method_clang_type,lldb::AccessType access,bool is_artificial)5565 ClangASTType::AddMethodToObjCObjectType (const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
5566 const ClangASTType &method_clang_type,
5567 lldb::AccessType access,
5568 bool is_artificial)
5569 {
5570 if (!IsValid() || !method_clang_type.IsValid())
5571 return nullptr;
5572
5573 clang::ObjCInterfaceDecl *class_interface_decl = GetAsObjCInterfaceDecl();
5574
5575 if (class_interface_decl == nullptr)
5576 return nullptr;
5577
5578 const char *selector_start = ::strchr (name, ' ');
5579 if (selector_start == nullptr)
5580 return nullptr;
5581
5582 selector_start++;
5583 llvm::SmallVector<clang::IdentifierInfo *, 12> selector_idents;
5584
5585 size_t len = 0;
5586 const char *start;
5587 //printf ("name = '%s'\n", name);
5588
5589 unsigned num_selectors_with_args = 0;
5590 for (start = selector_start;
5591 start && *start != '\0' && *start != ']';
5592 start += len)
5593 {
5594 len = ::strcspn(start, ":]");
5595 bool has_arg = (start[len] == ':');
5596 if (has_arg)
5597 ++num_selectors_with_args;
5598 selector_idents.push_back (&m_ast->Idents.get (llvm::StringRef (start, len)));
5599 if (has_arg)
5600 len += 1;
5601 }
5602
5603
5604 if (selector_idents.size() == 0)
5605 return nullptr;
5606
5607 clang::Selector method_selector = m_ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
5608 selector_idents.data());
5609
5610 clang::QualType method_qual_type (method_clang_type.GetQualType());
5611
5612 // Populate the method decl with parameter decls
5613 const clang::Type *method_type(method_qual_type.getTypePtr());
5614
5615 if (method_type == nullptr)
5616 return nullptr;
5617
5618 const clang::FunctionProtoType *method_function_prototype (llvm::dyn_cast<clang::FunctionProtoType>(method_type));
5619
5620 if (!method_function_prototype)
5621 return nullptr;
5622
5623
5624 bool is_variadic = false;
5625 bool is_synthesized = false;
5626 bool is_defined = false;
5627 clang::ObjCMethodDecl::ImplementationControl imp_control = clang::ObjCMethodDecl::None;
5628
5629 const unsigned num_args = method_function_prototype->getNumParams();
5630
5631 if (num_args != num_selectors_with_args)
5632 return nullptr; // some debug information is corrupt. We are not going to deal with it.
5633
5634 clang::ObjCMethodDecl *objc_method_decl = clang::ObjCMethodDecl::Create (*m_ast,
5635 clang::SourceLocation(), // beginLoc,
5636 clang::SourceLocation(), // endLoc,
5637 method_selector,
5638 method_function_prototype->getReturnType(),
5639 nullptr, // TypeSourceInfo *ResultTInfo,
5640 GetDeclContextForType (),
5641 name[0] == '-',
5642 is_variadic,
5643 is_synthesized,
5644 true, // is_implicitly_declared; we force this to true because we don't have source locations
5645 is_defined,
5646 imp_control,
5647 false /*has_related_result_type*/);
5648
5649
5650 if (objc_method_decl == nullptr)
5651 return nullptr;
5652
5653 if (num_args > 0)
5654 {
5655 llvm::SmallVector<clang::ParmVarDecl *, 12> params;
5656
5657 for (unsigned param_index = 0; param_index < num_args; ++param_index)
5658 {
5659 params.push_back (clang::ParmVarDecl::Create (*m_ast,
5660 objc_method_decl,
5661 clang::SourceLocation(),
5662 clang::SourceLocation(),
5663 nullptr, // anonymous
5664 method_function_prototype->getParamType(param_index),
5665 nullptr,
5666 clang::SC_Auto,
5667 nullptr));
5668 }
5669
5670 objc_method_decl->setMethodParams(*m_ast, llvm::ArrayRef<clang::ParmVarDecl*>(params), llvm::ArrayRef<clang::SourceLocation>());
5671 }
5672
5673 class_interface_decl->addDecl (objc_method_decl);
5674
5675 #ifdef LLDB_CONFIGURATION_DEBUG
5676 VerifyDecl(objc_method_decl);
5677 #endif
5678
5679 return objc_method_decl;
5680 }
5681
5682
5683 clang::DeclContext *
GetDeclContextForType() const5684 ClangASTType::GetDeclContextForType () const
5685 {
5686 if (!IsValid())
5687 return nullptr;
5688
5689 clang::QualType qual_type(GetCanonicalQualType());
5690 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5691 switch (type_class)
5692 {
5693 case clang::Type::UnaryTransform: break;
5694 case clang::Type::FunctionNoProto: break;
5695 case clang::Type::FunctionProto: break;
5696 case clang::Type::IncompleteArray: break;
5697 case clang::Type::VariableArray: break;
5698 case clang::Type::ConstantArray: break;
5699 case clang::Type::DependentSizedArray: break;
5700 case clang::Type::ExtVector: break;
5701 case clang::Type::DependentSizedExtVector: break;
5702 case clang::Type::Vector: break;
5703 case clang::Type::Builtin: break;
5704 case clang::Type::BlockPointer: break;
5705 case clang::Type::Pointer: break;
5706 case clang::Type::LValueReference: break;
5707 case clang::Type::RValueReference: break;
5708 case clang::Type::MemberPointer: break;
5709 case clang::Type::Complex: break;
5710 case clang::Type::ObjCObject: break;
5711 case clang::Type::ObjCInterface: return llvm::cast<clang::ObjCObjectType>(qual_type.getTypePtr())->getInterface();
5712 case clang::Type::ObjCObjectPointer: return ClangASTType (m_ast, llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType()).GetDeclContextForType();
5713 case clang::Type::Record: return llvm::cast<clang::RecordType>(qual_type)->getDecl();
5714 case clang::Type::Enum: return llvm::cast<clang::EnumType>(qual_type)->getDecl();
5715 case clang::Type::Typedef: return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetDeclContextForType();
5716 case clang::Type::Elaborated: return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetDeclContextForType();
5717 case clang::Type::Paren: return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetDeclContextForType();
5718 case clang::Type::TypeOfExpr: break;
5719 case clang::Type::TypeOf: break;
5720 case clang::Type::Decltype: break;
5721 //case clang::Type::QualifiedName: break;
5722 case clang::Type::TemplateSpecialization: break;
5723 case clang::Type::DependentTemplateSpecialization: break;
5724 case clang::Type::TemplateTypeParm: break;
5725 case clang::Type::SubstTemplateTypeParm: break;
5726 case clang::Type::SubstTemplateTypeParmPack:break;
5727 case clang::Type::PackExpansion: break;
5728 case clang::Type::UnresolvedUsing: break;
5729 case clang::Type::Attributed: break;
5730 case clang::Type::Auto: break;
5731 case clang::Type::InjectedClassName: break;
5732 case clang::Type::DependentName: break;
5733 case clang::Type::Atomic: break;
5734 case clang::Type::Adjusted: break;
5735
5736 // pointer type decayed from an array or function type.
5737 case clang::Type::Decayed: break;
5738 }
5739 // No DeclContext in this type...
5740 return nullptr;
5741 }
5742
5743 bool
SetDefaultAccessForRecordFields(int default_accessibility,int * assigned_accessibilities,size_t num_assigned_accessibilities)5744 ClangASTType::SetDefaultAccessForRecordFields (int default_accessibility,
5745 int *assigned_accessibilities,
5746 size_t num_assigned_accessibilities)
5747 {
5748 if (IsValid())
5749 {
5750 clang::RecordDecl *record_decl = GetAsRecordDecl();
5751 if (record_decl)
5752 {
5753 uint32_t field_idx;
5754 clang::RecordDecl::field_iterator field, field_end;
5755 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
5756 field != field_end;
5757 ++field, ++field_idx)
5758 {
5759 // If no accessibility was assigned, assign the correct one
5760 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
5761 field->setAccess ((clang::AccessSpecifier)default_accessibility);
5762 }
5763 return true;
5764 }
5765 }
5766 return false;
5767 }
5768
5769
5770 bool
SetHasExternalStorage(bool has_extern)5771 ClangASTType::SetHasExternalStorage (bool has_extern)
5772 {
5773 if (!IsValid())
5774 return false;
5775
5776 clang::QualType qual_type (GetCanonicalQualType());
5777
5778 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
5779 switch (type_class)
5780 {
5781 case clang::Type::Record:
5782 {
5783 clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
5784 if (cxx_record_decl)
5785 {
5786 cxx_record_decl->setHasExternalLexicalStorage (has_extern);
5787 cxx_record_decl->setHasExternalVisibleStorage (has_extern);
5788 return true;
5789 }
5790 }
5791 break;
5792
5793 case clang::Type::Enum:
5794 {
5795 clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl();
5796 if (enum_decl)
5797 {
5798 enum_decl->setHasExternalLexicalStorage (has_extern);
5799 enum_decl->setHasExternalVisibleStorage (has_extern);
5800 return true;
5801 }
5802 }
5803 break;
5804
5805 case clang::Type::ObjCObject:
5806 case clang::Type::ObjCInterface:
5807 {
5808 const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
5809 assert (objc_class_type);
5810 if (objc_class_type)
5811 {
5812 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
5813
5814 if (class_interface_decl)
5815 {
5816 class_interface_decl->setHasExternalLexicalStorage (has_extern);
5817 class_interface_decl->setHasExternalVisibleStorage (has_extern);
5818 return true;
5819 }
5820 }
5821 }
5822 break;
5823
5824 case clang::Type::Typedef:
5825 return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).SetHasExternalStorage (has_extern);
5826
5827 case clang::Type::Elaborated:
5828 return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).SetHasExternalStorage (has_extern);
5829
5830 case clang::Type::Paren:
5831 return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).SetHasExternalStorage (has_extern);
5832
5833 default:
5834 break;
5835 }
5836 return false;
5837 }
5838
5839 bool
SetTagTypeKind(int kind) const5840 ClangASTType::SetTagTypeKind (int kind) const
5841 {
5842 if (IsValid())
5843 {
5844 clang::QualType tag_qual_type(GetQualType());
5845 const clang::Type *clang_type = tag_qual_type.getTypePtr();
5846 if (clang_type)
5847 {
5848 const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(clang_type);
5849 if (tag_type)
5850 {
5851 clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(tag_type->getDecl());
5852 if (tag_decl)
5853 {
5854 tag_decl->setTagKind ((clang::TagDecl::TagKind)kind);
5855 return true;
5856 }
5857 }
5858 }
5859 }
5860 return false;
5861 }
5862
5863
5864 #pragma mark TagDecl
5865
5866 bool
StartTagDeclarationDefinition()5867 ClangASTType::StartTagDeclarationDefinition ()
5868 {
5869 if (IsValid())
5870 {
5871 clang::QualType qual_type (GetQualType());
5872 const clang::Type *t = qual_type.getTypePtr();
5873 if (t)
5874 {
5875 const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(t);
5876 if (tag_type)
5877 {
5878 clang::TagDecl *tag_decl = tag_type->getDecl();
5879 if (tag_decl)
5880 {
5881 tag_decl->startDefinition();
5882 return true;
5883 }
5884 }
5885
5886 const clang::ObjCObjectType *object_type = llvm::dyn_cast<clang::ObjCObjectType>(t);
5887 if (object_type)
5888 {
5889 clang::ObjCInterfaceDecl *interface_decl = object_type->getInterface();
5890 if (interface_decl)
5891 {
5892 interface_decl->startDefinition();
5893 return true;
5894 }
5895 }
5896 }
5897 }
5898 return false;
5899 }
5900
5901 bool
CompleteTagDeclarationDefinition()5902 ClangASTType::CompleteTagDeclarationDefinition ()
5903 {
5904 if (IsValid())
5905 {
5906 clang::QualType qual_type (GetQualType());
5907
5908 clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
5909
5910 if (cxx_record_decl)
5911 {
5912 cxx_record_decl->completeDefinition();
5913
5914 return true;
5915 }
5916
5917 const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(qual_type.getTypePtr());
5918
5919 if (enum_type)
5920 {
5921 clang::EnumDecl *enum_decl = enum_type->getDecl();
5922
5923 if (enum_decl)
5924 {
5925 /// TODO This really needs to be fixed.
5926
5927 unsigned NumPositiveBits = 1;
5928 unsigned NumNegativeBits = 0;
5929
5930 clang::QualType promotion_qual_type;
5931 // If the enum integer type is less than an integer in bit width,
5932 // then we must promote it to an integer size.
5933 if (m_ast->getTypeSize(enum_decl->getIntegerType()) < m_ast->getTypeSize(m_ast->IntTy))
5934 {
5935 if (enum_decl->getIntegerType()->isSignedIntegerType())
5936 promotion_qual_type = m_ast->IntTy;
5937 else
5938 promotion_qual_type = m_ast->UnsignedIntTy;
5939 }
5940 else
5941 promotion_qual_type = enum_decl->getIntegerType();
5942
5943 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
5944 return true;
5945 }
5946 }
5947 }
5948 return false;
5949 }
5950
5951
5952
5953
5954
5955
5956
5957 bool
AddEnumerationValueToEnumerationType(const ClangASTType & enumerator_clang_type,const Declaration & decl,const char * name,int64_t enum_value,uint32_t enum_value_bit_size)5958 ClangASTType::AddEnumerationValueToEnumerationType (const ClangASTType &enumerator_clang_type,
5959 const Declaration &decl,
5960 const char *name,
5961 int64_t enum_value,
5962 uint32_t enum_value_bit_size)
5963 {
5964 if (IsValid() && enumerator_clang_type.IsValid() && name && name[0])
5965 {
5966 clang::QualType enum_qual_type (GetCanonicalQualType());
5967
5968 bool is_signed = false;
5969 enumerator_clang_type.IsIntegerType (is_signed);
5970 const clang::Type *clang_type = enum_qual_type.getTypePtr();
5971 if (clang_type)
5972 {
5973 const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(clang_type);
5974
5975 if (enum_type)
5976 {
5977 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, is_signed);
5978 enum_llvm_apsint = enum_value;
5979 clang::EnumConstantDecl *enumerator_decl =
5980 clang::EnumConstantDecl::Create (*m_ast,
5981 enum_type->getDecl(),
5982 clang::SourceLocation(),
5983 name ? &m_ast->Idents.get(name) : nullptr, // Identifier
5984 enumerator_clang_type.GetQualType(),
5985 nullptr,
5986 enum_llvm_apsint);
5987
5988 if (enumerator_decl)
5989 {
5990 enum_type->getDecl()->addDecl(enumerator_decl);
5991
5992 #ifdef LLDB_CONFIGURATION_DEBUG
5993 VerifyDecl(enumerator_decl);
5994 #endif
5995
5996 return true;
5997 }
5998 }
5999 }
6000 }
6001 return false;
6002 }
6003
6004
6005 ClangASTType
GetEnumerationIntegerType() const6006 ClangASTType::GetEnumerationIntegerType () const
6007 {
6008 clang::QualType enum_qual_type (GetCanonicalQualType());
6009 const clang::Type *clang_type = enum_qual_type.getTypePtr();
6010 if (clang_type)
6011 {
6012 const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(clang_type);
6013 if (enum_type)
6014 {
6015 clang::EnumDecl *enum_decl = enum_type->getDecl();
6016 if (enum_decl)
6017 return ClangASTType (m_ast, enum_decl->getIntegerType());
6018 }
6019 }
6020 return ClangASTType();
6021 }
6022
6023 ClangASTType
CreateMemberPointerType(const ClangASTType & pointee_type) const6024 ClangASTType::CreateMemberPointerType (const ClangASTType &pointee_type) const
6025 {
6026 if (IsValid() && pointee_type.IsValid())
6027 {
6028 return ClangASTType (m_ast, m_ast->getMemberPointerType (pointee_type.GetQualType(),
6029 GetQualType().getTypePtr()));
6030 }
6031 return ClangASTType();
6032 }
6033
6034
6035 size_t
ConvertStringToFloatValue(const char * s,uint8_t * dst,size_t dst_size) const6036 ClangASTType::ConvertStringToFloatValue (const char *s, uint8_t *dst, size_t dst_size) const
6037 {
6038 if (IsValid())
6039 {
6040 clang::QualType qual_type (GetCanonicalQualType());
6041 uint32_t count = 0;
6042 bool is_complex = false;
6043 if (IsFloatingPointType (count, is_complex))
6044 {
6045 // TODO: handle complex and vector types
6046 if (count != 1)
6047 return false;
6048
6049 llvm::StringRef s_sref(s);
6050 llvm::APFloat ap_float(m_ast->getFloatTypeSemantics(qual_type), s_sref);
6051
6052 const uint64_t bit_size = m_ast->getTypeSize (qual_type);
6053 const uint64_t byte_size = bit_size / 8;
6054 if (dst_size >= byte_size)
6055 {
6056 if (bit_size == sizeof(float)*8)
6057 {
6058 float float32 = ap_float.convertToFloat();
6059 ::memcpy (dst, &float32, byte_size);
6060 return byte_size;
6061 }
6062 else if (bit_size >= 64)
6063 {
6064 llvm::APInt ap_int(ap_float.bitcastToAPInt());
6065 ::memcpy (dst, ap_int.getRawData(), byte_size);
6066 return byte_size;
6067 }
6068 }
6069 }
6070 }
6071 return 0;
6072 }
6073
6074
6075
6076 //----------------------------------------------------------------------
6077 // Dumping types
6078 //----------------------------------------------------------------------
6079 #define DEPTH_INCREMENT 2
6080
6081 void
DumpValue(ExecutionContext * exe_ctx,Stream * s,lldb::Format format,const lldb_private::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)6082 ClangASTType::DumpValue (ExecutionContext *exe_ctx,
6083 Stream *s,
6084 lldb::Format format,
6085 const lldb_private::DataExtractor &data,
6086 lldb::offset_t data_byte_offset,
6087 size_t data_byte_size,
6088 uint32_t bitfield_bit_size,
6089 uint32_t bitfield_bit_offset,
6090 bool show_types,
6091 bool show_summary,
6092 bool verbose,
6093 uint32_t depth)
6094 {
6095 if (!IsValid())
6096 return;
6097
6098 clang::QualType qual_type(GetQualType());
6099 switch (qual_type->getTypeClass())
6100 {
6101 case clang::Type::Record:
6102 if (GetCompleteType ())
6103 {
6104 const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
6105 const clang::RecordDecl *record_decl = record_type->getDecl();
6106 assert(record_decl);
6107 uint32_t field_bit_offset = 0;
6108 uint32_t field_byte_offset = 0;
6109 const clang::ASTRecordLayout &record_layout = m_ast->getASTRecordLayout(record_decl);
6110 uint32_t child_idx = 0;
6111
6112 const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
6113 if (cxx_record_decl)
6114 {
6115 // We might have base classes to print out first
6116 clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
6117 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
6118 base_class != base_class_end;
6119 ++base_class)
6120 {
6121 const clang::CXXRecordDecl *base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl());
6122
6123 // Skip empty base classes
6124 if (verbose == false && ClangASTContext::RecordHasFields(base_class_decl) == false)
6125 continue;
6126
6127 if (base_class->isVirtual())
6128 field_bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
6129 else
6130 field_bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
6131 field_byte_offset = field_bit_offset / 8;
6132 assert (field_bit_offset % 8 == 0);
6133 if (child_idx == 0)
6134 s->PutChar('{');
6135 else
6136 s->PutChar(',');
6137
6138 clang::QualType base_class_qual_type = base_class->getType();
6139 std::string base_class_type_name(base_class_qual_type.getAsString());
6140
6141 // Indent and print the base class type name
6142 s->Printf("\n%*s%s ", depth + DEPTH_INCREMENT, "", base_class_type_name.c_str());
6143
6144 clang::TypeInfo base_class_type_info = m_ast->getTypeInfo(base_class_qual_type);
6145
6146 // Dump the value of the member
6147 ClangASTType base_clang_type(m_ast, base_class_qual_type);
6148 base_clang_type.DumpValue (exe_ctx,
6149 s, // Stream to dump to
6150 base_clang_type.GetFormat(), // The format with which to display the member
6151 data, // Data buffer containing all bytes for this type
6152 data_byte_offset + field_byte_offset,// Offset into "data" where to grab value from
6153 base_class_type_info.Width / 8, // Size of this type in bytes
6154 0, // Bitfield bit size
6155 0, // Bitfield bit offset
6156 show_types, // Boolean indicating if we should show the variable types
6157 show_summary, // Boolean indicating if we should show a summary for the current type
6158 verbose, // Verbose output?
6159 depth + DEPTH_INCREMENT); // Scope depth for any types that have children
6160
6161 ++child_idx;
6162 }
6163 }
6164 uint32_t field_idx = 0;
6165 clang::RecordDecl::field_iterator field, field_end;
6166 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
6167 {
6168 // Print the starting squiggly bracket (if this is the
6169 // first member) or comma (for member 2 and beyond) for
6170 // the struct/union/class member.
6171 if (child_idx == 0)
6172 s->PutChar('{');
6173 else
6174 s->PutChar(',');
6175
6176 // Indent
6177 s->Printf("\n%*s", depth + DEPTH_INCREMENT, "");
6178
6179 clang::QualType field_type = field->getType();
6180 // Print the member type if requested
6181 // Figure out the type byte size (field_type_info.first) and
6182 // alignment (field_type_info.second) from the AST context.
6183 clang::TypeInfo field_type_info = m_ast->getTypeInfo(field_type);
6184 assert(field_idx < record_layout.getFieldCount());
6185 // Figure out the field offset within the current struct/union/class type
6186 field_bit_offset = record_layout.getFieldOffset (field_idx);
6187 field_byte_offset = field_bit_offset / 8;
6188 uint32_t field_bitfield_bit_size = 0;
6189 uint32_t field_bitfield_bit_offset = 0;
6190 if (ClangASTContext::FieldIsBitfield (m_ast, *field, field_bitfield_bit_size))
6191 field_bitfield_bit_offset = field_bit_offset % 8;
6192
6193 if (show_types)
6194 {
6195 std::string field_type_name(field_type.getAsString());
6196 if (field_bitfield_bit_size > 0)
6197 s->Printf("(%s:%u) ", field_type_name.c_str(), field_bitfield_bit_size);
6198 else
6199 s->Printf("(%s) ", field_type_name.c_str());
6200 }
6201 // Print the member name and equal sign
6202 s->Printf("%s = ", field->getNameAsString().c_str());
6203
6204
6205 // Dump the value of the member
6206 ClangASTType field_clang_type (m_ast, field_type);
6207 field_clang_type.DumpValue (exe_ctx,
6208 s, // Stream to dump to
6209 field_clang_type.GetFormat(), // The format with which to display the member
6210 data, // Data buffer containing all bytes for this type
6211 data_byte_offset + field_byte_offset,// Offset into "data" where to grab value from
6212 field_type_info.Width / 8, // Size of this type in bytes
6213 field_bitfield_bit_size, // Bitfield bit size
6214 field_bitfield_bit_offset, // Bitfield bit offset
6215 show_types, // Boolean indicating if we should show the variable types
6216 show_summary, // Boolean indicating if we should show a summary for the current type
6217 verbose, // Verbose output?
6218 depth + DEPTH_INCREMENT); // Scope depth for any types that have children
6219 }
6220
6221 // Indent the trailing squiggly bracket
6222 if (child_idx > 0)
6223 s->Printf("\n%*s}", depth, "");
6224 }
6225 return;
6226
6227 case clang::Type::Enum:
6228 if (GetCompleteType ())
6229 {
6230 const clang::EnumType *enum_type = llvm::cast<clang::EnumType>(qual_type.getTypePtr());
6231 const clang::EnumDecl *enum_decl = enum_type->getDecl();
6232 assert(enum_decl);
6233 clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
6234 lldb::offset_t offset = data_byte_offset;
6235 const int64_t enum_value = data.GetMaxU64Bitfield(&offset, data_byte_size, bitfield_bit_size, bitfield_bit_offset);
6236 for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
6237 {
6238 if (enum_pos->getInitVal() == enum_value)
6239 {
6240 s->Printf("%s", enum_pos->getNameAsString().c_str());
6241 return;
6242 }
6243 }
6244 // If we have gotten here we didn't get find the enumerator in the
6245 // enum decl, so just print the integer.
6246 s->Printf("%" PRIi64, enum_value);
6247 }
6248 return;
6249
6250 case clang::Type::ConstantArray:
6251 {
6252 const clang::ConstantArrayType *array = llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr());
6253 bool is_array_of_characters = false;
6254 clang::QualType element_qual_type = array->getElementType();
6255
6256 const clang::Type *canonical_type = element_qual_type->getCanonicalTypeInternal().getTypePtr();
6257 if (canonical_type)
6258 is_array_of_characters = canonical_type->isCharType();
6259
6260 const uint64_t element_count = array->getSize().getLimitedValue();
6261
6262 clang::TypeInfo field_type_info = m_ast->getTypeInfo(element_qual_type);
6263
6264 uint32_t element_idx = 0;
6265 uint32_t element_offset = 0;
6266 uint64_t element_byte_size = field_type_info.Width / 8;
6267 uint32_t element_stride = element_byte_size;
6268
6269 if (is_array_of_characters)
6270 {
6271 s->PutChar('"');
6272 data.Dump(s, data_byte_offset, lldb::eFormatChar, element_byte_size, element_count, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
6273 s->PutChar('"');
6274 return;
6275 }
6276 else
6277 {
6278 ClangASTType element_clang_type(m_ast, element_qual_type);
6279 lldb::Format element_format = element_clang_type.GetFormat();
6280
6281 for (element_idx = 0; element_idx < element_count; ++element_idx)
6282 {
6283 // Print the starting squiggly bracket (if this is the
6284 // first member) or comma (for member 2 and beyond) for
6285 // the struct/union/class member.
6286 if (element_idx == 0)
6287 s->PutChar('{');
6288 else
6289 s->PutChar(',');
6290
6291 // Indent and print the index
6292 s->Printf("\n%*s[%u] ", depth + DEPTH_INCREMENT, "", element_idx);
6293
6294 // Figure out the field offset within the current struct/union/class type
6295 element_offset = element_idx * element_stride;
6296
6297 // Dump the value of the member
6298 element_clang_type.DumpValue (exe_ctx,
6299 s, // Stream to dump to
6300 element_format, // The format with which to display the element
6301 data, // Data buffer containing all bytes for this type
6302 data_byte_offset + element_offset,// Offset into "data" where to grab value from
6303 element_byte_size, // Size of this type in bytes
6304 0, // Bitfield bit size
6305 0, // Bitfield bit offset
6306 show_types, // Boolean indicating if we should show the variable types
6307 show_summary, // Boolean indicating if we should show a summary for the current type
6308 verbose, // Verbose output?
6309 depth + DEPTH_INCREMENT); // Scope depth for any types that have children
6310 }
6311
6312 // Indent the trailing squiggly bracket
6313 if (element_idx > 0)
6314 s->Printf("\n%*s}", depth, "");
6315 }
6316 }
6317 return;
6318
6319 case clang::Type::Typedef:
6320 {
6321 clang::QualType typedef_qual_type = llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType();
6322
6323 ClangASTType typedef_clang_type (m_ast, typedef_qual_type);
6324 lldb::Format typedef_format = typedef_clang_type.GetFormat();
6325 clang::TypeInfo typedef_type_info = m_ast->getTypeInfo(typedef_qual_type);
6326 uint64_t typedef_byte_size = typedef_type_info.Width / 8;
6327
6328 return typedef_clang_type.DumpValue (exe_ctx,
6329 s, // Stream to dump to
6330 typedef_format, // The format with which to display the element
6331 data, // Data buffer containing all bytes for this type
6332 data_byte_offset, // Offset into "data" where to grab value from
6333 typedef_byte_size, // Size of this type in bytes
6334 bitfield_bit_size, // Bitfield bit size
6335 bitfield_bit_offset,// Bitfield bit offset
6336 show_types, // Boolean indicating if we should show the variable types
6337 show_summary, // Boolean indicating if we should show a summary for the current type
6338 verbose, // Verbose output?
6339 depth); // Scope depth for any types that have children
6340 }
6341 break;
6342
6343 case clang::Type::Elaborated:
6344 {
6345 clang::QualType elaborated_qual_type = llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType();
6346 ClangASTType elaborated_clang_type (m_ast, elaborated_qual_type);
6347 lldb::Format elaborated_format = elaborated_clang_type.GetFormat();
6348 clang::TypeInfo elaborated_type_info = m_ast->getTypeInfo(elaborated_qual_type);
6349 uint64_t elaborated_byte_size = elaborated_type_info.Width / 8;
6350
6351 return elaborated_clang_type.DumpValue (exe_ctx,
6352 s, // Stream to dump to
6353 elaborated_format, // The format with which to display the element
6354 data, // Data buffer containing all bytes for this type
6355 data_byte_offset, // Offset into "data" where to grab value from
6356 elaborated_byte_size, // Size of this type in bytes
6357 bitfield_bit_size, // Bitfield bit size
6358 bitfield_bit_offset,// Bitfield bit offset
6359 show_types, // Boolean indicating if we should show the variable types
6360 show_summary, // Boolean indicating if we should show a summary for the current type
6361 verbose, // Verbose output?
6362 depth); // Scope depth for any types that have children
6363 }
6364 break;
6365
6366 case clang::Type::Paren:
6367 {
6368 clang::QualType desugar_qual_type = llvm::cast<clang::ParenType>(qual_type)->desugar();
6369 ClangASTType desugar_clang_type (m_ast, desugar_qual_type);
6370
6371 lldb::Format desugar_format = desugar_clang_type.GetFormat();
6372 clang::TypeInfo desugar_type_info = m_ast->getTypeInfo(desugar_qual_type);
6373 uint64_t desugar_byte_size = desugar_type_info.Width / 8;
6374
6375 return desugar_clang_type.DumpValue (exe_ctx,
6376 s, // Stream to dump to
6377 desugar_format, // The format with which to display the element
6378 data, // Data buffer containing all bytes for this type
6379 data_byte_offset, // Offset into "data" where to grab value from
6380 desugar_byte_size, // Size of this type in bytes
6381 bitfield_bit_size, // Bitfield bit size
6382 bitfield_bit_offset,// Bitfield bit offset
6383 show_types, // Boolean indicating if we should show the variable types
6384 show_summary, // Boolean indicating if we should show a summary for the current type
6385 verbose, // Verbose output?
6386 depth); // Scope depth for any types that have children
6387 }
6388 break;
6389
6390 default:
6391 // We are down to a scalar type that we just need to display.
6392 data.Dump(s,
6393 data_byte_offset,
6394 format,
6395 data_byte_size,
6396 1,
6397 UINT32_MAX,
6398 LLDB_INVALID_ADDRESS,
6399 bitfield_bit_size,
6400 bitfield_bit_offset);
6401
6402 if (show_summary)
6403 DumpSummary (exe_ctx, s, data, data_byte_offset, data_byte_size);
6404 break;
6405 }
6406 }
6407
6408
6409
6410
6411 bool
DumpTypeValue(Stream * s,lldb::Format format,const lldb_private::DataExtractor & data,lldb::offset_t byte_offset,size_t byte_size,uint32_t bitfield_bit_size,uint32_t bitfield_bit_offset,ExecutionContextScope * exe_scope)6412 ClangASTType::DumpTypeValue (Stream *s,
6413 lldb::Format format,
6414 const lldb_private::DataExtractor &data,
6415 lldb::offset_t byte_offset,
6416 size_t byte_size,
6417 uint32_t bitfield_bit_size,
6418 uint32_t bitfield_bit_offset,
6419 ExecutionContextScope *exe_scope)
6420 {
6421 if (!IsValid())
6422 return false;
6423 if (IsAggregateType())
6424 {
6425 return false;
6426 }
6427 else
6428 {
6429 clang::QualType qual_type(GetQualType());
6430
6431 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6432 switch (type_class)
6433 {
6434 case clang::Type::Typedef:
6435 {
6436 clang::QualType typedef_qual_type = llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType();
6437 ClangASTType typedef_clang_type (m_ast, typedef_qual_type);
6438 if (format == eFormatDefault)
6439 format = typedef_clang_type.GetFormat();
6440 clang::TypeInfo typedef_type_info = m_ast->getTypeInfo(typedef_qual_type);
6441 uint64_t typedef_byte_size = typedef_type_info.Width / 8;
6442
6443 return typedef_clang_type.DumpTypeValue (s,
6444 format, // The format with which to display the element
6445 data, // Data buffer containing all bytes for this type
6446 byte_offset, // Offset into "data" where to grab value from
6447 typedef_byte_size, // Size of this type in bytes
6448 bitfield_bit_size, // Size in bits of a bitfield value, if zero don't treat as a bitfield
6449 bitfield_bit_offset, // Offset in bits of a bitfield value if bitfield_bit_size != 0
6450 exe_scope);
6451 }
6452 break;
6453
6454 case clang::Type::Enum:
6455 // If our format is enum or default, show the enumeration value as
6456 // its enumeration string value, else just display it as requested.
6457 if ((format == eFormatEnum || format == eFormatDefault) && GetCompleteType ())
6458 {
6459 const clang::EnumType *enum_type = llvm::cast<clang::EnumType>(qual_type.getTypePtr());
6460 const clang::EnumDecl *enum_decl = enum_type->getDecl();
6461 assert(enum_decl);
6462 clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
6463 const bool is_signed = qual_type->isSignedIntegerOrEnumerationType();
6464 lldb::offset_t offset = byte_offset;
6465 if (is_signed)
6466 {
6467 const int64_t enum_svalue = data.GetMaxS64Bitfield (&offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
6468 for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
6469 {
6470 if (enum_pos->getInitVal().getSExtValue() == enum_svalue)
6471 {
6472 s->PutCString (enum_pos->getNameAsString().c_str());
6473 return true;
6474 }
6475 }
6476 // If we have gotten here we didn't get find the enumerator in the
6477 // enum decl, so just print the integer.
6478 s->Printf("%" PRIi64, enum_svalue);
6479 }
6480 else
6481 {
6482 const uint64_t enum_uvalue = data.GetMaxU64Bitfield (&offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
6483 for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
6484 {
6485 if (enum_pos->getInitVal().getZExtValue() == enum_uvalue)
6486 {
6487 s->PutCString (enum_pos->getNameAsString().c_str());
6488 return true;
6489 }
6490 }
6491 // If we have gotten here we didn't get find the enumerator in the
6492 // enum decl, so just print the integer.
6493 s->Printf("%" PRIu64, enum_uvalue);
6494 }
6495 return true;
6496 }
6497 // format was not enum, just fall through and dump the value as requested....
6498
6499 default:
6500 // We are down to a scalar type that we just need to display.
6501 {
6502 uint32_t item_count = 1;
6503 // A few formats, we might need to modify our size and count for depending
6504 // on how we are trying to display the value...
6505 switch (format)
6506 {
6507 default:
6508 case eFormatBoolean:
6509 case eFormatBinary:
6510 case eFormatComplex:
6511 case eFormatCString: // NULL terminated C strings
6512 case eFormatDecimal:
6513 case eFormatEnum:
6514 case eFormatHex:
6515 case eFormatHexUppercase:
6516 case eFormatFloat:
6517 case eFormatOctal:
6518 case eFormatOSType:
6519 case eFormatUnsigned:
6520 case eFormatPointer:
6521 case eFormatVectorOfChar:
6522 case eFormatVectorOfSInt8:
6523 case eFormatVectorOfUInt8:
6524 case eFormatVectorOfSInt16:
6525 case eFormatVectorOfUInt16:
6526 case eFormatVectorOfSInt32:
6527 case eFormatVectorOfUInt32:
6528 case eFormatVectorOfSInt64:
6529 case eFormatVectorOfUInt64:
6530 case eFormatVectorOfFloat32:
6531 case eFormatVectorOfFloat64:
6532 case eFormatVectorOfUInt128:
6533 break;
6534
6535 case eFormatChar:
6536 case eFormatCharPrintable:
6537 case eFormatCharArray:
6538 case eFormatBytes:
6539 case eFormatBytesWithASCII:
6540 item_count = byte_size;
6541 byte_size = 1;
6542 break;
6543
6544 case eFormatUnicode16:
6545 item_count = byte_size / 2;
6546 byte_size = 2;
6547 break;
6548
6549 case eFormatUnicode32:
6550 item_count = byte_size / 4;
6551 byte_size = 4;
6552 break;
6553 }
6554 return data.Dump (s,
6555 byte_offset,
6556 format,
6557 byte_size,
6558 item_count,
6559 UINT32_MAX,
6560 LLDB_INVALID_ADDRESS,
6561 bitfield_bit_size,
6562 bitfield_bit_offset,
6563 exe_scope);
6564 }
6565 break;
6566 }
6567 }
6568 return 0;
6569 }
6570
6571
6572
6573 void
DumpSummary(ExecutionContext * exe_ctx,Stream * s,const lldb_private::DataExtractor & data,lldb::offset_t data_byte_offset,size_t data_byte_size)6574 ClangASTType::DumpSummary (ExecutionContext *exe_ctx,
6575 Stream *s,
6576 const lldb_private::DataExtractor &data,
6577 lldb::offset_t data_byte_offset,
6578 size_t data_byte_size)
6579 {
6580 uint32_t length = 0;
6581 if (IsCStringType (length))
6582 {
6583 if (exe_ctx)
6584 {
6585 Process *process = exe_ctx->GetProcessPtr();
6586 if (process)
6587 {
6588 lldb::offset_t offset = data_byte_offset;
6589 lldb::addr_t pointer_address = data.GetMaxU64(&offset, data_byte_size);
6590 std::vector<uint8_t> buf;
6591 if (length > 0)
6592 buf.resize (length);
6593 else
6594 buf.resize (256);
6595
6596 lldb_private::DataExtractor cstr_data(&buf.front(), buf.size(), process->GetByteOrder(), 4);
6597 buf.back() = '\0';
6598 size_t bytes_read;
6599 size_t total_cstr_len = 0;
6600 Error error;
6601 while ((bytes_read = process->ReadMemory (pointer_address, &buf.front(), buf.size(), error)) > 0)
6602 {
6603 const size_t len = strlen((const char *)&buf.front());
6604 if (len == 0)
6605 break;
6606 if (total_cstr_len == 0)
6607 s->PutCString (" \"");
6608 cstr_data.Dump(s, 0, lldb::eFormatChar, 1, len, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
6609 total_cstr_len += len;
6610 if (len < buf.size())
6611 break;
6612 pointer_address += total_cstr_len;
6613 }
6614 if (total_cstr_len > 0)
6615 s->PutChar ('"');
6616 }
6617 }
6618 }
6619 }
6620
6621 void
DumpTypeDescription() const6622 ClangASTType::DumpTypeDescription () const
6623 {
6624 StreamFile s (stdout, false);
6625 DumpTypeDescription (&s);
6626 ClangASTMetadata *metadata = ClangASTContext::GetMetadata (m_ast, m_type);
6627 if (metadata)
6628 {
6629 metadata->Dump (&s);
6630 }
6631 }
6632
6633 void
DumpTypeDescription(Stream * s) const6634 ClangASTType::DumpTypeDescription (Stream *s) const
6635 {
6636 if (IsValid())
6637 {
6638 clang::QualType qual_type(GetQualType());
6639
6640 llvm::SmallVector<char, 1024> buf;
6641 llvm::raw_svector_ostream llvm_ostrm (buf);
6642
6643 const clang::Type::TypeClass type_class = qual_type->getTypeClass();
6644 switch (type_class)
6645 {
6646 case clang::Type::ObjCObject:
6647 case clang::Type::ObjCInterface:
6648 {
6649 GetCompleteType ();
6650
6651 const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
6652 assert (objc_class_type);
6653 if (objc_class_type)
6654 {
6655 clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
6656 if (class_interface_decl)
6657 {
6658 clang::PrintingPolicy policy = m_ast->getPrintingPolicy();
6659 class_interface_decl->print(llvm_ostrm, policy, s->GetIndentLevel());
6660 }
6661 }
6662 }
6663 break;
6664
6665 case clang::Type::Typedef:
6666 {
6667 const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
6668 if (typedef_type)
6669 {
6670 const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
6671 std::string clang_typedef_name (typedef_decl->getQualifiedNameAsString());
6672 if (!clang_typedef_name.empty())
6673 {
6674 s->PutCString ("typedef ");
6675 s->PutCString (clang_typedef_name.c_str());
6676 }
6677 }
6678 }
6679 break;
6680
6681 case clang::Type::Elaborated:
6682 ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).DumpTypeDescription(s);
6683 return;
6684
6685 case clang::Type::Paren:
6686 ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).DumpTypeDescription(s);
6687 return;
6688
6689 case clang::Type::Record:
6690 {
6691 GetCompleteType ();
6692
6693 const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
6694 const clang::RecordDecl *record_decl = record_type->getDecl();
6695 const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
6696
6697 if (cxx_record_decl)
6698 cxx_record_decl->print(llvm_ostrm, m_ast->getPrintingPolicy(), s->GetIndentLevel());
6699 else
6700 record_decl->print(llvm_ostrm, m_ast->getPrintingPolicy(), s->GetIndentLevel());
6701 }
6702 break;
6703
6704 default:
6705 {
6706 const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
6707 if (tag_type)
6708 {
6709 clang::TagDecl *tag_decl = tag_type->getDecl();
6710 if (tag_decl)
6711 tag_decl->print(llvm_ostrm, 0);
6712 }
6713 else
6714 {
6715 std::string clang_type_name(qual_type.getAsString());
6716 if (!clang_type_name.empty())
6717 s->PutCString (clang_type_name.c_str());
6718 }
6719 }
6720 }
6721
6722 llvm_ostrm.flush();
6723 if (buf.size() > 0)
6724 {
6725 s->Write (buf.data(), buf.size());
6726 }
6727 }
6728 }
6729
6730 bool
GetValueAsScalar(const lldb_private::DataExtractor & data,lldb::offset_t data_byte_offset,size_t data_byte_size,Scalar & value) const6731 ClangASTType::GetValueAsScalar (const lldb_private::DataExtractor &data,
6732 lldb::offset_t data_byte_offset,
6733 size_t data_byte_size,
6734 Scalar &value) const
6735 {
6736 if (!IsValid())
6737 return false;
6738
6739 if (IsAggregateType ())
6740 {
6741 return false; // Aggregate types don't have scalar values
6742 }
6743 else
6744 {
6745 uint64_t count = 0;
6746 lldb::Encoding encoding = GetEncoding (count);
6747
6748 if (encoding == lldb::eEncodingInvalid || count != 1)
6749 return false;
6750
6751 const uint64_t byte_size = GetByteSize(nullptr);
6752 lldb::offset_t offset = data_byte_offset;
6753 switch (encoding)
6754 {
6755 case lldb::eEncodingInvalid:
6756 break;
6757 case lldb::eEncodingVector:
6758 break;
6759 case lldb::eEncodingUint:
6760 if (byte_size <= sizeof(unsigned long long))
6761 {
6762 uint64_t uval64 = data.GetMaxU64 (&offset, byte_size);
6763 if (byte_size <= sizeof(unsigned int))
6764 {
6765 value = (unsigned int)uval64;
6766 return true;
6767 }
6768 else if (byte_size <= sizeof(unsigned long))
6769 {
6770 value = (unsigned long)uval64;
6771 return true;
6772 }
6773 else if (byte_size <= sizeof(unsigned long long))
6774 {
6775 value = (unsigned long long )uval64;
6776 return true;
6777 }
6778 else
6779 value.Clear();
6780 }
6781 break;
6782
6783 case lldb::eEncodingSint:
6784 if (byte_size <= sizeof(long long))
6785 {
6786 int64_t sval64 = data.GetMaxS64 (&offset, byte_size);
6787 if (byte_size <= sizeof(int))
6788 {
6789 value = (int)sval64;
6790 return true;
6791 }
6792 else if (byte_size <= sizeof(long))
6793 {
6794 value = (long)sval64;
6795 return true;
6796 }
6797 else if (byte_size <= sizeof(long long))
6798 {
6799 value = (long long )sval64;
6800 return true;
6801 }
6802 else
6803 value.Clear();
6804 }
6805 break;
6806
6807 case lldb::eEncodingIEEE754:
6808 if (byte_size <= sizeof(long double))
6809 {
6810 uint32_t u32;
6811 uint64_t u64;
6812 if (byte_size == sizeof(float))
6813 {
6814 if (sizeof(float) == sizeof(uint32_t))
6815 {
6816 u32 = data.GetU32(&offset);
6817 value = *((float *)&u32);
6818 return true;
6819 }
6820 else if (sizeof(float) == sizeof(uint64_t))
6821 {
6822 u64 = data.GetU64(&offset);
6823 value = *((float *)&u64);
6824 return true;
6825 }
6826 }
6827 else
6828 if (byte_size == sizeof(double))
6829 {
6830 if (sizeof(double) == sizeof(uint32_t))
6831 {
6832 u32 = data.GetU32(&offset);
6833 value = *((double *)&u32);
6834 return true;
6835 }
6836 else if (sizeof(double) == sizeof(uint64_t))
6837 {
6838 u64 = data.GetU64(&offset);
6839 value = *((double *)&u64);
6840 return true;
6841 }
6842 }
6843 else
6844 if (byte_size == sizeof(long double))
6845 {
6846 if (sizeof(long double) == sizeof(uint32_t))
6847 {
6848 u32 = data.GetU32(&offset);
6849 value = *((long double *)&u32);
6850 return true;
6851 }
6852 else if (sizeof(long double) == sizeof(uint64_t))
6853 {
6854 u64 = data.GetU64(&offset);
6855 value = *((long double *)&u64);
6856 return true;
6857 }
6858 }
6859 }
6860 break;
6861 }
6862 }
6863 return false;
6864 }
6865
6866 bool
SetValueFromScalar(const Scalar & value,Stream & strm)6867 ClangASTType::SetValueFromScalar (const Scalar &value, Stream &strm)
6868 {
6869 // Aggregate types don't have scalar values
6870 if (!IsAggregateType ())
6871 {
6872 strm.GetFlags().Set(Stream::eBinary);
6873 uint64_t count = 0;
6874 lldb::Encoding encoding = GetEncoding (count);
6875
6876 if (encoding == lldb::eEncodingInvalid || count != 1)
6877 return false;
6878
6879 const uint64_t bit_width = GetBitSize(nullptr);
6880 // This function doesn't currently handle non-byte aligned assignments
6881 if ((bit_width % 8) != 0)
6882 return false;
6883
6884 const uint64_t byte_size = (bit_width + 7 ) / 8;
6885 switch (encoding)
6886 {
6887 case lldb::eEncodingInvalid:
6888 break;
6889 case lldb::eEncodingVector:
6890 break;
6891 case lldb::eEncodingUint:
6892 switch (byte_size)
6893 {
6894 case 1: strm.PutHex8(value.UInt()); return true;
6895 case 2: strm.PutHex16(value.UInt()); return true;
6896 case 4: strm.PutHex32(value.UInt()); return true;
6897 case 8: strm.PutHex64(value.ULongLong()); return true;
6898 default:
6899 break;
6900 }
6901 break;
6902
6903 case lldb::eEncodingSint:
6904 switch (byte_size)
6905 {
6906 case 1: strm.PutHex8(value.SInt()); return true;
6907 case 2: strm.PutHex16(value.SInt()); return true;
6908 case 4: strm.PutHex32(value.SInt()); return true;
6909 case 8: strm.PutHex64(value.SLongLong()); return true;
6910 default:
6911 break;
6912 }
6913 break;
6914
6915 case lldb::eEncodingIEEE754:
6916 if (byte_size <= sizeof(long double))
6917 {
6918 if (byte_size == sizeof(float))
6919 {
6920 strm.PutFloat(value.Float());
6921 return true;
6922 }
6923 else
6924 if (byte_size == sizeof(double))
6925 {
6926 strm.PutDouble(value.Double());
6927 return true;
6928 }
6929 else
6930 if (byte_size == sizeof(long double))
6931 {
6932 strm.PutDouble(value.LongDouble());
6933 return true;
6934 }
6935 }
6936 break;
6937 }
6938 }
6939 return false;
6940 }
6941
6942 bool
ReadFromMemory(lldb_private::ExecutionContext * exe_ctx,lldb::addr_t addr,AddressType address_type,lldb_private::DataExtractor & data)6943 ClangASTType::ReadFromMemory (lldb_private::ExecutionContext *exe_ctx,
6944 lldb::addr_t addr,
6945 AddressType address_type,
6946 lldb_private::DataExtractor &data)
6947 {
6948 if (!IsValid())
6949 return false;
6950
6951 // Can't convert a file address to anything valid without more
6952 // context (which Module it came from)
6953 if (address_type == eAddressTypeFile)
6954 return false;
6955
6956 if (!GetCompleteType())
6957 return false;
6958
6959 const uint64_t byte_size = GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
6960 if (data.GetByteSize() < byte_size)
6961 {
6962 lldb::DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0'));
6963 data.SetData(data_sp);
6964 }
6965
6966 uint8_t* dst = (uint8_t*)data.PeekData(0, byte_size);
6967 if (dst != nullptr)
6968 {
6969 if (address_type == eAddressTypeHost)
6970 {
6971 if (addr == 0)
6972 return false;
6973 // The address is an address in this process, so just copy it
6974 memcpy (dst, (uint8_t*)nullptr + addr, byte_size);
6975 return true;
6976 }
6977 else
6978 {
6979 Process *process = nullptr;
6980 if (exe_ctx)
6981 process = exe_ctx->GetProcessPtr();
6982 if (process)
6983 {
6984 Error error;
6985 return process->ReadMemory(addr, dst, byte_size, error) == byte_size;
6986 }
6987 }
6988 }
6989 return false;
6990 }
6991
6992 bool
WriteToMemory(lldb_private::ExecutionContext * exe_ctx,lldb::addr_t addr,AddressType address_type,StreamString & new_value)6993 ClangASTType::WriteToMemory (lldb_private::ExecutionContext *exe_ctx,
6994 lldb::addr_t addr,
6995 AddressType address_type,
6996 StreamString &new_value)
6997 {
6998 if (!IsValid())
6999 return false;
7000
7001 // Can't convert a file address to anything valid without more
7002 // context (which Module it came from)
7003 if (address_type == eAddressTypeFile)
7004 return false;
7005
7006 if (!GetCompleteType())
7007 return false;
7008
7009 const uint64_t byte_size = GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
7010
7011 if (byte_size > 0)
7012 {
7013 if (address_type == eAddressTypeHost)
7014 {
7015 // The address is an address in this process, so just copy it
7016 memcpy ((void *)addr, new_value.GetData(), byte_size);
7017 return true;
7018 }
7019 else
7020 {
7021 Process *process = nullptr;
7022 if (exe_ctx)
7023 process = exe_ctx->GetProcessPtr();
7024 if (process)
7025 {
7026 Error error;
7027 return process->WriteMemory(addr, new_value.GetData(), byte_size, error) == byte_size;
7028 }
7029 }
7030 }
7031 return false;
7032 }
7033
7034
7035 //clang::CXXRecordDecl *
7036 //ClangASTType::GetAsCXXRecordDecl (lldb::clang_type_t opaque_clang_qual_type)
7037 //{
7038 // if (opaque_clang_qual_type)
7039 // return clang::QualType::getFromOpaquePtr(opaque_clang_qual_type)->getAsCXXRecordDecl();
7040 // return NULL;
7041 //}
7042
7043 bool
operator ==(const lldb_private::ClangASTType & lhs,const lldb_private::ClangASTType & rhs)7044 lldb_private::operator == (const lldb_private::ClangASTType &lhs, const lldb_private::ClangASTType &rhs)
7045 {
7046 return lhs.GetASTContext() == rhs.GetASTContext() && lhs.GetOpaqueQualType() == rhs.GetOpaqueQualType();
7047 }
7048
7049
7050 bool
operator !=(const lldb_private::ClangASTType & lhs,const lldb_private::ClangASTType & rhs)7051 lldb_private::operator != (const lldb_private::ClangASTType &lhs, const lldb_private::ClangASTType &rhs)
7052 {
7053 return lhs.GetASTContext() != rhs.GetASTContext() || lhs.GetOpaqueQualType() != rhs.GetOpaqueQualType();
7054 }
7055
7056
7057
7058