ClangASTType.cpp revision 9488b7423b556c7c777b721d2094fd5ec4a47578
1//===-- ClangASTType.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#include "lldb/Symbol/ClangASTType.h"
11
12#include "clang/AST/ASTConsumer.h"
13#include "clang/AST/ASTContext.h"
14#include "clang/AST/Decl.h"
15#include "clang/AST/DeclCXX.h"
16#include "clang/AST/DeclGroup.h"
17#include "clang/AST/RecordLayout.h"
18
19#include "clang/Basic/Builtins.h"
20#include "clang/Basic/IdentifierTable.h"
21#include "clang/Basic/LangOptions.h"
22#include "clang/Basic/SourceManager.h"
23#include "clang/Basic/TargetInfo.h"
24
25#include "llvm/Support/FormattedStream.h"
26#include "llvm/Support/raw_ostream.h"
27
28#include "lldb/Core/ConstString.h"
29#include "lldb/Core/DataBufferHeap.h"
30#include "lldb/Core/DataExtractor.h"
31#include "lldb/Core/Scalar.h"
32#include "lldb/Core/Stream.h"
33#include "lldb/Core/StreamString.h"
34#include "lldb/Symbol/ClangASTContext.h"
35#include "lldb/Target/ExecutionContext.h"
36#include "lldb/Target/Process.h"
37
38using namespace lldb_private;
39
40ClangASTType::~ClangASTType()
41{
42}
43
44ConstString
45ClangASTType::GetClangTypeName ()
46{
47    return GetClangTypeName (m_type);
48}
49
50ConstString
51ClangASTType::GetClangTypeName (void *opaque_clang_qual_type)
52{
53    ConstString clang_type_name;
54    if (opaque_clang_qual_type)
55    {
56        clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
57
58        const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
59        if (typedef_type)
60        {
61            const clang::TypedefDecl *typedef_decl = typedef_type->getDecl();
62            std::string clang_typedef_name (typedef_decl->getQualifiedNameAsString());
63            if (!clang_typedef_name.empty())
64                clang_type_name.SetCString (clang_typedef_name.c_str());
65        }
66        else
67        {
68            std::string type_name(qual_type.getAsString());
69            if (!type_name.empty())
70                clang_type_name.SetCString (type_name.c_str());
71        }
72    }
73    else
74    {
75        clang_type_name.SetCString ("<invalid>");
76    }
77
78    return clang_type_name;
79}
80
81lldb::Encoding
82ClangASTType::GetEncoding (uint32_t &count)
83{
84    return GetEncoding(m_type, count);
85}
86
87
88lldb::Encoding
89ClangASTType::GetEncoding (void *opaque_clang_qual_type, uint32_t &count)
90{
91    count = 1;
92    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
93
94    switch (qual_type->getTypeClass())
95    {
96    case clang::Type::FunctionNoProto:
97    case clang::Type::FunctionProto:
98        break;
99
100    case clang::Type::IncompleteArray:
101    case clang::Type::VariableArray:
102        break;
103
104    case clang::Type::ConstantArray:
105        break;
106
107    case clang::Type::ExtVector:
108    case clang::Type::Vector:
109        // TODO: Set this to more than one???
110        break;
111
112    case clang::Type::Builtin:
113        switch (cast<clang::BuiltinType>(qual_type)->getKind())
114        {
115        default: assert(0 && "Unknown builtin type!");
116        case clang::BuiltinType::Void:
117            break;
118
119        case clang::BuiltinType::Bool:
120        case clang::BuiltinType::Char_S:
121        case clang::BuiltinType::SChar:
122        case clang::BuiltinType::WChar:
123        case clang::BuiltinType::Char16:
124        case clang::BuiltinType::Char32:
125        case clang::BuiltinType::Short:
126        case clang::BuiltinType::Int:
127        case clang::BuiltinType::Long:
128        case clang::BuiltinType::LongLong:
129        case clang::BuiltinType::Int128:        return lldb::eEncodingSint;
130
131        case clang::BuiltinType::Char_U:
132        case clang::BuiltinType::UChar:
133        case clang::BuiltinType::UShort:
134        case clang::BuiltinType::UInt:
135        case clang::BuiltinType::ULong:
136        case clang::BuiltinType::ULongLong:
137        case clang::BuiltinType::UInt128:       return lldb::eEncodingUint;
138
139        case clang::BuiltinType::Float:
140        case clang::BuiltinType::Double:
141        case clang::BuiltinType::LongDouble:    return lldb::eEncodingIEEE754;
142
143        case clang::BuiltinType::NullPtr:       return lldb::eEncodingUint;
144        }
145        break;
146    // All pointer types are represented as unsigned integer encodings.
147    // We may nee to add a eEncodingPointer if we ever need to know the
148    // difference
149    case clang::Type::ObjCObjectPointer:
150    case clang::Type::BlockPointer:
151    case clang::Type::Pointer:
152    case clang::Type::LValueReference:
153    case clang::Type::RValueReference:
154    case clang::Type::MemberPointer:            return lldb::eEncodingUint;
155    // Complex numbers are made up of floats
156    case clang::Type::Complex:
157        count = 2;
158        return lldb::eEncodingIEEE754;
159
160    case clang::Type::ObjCInterface:            break;
161    case clang::Type::Record:                   break;
162    case clang::Type::Enum:                     return lldb::eEncodingSint;
163    case clang::Type::Typedef:
164        return GetEncoding(cast<clang::TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), count);
165        break;
166
167    case clang::Type::TypeOfExpr:
168    case clang::Type::TypeOf:
169    case clang::Type::Decltype:
170//    case clang::Type::QualifiedName:
171    case clang::Type::TemplateSpecialization:   break;
172    }
173    count = 0;
174    return lldb::eEncodingInvalid;
175}
176
177lldb::Format
178ClangASTType::GetFormat ()
179{
180    return GetFormat (m_type);
181}
182
183lldb::Format
184ClangASTType::GetFormat (void *opaque_clang_qual_type)
185{
186    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
187
188    switch (qual_type->getTypeClass())
189    {
190    case clang::Type::FunctionNoProto:
191    case clang::Type::FunctionProto:
192        break;
193
194    case clang::Type::IncompleteArray:
195    case clang::Type::VariableArray:
196        break;
197
198    case clang::Type::ConstantArray:
199        break;
200
201    case clang::Type::ExtVector:
202    case clang::Type::Vector:
203        break;
204
205    case clang::Type::Builtin:
206        switch (cast<clang::BuiltinType>(qual_type)->getKind())
207        {
208        default: assert(0 && "Unknown builtin type!");
209        case clang::BuiltinType::Void:
210            break;
211
212        case clang::BuiltinType::Bool:          return lldb::eFormatBoolean;
213        case clang::BuiltinType::Char_S:
214        case clang::BuiltinType::SChar:
215        case clang::BuiltinType::Char_U:
216        case clang::BuiltinType::UChar:
217        case clang::BuiltinType::WChar:         return lldb::eFormatChar;
218        case clang::BuiltinType::Char16:        return lldb::eFormatUnicode16;
219        case clang::BuiltinType::Char32:        return lldb::eFormatUnicode32;
220        case clang::BuiltinType::UShort:        return lldb::eFormatHex;
221        case clang::BuiltinType::Short:         return lldb::eFormatDecimal;
222        case clang::BuiltinType::UInt:          return lldb::eFormatHex;
223        case clang::BuiltinType::Int:           return lldb::eFormatDecimal;
224        case clang::BuiltinType::ULong:         return lldb::eFormatHex;
225        case clang::BuiltinType::Long:          return lldb::eFormatDecimal;
226        case clang::BuiltinType::ULongLong:     return lldb::eFormatHex;
227        case clang::BuiltinType::LongLong:      return lldb::eFormatDecimal;
228        case clang::BuiltinType::UInt128:       return lldb::eFormatHex;
229        case clang::BuiltinType::Int128:        return lldb::eFormatDecimal;
230        case clang::BuiltinType::Float:         return lldb::eFormatFloat;
231        case clang::BuiltinType::Double:        return lldb::eFormatFloat;
232        case clang::BuiltinType::LongDouble:    return lldb::eFormatFloat;
233        case clang::BuiltinType::NullPtr:       return lldb::eFormatHex;
234        }
235        break;
236    case clang::Type::ObjCObjectPointer:        return lldb::eFormatHex;
237    case clang::Type::BlockPointer:             return lldb::eFormatHex;
238    case clang::Type::Pointer:                  return lldb::eFormatHex;
239    case clang::Type::LValueReference:
240    case clang::Type::RValueReference:          return lldb::eFormatHex;
241    case clang::Type::MemberPointer:            break;
242    case clang::Type::Complex:                  return lldb::eFormatComplex;
243    case clang::Type::ObjCInterface:            break;
244    case clang::Type::Record:                   break;
245    case clang::Type::Enum:                     return lldb::eFormatEnum;
246    case clang::Type::Typedef:
247        return ClangASTType::GetFormat(cast<clang::TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr());
248
249    case clang::Type::TypeOfExpr:
250    case clang::Type::TypeOf:
251    case clang::Type::Decltype:
252//    case clang::Type::QualifiedName:
253    case clang::Type::TemplateSpecialization:   break;
254    }
255    // We don't know hot to display this type...
256    return lldb::eFormatBytes;
257}
258
259
260void
261ClangASTType::DumpValue
262(
263    ExecutionContext *exe_ctx,
264    Stream *s,
265    lldb::Format format,
266    const lldb_private::DataExtractor &data,
267    uint32_t data_byte_offset,
268    size_t data_byte_size,
269    uint32_t bitfield_bit_size,
270    uint32_t bitfield_bit_offset,
271    bool show_types,
272    bool show_summary,
273    bool verbose,
274    uint32_t depth
275)
276{
277    return DumpValue (m_ast,
278                      m_type,
279                      exe_ctx,
280                      s,
281                      format,
282                      data,
283                      data_byte_offset,
284                      data_byte_size,
285                      bitfield_bit_size,
286                      bitfield_bit_offset,
287                      show_types,
288                      show_summary,
289                      verbose,
290                      depth);
291}
292
293#define DEPTH_INCREMENT 2
294void
295ClangASTType::DumpValue
296(
297    clang::ASTContext *ast_context,
298    void *opaque_clang_qual_type,
299    ExecutionContext *exe_ctx,
300    Stream *s,
301    lldb::Format format,
302    const lldb_private::DataExtractor &data,
303    uint32_t data_byte_offset,
304    size_t data_byte_size,
305    uint32_t bitfield_bit_size,
306    uint32_t bitfield_bit_offset,
307    bool show_types,
308    bool show_summary,
309    bool verbose,
310    uint32_t depth
311)
312{
313    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
314    switch (qual_type->getTypeClass())
315    {
316    case clang::Type::Record:
317        {
318            const clang::RecordType *record_type = cast<clang::RecordType>(qual_type.getTypePtr());
319            const clang::RecordDecl *record_decl = record_type->getDecl();
320            assert(record_decl);
321            uint32_t field_bit_offset = 0;
322            uint32_t field_byte_offset = 0;
323            const clang::ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
324            uint32_t child_idx = 0;
325
326
327            const clang::CXXRecordDecl *cxx_record_decl = dyn_cast<clang::CXXRecordDecl>(record_decl);
328            if (cxx_record_decl)
329            {
330                // We might have base classes to print out first
331                clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
332                for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
333                     base_class != base_class_end;
334                     ++base_class)
335                {
336                    const clang::CXXRecordDecl *base_class_decl = cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl());
337
338                    // Skip empty base classes
339                    if (verbose == false && ClangASTContext::RecordHasFields(base_class_decl) == false)
340                        continue;
341
342                    if (base_class->isVirtual())
343                        field_bit_offset = record_layout.getVBaseClassOffset(base_class_decl);
344                    else
345                        field_bit_offset = record_layout.getBaseClassOffset(base_class_decl);
346                    field_byte_offset = field_bit_offset / 8;
347                    assert (field_bit_offset % 8 == 0);
348                    if (child_idx == 0)
349                        s->PutChar('{');
350                    else
351                        s->PutChar(',');
352
353                    clang::QualType base_class_qual_type = base_class->getType();
354                    std::string base_class_type_name(base_class_qual_type.getAsString());
355
356                    // Indent and print the base class type name
357                    s->Printf("\n%*s%s ", depth + DEPTH_INCREMENT, "", base_class_type_name.c_str());
358
359                    std::pair<uint64_t, unsigned> base_class_type_info = ast_context->getTypeInfo(base_class_qual_type);
360
361                    // Dump the value of the member
362                    DumpValue (ast_context,                        // The clang AST context for this type
363                               base_class_qual_type.getAsOpaquePtr(),// The clang type we want to dump
364                               exe_ctx,
365                               s,                                  // Stream to dump to
366                               ClangASTType::GetFormat(base_class_qual_type.getAsOpaquePtr()), // The format with which to display the member
367                               data,                               // Data buffer containing all bytes for this type
368                               data_byte_offset + field_byte_offset,// Offset into "data" where to grab value from
369                               base_class_type_info.first / 8,     // Size of this type in bytes
370                               0,                                  // Bitfield bit size
371                               0,                                  // Bitfield bit offset
372                               show_types,                         // Boolean indicating if we should show the variable types
373                               show_summary,                       // Boolean indicating if we should show a summary for the current type
374                               verbose,                            // Verbose output?
375                               depth + DEPTH_INCREMENT);           // Scope depth for any types that have children
376
377                    ++child_idx;
378                }
379            }
380            uint32_t field_idx = 0;
381            clang::RecordDecl::field_iterator field, field_end;
382            for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
383            {
384                // Print the starting squiggly bracket (if this is the
385                // first member) or comman (for member 2 and beyong) for
386                // the struct/union/class member.
387                if (child_idx == 0)
388                    s->PutChar('{');
389                else
390                    s->PutChar(',');
391
392                // Indent
393                s->Printf("\n%*s", depth + DEPTH_INCREMENT, "");
394
395                clang::QualType field_type = field->getType();
396                // Print the member type if requested
397                // Figure out the type byte size (field_type_info.first) and
398                // alignment (field_type_info.second) from the AST context.
399                std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field_type);
400                assert(field_idx < record_layout.getFieldCount());
401                // Figure out the field offset within the current struct/union/class type
402                field_bit_offset = record_layout.getFieldOffset (field_idx);
403                field_byte_offset = field_bit_offset / 8;
404                uint32_t field_bitfield_bit_size = 0;
405                uint32_t field_bitfield_bit_offset = 0;
406                if (ClangASTContext::FieldIsBitfield (ast_context, *field, field_bitfield_bit_size))
407                    field_bitfield_bit_offset = field_bit_offset % 8;
408
409                if (show_types)
410                {
411                    std::string field_type_name(field_type.getAsString());
412                    if (field_bitfield_bit_size > 0)
413                        s->Printf("(%s:%u) ", field_type_name.c_str(), field_bitfield_bit_size);
414                    else
415                        s->Printf("(%s) ", field_type_name.c_str());
416                }
417                // Print the member name and equal sign
418                s->Printf("%s = ", field->getNameAsString().c_str());
419
420
421                // Dump the value of the member
422                DumpValue (ast_context,                    // The clang AST context for this type
423                           field_type.getAsOpaquePtr(),    // The clang type we want to dump
424                           exe_ctx,
425                           s,                              // Stream to dump to
426                           ClangASTType::GetFormat(field_type.getAsOpaquePtr()),   // The format with which to display the member
427                           data,                           // Data buffer containing all bytes for this type
428                           data_byte_offset + field_byte_offset,// Offset into "data" where to grab value from
429                           field_type_info.first / 8,      // Size of this type in bytes
430                           field_bitfield_bit_size,        // Bitfield bit size
431                           field_bitfield_bit_offset,      // Bitfield bit offset
432                           show_types,                     // Boolean indicating if we should show the variable types
433                           show_summary,                   // Boolean indicating if we should show a summary for the current type
434                           verbose,                        // Verbose output?
435                           depth + DEPTH_INCREMENT);       // Scope depth for any types that have children
436            }
437
438            // Indent the trailing squiggly bracket
439            if (child_idx > 0)
440                s->Printf("\n%*s}", depth, "");
441        }
442        return;
443
444    case clang::Type::Enum:
445        {
446            const clang::EnumType *enum_type = cast<clang::EnumType>(qual_type.getTypePtr());
447            const clang::EnumDecl *enum_decl = enum_type->getDecl();
448            assert(enum_decl);
449            clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
450            uint32_t offset = data_byte_offset;
451            const int64_t enum_value = data.GetMaxU64Bitfield(&offset, data_byte_size, bitfield_bit_size, bitfield_bit_offset);
452            for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
453            {
454                if (enum_pos->getInitVal() == enum_value)
455                {
456                    s->Printf("%s", enum_pos->getNameAsCString());
457                    return;
458                }
459            }
460            // If we have gotten here we didn't get find the enumerator in the
461            // enum decl, so just print the integer.
462            s->Printf("%lli", enum_value);
463        }
464        return;
465
466    case clang::Type::ConstantArray:
467        {
468            const clang::ConstantArrayType *array = cast<clang::ConstantArrayType>(qual_type.getTypePtr());
469            bool is_array_of_characters = false;
470            clang::QualType element_qual_type = array->getElementType();
471
472            clang::Type *canonical_type = element_qual_type->getCanonicalTypeInternal().getTypePtr();
473            if (canonical_type)
474                is_array_of_characters = canonical_type->isCharType();
475
476            const uint64_t element_count = array->getSize().getLimitedValue();
477
478            std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(element_qual_type);
479
480            uint32_t element_idx = 0;
481            uint32_t element_offset = 0;
482            uint64_t element_byte_size = field_type_info.first / 8;
483            uint32_t element_stride = element_byte_size;
484
485            if (is_array_of_characters)
486            {
487                s->PutChar('"');
488                data.Dump(s, data_byte_offset, lldb::eFormatChar, element_byte_size, element_count, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
489                s->PutChar('"');
490                return;
491            }
492            else
493            {
494                lldb::Format element_format = ClangASTType::GetFormat(element_qual_type.getAsOpaquePtr());
495
496                for (element_idx = 0; element_idx < element_count; ++element_idx)
497                {
498                    // Print the starting squiggly bracket (if this is the
499                    // first member) or comman (for member 2 and beyong) for
500                    // the struct/union/class member.
501                    if (element_idx == 0)
502                        s->PutChar('{');
503                    else
504                        s->PutChar(',');
505
506                    // Indent and print the index
507                    s->Printf("\n%*s[%u] ", depth + DEPTH_INCREMENT, "", element_idx);
508
509                    // Figure out the field offset within the current struct/union/class type
510                    element_offset = element_idx * element_stride;
511
512                    // Dump the value of the member
513                    DumpValue (ast_context,                    // The clang AST context for this type
514                               element_qual_type.getAsOpaquePtr(), // The clang type we want to dump
515                               exe_ctx,
516                               s,                              // Stream to dump to
517                               element_format,                 // The format with which to display the element
518                               data,                           // Data buffer containing all bytes for this type
519                               data_byte_offset + element_offset,// Offset into "data" where to grab value from
520                               element_byte_size,              // Size of this type in bytes
521                               0,                              // Bitfield bit size
522                               0,                              // Bitfield bit offset
523                               show_types,                     // Boolean indicating if we should show the variable types
524                               show_summary,                   // Boolean indicating if we should show a summary for the current type
525                               verbose,                        // Verbose output?
526                               depth + DEPTH_INCREMENT);       // Scope depth for any types that have children
527                }
528
529                // Indent the trailing squiggly bracket
530                if (element_idx > 0)
531                    s->Printf("\n%*s}", depth, "");
532            }
533        }
534        return;
535
536    case clang::Type::Typedef:
537        {
538            clang::QualType typedef_qual_type = cast<clang::TypedefType>(qual_type)->LookThroughTypedefs();
539            lldb::Format typedef_format = ClangASTType::GetFormat(typedef_qual_type.getAsOpaquePtr());
540            std::pair<uint64_t, unsigned> typedef_type_info = ast_context->getTypeInfo(typedef_qual_type);
541            uint64_t typedef_byte_size = typedef_type_info.first / 8;
542
543            return DumpValue (ast_context,        // The clang AST context for this type
544                              typedef_qual_type.getAsOpaquePtr(), // The clang type we want to dump
545                              exe_ctx,
546                              s,                  // Stream to dump to
547                              typedef_format,     // The format with which to display the element
548                              data,               // Data buffer containing all bytes for this type
549                              data_byte_offset,   // Offset into "data" where to grab value from
550                              typedef_byte_size,  // Size of this type in bytes
551                              bitfield_bit_size,  // Bitfield bit size
552                              bitfield_bit_offset,// Bitfield bit offset
553                              show_types,         // Boolean indicating if we should show the variable types
554                              show_summary,       // Boolean indicating if we should show a summary for the current type
555                              verbose,            // Verbose output?
556                              depth);             // Scope depth for any types that have children
557        }
558        break;
559
560    default:
561        // We are down the a scalar type that we just need to display.
562        data.Dump(s, data_byte_offset, format, data_byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size, bitfield_bit_offset);
563
564        if (show_summary)
565            DumpSummary (ast_context, opaque_clang_qual_type, exe_ctx, s, data, data_byte_offset, data_byte_size);
566        break;
567    }
568}
569
570
571
572bool
573ClangASTType::DumpTypeValue
574(
575    Stream *s,
576    lldb::Format format,
577    const lldb_private::DataExtractor &data,
578    uint32_t byte_offset,
579    size_t byte_size,
580    uint32_t bitfield_bit_size,
581    uint32_t bitfield_bit_offset
582)
583{
584    return DumpTypeValue (m_ast,
585                          m_type,
586                          s,
587                          format,
588                          data,
589                          byte_offset,
590                          byte_size,
591                          bitfield_bit_size,
592                          bitfield_bit_offset);
593}
594
595
596bool
597ClangASTType::DumpTypeValue
598(
599    clang::ASTContext *ast_context,
600    void *opaque_clang_qual_type,
601    Stream *s,
602    lldb::Format format,
603    const lldb_private::DataExtractor &data,
604    uint32_t byte_offset,
605    size_t byte_size,
606    uint32_t bitfield_bit_size,
607    uint32_t bitfield_bit_offset
608)
609{
610    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
611    if (ClangASTContext::IsAggregateType (opaque_clang_qual_type))
612    {
613        return 0;
614    }
615    else
616    {
617        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
618        switch (type_class)
619        {
620        case clang::Type::Enum:
621            {
622                const clang::EnumType *enum_type = cast<clang::EnumType>(qual_type.getTypePtr());
623                const clang::EnumDecl *enum_decl = enum_type->getDecl();
624                assert(enum_decl);
625                clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
626                uint32_t offset = byte_offset;
627                const int64_t enum_value = data.GetMaxU64Bitfield (&offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
628                for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
629                {
630                    if (enum_pos->getInitVal() == enum_value)
631                    {
632                        s->PutCString (enum_pos->getNameAsCString());
633                        return true;
634                    }
635                }
636                // If we have gotten here we didn't get find the enumerator in the
637                // enum decl, so just print the integer.
638
639                s->Printf("%lli", enum_value);
640                return true;
641            }
642            break;
643
644        case clang::Type::Typedef:
645            {
646                clang::QualType typedef_qual_type = cast<clang::TypedefType>(qual_type)->LookThroughTypedefs();
647                lldb::Format typedef_format = ClangASTType::GetFormat(typedef_qual_type.getAsOpaquePtr());
648                std::pair<uint64_t, unsigned> typedef_type_info = ast_context->getTypeInfo(typedef_qual_type);
649                uint64_t typedef_byte_size = typedef_type_info.first / 8;
650
651                return ClangASTType::DumpTypeValue(
652                            ast_context,            // The clang AST context for this type
653                            typedef_qual_type.getAsOpaquePtr(),     // The clang type we want to dump
654                            s,
655                            typedef_format,         // The format with which to display the element
656                            data,                   // Data buffer containing all bytes for this type
657                            byte_offset,            // Offset into "data" where to grab value from
658                            typedef_byte_size,      // Size of this type in bytes
659                            bitfield_bit_size,      // Size in bits of a bitfield value, if zero don't treat as a bitfield
660                            bitfield_bit_offset);   // Offset in bits of a bitfield value if bitfield_bit_size != 0
661            }
662            break;
663
664        default:
665            // We are down the a scalar type that we just need to display.
666            return data.Dump(s,
667                             byte_offset,
668                             format,
669                             byte_size,
670                             1,
671                             UINT32_MAX,
672                             LLDB_INVALID_ADDRESS,
673                             bitfield_bit_size,
674                             bitfield_bit_offset);
675            break;
676        }
677    }
678    return 0;
679}
680
681
682
683void
684ClangASTType::DumpSummary
685(
686    ExecutionContext *exe_ctx,
687    Stream *s,
688    const lldb_private::DataExtractor &data,
689    uint32_t data_byte_offset,
690    size_t data_byte_size
691)
692{
693    return DumpSummary (m_ast,
694                        m_type,
695                        exe_ctx,
696                        s,
697                        data,
698                        data_byte_offset,
699                        data_byte_size);
700}
701
702void
703ClangASTType::DumpSummary
704(
705    clang::ASTContext *ast_context,
706    void *opaque_clang_qual_type,
707    ExecutionContext *exe_ctx,
708    Stream *s,
709    const lldb_private::DataExtractor &data,
710    uint32_t data_byte_offset,
711    size_t data_byte_size
712)
713{
714    uint32_t length = 0;
715    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
716    if (ClangASTContext::IsCStringType (opaque_clang_qual_type, length))
717    {
718
719        if (exe_ctx && exe_ctx->process)
720        {
721            uint32_t offset = data_byte_offset;
722            lldb::addr_t pointer_addresss = data.GetMaxU64(&offset, data_byte_size);
723            std::vector<uint8_t> buf;
724            if (length > 0)
725                buf.resize (length);
726            else
727                buf.resize (256);
728
729            lldb_private::DataExtractor cstr_data(&buf.front(), buf.size(), exe_ctx->process->GetByteOrder(), 4);
730            buf.back() = '\0';
731            size_t bytes_read;
732            size_t total_cstr_len = 0;
733            Error error;
734            while ((bytes_read = exe_ctx->process->ReadMemory (pointer_addresss, &buf.front(), buf.size(), error)) > 0)
735            {
736                const size_t len = strlen((const char *)&buf.front());
737                if (len == 0)
738                    break;
739                if (total_cstr_len == 0)
740                    s->PutCString (" \"");
741                cstr_data.Dump(s, 0, lldb::eFormatChar, 1, len, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
742                total_cstr_len += len;
743                if (len < buf.size())
744                    break;
745                pointer_addresss += total_cstr_len;
746            }
747            if (total_cstr_len > 0)
748                s->PutChar ('"');
749        }
750    }
751}
752
753bool
754ClangASTType::GetValueAsScalar
755(
756    const lldb_private::DataExtractor &data,
757    uint32_t data_byte_offset,
758    size_t data_byte_size,
759    Scalar &value
760)
761{
762    return GetValueAsScalar (m_ast,
763                             m_type,
764                             data,
765                             data_byte_offset,
766                             data_byte_size,
767                             value);
768}
769
770bool
771ClangASTType::GetValueAsScalar
772(
773    clang::ASTContext *ast_context,
774    void *opaque_clang_qual_type,
775    const lldb_private::DataExtractor &data,
776    uint32_t data_byte_offset,
777    size_t data_byte_size,
778    Scalar &value
779)
780{
781    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
782
783    if (ClangASTContext::IsAggregateType (opaque_clang_qual_type))
784    {
785        return false;   // Aggregate types don't have scalar values
786    }
787    else
788    {
789        uint32_t count = 0;
790        lldb::Encoding encoding = GetEncoding (opaque_clang_qual_type, count);
791
792        if (encoding == lldb::eEncodingInvalid || count != 1)
793            return false;
794
795        uint64_t bit_width = ast_context->getTypeSize(qual_type);
796        uint32_t byte_size = (bit_width + 7 ) / 8;
797        uint32_t offset = data_byte_offset;
798        switch (encoding)
799        {
800        case lldb::eEncodingUint:
801            if (byte_size <= sizeof(unsigned long long))
802            {
803                uint64_t uval64 = data.GetMaxU64 (&offset, byte_size);
804                if (byte_size <= sizeof(unsigned int))
805                {
806                    value = (unsigned int)uval64;
807                    return true;
808                }
809                else if (byte_size <= sizeof(unsigned long))
810                {
811                    value = (unsigned long)uval64;
812                    return true;
813                }
814                else if (byte_size <= sizeof(unsigned long long))
815                {
816                    value = (unsigned long long )uval64;
817                    return true;
818                }
819                else
820                    value.Clear();
821            }
822            break;
823
824        case lldb::eEncodingSint:
825            if (byte_size <= sizeof(long long))
826            {
827                int64_t sval64 = (int64_t)data.GetMaxU64 (&offset, byte_size);
828                if (byte_size <= sizeof(int))
829                {
830                    value = (int)sval64;
831                    return true;
832                }
833                else if (byte_size <= sizeof(long))
834                {
835                    value = (long)sval64;
836                    return true;
837                }
838                else if (byte_size <= sizeof(long long))
839                {
840                    value = (long long )sval64;
841                    return true;
842                }
843                else
844                    value.Clear();
845            }
846            break;
847
848        case lldb::eEncodingIEEE754:
849            if (byte_size <= sizeof(long double))
850            {
851                uint32_t u32;
852                uint64_t u64;
853                if (byte_size == sizeof(float))
854                {
855                    if (sizeof(float) == sizeof(uint32_t))
856                    {
857                        u32 = data.GetU32(&offset);
858                        value = *((float *)&u32);
859                        return true;
860                    }
861                    else if (sizeof(float) == sizeof(uint64_t))
862                    {
863                        u64 = data.GetU64(&offset);
864                        value = *((float *)&u64);
865                        return true;
866                    }
867                }
868                else
869                if (byte_size == sizeof(double))
870                {
871                    if (sizeof(double) == sizeof(uint32_t))
872                    {
873                        u32 = data.GetU32(&offset);
874                        value = *((double *)&u32);
875                        return true;
876                    }
877                    else if (sizeof(double) == sizeof(uint64_t))
878                    {
879                        u64 = data.GetU64(&offset);
880                        value = *((double *)&u64);
881                        return true;
882                    }
883                }
884                else
885                if (byte_size == sizeof(long double))
886                {
887                    if (sizeof(long double) == sizeof(uint32_t))
888                    {
889                        u32 = data.GetU32(&offset);
890                        value = *((long double *)&u32);
891                        return true;
892                    }
893                    else if (sizeof(long double) == sizeof(uint64_t))
894                    {
895                        u64 = data.GetU64(&offset);
896                        value = *((long double *)&u64);
897                        return true;
898                    }
899                }
900            }
901            break;
902        }
903    }
904    return false;
905}
906
907bool
908ClangASTType::SetValueFromScalar (const Scalar &value, Stream &strm)
909{
910    return SetValueFromScalar (m_ast, m_type, value, strm);
911}
912
913bool
914ClangASTType::SetValueFromScalar
915(
916    clang::ASTContext *ast_context,
917    void *opaque_clang_qual_type,
918    const Scalar &value,
919    Stream &strm
920)
921{
922    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
923
924    // Aggregate types don't have scalar values
925    if (!ClangASTContext::IsAggregateType (opaque_clang_qual_type))
926    {
927        strm.GetFlags().Set(Stream::eBinary);
928        uint32_t count = 0;
929        lldb::Encoding encoding = GetEncoding (opaque_clang_qual_type, count);
930
931        if (encoding == lldb::eEncodingInvalid || count != 1)
932            return false;
933
934        uint64_t bit_width = ast_context->getTypeSize(qual_type);
935        // This function doesn't currently handle non-byte aligned assignments
936        if ((bit_width % 8) != 0)
937            return false;
938
939        uint32_t byte_size = (bit_width + 7 ) / 8;
940        switch (encoding)
941        {
942        case lldb::eEncodingUint:
943            switch (byte_size)
944            {
945            case 1: strm.PutHex8(value.UInt()); return true;
946            case 2: strm.PutHex16(value.UInt()); return true;
947            case 4: strm.PutHex32(value.UInt()); return true;
948            case 8: strm.PutHex64(value.ULongLong()); return true;
949            default:
950                break;
951            }
952            break;
953
954        case lldb::eEncodingSint:
955            switch (byte_size)
956            {
957            case 1: strm.PutHex8(value.SInt()); return true;
958            case 2: strm.PutHex16(value.SInt()); return true;
959            case 4: strm.PutHex32(value.SInt()); return true;
960            case 8: strm.PutHex64(value.SLongLong()); return true;
961            default:
962                break;
963            }
964            break;
965
966        case lldb::eEncodingIEEE754:
967            if (byte_size <= sizeof(long double))
968            {
969                if (byte_size == sizeof(float))
970                {
971                    strm.PutFloat(value.Float());
972                    return true;
973                }
974                else
975                if (byte_size == sizeof(double))
976                {
977                    strm.PutDouble(value.Double());
978                    return true;
979                }
980                else
981                if (byte_size == sizeof(long double))
982                {
983                    strm.PutDouble(value.LongDouble());
984                    return true;
985                }
986            }
987            break;
988        }
989    }
990    return false;
991}
992
993bool
994ClangASTType::ReadFromMemory
995(
996    lldb_private::ExecutionContext *exe_ctx,
997    lldb::addr_t addr,
998    lldb::AddressType address_type,
999    lldb_private::DataExtractor &data
1000)
1001{
1002    return ReadFromMemory (m_ast,
1003                           m_type,
1004                           exe_ctx,
1005                           addr,
1006                           address_type,
1007                           data);
1008}
1009
1010
1011bool
1012ClangASTType::ReadFromMemory
1013(
1014    clang::ASTContext *ast_context,
1015    void *opaque_clang_qual_type,
1016    lldb_private::ExecutionContext *exe_ctx,
1017    lldb::addr_t addr,
1018    lldb::AddressType address_type,
1019    lldb_private::DataExtractor &data
1020)
1021{
1022    if (address_type == lldb::eAddressTypeFile)
1023    {
1024        // Can't convert a file address to anything valid without more
1025        // context (which Module it came from)
1026        return false;
1027    }
1028    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
1029
1030    const uint32_t byte_size = (ast_context->getTypeSize (qual_type) + 7) / 8;
1031    if (data.GetByteSize() < byte_size)
1032    {
1033        lldb::DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0'));
1034        data.SetData(data_sp);
1035    }
1036
1037    uint8_t* dst = (uint8_t*)data.PeekData(0, byte_size);
1038    if (dst != NULL)
1039    {
1040        if (address_type == lldb::eAddressTypeHost)
1041        {
1042            // The address is an address in this process, so just copy it
1043            memcpy (dst, (uint8_t*)NULL + addr, byte_size);
1044            return true;
1045        }
1046        else
1047        {
1048            if (exe_ctx && exe_ctx->process)
1049            {
1050                Error error;
1051                return exe_ctx->process->ReadMemory(addr, dst, byte_size, error) == byte_size;
1052            }
1053        }
1054    }
1055    return false;
1056}
1057
1058bool
1059ClangASTType::WriteToMemory
1060(
1061    lldb_private::ExecutionContext *exe_ctx,
1062    lldb::addr_t addr,
1063    lldb::AddressType address_type,
1064    StreamString &new_value
1065)
1066{
1067    return WriteToMemory (m_ast,
1068                          m_type,
1069                          exe_ctx,
1070                          addr,
1071                          address_type,
1072                          new_value);
1073}
1074
1075bool
1076ClangASTType::WriteToMemory
1077(
1078    clang::ASTContext *ast_context,
1079    void *opaque_clang_qual_type,
1080    lldb_private::ExecutionContext *exe_ctx,
1081    lldb::addr_t addr,
1082    lldb::AddressType address_type,
1083    StreamString &new_value
1084)
1085{
1086    if (address_type == lldb::eAddressTypeFile)
1087    {
1088        // Can't convert a file address to anything valid without more
1089        // context (which Module it came from)
1090        return false;
1091    }
1092    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
1093    const uint32_t byte_size = (ast_context->getTypeSize (qual_type) + 7) / 8;
1094
1095    if (byte_size > 0)
1096    {
1097        if (address_type == lldb::eAddressTypeHost)
1098        {
1099            // The address is an address in this process, so just copy it
1100            memcpy ((void *)addr, new_value.GetData(), byte_size);
1101            return true;
1102        }
1103        else
1104        {
1105            if (exe_ctx && exe_ctx->process)
1106            {
1107                Error error;
1108                return exe_ctx->process->WriteMemory(addr, new_value.GetData(), byte_size, error) == byte_size;
1109            }
1110        }
1111    }
1112    return false;
1113}
1114
1115
1116