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