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