//===-- Type.cpp ------------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// Other libraries and framework includes

#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Core/StreamString.h"

#include "lldb/Symbol/ClangASTType.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContextScope.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeList.h"

#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"

#include "llvm/ADT/StringRef.h"

using namespace lldb;
using namespace lldb_private;

class TypeAppendVisitor
{
public:
    TypeAppendVisitor(TypeListImpl &type_list) :
        m_type_list(type_list)
    {
    }
    
    bool
    operator() (const lldb::TypeSP& type)
    {
        m_type_list.Append(TypeImplSP(new TypeImpl(type)));
        return true;
    }
    
private:
    TypeListImpl &m_type_list;
};

void
TypeListImpl::Append (const lldb_private::TypeList &type_list)
{
    TypeAppendVisitor cb(*this);
    type_list.ForEach(cb);
}


Type *
SymbolFileType::GetType ()
{
    if (!m_type_sp)
    {
        Type *resolved_type = m_symbol_file.ResolveTypeUID (GetID());
        if (resolved_type)
            m_type_sp = resolved_type->shared_from_this();
    }
    return m_type_sp.get();
}


Type::Type
(
    lldb::user_id_t uid,
    SymbolFile* symbol_file,
    const ConstString &name,
    uint64_t byte_size,
    SymbolContextScope *context,
    user_id_t encoding_uid,
    EncodingDataType encoding_uid_type,
    const Declaration& decl,
    const ClangASTType &clang_type,
    ResolveState clang_type_resolve_state
) :
    std::enable_shared_from_this<Type> (),
    UserID (uid),
    m_name (name),
    m_symbol_file (symbol_file),
    m_context (context),
    m_encoding_type (NULL),
    m_encoding_uid (encoding_uid),
    m_encoding_uid_type (encoding_uid_type),
    m_byte_size (byte_size),
    m_decl (decl),
    m_clang_type (clang_type)
{
    m_flags.clang_type_resolve_state = (clang_type ? clang_type_resolve_state : eResolveStateUnresolved);
    m_flags.is_complete_objc_class = false;
}

Type::Type () :
    std::enable_shared_from_this<Type> (),
    UserID (0),
    m_name ("<INVALID TYPE>"),
    m_symbol_file (NULL),
    m_context (NULL),
    m_encoding_type (NULL),
    m_encoding_uid (LLDB_INVALID_UID),
    m_encoding_uid_type (eEncodingInvalid),
    m_byte_size (0),
    m_decl (),
    m_clang_type ()
{
    m_flags.clang_type_resolve_state = eResolveStateUnresolved;
    m_flags.is_complete_objc_class = false;
}


Type::Type (const Type &rhs) :
    std::enable_shared_from_this<Type> (rhs),
    UserID (rhs),
    m_name (rhs.m_name),
    m_symbol_file (rhs.m_symbol_file),
    m_context (rhs.m_context),
    m_encoding_type (rhs.m_encoding_type),
    m_encoding_uid (rhs.m_encoding_uid),
    m_encoding_uid_type (rhs.m_encoding_uid_type),
    m_byte_size (rhs.m_byte_size),
    m_decl (rhs.m_decl),
    m_clang_type (rhs.m_clang_type),
    m_flags (rhs.m_flags)
{
}

const Type&
Type::operator= (const Type& rhs)
{
    if (this != &rhs)
    {
    }
    return *this;
}


