1 //===-- Type.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 // Other libraries and framework includes
11
12 #include "lldb/Core/DataExtractor.h"
13 #include "lldb/Core/DataBufferHeap.h"
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/Scalar.h"
16 #include "lldb/Core/StreamString.h"
17
18 #include "lldb/Symbol/ClangASTType.h"
19 #include "lldb/Symbol/ClangASTContext.h"
20 #include "lldb/Symbol/ObjectFile.h"
21 #include "lldb/Symbol/SymbolContextScope.h"
22 #include "lldb/Symbol/SymbolFile.h"
23 #include "lldb/Symbol/SymbolVendor.h"
24 #include "lldb/Symbol/Type.h"
25 #include "lldb/Symbol/TypeList.h"
26
27 #include "lldb/Target/ExecutionContext.h"
28 #include "lldb/Target/Process.h"
29 #include "lldb/Target/Target.h"
30
31 #include "llvm/ADT/StringRef.h"
32
33 #include "clang/AST/Decl.h"
34 #include "clang/AST/DeclObjC.h"
35
36 using namespace lldb;
37 using namespace lldb_private;
38
39 class TypeAppendVisitor
40 {
41 public:
TypeAppendVisitor(TypeListImpl & type_list)42 TypeAppendVisitor(TypeListImpl &type_list) :
43 m_type_list(type_list)
44 {
45 }
46
47 bool
operator ()(const lldb::TypeSP & type)48 operator() (const lldb::TypeSP& type)
49 {
50 m_type_list.Append(TypeImplSP(new TypeImpl(type)));
51 return true;
52 }
53
54 private:
55 TypeListImpl &m_type_list;
56 };
57
58 void
Append(const lldb_private::TypeList & type_list)59 TypeListImpl::Append (const lldb_private::TypeList &type_list)
60 {
61 TypeAppendVisitor cb(*this);
62 type_list.ForEach(cb);
63 }
64
65
66 Type *
GetType()67 SymbolFileType::GetType ()
68 {
69 if (!m_type_sp)
70 {
71 Type *resolved_type = m_symbol_file.ResolveTypeUID (GetID());
72 if (resolved_type)
73 m_type_sp = resolved_type->shared_from_this();
74 }
75 return m_type_sp.get();
76 }
77
78
Type(lldb::user_id_t uid,SymbolFile * symbol_file,const ConstString & name,uint64_t byte_size,SymbolContextScope * context,user_id_t encoding_uid,EncodingDataType encoding_uid_type,const Declaration & decl,const ClangASTType & clang_type,ResolveState clang_type_resolve_state)79 Type::Type
80 (
81 lldb::user_id_t uid,
82 SymbolFile* symbol_file,
83 const ConstString &name,
84 uint64_t byte_size,
85 SymbolContextScope *context,
86 user_id_t encoding_uid,
87 EncodingDataType encoding_uid_type,
88 const Declaration& decl,
89 const ClangASTType &clang_type,
90 ResolveState clang_type_resolve_state
91 ) :
92 std::enable_shared_from_this<Type> (),
93 UserID (uid),
94 m_name (name),
95 m_symbol_file (symbol_file),
96 m_context (context),
97 m_encoding_type (nullptr),
98 m_encoding_uid (encoding_uid),
99 m_encoding_uid_type (encoding_uid_type),
100 m_byte_size (byte_size),
101 m_decl (decl),
102 m_clang_type (clang_type)
103 {
104 m_flags.clang_type_resolve_state = (clang_type ? clang_type_resolve_state : eResolveStateUnresolved);
105 m_flags.is_complete_objc_class = false;
106 }
107
Type()108 Type::Type () :
109 std::enable_shared_from_this<Type> (),
110 UserID (0),
111 m_name ("<INVALID TYPE>"),
112 m_symbol_file (nullptr),
113 m_context (nullptr),
114 m_encoding_type (nullptr),
115 m_encoding_uid (LLDB_INVALID_UID),
116 m_encoding_uid_type (eEncodingInvalid),
117 m_byte_size (0),
118 m_decl (),
119 m_clang_type ()
120 {
121 m_flags.clang_type_resolve_state = eResolveStateUnresolved;
122 m_flags.is_complete_objc_class = false;
123 }
124
125
Type(const Type & rhs)126 Type::Type (const Type &rhs) :
127 std::enable_shared_from_this<Type> (rhs),
128 UserID (rhs),
129 m_name (rhs.m_name),
130 m_symbol_file (rhs.m_symbol_file),
131 m_context (rhs.m_context),
132 m_encoding_type (rhs.m_encoding_type),
133 m_encoding_uid (rhs.m_encoding_uid),
134 m_encoding_uid_type (rhs.m_encoding_uid_type),
135 m_byte_size (rhs.m_byte_size),
136 m_decl (rhs.m_decl),
137 m_clang_type (rhs.m_clang_type),
138 m_flags (rhs.m_flags)
139 {
140 }
141
142 const Type&
operator =(const Type & rhs)143 Type::operator= (const Type& rhs)
144 {
145 if (this != &rhs)
146 {
147 }
148 return *this;
149 }
150
151
152 void
GetDescription(Stream * s,lldb::DescriptionLevel level,bool show_name)153 Type::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_name)
154 {
155 *s << "id = " << (const UserID&)*this;
156
157 // Call the name accessor to make sure we resolve the type name
158 if (show_name)
159 {
160 const ConstString &type_name = GetName();
161 if (type_name)
162 {
163 *s << ", name = \"" << type_name << '"';
164 ConstString qualified_type_name (GetQualifiedName());
165 if (qualified_type_name != type_name)
166 {
167 *s << ", qualified = \"" << qualified_type_name << '"';
168 }
169 }
170 }
171
172 // Call the get byte size accesor so we resolve our byte size
173 if (GetByteSize())
174 s->Printf(", byte-size = %" PRIu64, m_byte_size);
175 bool show_fullpaths = (level == lldb::eDescriptionLevelVerbose);
176 m_decl.Dump(s, show_fullpaths);
177
178 if (m_clang_type.IsValid())
179 {
180 *s << ", clang_type = \"";
181 GetClangForwardType().DumpTypeDescription(s);
182 *s << '"';
183 }
184 else if (m_encoding_uid != LLDB_INVALID_UID)
185 {
186 s->Printf(", type_uid = 0x%8.8" PRIx64, m_encoding_uid);
187 switch (m_encoding_uid_type)
188 {
189 case eEncodingInvalid: break;
190 case eEncodingIsUID: s->PutCString(" (unresolved type)"); break;
191 case eEncodingIsConstUID: s->PutCString(" (unresolved const type)"); break;
192 case eEncodingIsRestrictUID: s->PutCString(" (unresolved restrict type)"); break;
193 case eEncodingIsVolatileUID: s->PutCString(" (unresolved volatile type)"); break;
194 case eEncodingIsTypedefUID: s->PutCString(" (unresolved typedef)"); break;
195 case eEncodingIsPointerUID: s->PutCString(" (unresolved pointer)"); break;
196 case eEncodingIsLValueReferenceUID: s->PutCString(" (unresolved L value reference)"); break;
197 case eEncodingIsRValueReferenceUID: s->PutCString(" (unresolved R value reference)"); break;
198 case eEncodingIsSyntheticUID: s->PutCString(" (synthetic type)"); break;
199 }
200 }
201 }
202
203
204 void
Dump(Stream * s,bool show_context)205 Type::Dump (Stream *s, bool show_context)
206 {
207 s->Printf("%p: ", static_cast<void*>(this));
208 s->Indent();
209 *s << "Type" << static_cast<const UserID&>(*this) << ' ';
210 if (m_name)
211 *s << ", name = \"" << m_name << "\"";
212
213 if (m_byte_size != 0)
214 s->Printf(", size = %" PRIu64, m_byte_size);
215
216 if (show_context && m_context != nullptr)
217 {
218 s->PutCString(", context = ( ");
219 m_context->DumpSymbolContext(s);
220 s->PutCString(" )");
221 }
222
223 bool show_fullpaths = false;
224 m_decl.Dump (s,show_fullpaths);
225
226 if (m_clang_type.IsValid())
227 {
228 *s << ", clang_type = " << m_clang_type.GetOpaqueQualType() << ' ';
229 GetClangForwardType().DumpTypeDescription (s);
230 }
231 else if (m_encoding_uid != LLDB_INVALID_UID)
232 {
233 *s << ", type_data = " << (uint64_t)m_encoding_uid;
234 switch (m_encoding_uid_type)
235 {
236 case eEncodingInvalid: break;
237 case eEncodingIsUID: s->PutCString(" (unresolved type)"); break;
238 case eEncodingIsConstUID: s->PutCString(" (unresolved const type)"); break;
239 case eEncodingIsRestrictUID: s->PutCString(" (unresolved restrict type)"); break;
240 case eEncodingIsVolatileUID: s->PutCString(" (unresolved volatile type)"); break;
241 case eEncodingIsTypedefUID: s->PutCString(" (unresolved typedef)"); break;
242 case eEncodingIsPointerUID: s->PutCString(" (unresolved pointer)"); break;
243 case eEncodingIsLValueReferenceUID: s->PutCString(" (unresolved L value reference)"); break;
244 case eEncodingIsRValueReferenceUID: s->PutCString(" (unresolved R value reference)"); break;
245 case eEncodingIsSyntheticUID: s->PutCString(" (synthetic type)"); break;
246 }
247 }
248
249 //
250 // if (m_access)
251 // s->Printf(", access = %u", m_access);
252 s->EOL();
253 }
254
255 const ConstString &
GetName()256 Type::GetName()
257 {
258 if (!m_name)
259 m_name = GetClangForwardType().GetConstTypeName();
260 return m_name;
261 }
262
263 void
DumpTypeName(Stream * s)264 Type::DumpTypeName(Stream *s)
265 {
266 GetName().Dump(s, "<invalid-type-name>");
267 }
268
269
270 void
DumpValue(ExecutionContext * exe_ctx,Stream * s,const DataExtractor & data,uint32_t data_byte_offset,bool show_types,bool show_summary,bool verbose,lldb::Format format)271 Type::DumpValue
272 (
273 ExecutionContext *exe_ctx,
274 Stream *s,
275 const DataExtractor &data,
276 uint32_t data_byte_offset,
277 bool show_types,
278 bool show_summary,
279 bool verbose,
280 lldb::Format format
281 )
282 {
283 if (ResolveClangType(eResolveStateForward))
284 {
285 if (show_types)
286 {
287 s->PutChar('(');
288 if (verbose)
289 s->Printf("Type{0x%8.8" PRIx64 "} ", GetID());
290 DumpTypeName (s);
291 s->PutCString(") ");
292 }
293
294 GetClangForwardType().DumpValue (exe_ctx,
295 s,
296 format == lldb::eFormatDefault ? GetFormat() : format,
297 data,
298 data_byte_offset,
299 GetByteSize(),
300 0, // Bitfield bit size
301 0, // Bitfield bit offset
302 show_types,
303 show_summary,
304 verbose,
305 0);
306 }
307 }
308
309 Type *
GetEncodingType()310 Type::GetEncodingType ()
311 {
312 if (m_encoding_type == nullptr && m_encoding_uid != LLDB_INVALID_UID)
313 m_encoding_type = m_symbol_file->ResolveTypeUID(m_encoding_uid);
314 return m_encoding_type;
315 }
316
317
318
319 uint64_t
GetByteSize()320 Type::GetByteSize()
321 {
322 if (m_byte_size == 0)
323 {
324 switch (m_encoding_uid_type)
325 {
326 case eEncodingInvalid:
327 case eEncodingIsSyntheticUID:
328 break;
329 case eEncodingIsUID:
330 case eEncodingIsConstUID:
331 case eEncodingIsRestrictUID:
332 case eEncodingIsVolatileUID:
333 case eEncodingIsTypedefUID:
334 {
335 Type *encoding_type = GetEncodingType ();
336 if (encoding_type)
337 m_byte_size = encoding_type->GetByteSize();
338 if (m_byte_size == 0)
339 m_byte_size = GetClangLayoutType().GetByteSize(nullptr);
340 }
341 break;
342
343 // If we are a pointer or reference, then this is just a pointer size;
344 case eEncodingIsPointerUID:
345 case eEncodingIsLValueReferenceUID:
346 case eEncodingIsRValueReferenceUID:
347 m_byte_size = m_symbol_file->GetClangASTContext().GetPointerByteSize();
348 break;
349 }
350 }
351 return m_byte_size;
352 }
353
354
355 uint32_t
GetNumChildren(bool omit_empty_base_classes)356 Type::GetNumChildren (bool omit_empty_base_classes)
357 {
358 return GetClangForwardType().GetNumChildren(omit_empty_base_classes);
359 }
360
361 bool
IsAggregateType()362 Type::IsAggregateType ()
363 {
364 return GetClangForwardType().IsAggregateType();
365 }
366
367 lldb::TypeSP
GetTypedefType()368 Type::GetTypedefType()
369 {
370 lldb::TypeSP type_sp;
371 if (IsTypedef())
372 {
373 Type *typedef_type = m_symbol_file->ResolveTypeUID(m_encoding_uid);
374 if (typedef_type)
375 type_sp = typedef_type->shared_from_this();
376 }
377 return type_sp;
378 }
379
380
381
382 lldb::Format
GetFormat()383 Type::GetFormat ()
384 {
385 return GetClangForwardType().GetFormat();
386 }
387
388
389
390 lldb::Encoding
GetEncoding(uint64_t & count)391 Type::GetEncoding (uint64_t &count)
392 {
393 // Make sure we resolve our type if it already hasn't been.
394 return GetClangForwardType().GetEncoding(count);
395 }
396
397 bool
DumpValueInMemory(ExecutionContext * exe_ctx,Stream * s,lldb::addr_t address,AddressType address_type,bool show_types,bool show_summary,bool verbose)398 Type::DumpValueInMemory
399 (
400 ExecutionContext *exe_ctx,
401 Stream *s,
402 lldb::addr_t address,
403 AddressType address_type,
404 bool show_types,
405 bool show_summary,
406 bool verbose
407 )
408 {
409 if (address != LLDB_INVALID_ADDRESS)
410 {
411 DataExtractor data;
412 Target *target = nullptr;
413 if (exe_ctx)
414 target = exe_ctx->GetTargetPtr();
415 if (target)
416 data.SetByteOrder (target->GetArchitecture().GetByteOrder());
417 if (ReadFromMemory (exe_ctx, address, address_type, data))
418 {
419 DumpValue(exe_ctx, s, data, 0, show_types, show_summary, verbose);
420 return true;
421 }
422 }
423 return false;
424 }
425
426
427 bool
ReadFromMemory(ExecutionContext * exe_ctx,lldb::addr_t addr,AddressType address_type,DataExtractor & data)428 Type::ReadFromMemory (ExecutionContext *exe_ctx, lldb::addr_t addr, AddressType address_type, DataExtractor &data)
429 {
430 if (address_type == eAddressTypeFile)
431 {
432 // Can't convert a file address to anything valid without more
433 // context (which Module it came from)
434 return false;
435 }
436
437 const uint64_t byte_size = GetByteSize();
438 if (data.GetByteSize() < byte_size)
439 {
440 lldb::DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0'));
441 data.SetData(data_sp);
442 }
443
444 uint8_t* dst = (uint8_t*)data.PeekData(0, byte_size);
445 if (dst != nullptr)
446 {
447 if (address_type == eAddressTypeHost)
448 {
449 // The address is an address in this process, so just copy it
450 if (addr == 0)
451 return false;
452 memcpy (dst, (uint8_t*)nullptr + addr, byte_size);
453 return true;
454 }
455 else
456 {
457 if (exe_ctx)
458 {
459 Process *process = exe_ctx->GetProcessPtr();
460 if (process)
461 {
462 Error error;
463 return exe_ctx->GetProcessPtr()->ReadMemory(addr, dst, byte_size, error) == byte_size;
464 }
465 }
466 }
467 }
468 return false;
469 }
470
471
472 bool
WriteToMemory(ExecutionContext * exe_ctx,lldb::addr_t addr,AddressType address_type,DataExtractor & data)473 Type::WriteToMemory (ExecutionContext *exe_ctx, lldb::addr_t addr, AddressType address_type, DataExtractor &data)
474 {
475 return false;
476 }
477
478
479 TypeList*
GetTypeList()480 Type::GetTypeList()
481 {
482 return GetSymbolFile()->GetTypeList();
483 }
484
485 const Declaration &
GetDeclaration() const486 Type::GetDeclaration () const
487 {
488 return m_decl;
489 }
490
491 bool
ResolveClangType(ResolveState clang_type_resolve_state)492 Type::ResolveClangType (ResolveState clang_type_resolve_state)
493 {
494 Type *encoding_type = nullptr;
495 if (!m_clang_type.IsValid())
496 {
497 encoding_type = GetEncodingType();
498 if (encoding_type)
499 {
500 switch (m_encoding_uid_type)
501 {
502 case eEncodingIsUID:
503 {
504 ClangASTType encoding_clang_type = encoding_type->GetClangForwardType();
505 if (encoding_clang_type.IsValid())
506 {
507 m_clang_type = encoding_clang_type;
508 m_flags.clang_type_resolve_state = encoding_type->m_flags.clang_type_resolve_state;
509 }
510 }
511 break;
512
513 case eEncodingIsConstUID:
514 m_clang_type = encoding_type->GetClangForwardType().AddConstModifier();
515 break;
516
517 case eEncodingIsRestrictUID:
518 m_clang_type = encoding_type->GetClangForwardType().AddRestrictModifier();
519 break;
520
521 case eEncodingIsVolatileUID:
522 m_clang_type = encoding_type->GetClangForwardType().AddVolatileModifier();
523 break;
524
525 case eEncodingIsTypedefUID:
526 m_clang_type = encoding_type->GetClangForwardType().CreateTypedefType (GetName().AsCString(),
527 GetSymbolFile()->GetClangDeclContextContainingTypeUID(GetID()));
528 m_name.Clear();
529 break;
530
531 case eEncodingIsPointerUID:
532 m_clang_type = encoding_type->GetClangForwardType().GetPointerType();
533 break;
534
535 case eEncodingIsLValueReferenceUID:
536 m_clang_type = encoding_type->GetClangForwardType().GetLValueReferenceType();
537 break;
538
539 case eEncodingIsRValueReferenceUID:
540 m_clang_type = encoding_type->GetClangForwardType().GetRValueReferenceType();
541 break;
542
543 default:
544 assert(!"Unhandled encoding_data_type.");
545 break;
546 }
547 }
548 else
549 {
550 // We have no encoding type, return void?
551 ClangASTType void_clang_type (ClangASTContext::GetBasicType(GetClangASTContext().getASTContext(), eBasicTypeVoid));
552 switch (m_encoding_uid_type)
553 {
554 case eEncodingIsUID:
555 m_clang_type = void_clang_type;
556 break;
557
558 case eEncodingIsConstUID:
559 m_clang_type = void_clang_type.AddConstModifier ();
560 break;
561
562 case eEncodingIsRestrictUID:
563 m_clang_type = void_clang_type.AddRestrictModifier ();
564 break;
565
566 case eEncodingIsVolatileUID:
567 m_clang_type = void_clang_type.AddVolatileModifier ();
568 break;
569
570 case eEncodingIsTypedefUID:
571 m_clang_type = void_clang_type.CreateTypedefType (GetName().AsCString(),
572 GetSymbolFile()->GetClangDeclContextContainingTypeUID(GetID()));
573 break;
574
575 case eEncodingIsPointerUID:
576 m_clang_type = void_clang_type.GetPointerType ();
577 break;
578
579 case eEncodingIsLValueReferenceUID:
580 m_clang_type = void_clang_type.GetLValueReferenceType ();
581 break;
582
583 case eEncodingIsRValueReferenceUID:
584 m_clang_type = void_clang_type.GetRValueReferenceType ();
585 break;
586
587 default:
588 assert(!"Unhandled encoding_data_type.");
589 break;
590 }
591 }
592
593 // When we have a EncodingUID, our "m_flags.clang_type_resolve_state" is set to eResolveStateUnresolved
594 // so we need to update it to say that we now have a forward declaration since that is what we created
595 // above.
596 if (m_clang_type.IsValid())
597 m_flags.clang_type_resolve_state = eResolveStateForward;
598
599 }
600
601 // Check if we have a forward reference to a class/struct/union/enum?
602 if (clang_type_resolve_state == eResolveStateLayout || clang_type_resolve_state == eResolveStateFull)
603 {
604 // Check if we have a forward reference to a class/struct/union/enum?
605 if (m_clang_type.IsValid() && m_flags.clang_type_resolve_state < clang_type_resolve_state)
606 {
607 m_flags.clang_type_resolve_state = eResolveStateFull;
608 if (!m_clang_type.IsDefined ())
609 {
610 // We have a forward declaration, we need to resolve it to a complete definition.
611 m_symbol_file->ResolveClangOpaqueTypeDefinition (m_clang_type);
612 }
613 }
614 }
615
616 // If we have an encoding type, then we need to make sure it is
617 // resolved appropriately.
618 if (m_encoding_uid != LLDB_INVALID_UID)
619 {
620 if (encoding_type == nullptr)
621 encoding_type = GetEncodingType();
622 if (encoding_type)
623 {
624 ResolveState encoding_clang_type_resolve_state = clang_type_resolve_state;
625
626 if (clang_type_resolve_state == eResolveStateLayout)
627 {
628 switch (m_encoding_uid_type)
629 {
630 case eEncodingIsPointerUID:
631 case eEncodingIsLValueReferenceUID:
632 case eEncodingIsRValueReferenceUID:
633 encoding_clang_type_resolve_state = eResolveStateForward;
634 break;
635 default:
636 break;
637 }
638 }
639 encoding_type->ResolveClangType (encoding_clang_type_resolve_state);
640 }
641 }
642 return m_clang_type.IsValid();
643 }
644 uint32_t
GetEncodingMask()645 Type::GetEncodingMask ()
646 {
647 uint32_t encoding_mask = 1u << m_encoding_uid_type;
648 Type *encoding_type = GetEncodingType();
649 assert (encoding_type != this);
650 if (encoding_type)
651 encoding_mask |= encoding_type->GetEncodingMask ();
652 return encoding_mask;
653 }
654
655 ClangASTType
GetClangFullType()656 Type::GetClangFullType ()
657 {
658 ResolveClangType(eResolveStateFull);
659 return m_clang_type;
660 }
661
662 ClangASTType
GetClangLayoutType()663 Type::GetClangLayoutType ()
664 {
665 ResolveClangType(eResolveStateLayout);
666 return m_clang_type;
667 }
668
669 ClangASTType
GetClangForwardType()670 Type::GetClangForwardType ()
671 {
672 ResolveClangType (eResolveStateForward);
673 return m_clang_type;
674 }
675
676 ClangASTContext &
GetClangASTContext()677 Type::GetClangASTContext ()
678 {
679 return m_symbol_file->GetClangASTContext();
680 }
681
682 int
Compare(const Type & a,const Type & b)683 Type::Compare(const Type &a, const Type &b)
684 {
685 // Just compare the UID values for now...
686 lldb::user_id_t a_uid = a.GetID();
687 lldb::user_id_t b_uid = b.GetID();
688 if (a_uid < b_uid)
689 return -1;
690 if (a_uid > b_uid)
691 return 1;
692 return 0;
693 // if (a.getQualType() == b.getQualType())
694 // return 0;
695 }
696
697
698 #if 0 // START REMOVE
699 // Move this into ClangASTType
700 void *
701 Type::CreateClangPointerType (Type *type)
702 {
703 assert(type);
704 return GetClangASTContext().CreatePointerType(type->GetClangForwardType());
705 }
706
707 void *
708 Type::CreateClangTypedefType (Type *typedef_type, Type *base_type)
709 {
710 assert(typedef_type && base_type);
711 return GetClangASTContext().CreateTypedefType (typedef_type->GetName().AsCString(),
712 base_type->GetClangForwardType(),
713 typedef_type->GetSymbolFile()->GetClangDeclContextContainingTypeUID(typedef_type->GetID()));
714 }
715
716 void *
717 Type::CreateClangLValueReferenceType (Type *type)
718 {
719 assert(type);
720 return GetClangASTContext().CreateLValueReferenceType(type->GetClangForwardType());
721 }
722
723 void *
724 Type::CreateClangRValueReferenceType (Type *type)
725 {
726 assert(type);
727 return GetClangASTContext().CreateRValueReferenceType (type->GetClangForwardType());
728 }
729 #endif // END REMOVE
730
731 bool
IsRealObjCClass()732 Type::IsRealObjCClass()
733 {
734 // For now we are just skipping ObjC classes that get made by hand from the runtime, because
735 // those don't have any information. We could extend this to only return true for "full
736 // definitions" if we can figure that out.
737
738 if (m_clang_type.IsObjCObjectOrInterfaceType() && GetByteSize() != 0)
739 return true;
740 else
741 return false;
742 }
743
744 ConstString
GetQualifiedName()745 Type::GetQualifiedName ()
746 {
747 return GetClangForwardType().GetConstTypeName();
748 }
749
750
751 bool
GetTypeScopeAndBasename(const char * & name_cstr,std::string & scope,std::string & basename,TypeClass & type_class)752 Type::GetTypeScopeAndBasename (const char* &name_cstr,
753 std::string &scope,
754 std::string &basename,
755 TypeClass &type_class)
756 {
757 // Protect against null c string.
758
759 type_class = eTypeClassAny;
760
761 if (name_cstr && name_cstr[0])
762 {
763 llvm::StringRef name_strref(name_cstr);
764 if (name_strref.startswith("struct "))
765 {
766 name_cstr += 7;
767 type_class = eTypeClassStruct;
768 }
769 else if (name_strref.startswith("class "))
770 {
771 name_cstr += 6;
772 type_class = eTypeClassClass;
773 }
774 else if (name_strref.startswith("union "))
775 {
776 name_cstr += 6;
777 type_class = eTypeClassUnion;
778 }
779 else if (name_strref.startswith("enum "))
780 {
781 name_cstr += 5;
782 type_class = eTypeClassEnumeration;
783 }
784 else if (name_strref.startswith("typedef "))
785 {
786 name_cstr += 8;
787 type_class = eTypeClassTypedef;
788 }
789 const char *basename_cstr = name_cstr;
790 const char* namespace_separator = ::strstr (basename_cstr, "::");
791 if (namespace_separator)
792 {
793 const char* template_arg_char = ::strchr (basename_cstr, '<');
794 while (namespace_separator != nullptr)
795 {
796 if (template_arg_char && namespace_separator > template_arg_char) // but namespace'd template arguments are still good to go
797 break;
798 basename_cstr = namespace_separator + 2;
799 namespace_separator = strstr(basename_cstr, "::");
800 }
801 if (basename_cstr > name_cstr)
802 {
803 scope.assign (name_cstr, basename_cstr - name_cstr);
804 basename.assign (basename_cstr);
805 return true;
806 }
807 }
808 }
809 return false;
810 }
811
812
813 ModuleSP
GetModule()814 Type::GetModule()
815 {
816 if (m_symbol_file)
817 return m_symbol_file->GetObjectFile()->GetModule();
818 return ModuleSP();
819 }
820
821
TypeAndOrName()822 TypeAndOrName::TypeAndOrName () : m_type_pair(), m_type_name()
823 {
824
825 }
826
TypeAndOrName(TypeSP & in_type_sp)827 TypeAndOrName::TypeAndOrName (TypeSP &in_type_sp) : m_type_pair(in_type_sp)
828 {
829 if (in_type_sp)
830 m_type_name = in_type_sp->GetName();
831 }
832
TypeAndOrName(const char * in_type_str)833 TypeAndOrName::TypeAndOrName (const char *in_type_str) : m_type_name(in_type_str)
834 {
835 }
836
TypeAndOrName(const TypeAndOrName & rhs)837 TypeAndOrName::TypeAndOrName (const TypeAndOrName &rhs) : m_type_pair (rhs.m_type_pair), m_type_name (rhs.m_type_name)
838 {
839
840 }
841
TypeAndOrName(ConstString & in_type_const_string)842 TypeAndOrName::TypeAndOrName (ConstString &in_type_const_string) : m_type_name (in_type_const_string)
843 {
844 }
845
846 TypeAndOrName &
operator =(const TypeAndOrName & rhs)847 TypeAndOrName::operator= (const TypeAndOrName &rhs)
848 {
849 if (this != &rhs)
850 {
851 m_type_name = rhs.m_type_name;
852 m_type_pair = rhs.m_type_pair;
853 }
854 return *this;
855 }
856
857 bool
operator ==(const TypeAndOrName & other) const858 TypeAndOrName::operator==(const TypeAndOrName &other) const
859 {
860 if (m_type_pair != other.m_type_pair)
861 return false;
862 if (m_type_name != other.m_type_name)
863 return false;
864 return true;
865 }
866
867 bool
operator !=(const TypeAndOrName & other) const868 TypeAndOrName::operator!=(const TypeAndOrName &other) const
869 {
870 if (m_type_pair != other.m_type_pair)
871 return true;
872 if (m_type_name != other.m_type_name)
873 return true;
874 return false;
875 }
876
877 ConstString
GetName() const878 TypeAndOrName::GetName () const
879 {
880 if (m_type_name)
881 return m_type_name;
882 if (m_type_pair)
883 return m_type_pair.GetName();
884 return ConstString("<invalid>");
885 }
886
887 void
SetName(const ConstString & type_name)888 TypeAndOrName::SetName (const ConstString &type_name)
889 {
890 m_type_name = type_name;
891 }
892
893 void
SetName(const char * type_name_cstr)894 TypeAndOrName::SetName (const char *type_name_cstr)
895 {
896 m_type_name.SetCString (type_name_cstr);
897 }
898
899 void
SetTypeSP(lldb::TypeSP type_sp)900 TypeAndOrName::SetTypeSP (lldb::TypeSP type_sp)
901 {
902 m_type_pair.SetType(type_sp);
903 if (m_type_pair)
904 m_type_name = m_type_pair.GetName();
905 }
906
907 void
SetClangASTType(ClangASTType clang_type)908 TypeAndOrName::SetClangASTType (ClangASTType clang_type)
909 {
910 m_type_pair.SetType(clang_type);
911 if (m_type_pair)
912 m_type_name = m_type_pair.GetName();
913 }
914
915 bool
IsEmpty() const916 TypeAndOrName::IsEmpty() const
917 {
918 if ((bool)m_type_name || (bool)m_type_pair)
919 return false;
920 else
921 return true;
922 }
923
924 void
Clear()925 TypeAndOrName::Clear ()
926 {
927 m_type_name.Clear();
928 m_type_pair.Clear();
929 }
930
931 bool
HasName() const932 TypeAndOrName::HasName () const
933 {
934 return (bool)m_type_name;
935 }
936
937 bool
HasTypeSP() const938 TypeAndOrName::HasTypeSP () const
939 {
940 return m_type_pair.GetTypeSP().get() != nullptr;
941 }
942
943 bool
HasClangASTType() const944 TypeAndOrName::HasClangASTType () const
945 {
946 return m_type_pair.GetClangASTType().IsValid();
947 }
948
949
TypeImpl()950 TypeImpl::TypeImpl() :
951 m_module_wp(),
952 m_static_type(),
953 m_dynamic_type()
954 {
955 }
956
TypeImpl(const TypeImpl & rhs)957 TypeImpl::TypeImpl(const TypeImpl& rhs) :
958 m_module_wp (rhs.m_module_wp),
959 m_static_type(rhs.m_static_type),
960 m_dynamic_type(rhs.m_dynamic_type)
961 {
962 }
963
TypeImpl(const lldb::TypeSP & type_sp)964 TypeImpl::TypeImpl (const lldb::TypeSP &type_sp) :
965 m_module_wp (),
966 m_static_type(),
967 m_dynamic_type()
968 {
969 SetType (type_sp);
970 }
971
TypeImpl(const ClangASTType & clang_type)972 TypeImpl::TypeImpl (const ClangASTType &clang_type) :
973 m_module_wp (),
974 m_static_type(),
975 m_dynamic_type()
976 {
977 SetType (clang_type);
978 }
979
TypeImpl(const lldb::TypeSP & type_sp,const ClangASTType & dynamic)980 TypeImpl::TypeImpl (const lldb::TypeSP &type_sp, const ClangASTType &dynamic) :
981 m_module_wp (),
982 m_static_type (type_sp),
983 m_dynamic_type(dynamic)
984 {
985 SetType (type_sp, dynamic);
986 }
987
TypeImpl(const ClangASTType & static_type,const ClangASTType & dynamic_type)988 TypeImpl::TypeImpl (const ClangASTType &static_type, const ClangASTType &dynamic_type) :
989 m_module_wp (),
990 m_static_type (),
991 m_dynamic_type()
992 {
993 SetType (static_type, dynamic_type);
994 }
995
TypeImpl(const TypePair & pair,const ClangASTType & dynamic)996 TypeImpl::TypeImpl (const TypePair &pair, const ClangASTType &dynamic) :
997 m_module_wp (),
998 m_static_type (),
999 m_dynamic_type()
1000 {
1001 SetType (pair, dynamic);
1002 }
1003
1004 void
SetType(const lldb::TypeSP & type_sp)1005 TypeImpl::SetType (const lldb::TypeSP &type_sp)
1006 {
1007 m_static_type.SetType(type_sp);
1008 if (type_sp)
1009 m_module_wp = type_sp->GetModule();
1010 else
1011 m_module_wp = lldb::ModuleWP();
1012 }
1013
1014 void
SetType(const ClangASTType & clang_type)1015 TypeImpl::SetType (const ClangASTType &clang_type)
1016 {
1017 m_module_wp = lldb::ModuleWP();
1018 m_static_type.SetType (clang_type);
1019 }
1020
1021 void
SetType(const lldb::TypeSP & type_sp,const ClangASTType & dynamic)1022 TypeImpl::SetType (const lldb::TypeSP &type_sp, const ClangASTType &dynamic)
1023 {
1024 SetType (type_sp);
1025 m_dynamic_type = dynamic;
1026 }
1027
1028 void
SetType(const ClangASTType & clang_type,const ClangASTType & dynamic)1029 TypeImpl::SetType (const ClangASTType &clang_type, const ClangASTType &dynamic)
1030 {
1031 m_module_wp = lldb::ModuleWP();
1032 m_static_type.SetType (clang_type);
1033 m_dynamic_type = dynamic;
1034 }
1035
1036 void
SetType(const TypePair & pair,const ClangASTType & dynamic)1037 TypeImpl::SetType (const TypePair &pair, const ClangASTType &dynamic)
1038 {
1039 m_module_wp = pair.GetModule();
1040 m_static_type = pair;
1041 m_dynamic_type = dynamic;
1042 }
1043
1044 TypeImpl&
operator =(const TypeImpl & rhs)1045 TypeImpl::operator = (const TypeImpl& rhs)
1046 {
1047 if (rhs != *this)
1048 {
1049 m_module_wp = rhs.m_module_wp;
1050 m_static_type = rhs.m_static_type;
1051 m_dynamic_type = rhs.m_dynamic_type;
1052 }
1053 return *this;
1054 }
1055
1056 bool
CheckModule(lldb::ModuleSP & module_sp) const1057 TypeImpl::CheckModule (lldb::ModuleSP &module_sp) const
1058 {
1059 // Check if we have a module for this type. If we do and the shared pointer is
1060 // can be successfully initialized with m_module_wp, return true. Else return false
1061 // if we didn't have a module, or if we had a module and it has been deleted. Any
1062 // functions doing anything with a TypeSP in this TypeImpl class should call this
1063 // function and only do anything with the ivars if this function returns true. If
1064 // we have a module, the "module_sp" will be filled in with a strong reference to the
1065 // module so that the module will at least stay around long enough for the type
1066 // query to succeed.
1067 module_sp = m_module_wp.lock();
1068 if (!module_sp)
1069 {
1070 lldb::ModuleWP empty_module_wp;
1071 // If either call to "std::weak_ptr::owner_before(...) value returns true, this
1072 // indicates that m_module_wp once contained (possibly still does) a reference
1073 // to a valid shared pointer. This helps us know if we had a valid reference to
1074 // a section which is now invalid because the module it was in was deleted
1075 if (empty_module_wp.owner_before(m_module_wp) || m_module_wp.owner_before(empty_module_wp))
1076 {
1077 // m_module_wp had a valid reference to a module, but all strong references
1078 // have been released and the module has been deleted
1079 return false;
1080 }
1081 }
1082 // We either successfully locked the module, or didn't have one to begin with
1083 return true;
1084 }
1085
1086 bool
operator ==(const TypeImpl & rhs) const1087 TypeImpl::operator == (const TypeImpl& rhs) const
1088 {
1089 return m_static_type == rhs.m_static_type && m_dynamic_type == rhs.m_dynamic_type;
1090 }
1091
1092 bool
operator !=(const TypeImpl & rhs) const1093 TypeImpl::operator != (const TypeImpl& rhs) const
1094 {
1095 return m_static_type != rhs.m_static_type || m_dynamic_type != rhs.m_dynamic_type;
1096 }
1097
1098 bool
IsValid() const1099 TypeImpl::IsValid() const
1100 {
1101 // just a name is not valid
1102 ModuleSP module_sp;
1103 if (CheckModule (module_sp))
1104 return m_static_type.IsValid() || m_dynamic_type.IsValid();
1105 return false;
1106 }
1107
operator bool() const1108 TypeImpl::operator bool () const
1109 {
1110 return IsValid();
1111 }
1112
1113 void
Clear()1114 TypeImpl::Clear()
1115 {
1116 m_module_wp = lldb::ModuleWP();
1117 m_static_type.Clear();
1118 m_dynamic_type.Clear();
1119 }
1120
1121 ConstString
GetName() const1122 TypeImpl::GetName () const
1123 {
1124 ModuleSP module_sp;
1125 if (CheckModule (module_sp))
1126 {
1127 if (m_dynamic_type)
1128 return m_dynamic_type.GetTypeName();
1129 return m_static_type.GetName ();
1130 }
1131 return ConstString();
1132 }
1133
1134 ConstString
GetDisplayTypeName() const1135 TypeImpl::GetDisplayTypeName () const
1136 {
1137 ModuleSP module_sp;
1138 if (CheckModule (module_sp))
1139 {
1140 if (m_dynamic_type)
1141 return m_dynamic_type.GetDisplayTypeName();
1142 return m_static_type.GetDisplayTypeName();
1143 }
1144 return ConstString();
1145 }
1146
1147 TypeImpl
GetPointerType() const1148 TypeImpl::GetPointerType () const
1149 {
1150 ModuleSP module_sp;
1151 if (CheckModule (module_sp))
1152 {
1153 if (m_dynamic_type.IsValid())
1154 {
1155 return TypeImpl(m_static_type.GetPointerType(), m_dynamic_type.GetPointerType());
1156 }
1157 return TypeImpl(m_static_type.GetPointerType());
1158 }
1159 return TypeImpl();
1160 }
1161
1162 TypeImpl
GetPointeeType() const1163 TypeImpl::GetPointeeType () const
1164 {
1165 ModuleSP module_sp;
1166 if (CheckModule (module_sp))
1167 {
1168 if (m_dynamic_type.IsValid())
1169 {
1170 return TypeImpl(m_static_type.GetPointeeType(), m_dynamic_type.GetPointeeType());
1171 }
1172 return TypeImpl(m_static_type.GetPointeeType());
1173 }
1174 return TypeImpl();
1175 }
1176
1177 TypeImpl
GetReferenceType() const1178 TypeImpl::GetReferenceType () const
1179 {
1180 ModuleSP module_sp;
1181 if (CheckModule (module_sp))
1182 {
1183 if (m_dynamic_type.IsValid())
1184 {
1185 return TypeImpl(m_static_type.GetReferenceType(), m_dynamic_type.GetLValueReferenceType());
1186 }
1187 return TypeImpl(m_static_type.GetReferenceType());
1188 }
1189 return TypeImpl();
1190 }
1191
1192 TypeImpl
GetTypedefedType() const1193 TypeImpl::GetTypedefedType () const
1194 {
1195 ModuleSP module_sp;
1196 if (CheckModule (module_sp))
1197 {
1198 if (m_dynamic_type.IsValid())
1199 {
1200 return TypeImpl(m_static_type.GetTypedefedType(), m_dynamic_type.GetTypedefedType());
1201 }
1202 return TypeImpl(m_static_type.GetTypedefedType());
1203 }
1204 return TypeImpl();
1205 }
1206
1207 TypeImpl
GetDereferencedType() const1208 TypeImpl::GetDereferencedType () const
1209 {
1210 ModuleSP module_sp;
1211 if (CheckModule (module_sp))
1212 {
1213 if (m_dynamic_type.IsValid())
1214 {
1215 return TypeImpl(m_static_type.GetDereferencedType(), m_dynamic_type.GetNonReferenceType());
1216 }
1217 return TypeImpl(m_static_type.GetDereferencedType());
1218 }
1219 return TypeImpl();
1220 }
1221
1222 TypeImpl
GetUnqualifiedType() const1223 TypeImpl::GetUnqualifiedType() const
1224 {
1225 ModuleSP module_sp;
1226 if (CheckModule (module_sp))
1227 {
1228 if (m_dynamic_type.IsValid())
1229 {
1230 return TypeImpl(m_static_type.GetUnqualifiedType(), m_dynamic_type.GetFullyUnqualifiedType());
1231 }
1232 return TypeImpl(m_static_type.GetUnqualifiedType());
1233 }
1234 return TypeImpl();
1235 }
1236
1237 TypeImpl
GetCanonicalType() const1238 TypeImpl::GetCanonicalType() const
1239 {
1240 ModuleSP module_sp;
1241 if (CheckModule (module_sp))
1242 {
1243 if (m_dynamic_type.IsValid())
1244 {
1245 return TypeImpl(m_static_type.GetCanonicalType(), m_dynamic_type.GetCanonicalType());
1246 }
1247 return TypeImpl(m_static_type.GetCanonicalType());
1248 }
1249 return TypeImpl();
1250 }
1251
1252 ClangASTType
GetClangASTType(bool prefer_dynamic)1253 TypeImpl::GetClangASTType (bool prefer_dynamic)
1254 {
1255 ModuleSP module_sp;
1256 if (CheckModule (module_sp))
1257 {
1258 if (prefer_dynamic)
1259 {
1260 if (m_dynamic_type.IsValid())
1261 return m_dynamic_type;
1262 }
1263 return m_static_type.GetClangASTType();
1264 }
1265 return ClangASTType();
1266 }
1267
1268 clang::ASTContext *
GetClangASTContext(bool prefer_dynamic)1269 TypeImpl::GetClangASTContext (bool prefer_dynamic)
1270 {
1271 ModuleSP module_sp;
1272 if (CheckModule (module_sp))
1273 {
1274 if (prefer_dynamic)
1275 {
1276 if (m_dynamic_type.IsValid())
1277 return m_dynamic_type.GetASTContext();
1278 }
1279 return m_static_type.GetClangASTContext();
1280 }
1281 return NULL;
1282 }
1283
1284 bool
GetDescription(lldb_private::Stream & strm,lldb::DescriptionLevel description_level)1285 TypeImpl::GetDescription (lldb_private::Stream &strm,
1286 lldb::DescriptionLevel description_level)
1287 {
1288 ModuleSP module_sp;
1289 if (CheckModule (module_sp))
1290 {
1291 if (m_dynamic_type.IsValid())
1292 {
1293 strm.Printf("Dynamic:\n");
1294 m_dynamic_type.DumpTypeDescription(&strm);
1295 strm.Printf("\nStatic:\n");
1296 }
1297 m_static_type.GetClangASTType().DumpTypeDescription(&strm);
1298 }
1299 else
1300 {
1301 strm.PutCString("Invalid TypeImpl module for type has been deleted\n");
1302 }
1303 return true;
1304 }
1305
1306 TypeMemberFunctionImpl&
operator =(const TypeMemberFunctionImpl & rhs)1307 TypeMemberFunctionImpl::operator = (const TypeMemberFunctionImpl& rhs)
1308 {
1309 if (this != &rhs)
1310 {
1311 m_type = rhs.m_type;
1312 m_objc_method_decl = rhs.m_objc_method_decl;
1313 m_name = rhs.m_name;
1314 m_kind = rhs.m_kind;
1315 }
1316 return *this;
1317 }
1318
1319 bool
IsValid()1320 TypeMemberFunctionImpl::IsValid ()
1321 {
1322 return m_type.IsValid() && m_kind != lldb::eMemberFunctionKindUnknown;
1323 }
1324
1325 ConstString
GetName() const1326 TypeMemberFunctionImpl::GetName () const
1327 {
1328 return m_name;
1329 }
1330
1331 ClangASTType
GetType() const1332 TypeMemberFunctionImpl::GetType () const
1333 {
1334 return m_type;
1335 }
1336
1337 lldb::MemberFunctionKind
GetKind() const1338 TypeMemberFunctionImpl::GetKind () const
1339 {
1340 return m_kind;
1341 }
1342
1343 std::string
GetPrintableTypeName()1344 TypeMemberFunctionImpl::GetPrintableTypeName ()
1345 {
1346 if (m_type)
1347 return m_type.GetTypeName().AsCString("<unknown>");
1348 if (m_objc_method_decl)
1349 {
1350 if (m_objc_method_decl->getClassInterface())
1351 {
1352 return m_objc_method_decl->getClassInterface()->getName();
1353 }
1354 }
1355 return "<unknown>";
1356 }
1357
1358 bool
GetDescription(Stream & stream)1359 TypeMemberFunctionImpl::GetDescription (Stream& stream)
1360 {
1361 switch (m_kind) {
1362 case lldb::eMemberFunctionKindUnknown:
1363 return false;
1364 case lldb::eMemberFunctionKindConstructor:
1365 stream.Printf("constructor for %s", GetPrintableTypeName().c_str());
1366 break;
1367 case lldb::eMemberFunctionKindDestructor:
1368 stream.Printf("destructor for %s", GetPrintableTypeName().c_str());
1369 break;
1370 case lldb::eMemberFunctionKindInstanceMethod:
1371 stream.Printf("instance method %s of type %s",
1372 m_name.AsCString(),
1373 GetPrintableTypeName().c_str());
1374 break;
1375 case lldb::eMemberFunctionKindStaticMethod:
1376 stream.Printf("static method %s of type %s",
1377 m_name.AsCString(),
1378 GetPrintableTypeName().c_str());
1379 break;
1380 }
1381 return true;
1382 }
1383
1384 ClangASTType
GetReturnType() const1385 TypeMemberFunctionImpl::GetReturnType () const
1386 {
1387 if (m_type)
1388 return m_type.GetFunctionReturnType();
1389 if (m_objc_method_decl)
1390 return ClangASTType(&m_objc_method_decl->getASTContext(),m_objc_method_decl->getReturnType().getAsOpaquePtr());
1391 return ClangASTType();
1392 }
1393
1394 size_t
GetNumArguments() const1395 TypeMemberFunctionImpl::GetNumArguments () const
1396 {
1397 if (m_type)
1398 return m_type.GetNumberOfFunctionArguments();
1399 if (m_objc_method_decl)
1400 return m_objc_method_decl->param_size();
1401 return 0;
1402 }
1403
1404 ClangASTType
GetArgumentAtIndex(size_t idx) const1405 TypeMemberFunctionImpl::GetArgumentAtIndex (size_t idx) const
1406 {
1407 if (m_type)
1408 return m_type.GetFunctionArgumentAtIndex (idx);
1409 if (m_objc_method_decl)
1410 {
1411 if (idx < m_objc_method_decl->param_size())
1412 return ClangASTType(&m_objc_method_decl->getASTContext(), m_objc_method_decl->parameters()[idx]->getOriginalType().getAsOpaquePtr());
1413 }
1414 return ClangASTType();
1415 }
1416
TypeEnumMemberImpl(const clang::EnumConstantDecl * enum_member_decl,const lldb_private::ClangASTType & integer_type)1417 TypeEnumMemberImpl::TypeEnumMemberImpl (const clang::EnumConstantDecl* enum_member_decl,
1418 const lldb_private::ClangASTType& integer_type) :
1419 m_integer_type_sp(),
1420 m_name(),
1421 m_value(),
1422 m_valid(false)
1423
1424 {
1425 if (enum_member_decl)
1426 {
1427 m_integer_type_sp.reset(new TypeImpl(integer_type));
1428 m_name = ConstString(enum_member_decl->getNameAsString().c_str());
1429 m_value = enum_member_decl->getInitVal();
1430 m_valid = true;
1431 }
1432 }
1433