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