1254721Semaste//===-- Type.cpp ------------------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste// Other libraries and framework includes
11254721Semaste
12254721Semaste#include "lldb/Core/DataExtractor.h"
13254721Semaste#include "lldb/Core/DataBufferHeap.h"
14254721Semaste#include "lldb/Core/Module.h"
15254721Semaste#include "lldb/Core/Scalar.h"
16254721Semaste#include "lldb/Core/StreamString.h"
17254721Semaste
18254721Semaste#include "lldb/Symbol/ClangASTType.h"
19254721Semaste#include "lldb/Symbol/ClangASTContext.h"
20254721Semaste#include "lldb/Symbol/ObjectFile.h"
21254721Semaste#include "lldb/Symbol/SymbolContextScope.h"
22254721Semaste#include "lldb/Symbol/SymbolFile.h"
23254721Semaste#include "lldb/Symbol/SymbolVendor.h"
24254721Semaste#include "lldb/Symbol/Type.h"
25254721Semaste#include "lldb/Symbol/TypeList.h"
26254721Semaste
27254721Semaste#include "lldb/Target/ExecutionContext.h"
28254721Semaste#include "lldb/Target/Process.h"
29254721Semaste#include "lldb/Target/Target.h"
30254721Semaste
31254721Semaste#include "llvm/ADT/StringRef.h"
32254721Semaste
33254721Semasteusing namespace lldb;
34254721Semasteusing namespace lldb_private;
35254721Semaste
36254721Semasteclass TypeAppendVisitor
37254721Semaste{
38254721Semastepublic:
39254721Semaste    TypeAppendVisitor(TypeListImpl &type_list) :
40254721Semaste        m_type_list(type_list)
41254721Semaste    {
42254721Semaste    }
43254721Semaste
44254721Semaste    bool
45254721Semaste    operator() (const lldb::TypeSP& type)
46254721Semaste    {
47254721Semaste        m_type_list.Append(TypeImplSP(new TypeImpl(type)));
48254721Semaste        return true;
49254721Semaste    }
50254721Semaste
51254721Semasteprivate:
52254721Semaste    TypeListImpl &m_type_list;
53254721Semaste};
54254721Semaste
55254721Semastevoid
56254721SemasteTypeListImpl::Append (const lldb_private::TypeList &type_list)
57254721Semaste{
58254721Semaste    TypeAppendVisitor cb(*this);
59254721Semaste    type_list.ForEach(cb);
60254721Semaste}
61254721Semaste
62254721Semaste
63254721SemasteType *
64254721SemasteSymbolFileType::GetType ()
65254721Semaste{
66254721Semaste    if (!m_type_sp)
67254721Semaste    {
68254721Semaste        Type *resolved_type = m_symbol_file.ResolveTypeUID (GetID());
69254721Semaste        if (resolved_type)
70254721Semaste            m_type_sp = resolved_type->shared_from_this();
71254721Semaste    }
72254721Semaste    return m_type_sp.get();
73254721Semaste}
74254721Semaste
75254721Semaste
76254721SemasteType::Type
77254721Semaste(
78254721Semaste    lldb::user_id_t uid,
79254721Semaste    SymbolFile* symbol_file,
80254721Semaste    const ConstString &name,
81254721Semaste    uint64_t byte_size,
82254721Semaste    SymbolContextScope *context,
83254721Semaste    user_id_t encoding_uid,
84254721Semaste    EncodingDataType encoding_uid_type,
85254721Semaste    const Declaration& decl,
86254721Semaste    const ClangASTType &clang_type,
87254721Semaste    ResolveState clang_type_resolve_state
88254721Semaste) :
89254721Semaste    std::enable_shared_from_this<Type> (),
90254721Semaste    UserID (uid),
91254721Semaste    m_name (name),
92254721Semaste    m_symbol_file (symbol_file),
93254721Semaste    m_context (context),
94254721Semaste    m_encoding_type (NULL),
95254721Semaste    m_encoding_uid (encoding_uid),
96254721Semaste    m_encoding_uid_type (encoding_uid_type),
97254721Semaste    m_byte_size (byte_size),
98254721Semaste    m_decl (decl),
99254721Semaste    m_clang_type (clang_type)
100254721Semaste{
101254721Semaste    m_flags.clang_type_resolve_state = (clang_type ? clang_type_resolve_state : eResolveStateUnresolved);
102254721Semaste    m_flags.is_complete_objc_class = false;
103254721Semaste}
104254721Semaste
105254721SemasteType::Type () :
106254721Semaste    std::enable_shared_from_this<Type> (),
107254721Semaste    UserID (0),
108254721Semaste    m_name ("<INVALID TYPE>"),
109254721Semaste    m_symbol_file (NULL),
110254721Semaste    m_context (NULL),
111254721Semaste    m_encoding_type (NULL),
112254721Semaste    m_encoding_uid (LLDB_INVALID_UID),
113254721Semaste    m_encoding_uid_type (eEncodingInvalid),
114254721Semaste    m_byte_size (0),
115254721Semaste    m_decl (),
116254721Semaste    m_clang_type ()
117254721Semaste{
118254721Semaste    m_flags.clang_type_resolve_state = eResolveStateUnresolved;
119254721Semaste    m_flags.is_complete_objc_class = false;
120254721Semaste}
121254721Semaste
122254721Semaste
123254721SemasteType::Type (const Type &rhs) :
124254721Semaste    std::enable_shared_from_this<Type> (rhs),
125254721Semaste    UserID (rhs),
126254721Semaste    m_name (rhs.m_name),
127254721Semaste    m_symbol_file (rhs.m_symbol_file),
128254721Semaste    m_context (rhs.m_context),
129254721Semaste    m_encoding_type (rhs.m_encoding_type),
130254721Semaste    m_encoding_uid (rhs.m_encoding_uid),
131254721Semaste    m_encoding_uid_type (rhs.m_encoding_uid_type),
132254721Semaste    m_byte_size (rhs.m_byte_size),
133254721Semaste    m_decl (rhs.m_decl),
134254721Semaste    m_clang_type (rhs.m_clang_type),
135254721Semaste    m_flags (rhs.m_flags)
136254721Semaste{
137254721Semaste}
138254721Semaste
139254721Semasteconst Type&
140254721SemasteType::operator= (const Type& rhs)
141254721Semaste{
142254721Semaste    if (this != &rhs)
143254721Semaste    {
144254721Semaste    }
145254721Semaste    return *this;
146254721Semaste}
147254721Semaste
148254721Semaste
149254721Semastevoid
150254721SemasteType::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_name)
151254721Semaste{
152254721Semaste    *s << "id = " << (const UserID&)*this;
153254721Semaste
154254721Semaste    // Call the name accessor to make sure we resolve the type name
155254721Semaste    if (show_name)
156254721Semaste    {
157254721Semaste        const ConstString &type_name = GetName();
158254721Semaste        if (type_name)
159254721Semaste        {
160254721Semaste            *s << ", name = \"" << type_name << '"';
161254721Semaste            ConstString qualified_type_name (GetQualifiedName());
162254721Semaste            if (qualified_type_name != type_name)
163254721Semaste            {
164254721Semaste                *s << ", qualified = \"" << qualified_type_name << '"';
165254721Semaste            }
166254721Semaste        }
167254721Semaste    }
168254721Semaste
169254721Semaste    // Call the get byte size accesor so we resolve our byte size
170254721Semaste    if (GetByteSize())
171254721Semaste        s->Printf(", byte-size = %" PRIu64, m_byte_size);
172254721Semaste    bool show_fullpaths = (level == lldb::eDescriptionLevelVerbose);
173254721Semaste    m_decl.Dump(s, show_fullpaths);
174254721Semaste
175254721Semaste    if (m_clang_type.IsValid())
176254721Semaste    {
177254721Semaste        *s << ", clang_type = \"";
178254721Semaste        GetClangForwardType().DumpTypeDescription(s);
179254721Semaste        *s << '"';
180254721Semaste    }
181254721Semaste    else if (m_encoding_uid != LLDB_INVALID_UID)
182254721Semaste    {
183254721Semaste        s->Printf(", type_uid = 0x%8.8" PRIx64, m_encoding_uid);
184254721Semaste        switch (m_encoding_uid_type)
185254721Semaste        {
186254721Semaste        case eEncodingInvalid: break;
187254721Semaste        case eEncodingIsUID: s->PutCString(" (unresolved type)"); break;
188254721Semaste        case eEncodingIsConstUID: s->PutCString(" (unresolved const type)"); break;
189254721Semaste        case eEncodingIsRestrictUID: s->PutCString(" (unresolved restrict type)"); break;
190254721Semaste        case eEncodingIsVolatileUID: s->PutCString(" (unresolved volatile type)"); break;
191254721Semaste        case eEncodingIsTypedefUID: s->PutCString(" (unresolved typedef)"); break;
192254721Semaste        case eEncodingIsPointerUID: s->PutCString(" (unresolved pointer)"); break;
193254721Semaste        case eEncodingIsLValueReferenceUID: s->PutCString(" (unresolved L value reference)"); break;
194254721Semaste        case eEncodingIsRValueReferenceUID: s->PutCString(" (unresolved R value reference)"); break;
195254721Semaste        case eEncodingIsSyntheticUID: s->PutCString(" (synthetic type)"); break;
196254721Semaste        }
197254721Semaste    }
198254721Semaste}
199254721Semaste
200254721Semaste
201254721Semastevoid
202254721SemasteType::Dump (Stream *s, bool show_context)
203254721Semaste{
204254721Semaste    s->Printf("%p: ", this);
205254721Semaste    s->Indent();
206254721Semaste    *s << "Type" << (const UserID&)*this << ' ';
207254721Semaste    if (m_name)
208254721Semaste        *s << ", name = \"" << m_name << "\"";
209254721Semaste
210254721Semaste    if (m_byte_size != 0)
211254721Semaste        s->Printf(", size = %" PRIu64, m_byte_size);
212254721Semaste
213254721Semaste    if (show_context && m_context != NULL)
214254721Semaste    {
215254721Semaste        s->PutCString(", context = ( ");
216254721Semaste        m_context->DumpSymbolContext(s);
217254721Semaste        s->PutCString(" )");
218254721Semaste    }
219254721Semaste
220254721Semaste    bool show_fullpaths = false;
221254721Semaste    m_decl.Dump (s,show_fullpaths);
222254721Semaste
223254721Semaste    if (m_clang_type.IsValid())
224254721Semaste    {
225254721Semaste        *s << ", clang_type = " << m_clang_type.GetOpaqueQualType() << ' ';
226254721Semaste        GetClangForwardType().DumpTypeDescription (s);
227254721Semaste    }
228254721Semaste    else if (m_encoding_uid != LLDB_INVALID_UID)
229254721Semaste    {
230254721Semaste        *s << ", type_data = " << (uint64_t)m_encoding_uid;
231254721Semaste        switch (m_encoding_uid_type)
232254721Semaste        {
233254721Semaste        case eEncodingInvalid: break;
234254721Semaste        case eEncodingIsUID: s->PutCString(" (unresolved type)"); break;
235254721Semaste        case eEncodingIsConstUID: s->PutCString(" (unresolved const type)"); break;
236254721Semaste        case eEncodingIsRestrictUID: s->PutCString(" (unresolved restrict type)"); break;
237254721Semaste        case eEncodingIsVolatileUID: s->PutCString(" (unresolved volatile type)"); break;
238254721Semaste        case eEncodingIsTypedefUID: s->PutCString(" (unresolved typedef)"); break;
239254721Semaste        case eEncodingIsPointerUID: s->PutCString(" (unresolved pointer)"); break;
240254721Semaste        case eEncodingIsLValueReferenceUID: s->PutCString(" (unresolved L value reference)"); break;
241254721Semaste        case eEncodingIsRValueReferenceUID: s->PutCString(" (unresolved R value reference)"); break;
242254721Semaste        case eEncodingIsSyntheticUID: s->PutCString(" (synthetic type)"); break;
243254721Semaste        }
244254721Semaste    }
245254721Semaste
246254721Semaste//
247254721Semaste//  if (m_access)
248254721Semaste//      s->Printf(", access = %u", m_access);
249254721Semaste    s->EOL();
250254721Semaste}
251254721Semaste
252254721Semasteconst ConstString &
253254721SemasteType::GetName()
254254721Semaste{
255254721Semaste    if (!m_name)
256254721Semaste        m_name = GetClangForwardType().GetConstTypeName();
257254721Semaste    return m_name;
258254721Semaste}
259254721Semaste
260254721Semastevoid
261254721SemasteType::DumpTypeName(Stream *s)
262254721Semaste{
263254721Semaste    GetName().Dump(s, "<invalid-type-name>");
264254721Semaste}
265254721Semaste
266254721Semaste
267254721Semastevoid
268254721SemasteType::DumpValue
269254721Semaste(
270254721Semaste    ExecutionContext *exe_ctx,
271254721Semaste    Stream *s,
272254721Semaste    const DataExtractor &data,
273254721Semaste    uint32_t data_byte_offset,
274254721Semaste    bool show_types,
275254721Semaste    bool show_summary,
276254721Semaste    bool verbose,
277254721Semaste    lldb::Format format
278254721Semaste)
279254721Semaste{
280254721Semaste    if (ResolveClangType(eResolveStateForward))
281254721Semaste    {
282254721Semaste        if (show_types)
283254721Semaste        {
284254721Semaste            s->PutChar('(');
285254721Semaste            if (verbose)
286254721Semaste                s->Printf("Type{0x%8.8" PRIx64 "} ", GetID());
287254721Semaste            DumpTypeName (s);
288254721Semaste            s->PutCString(") ");
289254721Semaste        }
290254721Semaste
291254721Semaste        GetClangForwardType().DumpValue (exe_ctx,
292254721Semaste                                         s,
293254721Semaste                                         format == lldb::eFormatDefault ? GetFormat() : format,
294254721Semaste                                         data,
295254721Semaste                                         data_byte_offset,
296254721Semaste                                         GetByteSize(),
297254721Semaste                                         0, // Bitfield bit size
298254721Semaste                                         0, // Bitfield bit offset
299254721Semaste                                         show_types,
300254721Semaste                                         show_summary,
301254721Semaste                                         verbose,
302254721Semaste                                         0);
303254721Semaste    }
304254721Semaste}
305254721Semaste
306254721SemasteType *
307254721SemasteType::GetEncodingType ()
308254721Semaste{
309254721Semaste    if (m_encoding_type == NULL && m_encoding_uid != LLDB_INVALID_UID)
310254721Semaste        m_encoding_type = m_symbol_file->ResolveTypeUID(m_encoding_uid);
311254721Semaste    return m_encoding_type;
312254721Semaste}
313254721Semaste
314254721Semaste
315254721Semaste
316254721Semasteuint64_t
317254721SemasteType::GetByteSize()
318254721Semaste{
319254721Semaste    if (m_byte_size == 0)
320254721Semaste    {
321254721Semaste        switch (m_encoding_uid_type)
322254721Semaste        {
323254721Semaste        case eEncodingInvalid:
324254721Semaste        case eEncodingIsSyntheticUID:
325254721Semaste            break;
326254721Semaste        case eEncodingIsUID:
327254721Semaste        case eEncodingIsConstUID:
328254721Semaste        case eEncodingIsRestrictUID:
329254721Semaste        case eEncodingIsVolatileUID:
330254721Semaste        case eEncodingIsTypedefUID:
331254721Semaste            {
332254721Semaste                Type *encoding_type = GetEncodingType ();
333254721Semaste                if (encoding_type)
334254721Semaste                    m_byte_size = encoding_type->GetByteSize();
335254721Semaste                if (m_byte_size == 0)
336254721Semaste                    m_byte_size = GetClangLayoutType().GetByteSize();
337254721Semaste            }
338254721Semaste            break;
339254721Semaste
340254721Semaste        // If we are a pointer or reference, then this is just a pointer size;
341254721Semaste        case eEncodingIsPointerUID:
342254721Semaste        case eEncodingIsLValueReferenceUID:
343254721Semaste        case eEncodingIsRValueReferenceUID:
344254721Semaste            m_byte_size = m_symbol_file->GetClangASTContext().GetPointerByteSize();
345254721Semaste            break;
346254721Semaste        }
347254721Semaste    }
348254721Semaste    return m_byte_size;
349254721Semaste}
350254721Semaste
351254721Semaste
352254721Semasteuint32_t
353254721SemasteType::GetNumChildren (bool omit_empty_base_classes)
354254721Semaste{
355254721Semaste    return GetClangForwardType().GetNumChildren(omit_empty_base_classes);
356254721Semaste}
357254721Semaste
358254721Semastebool
359254721SemasteType::IsAggregateType ()
360254721Semaste{
361254721Semaste    return GetClangForwardType().IsAggregateType();
362254721Semaste}
363254721Semaste
364254721Semastelldb::TypeSP
365254721SemasteType::GetTypedefType()
366254721Semaste{
367254721Semaste    lldb::TypeSP type_sp;
368254721Semaste    if (IsTypedef())
369254721Semaste    {
370254721Semaste        Type *typedef_type = m_symbol_file->ResolveTypeUID(m_encoding_uid);
371254721Semaste        if (typedef_type)
372254721Semaste            type_sp = typedef_type->shared_from_this();
373254721Semaste    }
374254721Semaste    return type_sp;
375254721Semaste}
376254721Semaste
377254721Semaste
378254721Semaste
379254721Semastelldb::Format
380254721SemasteType::GetFormat ()
381254721Semaste{
382254721Semaste    return GetClangForwardType().GetFormat();
383254721Semaste}
384254721Semaste
385254721Semaste
386254721Semaste
387254721Semastelldb::Encoding
388254721SemasteType::GetEncoding (uint64_t &count)
389254721Semaste{
390254721Semaste    // Make sure we resolve our type if it already hasn't been.
391254721Semaste    return GetClangForwardType().GetEncoding(count);
392254721Semaste}
393254721Semaste
394254721Semastebool
395254721SemasteType::DumpValueInMemory
396254721Semaste(
397254721Semaste    ExecutionContext *exe_ctx,
398254721Semaste    Stream *s,
399254721Semaste    lldb::addr_t address,
400254721Semaste    AddressType address_type,
401254721Semaste    bool show_types,
402254721Semaste    bool show_summary,
403254721Semaste    bool verbose
404254721Semaste)
405254721Semaste{
406254721Semaste    if (address != LLDB_INVALID_ADDRESS)
407254721Semaste    {
408254721Semaste        DataExtractor data;
409254721Semaste        Target *target = NULL;
410254721Semaste        if (exe_ctx)
411254721Semaste            target = exe_ctx->GetTargetPtr();
412254721Semaste        if (target)
413254721Semaste            data.SetByteOrder (target->GetArchitecture().GetByteOrder());
414254721Semaste        if (ReadFromMemory (exe_ctx, address, address_type, data))
415254721Semaste        {
416254721Semaste            DumpValue(exe_ctx, s, data, 0, show_types, show_summary, verbose);
417254721Semaste            return true;
418254721Semaste        }
419254721Semaste    }
420254721Semaste    return false;
421254721Semaste}
422254721Semaste
423254721Semaste
424254721Semastebool
425254721SemasteType::ReadFromMemory (ExecutionContext *exe_ctx, lldb::addr_t addr, AddressType address_type, DataExtractor &data)
426254721Semaste{
427254721Semaste    if (address_type == eAddressTypeFile)
428254721Semaste    {
429254721Semaste        // Can't convert a file address to anything valid without more
430254721Semaste        // context (which Module it came from)
431254721Semaste        return false;
432254721Semaste    }
433254721Semaste
434254721Semaste    const uint64_t byte_size = GetByteSize();
435254721Semaste    if (data.GetByteSize() < byte_size)
436254721Semaste    {
437254721Semaste        lldb::DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0'));
438254721Semaste        data.SetData(data_sp);
439254721Semaste    }
440254721Semaste
441254721Semaste    uint8_t* dst = (uint8_t*)data.PeekData(0, byte_size);
442254721Semaste    if (dst != NULL)
443254721Semaste    {
444254721Semaste        if (address_type == eAddressTypeHost)
445254721Semaste        {
446254721Semaste            // The address is an address in this process, so just copy it
447254721Semaste            if (addr == 0)
448254721Semaste                return false;
449254721Semaste            memcpy (dst, (uint8_t*)NULL + addr, byte_size);
450254721Semaste            return true;
451254721Semaste        }
452254721Semaste        else
453254721Semaste        {
454254721Semaste            if (exe_ctx)
455254721Semaste            {
456254721Semaste                Process *process = exe_ctx->GetProcessPtr();
457254721Semaste                if (process)
458254721Semaste                {
459254721Semaste                    Error error;
460254721Semaste                    return exe_ctx->GetProcessPtr()->ReadMemory(addr, dst, byte_size, error) == byte_size;
461254721Semaste                }
462254721Semaste            }
463254721Semaste        }
464254721Semaste    }
465254721Semaste    return false;
466254721Semaste}
467254721Semaste
468254721Semaste
469254721Semastebool
470254721SemasteType::WriteToMemory (ExecutionContext *exe_ctx, lldb::addr_t addr, AddressType address_type, DataExtractor &data)
471254721Semaste{
472254721Semaste    return false;
473254721Semaste}
474254721Semaste
475254721Semaste
476254721SemasteTypeList*
477254721SemasteType::GetTypeList()
478254721Semaste{
479254721Semaste    return GetSymbolFile()->GetTypeList();
480254721Semaste}
481254721Semaste
482254721Semasteconst Declaration &
483254721SemasteType::GetDeclaration () const
484254721Semaste{
485254721Semaste    return m_decl;
486254721Semaste}
487254721Semaste
488254721Semastebool
489254721SemasteType::ResolveClangType (ResolveState clang_type_resolve_state)
490254721Semaste{
491254721Semaste    Type *encoding_type = NULL;
492254721Semaste    if (!m_clang_type.IsValid())
493254721Semaste    {
494254721Semaste        encoding_type = GetEncodingType();
495254721Semaste        if (encoding_type)
496254721Semaste        {
497254721Semaste            switch (m_encoding_uid_type)
498254721Semaste            {
499254721Semaste            case eEncodingIsUID:
500254721Semaste                {
501254721Semaste                    ClangASTType encoding_clang_type = encoding_type->GetClangForwardType();
502254721Semaste                    if (encoding_clang_type.IsValid())
503254721Semaste                    {
504254721Semaste                        m_clang_type = encoding_clang_type;
505254721Semaste                        m_flags.clang_type_resolve_state = encoding_type->m_flags.clang_type_resolve_state;
506254721Semaste                    }
507254721Semaste                }
508254721Semaste                break;
509254721Semaste
510254721Semaste            case eEncodingIsConstUID:
511254721Semaste                m_clang_type = encoding_type->GetClangForwardType().AddConstModifier();
512254721Semaste                break;
513254721Semaste
514254721Semaste            case eEncodingIsRestrictUID:
515254721Semaste                m_clang_type = encoding_type->GetClangForwardType().AddRestrictModifier();
516254721Semaste                break;
517254721Semaste
518254721Semaste            case eEncodingIsVolatileUID:
519254721Semaste                m_clang_type = encoding_type->GetClangForwardType().AddVolatileModifier();
520254721Semaste                break;
521254721Semaste
522254721Semaste            case eEncodingIsTypedefUID:
523254721Semaste                m_clang_type = encoding_type->GetClangForwardType().CreateTypedefType (GetName().AsCString(),
524254721Semaste                                                                                       GetSymbolFile()->GetClangDeclContextContainingTypeUID(GetID()));
525254721Semaste                m_name.Clear();
526254721Semaste                break;
527254721Semaste
528254721Semaste            case eEncodingIsPointerUID:
529254721Semaste                m_clang_type = encoding_type->GetClangForwardType().GetPointerType();
530254721Semaste                break;
531254721Semaste
532254721Semaste            case eEncodingIsLValueReferenceUID:
533254721Semaste                m_clang_type = encoding_type->GetClangForwardType().GetLValueReferenceType();
534254721Semaste                break;
535254721Semaste
536254721Semaste            case eEncodingIsRValueReferenceUID:
537254721Semaste                m_clang_type = encoding_type->GetClangForwardType().GetRValueReferenceType();
538254721Semaste                break;
539254721Semaste
540254721Semaste            default:
541254721Semaste                assert(!"Unhandled encoding_data_type.");
542254721Semaste                break;
543254721Semaste            }
544254721Semaste        }
545254721Semaste        else
546254721Semaste        {
547254721Semaste            // We have no encoding type, return void?
548254721Semaste            ClangASTType void_clang_type (ClangASTContext::GetBasicType(GetClangASTContext().getASTContext(), eBasicTypeVoid));
549254721Semaste            switch (m_encoding_uid_type)
550254721Semaste            {
551254721Semaste            case eEncodingIsUID:
552254721Semaste                m_clang_type = void_clang_type;
553254721Semaste                break;
554254721Semaste
555254721Semaste            case eEncodingIsConstUID:
556254721Semaste                m_clang_type = void_clang_type.AddConstModifier ();
557254721Semaste                break;
558254721Semaste
559254721Semaste            case eEncodingIsRestrictUID:
560254721Semaste                m_clang_type = void_clang_type.AddRestrictModifier ();
561254721Semaste                break;
562254721Semaste
563254721Semaste            case eEncodingIsVolatileUID:
564254721Semaste                m_clang_type = void_clang_type.AddVolatileModifier ();
565254721Semaste                break;
566254721Semaste
567254721Semaste            case eEncodingIsTypedefUID:
568254721Semaste                m_clang_type = void_clang_type.CreateTypedefType (GetName().AsCString(),
569254721Semaste                                                                  GetSymbolFile()->GetClangDeclContextContainingTypeUID(GetID()));
570254721Semaste                break;
571254721Semaste
572254721Semaste            case eEncodingIsPointerUID:
573254721Semaste                m_clang_type = void_clang_type.GetPointerType ();
574254721Semaste                break;
575254721Semaste
576254721Semaste            case eEncodingIsLValueReferenceUID:
577254721Semaste                m_clang_type = void_clang_type.GetLValueReferenceType ();
578254721Semaste                break;
579254721Semaste
580254721Semaste            case eEncodingIsRValueReferenceUID:
581254721Semaste                m_clang_type = void_clang_type.GetRValueReferenceType ();
582254721Semaste                break;
583254721Semaste
584254721Semaste            default:
585254721Semaste                assert(!"Unhandled encoding_data_type.");
586254721Semaste                break;
587254721Semaste            }
588254721Semaste        }
589254721Semaste    }
590254721Semaste
591254721Semaste    // Check if we have a forward reference to a class/struct/union/enum?
592254721Semaste    if (m_clang_type.IsValid() && m_flags.clang_type_resolve_state < clang_type_resolve_state)
593254721Semaste    {
594254721Semaste        m_flags.clang_type_resolve_state = eResolveStateFull;
595254721Semaste        if (!m_clang_type.IsDefined ())
596254721Semaste        {
597254721Semaste            // We have a forward declaration, we need to resolve it to a complete definition.
598254721Semaste            m_symbol_file->ResolveClangOpaqueTypeDefinition (m_clang_type);
599254721Semaste        }
600254721Semaste    }
601254721Semaste
602254721Semaste    // If we have an encoding type, then we need to make sure it is
603254721Semaste    // resolved appropriately.
604254721Semaste    if (m_encoding_uid != LLDB_INVALID_UID)
605254721Semaste    {
606254721Semaste        if (encoding_type == NULL)
607254721Semaste            encoding_type = GetEncodingType();
608254721Semaste        if (encoding_type)
609254721Semaste        {
610254721Semaste            ResolveState encoding_clang_type_resolve_state = clang_type_resolve_state;
611254721Semaste
612254721Semaste            if (clang_type_resolve_state == eResolveStateLayout)
613254721Semaste            {
614254721Semaste                switch (m_encoding_uid_type)
615254721Semaste                {
616254721Semaste                case eEncodingIsPointerUID:
617254721Semaste                case eEncodingIsLValueReferenceUID:
618254721Semaste                case eEncodingIsRValueReferenceUID:
619254721Semaste                    encoding_clang_type_resolve_state = eResolveStateForward;
620254721Semaste                    break;
621254721Semaste                default:
622254721Semaste                    break;
623254721Semaste                }
624254721Semaste            }
625254721Semaste            encoding_type->ResolveClangType (encoding_clang_type_resolve_state);
626254721Semaste        }
627254721Semaste    }
628254721Semaste    return m_clang_type.IsValid();
629254721Semaste}
630254721Semasteuint32_t
631254721SemasteType::GetEncodingMask ()
632254721Semaste{
633254721Semaste    uint32_t encoding_mask = 1u << m_encoding_uid_type;
634254721Semaste    Type *encoding_type = GetEncodingType();
635254721Semaste    assert (encoding_type != this);
636254721Semaste    if (encoding_type)
637254721Semaste        encoding_mask |= encoding_type->GetEncodingMask ();
638254721Semaste    return encoding_mask;
639254721Semaste}
640254721Semaste
641254721SemasteClangASTType
642254721SemasteType::GetClangFullType ()
643254721Semaste{
644254721Semaste    ResolveClangType(eResolveStateFull);
645254721Semaste    return m_clang_type;
646254721Semaste}
647254721Semaste
648254721SemasteClangASTType
649254721SemasteType::GetClangLayoutType ()
650254721Semaste{
651254721Semaste    ResolveClangType(eResolveStateLayout);
652254721Semaste    return m_clang_type;
653254721Semaste}
654254721Semaste
655254721SemasteClangASTType
656254721SemasteType::GetClangForwardType ()
657254721Semaste{
658254721Semaste    ResolveClangType (eResolveStateForward);
659254721Semaste    return m_clang_type;
660254721Semaste}
661254721Semaste
662254721SemasteClangASTContext &
663254721SemasteType::GetClangASTContext ()
664254721Semaste{
665254721Semaste    return m_symbol_file->GetClangASTContext();
666254721Semaste}
667254721Semaste
668254721Semasteint
669254721SemasteType::Compare(const Type &a, const Type &b)
670254721Semaste{
671254721Semaste    // Just compare the UID values for now...
672254721Semaste    lldb::user_id_t a_uid = a.GetID();
673254721Semaste    lldb::user_id_t b_uid = b.GetID();
674254721Semaste    if (a_uid < b_uid)
675254721Semaste        return -1;
676254721Semaste    if (a_uid > b_uid)
677254721Semaste        return 1;
678254721Semaste    return 0;
679254721Semaste//  if (a.getQualType() == b.getQualType())
680254721Semaste//      return 0;
681254721Semaste}
682254721Semaste
683254721Semaste
684254721Semaste#if 0  // START REMOVE
685254721Semaste// Move this into ClangASTType
686254721Semastevoid *
687254721SemasteType::CreateClangPointerType (Type *type)
688254721Semaste{
689254721Semaste    assert(type);
690254721Semaste    return GetClangASTContext().CreatePointerType(type->GetClangForwardType());
691254721Semaste}
692254721Semaste
693254721Semastevoid *
694254721SemasteType::CreateClangTypedefType (Type *typedef_type, Type *base_type)
695254721Semaste{
696254721Semaste    assert(typedef_type && base_type);
697254721Semaste    return GetClangASTContext().CreateTypedefType (typedef_type->GetName().AsCString(),
698254721Semaste                                                   base_type->GetClangForwardType(),
699254721Semaste                                                   typedef_type->GetSymbolFile()->GetClangDeclContextContainingTypeUID(typedef_type->GetID()));
700254721Semaste}
701254721Semaste
702254721Semastevoid *
703254721SemasteType::CreateClangLValueReferenceType (Type *type)
704254721Semaste{
705254721Semaste    assert(type);
706254721Semaste    return GetClangASTContext().CreateLValueReferenceType(type->GetClangForwardType());
707254721Semaste}
708254721Semaste
709254721Semastevoid *
710254721SemasteType::CreateClangRValueReferenceType (Type *type)
711254721Semaste{
712254721Semaste    assert(type);
713254721Semaste    return GetClangASTContext().CreateRValueReferenceType (type->GetClangForwardType());
714254721Semaste}
715254721Semaste#endif // END REMOVE
716254721Semaste
717254721Semastebool
718254721SemasteType::IsRealObjCClass()
719254721Semaste{
720254721Semaste    // For now we are just skipping ObjC classes that get made by hand from the runtime, because
721254721Semaste    // those don't have any information.  We could extend this to only return true for "full
722254721Semaste    // definitions" if we can figure that out.
723254721Semaste
724254721Semaste    if (m_clang_type.IsObjCObjectOrInterfaceType() && GetByteSize() != 0)
725254721Semaste        return true;
726254721Semaste    else
727254721Semaste        return false;
728254721Semaste}
729254721Semaste
730254721SemasteConstString
731254721SemasteType::GetQualifiedName ()
732254721Semaste{
733254721Semaste    return GetClangForwardType().GetConstTypeName();
734254721Semaste}
735254721Semaste
736254721Semaste
737254721Semastebool
738254721SemasteType::GetTypeScopeAndBasename (const char* &name_cstr,
739254721Semaste                               std::string &scope,
740254721Semaste                               std::string &basename,
741254721Semaste                               TypeClass &type_class)
742254721Semaste{
743254721Semaste    // Protect against null c string.
744254721Semaste
745254721Semaste    type_class = eTypeClassAny;
746254721Semaste
747254721Semaste    if (name_cstr && name_cstr[0])
748254721Semaste    {
749254721Semaste        llvm::StringRef name_strref(name_cstr);
750254721Semaste        if (name_strref.startswith("struct "))
751254721Semaste        {
752254721Semaste            name_cstr += 7;
753254721Semaste            type_class = eTypeClassStruct;
754254721Semaste        }
755254721Semaste        else if (name_strref.startswith("class "))
756254721Semaste        {
757254721Semaste            name_cstr += 6;
758254721Semaste            type_class = eTypeClassClass;
759254721Semaste        }
760254721Semaste        else if (name_strref.startswith("union "))
761254721Semaste        {
762254721Semaste            name_cstr += 6;
763254721Semaste            type_class = eTypeClassUnion;
764254721Semaste        }
765254721Semaste        else if (name_strref.startswith("enum "))
766254721Semaste        {
767254721Semaste            name_cstr += 5;
768254721Semaste            type_class = eTypeClassEnumeration;
769254721Semaste        }
770254721Semaste        else if (name_strref.startswith("typedef "))
771254721Semaste        {
772254721Semaste            name_cstr += 8;
773254721Semaste            type_class = eTypeClassTypedef;
774254721Semaste        }
775254721Semaste        const char *basename_cstr = name_cstr;
776254721Semaste        const char* namespace_separator = ::strstr (basename_cstr, "::");
777254721Semaste        if (namespace_separator)
778254721Semaste        {
779254721Semaste            const char* template_arg_char = ::strchr (basename_cstr, '<');
780254721Semaste            while (namespace_separator != NULL)
781254721Semaste            {
782254721Semaste                if (template_arg_char && namespace_separator > template_arg_char) // but namespace'd template arguments are still good to go
783254721Semaste                    break;
784254721Semaste                basename_cstr = namespace_separator + 2;
785254721Semaste                namespace_separator = strstr(basename_cstr, "::");
786254721Semaste            }
787254721Semaste            if (basename_cstr > name_cstr)
788254721Semaste            {
789254721Semaste                scope.assign (name_cstr, basename_cstr - name_cstr);
790254721Semaste                basename.assign (basename_cstr);
791254721Semaste                return true;
792254721Semaste            }
793254721Semaste        }
794254721Semaste    }
795254721Semaste    return false;
796254721Semaste}
797254721Semaste
798254721Semaste
799254721Semaste
800254721Semaste
801263363SemasteTypeAndOrName::TypeAndOrName () : m_type_pair(), m_type_name()
802254721Semaste{
803254721Semaste
804254721Semaste}
805254721Semaste
806263363SemasteTypeAndOrName::TypeAndOrName (TypeSP &in_type_sp) : m_type_pair(in_type_sp)
807254721Semaste{
808254721Semaste    if (in_type_sp)
809254721Semaste        m_type_name = in_type_sp->GetName();
810254721Semaste}
811254721Semaste
812254721SemasteTypeAndOrName::TypeAndOrName (const char *in_type_str) : m_type_name(in_type_str)
813254721Semaste{
814254721Semaste}
815254721Semaste
816263363SemasteTypeAndOrName::TypeAndOrName (const TypeAndOrName &rhs) : m_type_pair (rhs.m_type_pair), m_type_name (rhs.m_type_name)
817254721Semaste{
818254721Semaste
819254721Semaste}
820254721Semaste
821254721SemasteTypeAndOrName::TypeAndOrName (ConstString &in_type_const_string) : m_type_name (in_type_const_string)
822254721Semaste{
823254721Semaste}
824254721Semaste
825254721SemasteTypeAndOrName &
826254721SemasteTypeAndOrName::operator= (const TypeAndOrName &rhs)
827254721Semaste{
828254721Semaste    if (this != &rhs)
829254721Semaste    {
830254721Semaste        m_type_name = rhs.m_type_name;
831263363Semaste        m_type_pair = rhs.m_type_pair;
832254721Semaste    }
833254721Semaste    return *this;
834254721Semaste}
835254721Semaste
836254721Semastebool
837254721SemasteTypeAndOrName::operator==(const TypeAndOrName &other) const
838254721Semaste{
839263363Semaste    if (m_type_pair != other.m_type_pair)
840254721Semaste        return false;
841254721Semaste    if (m_type_name != other.m_type_name)
842254721Semaste        return false;
843254721Semaste    return true;
844254721Semaste}
845254721Semaste
846254721Semastebool
847254721SemasteTypeAndOrName::operator!=(const TypeAndOrName &other) const
848254721Semaste{
849263363Semaste    if (m_type_pair != other.m_type_pair)
850254721Semaste        return true;
851254721Semaste    if (m_type_name != other.m_type_name)
852254721Semaste        return true;
853254721Semaste    return false;
854254721Semaste}
855254721Semaste
856254721SemasteConstString
857254721SemasteTypeAndOrName::GetName () const
858263363Semaste{
859263363Semaste    if (m_type_name)
860254721Semaste        return m_type_name;
861263363Semaste    if (m_type_pair)
862263363Semaste        return m_type_pair.GetName();
863263363Semaste    return ConstString("<invalid>");
864254721Semaste}
865254721Semaste
866254721Semastevoid
867254721SemasteTypeAndOrName::SetName (const ConstString &type_name)
868254721Semaste{
869254721Semaste    m_type_name = type_name;
870254721Semaste}
871254721Semaste
872254721Semastevoid
873254721SemasteTypeAndOrName::SetName (const char *type_name_cstr)
874254721Semaste{
875254721Semaste    m_type_name.SetCString (type_name_cstr);
876254721Semaste}
877254721Semaste
878254721Semastevoid
879254721SemasteTypeAndOrName::SetTypeSP (lldb::TypeSP type_sp)
880254721Semaste{
881263363Semaste    m_type_pair.SetType(type_sp);
882263363Semaste    if (m_type_pair)
883263363Semaste        m_type_name = m_type_pair.GetName();
884254721Semaste}
885254721Semaste
886263363Semastevoid
887263363SemasteTypeAndOrName::SetClangASTType (ClangASTType clang_type)
888263363Semaste{
889263363Semaste    m_type_pair.SetType(clang_type);
890263363Semaste    if (m_type_pair)
891263363Semaste        m_type_name = m_type_pair.GetName();
892263363Semaste}
893263363Semaste
894254721Semastebool
895263363SemasteTypeAndOrName::IsEmpty()  const
896254721Semaste{
897263363Semaste    if ((bool)m_type_name || (bool)m_type_pair)
898254721Semaste        return false;
899254721Semaste    else
900254721Semaste        return true;
901254721Semaste}
902254721Semaste
903254721Semastevoid
904254721SemasteTypeAndOrName::Clear ()
905254721Semaste{
906254721Semaste    m_type_name.Clear();
907263363Semaste    m_type_pair.Clear();
908254721Semaste}
909254721Semaste
910254721Semastebool
911263363SemasteTypeAndOrName::HasName () const
912254721Semaste{
913254721Semaste    return (bool)m_type_name;
914254721Semaste}
915254721Semaste
916254721Semastebool
917263363SemasteTypeAndOrName::HasTypeSP () const
918254721Semaste{
919263363Semaste    return m_type_pair.GetTypeSP().get() != nullptr;
920254721Semaste}
921254721Semaste
922263363Semastebool
923263363SemasteTypeAndOrName::HasClangASTType () const
924254721Semaste{
925263363Semaste    return m_type_pair.GetClangASTType().IsValid();
926254721Semaste}
927254721Semaste
928263363Semaste
929263363SemasteTypeImpl::TypeImpl() :
930263363Semastem_static_type(),
931263363Semastem_dynamic_type()
932254721Semaste{
933254721Semaste}
934254721Semaste
935263363SemasteTypeImpl::TypeImpl(const TypeImpl& rhs) :
936263363Semastem_static_type(rhs.m_static_type),
937263363Semastem_dynamic_type(rhs.m_dynamic_type)
938263363Semaste{
939263363Semaste}
940263363Semaste
941263363SemasteTypeImpl::TypeImpl (lldb::TypeSP type_sp) :
942263363Semastem_static_type(type_sp),
943263363Semastem_dynamic_type()
944263363Semaste{
945263363Semaste}
946263363Semaste
947263363SemasteTypeImpl::TypeImpl (ClangASTType clang_type) :
948263363Semastem_static_type(clang_type),
949263363Semastem_dynamic_type()
950263363Semaste{
951263363Semaste}
952263363Semaste
953263363SemasteTypeImpl::TypeImpl (lldb::TypeSP type_sp, ClangASTType dynamic) :
954263363Semastem_static_type (type_sp),
955263363Semastem_dynamic_type(dynamic)
956263363Semaste{
957263363Semaste}
958263363Semaste
959263363SemasteTypeImpl::TypeImpl (ClangASTType clang_type, ClangASTType dynamic) :
960263363Semastem_static_type (clang_type),
961263363Semastem_dynamic_type(dynamic)
962263363Semaste{
963263363Semaste}
964263363Semaste
965263363SemasteTypeImpl::TypeImpl (TypePair pair, ClangASTType dynamic) :
966263363Semastem_static_type (pair),
967263363Semastem_dynamic_type(dynamic)
968263363Semaste{
969263363Semaste}
970263363Semaste
971254721Semastevoid
972263363SemasteTypeImpl::SetType (lldb::TypeSP type_sp)
973254721Semaste{
974263363Semaste    m_static_type.SetType(type_sp);
975254721Semaste}
976254721Semaste
977263363Semastevoid
978263363SemasteTypeImpl::SetType (ClangASTType clang_type)
979263363Semaste{
980263363Semaste    m_static_type.SetType (clang_type);
981263363Semaste}
982263363Semaste
983263363Semastevoid
984263363SemasteTypeImpl::SetType (lldb::TypeSP type_sp, ClangASTType dynamic)
985263363Semaste{
986263363Semaste    m_static_type.SetType (type_sp);
987263363Semaste    m_dynamic_type = dynamic;
988263363Semaste}
989263363Semaste
990263363Semastevoid
991263363SemasteTypeImpl::SetType (ClangASTType clang_type, ClangASTType dynamic)
992263363Semaste{
993263363Semaste    m_static_type.SetType (clang_type);
994263363Semaste    m_dynamic_type = dynamic;
995263363Semaste}
996263363Semaste
997263363Semastevoid
998263363SemasteTypeImpl::SetType (TypePair pair, ClangASTType dynamic)
999263363Semaste{
1000263363Semaste    m_static_type = pair;
1001263363Semaste    m_dynamic_type = dynamic;
1002263363Semaste}
1003263363Semaste
1004254721SemasteTypeImpl&
1005254721SemasteTypeImpl::operator = (const TypeImpl& rhs)
1006254721Semaste{
1007263363Semaste    if (rhs != *this)
1008254721Semaste    {
1009263363Semaste        m_static_type = rhs.m_static_type;
1010263363Semaste        m_dynamic_type = rhs.m_dynamic_type;
1011254721Semaste    }
1012254721Semaste    return *this;
1013254721Semaste}
1014254721Semaste
1015263363Semastebool
1016263363SemasteTypeImpl::operator == (const TypeImpl& rhs) const
1017254721Semaste{
1018263363Semaste    return m_static_type == rhs.m_static_type &&
1019263363Semaste    m_dynamic_type == rhs.m_dynamic_type;
1020254721Semaste}
1021254721Semaste
1022263363Semastebool
1023263363SemasteTypeImpl::operator != (const TypeImpl& rhs) const
1024254721Semaste{
1025263363Semaste    return m_static_type != rhs.m_static_type ||
1026263363Semaste    m_dynamic_type != rhs.m_dynamic_type;
1027254721Semaste}
1028254721Semaste
1029254721Semastebool
1030263363SemasteTypeImpl::IsValid() const
1031254721Semaste{
1032263363Semaste    // just a name is not valid
1033263363Semaste    return m_static_type.IsValid() || m_dynamic_type.IsValid();
1034263363Semaste}
1035263363Semaste
1036263363SemasteTypeImpl::operator bool () const
1037263363Semaste{
1038263363Semaste    return IsValid();
1039263363Semaste}
1040263363Semaste
1041263363Semastevoid
1042263363SemasteTypeImpl::Clear()
1043263363Semaste{
1044263363Semaste    m_static_type.Clear();
1045263363Semaste    m_dynamic_type.Clear();
1046263363Semaste}
1047263363Semaste
1048263363SemasteConstString
1049263363SemasteTypeImpl::GetName ()  const
1050263363Semaste{
1051263363Semaste    if (m_dynamic_type)
1052263363Semaste        return m_dynamic_type.GetTypeName();
1053263363Semaste    return m_static_type.GetName ();
1054263363Semaste}
1055263363Semaste
1056263363SemasteTypeImpl
1057263363SemasteTypeImpl::GetPointerType () const
1058263363Semaste{
1059263363Semaste    if (m_dynamic_type.IsValid())
1060254721Semaste    {
1061263363Semaste        return TypeImpl(m_static_type, m_dynamic_type.GetPointerType());
1062254721Semaste    }
1063263363Semaste    return TypeImpl(m_static_type.GetPointerType());
1064263363Semaste}
1065263363Semaste
1066263363SemasteTypeImpl
1067263363SemasteTypeImpl::GetPointeeType () const
1068263363Semaste{
1069263363Semaste    if (m_dynamic_type.IsValid())
1070254721Semaste    {
1071263363Semaste        return TypeImpl(m_static_type, m_dynamic_type.GetPointeeType());
1072254721Semaste    }
1073263363Semaste    return TypeImpl(m_static_type.GetPointeeType());
1074254721Semaste}
1075254721Semaste
1076263363SemasteTypeImpl
1077263363SemasteTypeImpl::GetReferenceType () const
1078254721Semaste{
1079263363Semaste    if (m_dynamic_type.IsValid())
1080263363Semaste    {
1081263363Semaste        return TypeImpl(m_static_type, m_dynamic_type.GetLValueReferenceType());
1082263363Semaste    }
1083263363Semaste    return TypeImpl(m_static_type.GetReferenceType());
1084254721Semaste}
1085263363Semaste
1086263363SemasteTypeImpl
1087269024SemasteTypeImpl::GetTypedefedType () const
1088269024Semaste{
1089269024Semaste    if (m_dynamic_type.IsValid())
1090269024Semaste    {
1091269024Semaste        return TypeImpl(m_static_type, m_dynamic_type.GetTypedefedType());
1092269024Semaste    }
1093269024Semaste    return TypeImpl(m_static_type.GetTypedefedType());
1094269024Semaste}
1095269024Semaste
1096269024SemasteTypeImpl
1097263363SemasteTypeImpl::GetDereferencedType () const
1098263363Semaste{
1099263363Semaste    if (m_dynamic_type.IsValid())
1100263363Semaste    {
1101263363Semaste        return TypeImpl(m_static_type, m_dynamic_type.GetNonReferenceType());
1102263363Semaste    }
1103263363Semaste    return TypeImpl(m_static_type.GetDereferencedType());
1104263363Semaste}
1105263363Semaste
1106263363SemasteTypeImpl
1107263363SemasteTypeImpl::GetUnqualifiedType() const
1108263363Semaste{
1109263363Semaste    if (m_dynamic_type.IsValid())
1110263363Semaste    {
1111263363Semaste        return TypeImpl(m_static_type, m_dynamic_type.GetFullyUnqualifiedType());
1112263363Semaste    }
1113263363Semaste    return TypeImpl(m_static_type.GetUnqualifiedType());
1114263363Semaste}
1115263363Semaste
1116263363SemasteTypeImpl
1117263363SemasteTypeImpl::GetCanonicalType() const
1118263363Semaste{
1119263363Semaste    if (m_dynamic_type.IsValid())
1120263363Semaste    {
1121263363Semaste        return TypeImpl(m_static_type, m_dynamic_type.GetCanonicalType());
1122263363Semaste    }
1123263363Semaste    return TypeImpl(m_static_type.GetCanonicalType());
1124263363Semaste}
1125263363Semaste
1126263363SemasteClangASTType
1127263363SemasteTypeImpl::GetClangASTType (bool prefer_dynamic)
1128263363Semaste{
1129263363Semaste    if (prefer_dynamic)
1130263363Semaste    {
1131263363Semaste        if (m_dynamic_type.IsValid())
1132263363Semaste            return m_dynamic_type;
1133263363Semaste    }
1134263363Semaste    return m_static_type.GetClangASTType();
1135263363Semaste}
1136263363Semaste
1137263363Semasteclang::ASTContext *
1138263363SemasteTypeImpl::GetClangASTContext (bool prefer_dynamic)
1139263363Semaste{
1140263363Semaste    if (prefer_dynamic)
1141263363Semaste    {
1142263363Semaste        if (m_dynamic_type.IsValid())
1143263363Semaste            return m_dynamic_type.GetASTContext();
1144263363Semaste    }
1145263363Semaste    return m_static_type.GetClangASTContext();
1146263363Semaste}
1147263363Semaste
1148263363Semastebool
1149263363SemasteTypeImpl::GetDescription (lldb_private::Stream &strm,
1150263363Semaste                lldb::DescriptionLevel description_level)
1151263363Semaste{
1152263363Semaste    if (m_dynamic_type.IsValid())
1153263363Semaste    {
1154263363Semaste        strm.Printf("Dynamic:\n");
1155263363Semaste        m_dynamic_type.DumpTypeDescription(&strm);
1156263363Semaste        strm.Printf("\nStatic:\n");
1157263363Semaste    }
1158263363Semaste    m_static_type.GetClangASTType().DumpTypeDescription(&strm);
1159263363Semaste    return true;
1160263363Semaste}
1161