void
Type::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_name)
{
    *s << "id = " << (const UserID&)*this;

    // Call the name accessor to make sure we resolve the type name
    if (show_name)
    {
        const ConstString &type_name = GetName();
        if (type_name)
        {
            *s << ", name = \"" << type_name << '"';
            ConstString qualified_type_name (GetQualifiedName());
            if (qualified_type_name != type_name)
            {
                *s << ", qualified = \"" << qualified_type_name << '"';
            }
        }
    }

    // Call the get byte size accesor so we resolve our byte size
    if (GetByteSize())
        s->Printf(", byte-size = %" PRIu64, m_byte_size);
    bool show_fullpaths = (level == lldb::eDescriptionLevelVerbose);
    m_decl.Dump(s, show_fullpaths);

    if (m_clang_type.IsValid())
    {
        *s << ", clang_type = \"";
        GetClangForwardType().DumpTypeDescription(s);
        *s << '"';
    }
    else if (m_encoding_uid != LLDB_INVALID_UID)
    {
        s->Printf(", type_uid = 0x%8.8" PRIx64, m_encoding_uid);
        switch (m_encoding_uid_type)
        {
        case eEncodingInvalid: break;
        case eEncodingIsUID: s->PutCString(" (unresolved type)"); break;
        case eEncodingIsConstUID: s->PutCString(" (unresolved const type)"); break;
        case eEncodingIsRestrictUID: s->PutCString(" (unresolved restrict type)"); break;
        case eEncodingIsVolatileUID: s->PutCString(" (unresolved volatile type)"); break;
        case eEncodingIsTypedefUID: s->PutCString(" (unresolved typedef)"); break;
        case eEncodingIsPointerUID: s->PutCString(" (unresolved pointer)"); break;
        case eEncodingIsLValueReferenceUID: s->PutCString(" (unresolved L value reference)"); break;
        case eEncodingIsRValueReferenceUID: s->PutCString(" (unresolved R value reference)"); break;
        case eEncodingIsSyntheticUID: s->PutCString(" (synthetic type)"); break;
        }
    }    
}


void
Type::Dump (Stream *s, bool show_context)
{
    s->Printf("%p: ", this);
    s->Indent();
    *s << "Type" << (const UserID&)*this << ' ';
    if (m_name)
        *s << ", name = \"" << m_name << "\"";

    if (m_byte_size != 0)
        s->Printf(", size = %" PRIu64, m_byte_size);

    if (show_context && m_context != NULL)
    {
        s->PutCString(", context = ( ");
        m_context->DumpSymbolContext(s);
        s->PutCString(" )");
    }

    bool show_fullpaths = false;
    m_decl.Dump (s,show_fullpaths);

    if (m_clang_type.IsValid())
    {
        *s << ", clang_type = " << m_clang_type.GetOpaqueQualType() << ' ';
        GetClangForwardType().DumpTypeDescription (s);
    }
    else if (m_encoding_uid != LLDB_INVALID_UID)
    {
        *s << ", type_data = " << (uint64_t)m_encoding_uid;
        switch (m_encoding_uid_type)
        {
        case eEncodingInvalid: break;
        case eEncodingIsUID: s->PutCString(" (unresolved type)"); break;
        case eEncodingIsConstUID: s->PutCString(" (unresolved const type)"); break;
        case eEncodingIsRestrictUID: s->PutCString(" (unresolved restrict type)"); break;
        case eEncodingIsVolatileUID: s->PutCString(" (unresolved volatile type)"); break;
        case eEncodingIsTypedefUID: s->PutCString(" (unresolved typedef)"); break;
        case eEncodingIsPointerUID: s->PutCString(" (unresolved pointer)"); break;
        case eEncodingIsLValueReferenceUID: s->PutCString(" (unresolved L value reference)"); break;
        case eEncodingIsRValueReferenceUID: s->PutCString(" (unresolved R value reference)"); break;
        case eEncodingIsSyntheticUID: s->PutCString(" (synthetic type)"); break;
        }
    }

//
//  if (m_access)
//      s->Printf(", access = %u", m_access);
    s->EOL();
}

const ConstString &
Type::GetName()
{
    if (!m_name)
        m_name = GetClangForwardType().GetConstTypeName();
    return m_name;
}

void
Type::DumpTypeName(Stream *s)
{
    GetName().Dump(s, "<invalid-type-name>");
}


void
Type::DumpValue
(
    ExecutionContext *exe_ctx,
    Stream *s,
    const DataExtractor &data,
    uint32_t data_byte_offset,
    bool show_types,
    bool show_summary,
    bool verbose,
    lldb::Format format
)
{
    if (ResolveClangType(eResolveStateForward))
    {
        if (show_types)
        {
            s->PutChar('(');
            if (verbose)
                s->Printf("Type{0x%8.8" PRIx64 "} ", GetID());
            DumpTypeName (s);
            s->PutCString(") ");
        }

        GetClangForwardType().DumpValue (exe_ctx,
                                         s,
                                         format == lldb::eFormatDefault ? GetFormat() : format,
                                         data,
                                         data_byte_offset,
                                         GetByteSize(),
                                         0, // Bitfield bit size
                                         0, // Bitfield bit offset
                                         show_types,
                                         show_summary,
                                         verbose,
                                         0);
    }
}

