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