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