Type *
Type::GetEncodingType ()
{
    if (m_encoding_type == NULL && m_encoding_uid != LLDB_INVALID_UID)
        m_encoding_type = m_symbol_file->ResolveTypeUID(m_encoding_uid);
    return m_encoding_type;
}
    


uint64_t
Type::GetByteSize()
{
    if (m_byte_size == 0)
    {
        switch (m_encoding_uid_type)
        {
        case eEncodingInvalid:
        case eEncodingIsSyntheticUID:
            break;
        case eEncodingIsUID:
        case eEncodingIsConstUID:
        case eEncodingIsRestrictUID:
        case eEncodingIsVolatileUID:
        case eEncodingIsTypedefUID:
            {
                Type *encoding_type = GetEncodingType ();
                if (encoding_type)
                    m_byte_size = encoding_type->GetByteSize();
                if (m_byte_size == 0)
                    m_byte_size = GetClangLayoutType().GetByteSize();
            }
            break;

        // If we are a pointer or reference, then this is just a pointer size;
        case eEncodingIsPointerUID:
        case eEncodingIsLValueReferenceUID:
        case eEncodingIsRValueReferenceUID:
            m_byte_size = m_symbol_file->GetClangASTContext().GetPointerByteSize();
            break;
        }
    }
    return m_byte_size;
}


uint32_t
Type::GetNumChildren (bool omit_empty_base_classes)
{
    return GetClangForwardType().GetNumChildren(omit_empty_base_classes);
}

bool
Type::IsAggregateType ()
{
    return GetClangForwardType().IsAggregateType();
}

lldb::TypeSP
Type::GetTypedefType()
{
    lldb::TypeSP type_sp;
    if (IsTypedef())
    {
        Type *typedef_type = m_symbol_file->ResolveTypeUID(m_encoding_uid);
        if (typedef_type)
            type_sp = typedef_type->shared_from_this();
    }
    return type_sp;
}



lldb::Format
Type::GetFormat ()
{
    return GetClangForwardType().GetFormat();
}



lldb::Encoding
Type::GetEncoding (uint64_t &count)
{
    // Make sure we resolve our type if it already hasn't been.
    return GetClangForwardType().GetEncoding(count);
}

bool
Type::DumpValueInMemory
(
    ExecutionContext *exe_ctx,
    Stream *s,
    lldb::addr_t address,
    AddressType address_type,
    bool show_types,
    bool show_summary,
    bool verbose
)
{
    if (address != LLDB_INVALID_ADDRESS)
    {
        DataExtractor data;
        Target *target = NULL;
        if (exe_ctx)
            target = exe_ctx->GetTargetPtr();
        if (target)
            data.SetByteOrder (target->GetArchitecture().GetByteOrder());
        if (ReadFromMemory (exe_ctx, address, address_type, data))
        {
            DumpValue(exe_ctx, s, data, 0, show_types, show_summary, verbose);
            return true;
        }
    }
    return false;
}


bool
Type::ReadFromMemory (ExecutionContext *exe_ctx, lldb::addr_t addr, AddressType address_type, DataExtractor &data)
{
    if (address_type == eAddressTypeFile)
    {
        // Can't convert a file address to anything valid without more
        // context (which Module it came from)
        return false;
    }

    const uint64_t byte_size = GetByteSize();
    if (data.GetByteSize() < byte_size)
    {
        lldb::DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0'));
        data.SetData(data_sp);
    }

    uint8_t* dst = (uint8_t*)data.PeekData(0, byte_size);
    if (dst != NULL)
    {
        if (address_type == eAddressTypeHost)
        {
            // The address is an address in this process, so just copy it
            if (addr == 0)
                return false;
            memcpy (dst, (uint8_t*)NULL + addr, byte_size);
            return true;
        }
        else
        {
            if (exe_ctx)
            {
                Process *process = exe_ctx->GetProcessPtr();
                if (process)
                {
                    Error error;
                    return exe_ctx->GetProcessPtr()->ReadMemory(addr, dst, byte_size, error) == byte_size;
                }
            }
        }
    }
    return false;
}


bool
Type::WriteToMemory (ExecutionContext *exe_ctx, lldb::addr_t addr, AddressType address_type, DataExtractor &data)
{
    return false;
}


TypeList*
Type::GetTypeList()
{
    return GetSymbolFile()->GetTypeList();
}

const Declaration &
Type::GetDeclaration () const
{
    return m_decl;
}

