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 using namespace lldb;
32 using namespace lldb_private;
33 
34 Type *
35 SymbolFileType::GetType ()
36 {
37     if (!m_type_sp)
38     {
39         Type *resolved_type = m_symbol_file.ResolveTypeUID (GetID());
40         if (resolved_type)
41             m_type_sp = resolved_type->shared_from_this();
42     }
43     return m_type_sp.get();
44 }
45 
46 
47 Type::Type
48 (
49     lldb::user_id_t uid,
50     SymbolFile* symbol_file,
51     const ConstString &name,
52     uint32_t byte_size,
53     SymbolContextScope *context,
54     user_id_t encoding_uid,
55     EncodingDataType encoding_uid_type,
56     const Declaration& decl,
57     clang_type_t clang_type,
58     ResolveState clang_type_resolve_state
59 ) :
60     UserID (uid),
61     m_name (name),
62     m_symbol_file (symbol_file),
63     m_context (context),
64     m_encoding_type (NULL),
65     m_encoding_uid (encoding_uid),
66     m_encoding_uid_type (encoding_uid_type),
67     m_byte_size (byte_size),
68     m_decl (decl),
69     m_clang_type (clang_type)
70 {
71     m_flags.clang_type_resolve_state = (clang_type ? clang_type_resolve_state : eResolveStateUnresolved);
72     m_flags.is_complete_objc_class = false;
73 }
74 
75 Type::Type () :
76     UserID (0),
77     m_name ("<INVALID TYPE>"),
78     m_symbol_file (NULL),
79     m_context (NULL),
80     m_encoding_type (NULL),
81     m_encoding_uid (0),
82     m_encoding_uid_type (eEncodingInvalid),
83     m_byte_size (0),
84     m_decl (),
85     m_clang_type (NULL)
86 {
87     m_flags.clang_type_resolve_state = eResolveStateUnresolved;
88     m_flags.is_complete_objc_class = false;
89 }
90 
91 
92 Type::Type (const Type &rhs) :
93     UserID (rhs),
94     m_name (rhs.m_name),
95     m_symbol_file (rhs.m_symbol_file),
96     m_context (rhs.m_context),
97     m_encoding_type (rhs.m_encoding_type),
98     m_encoding_uid (rhs.m_encoding_uid),
99     m_encoding_uid_type (rhs.m_encoding_uid_type),
100     m_byte_size (rhs.m_byte_size),
101     m_decl (rhs.m_decl),
102     m_clang_type (rhs.m_clang_type),
103     m_flags (rhs.m_flags)
104 {
105 }
106 
107 const Type&
108 Type::operator= (const Type& rhs)
109 {
110     if (this != &rhs)
111     {
112     }
113     return *this;
114 }
115 
116 
117 void
118 Type::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_name)
119 {
120     *s << "id = " << (const UserID&)*this;
121 
122     // Call the name accessor to make sure we resolve the type name
123     if (show_name && GetName())
124         *s << ", name = \"" << m_name << '"';
125 
126     // Call the get byte size accesor so we resolve our byte size
127     if (GetByteSize())
128         s->Printf(", byte-size = %u", m_byte_size);
129     bool show_fullpaths = (level == lldb::eDescriptionLevelVerbose);
130     m_decl.Dump(s, show_fullpaths);
131 
132     if (m_clang_type)
133     {
134         *s << ", clang_type = \"";
135         ClangASTType::DumpTypeDescription (GetClangAST(), m_clang_type, s);
136         *s << '"';
137     }
138     else if (m_encoding_uid != LLDB_INVALID_UID)
139     {
140         s->Printf(", type_uid = 0x%8.8x", m_encoding_uid);
141         switch (m_encoding_uid_type)
142         {
143         case eEncodingInvalid: break;
144         case eEncodingIsUID: s->PutCString(" (unresolved type)"); break;
145         case eEncodingIsConstUID: s->PutCString(" (unresolved const type)"); break;
146         case eEncodingIsRestrictUID: s->PutCString(" (unresolved restrict type)"); break;
147         case eEncodingIsVolatileUID: s->PutCString(" (unresolved volatile type)"); break;
148         case eEncodingIsTypedefUID: s->PutCString(" (unresolved typedef)"); break;
149         case eEncodingIsPointerUID: s->PutCString(" (unresolved pointer)"); break;
150         case eEncodingIsLValueReferenceUID: s->PutCString(" (unresolved L value reference)"); break;
151         case eEncodingIsRValueReferenceUID: s->PutCString(" (unresolved R value reference)"); break;
152         case eEncodingIsSyntheticUID: s->PutCString(" (synthetic type)"); break;
153         }
154     }
155 }
156 
157 
158 void
159 Type::Dump (Stream *s, bool show_context)
160 {
161     s->Printf("%p: ", this);
162     s->Indent();
163     *s << "Type" << (const UserID&)*this << ' ';
164     if (m_name)
165         *s << ", name = \"" << m_name << "\"";
166 
167     if (m_byte_size != 0)
168         s->Printf(", size = %u", m_byte_size);
169 
170     if (show_context && m_context != NULL)
171     {
172         s->PutCString(", context = ( ");
173         m_context->DumpSymbolContext(s);
174         s->PutCString(" )");
175     }
176 
177     bool show_fullpaths = false;
178     m_decl.Dump (s,show_fullpaths);
179 
180     if (m_clang_type)
181     {
182         *s << ", clang_type = " << m_clang_type << ' ';
183 
184         ClangASTType::DumpTypeDescription (GetClangAST(), m_clang_type, s);
185     }
186     else if (m_encoding_uid != LLDB_INVALID_UID)
187     {
188         *s << ", type_data = " << (uint64_t)m_encoding_uid;
189         switch (m_encoding_uid_type)
190         {
191         case eEncodingInvalid: break;
192         case eEncodingIsUID: s->PutCString(" (unresolved type)"); break;
193         case eEncodingIsConstUID: s->PutCString(" (unresolved const type)"); break;
194         case eEncodingIsRestrictUID: s->PutCString(" (unresolved restrict type)"); break;
195         case eEncodingIsVolatileUID: s->PutCString(" (unresolved volatile type)"); break;
196         case eEncodingIsTypedefUID: s->PutCString(" (unresolved typedef)"); break;
197         case eEncodingIsPointerUID: s->PutCString(" (unresolved pointer)"); break;
198         case eEncodingIsLValueReferenceUID: s->PutCString(" (unresolved L value reference)"); break;
199         case eEncodingIsRValueReferenceUID: s->PutCString(" (unresolved R value reference)"); break;
200         case eEncodingIsSyntheticUID: s->PutCString(" (synthetic type)"); break;
201         }
202     }
203 
204 //
205 //  if (m_access)
206 //      s->Printf(", access = %u", m_access);
207     s->EOL();
208 }
209 
210 const ConstString &
211 Type::GetName()
212 {
213     if (!m_name)
214     {
215         if (ResolveClangType(eResolveStateForward))
216             m_name = ClangASTType::GetConstTypeName (m_clang_type);
217     }
218     return m_name;
219 }
220 
221 void
222 Type::DumpTypeName(Stream *s)
223 {
224     GetName().Dump(s, "<invalid-type-name>");
225 }
226 
227 
228 void
229 Type::DumpValue
230 (
231     ExecutionContext *exe_ctx,
232     Stream *s,
233     const DataExtractor &data,
234     uint32_t data_byte_offset,
235     bool show_types,
236     bool show_summary,
237     bool verbose,
238     lldb::Format format
239 )
240 {
241     if (ResolveClangType(eResolveStateForward))
242     {
243         if (show_types)
244         {
245             s->PutChar('(');
246             if (verbose)
247                 s->Printf("Type{0x%8.8llx} ", GetID());
248             DumpTypeName (s);
249             s->PutCString(") ");
250         }
251 
252         ClangASTType::DumpValue (GetClangAST (),
253                                                m_clang_type,
254                                                exe_ctx,
255                                                s,
256                                                format == lldb::eFormatDefault ? GetFormat() : format,
257                                                data,
258                                                data_byte_offset,
259                                                GetByteSize(),
260                                                0, // Bitfield bit size
261                                                0, // Bitfield bit offset
262                                                show_types,
263                                                show_summary,
264                                                verbose,
265                                                0);
266     }
267 }
268 
269 Type *
270 Type::GetEncodingType ()
271 {
272     if (m_encoding_type == NULL && m_encoding_uid != LLDB_INVALID_UID)
273         m_encoding_type = m_symbol_file->ResolveTypeUID(m_encoding_uid);
274     return m_encoding_type;
275 }
276 
277 
278 
279 uint32_t
280 Type::GetByteSize()
281 {
282     if (m_byte_size == 0)
283     {
284         switch (m_encoding_uid_type)
285         {
286         case eEncodingInvalid:
287         case eEncodingIsSyntheticUID:
288             break;
289         case eEncodingIsUID:
290         case eEncodingIsConstUID:
291         case eEncodingIsRestrictUID:
292         case eEncodingIsVolatileUID:
293         case eEncodingIsTypedefUID:
294             {
295                 Type *encoding_type = GetEncodingType ();
296                 if (encoding_type)
297                     m_byte_size = encoding_type->GetByteSize();
298                 if (m_byte_size == 0)
299                 {
300                     uint32_t bit_width = ClangASTType::GetClangTypeBitWidth (GetClangAST(), GetClangLayoutType());
301                     m_byte_size = (bit_width + 7 ) / 8;
302                 }
303             }
304             break;
305 
306         // If we are a pointer or reference, then this is just a pointer size;
307         case eEncodingIsPointerUID:
308         case eEncodingIsLValueReferenceUID:
309         case eEncodingIsRValueReferenceUID:
310             m_byte_size = m_symbol_file->GetClangASTContext().GetPointerBitSize() / 8;
311             break;
312         }
313     }
314     return m_byte_size;
315 }
316 
317 
318 uint32_t
319 Type::GetNumChildren (bool omit_empty_base_classes)
320 {
321     if (ResolveClangType(eResolveStateForward))
322     {
323         return ClangASTContext::GetNumChildren (m_symbol_file->GetClangASTContext().getASTContext(),
324                                                 m_clang_type,
325                                                 omit_empty_base_classes);
326     }
327     return 0;
328 }
329 
330 bool
331 Type::IsAggregateType ()
332 {
333     if (ResolveClangType(eResolveStateForward))
334         return ClangASTContext::IsAggregateType (m_clang_type);
335     return false;
336 }
337 
338 lldb::Format
339 Type::GetFormat ()
340 {
341     // Make sure we resolve our type if it already hasn't been.
342     if (!ResolveClangType(eResolveStateForward))
343         return lldb::eFormatInvalid;
344     return ClangASTType::GetFormat (m_clang_type);
345 }
346 
347 
348 
349 lldb::Encoding
350 Type::GetEncoding (uint32_t &count)
351 {
352     // Make sure we resolve our type if it already hasn't been.
353     if (!ResolveClangType(eResolveStateForward))
354         return lldb::eEncodingInvalid;
355 
356     return ClangASTType::GetEncoding (m_clang_type, count);
357 }
358 
359 
360 
361 bool
362 Type::DumpValueInMemory
363 (
364     ExecutionContext *exe_ctx,
365     Stream *s,
366     lldb::addr_t address,
367     AddressType address_type,
368     bool show_types,
369     bool show_summary,
370     bool verbose
371 )
372 {
373     if (address != LLDB_INVALID_ADDRESS)
374     {
375         DataExtractor data;
376         Target *target = NULL;
377         if (exe_ctx)
378             target = exe_ctx->GetTargetPtr();
379         if (target)
380             data.SetByteOrder (target->GetArchitecture().GetByteOrder());
381         if (ReadFromMemory (exe_ctx, address, address_type, data))
382         {
383             DumpValue(exe_ctx, s, data, 0, show_types, show_summary, verbose);
384             return true;
385         }
386     }
387     return false;
388 }
389 
390 
391 bool
392 Type::ReadFromMemory (ExecutionContext *exe_ctx, lldb::addr_t addr, AddressType address_type, DataExtractor &data)
393 {
394     if (address_type == eAddressTypeFile)
395     {
396         // Can't convert a file address to anything valid without more
397         // context (which Module it came from)
398         return false;
399     }
400 
401     const uint32_t byte_size = GetByteSize();
402     if (data.GetByteSize() < byte_size)
403     {
404         lldb::DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0'));
405         data.SetData(data_sp);
406     }
407 
408     uint8_t* dst = (uint8_t*)data.PeekData(0, byte_size);
409     if (dst != NULL)
410     {
411         if (address_type == eAddressTypeHost)
412         {
413             // The address is an address in this process, so just copy it
414             memcpy (dst, (uint8_t*)NULL + addr, byte_size);
415             return true;
416         }
417         else
418         {
419             if (exe_ctx)
420             {
421                 Process *process = exe_ctx->GetProcessPtr();
422                 if (process)
423                 {
424                     Error error;
425                     return exe_ctx->GetProcessPtr()->ReadMemory(addr, dst, byte_size, error) == byte_size;
426                 }
427             }
428         }
429     }
430     return false;
431 }
432 
433 
434 bool
435 Type::WriteToMemory (ExecutionContext *exe_ctx, lldb::addr_t addr, AddressType address_type, DataExtractor &data)
436 {
437     return false;
438 }
439 
440 
441 TypeList*
442 Type::GetTypeList()
443 {
444     return GetSymbolFile()->GetTypeList();
445 }
446 
447 const Declaration &
448 Type::GetDeclaration () const
449 {
450     return m_decl;
451 }
452 
453 bool
454 Type::ResolveClangType (ResolveState clang_type_resolve_state)
455 {
456     Type *encoding_type = NULL;
457     if (m_clang_type == NULL)
458     {
459         encoding_type = GetEncodingType();
460         if (encoding_type)
461         {
462             switch (m_encoding_uid_type)
463             {
464             case eEncodingIsUID:
465                 if (encoding_type->ResolveClangType(clang_type_resolve_state))
466                 {
467                     m_clang_type = encoding_type->m_clang_type;
468                     m_flags.clang_type_resolve_state = encoding_type->m_flags.clang_type_resolve_state;
469                 }
470                 break;
471 
472             case eEncodingIsConstUID:
473                 m_clang_type = ClangASTContext::AddConstModifier (encoding_type->GetClangForwardType());
474                 break;
475 
476             case eEncodingIsRestrictUID:
477                 m_clang_type = ClangASTContext::AddRestrictModifier (encoding_type->GetClangForwardType());
478                 break;
479 
480             case eEncodingIsVolatileUID:
481                 m_clang_type = ClangASTContext::AddVolatileModifier (encoding_type->GetClangForwardType());
482                 break;
483 
484             case eEncodingIsTypedefUID:
485                 m_clang_type = CreateClangTypedefType (this, encoding_type);
486                 // Clear the name so it can get fully qualified in case the
487                 // typedef is in a namespace.
488                 m_name.Clear();
489                 break;
490 
491             case eEncodingIsPointerUID:
492                 m_clang_type = CreateClangPointerType (encoding_type);
493                 break;
494 
495             case eEncodingIsLValueReferenceUID:
496                 m_clang_type = CreateClangLValueReferenceType (encoding_type);
497                 break;
498 
499             case eEncodingIsRValueReferenceUID:
500                 m_clang_type = CreateClangRValueReferenceType (encoding_type);
501                 break;
502 
503             default:
504                 assert(!"Unhandled encoding_data_type.");
505                 break;
506             }
507         }
508         else
509         {
510             // We have no encoding type, return void?
511             clang_type_t void_clang_type = GetClangASTContext().GetBuiltInType_void();
512             switch (m_encoding_uid_type)
513             {
514             case eEncodingIsUID:
515                 m_clang_type = void_clang_type;
516                 break;
517 
518             case eEncodingIsConstUID:
519                 m_clang_type = ClangASTContext::AddConstModifier (void_clang_type);
520                 break;
521 
522             case eEncodingIsRestrictUID:
523                 m_clang_type = ClangASTContext::AddRestrictModifier (void_clang_type);
524                 break;
525 
526             case eEncodingIsVolatileUID:
527                 m_clang_type = ClangASTContext::AddVolatileModifier (void_clang_type);
528                 break;
529 
530             case eEncodingIsTypedefUID:
531                 m_clang_type = GetClangASTContext().CreateTypedefType (m_name.AsCString(), void_clang_type, NULL);
532                 break;
533 
534             case eEncodingIsPointerUID:
535                 m_clang_type = GetClangASTContext().CreatePointerType (void_clang_type);
536                 break;
537 
538             case eEncodingIsLValueReferenceUID:
539                 m_clang_type = GetClangASTContext().CreateLValueReferenceType (void_clang_type);
540                 break;
541 
542             case eEncodingIsRValueReferenceUID:
543                 m_clang_type = GetClangASTContext().CreateRValueReferenceType (void_clang_type);
544                 break;
545 
546             default:
547                 assert(!"Unhandled encoding_data_type.");
548                 break;
549             }
550         }
551     }
552 
553     // Check if we have a forward reference to a class/struct/union/enum?
554     if (m_clang_type && m_flags.clang_type_resolve_state < clang_type_resolve_state)
555     {
556         m_flags.clang_type_resolve_state = eResolveStateFull;
557         if (!ClangASTType::IsDefined (m_clang_type))
558         {
559             // We have a forward declaration, we need to resolve it to a complete
560             // definition.
561             m_symbol_file->ResolveClangOpaqueTypeDefinition (m_clang_type);
562         }
563     }
564 
565     // If we have an encoding type, then we need to make sure it is
566     // resolved appropriately.
567     if (m_encoding_uid != LLDB_INVALID_UID)
568     {
569         if (encoding_type == NULL)
570             encoding_type = GetEncodingType();
571         if (encoding_type)
572         {
573             ResolveState encoding_clang_type_resolve_state = clang_type_resolve_state;
574 
575             if (clang_type_resolve_state == eResolveStateLayout)
576             {
577                 switch (m_encoding_uid_type)
578                 {
579                 case eEncodingIsPointerUID:
580                 case eEncodingIsLValueReferenceUID:
581                 case eEncodingIsRValueReferenceUID:
582                     encoding_clang_type_resolve_state = eResolveStateForward;
583                     break;
584                 default:
585                     break;
586                 }
587             }
588             encoding_type->ResolveClangType (encoding_clang_type_resolve_state);
589         }
590     }
591     return m_clang_type != NULL;
592 }
593 uint32_t
594 Type::GetEncodingMask ()
595 {
596     uint32_t encoding_mask = 1u << m_encoding_uid_type;
597     Type *encoding_type = GetEncodingType();
598     assert (encoding_type != this);
599     if (encoding_type)
600         encoding_mask |= encoding_type->GetEncodingMask ();
601     return encoding_mask;
602 }
603 
604 clang_type_t
605 Type::GetClangFullType ()
606 {
607     ResolveClangType(eResolveStateFull);
608     return m_clang_type;
609 }
610 
611 clang_type_t
612 Type::GetClangLayoutType ()
613 {
614     ResolveClangType(eResolveStateLayout);
615     return m_clang_type;
616 }
617 
618 clang_type_t
619 Type::GetClangForwardType ()
620 {
621     ResolveClangType (eResolveStateForward);
622     return m_clang_type;
623 }
624 
625 clang::ASTContext *
626 Type::GetClangAST ()
627 {
628     return GetClangASTContext().getASTContext();
629 }
630 
631 ClangASTContext &
632 Type::GetClangASTContext ()
633 {
634     return m_symbol_file->GetClangASTContext();
635 }
636 
637 int
638 Type::Compare(const Type &a, const Type &b)
639 {
640     // Just compare the UID values for now...
641     lldb::user_id_t a_uid = a.GetID();
642     lldb::user_id_t b_uid = b.GetID();
643     if (a_uid < b_uid)
644         return -1;
645     if (a_uid > b_uid)
646         return 1;
647     return 0;
648 //  if (a.getQualType() == b.getQualType())
649 //      return 0;
650 }
651 
652 
653 void *
654 Type::CreateClangPointerType (Type *type)
655 {
656     assert(type);
657     return GetClangASTContext().CreatePointerType(type->GetClangForwardType());
658 }
659 
660 void *
661 Type::CreateClangTypedefType (Type *typedef_type, Type *base_type)
662 {
663     assert(typedef_type && base_type);
664     return GetClangASTContext().CreateTypedefType (typedef_type->GetName().AsCString(),
665                                                    base_type->GetClangForwardType(),
666                                                    typedef_type->GetSymbolFile()->GetClangDeclContextContainingTypeUID(typedef_type->GetID()));
667 }
668 
669 void *
670 Type::CreateClangLValueReferenceType (Type *type)
671 {
672     assert(type);
673     return GetClangASTContext().CreateLValueReferenceType(type->GetClangForwardType());
674 }
675 
676 void *
677 Type::CreateClangRValueReferenceType (Type *type)
678 {
679     assert(type);
680     return GetClangASTContext().CreateRValueReferenceType (type->GetClangForwardType());
681 }
682 
683 bool
684 Type::IsRealObjCClass()
685 {
686     // For now we are just skipping ObjC classes that get made by hand from the runtime, because
687     // those don't have any information.  We could extend this to only return true for "full
688     // definitions" if we can figure that out.
689 
690     if (ClangASTContext::IsObjCClassType(m_clang_type) && GetByteSize() != 0)
691         return true;
692     else
693         return false;
694 }
695 
696 TypeAndOrName::TypeAndOrName () : m_type_sp(), m_type_name()
697 {
698 
699 }
700 
701 TypeAndOrName::TypeAndOrName (TypeSP &in_type_sp) : m_type_sp(in_type_sp)
702 {
703     if (in_type_sp)
704         m_type_name = in_type_sp->GetName();
705 }
706 
707 TypeAndOrName::TypeAndOrName (const char *in_type_str) : m_type_name(in_type_str)
708 {
709 }
710 
711 TypeAndOrName::TypeAndOrName (const TypeAndOrName &rhs) : m_type_sp (rhs.m_type_sp), m_type_name (rhs.m_type_name)
712 {
713 
714 }
715 
716 TypeAndOrName::TypeAndOrName (ConstString &in_type_const_string) : m_type_name (in_type_const_string)
717 {
718 }
719 
720 TypeAndOrName &
721 TypeAndOrName::operator= (const TypeAndOrName &rhs)
722 {
723     if (this != &rhs)
724     {
725         m_type_name = rhs.m_type_name;
726         m_type_sp = rhs.m_type_sp;
727     }
728     return *this;
729 }
730 
731 ConstString
732 TypeAndOrName::GetName () const
733 {
734     if (m_type_sp)
735         return m_type_sp->GetName();
736     else
737         return m_type_name;
738 }
739 
740 void
741 TypeAndOrName::SetName (ConstString &type_name_const_str)
742 {
743     m_type_name = type_name_const_str;
744 }
745 
746 void
747 TypeAndOrName::SetName (const char *type_name_str)
748 {
749     m_type_name.SetCString (type_name_str);
750 }
751 
752 void
753 TypeAndOrName::SetTypeSP (lldb::TypeSP type_sp)
754 {
755     m_type_sp = type_sp;
756     if (type_sp)
757         m_type_name = type_sp->GetName();
758 }
759 
760 bool
761 TypeAndOrName::IsEmpty()
762 {
763     if (m_type_name || m_type_sp)
764         return false;
765     else
766         return true;
767 }
768 
769 TypeImpl::TypeImpl(const lldb_private::ClangASTType& clang_ast_type) :
770     m_clang_ast_type(clang_ast_type.GetASTContext(), clang_ast_type.GetOpaqueQualType()),
771     m_type_sp()
772 {}
773 
774 TypeImpl::TypeImpl(const lldb::TypeSP& type) :
775     m_clang_ast_type(type->GetClangAST(), type->GetClangFullType()),
776     m_type_sp(type)
777 {
778 }
779 
780 void
781 TypeImpl::SetType (const lldb::TypeSP &type_sp)
782 {
783     if (type_sp)
784     {
785         m_clang_ast_type.SetClangType (type_sp->GetClangAST(), type_sp->GetClangFullType());
786         m_type_sp = type_sp;
787     }
788     else
789     {
790         m_clang_ast_type.Clear();
791         m_type_sp.reset();
792     }
793 }
794 
795 TypeImpl&
796 TypeImpl::operator = (const TypeImpl& rhs)
797 {
798     if (*this != rhs)
799     {
800         m_clang_ast_type = rhs.m_clang_ast_type;
801         m_type_sp = rhs.m_type_sp;
802     }
803     return *this;
804 }
805 
806 clang::ASTContext*
807 TypeImpl::GetASTContext()
808 {
809     if (!IsValid())
810         return NULL;
811 
812     return m_clang_ast_type.GetASTContext();
813 }
814 
815 lldb::clang_type_t
816 TypeImpl::GetOpaqueQualType()
817 {
818     if (!IsValid())
819         return NULL;
820 
821     return m_clang_ast_type.GetOpaqueQualType();
822 }
823 
824 bool
825 TypeImpl::GetDescription (lldb_private::Stream &strm,
826                           lldb::DescriptionLevel description_level)
827 {
828     if (m_clang_ast_type.IsValid())
829     {
830         ClangASTType::DumpTypeDescription (m_clang_ast_type.GetASTContext(),
831                                            m_clang_ast_type.GetOpaqueQualType(),
832                                            &strm);
833     }
834     else
835     {
836         strm.PutCString ("No value");
837     }
838     return true;
839 }
840 
841