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