bool
Type::ResolveClangType (ResolveState clang_type_resolve_state)
{
    Type *encoding_type = NULL;
    if (!m_clang_type.IsValid())
    {
        encoding_type = GetEncodingType();
        if (encoding_type)
        {
            switch (m_encoding_uid_type)
            {
            case eEncodingIsUID:
                {
                    ClangASTType encoding_clang_type = encoding_type->GetClangForwardType();
                    if (encoding_clang_type.IsValid())
                    {
                        m_clang_type = encoding_clang_type;
                        m_flags.clang_type_resolve_state = encoding_type->m_flags.clang_type_resolve_state;
                    }
                }
                break;

            case eEncodingIsConstUID:
                m_clang_type = encoding_type->GetClangForwardType().AddConstModifier();
                break;

            case eEncodingIsRestrictUID:
                m_clang_type = encoding_type->GetClangForwardType().AddRestrictModifier();
                break;

            case eEncodingIsVolatileUID:
                m_clang_type = encoding_type->GetClangForwardType().AddVolatileModifier();
                break;

            case eEncodingIsTypedefUID:
                m_clang_type = encoding_type->GetClangForwardType().CreateTypedefType (GetName().AsCString(),
                                                                                       GetSymbolFile()->GetClangDeclContextContainingTypeUID(GetID()));
                m_name.Clear();
                break;

            case eEncodingIsPointerUID:
                m_clang_type = encoding_type->GetClangForwardType().GetPointerType();
                break;

            case eEncodingIsLValueReferenceUID:
                m_clang_type = encoding_type->GetClangForwardType().GetLValueReferenceType();
                break;

            case eEncodingIsRValueReferenceUID:
                m_clang_type = encoding_type->GetClangForwardType().GetRValueReferenceType();
                break;

            default:
                assert(!"Unhandled encoding_data_type.");
                break;
            }
        }
        else
        {
            // We have no encoding type, return void?
            ClangASTType void_clang_type (ClangASTContext::GetBasicType(GetClangASTContext().getASTContext(), eBasicTypeVoid));
            switch (m_encoding_uid_type)
            {
            case eEncodingIsUID:
                m_clang_type = void_clang_type;
                break;

            case eEncodingIsConstUID:
                m_clang_type = void_clang_type.AddConstModifier ();
                break;

            case eEncodingIsRestrictUID:
                m_clang_type = void_clang_type.AddRestrictModifier ();
                break;

            case eEncodingIsVolatileUID:
                m_clang_type = void_clang_type.AddVolatileModifier ();
                break;

            case eEncodingIsTypedefUID:
                m_clang_type = void_clang_type.CreateTypedefType (GetName().AsCString(),
                                                                  GetSymbolFile()->GetClangDeclContextContainingTypeUID(GetID()));
                break;

            case eEncodingIsPointerUID:
                m_clang_type = void_clang_type.GetPointerType ();
                break;

            case eEncodingIsLValueReferenceUID:
                m_clang_type = void_clang_type.GetLValueReferenceType ();
                break;

            case eEncodingIsRValueReferenceUID:
                m_clang_type = void_clang_type.GetRValueReferenceType ();
                break;

            default:
                assert(!"Unhandled encoding_data_type.");
                break;
            }
        }
    }
    
    // Check if we have a forward reference to a class/struct/union/enum?
    if (m_clang_type.IsValid() && m_flags.clang_type_resolve_state < clang_type_resolve_state)
    {
        m_flags.clang_type_resolve_state = eResolveStateFull;
        if (!m_clang_type.IsDefined ())
        {
            // We have a forward declaration, we need to resolve it to a complete definition.
            m_symbol_file->ResolveClangOpaqueTypeDefinition (m_clang_type);
        }
    }
    
    // If we have an encoding type, then we need to make sure it is 
    // resolved appropriately.
    if (m_encoding_uid != LLDB_INVALID_UID)
    {
        if (encoding_type == NULL)
            encoding_type = GetEncodingType();
        if (encoding_type)
        {
            ResolveState encoding_clang_type_resolve_state = clang_type_resolve_state;
            
            if (clang_type_resolve_state == eResolveStateLayout)
            {
                switch (m_encoding_uid_type)
                {
                case eEncodingIsPointerUID:
                case eEncodingIsLValueReferenceUID:
                case eEncodingIsRValueReferenceUID:
                    encoding_clang_type_resolve_state = eResolveStateForward;
                    break;
                default:
                    break;
                }
            }
            encoding_type->ResolveClangType (encoding_clang_type_resolve_state);
        }
    }
    return m_clang_type.IsValid();
}
uint32_t
Type::GetEncodingMask ()
{
    uint32_t encoding_mask = 1u << m_encoding_uid_type;
    Type *encoding_type = GetEncodingType();
    assert (encoding_type != this);
    if (encoding_type)
        encoding_mask |= encoding_type->GetEncodingMask ();
    return encoding_mask;
}

