1 //===-- SBType.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/API/SBDefines.h"
11 #include "lldb/API/SBType.h"
12 #include "lldb/API/SBStream.h"
13 #include "lldb/Core/ConstString.h"
14 #include "lldb/Core/Log.h"
15 #include "lldb/Core/Stream.h"
16 #include "lldb/Symbol/ClangASTContext.h"
17 #include "lldb/Symbol/ClangASTType.h"
18 #include "lldb/Symbol/Type.h"
19
20 using namespace lldb;
21 using namespace lldb_private;
22 using namespace clang;
23
SBType()24 SBType::SBType() :
25 m_opaque_sp()
26 {
27 }
28
SBType(const ClangASTType & type)29 SBType::SBType (const ClangASTType &type) :
30 m_opaque_sp(new TypeImpl(ClangASTType(type.GetASTContext(),
31 type.GetOpaqueQualType())))
32 {
33 }
34
SBType(const lldb::TypeSP & type_sp)35 SBType::SBType (const lldb::TypeSP &type_sp) :
36 m_opaque_sp(new TypeImpl(type_sp))
37 {
38 }
39
SBType(const lldb::TypeImplSP & type_impl_sp)40 SBType::SBType (const lldb::TypeImplSP &type_impl_sp) :
41 m_opaque_sp(type_impl_sp)
42 {
43 }
44
45
SBType(const SBType & rhs)46 SBType::SBType (const SBType &rhs) :
47 m_opaque_sp()
48 {
49 if (this != &rhs)
50 {
51 m_opaque_sp = rhs.m_opaque_sp;
52 }
53 }
54
55
56 //SBType::SBType (TypeImpl* impl) :
57 // m_opaque_ap(impl)
58 //{}
59 //
60 bool
operator ==(SBType & rhs)61 SBType::operator == (SBType &rhs)
62 {
63 if (IsValid() == false)
64 return !rhs.IsValid();
65
66 if (rhs.IsValid() == false)
67 return false;
68
69 return *m_opaque_sp.get() == *rhs.m_opaque_sp.get();
70 }
71
72 bool
operator !=(SBType & rhs)73 SBType::operator != (SBType &rhs)
74 {
75 if (IsValid() == false)
76 return rhs.IsValid();
77
78 if (rhs.IsValid() == false)
79 return true;
80
81 return *m_opaque_sp.get() != *rhs.m_opaque_sp.get();
82 }
83
84 lldb::TypeImplSP
GetSP()85 SBType::GetSP ()
86 {
87 return m_opaque_sp;
88 }
89
90
91 void
SetSP(const lldb::TypeImplSP & type_impl_sp)92 SBType::SetSP (const lldb::TypeImplSP &type_impl_sp)
93 {
94 m_opaque_sp = type_impl_sp;
95 }
96
97 SBType &
operator =(const SBType & rhs)98 SBType::operator = (const SBType &rhs)
99 {
100 if (this != &rhs)
101 {
102 m_opaque_sp = rhs.m_opaque_sp;
103 }
104 return *this;
105 }
106
~SBType()107 SBType::~SBType ()
108 {}
109
110 TypeImpl &
ref()111 SBType::ref ()
112 {
113 if (m_opaque_sp.get() == NULL)
114 m_opaque_sp.reset (new TypeImpl());
115 return *m_opaque_sp;
116 }
117
118 const TypeImpl &
ref() const119 SBType::ref () const
120 {
121 // "const SBAddress &addr" should already have checked "addr.IsValid()"
122 // prior to calling this function. In case you didn't we will assert
123 // and die to let you know.
124 assert (m_opaque_sp.get());
125 return *m_opaque_sp;
126 }
127
128 bool
IsValid() const129 SBType::IsValid() const
130 {
131 if (m_opaque_sp.get() == NULL)
132 return false;
133
134 return m_opaque_sp->IsValid();
135 }
136
137 uint64_t
GetByteSize()138 SBType::GetByteSize()
139 {
140 if (!IsValid())
141 return 0;
142
143 return m_opaque_sp->GetClangASTType(false).GetByteSize();
144
145 }
146
147 bool
IsPointerType()148 SBType::IsPointerType()
149 {
150 if (!IsValid())
151 return false;
152 return m_opaque_sp->GetClangASTType(true).IsPointerType();
153 }
154
155 bool
IsReferenceType()156 SBType::IsReferenceType()
157 {
158 if (!IsValid())
159 return false;
160 return m_opaque_sp->GetClangASTType(true).IsReferenceType();
161 }
162
163 SBType
GetPointerType()164 SBType::GetPointerType()
165 {
166 if (!IsValid())
167 return SBType();
168
169 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetPointerType())));
170 }
171
172 SBType
GetPointeeType()173 SBType::GetPointeeType()
174 {
175 if (!IsValid())
176 return SBType();
177 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetPointeeType())));
178 }
179
180 SBType
GetReferenceType()181 SBType::GetReferenceType()
182 {
183 if (!IsValid())
184 return SBType();
185 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetReferenceType())));
186 }
187
188 SBType
GetTypedefedType()189 SBType::GetTypedefedType()
190 {
191 if (!IsValid())
192 return SBType();
193 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetTypedefedType())));
194 }
195
196 SBType
GetDereferencedType()197 SBType::GetDereferencedType()
198 {
199 if (!IsValid())
200 return SBType();
201 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetDereferencedType())));
202 }
203
204 bool
IsFunctionType()205 SBType::IsFunctionType ()
206 {
207 if (!IsValid())
208 return false;
209 return m_opaque_sp->GetClangASTType(true).IsFunctionType();
210 }
211
212 bool
IsPolymorphicClass()213 SBType::IsPolymorphicClass ()
214 {
215 if (!IsValid())
216 return false;
217 return m_opaque_sp->GetClangASTType(true).IsPolymorphicClass();
218 }
219
220
221
222 lldb::SBType
GetFunctionReturnType()223 SBType::GetFunctionReturnType ()
224 {
225 if (IsValid())
226 {
227 ClangASTType return_clang_type (m_opaque_sp->GetClangASTType(true).GetFunctionReturnType());
228 if (return_clang_type.IsValid())
229 return SBType(return_clang_type);
230 }
231 return lldb::SBType();
232 }
233
234 lldb::SBTypeList
GetFunctionArgumentTypes()235 SBType::GetFunctionArgumentTypes ()
236 {
237 SBTypeList sb_type_list;
238 if (IsValid())
239 {
240 ClangASTType func_type(m_opaque_sp->GetClangASTType(true));
241 size_t count = func_type.GetNumberOfFunctionArguments();
242 for (size_t i = 0;
243 i < count;
244 i++)
245 {
246 sb_type_list.Append(SBType(func_type.GetFunctionArgumentAtIndex(i)));
247 }
248 }
249 return sb_type_list;
250 }
251
252 lldb::SBType
GetUnqualifiedType()253 SBType::GetUnqualifiedType()
254 {
255 if (!IsValid())
256 return SBType();
257 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetUnqualifiedType())));
258 }
259
260 lldb::SBType
GetCanonicalType()261 SBType::GetCanonicalType()
262 {
263 if (IsValid())
264 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetCanonicalType())));
265 return SBType();
266 }
267
268
269 lldb::BasicType
GetBasicType()270 SBType::GetBasicType()
271 {
272 if (IsValid())
273 return m_opaque_sp->GetClangASTType(false).GetBasicTypeEnumeration ();
274 return eBasicTypeInvalid;
275 }
276
277 SBType
GetBasicType(lldb::BasicType basic_type)278 SBType::GetBasicType(lldb::BasicType basic_type)
279 {
280 if (IsValid())
281 return SBType (ClangASTContext::GetBasicType (m_opaque_sp->GetClangASTContext(false), basic_type));
282 return SBType();
283 }
284
285 uint32_t
GetNumberOfDirectBaseClasses()286 SBType::GetNumberOfDirectBaseClasses ()
287 {
288 if (IsValid())
289 return m_opaque_sp->GetClangASTType(true).GetNumDirectBaseClasses();
290 return 0;
291 }
292
293 uint32_t
GetNumberOfVirtualBaseClasses()294 SBType::GetNumberOfVirtualBaseClasses ()
295 {
296 if (IsValid())
297 return m_opaque_sp->GetClangASTType(true).GetNumVirtualBaseClasses();
298 return 0;
299 }
300
301 uint32_t
GetNumberOfFields()302 SBType::GetNumberOfFields ()
303 {
304 if (IsValid())
305 return m_opaque_sp->GetClangASTType(false).GetNumFields();
306 return 0;
307 }
308
309 bool
GetDescription(SBStream & description,lldb::DescriptionLevel description_level)310 SBType::GetDescription (SBStream &description, lldb::DescriptionLevel description_level)
311 {
312 Stream &strm = description.ref();
313
314 if (m_opaque_sp)
315 {
316 m_opaque_sp->GetDescription (strm, description_level);
317 }
318 else
319 strm.PutCString ("No value");
320
321 return true;
322 }
323
324
325
326 SBTypeMember
GetDirectBaseClassAtIndex(uint32_t idx)327 SBType::GetDirectBaseClassAtIndex (uint32_t idx)
328 {
329 SBTypeMember sb_type_member;
330 if (IsValid())
331 {
332 ClangASTType this_type (m_opaque_sp->GetClangASTType (true));
333 if (this_type.IsValid())
334 {
335 uint32_t bit_offset = 0;
336 ClangASTType base_class_type (this_type.GetDirectBaseClassAtIndex(idx, &bit_offset));
337 if (base_class_type.IsValid())
338 {
339 sb_type_member.reset (new TypeMemberImpl (TypeImplSP(new TypeImpl(base_class_type)), bit_offset));
340 }
341 }
342 }
343 return sb_type_member;
344
345 }
346
347 SBTypeMember
GetVirtualBaseClassAtIndex(uint32_t idx)348 SBType::GetVirtualBaseClassAtIndex (uint32_t idx)
349 {
350 SBTypeMember sb_type_member;
351 if (IsValid())
352 {
353 ClangASTType this_type (m_opaque_sp->GetClangASTType (true));
354 if (this_type.IsValid())
355 {
356 uint32_t bit_offset = 0;
357 ClangASTType base_class_type (this_type.GetVirtualBaseClassAtIndex(idx, &bit_offset));
358 if (base_class_type.IsValid())
359 {
360 sb_type_member.reset (new TypeMemberImpl (TypeImplSP(new TypeImpl(base_class_type)), bit_offset));
361 }
362 }
363 }
364 return sb_type_member;
365 }
366
367 SBTypeMember
GetFieldAtIndex(uint32_t idx)368 SBType::GetFieldAtIndex (uint32_t idx)
369 {
370 SBTypeMember sb_type_member;
371 if (IsValid())
372 {
373 ClangASTType this_type (m_opaque_sp->GetClangASTType (false));
374 if (this_type.IsValid())
375 {
376 uint64_t bit_offset = 0;
377 uint32_t bitfield_bit_size = 0;
378 bool is_bitfield = false;
379 std::string name_sstr;
380 ClangASTType field_type (this_type.GetFieldAtIndex (idx,
381 name_sstr,
382 &bit_offset,
383 &bitfield_bit_size,
384 &is_bitfield));
385 if (field_type.IsValid())
386 {
387 ConstString name;
388 if (!name_sstr.empty())
389 name.SetCString(name_sstr.c_str());
390 sb_type_member.reset (new TypeMemberImpl (TypeImplSP (new TypeImpl(field_type)),
391 bit_offset,
392 name,
393 bitfield_bit_size,
394 is_bitfield));
395 }
396 }
397 }
398 return sb_type_member;
399 }
400
401 bool
IsTypeComplete()402 SBType::IsTypeComplete()
403 {
404 if (!IsValid())
405 return false;
406 return m_opaque_sp->GetClangASTType(false).IsCompleteType();
407 }
408
409 const char*
GetName()410 SBType::GetName()
411 {
412 if (!IsValid())
413 return "";
414 return m_opaque_sp->GetName().GetCString();
415 }
416
417 lldb::TypeClass
GetTypeClass()418 SBType::GetTypeClass ()
419 {
420 if (IsValid())
421 return m_opaque_sp->GetClangASTType(false).GetTypeClass();
422 return lldb::eTypeClassInvalid;
423 }
424
425 uint32_t
GetNumberOfTemplateArguments()426 SBType::GetNumberOfTemplateArguments ()
427 {
428 if (IsValid())
429 return m_opaque_sp->GetClangASTType(false).GetNumTemplateArguments();
430 return 0;
431 }
432
433 lldb::SBType
GetTemplateArgumentType(uint32_t idx)434 SBType::GetTemplateArgumentType (uint32_t idx)
435 {
436 if (IsValid())
437 {
438 TemplateArgumentKind kind = eTemplateArgumentKindNull;
439 ClangASTType template_arg_type = m_opaque_sp->GetClangASTType(false).GetTemplateArgument (idx, kind);
440 if (template_arg_type.IsValid())
441 return SBType(template_arg_type);
442 }
443 return SBType();
444 }
445
446
447 lldb::TemplateArgumentKind
GetTemplateArgumentKind(uint32_t idx)448 SBType::GetTemplateArgumentKind (uint32_t idx)
449 {
450 TemplateArgumentKind kind = eTemplateArgumentKindNull;
451 if (IsValid())
452 m_opaque_sp->GetClangASTType(false).GetTemplateArgument (idx, kind);
453 return kind;
454 }
455
456
SBTypeList()457 SBTypeList::SBTypeList() :
458 m_opaque_ap(new TypeListImpl())
459 {
460 }
461
SBTypeList(const SBTypeList & rhs)462 SBTypeList::SBTypeList(const SBTypeList& rhs) :
463 m_opaque_ap(new TypeListImpl())
464 {
465 for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++)
466 Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i));
467 }
468
469 bool
IsValid()470 SBTypeList::IsValid ()
471 {
472 return (m_opaque_ap.get() != NULL);
473 }
474
475 SBTypeList&
operator =(const SBTypeList & rhs)476 SBTypeList::operator = (const SBTypeList& rhs)
477 {
478 if (this != &rhs)
479 {
480 m_opaque_ap.reset (new TypeListImpl());
481 for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++)
482 Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i));
483 }
484 return *this;
485 }
486
487 void
Append(SBType type)488 SBTypeList::Append (SBType type)
489 {
490 if (type.IsValid())
491 m_opaque_ap->Append (type.m_opaque_sp);
492 }
493
494 SBType
GetTypeAtIndex(uint32_t index)495 SBTypeList::GetTypeAtIndex(uint32_t index)
496 {
497 if (m_opaque_ap.get())
498 return SBType(m_opaque_ap->GetTypeAtIndex(index));
499 return SBType();
500 }
501
502 uint32_t
GetSize()503 SBTypeList::GetSize()
504 {
505 return m_opaque_ap->GetSize();
506 }
507
~SBTypeList()508 SBTypeList::~SBTypeList()
509 {
510 }
511
SBTypeMember()512 SBTypeMember::SBTypeMember() :
513 m_opaque_ap()
514 {
515 }
516
~SBTypeMember()517 SBTypeMember::~SBTypeMember()
518 {
519 }
520
SBTypeMember(const SBTypeMember & rhs)521 SBTypeMember::SBTypeMember (const SBTypeMember& rhs) :
522 m_opaque_ap()
523 {
524 if (this != &rhs)
525 {
526 if (rhs.IsValid())
527 m_opaque_ap.reset(new TypeMemberImpl(rhs.ref()));
528 }
529 }
530
531 lldb::SBTypeMember&
operator =(const lldb::SBTypeMember & rhs)532 SBTypeMember::operator = (const lldb::SBTypeMember& rhs)
533 {
534 if (this != &rhs)
535 {
536 if (rhs.IsValid())
537 m_opaque_ap.reset(new TypeMemberImpl(rhs.ref()));
538 }
539 return *this;
540 }
541
542 bool
IsValid() const543 SBTypeMember::IsValid() const
544 {
545 return m_opaque_ap.get();
546 }
547
548 const char *
GetName()549 SBTypeMember::GetName ()
550 {
551 if (m_opaque_ap.get())
552 return m_opaque_ap->GetName().GetCString();
553 return NULL;
554 }
555
556 SBType
GetType()557 SBTypeMember::GetType ()
558 {
559 SBType sb_type;
560 if (m_opaque_ap.get())
561 {
562 sb_type.SetSP (m_opaque_ap->GetTypeImpl());
563 }
564 return sb_type;
565
566 }
567
568 uint64_t
GetOffsetInBytes()569 SBTypeMember::GetOffsetInBytes()
570 {
571 if (m_opaque_ap.get())
572 return m_opaque_ap->GetBitOffset() / 8u;
573 return 0;
574 }
575
576 uint64_t
GetOffsetInBits()577 SBTypeMember::GetOffsetInBits()
578 {
579 if (m_opaque_ap.get())
580 return m_opaque_ap->GetBitOffset();
581 return 0;
582 }
583
584 bool
IsBitfield()585 SBTypeMember::IsBitfield()
586 {
587 if (m_opaque_ap.get())
588 return m_opaque_ap->GetIsBitfield();
589 return false;
590 }
591
592 uint32_t
GetBitfieldSizeInBits()593 SBTypeMember::GetBitfieldSizeInBits()
594 {
595 if (m_opaque_ap.get())
596 return m_opaque_ap->GetBitfieldBitSize();
597 return 0;
598 }
599
600
601 bool
GetDescription(lldb::SBStream & description,lldb::DescriptionLevel description_level)602 SBTypeMember::GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level)
603 {
604 Stream &strm = description.ref();
605
606 if (m_opaque_ap.get())
607 {
608 const uint32_t bit_offset = m_opaque_ap->GetBitOffset();
609 const uint32_t byte_offset = bit_offset / 8u;
610 const uint32_t byte_bit_offset = bit_offset % 8u;
611 const char *name = m_opaque_ap->GetName().GetCString();
612 if (byte_bit_offset)
613 strm.Printf ("+%u + %u bits: (", byte_offset, byte_bit_offset);
614 else
615 strm.Printf ("+%u: (", byte_offset);
616
617 TypeImplSP type_impl_sp (m_opaque_ap->GetTypeImpl());
618 if (type_impl_sp)
619 type_impl_sp->GetDescription(strm, description_level);
620
621 strm.Printf (") %s", name);
622 if (m_opaque_ap->GetIsBitfield())
623 {
624 const uint32_t bitfield_bit_size = m_opaque_ap->GetBitfieldBitSize();
625 strm.Printf (" : %u", bitfield_bit_size);
626 }
627 }
628 else
629 {
630 strm.PutCString ("No value");
631 }
632 return true;
633 }
634
635
636 void
reset(TypeMemberImpl * type_member_impl)637 SBTypeMember::reset(TypeMemberImpl *type_member_impl)
638 {
639 m_opaque_ap.reset(type_member_impl);
640 }
641
642 TypeMemberImpl &
ref()643 SBTypeMember::ref ()
644 {
645 if (m_opaque_ap.get() == NULL)
646 m_opaque_ap.reset (new TypeMemberImpl());
647 return *m_opaque_ap.get();
648 }
649
650 const TypeMemberImpl &
ref() const651 SBTypeMember::ref () const
652 {
653 return *m_opaque_ap.get();
654 }
655