ClangASTType
Type::GetClangFullType ()
{
    ResolveClangType(eResolveStateFull);
    return m_clang_type;
}

ClangASTType
Type::GetClangLayoutType ()
{
    ResolveClangType(eResolveStateLayout);
    return m_clang_type;
}

ClangASTType 
Type::GetClangForwardType ()
{
    ResolveClangType (eResolveStateForward);
    return m_clang_type;
}

ClangASTContext &
Type::GetClangASTContext ()
{
    return m_symbol_file->GetClangASTContext();
}

int
Type::Compare(const Type &a, const Type &b)
{
    // Just compare the UID values for now...
    lldb::user_id_t a_uid = a.GetID();
    lldb::user_id_t b_uid = b.GetID();
    if (a_uid < b_uid)
        return -1;
    if (a_uid > b_uid)
        return 1;
    return 0;
//  if (a.getQualType() == b.getQualType())
//      return 0;
}


#if 0  // START REMOVE
// Move this into ClangASTType
void *
Type::CreateClangPointerType (Type *type)
{
    assert(type);
    return GetClangASTContext().CreatePointerType(type->GetClangForwardType());
}

void *
Type::CreateClangTypedefType (Type *typedef_type, Type *base_type)
{
    assert(typedef_type && base_type);
    return GetClangASTContext().CreateTypedefType (typedef_type->GetName().AsCString(), 
                                                   base_type->GetClangForwardType(), 
                                                   typedef_type->GetSymbolFile()->GetClangDeclContextContainingTypeUID(typedef_type->GetID()));
}

void *
Type::CreateClangLValueReferenceType (Type *type)
{
    assert(type);
    return GetClangASTContext().CreateLValueReferenceType(type->GetClangForwardType());
}

void *
Type::CreateClangRValueReferenceType (Type *type)
{
    assert(type);
    return GetClangASTContext().CreateRValueReferenceType (type->GetClangForwardType());
}
#endif // END REMOVE

bool
Type::IsRealObjCClass()
{
    // For now we are just skipping ObjC classes that get made by hand from the runtime, because
    // those don't have any information.  We could extend this to only return true for "full 
    // definitions" if we can figure that out.
    
    if (m_clang_type.IsObjCObjectOrInterfaceType() && GetByteSize() != 0)
        return true;
    else
        return false;
}

ConstString
Type::GetQualifiedName ()
{
    return GetClangForwardType().GetConstTypeName();
}


bool
Type::GetTypeScopeAndBasename (const char* &name_cstr,
                               std::string &scope,
                               std::string &basename,
                               TypeClass &type_class)
{
    // Protect against null c string.
    
    type_class = eTypeClassAny;

    if (name_cstr && name_cstr[0])
    {
        llvm::StringRef name_strref(name_cstr);
        if (name_strref.startswith("struct "))
        {
            name_cstr += 7;
            type_class = eTypeClassStruct;
        }
        else if (name_strref.startswith("class "))
        {
            name_cstr += 6;
            type_class = eTypeClassClass;
        }
        else if (name_strref.startswith("union "))
        {
            name_cstr += 6;
            type_class = eTypeClassUnion;
        }
        else if (name_strref.startswith("enum "))
        {
            name_cstr += 5;
            type_class = eTypeClassEnumeration;
        }
        else if (name_strref.startswith("typedef "))
        {
            name_cstr += 8;
            type_class = eTypeClassTypedef;
        }
        const char *basename_cstr = name_cstr;
        const char* namespace_separator = ::strstr (basename_cstr, "::");
        if (namespace_separator)
        {
            const char* template_arg_char = ::strchr (basename_cstr, '<');
            while (namespace_separator != NULL)
            {
                if (template_arg_char && namespace_separator > template_arg_char) // but namespace'd template arguments are still good to go
                    break;
                basename_cstr = namespace_separator + 2;
                namespace_separator = strstr(basename_cstr, "::");
            }
            if (basename_cstr > name_cstr)
            {
                scope.assign (name_cstr, basename_cstr - name_cstr);
                basename.assign (basename_cstr);
                return true;
            }
        }
    }
    return false;
}




TypeAndOrName::TypeAndOrName () : m_type_sp(), m_type_name()
{

}

TypeAndOrName::TypeAndOrName (TypeSP &in_type_sp) : m_type_sp(in_type_sp)
{
    if (in_type_sp)
        m_type_name = in_type_sp->GetName();
}

TypeAndOrName::TypeAndOrName (const char *in_type_str) : m_type_name(in_type_str)
{
}

TypeAndOrName::TypeAndOrName (const TypeAndOrName &rhs) : m_type_sp (rhs.m_type_sp), m_type_name (rhs.m_type_name)
{

}

TypeAndOrName::TypeAndOrName (ConstString &in_type_const_string) : m_type_name (in_type_const_string)
{
}

TypeAndOrName &
TypeAndOrName::operator= (const TypeAndOrName &rhs)
{
    if (this != &rhs)
    {
        m_type_name = rhs.m_type_name;
        m_type_sp = rhs.m_type_sp;
    }
    return *this;
}

bool
TypeAndOrName::operator==(const TypeAndOrName &other) const
{
    if (m_type_sp != other.m_type_sp)
        return false;
    if (m_type_name != other.m_type_name)
        return false;
    return true;
}

bool
TypeAndOrName::operator!=(const TypeAndOrName &other) const
{
    if (m_type_sp != other.m_type_sp)
        return true;
    if (m_type_name != other.m_type_name)
        return true;
    return false;
}

ConstString
TypeAndOrName::GetName () const
{    
    if (m_type_sp)
        return m_type_sp->GetName();
    else
        return m_type_name;
}

void
TypeAndOrName::SetName (const ConstString &type_name)
{
    m_type_name = type_name;
}

void
TypeAndOrName::SetName (const char *type_name_cstr)
{
    m_type_name.SetCString (type_name_cstr);
}

void
TypeAndOrName::SetTypeSP (lldb::TypeSP type_sp)
{
    m_type_sp = type_sp;
    if (type_sp)
        m_type_name = type_sp->GetName();
}

bool
TypeAndOrName::IsEmpty()
{
    if (m_type_name || m_type_sp)
        return false;
    else
        return true;
}

void
TypeAndOrName::Clear ()
{
    m_type_name.Clear();
    m_type_sp.reset();
}

bool
TypeAndOrName::HasName ()
{
    return (bool)m_type_name;
}

bool
TypeAndOrName::HasTypeSP ()
{
    return m_type_sp.get() != NULL;
}

TypeImpl::TypeImpl(const lldb_private::ClangASTType& clang_ast_type) :
    m_clang_ast_type(clang_ast_type),
    m_type_sp()
{
}

TypeImpl::TypeImpl(const lldb::TypeSP& type) :
    m_clang_ast_type(type->GetClangForwardType()),
    m_type_sp(type)
{
}

void
TypeImpl::SetType (const lldb::TypeSP &type_sp)
{
    if (type_sp)
    {
        m_clang_ast_type = type_sp->GetClangForwardType();
        m_type_sp = type_sp;
    }
    else
    {
        m_clang_ast_type.Clear();
        m_type_sp.reset();
    }
}

TypeImpl&
TypeImpl::operator = (const TypeImpl& rhs)
{
    if (*this != rhs)
    {
        m_clang_ast_type = rhs.m_clang_ast_type;
        m_type_sp = rhs.m_type_sp;
    }
    return *this;
}

clang::ASTContext*
TypeImpl::GetASTContext()
{
    if (!IsValid())
        return NULL;
    
    return m_clang_ast_type.GetASTContext();
}

lldb::clang_type_t
TypeImpl::GetOpaqueQualType()
{
    if (!IsValid())
        return NULL;
    
    return m_clang_ast_type.GetOpaqueQualType();
}

bool
TypeImpl::GetDescription (lldb_private::Stream &strm, 
                          lldb::DescriptionLevel description_level)
{
    if (m_clang_ast_type.IsValid())
    {
        m_clang_ast_type.DumpTypeDescription (&strm);
    }
    else
    {
        strm.PutCString ("No value");
    }
    return true;
}

ConstString
TypeImpl::GetName ()
{
    if (m_clang_ast_type.IsValid())
        return m_clang_ast_type.GetConstTypeName();
    return ConstString();
}
